Skip to content
Open
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
11 changes: 11 additions & 0 deletions lambdas/enums/document_review_reason.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from enum import StrEnum


class DocumentReviewReason(StrEnum):
UNKNOWN_NHS_NUMBER = "Unknown NHS number"
DEMOGRAPHIC_MISMATCHES = "Demographic mismatches"
DUPLICATE_RECORD = "Duplicate records error"
FILE_COUNT_MISMATCH = "More or less files than we expected"
FILE_NAME_MISMATCH = "Filename Naming convention error"
GP2GP_ERROR = "GP2GP failure"
GENERAL_ERROR = "General error"
3 changes: 0 additions & 3 deletions lambdas/enums/document_review_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@ class DocumentReviewStatus(StrEnum):
REVIEW_PENDING_UPLOAD = "REVIEW_PENDING_UPLOAD"
VIRUS_SCAN_FAILED = "VIRUS_SCAN_FAILED"


class DocumentReviewReason(StrEnum):
REVIEW_FROM_DATA_CONTROLLER = "Needs review from data controller"
5 changes: 4 additions & 1 deletion lambdas/models/document_review.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import uuid
from datetime import datetime, timezone

from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.metadata_field_names import DocumentReferenceMetadataFields
from enums.snomed_codes import SnomedCodes
Expand Down Expand Up @@ -38,7 +39,9 @@ class DocumentUploadReviewReference(BaseModel):
review_status: DocumentReviewStatus = Field(
default=DocumentReviewStatus.PENDING_REVIEW
)
review_reason: str | None = None
review_reason: DocumentReviewReason = Field(
default=DocumentReviewReason.GENERAL_ERROR
)
review_date: int | None = Field(default=None)
reviewer: str | None = Field(default=None)
upload_date: int = Field(
Expand Down
10 changes: 8 additions & 2 deletions lambdas/models/sqs/review_message_body.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pydantic import BaseModel, Field
from enums.document_review_reason import DocumentReviewReason
from pydantic import BaseModel, ConfigDict, Field


class ReviewMessageFile(BaseModel):
Expand All @@ -12,10 +13,15 @@ class ReviewMessageFile(BaseModel):
class ReviewMessageBody(BaseModel):
"""Model for SQS message body from the document review queue."""

model_config = ConfigDict(
use_enum_values=True,
)
upload_id: str
files: list[ReviewMessageFile]
nhs_number: str
failure_reason: str
failure_reason: DocumentReviewReason = Field(
default=DocumentReviewReason.GENERAL_ERROR
)
upload_date: str
uploader_ods: str
current_gp: str
6 changes: 4 additions & 2 deletions lambdas/services/post_document_review_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from datetime import datetime, timezone

from botocore.exceptions import ClientError
from enums.document_review_status import DocumentReviewReason, DocumentReviewStatus

from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.lambda_error import LambdaError
from enums.patient_ods_inactive_status import PatientOdsInactiveStatus
from models.document_review import (
Expand Down Expand Up @@ -116,7 +118,7 @@ def create_review_reference_from_event(
files=document_file_details,
nhs_number=event.nhs_number,
document_snomed_code_type=event.snomed_code.code,
review_reason=DocumentReviewReason.REVIEW_FROM_DATA_CONTROLLER,
review_reason=DocumentReviewReason.GP2GP_ERROR,
)
return document_review_reference

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import json

import pytest

from enums.document_review_reason import DocumentReviewReason
from handlers.document_review_processor_handler import lambda_handler
from models.sqs.review_message_body import ReviewMessageBody, ReviewMessageFile

Expand All @@ -27,7 +29,7 @@ def sample_review_message_body():
)
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.GENERAL_ERROR,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down Expand Up @@ -62,7 +64,7 @@ def sample_sqs_event_multiple_messages(sample_review_message_body):
)
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.UNKNOWN_NHS_NUMBER,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand All @@ -77,7 +79,7 @@ def sample_sqs_event_multiple_messages(sample_review_message_body):
)
],
nhs_number="9000000010",
failure_reason="Invalid file format",
failure_reason=DocumentReviewReason.FILE_NAME_MISMATCH,
upload_date="2024-01-15T10:35:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand All @@ -92,7 +94,7 @@ def sample_sqs_event_multiple_messages(sample_review_message_body):
)
],
nhs_number="9000000011",
failure_reason="Missing metadata",
failure_reason=DocumentReviewReason.FILE_COUNT_MISMATCH,
upload_date="2024-01-15T10:40:00Z",
uploader_ods="Y67890",
current_gp="Y67890",
Expand Down Expand Up @@ -194,7 +196,7 @@ def test_lambda_handler_parses_json_body_correctly(
{"file_name": "test.pdf", "file_path": "staging/test.pdf"}
],
"nhs_number": "9000000009",
"failure_reason": "Test failure",
"failure_reason": "General error",
"upload_date": "2024-01-15T10:30:00Z",
"uploader_ods": "Y12345",
"current_gp": "Y12345",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.snomed_codes import SnomedCodes
from tests.unit.conftest import (
Expand Down Expand Up @@ -28,7 +29,7 @@
"Custodian": TEST_CURRENT_GP_ODS,
"UploadDate": 1704110400,
"NhsNumber": TEST_NHS_NUMBER,
"ReviewReason": "Failure",
"ReviewReason": DocumentReviewReason.FILE_COUNT_MISMATCH,
"ReviewStatus": DocumentReviewStatus.PENDING_REVIEW,
"LastUpdated": 1704110400, # Timestamp: 2024-01-01T12:00:00
"DocumentSnomedCodeType": SnomedCodes.LLOYD_GEORGE.value.code,
Expand All @@ -50,7 +51,7 @@
"Custodian": TEST_CURRENT_GP_ODS,
"UploadDate": 1704110400,
"NhsNumber": TEST_NHS_NUMBER,
"ReviewReason": "Failure",
"ReviewReason": DocumentReviewReason.FILE_COUNT_MISMATCH,
"ReviewStatus": DocumentReviewStatus.PENDING_REVIEW,
"LastUpdated": 1704110400, # Timestamp: 2024-01-01T12:00:00
"DocumentSnomedCodeType": SnomedCodes.LLOYD_GEORGE.value.code,
Expand All @@ -74,7 +75,7 @@
"Reviewer": None,
"NhsNumber": TEST_NHS_NUMBER,
"ReviewDate": None,
"ReviewReason": "Failure",
"ReviewReason": DocumentReviewReason.FILE_COUNT_MISMATCH,
"ReviewStatus": DocumentReviewStatus.PENDING_REVIEW,
"LastUpdated": 1704110400, # Timestamp: 2024-01-01T12:00:00
"DocumentSnomedCodeType": SnomedCodes.LLOYD_GEORGE.value.code,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from botocore.exceptions import ClientError
from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from models.document_review import (
DocumentReviewFileDetails,
Expand Down Expand Up @@ -40,7 +41,7 @@ def sample_review_message():
)
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.DEMOGRAPHIC_MISMATCHES,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down Expand Up @@ -95,7 +96,7 @@ def test_process_review_message_multiple_files(service_under_test, mocker):
),
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.FILE_COUNT_MISMATCH,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down Expand Up @@ -212,7 +213,7 @@ def test_build_review_record_success(service_under_test, sample_review_message):
assert result.id == "test-review-id"
assert result.nhs_number == "9000000009"
assert result.review_status == DocumentReviewStatus.PENDING_REVIEW
assert result.review_reason == "Failed virus scan"
assert result.review_reason == "Demographic mismatches"
assert result.author == "Y12345"
assert result.custodian == "Y12345"
assert len(result.files) == 1
Expand All @@ -237,7 +238,7 @@ def test_build_review_record_with_multiple_files(service_under_test):
),
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.FILE_COUNT_MISMATCH,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down Expand Up @@ -302,7 +303,7 @@ def test_move_multiple_files_success(service_under_test, mocker):
),
],
nhs_number="9000000009",
failure_reason="Failed virus scan",
failure_reason=DocumentReviewReason.FILE_COUNT_MISMATCH,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down Expand Up @@ -409,7 +410,7 @@ def test_workflow_handles_multiple_different_patients(service_under_test):
)
],
nhs_number=f"900000000{i}",
failure_reason="Test failure",
failure_reason=DocumentReviewReason.GENERAL_ERROR,
upload_date="2024-01-15T10:30:00Z",
uploader_ods="Y12345",
current_gp="Y12345",
Expand Down
15 changes: 10 additions & 5 deletions lambdas/tests/unit/services/test_document_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,15 +518,21 @@ def test_get_item_success(
@pytest.mark.parametrize(
"document_id,mock_response",
[
("non-existent-doc", {}, ),
(
"non-existent-doc",
{},
),
(
"invalid-doc",
{"Item": {"ID": "invalid-doc", "InvalidField": "invalid-value"}},
),
],
)
def test_get_item_returns_none(
mock_service, mock_dynamo_service, document_id, mock_response,
mock_service,
mock_dynamo_service,
document_id,
mock_response,
):
"""Test get_item returns None for not found or invalid documents."""
mock_dynamo_service.get_item.return_value = mock_response
Expand Down Expand Up @@ -563,11 +569,10 @@ def test_get_item_with_custom_model_class(
mock_dynamo_response = {
"Item": {
"ID": document_id,

"Author": "Y12345",
"Custodian": "Y12345",
"ReviewStatus": "PENDING_REVIEW",
"ReviewReason": "Test reason",
"ReviewReason": "General error",
"UploadDate": 1699000000,
"Files": [
{
Expand Down Expand Up @@ -610,4 +615,4 @@ def test_get_item_document_id_with_sort_key(mock_service, mock_dynamo_service):

mock_dynamo_service.get_item.assert_called_once_with(
table_name=MOCK_LG_TABLE_NAME, key={"ID": document_id, **sort_key}
)
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock

import pytest
from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.lambda_error import LambdaError
from enums.snomed_codes import SnomedCodes
Expand Down Expand Up @@ -65,7 +66,7 @@ def mock_document_review():
author=TEST_ODS_CODE,
custodian=TEST_ODS_CODE,
review_status=DocumentReviewStatus.PENDING_REVIEW,
review_reason="Uploaded for review",
review_reason=DocumentReviewReason.FILE_NAME_MISMATCH,
upload_date=1699000000,
files=files,
nhs_number=TEST_NHS_NUMBER,
Expand Down
4 changes: 3 additions & 1 deletion lambdas/tests/unit/services/test_ods_report_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from unittest.mock import call

import pytest

from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.dynamo_filter import AttributeOperator
from enums.file_type import FileType
Expand Down Expand Up @@ -61,7 +63,7 @@ def mock_review_result():
return DocumentUploadReviewReference(
nhs_number="mock_nhs_number",
author="mock_author",
review_reason="mock_review_reason",
review_reason=DocumentReviewReason.GENERAL_ERROR,
document_snomed_code_type="mock_snomed_code",
upload_date=int(datetime.now().timestamp()),
files=[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ def mock_document_references(mocker):

@pytest.fixture
def mock_document_review_references(mocker):
# Create a list of mock document review references
reviews = []
for i in range(2):
review = MagicMock(spec=DocumentUploadReviewReference)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
from botocore.exceptions import ClientError

from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.virus_scan_result import VirusScanResult
from models.document_reference import S3_PREFIX
Expand Down Expand Up @@ -64,7 +66,7 @@ def sample_document_reference():
author="Y12345",
custodian="Y12345",
review_status=DocumentReviewStatus.REVIEW_PENDING_UPLOAD,
review_reason="Test reason",
review_reason=DocumentReviewReason.FILE_COUNT_MISMATCH,
upload_date=1704110400,
files=[
DocumentReviewFileDetails(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock

import pytest
from enums.document_review_reason import DocumentReviewReason
from enums.document_review_status import DocumentReviewStatus
from enums.lambda_error import LambdaError
from enums.snomed_codes import SnomedCodes
Expand Down Expand Up @@ -56,7 +57,7 @@ def mock_document_review():
author=TEST_ODS_CODE,
custodian=TEST_ODS_CODE,
review_status=DocumentReviewStatus.PENDING_REVIEW,
review_reason="Uploaded for review",
review_reason=DocumentReviewReason.DUPLICATE_RECORD,
upload_date=TEST_UPLOAD_DATE,
files=files,
nhs_number=TEST_NHS_NUMBER,
Expand Down Expand Up @@ -732,7 +733,11 @@ def test_update_document_review_raises_exception_when_updating_approved_pending_
mock_document_review.review_status = DocumentReviewStatus.APPROVED_PENDING_DOCUMENTS
update_data = PatchDocumentReviewRequest(
review_status=invalid_target_status,
nhs_number=TEST_REASSIGNED_NHS_NUMBER if "REASSIGNED" in invalid_target_status.value else None,
nhs_number=(
TEST_REASSIGNED_NHS_NUMBER
if "REASSIGNED" in invalid_target_status.value
else None
),
)
mock_service.document_review_service.get_document_review_by_id.return_value = (
mock_document_review
Expand Down Expand Up @@ -784,4 +789,4 @@ def test_update_document_review_raises_exception_when_approving_from_non_approve
)

assert exc_info.value.status_code == 400
assert exc_info.value.error == LambdaError.UpdateDocStatusUnavailable
assert exc_info.value.error == LambdaError.UpdateDocStatusUnavailable
Loading