import pytest from datatypes.epc.construction_age_band import EpcConstructionAgeBand from datatypes.epc.roof import EpcRoofDescriptions from datatypes.epc.efficiency import EpcEfficiency from backend.onboarders.mappings.parity.as_built_roof_classifiers import ( map_flat_roof, map_sloping_ceiling_roof, ) from backend.onboarders.mappings.parity.roof import resolve_roof_efficiency # --------------------------------------------------------------------- # As-built roof description classification # --------------------------------------------------------------------- @pytest.mark.parametrize( "age_band, expected", [ (EpcConstructionAgeBand.before_1900, EpcRoofDescriptions.flat_no_insulation), (EpcConstructionAgeBand.from_1950_to_1966, EpcRoofDescriptions.flat_no_insulation), (EpcConstructionAgeBand.from_1967_to_1975, EpcRoofDescriptions.flat_limited_insulation), (EpcConstructionAgeBand.from_1976_to_1982, EpcRoofDescriptions.flat_limited_insulation), (EpcConstructionAgeBand.from_1983_to_1990, EpcRoofDescriptions.flat_insulated), (EpcConstructionAgeBand.from_2007_to_2011, EpcRoofDescriptions.flat_insulated), (EpcConstructionAgeBand.from_2023_onwards, EpcRoofDescriptions.flat_insulated), ], ) def test_classify_flat_roof(age_band, expected): assert map_flat_roof(age_band) == expected @pytest.mark.parametrize( "age_band, expected", [ (EpcConstructionAgeBand.before_1900, EpcRoofDescriptions.sloping_pitched_no_insulation), (EpcConstructionAgeBand.from_1967_to_1975, EpcRoofDescriptions.sloping_pitched_no_insulation), (EpcConstructionAgeBand.from_1976_to_1982, EpcRoofDescriptions.sloping_pitched_limited_insulation), (EpcConstructionAgeBand.from_1983_to_1990, EpcRoofDescriptions.sloping_pitched_insulated), (EpcConstructionAgeBand.from_2012_to_2022, EpcRoofDescriptions.sloping_pitched_insulated), (EpcConstructionAgeBand.from_2023_onwards, EpcRoofDescriptions.sloping_pitched_insulated), ], ) def test_classify_sloping_ceiling_roof(age_band, expected): assert map_sloping_ceiling_roof(age_band) == expected # --------------------------------------------------------------------- # Roof efficiency — fixed & age-band driven # --------------------------------------------------------------------- @pytest.mark.parametrize( "description, age_band, expected", [ # Flat roof, no insulation (EpcRoofDescriptions.flat_no_insulation, EpcConstructionAgeBand.before_1900, EpcEfficiency.VERY_POOR), # Flat roof, limited insulation (age-band driven) (EpcRoofDescriptions.flat_limited_insulation, EpcConstructionAgeBand.from_1976_to_1982, EpcEfficiency.POOR), ( EpcRoofDescriptions.flat_limited_insulation, EpcConstructionAgeBand.from_1967_to_1975, EpcEfficiency.VERY_POOR), # Flat roof, insulated (age-band driven) (EpcRoofDescriptions.flat_insulated, EpcConstructionAgeBand.from_1983_to_1990, EpcEfficiency.AVERAGE), (EpcRoofDescriptions.flat_insulated, EpcConstructionAgeBand.from_2003_to_2006, EpcEfficiency.GOOD), (EpcRoofDescriptions.flat_insulated, EpcConstructionAgeBand.from_2023_onwards, EpcEfficiency.VERY_GOOD), # Pitched, insulated assumed (loft) (EpcRoofDescriptions.pitched_insulated_assumed, EpcConstructionAgeBand.from_1996_to_2002, EpcEfficiency.GOOD), (EpcRoofDescriptions.pitched_insulated_assumed, EpcConstructionAgeBand.from_2007_to_2011, EpcEfficiency.VERY_GOOD), ], ) def test_roof_efficiency_age_band_only(description, age_band, expected): assert resolve_roof_efficiency( description=description, age_band=age_band, insulation_thickness=None, ) == expected # --------------------------------------------------------------------- # Roof efficiency — insulation thickness driven # --------------------------------------------------------------------- @pytest.mark.parametrize( "description, thickness, expected", [ # Loft insulation (EpcRoofDescriptions.loft_12mm_insulation, 12, EpcEfficiency.VERY_POOR), (EpcRoofDescriptions.loft_25mm_insulation, 25, EpcEfficiency.POOR), (EpcRoofDescriptions.loft_75mm_insulation, 75, EpcEfficiency.AVERAGE), (EpcRoofDescriptions.loft_150mm_insulation, 150, EpcEfficiency.GOOD), (EpcRoofDescriptions.loft_300mm_insulation, 300, EpcEfficiency.VERY_GOOD), # Flat insulated — thickness overrides age band (EpcRoofDescriptions.flat_insulated, 50, EpcEfficiency.POOR), (EpcRoofDescriptions.flat_insulated, 100, EpcEfficiency.AVERAGE), (EpcRoofDescriptions.flat_insulated, 200, EpcEfficiency.GOOD), (EpcRoofDescriptions.flat_insulated, 300, EpcEfficiency.VERY_GOOD), # Sloping ceiling (EpcRoofDescriptions.sloping_pitched_insulated, 75, EpcEfficiency.AVERAGE), (EpcRoofDescriptions.sloping_pitched_insulated, 150, EpcEfficiency.GOOD), (EpcRoofDescriptions.sloping_pitched_insulated, 350, EpcEfficiency.VERY_GOOD), ], ) def test_roof_efficiency_thickness_based(description, thickness, expected): assert resolve_roof_efficiency( description=description, age_band=EpcConstructionAgeBand.before_1900, # should be ignored insulation_thickness=thickness, ) == expected # --------------------------------------------------------------------- # Thatched roofs # --------------------------------------------------------------------- @pytest.mark.parametrize( "description, age_band, expected", [ (EpcRoofDescriptions.thatched, EpcConstructionAgeBand.before_1900, EpcEfficiency.AVERAGE), (EpcRoofDescriptions.thatched, EpcConstructionAgeBand.from_2003_to_2006, EpcEfficiency.GOOD), (EpcRoofDescriptions.thatched, EpcConstructionAgeBand.from_2023_onwards, EpcEfficiency.VERY_GOOD), ], ) def test_thatched_efficiency_age_band(description, age_band, expected): assert resolve_roof_efficiency( description=description, age_band=age_band, insulation_thickness=None, ) == expected @pytest.mark.parametrize( "thickness, expected", [ (12, EpcEfficiency.AVERAGE), (50, EpcEfficiency.GOOD), (150, EpcEfficiency.GOOD), (200, EpcEfficiency.VERY_GOOD), ], ) def test_thatched_efficiency_thickness(thickness, expected): assert resolve_roof_efficiency( description=EpcRoofDescriptions.thatched_with_additional_insulation, age_band=EpcConstructionAgeBand.before_1900, insulation_thickness=thickness, ) == expected # --------------------------------------------------------------------- # Unknown / holding descriptions # --------------------------------------------------------------------- @pytest.mark.parametrize( "description", [ EpcRoofDescriptions.flat_as_built_unknown, EpcRoofDescriptions.loft_as_built_unknown, EpcRoofDescriptions.thatched_as_built_unknown, EpcRoofDescriptions.sloping_pitched_as_built_unknown, ], ) def test_unknown_roof_descriptions_return_na(description): assert resolve_roof_efficiency( description=description, age_band=None, insulation_thickness=None, ) == EpcEfficiency.NA