From 9d0d12c278ccd8b100591f6eeb50b0262b26d2db Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 19 Jun 2026 14:10:02 +0000 Subject: [PATCH] =?UTF-8?q?Lock=20heating-override=20value=20coverage=20an?= =?UTF-8?q?d=20reader/overlay=20registry=20parity=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../epc/test_main_heating_system_overlay.py | 15 ++++++++++++ .../domain/epc/test_water_heating_overlay.py | 14 +++++++++++ .../test_override_component_consistency.py | 24 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/repositories/property/test_override_component_consistency.py diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index 0710837e..e161dbf5 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -8,6 +8,7 @@ from __future__ import annotations import pytest +from domain.epc.main_heating_system_type import MainHeatingSystemType from domain.epc.property_overlays.main_fuel_overlay import fuel_overlay_for from domain.epc.property_overlays.main_heating_system_overlay import ( main_heating_overlay_for, @@ -103,3 +104,17 @@ def test_the_three_heating_overrides_compose_without_conflict() -> None: assert main.sap_main_heating_code == 404 assert result.sap_heating.water_heating_code == 903 assert result.sap_heating.water_heating_fuel == 29 + + +@pytest.mark.parametrize( + "member", + [m for m in MainHeatingSystemType if m is not MainHeatingSystemType.UNKNOWN], +) +def test_every_resolvable_main_heating_value_decodes( + member: MainHeatingSystemType, +) -> None: + # Act + simulation = main_heating_overlay_for(member.value, 0) + + # Assert + assert simulation is not None diff --git a/tests/domain/epc/test_water_heating_overlay.py b/tests/domain/epc/test_water_heating_overlay.py index 7dd8c2d0..6e0b1fdb 100644 --- a/tests/domain/epc/test_water_heating_overlay.py +++ b/tests/domain/epc/test_water_heating_overlay.py @@ -11,6 +11,7 @@ import pytest from domain.epc.property_overlays.water_heating_overlay import ( water_heating_overlay_for, ) +from domain.epc.water_heating_type import WaterHeatingType from domain.modelling.scoring.overlay_applicator import apply_simulations from tests.domain.sap10_calculator.worksheet._elmhurst_worksheet_000490 import ( build_epc, @@ -71,3 +72,16 @@ def test_water_heating_override_remaps_the_hot_water_arrangement() -> None: # Assert — the calculator reads these off sap_heating. assert result.sap_heating.water_heating_code == 903 assert result.sap_heating.water_heating_fuel == 29 + + +@pytest.mark.parametrize( + "member", [m for m in WaterHeatingType if m is not WaterHeatingType.UNKNOWN] +) +def test_every_resolvable_water_heating_value_decodes( + member: WaterHeatingType, +) -> None: + # Act + simulation = water_heating_overlay_for(member.value, 0) + + # Assert + assert simulation is not None diff --git a/tests/repositories/property/test_override_component_consistency.py b/tests/repositories/property/test_override_component_consistency.py new file mode 100644 index 00000000..df830cd0 --- /dev/null +++ b/tests/repositories/property/test_override_component_consistency.py @@ -0,0 +1,24 @@ +"""Every override component must be wired through the WHOLE chain. + +The finaliser reader (`_ROW_TYPES`, component -> landlord table) and the overlay +registry (`_COMPONENT_OVERLAYS`, component -> overlay mapper) must cover exactly +the same set of components. If a component is classified + stored but has no +reader entry, the finaliser silently never writes its `property_overrides` rows; +if it has no overlay entry, the row never reaches the calculator. This guard +keeps the two registries in lock-step (it would have caught the missing +main_fuel / glazing / construction_age_band reader entries). +""" + +from __future__ import annotations + +from infrastructure.landlord_overrides.landlord_override_reader_postgres_repository import ( # pyright: ignore[reportPrivateUsage] + _ROW_TYPES, +) +from repositories.property.landlord_override_overlays import ( # pyright: ignore[reportPrivateUsage] + _COMPONENT_OVERLAYS, +) + + +def test_reader_and_overlay_registries_cover_the_same_components() -> None: + # Assert + assert set(_ROW_TYPES) == set(_COMPONENT_OVERLAYS)