"""The Landlord-Override main-heating-system → heating Simulation Overlay mapping. A main-heating-system value resolves to the SAP `sap_main_heating_code` the calculator reads from the primary system; the overlay is whole-dwelling. """ from __future__ import annotations import pytest from domain.epc.property_overrides.main_heating_system_type import MainHeatingSystemType from domain.epc.property_overlays.main_fuel_overlay import fuel_overlay_for from domain.epc.property_overlays.main_heating_system_overlay import ( main_heating_overlay_for, ) from domain.epc.property_overlays.water_heating_overlay import ( water_heating_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_gas_combi_overlays_the_primary_heating_code() -> None: # Act simulation = main_heating_overlay_for("Gas boiler, combi", 0) # Assert — condensing combi is SAP Table 4b code 104. assert simulation is not None assert simulation.heating is not None assert simulation.heating.sap_main_heating_code == 104 @pytest.mark.parametrize( ("main_heating_value", "code"), [ ("Gas boiler, regular", 102), ("Gas CPSU", 120), ("Electric storage heaters, fan", 404), ("Direct-acting electric", 191), ], ) def test_heating_archetypes_decode_to_their_sap_codes( main_heating_value: str, code: int ) -> None: # Act simulation = main_heating_overlay_for(main_heating_value, 0) # Assert assert simulation is not None assert simulation.heating is not None assert simulation.heating.sap_main_heating_code == code @pytest.mark.parametrize( ("main_heating_value", "code"), [ ("Electric storage heaters, old", 401), ("Electric storage heaters, slimline", 402), ("Electric storage heaters, convector", 403), ], ) def test_storage_heater_subtypes_decode_to_their_codes( main_heating_value: str, code: int ) -> None: # Act simulation = main_heating_overlay_for(main_heating_value, 0) # Assert assert simulation is not None assert simulation.heating is not None assert simulation.heating.sap_main_heating_code == code @pytest.mark.parametrize( "main_heating_value", ["Unknown", "", "Air source heat pump", "Community heating"], ) def test_unresolvable_or_unmodelled_heating_produces_no_overlay( main_heating_value: str, ) -> None: # Heat pumps (main_heating_index_number) and community heating (community # codes) don't map to a Table 4b sap_main_heating_code yet — no overlay. # Act simulation = main_heating_overlay_for(main_heating_value, 0) # Assert assert simulation is None def test_main_heating_override_remaps_the_primary_system_code() -> None: # Arrange baseline = build_epc() overlay = main_heating_overlay_for("Gas boiler, regular", 0) assert overlay is not None # Act result = apply_simulations(baseline, [overlay]) # Assert — the calculator reads the code off main_heating_details[0]. assert result.sap_heating.main_heating_details[0].sap_main_heating_code == 102 def test_the_three_heating_overrides_compose_without_conflict() -> None: # Arrange — main_fuel, water_heating and main_heating_system all fold onto one # HeatingOverlay surface but set DISJOINT fields, so they compose (the # field-disjoint design that makes precedence moot for these three). baseline = build_epc() overlays = [ fuel_overlay_for("electricity", 0), water_heating_overlay_for("Electric immersion, electricity", 0), main_heating_overlay_for("Electric storage heaters, fan", 0), ] assert all(o is not None for o in overlays) # Act result = apply_simulations(baseline, [o for o in overlays if o is not None]) # Assert — each override landed on its own field. main = result.sap_heating.main_heating_details[0] assert main.main_fuel_type == 29 assert main.sap_main_heating_code == 404 assert result.sap_heating.water_heating_code == 903 assert result.sap_heating.water_heating_fuel == 29 @pytest.mark.parametrize( "member", [m for m in MainHeatingSystemType if m is not MainHeatingSystemType.UNKNOWN], ) def test_every_resolvable_main_heating_value_decodes( member: MainHeatingSystemType, ) -> None: # Act simulation = main_heating_overlay_for(member.value, 0) # Assert assert simulation is not None