Skip to content

Commit 4682d34

Browse files
committed
[NRL-520] Fixup PR comments in validator logic. Add validation for single ASID only. Update unit tests
1 parent 249e261 commit 4682d34

File tree

5 files changed

+136
-47
lines changed

5 files changed

+136
-47
lines changed

api/producer/createDocumentReference/tests/test_create_document_reference.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ def test_create_document_reference_with_no_context_related_for_ssp_url(
743743
}
744744
]
745745
},
746-
"diagnostics": "Missing context.related. It must be provided and contain a valid ASID identifier when content contains an SSP URL",
746+
"diagnostics": "Missing context.related. It must be provided and contain a single valid ASID identifier when content contains an SSP URL",
747747
"expression": ["context.related"],
748748
}
749749
],
@@ -802,7 +802,7 @@ def test_create_document_reference_with_no_asid_in_for_ssp_url(
802802
}
803803
]
804804
},
805-
"diagnostics": "Missing ASID identifier. context.related must contain a valid ASID identifier when content contains an SSP URL",
805+
"diagnostics": "Missing ASID identifier. context.related must contain a single valid ASID identifier when content contains an SSP URL",
806806
"expression": ["context.related"],
807807
}
808808
],
@@ -861,8 +861,8 @@ def test_create_document_reference_with_invalid_asid_for_ssp_url(
861861
}
862862
]
863863
},
864-
"diagnostics": "Invalid ASID value not-a-valid-asid. context.related must contain a valid ASID identifier when content contains an SSP URL",
865-
"expression": ["context.related[].identifier.value"],
864+
"diagnostics": "Invalid ASID value 'not-a-valid-asid'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
865+
"expression": ["context.related[0].identifier.value"],
866866
}
867867
],
868868
}

api/producer/updateDocumentReference/tests/test_update_document_reference.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ def test_update_document_reference_with_no_context_related_for_ssp_url(repositor
506506
}
507507
]
508508
},
509-
"diagnostics": "Missing context.related. It must be provided and contain a valid ASID identifier when content contains an SSP URL",
509+
"diagnostics": "Missing context.related. It must be provided and contain a single valid ASID identifier when content contains an SSP URL",
510510
"expression": ["context.related"],
511511
}
512512
],
@@ -561,7 +561,7 @@ def test_create_document_reference_with_no_asid_in_for_ssp_url(
561561
}
562562
]
563563
},
564-
"diagnostics": "Missing ASID identifier. context.related must contain a valid ASID identifier when content contains an SSP URL",
564+
"diagnostics": "Missing ASID identifier. context.related must contain a single valid ASID identifier when content contains an SSP URL",
565565
"expression": ["context.related"],
566566
}
567567
],
@@ -616,8 +616,8 @@ def test_create_document_reference_with_invalid_asid_for_ssp_url(
616616
}
617617
]
618618
},
619-
"diagnostics": "Invalid ASID value not-a-valid-asid. context.related must contain a valid ASID identifier when content contains an SSP URL",
620-
"expression": ["context.related[].identifier.value"],
619+
"diagnostics": "Invalid ASID value 'not-a-valid-asid'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
620+
"expression": ["context.related[0].identifier.value"],
621621
}
622622
],
623623
}

api/producer/upsertDocumentReference/tests/test_upsert_document_reference.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ def test_create_document_reference_with_no_context_related_for_ssp_url(
775775
}
776776
]
777777
},
778-
"diagnostics": "Missing context.related. It must be provided and contain a valid ASID identifier when content contains an SSP URL",
778+
"diagnostics": "Missing context.related. It must be provided and contain a single valid ASID identifier when content contains an SSP URL",
779779
"expression": ["context.related"],
780780
}
781781
],
@@ -834,7 +834,7 @@ def test_create_document_reference_with_no_asid_in_for_ssp_url(
834834
}
835835
]
836836
},
837-
"diagnostics": "Missing ASID identifier. context.related must contain a valid ASID identifier when content contains an SSP URL",
837+
"diagnostics": "Missing ASID identifier. context.related must contain a single valid ASID identifier when content contains an SSP URL",
838838
"expression": ["context.related"],
839839
}
840840
],
@@ -893,8 +893,8 @@ def test_create_document_reference_with_invalid_asid_for_ssp_url(
893893
}
894894
]
895895
},
896-
"diagnostics": "Invalid ASID value not-a-valid-asid. context.related must contain a valid ASID identifier when content contains an SSP URL",
897-
"expression": ["context.related[].identifier.value"],
896+
"diagnostics": "Invalid ASID value 'not-a-valid-asid'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
897+
"expression": ["context.related[0].identifier.value"],
898898
}
899899
],
900900
}

layer/nrlf/core/tests/test_validators.py

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def test_validate_ssp_content_without_any_context_related():
508508
}
509509
]
510510
},
511-
"diagnostics": "Missing context.related. It must be provided and contain a valid ASID identifier when content contains an SSP URL",
511+
"diagnostics": "Missing context.related. It must be provided and contain a single valid ASID identifier when content contains an SSP URL",
512512
"expression": ["context.related"],
513513
}
514514

@@ -544,7 +544,7 @@ def test_validate_ssp_content_without_asid_in_context_related():
544544
}
545545
]
546546
},
547-
"diagnostics": "Missing ASID identifier. context.related must contain a valid ASID identifier when content contains an SSP URL",
547+
"diagnostics": "Missing ASID identifier. context.related must contain a single valid ASID identifier when content contains an SSP URL",
548548
"expression": ["context.related"],
549549
}
550550

@@ -575,6 +575,97 @@ def test_validate_ssp_content_with_invalid_asid_value():
575575
}
576576
]
577577
},
578-
"diagnostics": "Invalid ASID value TEST_INVALID_ASID. context.related must contain a valid ASID identifier when content contains an SSP URL",
579-
"expression": ["context.related[].identifier.value"],
578+
"diagnostics": "Invalid ASID value 'TEST_INVALID_ASID'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
579+
"expression": ["context.related[0].identifier.value"],
580+
}
581+
582+
583+
def test_validate_ssp_content_with_invalid_asid_value_and_multiple_related():
584+
validator = DocumentReferenceValidator()
585+
document_ref_data = load_document_reference_json(
586+
"Y05868-736253002-Valid-with-ssp-content"
587+
)
588+
589+
document_ref_data["context"]["related"] = [
590+
{
591+
"identifier": {
592+
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
593+
"value": "Y05868",
594+
}
595+
}
596+
]
597+
document_ref_data["context"]["related"].append(
598+
{
599+
"identifier": {
600+
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
601+
"value": "Y09999",
602+
}
603+
}
604+
)
605+
document_ref_data["context"]["related"].append(
606+
{
607+
"identifier": {
608+
"system": "https://fhir.nhs.uk/Id/nhsSpineASID",
609+
"value": "TEST_INVALID_ASID",
610+
}
611+
}
612+
)
613+
614+
result = validator.validate(document_ref_data)
615+
616+
assert result.is_valid is False
617+
assert len(result.issues) == 1
618+
assert result.issues[0].dict(exclude_none=True) == {
619+
"severity": "error",
620+
"code": "value",
621+
"details": {
622+
"coding": [
623+
{
624+
"system": "https://fhir.nhs.uk/ValueSet/Spine-ErrorOrWarningCode-1",
625+
"code": "INVALID_IDENTIFIER_VALUE",
626+
"display": "Invalid identifier value",
627+
}
628+
]
629+
},
630+
"diagnostics": "Invalid ASID value 'TEST_INVALID_ASID'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
631+
"expression": ["context.related[2].identifier.value"],
632+
}
633+
634+
635+
def test_validate_ssp_content_with_multiple_asids():
636+
validator = DocumentReferenceValidator()
637+
document_ref_data = load_document_reference_json(
638+
"Y05868-736253002-Valid-with-ssp-content"
639+
)
640+
641+
document_ref_data["context"]["related"][0]["identifier"][
642+
"value"
643+
] = "TEST_INVALID_ASID"
644+
document_ref_data["context"]["related"].append(
645+
{
646+
"identifier": {
647+
"system": "https://fhir.nhs.uk/Id/nhsSpineASID",
648+
"value": "09876543210",
649+
}
650+
}
651+
)
652+
653+
result = validator.validate(document_ref_data)
654+
655+
assert result.is_valid is False
656+
assert len(result.issues) == 1
657+
assert result.issues[0].dict(exclude_none=True) == {
658+
"severity": "error",
659+
"code": "invalid",
660+
"details": {
661+
"coding": [
662+
{
663+
"system": "https://fhir.nhs.uk/ValueSet/Spine-ErrorOrWarningCode-1",
664+
"code": "INVALID_RESOURCE",
665+
"display": "Invalid validation of resource",
666+
}
667+
]
668+
},
669+
"diagnostics": "Multiple ASID identifiers provided. context.related must contain a single valid ASID identifier when content contains an SSP URL",
670+
"expression": ["context.related"],
580671
}

layer/nrlf/core/validators.py

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@ def validate_type_system(
2929
return type_system in pointer_type_systems
3030

3131

32-
def _is_ssp_content(content: producer_model.DocumentReferenceContent) -> bool:
33-
return content.attachment.url and content.attachment.url.startswith("ssp://")
34-
35-
36-
def _is_asid_reference(reference: producer_model.Reference) -> bool:
37-
return reference.identifier.system == "https://fhir.nhs.uk/Id/nhsSpineASID"
38-
39-
4032
@dataclass
4133
class ValidationResult:
4234
resource: DocumentReference
@@ -268,17 +260,16 @@ def _validate_ssp_asid(self, model: DocumentReference):
268260
Validate that the document contains a valid ASID in the context.related field when the content contains an SSP URL
269261
"""
270262

271-
ssp_content = next(
272-
filter(
273-
_is_ssp_content,
274-
model.content,
275-
),
276-
None,
263+
ssp_content = any(
264+
[
265+
content
266+
for content in model.content
267+
if content.attachment.url.startswith("ssp://")
268+
]
277269
)
278-
279270
if not ssp_content:
280271
logger.log(
281-
LogReference.VALIDATOR001, step="ssp_asid", reason="no_ssp_content"
272+
LogReference.VALIDATOR001a, step="ssp_asid", reason="no_ssp_content"
282273
)
283274
return
284275

@@ -288,33 +279,40 @@ def _validate_ssp_asid(self, model: DocumentReference):
288279
self.result.add_error(
289280
issue_code="required",
290281
error_code="INVALID_RESOURCE",
291-
diagnostics="Missing context.related. It must be provided and contain a valid ASID identifier when content contains an SSP URL",
282+
diagnostics="Missing context.related. It must be provided and contain a single valid ASID identifier when content contains an SSP URL",
292283
field="context.related",
293284
)
294-
raise StopValidationError()
285+
return
295286

296-
asid_reference = next(
297-
filter(
298-
_is_asid_reference,
299-
getattr(model.context, "related", []),
300-
),
301-
None,
302-
)
303-
if not asid_reference:
287+
asid_references = [
288+
(idx, related)
289+
for idx, related in enumerate(getattr(model.context, "related", []))
290+
if related.identifier.system == "https://fhir.nhs.uk/Id/nhsSpineASID"
291+
]
292+
if not asid_references:
304293
self.result.add_error(
305294
issue_code="required",
306295
error_code="INVALID_RESOURCE",
307-
diagnostics="Missing ASID identifier. context.related must contain a valid ASID identifier when content contains an SSP URL",
296+
diagnostics="Missing ASID identifier. context.related must contain a single valid ASID identifier when content contains an SSP URL",
308297
field="context.related",
309298
)
310-
raise StopValidationError()
299+
return
300+
if len(asid_references) > 1:
301+
self.result.add_error(
302+
issue_code="invalid",
303+
error_code="INVALID_RESOURCE",
304+
diagnostics="Multiple ASID identifiers provided. context.related must contain a single valid ASID identifier when content contains an SSP URL",
305+
field="context.related",
306+
)
307+
return
311308

309+
idx, asid_reference = asid_references[0]
312310
asid_value = getattr(asid_reference.identifier, "value", "")
313311
if not match(r"^\d{12}$", asid_value):
314312
self.result.add_error(
315313
issue_code="value",
316314
error_code="INVALID_IDENTIFIER_VALUE",
317-
diagnostics=f"Invalid ASID value {asid_value}. context.related must contain a valid ASID identifier when content contains an SSP URL",
318-
field="context.related[].identifier.value",
315+
diagnostics=f"Invalid ASID value '{asid_value}'. context.related must contain a single valid ASID identifier when content contains an SSP URL",
316+
field=f"context.related[{idx}].identifier.value",
319317
)
320-
raise StopValidationError()
318+
return

0 commit comments

Comments
 (0)