From 38e9ebd5c772e1255002ae08c8df21e066e75578 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 16 Jul 2026 16:04:05 +0000 Subject: [PATCH] =?UTF-8?q?Rate=20MVHR=20dwellings=20via=20Table=204g=20an?= =?UTF-8?q?d=20biomass=20heat=20networks=20via=20Table=2012=20code=2043=20?= =?UTF-8?q?=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 | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/datatypes/epc/domain/tests/test_from_site_notes.py b/datatypes/epc/domain/tests/test_from_site_notes.py index d65bf2ee4..16ad4f4d8 100644 --- a/datatypes/epc/domain/tests/test_from_site_notes.py +++ b/datatypes/epc/domain/tests/test_from_site_notes.py @@ -157,6 +157,30 @@ class TestCommunityHeatingMapping: assert main.sap_main_heating_code == 301 assert main.main_fuel_type == 51 + def test_community_biomass_boilers_lodge_table_12_biomass_fuel(self) -> None: + # Arrange — PasHub renders the community fuel with the Table 12 row + # wording (`Heat from boilers - biomass`), unlike the Elmhurst §14.1 + # labels (`Biomass`). + data = load("pashub_rdsap_site_notes_example1.json") + mh = data["heating_and_hot_water"]["main_heating"] + mh["system_type"] = "Community heating system" + mh["community_heat_source"] = "Community heating - boilers only" + mh["fuel"] = "Heat from boilers - biomass" + mh["controls"] = ( + "Charging system linked to use of community heating, room thermostat only" + ) + mh["product_id"] = 0 + survey = from_dict(PasHubRdSapSiteNotes, data) + + # Act + main = EpcPropertyDataMapper.from_site_notes( + survey + ).sap_heating.main_heating_details[0] + + # Assert — Table 12 code 43 (heat from boilers — biomass). + assert main.sap_main_heating_code == 301 + assert main.main_fuel_type == 43 + def test_unknown_heat_source_strict_raises(self) -> None: # Arrange data = load("pashub_rdsap_site_notes_example1.json") @@ -170,6 +194,22 @@ class TestCommunityHeatingMapping: with pytest.raises(UnmappedPasHubLabel, match="community heat source"): EpcPropertyDataMapper.from_site_notes(survey) + def test_unknown_community_fuel_strict_raises(self) -> None: + # Arrange — a recognised heat source with an uncovered fuel label. It + # must strict-raise at the boundary rather than pass the raw string + # through to the calculator's deep `MissingMainFuelType` (ADR-0015). + data = load("pashub_rdsap_site_notes_example1.json") + mh = data["heating_and_hot_water"]["main_heating"] + mh["system_type"] = "Community heating system" + mh["community_heat_source"] = "Community heating - boilers only" + mh["fuel"] = "Some novel fuel" + mh["controls"] = "" + survey = from_dict(PasHubRdSapSiteNotes, data) + + # Act / Assert + with pytest.raises(UnmappedPasHubLabel, match="community fuel"): + EpcPropertyDataMapper.from_site_notes(survey) + class TestRoomInRoofMapping: """A surveyed room-in-roof block (RdSAP §3.10 detailed measurement) must @@ -833,6 +873,7 @@ class TestMechanicalVentilationKindCoding: ("Mechanical Extract - Centralised", "EXTRACT_OR_PIV_OUTSIDE"), ("Positive Input - From Outside", "EXTRACT_OR_PIV_OUTSIDE"), ("Positive Input - From Loft (As Natural)", None), + ("MV - Heat Recovery", "MVHR"), ], ) def test_label_maps_to_mechanical_kind(