"""The ModellingOrchestrator honours a Fabric First Scenario: when ``scenario.fabric_first`` is set, the Optimiser treats the building envelope with the full budget before heating / renewables are considered, so a budget the plain optimiser would spend on a heating system is spent on fabric instead. End-to-end through ``run_modelling`` (no database) with the real calculator, against the uninsulated solid-brick 001431 dwelling whose plain plan is heating-led. """ from __future__ import annotations from datatypes.epc.domain.epc_property_data import EpcPropertyData from domain.modelling.measure_type import FABRIC_MEASURE_TYPES, MeasureType from domain.modelling.plan import Plan from domain.modelling.scenario import Scenario from harness.console import run_modelling from tests.domain.modelling._elmhurst_recommendation import ( parse_recommendation_summary, ) _HEATING_MEASURES: frozenset[MeasureType] = frozenset( { MeasureType.GAS_BOILER_UPGRADE, MeasureType.AIR_SOURCE_HEAT_PUMP, MeasureType.HIGH_HEAT_RETENTION_STORAGE_HEATERS, MeasureType.SOLAR_PV, } ) def _fabric_first_scenario(*, budget: float) -> Scenario: return Scenario( id=999, goal="Increasing EPC", goal_value="C", budget=budget, is_default=True, fabric_first=True, ) def test_fabric_first_scenario_spends_the_budget_on_fabric_before_heating() -> None: # Arrange — uninsulated solid brick: at a £4000 budget the plain optimiser # buys the £3200 gas boiler (the cheapest route toward band C). Fabric # first must commit the envelope work first, after which the boiler no # longer fits the leftover budget. epc: EpcPropertyData = parse_recommendation_summary( "solid_brick_ewi_001431_before.pdf" ) # Act plan: Plan = run_modelling( epc, scenario=_fabric_first_scenario(budget=4000.0), print_table=False ) # Assert — the plan is fabric-led: at least one envelope measure, and none # of the budget leaked to a heating system or renewables. selected = {measure.measure_type for measure in plan.measures} assert selected & FABRIC_MEASURE_TYPES assert not selected & _HEATING_MEASURES