mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-19 17:03:02 +00:00
120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
"""Effective EPC on the `epc_with_overlay` path folds Landlord Overrides (ADR-0032).
|
|
|
|
When a Property has a lodged EPC and resolved Landlord Overrides (as Simulation
|
|
Overlays), the Effective EPC is the lodged EPC with those overlays applied — so
|
|
the calculator scores what the landlord knows beyond the cert. With no overrides
|
|
the lodged EPC is returned unchanged.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from datatypes.epc.domain.epc_property_data import (
|
|
BuildingPartIdentifier,
|
|
EpcPropertyData,
|
|
)
|
|
from domain.epc.property_overlays.attribute_overlay import property_type_overlay_for
|
|
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()
|
|
)
|
|
from datatypes.epc.domain.mapper import EpcPropertyDataMapper
|
|
|
|
return EpcPropertyDataMapper.from_api_response(raw)
|
|
|
|
|
|
def _identity() -> PropertyIdentity:
|
|
return PropertyIdentity(
|
|
portfolio_id=1, postcode="A0 0AA", address="1 Some Street", uprn=12345
|
|
)
|
|
|
|
|
|
def _main_wall(epc: EpcPropertyData) -> Any:
|
|
return next(
|
|
part
|
|
for part in epc.sap_building_parts
|
|
if part.identifier is BuildingPartIdentifier.MAIN
|
|
)
|
|
|
|
|
|
def test_effective_epc_folds_the_wall_override_onto_the_main_part() -> None:
|
|
# Arrange — a Property with a lodged EPC and a solid-brick/internal-insulation
|
|
# wall override.
|
|
overlay = wall_overlay_for("Solid brick, with internal insulation", 0)
|
|
assert overlay is not None
|
|
prop = Property(identity=_identity(), epc=_epc(), landlord_overrides=[overlay])
|
|
|
|
# Act
|
|
main = _main_wall(prop.effective_epc)
|
|
|
|
# Assert — the override's codes are present on the main wall.
|
|
assert main.wall_construction == 3
|
|
assert main.wall_insulation_type == 3
|
|
|
|
|
|
def test_effective_epc_reflects_a_property_type_override() -> None:
|
|
# Arrange — the landlord corrects the dwelling's property type to House.
|
|
overlay = property_type_overlay_for("House", 0)
|
|
assert overlay is not None
|
|
prop = Property(identity=_identity(), epc=_epc(), landlord_overrides=[overlay])
|
|
|
|
# Act / Assert — the Effective EPC carries the corrected property type.
|
|
assert prop.effective_epc.property_type == "House"
|
|
|
|
|
|
def test_effective_epc_is_the_lodged_epc_when_there_are_no_overrides() -> None:
|
|
# Arrange — a Property with an EPC and no Landlord Overrides.
|
|
prop = Property(identity=_identity(), epc=_epc())
|
|
|
|
# Act
|
|
effective = prop.effective_epc
|
|
|
|
# Assert — the lodged EPC is returned untouched (same object, no fold).
|
|
assert effective is prop.epc
|
|
|
|
|
|
def test_baseline_wall_is_unchanged_when_no_override_applies() -> None:
|
|
# Arrange — the lodged main wall is cavity (construction 4).
|
|
prop = Property(identity=_identity(), epc=_epc())
|
|
|
|
# Act
|
|
main = _main_wall(prop.effective_epc)
|
|
|
|
# Assert
|
|
assert main.wall_construction == 4
|
|
|
|
|
|
def test_effective_epc_folds_overrides_onto_a_predicted_epc() -> None:
|
|
# Arrange — an EPC-less Property whose EPC was neighbour-synthesised, plus a
|
|
# solid-brick/internal-insulation wall override the landlord knows.
|
|
overlay = wall_overlay_for("Solid brick, with internal insulation", 0)
|
|
assert overlay is not None
|
|
prop = Property(
|
|
identity=_identity(), predicted_epc=_epc(), landlord_overrides=[overlay]
|
|
)
|
|
|
|
# Act
|
|
main = _main_wall(prop.effective_epc)
|
|
|
|
# Assert — the override's codes correct the synthesised main wall, exactly as
|
|
# they do on the lodged path (the cohort fills the rest).
|
|
assert main.wall_construction == 3
|
|
assert main.wall_insulation_type == 3
|
|
|
|
|
|
def test_effective_epc_predicted_is_returned_as_is_when_no_overrides() -> None:
|
|
# Arrange — a predicted Property with no Landlord Overrides.
|
|
predicted = _epc()
|
|
prop = Property(identity=_identity(), predicted_epc=predicted)
|
|
|
|
# Act / Assert — the synthesised EPC is returned untouched (same object).
|
|
assert prop.effective_epc is predicted
|