feat(harness): explain gas_boiler_upgrade in the report triggers

Add the `gas_boiler_upgrade` branch to `report._triggers_for`, mirroring the
generator's eligibility guard so a cohort report explains why the boiler upgrade
fired: the wet-boiler SAP code, the mains-gas connection that makes the gas
end-state installable, and the cylinder presence that shapes the bundle (combi
vs regular + cylinder fixes).

No golden API cert selects the boiler upgrade (it competes with — and on houses
loses to — the ASHP bundle within the one heating Recommendation), so the branch
is covered by a direct `_triggers_for` unit test, following the repo pattern for
testing internal helpers (cert_to_inputs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-10 08:44:37 +00:00
parent 2413bc87da
commit 3d108a9d9e
2 changed files with 37 additions and 0 deletions

View file

@ -153,6 +153,17 @@ def _triggers_for(epc: EpcPropertyData, measure_type: str) -> dict[str, Any]:
epc.sap_heating.main_heating_details[0].main_heating_category
),
}
if measure_type == "gas_boiler_upgrade":
# heating_recommendation.py offers a gas condensing boiler to a dwelling
# with an existing (non-electric) wet boiler and a mains-gas connection;
# the cylinder presence shapes it (combi vs regular + cylinder fixes).
return {
"sap_main_heating_code": (
epc.sap_heating.main_heating_details[0].sap_main_heating_code
),
"mains_gas": epc.sap_energy_source.mains_gas,
"has_hot_water_cylinder": epc.has_hot_water_cylinder,
}
return {}

View file

@ -15,6 +15,9 @@ from harness.report import (
format_report_markdown,
parity_report_for,
)
from tests.domain.modelling._elmhurst_recommendation import (
parse_recommendation_summary,
)
_GOLDEN = (
Path(__file__).resolve().parents[1]
@ -99,6 +102,29 @@ def test_each_fired_measure_carries_the_attributes_that_triggered_it() -> None:
}
def test_gas_boiler_upgrade_surfaces_its_eligibility_triggers() -> None:
# No golden API cert selects the boiler upgrade (it competes with — and on
# houses loses to — the ASHP bundle within the one heating Recommendation),
# so the trigger branch is exercised directly, like the cert_to_inputs unit
# tests of internal helpers.
from harness.report import _triggers_for # pyright: ignore[reportPrivateUsage]
# Arrange — a mains-gas wet boiler (SAP code 114) with a hot-water cylinder:
# the boiler-upgrade eligibility attributes the report should explain.
epc = parse_recommendation_summary("boiler_cyl_gas_001431_before.pdf")
# Act
triggers = _triggers_for(epc, "gas_boiler_upgrade")
# Assert — the wet-boiler SAP code, the mains-gas connection that makes the
# gas end-state installable, and the cylinder that shapes the bundle.
assert triggers == {
"sap_main_heating_code": 114,
"mains_gas": True,
"has_hot_water_cylinder": True,
}
def test_few_measure_cert_surfaces_only_its_fired_measures_triggers() -> None:
# Arrange
path: Path = _GOLDEN / f"{_WITHIN_TOLERANCE}.json"