From 47cae167c803dc08eb76b7983bfb8e8bf0b744fc Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 16 Apr 2026 14:30:15 +0000 Subject: [PATCH] =?UTF-8?q?Load=20Conservatories,=20Renewables,=20RoomCoun?= =?UTF-8?q?tElements,=20WaterUse,=20CustomerReponse,=20SurveyAddendum=20fr?= =?UTF-8?q?om=20SiteNotes=20JSON=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/documents_parser/extractor.py | 25 +++++ .../documents_parser/tests/test_extractor.py | 101 ++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/backend/documents_parser/extractor.py b/backend/documents_parser/extractor.py index 9fffcf5a..a4d9bcc9 100644 --- a/backend/documents_parser/extractor.py +++ b/backend/documents_parser/extractor.py @@ -4,6 +4,8 @@ from typing import List, Optional from datatypes.epc.surveys.pashub_rdsap_site_notes import ( BuildingConstruction, BuildingMeasurements, + Conservatories, + CustomerResponse, ExtensionConstruction, ExtensionMeasurements, ExtensionRoofSpace, @@ -15,11 +17,16 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import ( MainBuildingMeasurements, MainHeating, PasHubRdSapSiteNotes, + Renewables, + RoomCountElements, RoofSpace, RoofSpaceDetail, SecondaryHeating, + Shower, + SurveyAddendum, Ventilation, WaterHeating, + WaterUse, Window, ) @@ -314,6 +321,24 @@ class PasHubRdSapSiteNotesExtractor: ), ) + def extract_conservatories(self) -> Conservatories: + raise NotImplementedError + + def extract_renewables(self) -> Renewables: + raise NotImplementedError + + def extract_room_count_elements(self) -> RoomCountElements: + raise NotImplementedError + + def extract_water_use(self) -> WaterUse: + raise NotImplementedError + + def extract_customer_response(self) -> CustomerResponse: + raise NotImplementedError + + def extract_addendum(self) -> SurveyAddendum: + raise NotImplementedError + def _parse_main_heating(self, data: List[str]) -> MainHeating: return MainHeating( selection_method=self._get_in(data, "How would you like to select the Heating System?") or "", diff --git a/backend/documents_parser/tests/test_extractor.py b/backend/documents_parser/tests/test_extractor.py index cf8f94d0..fc46f8ef 100644 --- a/backend/documents_parser/tests/test_extractor.py +++ b/backend/documents_parser/tests/test_extractor.py @@ -7,6 +7,8 @@ from backend.documents_parser.extractor import PasHubRdSapSiteNotesExtractor from datatypes.epc.surveys.pashub_rdsap_site_notes import ( BuildingConstruction, BuildingMeasurements, + Conservatories, + CustomerResponse, ExtensionConstruction, ExtensionMeasurements, ExtensionRoofSpace, @@ -18,11 +20,16 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import ( MainBuildingMeasurements, MainHeating, PasHubRdSapSiteNotes, + Renewables, + RoomCountElements, RoofSpace, RoofSpaceDetail, SecondaryHeating, + Shower, + SurveyAddendum, Ventilation, WaterHeating, + WaterUse, ) FIXTURES = os.path.join(os.path.dirname(__file__), "fixtures") @@ -442,3 +449,97 @@ class TestVentilation: draught_lobby=False, ventilation_in_pcdf_database=False, ) + + +class TestConservatories: + def test_full_conservatories(self) -> None: + result = PasHubRdSapSiteNotesExtractor( + load_text_fixture() + ).extract_conservatories() + assert result == Conservatories(has_conservatory=False) + + +class TestRenewables: + def test_number_of_pv_batteries_none_string_becomes_zero(self) -> None: + result = PasHubRdSapSiteNotesExtractor(load_text_fixture()).extract_renewables() + assert result.number_of_pv_batteries == 0 + + def test_full_renewables(self) -> None: + result = PasHubRdSapSiteNotesExtractor(load_text_fixture()).extract_renewables() + assert result == Renewables( + wind_turbines=False, + solar_hot_water=False, + photovoltaic_array=False, + number_of_pv_batteries=0, + hydro=False, + ) + + +class TestRoomCountElements: + @pytest.fixture + def rce(self) -> RoomCountElements: + return PasHubRdSapSiteNotesExtractor( + load_text_fixture() + ).extract_room_count_elements() + + def test_habitable_rooms(self, rce: RoomCountElements) -> None: + assert rce.number_of_habitable_rooms == 3 + + def test_heated_rooms_null(self, rce: RoomCountElements) -> None: + assert rce.number_of_heated_rooms is None + + def test_full_room_count_elements(self, rce: RoomCountElements) -> None: + assert rce == RoomCountElements( + number_of_habitable_rooms=3, + any_unheated_rooms=False, + number_of_heated_rooms=None, + number_of_external_doors=2, + number_of_insulated_external_doors=0, + number_of_draughtproofed_external_doors=2, + number_of_open_chimneys=0, + number_of_blocked_chimneys=0, + number_of_fixed_incandescent_bulbs=4, + exact_led_cfl_count_known=True, + number_of_fixed_led_bulbs=0, + number_of_fixed_cfl_bulbs=1, + waste_water_heat_recovery="None", + ) + + +class TestWaterUse: + def test_full_water_use(self) -> None: + result = PasHubRdSapSiteNotesExtractor(load_text_fixture()).extract_water_use() + assert result == WaterUse( + number_of_baths=1, + number_of_special_features=0, + showers=[Shower(id=1, outlet_type="Non-Electric Shower")], + ) + + +class TestCustomerResponse: + def test_full_customer_response(self) -> None: + result = PasHubRdSapSiteNotesExtractor( + load_text_fixture() + ).extract_customer_response() + assert result == CustomerResponse( + customer_present=True, + willing_to_answer_satisfaction_survey=False, + ) + + +class TestSurveyAddendum: + def test_hard_to_treat_flags(self) -> None: + result = PasHubRdSapSiteNotesExtractor(load_text_fixture()).extract_addendum() + assert result.hard_to_treat_cavity_access_issues is False + assert result.hard_to_treat_cavity_high_exposure is False + assert result.hard_to_treat_cavity_narrow_cavities is False + + def test_full_addendum(self) -> None: + result = PasHubRdSapSiteNotesExtractor(load_text_fixture()).extract_addendum() + assert result == SurveyAddendum( + addendum="None", + related_party_disclosure="No related party", + hard_to_treat_cavity_access_issues=False, + hard_to_treat_cavity_high_exposure=False, + hard_to_treat_cavity_narrow_cavities=False, + )