mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Persist no Lodged Performance for a predicted Property 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ecb7eebd1
commit
5d63118d5a
1 changed files with 75 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
|
||||
|
|
@ -244,6 +244,80 @@ def test_run_raises_when_no_rhi_and_no_scored_result() -> None:
|
|||
assert uow.commits == 0
|
||||
|
||||
|
||||
class _PredictedRebaseliner(Rebaseliner):
|
||||
"""Scores a predicted picture into a fixed Effective Performance, ignoring the
|
||||
(absent) lodged half — a predicted Property always has ``physical_state_changed``,
|
||||
so the calculator output IS the Effective Performance (ADR-0039)."""
|
||||
|
||||
def __init__(self, effective: Performance, result: SapResult) -> None:
|
||||
self._effective = effective
|
||||
self._result = result
|
||||
|
||||
def rebaseline(
|
||||
self,
|
||||
property_id: int,
|
||||
effective_epc: EpcPropertyData,
|
||||
lodged: Optional[Performance],
|
||||
*,
|
||||
physical_state_changed: bool = False,
|
||||
) -> RebaselineResult:
|
||||
return RebaselineResult(
|
||||
effective=self._effective,
|
||||
reason="physical_state_changed",
|
||||
sap_result=self._result,
|
||||
)
|
||||
|
||||
|
||||
def _predicted_property() -> Property:
|
||||
"""A predicted Property (ADR-0031): no lodged EPC, only a neighbour-synthesised
|
||||
predicted EPC whose recorded performance fields are a *different dwelling's* —
|
||||
the phantom Lodged Performance this fix must not propagate. Mirrors the #1361
|
||||
exemplar (uprn 34003067 / property 742072), predicted-only."""
|
||||
predicted = object.__new__(EpcPropertyData)
|
||||
predicted.energy_rating_current = 14 # phantom: copied from a neighbour template
|
||||
predicted.current_energy_efficiency_band = Epc.G
|
||||
predicted.co2_emissions_current = 5.0
|
||||
predicted.energy_consumption_current = 400
|
||||
predicted.sap_version = 10.2
|
||||
predicted.renewable_heat_incentive = None
|
||||
return Property(
|
||||
identity=PropertyIdentity(
|
||||
portfolio_id=1, postcode="A0 0AA", address="1 Some Street", uprn=34003067
|
||||
),
|
||||
epc=None,
|
||||
predicted_epc=predicted,
|
||||
)
|
||||
|
||||
|
||||
def test_run_persists_no_lodged_performance_for_a_predicted_property() -> None:
|
||||
# Arrange — a predicted Property (no lodged cert); the rebaseliner scores its
|
||||
# predicted picture into a known Effective Performance.
|
||||
property_baseline_repo = FakePropertyBaselineRepo()
|
||||
uow = FakeUnitOfWork(
|
||||
property=FakePropertyRepo({742072: _predicted_property()}),
|
||||
property_baseline=property_baseline_repo,
|
||||
)
|
||||
effective = Performance(
|
||||
sap_score=57, epc_band=Epc.D, co2_emissions=1.5, primary_energy_intensity=160
|
||||
)
|
||||
orchestrator = PropertyBaselineOrchestrator(
|
||||
unit_of_work=lambda: uow,
|
||||
rebaseliner=_PredictedRebaseliner(
|
||||
effective, _sap_result_with_heating(space_kwh=4200.0, water_kwh=1600.0)
|
||||
),
|
||||
fuel_rates=FuelRatesStaticFileRepository(),
|
||||
)
|
||||
|
||||
# Act
|
||||
orchestrator.run([742072])
|
||||
|
||||
# Assert — no lodged comparator was manufactured from the neighbour-synthesised
|
||||
# EPC's recorded fields; the Effective half is still persisted.
|
||||
(baseline, _) = property_baseline_repo.saved[0]
|
||||
assert baseline.lodged is None
|
||||
assert baseline.effective == effective
|
||||
|
||||
|
||||
def test_run_derives_and_persists_a_bill_when_the_rebaseliner_scores() -> None:
|
||||
# Arrange — a rebaseliner that hands back a SapResult with lighting energy,
|
||||
# so the orchestrator prices it into a Bill at the committed snapshot.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue