From 87922b622a848997b010ed4c809edbd98c7f0929 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 14 Jul 2026 23:24:47 +0000 Subject: [PATCH] =?UTF-8?q?Int-code=20the=20surveyed=20cylinder=20insulati?= =?UTF-8?q?on=20label=20for=20the=20storage-loss=20cascade=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../epc/domain/tests/test_from_site_notes.py | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/datatypes/epc/domain/tests/test_from_site_notes.py b/datatypes/epc/domain/tests/test_from_site_notes.py index 77c7ed4fd..2b89ab80d 100644 --- a/datatypes/epc/domain/tests/test_from_site_notes.py +++ b/datatypes/epc/domain/tests/test_from_site_notes.py @@ -297,6 +297,40 @@ class TestRoomInRoofMapping: ] +class TestCylinderInsulationTypeCoding: + """The surveyed cylinder "Insulation Type:" label must be int-coded for + the calculator's `cylinder_insulation_type` cascade ("Factory fitted" → + foam, code 1, mirroring Elmhurst "Foam"). Passed through raw, the + storage-loss resolver's `_int_or_none` yields None and a real lodged + cylinder is billed ZERO storage loss (fixture 507644414148 over-rates + by 1.4 SAP on this alone).""" + + def test_factory_fitted_codes_to_foam(self) -> None: + # Arrange — the fixture as lodged ("Factory fitted", Normal cylinder). + survey = from_dict( + PasHubRdSapSiteNotes, load("pashub_rdsap_site_notes_example1.json") + ) + + # Act + result = EpcPropertyDataMapper.from_site_notes(survey) + + # Assert + assert result.sap_heating is not None + assert result.sap_heating.cylinder_insulation_type == 1 + + def test_unknown_label_strict_raises(self) -> None: + # Arrange + data = load("pashub_rdsap_site_notes_example1.json") + data["heating_and_hot_water"]["water_heating"]["insulation_type"] = ( + "Sheep's wool wrap" + ) + survey = from_dict(PasHubRdSapSiteNotes, data) + + # Act / Assert + with pytest.raises(UnmappedPasHubLabel): + EpcPropertyDataMapper.from_site_notes(survey) + + class TestWallDryLinedMapping: """A surveyed "Wall Dry-Lined? Yes" must reach `sap_building_parts[*].wall_dry_lined` — the flag the wall-U cascade @@ -1290,7 +1324,7 @@ class TestFromSiteNotesExample1: ], has_fixed_air_conditioning=False, cylinder_size=2, # "Normal (90-130 litres)" → Table 28 code 2 - cylinder_insulation_type="Factory fitted", + cylinder_insulation_type=1, # "Factory fitted" → foam, SAP10 code 1 cylinder_insulation_thickness_mm=12, water_heating_code=901, # cylinder + "From main heating 1" → WHC 901 shower_outlets=ShowerOutlets(