diff --git a/backend/documents_parser/tests/test_extractor.py b/backend/documents_parser/tests/test_extractor.py index 438c8a74d..947c6e44d 100644 --- a/backend/documents_parser/tests/test_extractor.py +++ b/backend/documents_parser/tests/test_extractor.py @@ -21,6 +21,7 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import ( MainBuildingConstruction, MainBuildingMeasurements, MainHeating, + PvArrayDetail, Renewables, RoomCountElements, RoofSpace, @@ -646,6 +647,64 @@ class TestRenewablesPvConnection: assert renewables.percent_roof_covered_pv == 45 +class TestRenewablesPvArrays: + """When "Photovoltaic array kWp Known?" is Yes, the survey lodges a + per-system block ("Number of PV systems?", then "PV {n}: kWp value / + Photovoltaic Pitch / Orientation / Overshading") instead of the + percent-roof estimate. The extractor must capture it — dropped detail + silently zeroes the Appendix M PV credit (issue #1590 bug 1; verbatim + lines from accuracy fixture deal 507639151843). + """ + + # The real kWp-known block, verbatim from the 507639151843 site notes. + _KWP_KNOWN_BLOCK = [ + "Photovoltaic array kWp Known?", + "Yes", + "Number of PV systems?", + "1", + "PV 1: kWp value:", + "2.43 kWp", + "PV 1: Photovoltaic Pitch?", + "30 Degrees", + "PV 1: Photovoltaic Orientation?", + "South East", + "PV 1: Photovoltaic Overshading:", + "None or very little", + ] + + @pytest.fixture + def renewables(self) -> Renewables: + # Arrange — fixture 3's Renewables section with its "kWp Known? No + + # percent roof" block swapped for the real kWp-known block. + lines = load_text_fixture_3() + start = lines.index("Photovoltaic array kWp Known?") + end = lines.index("Number of PV batteries:") + spliced = lines[:start] + self._KWP_KNOWN_BLOCK + lines[end:] + return PasHubRdSapSiteNotesExtractor(spliced).extract_renewables() + + def test_pv_array_detail_is_captured(self, renewables: Renewables) -> None: + assert renewables.pv_arrays == [ + PvArrayDetail( + kwp=2.43, + pitch_degrees=30, + orientation="South East", + overshading="None or very little", + ) + ] + + def test_pv_diverter_is_captured(self, renewables: Renewables) -> None: + assert renewables.pv_diverter_present is False # fixture 3 lodges "No" + + def test_no_pv_block_leaves_arrays_absent(self) -> None: + # Arrange / Act — fixture 3 as lodged (kWp Known? No, percent path). + renewables = PasHubRdSapSiteNotesExtractor( + load_text_fixture_3() + ).extract_renewables() + + # Assert + assert renewables.pv_arrays is None + + class TestRoomCountElements: @pytest.fixture def rce(self) -> RoomCountElements: