Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def handler(
pointer_types=metadata.pointer_types,
)
return SpineErrorResponse.INVALID_CODE_SYSTEM(
diagnostics="Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
diagnostics="Invalid query parameter (The provided type does not match the allowed types for this organisation)",
expression="type",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,56 @@ def test_search_document_reference_happy_path(repository: DocumentPointerReposit
}


@mock_aws
@mock_repository
def test_search_document_reference_accession_number_in_pointer(
repository: DocumentPointerRepository,
):
doc_ref = load_document_reference("Y05868-736253002-Valid")
doc_ref.identifier = [
{"type": {"text": "Accession-Number"}, "value": "Y05868.123456789"}
]
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
repository.create(doc_pointer)

event = create_test_api_gateway_event(
headers=create_headers(),
query_string_parameters={
"subject:identifier": "https://fhir.nhs.uk/Id/nhs-number|6700028191",
},
)

result = handler(event, create_mock_context())
body = result.pop("body")

assert result == {
"statusCode": "200",
"headers": default_response_headers(),
"isBase64Encoded": False,
}

parsed_body = json.loads(body)
assert parsed_body == {
"resourceType": "Bundle",
"type": "searchset",
"total": 1,
"link": [
{
"relation": "self",
"url": "https://pytest.api.service.nhs.uk/record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|6700028191",
}
],
"entry": [{"resource": doc_ref.model_dump(exclude_none=True)}],
}

created_doc_pointer = repository.get_by_id("Y05868-99999-99999-999999")

assert created_doc_pointer is not None
assert json.loads(created_doc_pointer.document)["identifier"] == [
{"type": {"text": "Accession-Number"}, "value": "Y05868.123456789"}
]


@mock_aws
@mock_repository
def test_search_document_reference_happy_path_with_custodian(
Expand Down Expand Up @@ -451,7 +501,7 @@ def test_search_document_reference_invalid_type(repository: DocumentPointerRepos
}
]
},
"diagnostics": "Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
"diagnostics": "Invalid query parameter (The provided type does not match the allowed types for this organisation)",
"expression": ["type"],
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def handler(
pointer_types=metadata.pointer_types,
)
return SpineErrorResponse.INVALID_CODE_SYSTEM(
diagnostics="Invalid type (The provided type system does not match the allowed types for this organisation)",
diagnostics="The provided type does not match the allowed types for this organisation",
expression="type",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ def test_search_post_document_reference_invalid_type(
}
]
},
"diagnostics": "Invalid type (The provided type system does not match the allowed types for this organisation)",
"diagnostics": "The provided type does not match the allowed types for this organisation",
"expression": ["type"],
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def handler(
pointer_types=metadata.pointer_types,
)
return SpineErrorResponse.INVALID_CODE_SYSTEM(
diagnostics="Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
diagnostics="Invalid query parameter (The provided type does not match the allowed types for this organisation)",
expression="type",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def test_search_document_reference_invalid_type(repository: DocumentPointerRepos
}
]
},
"diagnostics": "Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
"diagnostics": "Invalid query parameter (The provided type does not match the allowed types for this organisation)",
"expression": ["type"],
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def handler(
pointer_types=metadata.pointer_types,
)
return SpineErrorResponse.INVALID_CODE_SYSTEM(
diagnostics="The provided type system does not match the allowed types for this organisation",
diagnostics="The provided type does not match the allowed types for this organisation",
expression="type",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def test_search_document_reference_invalid_type(repository: DocumentPointerRepos
}
]
},
"diagnostics": "The provided type system does not match the allowed types for this organisation",
"diagnostics": "The provided type does not match the allowed types for this organisation",
"expression": ["type"],
}
],
Expand Down
2 changes: 1 addition & 1 deletion layer/nrlf/core/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

def validate_type(type_: Optional[RequestQueryType], pointer_types: List[str]) -> bool:
"""
Validates if the given type system is present in the list of pointer types.
Validates if the given type is present in the list of pointer types.
"""
if not type_:
return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,35 @@ Feature: Consumer - searchDocumentReference - Failure Scenarios
"display": "Invalid code system"
}]
},
"diagnostics": "Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
"diagnostics": "Invalid query parameter (The provided type does not match the allowed types for this organisation)",
"expression": ["type"]
}
"""

Scenario: Search rejects request with type they are not allowed to use
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
And the organisation 'RX898' is authorised to access pointer types:
| system | value |
| http://snomed.info/sct | 736253002 |
When consumer 'RX898' searches for DocumentReferences with parameters:
| parameter | value |
| subject | 9278693472 |
| type | http://snomed.info/sct\|887701000000100 |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might not be doing what you expect it to do. See:

if type_code := items.get("type"):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm searching for pointers with that type as a parameter thats got nothing to do with creating a pointer of a certain type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, it's a search, ignore me

Then the response status code is 400
And the response is an OperationOutcome with 1 issue
And the OperationOutcome contains the issue:
"""
{
"severity": "error",
"code": "code-invalid",
"details": {
"coding": [{
"system": "https://fhir.nhs.uk/ValueSet/Spine-ErrorOrWarningCode-1",
"code": "INVALID_CODE_SYSTEM",
"display": "Invalid code system"
}]
},
"diagnostics": "Invalid query parameter (The provided type does not match the allowed types for this organisation)",
"expression": ["type"]
}
"""
Expand Down
38 changes: 38 additions & 0 deletions tests/features/consumer/searchDocumentReference-success.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,44 @@ Feature: Consumer - searchDocumentReference - Success Scenarios
| custodian | 02V |
| author | 02V |

Scenario: Search for a DocumentReference and Accession Number is in response
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
And the organisation 'RX898' is authorised to access pointer types:
| system | value |
| http://snomed.info/sct | 736253002 |
And a DocumentReference resource exists with values:
| property | value |
| id | 02V-1111111111-SearchDocRefTest |
| subject | 9278693472 |
| status | current |
| type | 736253002 |
| category | 734163000 |
| contentType | application/pdf |
| url | https://example.org/my-doc.pdf |
| custodian | 02V |
| author | 02V |
| identifier | 02V.123456789 |
When consumer 'RX898' searches for DocumentReferences with parameters:
| parameter | value |
| subject | 9278693472 |
Then the response status code is 200
And the response is a searchset Bundle
And the Bundle has a self link matching 'DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|9278693472'
And the Bundle has a total of 1
And the Bundle has 1 entry
And the Bundle contains an DocumentReference with values
| property | value |
| id | 02V-1111111111-SearchDocRefTest |
| subject | 9278693472 |
| status | current |
| type | 736253002 |
| category | 734163000 |
| contentType | application/pdf |
| url | https://example.org/my-doc.pdf |
| custodian | 02V |
| author | 02V |
| identifier | 02V.123456789 |

Scenario: Search for a DocumentReference by NHS Number and Custodian where both search parameters match
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
And the organisation 'RX898' is authorised to access pointer types:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,35 @@ Feature: Consumer - searchDocumentReference - Failure Scenarios
"display": "Invalid code system"
}]
},
"diagnostics": "Invalid type (The provided type system does not match the allowed types for this organisation)",
"diagnostics": "The provided type does not match the allowed types for this organisation",
"expression": ["type"]
}
"""

Scenario: Search rejects request with type they are not allowed to use
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
And the organisation 'RX898' is authorised to access pointer types:
| system | value |
| http://snomed.info/sct | 736253002 |
When consumer 'RX898' searches for DocumentReferences using POST with request body:
| key | value |
| subject | 9278693472 |
| type | http://snomed.info/sct\|887701000000100 |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, see:

if type_code := items.get("type"):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah its a parameter for the search request not creating a pointer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, it's a search, ignore me

Then the response status code is 400
And the response is an OperationOutcome with 1 issue
And the OperationOutcome contains the issue:
"""
{
"severity": "error",
"code": "code-invalid",
"details": {
"coding": [{
"system": "https://fhir.nhs.uk/ValueSet/Spine-ErrorOrWarningCode-1",
"code": "INVALID_CODE_SYSTEM",
"display": "Invalid code system"
}]
},
"diagnostics": "The provided type does not match the allowed types for this organisation",
"expression": ["type"]
}
"""
Expand Down
8 changes: 8 additions & 0 deletions tests/features/steps/3_assert.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ def assert_document_reference_matches_value(
context.response.json(),
)

if identifier := items.get("identifier"):
assert doc_ref.identifier[0].value == identifier, format_error(
"DocumentReference Identifier does not match",
identifier,
doc_ref.identifier[0].value,
context.response.json(),
)


@then("the Bundle contains an DocumentReference with values")
def assert_bundle_contains_documentreference_values_step(context: Context):
Expand Down
6 changes: 6 additions & 0 deletions tests/features/utils/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ def create_test_document_reference(items: dict) -> DocumentReference:
),
)
]
if items.get("identifier"):
base_doc_ref.identifier = [
Identifier(
type=CodeableConcept(text="Accession-Number"), value=items["identifier"]
)
]

return base_doc_ref

Expand Down