Skip to content

Commit cb69b2c

Browse files
committed
NRL-1205 add optimisation back and extra test scenarios
1 parent 4ac28a3 commit cb69b2c

File tree

3 files changed

+165
-9
lines changed

3 files changed

+165
-9
lines changed

api/consumer/searchDocumentReference/tests/test_search_document_reference_consumer.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,114 @@ def test_search_document_reference_happy_path_with_category_and_type(
301301
}
302302

303303

304+
@mock_aws
305+
@mock_repository
306+
def test_search_document_reference_happy_path_with_category_and_type_no_results(
307+
repository: DocumentPointerRepository,
308+
):
309+
doc_ref = load_document_reference("Y05868-736253002-Valid")
310+
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
311+
repository.create(doc_pointer)
312+
313+
# Second pointer different category
314+
doc_ref2 = load_document_reference("Y05868-736253002-Valid")
315+
doc_ref2.id = "Y05868-736253002-Valid2"
316+
doc_ref2.type.coding[0].code = PointerTypes.NEWS2_CHART.coding_value()
317+
doc_ref2.type.coding[0].display = TYPE_ATTRIBUTES.get(
318+
PointerTypes.NEWS2_CHART.value
319+
).get("display")
320+
doc_ref2.category[0].coding[0].code = Categories.OBSERVATIONS.coding_value()
321+
doc_ref2.category[0].coding[0].display = CATEGORY_ATTRIBUTES.get(
322+
Categories.OBSERVATIONS.value
323+
).get("display")
324+
repository.create(DocumentPointer.from_document_reference(doc_ref2))
325+
326+
event = create_test_api_gateway_event(
327+
headers=create_headers(),
328+
query_string_parameters={
329+
"subject:identifier": "https://fhir.nhs.uk/Id/nhs-number|6700028191",
330+
"category": "http://snomed.info/sct|1102421000000108",
331+
"type": "http://snomed.info/sct|736253002",
332+
},
333+
)
334+
335+
result = handler(event, create_mock_context())
336+
body = result.pop("body")
337+
338+
assert result == {
339+
"statusCode": "200",
340+
"headers": default_response_headers(),
341+
"isBase64Encoded": False,
342+
}
343+
parsed_body = json.loads(body)
344+
assert parsed_body == {
345+
"resourceType": "Bundle",
346+
"type": "searchset",
347+
"link": [
348+
{
349+
"relation": "self",
350+
"url": "https://pytest.api.service.nhs.uk/record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|6700028191&type=http://snomed.info/sct|736253002&category=http://snomed.info/sct|1102421000000108",
351+
}
352+
],
353+
"total": 0,
354+
"entry": [],
355+
}
356+
357+
358+
@mock_aws
359+
@mock_repository
360+
def test_search_document_reference_happy_path_with_multiple_categories_and_type(
361+
repository: DocumentPointerRepository,
362+
):
363+
doc_ref = load_document_reference("Y05868-736253002-Valid")
364+
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
365+
repository.create(doc_pointer)
366+
367+
# Second pointer different category
368+
doc_ref2 = load_document_reference("Y05868-736253002-Valid")
369+
doc_ref2.id = "Y05868-736253002-Valid2"
370+
doc_ref2.type.coding[0].code = PointerTypes.NEWS2_CHART.coding_value()
371+
doc_ref2.type.coding[0].display = TYPE_ATTRIBUTES.get(
372+
PointerTypes.NEWS2_CHART.value
373+
).get("display")
374+
doc_ref2.category[0].coding[0].code = Categories.OBSERVATIONS.coding_value()
375+
doc_ref2.category[0].coding[0].display = CATEGORY_ATTRIBUTES.get(
376+
Categories.OBSERVATIONS.value
377+
).get("display")
378+
repository.create(DocumentPointer.from_document_reference(doc_ref2))
379+
380+
event = create_test_api_gateway_event(
381+
headers=create_headers(),
382+
query_string_parameters={
383+
"subject:identifier": "https://fhir.nhs.uk/Id/nhs-number|6700028191",
384+
"category": "http://snomed.info/sct|734163000,http://snomed.info/sct|1102421000000108",
385+
"type": "http://snomed.info/sct|736253002",
386+
},
387+
)
388+
389+
result = handler(event, create_mock_context())
390+
body = result.pop("body")
391+
392+
assert result == {
393+
"statusCode": "200",
394+
"headers": default_response_headers(),
395+
"isBase64Encoded": False,
396+
}
397+
parsed_body = json.loads(body)
398+
assert parsed_body == {
399+
"resourceType": "Bundle",
400+
"type": "searchset",
401+
"link": [
402+
{
403+
"relation": "self",
404+
"url": "https://pytest.api.service.nhs.uk/record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|6700028191&type=http://snomed.info/sct|736253002&category=http://snomed.info/sct|734163000,http://snomed.info/sct|1102421000000108",
405+
}
406+
],
407+
"total": 1,
408+
"entry": [{"resource": doc_ref.model_dump(exclude_none=True)}],
409+
}
410+
411+
304412
@mock_aws
305413
@mock_repository
306414
def test_search_document_reference_happy_path_with_multiple_categories(

layer/nrlf/core/dynamodb/repository.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,22 @@ def search(
236236

237237
# Add pointer_types filter if provided
238238
if pointer_types:
239-
expression_names["#pointer_type"] = "type"
240-
types_filters = [
241-
f"#pointer_type = :type_{i}" for i in range(len(pointer_types))
242-
]
243-
types_filter_values = {
244-
f":type_{i}": pointer_types[i] for i in range(len(pointer_types))
245-
}
246-
filter_expressions.append(f"({' OR '.join(types_filters)})")
247-
expression_values.update(types_filter_values)
239+
if len(pointer_types) == 1:
240+
# Optimisation for single pointer type
241+
category_id, type_id = _get_sk_ids_for_type(pointer_types[0])
242+
patient_sort = f"C#{category_id}#T#{type_id}"
243+
key_conditions.append("begins_with(patient_sort, :patient_sort)")
244+
expression_values[":patient_sort"] = patient_sort
245+
else:
246+
expression_names["#pointer_type"] = "type"
247+
types_filters = [
248+
f"#pointer_type = :type_{i}" for i in range(len(pointer_types))
249+
]
250+
types_filter_values = {
251+
f":type_{i}": pointer_types[i] for i in range(len(pointer_types))
252+
}
253+
filter_expressions.append(f"({' OR '.join(types_filters)})")
254+
expression_values.update(types_filter_values)
248255

249256
# Add categories filter if provided
250257
if categories:

tests/features/consumer/searchDocumentReference-success.feature

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,47 @@ Feature: Consumer - searchDocumentReference - Success Scenarios
381381
| author | 02V |
382382
And the Bundle does not contain a DocumentReference with ID '02V-1111111111-SearchMultipleRefTest3'
383383

384+
Scenario: Search for DocumentReference by NHS number and Category and type
385+
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
386+
And the organisation 'RX898' is authorised to access pointer types:
387+
| system | value |
388+
| http://snomed.info/sct | 736253002 |
389+
| http://snomed.info/sct | 1363501000000100 |
390+
And a DocumentReference resource exists with values:
391+
| property | value |
392+
| id | 02V-1111111111-SearchMultipleRefTest1 |
393+
| subject | 9278693472 |
394+
| status | current |
395+
| type | 736253002 |
396+
| category | 734163000 |
397+
| contentType | application/pdf |
398+
| url | https://example.org/my-doc-1.pdf |
399+
| custodian | 02V |
400+
| author | 02V |
401+
And a DocumentReference resource exists with values:
402+
| property | value |
403+
| id | 02V-1111111111-SearchMultipleRefTest3 |
404+
| subject | 9278693472 |
405+
| status | current |
406+
| type | 1363501000000100 |
407+
| category | 1102421000000108 |
408+
| contentType | application/pdf |
409+
| url | https://example.org/my-doc-3.pdf |
410+
| custodian | 02V |
411+
| author | 02V |
412+
When consumer 'RX898' searches for DocumentReferences with parameters:
413+
| parameter | value |
414+
| subject | 9278693472 |
415+
| category | http://snomed.info/sct\|1102421000000108 |
416+
| type | http://snomed.info/sct\|736253002 |
417+
Then the response status code is 200
418+
And the response is a searchset Bundle
419+
And the Bundle has a self link matching 'DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|9278693472&type=http://snomed.info/sct|736253002&category=http://snomed.info/sct|1102421000000108'
420+
And the Bundle has a total of 0
421+
And the Bundle has 0 entries
422+
And the Bundle does not contain a DocumentReference with ID '02V-1111111111-SearchMultipleRefTest1'
423+
And the Bundle does not contain a DocumentReference with ID '02V-1111111111-SearchMultipleRefTest3'
424+
384425
Scenario: Search for multiple DocumentReferences by NHS number and Multiple Categories
385426
Given the application 'DataShare' (ID 'z00z-y11y-x22x') is registered to access the API
386427
And the organisation 'RX898' is authorised to access pointer types:

0 commit comments

Comments
 (0)