diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index c4a33a514..0ae92c9c8 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -612,6 +612,17 @@ class EpcPropertyDataMapper: main_heating=EpcPropertyDataMapper._map_energy_elements( schema.main_heating ), + # First control system if multiple — mirrors the 19.0/21.0.1 paths. + # 17.0 lodges main_heating_controls (List[EnergyElement]) but omitted + # it, leaving main_heating_controls=None so the heating-control + # recommendations (programmer/room-stat/TRVs) had nothing to read. + main_heating_controls=( + EpcPropertyDataMapper._map_energy_element( + schema.main_heating_controls[0] + ) + if schema.main_heating_controls + else None + ), window=EpcPropertyDataMapper._map_energy_element(schema.window), lighting=EpcPropertyDataMapper._map_energy_element(schema.lighting), hot_water=EpcPropertyDataMapper._map_energy_element(schema.hot_water), diff --git a/tests/datatypes/epc/domain/test_mapper_main_heating_controls_17_0.py b/tests/datatypes/epc/domain/test_mapper_main_heating_controls_17_0.py new file mode 100644 index 000000000..3bb1a6d63 --- /dev/null +++ b/tests/datatypes/epc/domain/test_mapper_main_heating_controls_17_0.py @@ -0,0 +1,48 @@ +"""Regression: the RdSAP-Schema-17.0 mapper path must carry the lodged +main_heating_controls, like every other API path (19.0/20.0/21.x). + +PRD #1385 (mapper normalization). 17.0 lodges `main_heating_controls` +(List[EnergyElement]) but the mapper omitted it, leaving the domain field None +while the 19.0/21.0.1 paths map the first control via `_map_energy_element`. The +mapped element is the same EnergyElement type 17.0 already carries for +`main_heating` / `window`, so this is straight parity. +""" + +from __future__ import annotations + +import json +from pathlib import Path +from typing import Any + +from datatypes.epc.domain.mapper import EpcPropertyDataMapper + +# 17.0 cert lodging a main-heating control ("Programmer, TRVs and bypass"). +_FIXTURE = Path("tests/fixtures/epc_prediction/PE71NT/cert-26619d8e7f8e.json") + + +def _load() -> dict[str, Any]: + data: dict[str, Any] = json.loads(_FIXTURE.read_text()) + assert data["schema_type"] == "RdSAP-Schema-17.0" + return data + + +def test_17_0_maps_lodged_main_heating_controls() -> None: + data = _load() + assert data["main_heating_controls"], "fixture must lodge a control" + + epc = EpcPropertyDataMapper.from_api_response(data) + + # Was None on the 17.0 path; now carries the first lodged control element. + assert epc.main_heating_controls is not None + assert epc.main_heating_controls.description == "Programmer, TRVs and bypass" + assert epc.main_heating_controls.energy_efficiency_rating == 3 + + +def test_17_0_no_controls_maps_to_none() -> None: + # An empty control list maps to None (no phantom element), like the siblings. + data = _load() + data["main_heating_controls"] = [] + + epc = EpcPropertyDataMapper.from_api_response(data) + + assert epc.main_heating_controls is None