"""`Property.physical_state_changed` — the Rebaselining trigger (b)/(c) signal. True when the Effective EPC was assembled from something other than a pristine lodged cert: Landlord Overrides folded on, Site Notes superseding the cert, or an EPC-Prediction synthesis. The PropertyBaselineOrchestrator threads it into the Rebaseliner so an overridden / predicted SAP >= 10.2 picture rebaselines off the calculator instead of echoing the (now-stale) accredited lodged figure. """ from __future__ import annotations import json from pathlib import Path from typing import Any from datatypes.epc.domain.epc_property_data import EpcPropertyData from datatypes.epc.domain.mapper import EpcPropertyDataMapper from domain.epc.property_overlays.wall_type_overlay import wall_overlay_for from domain.property.property import Property, PropertyIdentity _JSON_SAMPLES = Path(__file__).resolve().parents[3] / "backend/epc_api/json_samples" def _epc() -> EpcPropertyData: raw: dict[str, Any] = json.loads( (_JSON_SAMPLES / "RdSAP-Schema-21.0.0" / "epc.json").read_text() ) return EpcPropertyDataMapper.from_api_response(raw) def _identity() -> PropertyIdentity: return PropertyIdentity( portfolio_id=1, postcode="A0 0AA", address="1 Some Street", uprn=12345 ) def test_pristine_lodged_cert_with_no_overrides_is_unchanged() -> None: prop = Property(identity=_identity(), epc=_epc()) assert prop.physical_state_changed is False def test_lodged_cert_with_landlord_overrides_is_changed() -> None: overlay = wall_overlay_for("Solid brick, with internal insulation", 0) assert overlay is not None prop = Property(identity=_identity(), epc=_epc(), landlord_overrides=[overlay]) assert prop.physical_state_changed is True def test_predicted_property_is_changed() -> None: # A neighbour-synthesised picture is assembled, not a real lodged cert, so it # rebaselines off the calculator (trigger (c)). prop = Property(identity=_identity(), epc=None, predicted_epc=_epc()) assert prop.physical_state_changed is True