Skip to content

Commit a4204e8

Browse files
committed
VED-350: Dose Unit code logic and test
1 parent 60e70fb commit a4204e8

File tree

5 files changed

+67
-23
lines changed

5 files changed

+67
-23
lines changed

backend/src/models/fhir_immunization_pre_validators.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def validate(self):
8585
self.pre_validate_route_coding_display,
8686
self.pre_validate_dose_quantity_value,
8787
self.pre_validate_dose_quantity_code,
88+
self.pre_validate_dose_quantity_system,
89+
self.pre_validate_dose_quantity_system_and_code,
8890
self.pre_validate_dose_quantity_unit,
8991
self.pre_validate_reason_code_codings,
9092
self.pre_validate_reason_code_coding_codes,
@@ -814,27 +816,17 @@ def pre_validate_dose_quantity_value(self, values: dict) -> dict:
814816
PreValidation.for_integer_or_decimal(field_value, "doseQuantity.value")
815817
except KeyError:
816818
pass
817-
818-
def pre_validate_dose_quantity_system_and_code(self, values: dict) -> dict:
819+
820+
def pre_validate_dose_quantity_system(self, values: dict) -> dict:
819821
"""
820-
Pre-validate doseQuantity.code and doseQuantity.system:
821-
1. If code exists, it must be a non-empty string (legacy CSV: DOSE_UNIT_CODE).
822-
2. If system exists, it must be a non-empty string.
823-
3. If code exists, system MUST also exist (FHIR SimpleQuantity rule).
822+
Pre-validate that if doseQuantity.system exists then it is a non-empty string:
823+
If system exists, it must be a non-empty string.
824824
"""
825-
field_value = values.get("doseQuantity", {})
826-
code = field_value.get("code")
827-
system = field_value.get("system")
828-
829-
if code is not None:
830-
PreValidation.for_string(code, "doseQuantity.code")
831-
832-
if system is not None:
833-
PreValidation.for_string(system, "doseQuantity.system")
834-
835-
PreValidation.require_system_when_code_present(
836-
code, system, "doseQuantity.code", "doseQuantity.system"
837-
)
825+
try:
826+
field_value = values["doseQuantity"]["system"]
827+
PreValidation.for_string(field_value, "doseQuantity.system")
828+
except KeyError:
829+
pass
838830

839831
def pre_validate_dose_quantity_code(self, values: dict) -> dict:
840832
"""
@@ -847,6 +839,21 @@ def pre_validate_dose_quantity_code(self, values: dict) -> dict:
847839
except KeyError:
848840
pass
849841

842+
def pre_validate_dose_quantity_system_and_code(self, values: dict) -> dict:
843+
"""
844+
Pre-validate doseQuantity.code and doseQuantity.system:
845+
1. If code exists, system MUST also exist (FHIR SimpleQuantity rule).
846+
"""
847+
dose_quantity = values.get("doseQuantity", {})
848+
code = dose_quantity.get("code")
849+
system = dose_quantity.get("system")
850+
851+
PreValidation.require_system_when_code_present(
852+
code, system, "doseQuantity.code", "doseQuantity.system"
853+
)
854+
855+
return values
856+
850857
def pre_validate_dose_quantity_unit(self, values: dict) -> dict:
851858
"""
852859
Pre-validate that, if doseQuantity.unit (legacy CSV field name: DOSE_UNIT_TERM) exists,

backend/src/models/utils/pre_validator_utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ def for_integer_or_decimal(field_value: Union[int, Decimal], field_location: str
198198
@staticmethod
199199
def require_system_when_code_present(
200200
code_value:str,
201-
system_value:str
201+
system_value:str,
202+
code_location,
203+
system_location,
202204
):
203205
"""
204206
If code is present (non-empty), system must also be present (non-empty).

backend/tests/test_immunization_pre_validator.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,11 +1140,36 @@ def test_pre_validate_dose_quantity_value(self):
11401140
Decimal("1.123456789"), # 9 decimal place
11411141
],
11421142
)
1143+
def test_pre_validate_dose_quantity_system(self):
1144+
"""Test pre_validate_dose_quantity_system accepts valid values and rejects invalid values"""
11431145

1146+
system_location = "doseQuantity.system"
1147+
ValidatorModelTests.test_string_value(self, system_location, valid_strings_to_test=["http://unitsofmeasure.org"])
1148+
11441149
def test_pre_validate_dose_quantity_code(self):
11451150
"""Test pre_validate_dose_quantity_code accepts valid values and rejects invalid values"""
1146-
field_location = "doseQuantity.code"
1147-
ValidatorModelTests.test_string_value(self, field_location, valid_strings_to_test=["ABC123"])
1151+
1152+
code_location = "doseQuantity.code"
1153+
ValidatorModelTests.test_string_value(self, code_location, valid_strings_to_test=["ABC123"])
1154+
1155+
def test_pre_validate_dose_quantity_system_and_code(self):
1156+
"""Test pre_validate_dose_quantity_system_and_code accepts valid values and rejects invalid values"""
1157+
1158+
field_location = "doseQuantity"
1159+
_test_valid_values_accepted(
1160+
self,
1161+
valid_json_data=deepcopy(self.json_data),
1162+
field_location=field_location,
1163+
valid_values_to_test=ValidValues.valid_dose_quantity,
1164+
)
1165+
1166+
_test_invalid_values_rejected(
1167+
self,
1168+
valid_json_data=deepcopy(self.json_data),
1169+
field_location=field_location,
1170+
invalid_value=InvalidValues.invalid_dose_quantity,
1171+
expected_error_message="If doseQuantity.code is present, doseQuantity.system must also be present"
1172+
)
11481173

11491174
def test_pre_validate_dose_quantity_unit(self):
11501175
"""Test pre_validate_dose_quantity_unit accepts valid values and rejects invalid values"""

backend/tests/utils/generic_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_invalid_values_rejected(
7272
invalid_json_data = parse(field_location).update(valid_json_data, invalid_value)
7373

7474
# Test that correct error type is raised
75-
with test_instance.assertRaises(ValueError or TypeError) as error:
75+
with test_instance.assertRaises((ValueError, TypeError)) as error:
7676
test_instance.validator.validate(invalid_json_data)
7777

7878
full_error_message = str(error.exception)

backend/tests/utils/values_for_tests.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ class ValidValues:
5555
# Not a valid snomed code, but is valid coding format for format testing
5656
snomed_coding_element = {"system": "http://snomed.info/sct", "code": "ABC123", "display": "test"}
5757

58+
valid_dose_quantity = [
59+
{"value": 3, "unit": "milliliter", "system": "http://unitsofmeasure.org", "code": "ml"},
60+
{"value": 2, "unit": "ml", "system": "http://snomed.info/sct", "code": "258773002"},
61+
{"value": 4, "unit": "ml", "system": "http://snomed.info/sct"},
62+
{"value": 5, "unit": "ml" }
63+
]
64+
5865
manufacturer_resource_id_Man1 = {"resourceType": "Manufacturer", "id": "Man1"}
5966

6067
practitioner_resource_id_Pract1 = {"resourceType": "Practitioner", "id": "Pract1"}
@@ -377,3 +384,6 @@ class InvalidValues:
377384
{"use": "official", "given": ["Florence"]},
378385
{"family": "Nightingale", "given": ""},
379386
]
387+
388+
invalid_dose_quantity = {"value": 2, "unit": "ml", "code": "258773002"}
389+

0 commit comments

Comments
 (0)