From 1e019ea3b3e77832deef000f51d5d70364e995e5 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 26 Jun 2026 19:04:32 +0000 Subject: [PATCH] =?UTF-8?q?test:=20rebaseliner=20adopts=20calc=20output=20?= =?UTF-8?q?when=20physical=20state=20changed=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A SAP>=10.2 cert whose physical state was changed by Landlord Overrides or Prediction must rebaseline off the calculator (the accredited lodged figure no longer describes the dwelling) and tag physical_state_changed / both, and must NOT log divergence (the calc IS adopted, nothing to validate against). This is the D1 fix: the stored Effective baseline stops echoing the lodged headline for overridden properties. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../test_calculator_rebaseliner.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/domain/property_baseline/test_calculator_rebaseliner.py b/tests/domain/property_baseline/test_calculator_rebaseliner.py index 766da437..f6002bd4 100644 --- a/tests/domain/property_baseline/test_calculator_rebaseliner.py +++ b/tests/domain/property_baseline/test_calculator_rebaseliner.py @@ -113,6 +113,75 @@ def test_a_10_2_cert_keeps_the_lodged_figures() -> None: assert result.sap_result is sap_result +def test_a_10_2_cert_with_changed_physical_state_uses_the_calculator() -> None: + # Arrange — a 10.2 cert whose physical state was changed by Landlord + # Overrides (or assembled by Prediction): the accredited lodged figure no + # longer describes the dwelling, so the calculator's output becomes Effective + # Performance (Rebaselining trigger (b)/(c), CONTEXT.md), not the lodged value. + sap_result = _sap_result( + sap_score=67, co2_kg_per_yr=2100.0, primary_energy_kwh_per_m2=210.0 + ) + rebaseliner = CalculatorRebaseliner(_StubCalculator(sap_result)) + epc = _epc(sap_version=10.2) + + # Act + result = rebaseliner.rebaseline( + property_id=10, + effective_epc=epc, + lodged=_lodged(), + physical_state_changed=True, + ) + + # Assert — calculated Performance wins, tagged physical_state_changed. + assert result.effective == Performance( + sap_score=67, epc_band=Epc.D, co2_emissions=2.1, primary_energy_intensity=210 + ) + assert result.reason == "physical_state_changed" + assert result.sap_result is sap_result + + +def test_a_pre_10_2_cert_with_changed_physical_state_is_reason_both() -> None: + # Arrange — both triggers fire: a superseded methodology (sap_version < 10.2) + # AND a physical-state change. The calculator wins (as for either alone); the + # reason records both. + rebaseliner = CalculatorRebaseliner(_StubCalculator(_sap_result(sap_score=65))) + epc = _epc(sap_version=10.0) + + # Act + result = rebaseliner.rebaseline( + property_id=10, + effective_epc=epc, + lodged=_lodged(), + physical_state_changed=True, + ) + + # Assert + assert result.effective.sap_score == 65 + assert result.reason == "both" + + +def test_a_10_2_cert_with_changed_state_does_not_log_divergence( + caplog: pytest.LogCaptureFixture, +) -> None: + # Arrange — when we ADOPT the calculator output (physical state changed), + # there is no accredited lodged figure to validate against, so no divergence + # warning is emitted (calc 90 vs lodged 72 would otherwise warn). + rebaseliner = CalculatorRebaseliner(_StubCalculator(_sap_result(sap_score=90))) + epc = _epc(sap_version=10.2) + + # Act + with caplog.at_level(logging.WARNING): + rebaseliner.rebaseline( + property_id=42, + effective_epc=epc, + lodged=_lodged(), + physical_state_changed=True, + ) + + # Assert — no divergence log when the calculator output is adopted. + assert caplog.records == [] + + def test_a_10_2_cert_logs_divergence_when_the_calculator_disagrees( caplog: pytest.LogCaptureFixture, ) -> None: