From 5276b4583687de7432f2e282945246f8b9adb152 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 15 Jul 2026 08:45:22 +0000 Subject: [PATCH] =?UTF-8?q?Int-code=20the=20surveyed=20window=20orientatio?= =?UTF-8?q?n=20to=20its=20SAP10=20octant=20code=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../epc/domain/tests/test_from_site_notes.py | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/datatypes/epc/domain/tests/test_from_site_notes.py b/datatypes/epc/domain/tests/test_from_site_notes.py index 78eb89da0..cd0d35de7 100644 --- a/datatypes/epc/domain/tests/test_from_site_notes.py +++ b/datatypes/epc/domain/tests/test_from_site_notes.py @@ -405,6 +405,55 @@ class TestCylinderInsulationTypeCoding: EpcPropertyDataMapper.from_site_notes(survey) +class TestWindowOrientationCoding: + """`from_site_notes` must int-code the PAS Hub window `orientation` label + to the SAP 10.2 octant code (1..8) the solar-gains cascade consumes. + `_orientation` in `solar_gains.py` returns None for a non-int and the + window is then skipped for solar gain entirely — so a raw string zeroes + EVERY window's solar contribution (100% of the Guinness cohort; the + single largest accuracy lever). PasHub lodges it space-separated + ("South East") where the shared octant map keys hyphenated. + """ + + @pytest.mark.parametrize( + "label, expected_code", + [ + ("North", 1), + ("North East", 2), + ("East", 3), + ("South East", 4), + ("South", 5), + ("South West", 6), + ("West", 7), + ("North West", 8), + ], + ) + def test_label_maps_to_octant( + self, label: str, expected_code: int + ) -> None: + data = load("pashub_rdsap_site_notes_example1.json") + data["windows"][0]["orientation"] = label + survey = from_dict(PasHubRdSapSiteNotes, data) + result = EpcPropertyDataMapper.from_site_notes(survey) + assert result.sap_windows[0].orientation == expected_code + + def test_blank_orientation_stays_none(self) -> None: + # A window with no lodged orientation degrades to None (the cascade + # skips it) — NOT a strict-raise, NOT a default octant. + data = load("pashub_rdsap_site_notes_example1.json") + data["windows"][0]["orientation"] = "" + survey = from_dict(PasHubRdSapSiteNotes, data) + result = EpcPropertyDataMapper.from_site_notes(survey) + assert result.sap_windows[0].orientation is None + + def test_unknown_orientation_strict_raises(self) -> None: + data = load("pashub_rdsap_site_notes_example1.json") + data["windows"][0]["orientation"] = "Sou'-sou'-west" + survey = from_dict(PasHubRdSapSiteNotes, data) + 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 @@ -1260,7 +1309,9 @@ class TestFromSiteNotesExample1: assert result.sap_windows[0].draught_proofed is True def test_window_orientation(self, result: EpcPropertyData) -> None: - assert result.sap_windows[0].orientation == "South East" + # "South East" → SAP10 octant code 4 (the solar-gains cascade reads + # orientation as an int; a raw string silently zeroes the gain). + assert result.sap_windows[0].orientation == 4 def test_window_glazing_type(self, result: EpcPropertyData) -> None: # windows[].glazing_type: "Double glazing, Unknown install date" @@ -1468,7 +1519,7 @@ class TestFromSiteNotesExample1: SapWindow( frame_material="Wooden or PVC", glazing_gap="16 mm or more", - orientation="South East", + orientation=4, # "South East" → SAP10 octant 4 window_type="Window", glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3 window_width=1.0, @@ -1481,7 +1532,7 @@ class TestFromSiteNotesExample1: SapWindow( frame_material="Wooden or PVC", glazing_gap="16 mm or more", - orientation="South East", + orientation=4, # "South East" → SAP10 octant 4 window_type="Window", glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3 window_width=0.96, @@ -1494,7 +1545,7 @@ class TestFromSiteNotesExample1: SapWindow( frame_material="Wooden or PVC", glazing_gap="16 mm or more", - orientation="North West", + orientation=8, # "North West" → SAP10 octant 8 window_type="Window", glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3 window_width=0.96, @@ -1507,7 +1558,7 @@ class TestFromSiteNotesExample1: SapWindow( frame_material="Wooden or PVC", glazing_gap="16 mm or more", - orientation="North West", + orientation=8, # "North West" → SAP10 octant 8 window_type="Window", glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3 window_width=0.97,