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
4 changes: 2 additions & 2 deletions app/src/helpers/requests/getDocumentSearchResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const getDocumentSearchResults = async ({
nhsNumber,
baseUrl,
baseHeaders,
docType = DOCUMENT_TYPE.ALL,
docType,
}: DocumentSearchResultsArgs): Promise<Array<SearchResult>> => {
const gatewayUrl = baseUrl + endpoints.DOCUMENT_SEARCH;

Expand All @@ -32,7 +32,7 @@ const getDocumentSearchResults = async ({
},
params: {
patientId: nhsNumber?.replaceAll(/\s/g, ''), // replace whitespace
docType: docType,
docType: docType == DOCUMENT_TYPE.ALL ? undefined : docType,
},
});
return response?.data;
Expand Down
24 changes: 20 additions & 4 deletions lambdas/handlers/document_reference_search_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json

from enums.feature_flags import FeatureFlags
from enums.lambda_error import LambdaError
from enums.logging_app_interaction import LoggingAppInteraction
from services.document_reference_search_service import DocumentReferenceSearchService
from services.feature_flags_service import FeatureFlagService
Expand All @@ -13,6 +14,8 @@
extract_nhs_number_from_event,
validate_patient_id,
)
from utils.document_type_utils import extract_document_type_to_enum
from utils.lambda_exceptions import DocumentRefSearchException
from utils.lambda_response import ApiGatewayResponse
from utils.request_context import request_context

Expand All @@ -29,6 +32,13 @@ def lambda_handler(event, context):
logger.info("Starting document reference search process")

nhs_number = extract_nhs_number_from_event(event)

doc_type = event.get("queryStringParameters", {}).get("docType", None)
try:
document_snomed_code = extract_document_type_to_enum(doc_type) if doc_type else None
except ValueError:
raise DocumentRefSearchException(400, LambdaError.DocTypeInvalid)

request_context.patient_nhs_no = nhs_number

document_reference_search_service = DocumentReferenceSearchService()
Expand All @@ -38,11 +48,17 @@ def lambda_handler(event, context):
doc_upload_iteration2_enabled = upload_lambda_enabled_flag_object[
FeatureFlags.UPLOAD_DOCUMENT_ITERATION_2_ENABLED
]
doc_status_filter = (
{"doc_status": "final"} if doc_upload_iteration2_enabled else None
)

additional_filters = {}
if doc_upload_iteration2_enabled:
additional_filters["doc_status"] = "final"
if document_snomed_code:
additional_filters["document_snomed_code"] = document_snomed_code[0].value

response = document_reference_search_service.get_document_references(
nhs_number, check_upload_completed=True, additional_filters=doc_status_filter
nhs_number,
check_upload_completed=True,
additional_filters=additional_filters
)
logger.info("User is able to view docs", {"Result": "Successful viewing docs"})

Expand Down
10 changes: 9 additions & 1 deletion lambdas/services/document_reference_search_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def _search_tables_for_documents(
return document_resources or None

def _get_filter_expression(
self, filters: dict[str, str] = None, upload_completed=False
self, filters: dict[str, str | None] = None, upload_completed=False
):
if filters:
return self._build_filter_expression(filters)
Expand Down Expand Up @@ -207,6 +207,14 @@ def _build_filter_expression(self, filter_values: dict[str, str]):
attr_operator=AttributeOperator.EQUAL,
filter_value=filter_value,
)
elif filter_key == "document_snomed_code":
filter_builder.add_condition(
attribute=str(
DocumentReferenceMetadataFields.DOCUMENT_SNOMED_CODE_TYPE.value
),
attr_operator=AttributeOperator.EQUAL,
filter_value=filter_value,
)
if filter_values:
filter_expression = filter_builder.build() & NotDeleted
else:
Expand Down
7 changes: 4 additions & 3 deletions lambdas/tests/unit/enums/test_metadata_field_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def test_returns_all_as_list():
assert DocumentReferenceMetadataFields.UPLOADED.value in subject
assert DocumentReferenceMetadataFields.UPLOADING.value in subject
assert DocumentReferenceMetadataFields.LAST_UPDATED.value in subject
assert DocumentReferenceMetadataFields.FILE_SIZE.value in subject
assert DocumentReferenceMetadataFields.DOC_STATUS.value in subject
assert DocumentReferenceMetadataFields.DOCUMENT_SCAN_CREATION.value in subject
assert DocumentReferenceMetadataFields.CUSTODIAN.value in subject
assert DocumentReferenceMetadataFields.FILE_SIZE.value in subject
assert DocumentReferenceMetadataFields.DOCUMENT_SNOMED_CODE_TYPE.value in subject
assert DocumentReferenceMetadataFields.DOCUMENT_SCAN_CREATION.value in subject
assert DocumentReferenceMetadataFields.DOCUMENT_SNOMED_CODE_TYPE.value in subject

Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ def test_lambda_handler_when_dynamo_tables_env_variable_not_supplied_then_return
def test_lambda_handler_with_feature_flag_enabled_applies_doc_status_filter(
set_env, mocker, valid_id_event_without_auth_header, context
):
"""Test that when feature flag is ON, doc_status filter is applied"""
mocked_service_class = mocker.patch(
"handlers.document_reference_search_handler.DocumentReferenceSearchService"
)
Expand Down Expand Up @@ -163,7 +162,6 @@ def test_lambda_handler_with_feature_flag_enabled_applies_doc_status_filter(
def test_lambda_handler_with_feature_flag_disabled_no_doc_status_filter(
set_env, mocker, valid_id_event_without_auth_header, context
):
"""Test that when feature flag is OFF, no doc_status filter is applied"""
mocked_service_class = mocker.patch(
"handlers.document_reference_search_handler.DocumentReferenceSearchService"
)
Expand Down Expand Up @@ -191,5 +189,70 @@ def test_lambda_handler_with_feature_flag_disabled_no_doc_status_filter(
mocked_service.get_document_references.assert_called_once_with(
"9000000009",
check_upload_completed=True,
additional_filters=None,
additional_filters={},
)

def test_lambda_handler_with_doc_type_applies_doc_type_filter(
set_env, mocker, valid_id_event_without_auth_header, context
):
mocked_service_class = mocker.patch(
"handlers.document_reference_search_handler.DocumentReferenceSearchService"
)
mocked_service = mocked_service_class.return_value
mocked_service.get_document_references.return_value = EXPECTED_RESPONSE

mocked_feature_flag_service = mocker.patch(
"handlers.document_reference_search_handler.FeatureFlagService"
)
mocked_feature_flag_instance = mocked_feature_flag_service.return_value
mocked_feature_flag_instance.get_feature_flags_by_flag.return_value = {
FeatureFlags.UPLOAD_DOCUMENT_ITERATION_2_ENABLED: False
}

expected = ApiGatewayResponse(
200, json.dumps(EXPECTED_RESPONSE), "GET"
).create_api_gateway_response()

doc_type = "16521000000101"
valid_id_event_without_auth_header["queryStringParameters"]["docType"] = doc_type

actual = lambda_handler(valid_id_event_without_auth_header, context)

assert expected == actual
mocked_feature_flag_instance.get_feature_flags_by_flag.assert_called_once_with(
FeatureFlags.UPLOAD_DOCUMENT_ITERATION_2_ENABLED
)
mocked_service.get_document_references.assert_called_once_with(
"9000000009",
check_upload_completed=True,
additional_filters={"document_snomed_code": doc_type},
)


def test_lambda_handler_with_invalid_doc_type_returns_400(
set_env, mocker, valid_id_event_without_auth_header, context
):
mocker.patch(
"handlers.document_reference_search_handler.DocumentReferenceSearchService"
)
mocker.patch(
"handlers.document_reference_search_handler.FeatureFlagService"
)

invalid_doc_type = "invalid_doc_type"
valid_id_event_without_auth_header["queryStringParameters"]["docType"] = invalid_doc_type

expected_body = json.dumps(
{
"message": "Invalid document type requested",
"err_code": "VDT_4002",
"interaction_id": "88888888-4444-4444-4444-121212121212",
}
)
expected = ApiGatewayResponse(
400, expected_body, "GET"
).create_api_gateway_response()

actual = lambda_handler(valid_id_event_without_auth_header, context)

assert expected == actual
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,13 @@ def test_build_filter_expression_defaults(mock_document_service):
actual_filter = mock_document_service._build_filter_expression(filter_values)

assert actual_filter == expected_filter

def test_build_filter_expression_document_snomed_code(mock_document_service):
filter_values = {"document_snomed_code": "16521000000101"}
expected_filter = Attr("DocumentSnomedCodeType").eq("16521000000101") & (
Attr("Deleted").eq("") | Attr("Deleted").not_exists()
)

actual_filter = mock_document_service._build_filter_expression(filter_values)

assert expected_filter == actual_filter
Loading