Resolve the PasHub PV Connection label to the gov-API credit-gate int 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 21:39:08 +00:00
parent f92d4f26b8
commit f9079eb0ac

View file

@ -122,6 +122,59 @@ class TestPhotovoltaicArrayMapping:
assert result.sap_energy_source.photovoltaic_arrays is None
class TestPvConnectionCoding:
"""The surveyed "PV Connection" label must resolve to the gov-API int enum
the calculator's credit gate keys off (`_pv_connected_to_dwelling_meter`:
only int 2 earns the Appendix M credit; int 1 is "present but NOT connected"
zero credit). The raw string fell through the gate's non-int branch to
True, crediting PV a dwelling doesn't get to count (issue #1590 bug 3;
fixture 499516101839 over-rates by ~6.9 SAP).
"""
@pytest.mark.parametrize(
"label, expected_code",
[
("Not connected to electricity meter", 1),
("Connected to dwellings electricity meter", 2),
],
)
def test_label_maps_to_gov_api_code(
self, label: str, expected_code: int
) -> None:
# Arrange
data = load("pashub_rdsap_site_notes_example1.json")
data["renewables"]["pv_connection"] = label
survey = from_dict(PasHubRdSapSiteNotes, data)
# Act
result = EpcPropertyDataMapper.from_site_notes(survey)
# Assert
assert result.sap_energy_source.pv_connection == expected_code
def test_absent_connection_stays_absent(self) -> None:
# Arrange — no PV Connection lodged (fixture default).
survey = from_dict(
PasHubRdSapSiteNotes, load("pashub_rdsap_site_notes_example1.json")
)
# Act
result = EpcPropertyDataMapper.from_site_notes(survey)
# Assert
assert result.sap_energy_source.pv_connection is None
def test_unknown_label_strict_raises(self) -> None:
# Arrange
data = load("pashub_rdsap_site_notes_example1.json")
data["renewables"]["pv_connection"] = "Some novel connection"
survey = from_dict(PasHubRdSapSiteNotes, data)
# Act / Assert
with pytest.raises(UnmappedPasHubLabel, match="PV connection"):
EpcPropertyDataMapper.from_site_notes(survey)
class TestRoofInsulationNoneCoding:
"""A surveyed roof-space "Insulation At: None" is the assessor explicitly
recording ZERO loft insulation `from_site_notes` must lodge an explicit