From 1debf5f5a3871303419d1d2ffe041ee7b0111887 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 1 Jul 2026 14:02:18 +0000 Subject: [PATCH] =?UTF-8?q?Assert=20every=20water-heating=20reclassify=20t?= =?UTF-8?q?arget=20round-trips=20to=20a=20resolvable=20archetype=20?= =?UTF-8?q?=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) --- .../scripts/test_reclassify_water_heating.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/scripts/test_reclassify_water_heating.py b/tests/scripts/test_reclassify_water_heating.py index f59e6d200..c6534a2f6 100644 --- a/tests/scripts/test_reclassify_water_heating.py +++ b/tests/scripts/test_reclassify_water_heating.py @@ -4,6 +4,11 @@ and already-correct rows alone, and is idempotent (#1376 / ADR-0043).""" from __future__ import annotations +from domain.epc.property_overlays.water_heating_overlay import ( + water_heating_overlay_for, +) +from domain.epc.property_overrides.water_heating_guard import water_heating_guard +from domain.epc.property_overrides.water_heating_type import WaterHeatingType from scripts.reclassify_water_heating import water_heating_corrections @@ -58,6 +63,34 @@ def test_house_coal_bucket_rows_are_remapped_to_faithful_fuels() -> None: } +def test_every_guard_target_round_trips_to_a_resolvable_archetype() -> None: + # The reclassify decides via the guard; every archetype the guard can emit for + # the house-coal bucket must be a real member that decodes to SAP water-heating + # codes — a guard/overlay drift can't silently write an unmodellable value to + # the DB (ADR-0043). + house_coal_bucket = [ + "from main heating system: wood logs", + "from main heating system: dual fuel: mineral and wood", + "hot-water only community scheme - boilers: biomass (community)", + "hot-water only community scheme - boilers: heat from boilers using " + "biodiesel from any source (community)", + "no hot water system present - electric immersion assumed: " + "no heating or hot water", + "from main heating system: house coal", + ] + + for description in house_coal_bucket: + member = water_heating_guard(description) + + assert member is not None, description + assert member in WaterHeatingType, description + simulation = water_heating_overlay_for(member.value, 0) + assert simulation is not None, description + assert simulation.heating is not None, description + assert simulation.heating.water_heating_code is not None, description + assert simulation.heating.water_heating_fuel is not None, description + + def test_already_corrected_rows_need_no_change() -> None: # Act / Assert — idempotent: a re-run against corrected data is a no-op. assert (