From f9079eb0acaa9e824a48961a27a5cc890be40bea Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 14 Jul 2026 21:39:08 +0000 Subject: [PATCH] =?UTF-8?q?Resolve=20the=20PasHub=20PV=20Connection=20labe?= =?UTF-8?q?l=20to=20the=20gov-API=20credit-gate=20int=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../epc/domain/tests/test_from_site_notes.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/datatypes/epc/domain/tests/test_from_site_notes.py b/datatypes/epc/domain/tests/test_from_site_notes.py index 5d0c165c0..48094d833 100644 --- a/datatypes/epc/domain/tests/test_from_site_notes.py +++ b/datatypes/epc/domain/tests/test_from_site_notes.py @@ -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