diff --git a/backend/src/models/fhir_immunization_pre_validators.py b/backend/src/models/fhir_immunization_pre_validators.py index d40d977ac..f9511b098 100644 --- a/backend/src/models/fhir_immunization_pre_validators.py +++ b/backend/src/models/fhir_immunization_pre_validators.py @@ -310,15 +310,18 @@ def pre_validate_patient_name_given(self, values: dict) -> dict: except (KeyError, IndexError, AttributeError): pass + PERSON_SURNAME_MAX_LENGTH = 35 + def pre_validate_patient_name_family(self, values: dict) -> dict: """ Pre-validate that, if a contained[?(@.resourceType=='Patient')].name[{index}].family (legacy CSV field name: - PERSON_SURNAME) exists, index dynamically determined then it is a an array containing a single non-empty string + PERSON_SURNAME) exists, index dynamically determined then it is a non-empty string of maximum length + 35 characters """ field_location = patient_name_family_field_location(values) try: field_value, _ = patient_and_practitioner_value_and_index(values, "family", "Patient") - PreValidation.for_string(field_value, field_location) + PreValidation.for_string(field_value, field_location, max_length=self.PERSON_SURNAME_MAX_LENGTH) except (KeyError, IndexError, AttributeError): pass diff --git a/backend/src/models/utils/pre_validator_utils.py b/backend/src/models/utils/pre_validator_utils.py index 793d86f92..9db92ea60 100644 --- a/backend/src/models/utils/pre_validator_utils.py +++ b/backend/src/models/utils/pre_validator_utils.py @@ -23,6 +23,9 @@ def for_string( if not isinstance(field_value, str): raise TypeError(f"{field_location} must be a string") + if field_value.isspace(): + raise ValueError(f"{field_location} must be a non-empty string") + if defined_length: if len(field_value) != defined_length: raise ValueError(f"{field_location} must be {defined_length} characters") diff --git a/backend/tests/test_immunization_pre_validator.py b/backend/tests/test_immunization_pre_validator.py index 704bb6832..5225048ed 100644 --- a/backend/tests/test_immunization_pre_validator.py +++ b/backend/tests/test_immunization_pre_validator.py @@ -506,7 +506,9 @@ def test_pre_validate_patient_name_family(self): ValidatorModelTests.test_string_value( self, field_location=patient_name_family_field_location(valid_json_data), - valid_strings_to_test=["test"], + valid_strings_to_test=["test", "Quitelongsurname", "Surnamewithjustthirtyfivecharacters"], + max_length=PreValidators.PERSON_SURNAME_MAX_LENGTH, + invalid_length_strings_to_test=["Surnamethathasgotthirtysixcharacters"], ) def test_pre_validate_patient_birth_date(self): diff --git a/backend/tests/testing_utils/pre_validation_test_utils.py b/backend/tests/testing_utils/pre_validation_test_utils.py index 2abd1c0ac..4276e1a90 100644 --- a/backend/tests/testing_utils/pre_validation_test_utils.py +++ b/backend/tests/testing_utils/pre_validation_test_utils.py @@ -76,6 +76,16 @@ def test_string_value( expected_error_message=f"{field_location} must be a string", ) + # Test whitespace + for invalid_whitespace_string in InvalidValues.for_whitespace_strings: + test_invalid_values_rejected( + test_instance, + valid_json_data, + field_location=field_location, + invalid_value=invalid_whitespace_string, + expected_error_message=f"{field_location} must be a non-empty string", + ) + # If there is a predefined string length, then test invalid string lengths, # otherwise check the empty string only if defined_length: diff --git a/backend/tests/testing_utils/values_for_tests.py b/backend/tests/testing_utils/values_for_tests.py index ed32e990c..9080419eb 100644 --- a/backend/tests/testing_utils/values_for_tests.py +++ b/backend/tests/testing_utils/values_for_tests.py @@ -319,6 +319,12 @@ class Invalid: class InvalidValues: """Store lists of invalid values for tests""" + for_whitespace_strings = [ + " ", # All spaces + " \n ", # Spaces and newlines + "\r\n\t", # CR, LF and tabs + ] + for_postal_codes = [ "SW1 1AA", # Too many spaces in divider "SW 1 1A", # Too many space dividers