From 04be6b57a25c095e73d4713817c083072b840243 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 13 Jul 2026 23:09:40 +0000 Subject: [PATCH] =?UTF-8?q?Guarantee=20every=20measure=20column=20on=20eve?= =?UTF-8?q?ry=20scenario=20sheet=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../scenario_export/test_scenario_sheet.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/domain/scenario_export/test_scenario_sheet.py b/tests/domain/scenario_export/test_scenario_sheet.py index 01b20f8ed..6712074bc 100644 --- a/tests/domain/scenario_export/test_scenario_sheet.py +++ b/tests/domain/scenario_export/test_scenario_sheet.py @@ -5,6 +5,7 @@ Property, and the Plan's post-works figures.""" from typing import Optional, Sequence from domain.scenario_export.scenario_sheet import ( + MEASURE_COLUMNS, ExportMeasure, PropertyScenarioData, shape_scenario_sheet, @@ -65,3 +66,23 @@ def test_a_measures_cost_lands_in_its_own_column_with_the_property_identity() -> assert row["property_id"] == 42 assert row["landlord_property_id"] == "LP42" assert row["loft_insulation"] == 1200.0 + + +def test_every_measure_column_is_present_and_blank_where_the_property_lacks_it() -> None: + # arrange — a Property with a single measure. Every other measure column + # must still appear on the sheet (the frozen contract, ADR-0065), blank for + # this Property, so all scenario sheets share one column set. + prop = _property( + measures=[_measure(measure_type="cavity_wall_insulation", estimated_cost=800.0)] + ) + + # act + sheet = shape_scenario_sheet([prop]) + + # assert — the full frozen measure contract is present; the one selected + # measure carries its cost, every other measure column is blank. + assert set(MEASURE_COLUMNS).issubset(set(sheet.columns)) + row = sheet.rows[0] + assert row["cavity_wall_insulation"] == 800.0 + assert row["loft_insulation"] == "" + assert row["solar_pv"] == ""