"""The Landlord-Override glazing → glazing Simulation Overlay mapping. A glazing value resolves to the SAP10 `glazing_type` code the calculator's Table-24 cascade reads; the overlay is whole-dwelling (expanded across every window by `_fold_glazing`). """ from __future__ import annotations import pytest from domain.epc.property_overrides.glazing_type import GlazingType from domain.epc.property_overlays.glazing_overlay import glazing_overlay_for from domain.modelling.scoring.overlay_applicator import apply_simulations from tests.domain.sap10_calculator.worksheet._elmhurst_worksheet_000490 import ( build_epc, ) def test_double_glazing_post_2002_overlays_its_glazing_code() -> None: # Act simulation = glazing_overlay_for("Double glazing, 2002 or later", 0) # Assert — double glazing 2002-2021 is SAP10 glazing_type code 2. assert simulation is not None assert simulation.glazing is not None assert simulation.glazing.glazing_type == 2 @pytest.mark.parametrize( ("glazing_value", "code"), [ ("Single glazing", 1), ("Double glazing, pre-2002", 3), ("Triple glazing, 2002 or later", 9), ("Triple glazing, pre-2002", 6), ], ) def test_glazing_types_decode_to_their_sap_codes( glazing_value: str, code: int ) -> None: # Act simulation = glazing_overlay_for(glazing_value, 0) # Assert assert simulation is not None assert simulation.glazing is not None assert simulation.glazing.glazing_type == code @pytest.mark.parametrize("glazing_value", ["Unknown", ""]) def test_unresolvable_glazing_produces_no_overlay(glazing_value: str) -> None: # Act simulation = glazing_overlay_for(glazing_value, 0) # Assert assert simulation is None def test_glazing_override_remaps_every_window_and_clears_lodged_u() -> None: # Arrange — baseline windows are double glazed (code 2, lodged U 2.8); the # landlord corrects the whole dwelling to single glazing. baseline = build_epc() assert len(baseline.sap_windows) > 1 overlay = glazing_overlay_for("Single glazing", 0) assert overlay is not None # Act result = apply_simulations(baseline, [overlay]) # Assert — every window flips to single (code 1) and its lodged transmission # U is cleared so the Table-24 cascade re-derives U from the new type. assert all(w.glazing_type == 1 for w in result.sap_windows) assert all(w.window_transmission_details is None for w in result.sap_windows) @pytest.mark.parametrize( "member", [m for m in GlazingType if m is not GlazingType.UNKNOWN] ) def test_every_resolvable_glazing_value_decodes_to_a_code( member: GlazingType, ) -> None: # A classifier emits a GlazingType value; if the overlay can't decode it the # override silently no-ops. Every non-UNKNOWN member must resolve. # Act simulation = glazing_overlay_for(member.value, 0) # Assert assert simulation is not None