diff --git a/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py b/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py index 335a3e919..3ce8b8dcc 100644 --- a/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py +++ b/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py @@ -232,6 +232,75 @@ def test_finalise_writes_overrides_for_uprn_rows_splitting_by_part() -> None: assert (prop_type.building_part, prop_type.override_value) == (0, "Semi-detached house") +def test_finalise_writes_the_boiler_efficiency_band_alongside_the_heating_system() -> None: + # The band rides the SAME "Heating" source column as main_heating_system + # (like Property Type feeds property_type + built_form), so a banded boiler + # cell yields two override rows: the archetype and its SEDBUK band (ADR-0068). + combiner = [{"address2uprn_uprn": "100023", "source_row_id": "row-a"}] + classifier = [{"Heating": "Boiler: D rated Regular Boiler", "source_row_id": "row-a"}] + vocab = { + "main_heating_system": {"boiler: d rated regular boiler": "Gas boiler, regular"}, + "boiler_efficiency_band": {"boiler: d rated regular boiler": "D"}, + } + orchestrator, overrides = _overrides_orchestrator({100023: 555}, vocab) + + orchestrator.finalise( + combiner, + portfolio_id=7, + task_id=uuid4(), + classifier_rows=classifier, + multi_entry_ordering={}, + column_mapping={ + "main_heating_system": "Heating", + "boiler_efficiency_band": "Heating", + }, + ) + + (band,) = [ + o for o in overrides.upserted if o.override_component == "boiler_efficiency_band" + ] + assert (band.building_part, band.override_value) == (0, "D") + + +def test_finalise_skips_an_unknown_boiler_efficiency_band_without_failing() -> None: + # A non-boiler heating system (or a plain boiler) carries no band, so the band + # classifier returns UNKNOWN. Unlike the mandatory components, an UNKNOWN band + # is a legitimate "no value" — skip it, don't fail the finalise (ADR-0068). + combiner = [{"address2uprn_uprn": "100023", "source_row_id": "row-a"}] + classifier = [ + {"Heating": "Community Heating Systems: Community boilers only (RdSAP)", + "source_row_id": "row-a"} + ] + vocab = { + "main_heating_system": { + "community heating systems: community boilers only (rdsap)": + "Community heating, boilers" + }, + "boiler_efficiency_band": { + "community heating systems: community boilers only (rdsap)": "Unknown" + }, + } + orchestrator, overrides = _overrides_orchestrator({100023: 555}, vocab) + + orchestrator.finalise( + combiner, + portfolio_id=7, + task_id=uuid4(), + classifier_rows=classifier, + multi_entry_ordering={}, + column_mapping={ + "main_heating_system": "Heating", + "boiler_efficiency_band": "Heating", + }, + ) + + # The heating system row is written; the UNKNOWN band produced no row. + assert any(o.override_component == "main_heating_system" for o in overrides.upserted) + assert not any( + o.override_component == "boiler_efficiency_band" for o in overrides.upserted + ) + + def test_finalise_fails_loudly_on_unresolved_description() -> None: combiner = [ {"address2uprn_uprn": "100023", "source_row_id": "row-a"},