diff --git a/tests/repositories/epc/test_epc_round_trip.py b/tests/repositories/epc/test_epc_round_trip.py index ed49b6d9..ab6b7f65 100644 --- a/tests/repositories/epc/test_epc_round_trip.py +++ b/tests/repositories/epc/test_epc_round_trip.py @@ -86,6 +86,44 @@ def test_non_separated_conservatory_round_trips(db_engine: Engine) -> None: assert reloaded == original +def test_photovoltaic_arrays_round_trip(db_engine: Engine) -> None: + # SAP 10.2 Appendix M — a dwelling's solar PV arrays generate electricity that + # offsets demand, worth a large slice of the SAP score (≈12 points on an + # electrically-heated dwelling). `sap_energy_source.photovoltaic_arrays` had + # no table, so every array was dropped on save (persist != score). We inject + # two arrays (distinct, so ORDER is observable) onto a clean PV-free fixture + # so the ONLY thing that can break deep-equality is the array list itself. + from dataclasses import replace + + from datatypes.epc.domain.epc_property_data import PhotovoltaicArray + + # Arrange — a green fixture with no PV, plus two ordered arrays. + original = _load_epc("RdSAP-Schema-21.0.1") + assert original.sap_energy_source.photovoltaic_arrays is None, ( + "fixture must start PV-free so the array list is the only variable" + ) + arrays = [ + PhotovoltaicArray(peak_power=3.24, pitch=3, overshading=1, orientation=3), + PhotovoltaicArray(peak_power=1.5, pitch=2, overshading=2, orientation=None), + ] + original = replace( + original, + sap_energy_source=replace( + original.sap_energy_source, photovoltaic_arrays=arrays + ), + ) + + # Act + with Session(db_engine) as session: + epc_property_id = EpcPostgresRepository(session).save(original) + session.commit() + with Session(db_engine) as session: + reloaded = EpcPostgresRepository(session).get(epc_property_id) + + # Assert — both arrays survive in order, deep-equal. + assert reloaded == original + + def test_floor_dimension_heat_loss_flags_round_trip(db_engine: Engine) -> None: # SAP 10.2 §3.3 — `is_exposed_floor` and `is_above_partially_heated_space` # are heat-loss flags on a `SapFloorDimension`: the calculator routes a floor