Skip to content

Commit 7d9c772

Browse files
committed
add future date check for birth date
1 parent 389b63a commit 7d9c772

File tree

5 files changed

+30
-11
lines changed

5 files changed

+30
-11
lines changed

backend/src/models/fhir_immunization_pre_validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ def pre_validate_expiration_date(self, values: dict) -> dict:
729729
"""
730730
try:
731731
field_value = values["expirationDate"]
732-
PreValidation.for_date(field_value, "expirationDate")
732+
PreValidation.for_date(field_value, "expirationDate", future_date_allowed=True)
733733
except KeyError:
734734
pass
735735

backend/src/models/utils/pre_validator_utils.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def for_list(
8383
raise ValueError(f"{field_location} must be an array of non-empty objects")
8484

8585
@staticmethod
86-
def for_date(field_value: str, field_location: str):
86+
def for_date(field_value: str, field_location: str, future_date_allowed: bool = False):
8787
"""
8888
Apply pre-validation to a date field to ensure that it is a string (JSON dates must be
8989
written as strings) containing a valid date in the format "YYYY-MM-DD"
@@ -98,8 +98,9 @@ def for_date(field_value: str, field_location: str):
9898
f'{field_location} must be a valid date string in the format "YYYY-MM-DD"'
9999
) from value_error
100100

101-
# Enforce not-in-the-future rule using central checker
102-
PreValidation.check_if_future_date(parsed_date)
101+
# Enforce not-in-the-future rule using central checker (after successful parse)
102+
if not future_date_allowed and PreValidation.check_if_future_date(parsed_date):
103+
raise ValueError(f"{field_location} must not be in the future")
103104

104105
@staticmethod
105106
def for_date_time(field_value: str, field_location: str, strict_timezone: bool = True):
@@ -139,13 +140,15 @@ def for_date_time(field_value: str, field_location: str, strict_timezone: bool =
139140
for fmt in formats:
140141
try:
141142
fhir_date = datetime.strptime(field_value, fmt)
142-
143+
# After successful parse, enforce timezone and future-date rules
143144
if strict_timezone and fhir_date.tzinfo is not None:
144-
if PreValidation.check_if_future_date(fhir_date):
145-
raise ValueError(error_message)
146-
if not any(field_value.endswith(suffix) for suffix in allowed_suffixes):
147-
raise ValueError(error_message)
148-
# Enforce not-in-the-future rule using central checker
145+
if not any(field_value.endswith(suffix) for suffix in allowed_suffixes):
146+
raise ValueError(error_message)
147+
148+
# Enforce not-in-the-future rule using central checker (after successful parse)
149+
if PreValidation.check_if_future_date(fhir_date):
150+
raise ValueError(f"{field_location} must not be in the future")
151+
149152
return fhir_date.isoformat()
150153
except ValueError:
151154
continue

backend/tests/test_immunization_pre_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ def test_pre_validate_lot_number(self):
11041104

11051105
def test_pre_validate_expiration_date(self):
11061106
"""Test pre_validate_expiration_date accepts valid values and rejects invalid values"""
1107-
ValidatorModelTests.test_date_value(self, field_location="expirationDate")
1107+
ValidatorModelTests.test_date_value(self, field_location="expirationDate", is_future_date_allowed=True)
11081108

11091109
def test_pre_validate_site_coding(self):
11101110
"""Test pre_validate_site_coding accepts valid values and rejects invalid values"""

backend/tests/utils/pre_validation_test_utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def test_unique_list(
282282
def test_date_value(
283283
test_instance: unittest.TestCase,
284284
field_location: str,
285+
is_future_date_allowed: bool = False,
285286
):
286287
"""
287288
Test that a FHIR model accepts valid date values and rejects the following invalid values:
@@ -314,6 +315,15 @@ def test_date_value(
314315
invalid_value=invalid_date_format,
315316
expected_error_message=f"{field_location} must be a valid date string in the " + 'format "YYYY-MM-DD"',
316317
)
318+
if not is_future_date_allowed:
319+
for invalid_date_format in InvalidValues.for_future_dates:
320+
test_invalid_values_rejected(
321+
test_instance,
322+
valid_json_data,
323+
field_location=field_location,
324+
invalid_value=invalid_date_format,
325+
expected_error_message=f"{field_location} must not be in the future",
326+
)
317327

318328
@staticmethod
319329
def test_date_time_value(

backend/tests/utils/values_for_tests.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ class InvalidValues:
291291
"2000-02-30", # Invalid combination of month and day
292292
]
293293

294+
for_future_dates = [
295+
"2100-01-01", # Year in future
296+
"2050-12-31", # Year in future
297+
"2029-06-15", # Year in future
298+
]
299+
294300
# Strings which are not in acceptable date time format
295301
for_date_time_string_formats_for_relaxed_timezone = [
296302
"", # Empty string

0 commit comments

Comments
 (0)