Skip to content

Commit bfcd913

Browse files
committed
eli-579 reverting changes to registry
1 parent 122b6dc commit bfcd913

3 files changed

Lines changed: 111 additions & 74 deletions

File tree

poetry.lock

Lines changed: 10 additions & 53 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jsonpath-rw = "^1.4.0"
4343
semver = "^3.0.4"
4444
gitpython = "^3.1.45"
4545
pytest = "^8.4.2"
46-
pytest-asyncio = "^1.2.0"
46+
pytest-asyncio = "^1.3.0"
4747
pytest-cov = "^7.0.0"
4848
pytest-nhsd-apim = "^5.0.14"
4949
aiohttp = "^3.12.15"
@@ -62,7 +62,7 @@ jsonschema = "^4.25.1"
6262
behave = "^1.3.3"
6363
python-dotenv = "^1.2.1"
6464
openapi-spec-validator = "^0.7.2"
65-
pip-licenses = "^5.0.0"
65+
pip-licenses = "^5.5.0"
6666

6767

6868
[tool.poetry-plugin-lambda-build]

tests/unit/services/processors/test_derived_values.py

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from unittest.mock import MagicMock
22

33
import pytest
4+
from hamcrest import assert_that, empty, equal_to, is_
45

56
from eligibility_signposting_api.services.processors.derived_values import (
67
AddDaysHandler,
@@ -26,7 +27,7 @@ def test_calculate_adds_default_days_to_date(self):
2627
result = handler.calculate(context)
2728

2829
# 2025-01-01 + 91 days = 2025-04-02
29-
assert result == "20250402"
30+
assert_that(result, is_(equal_to("20250402")))
3031

3132
def test_calculate_with_function_args_override(self):
3233
"""Test that function args override default days."""
@@ -42,7 +43,7 @@ def test_calculate_with_function_args_override(self):
4243
result = handler.calculate(context)
4344

4445
# 2025-01-01 + 30 days = 2025-01-31
45-
assert result == "20250131"
46+
assert_that(result, is_(equal_to("20250131")))
4647

4748
def test_calculate_with_vaccine_specific_days(self):
4849
"""Test that vaccine-specific days are used when configured."""
@@ -61,7 +62,7 @@ def test_calculate_with_vaccine_specific_days(self):
6162
result = handler.calculate(context)
6263

6364
# 2025-01-01 + 365 days = 2026-01-01
64-
assert result == "20260101"
65+
assert_that(result, is_(equal_to("20260101")))
6566

6667
def test_calculate_with_date_format(self):
6768
"""Test that date format is applied to output."""
@@ -76,7 +77,7 @@ def test_calculate_with_date_format(self):
7677

7778
result = handler.calculate(context)
7879

79-
assert result == "02 April 2025"
80+
assert_that(result, is_(equal_to("02 April 2025")))
8081

8182
def test_calculate_returns_empty_when_source_not_found(self):
8283
"""Test that empty string is returned when source date not found."""
@@ -91,7 +92,7 @@ def test_calculate_returns_empty_when_source_not_found(self):
9192

9293
result = handler.calculate(context)
9394

94-
assert result == ""
95+
assert_that(result, is_(empty()))
9596

9697
def test_calculate_returns_empty_when_vaccine_not_found(self):
9798
"""Test that empty string is returned when vaccine type not found."""
@@ -106,7 +107,7 @@ def test_calculate_returns_empty_when_vaccine_not_found(self):
106107

107108
result = handler.calculate(context)
108109

109-
assert result == ""
110+
assert_that(result, is_(empty()))
110111

111112
def test_calculate_with_invalid_date_raises_error(self):
112113
"""Test that invalid date format raises ValueError."""
@@ -126,13 +127,13 @@ def test_get_source_attribute_maps_derived_to_source(self):
126127
"""Test that get_source_attribute maps derived attributes correctly."""
127128
handler = AddDaysHandler()
128129

129-
assert handler.get_source_attribute("NEXT_DOSE_DUE") == "LAST_SUCCESSFUL_DATE"
130+
assert_that(handler.get_source_attribute("NEXT_DOSE_DUE"), is_(equal_to("LAST_SUCCESSFUL_DATE")))
130131

131132
def test_get_source_attribute_returns_original_if_not_mapped(self):
132133
"""Test that unmapped attributes return themselves."""
133134
handler = AddDaysHandler()
134135

135-
assert handler.get_source_attribute("UNKNOWN_ATTR") == "UNKNOWN_ATTR"
136+
assert_that(handler.get_source_attribute("UNKNOWN_ATTR"), is_(equal_to("UNKNOWN_ATTR")))
136137

137138
def test_function_args_priority_over_vaccine_config(self):
138139
"""Test that function args take priority over vaccine-specific config."""
@@ -151,7 +152,86 @@ def test_function_args_priority_over_vaccine_config(self):
151152
result = handler.calculate(context)
152153

153154
# 2025-01-01 + 30 days = 2025-01-31
154-
assert result == "20250131"
155+
assert_that(result, is_(equal_to("20250131")))
156+
157+
def test_calculate_with_negative_days(self):
158+
"""Test that negative days subtracts from date."""
159+
handler = AddDaysHandler(default_days=91)
160+
context = DerivedValueContext(
161+
person_data=[{"ATTRIBUTE_TYPE": "COVID", "LAST_SUCCESSFUL_DATE": "20250110"}],
162+
attribute_name="COVID",
163+
source_attribute="LAST_SUCCESSFUL_DATE",
164+
function_args="-7",
165+
date_format=None,
166+
)
167+
168+
result = handler.calculate(context)
169+
170+
# 2025-01-10 - 7 days = 2025-01-03
171+
assert_that(result, is_(equal_to("20250103")))
172+
173+
def test_calculate_with_zero_days(self):
174+
"""Test that zero days returns the same date."""
175+
handler = AddDaysHandler(default_days=91)
176+
context = DerivedValueContext(
177+
person_data=[{"ATTRIBUTE_TYPE": "COVID", "LAST_SUCCESSFUL_DATE": "20250115"}],
178+
attribute_name="COVID",
179+
source_attribute="LAST_SUCCESSFUL_DATE",
180+
function_args="0",
181+
date_format=None,
182+
)
183+
184+
result = handler.calculate(context)
185+
186+
assert_that(result, is_(equal_to("20250115")))
187+
188+
def test_calculate_with_invalid_args_falls_back_to_default(self):
189+
"""Test that invalid (non-numeric) function args falls back to default days."""
190+
handler = AddDaysHandler(default_days=91)
191+
context = DerivedValueContext(
192+
person_data=[{"ATTRIBUTE_TYPE": "COVID", "LAST_SUCCESSFUL_DATE": "20250101"}],
193+
attribute_name="COVID",
194+
source_attribute="LAST_SUCCESSFUL_DATE",
195+
function_args="invalid", # Non-numeric, should fall back to default
196+
date_format=None,
197+
)
198+
199+
result = handler.calculate(context)
200+
201+
# 2025-01-01 + 91 days (default) = 2025-04-02
202+
assert_that(result, is_(equal_to("20250402")))
203+
204+
def test_calculate_crossing_year_boundary(self):
205+
"""Test adding days that crosses year boundary."""
206+
handler = AddDaysHandler(default_days=91)
207+
context = DerivedValueContext(
208+
person_data=[{"ATTRIBUTE_TYPE": "COVID", "LAST_SUCCESSFUL_DATE": "20251230"}],
209+
attribute_name="COVID",
210+
source_attribute="LAST_SUCCESSFUL_DATE",
211+
function_args="5",
212+
date_format=None,
213+
)
214+
215+
result = handler.calculate(context)
216+
217+
# 2025-12-30 + 5 days = 2026-01-04
218+
assert_that(result, is_(equal_to("20260104")))
219+
220+
def test_calculate_leap_year_handling(self):
221+
"""Test adding days from leap year date."""
222+
handler = AddDaysHandler(default_days=91)
223+
context = DerivedValueContext(
224+
person_data=[{"ATTRIBUTE_TYPE": "COVID", "LAST_SUCCESSFUL_DATE": "20240229"}],
225+
attribute_name="COVID",
226+
source_attribute="LAST_SUCCESSFUL_DATE",
227+
function_args="365",
228+
date_format=None,
229+
)
230+
231+
result = handler.calculate(context)
232+
233+
# 2024-02-29 + 365 days = 2025-02-28 (no Feb 29 in 2025)
234+
assert_that(result, is_(equal_to("20250228")))
155235

156236

157237
class TestDerivedValueRegistry:
@@ -165,29 +245,29 @@ def test_register_and_get_handler(self):
165245

166246
retrieved = registry.get_handler("ADD_DAYS")
167247

168-
assert retrieved is handler
248+
assert_that(retrieved, is_(handler))
169249

170250
def test_get_handler_case_insensitive(self):
171251
"""Test that handler lookup is case insensitive."""
172252
registry = DerivedValueRegistry()
173253
handler = AddDaysHandler()
174254
registry.register(handler)
175255

176-
assert registry.get_handler("add_days") is handler
177-
assert registry.get_handler("Add_Days") is handler
256+
assert_that(registry.get_handler("add_days"), is_(handler))
257+
assert_that(registry.get_handler("Add_Days"), is_(handler))
178258

179259
def test_has_handler_returns_true_when_exists(self):
180260
"""Test has_handler returns True for registered handlers."""
181261
registry = DerivedValueRegistry()
182262
registry.register(AddDaysHandler())
183263

184-
assert registry.has_handler("ADD_DAYS") is True
264+
assert_that(registry.has_handler("ADD_DAYS"), is_(True))
185265

186266
def test_has_handler_returns_false_when_not_exists(self):
187267
"""Test has_handler returns False for unregistered handlers."""
188268
registry = DerivedValueRegistry()
189269

190-
assert registry.has_handler("UNKNOWN") is False
270+
assert_that(registry.has_handler("UNKNOWN"), is_(False))
191271

192272
def test_calculate_delegates_to_correct_handler(self):
193273
"""Test that calculate delegates to the correct handler."""
@@ -215,7 +295,7 @@ def test_calculate_delegates_to_correct_handler(self):
215295

216296
# Verify the mock handler was called with the context
217297
mock_handler.calculate.assert_called_once_with(context)
218-
assert result == "mock_result"
298+
assert_that(result, is_(equal_to("mock_result")))
219299

220300
def test_calculate_raises_for_unknown_function(self):
221301
"""Test that calculate raises ValueError for unknown functions."""
@@ -240,21 +320,21 @@ def test_is_derived_attribute_returns_true_for_derived(self):
240320
registry = DerivedValueRegistry()
241321
registry.register(AddDaysHandler())
242322

243-
assert registry.is_derived_attribute("NEXT_DOSE_DUE") is True
323+
assert_that(registry.is_derived_attribute("NEXT_DOSE_DUE"), is_(True))
244324

245325
def test_is_derived_attribute_returns_false_for_non_derived(self):
246326
"""Test is_derived_attribute for non-derived attributes."""
247327
registry = DerivedValueRegistry()
248328
registry.register(AddDaysHandler())
249329

250-
assert registry.is_derived_attribute("LAST_SUCCESSFUL_DATE") is False
330+
assert_that(registry.is_derived_attribute("LAST_SUCCESSFUL_DATE"), is_(False))
251331

252332
def test_default_handlers_are_registered(self):
253333
"""Test that default handlers from the module are registered."""
254334
registry = DerivedValueRegistry()
255335

256336
# The default ADD_DAYS handler should be registered via __init__.py
257-
assert registry.has_handler("ADD_DAYS")
337+
assert_that(registry.has_handler("ADD_DAYS"), is_(True))
258338

259339
def test_clear_defaults_removes_default_handlers(self):
260340
"""Test that clear_defaults removes all default handlers."""
@@ -266,7 +346,7 @@ def test_clear_defaults_removes_default_handlers(self):
266346

267347
# New registry should have no handlers
268348
registry = DerivedValueRegistry()
269-
assert not registry.has_handler("ADD_DAYS")
349+
assert_that(registry.has_handler("ADD_DAYS"), is_(False))
270350
finally:
271351
# Restore defaults for other tests using public method
272352
DerivedValueRegistry.set_default_handlers(saved_defaults)

0 commit comments

Comments
 (0)