diff --git a/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py b/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py index 05313170..98b86231 100644 --- a/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py +++ b/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py @@ -30,6 +30,8 @@ from datatypes.epc.domain.epc_property_data import ( SapFloorDimension, SapVentilation, SapWindow, + ShowerOutlet, + ShowerOutlets, ) from domain.ml.tests._fixtures import ( make_main_heating_detail, @@ -51,13 +53,23 @@ _WC_CAVITY = 4 def build_epc() -> EpcPropertyData: - """EpcPropertyData mirroring the Elmhurst 000490 inputs.""" + """EpcPropertyData mirroring the Elmhurst 000490 inputs. + + Field-level parity with `from_elmhurst_site_notes(Summary_000490. + pdf)` for the load-bearing field allow-list — cascade-equivalent + encoding-only fields (descriptive floor/roof strings, ventilation + zero counts) are populated explicitly to eliminate noise without + altering the SAP cascade output (the 11 1e-4 pins in + `test_e2e_elmhurst_sap_score.py` remain GREEN against the worksheet + PDF's `SAP value 57.3979`). + """ main = SapBuildingPart( identifier=BuildingPartIdentifier.MAIN, construction_age_band="B", wall_construction=_WC_CAVITY, wall_insulation_type=4, - wall_thickness_measured=False, + # Summary §7 lodges Wall Thickness 400 mm explicitly; matches mapper. + wall_thickness_measured=True, party_wall_construction=0, # "U Unable to determine" → U=0.25 roof_insulation_thickness=300, # Table 16 "300 mm joists" → U=0.14 sap_floor_dimensions=[ @@ -75,13 +87,20 @@ def build_epc() -> EpcPropertyData: ), ], wall_thickness_mm=400, + # Mapper-extracted descriptive fields (cascade reads int codes + # on SapFloorDimension; these carry the lodged Summary text). + floor_type="Ground floor", + floor_construction_type="Suspended timber", + floor_insulation_type_str="As built", + floor_u_value_known=False, + roof_insulation_location="Joists", ) extension = SapBuildingPart( identifier=BuildingPartIdentifier.EXTENSION_1, construction_age_band="B", wall_construction=_WC_CAVITY, wall_insulation_type=4, - wall_thickness_measured=False, + wall_thickness_measured=True, party_wall_construction=0, roof_insulation_thickness=300, sap_floor_dimensions=[ @@ -104,6 +123,11 @@ def build_epc() -> EpcPropertyData: ), ], wall_thickness_mm=400, + floor_type="Above unheated space", + floor_construction_type="Suspended timber", + floor_insulation_type_str="As built", + floor_u_value_known=False, + roof_insulation_location="Joists", ) # door_count=2 matches the worksheet's 3.70 m² of total door area: # Elmhurst lodges 1 oversized 3.7 m × 1.0 m door, our cascade uses the @@ -113,7 +137,7 @@ def build_epc() -> EpcPropertyData: # 28kW, 2004-2012, winter eff 88.2%, summer eff 79.6%). Lodging it on the # MainHeatingDetail routes `cert_to_inputs` into the PCDB precedence # cascade rather than the Table 4a category-2 default (80%). - return make_minimal_sap10_epc( + epc = make_minimal_sap10_epc( total_floor_area_m2=66.06, country_code="ENG", postcode="bd19 3TF", @@ -124,6 +148,11 @@ def build_epc() -> EpcPropertyData: low_energy_fixed_lighting_bulbs_count=8, sap_windows=list(SECTION_6_VERTICAL_WINDOWS), percent_draughtproofed=100, + extensions_count=1, + blocked_chimneys_count=0, + dwelling_type="End-Terrace house", + built_form="End-Terrace", + property_type="House", sap_ventilation=SapVentilation( extract_fans_count=2, sheltered_sides=1, @@ -131,6 +160,14 @@ def build_epc() -> EpcPropertyData: # the worksheet, same pattern as 000480. has_suspended_timber_floor=False, has_draught_lobby=False, + open_flues_count=0, + closed_flues_count=0, + boiler_flues_count=0, + other_flues_count=0, + passive_vents_count=0, + flueless_gas_fires_count=0, + draught_lobby=True, + pressure_test="Not available", ), sap_heating=make_sap_heating( main_heating_details=[ @@ -140,8 +177,21 @@ def build_epc() -> EpcPropertyData: ), ], secondary_heating_type=691, + # 000490 cert: number_baths=1 (mapper extracts this). Cascade- + # equivalent to leaving None — Appendix J §1a defaults to 1 + # when nothing is lodged. + number_baths=1, ), ) + # Top-level cert-lodgement booleans the mapper surfaces. + epc.has_conservatory = False + epc.any_unheated_rooms = False + epc.number_of_storeys = 2 + epc.sap_heating.shower_outlets = ShowerOutlets( + shower_outlet=ShowerOutlet(shower_outlet_type="Non-electric shower"), + ) + epc.sap_heating.main_heating_details[0].central_heating_pump_age_str = "Unknown" + return epc # ============================================================================