Int-code the surveyed cylinder insulation label for the storage-loss cascade 🟥

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 23:24:47 +00:00
parent 5a7ff6de1c
commit 87922b622a

View file

@ -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(