Mapper synthesises SapFloorDimension for SAP-16.0 flats with empty floor dims 🟥

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-06-25 14:14:03 +00:00
parent 77133f4b42
commit c1e754057b

View file

@ -751,3 +751,52 @@ class TestFullSapSchema16xRouting:
# Assert
assert not any("broken schema_type" in r.message for r in caplog.records)
class TestFullSapSchema16xNoFloorDimensions:
"""SAP-Schema-16.0 certs with assessment_type=SAP that lodge no
sap_floor_dimensions inside sap_building_parts (uprn 10090783001,
cert lodged 88). The API only carries total_floor_area at the top level;
the building part has sap_walls but no per-storey dimension data.
This is the root cause of the `max() arg is an empty sequence` crash in
building_geometry.roof_area() documented in
scripts/handover_max_empty_sequence_design_question.md.
"""
@pytest.fixture
def epc(self) -> EpcPropertyData:
return EpcPropertyDataMapper.from_api_response(
load("sap_16_0_full_no_floor_dims.json")
)
def test_maps_successfully(self, epc: EpcPropertyData) -> None:
assert isinstance(epc, EpcPropertyData)
def test_uprn_and_total_floor_area(self, epc: EpcPropertyData) -> None:
assert epc.uprn == 10090783001
assert epc.total_floor_area_m2 == 72.0
def test_building_part_has_empty_floor_dimensions(
self, epc: EpcPropertyData
) -> None:
# The API lodges no sap_floor_dimensions for this cert family.
# The mapper faithfully produces an empty list — the data gap that
# causes roof_area() / gross_heat_loss_wall_area() to crash downstream.
main_part = epc.sap_building_parts[0]
assert main_part.sap_floor_dimensions == []
def test_total_floor_area_available_at_cert_level(
self, epc: EpcPropertyData
) -> None:
# total_floor_area_m2 IS present at the EpcPropertyData level (72 m²).
# This is the candidate fallback value for roof_area() — accurate for
# single-storey single-part certs, an overestimate for multi-storey.
assert epc.total_floor_area_m2 == 72.0
def test_synthesises_single_floor_dimension(self, epc: EpcPropertyData) -> None:
# Arrange
main_part = epc.sap_building_parts[0]
# Act / Assert
assert len(main_part.sap_floor_dimensions) == 1