Fill partial summaries best-effort, fail loudly, skip evidence-only jobs, and retry on Coordination Hub 🟩

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-14 13:49:02 +00:00
parent 377c030c77
commit 62c0151469

View file

@ -783,3 +783,116 @@ def test_run_overlays_full_lodged_performance_onto_saved_site_notes() -> None:
assert saved.current_energy_efficiency_band == Epc.C
assert saved.co2_emissions_current == 1.70
assert saved.energy_consumption_current == 117
def test_run_overlays_only_present_fields_when_summary_partial() -> None:
# Arrange — only the SAP rating comes back; CO2 and PEUI are null
mock_client = _site_note_client(
summary=RdSapSummary(
pre_sap_rating=78.0,
pre_current_co2_emissions=None,
pre_current_energy_consumption=None,
)
)
parsed = make_epc_property_data()
service = make_service(pashub_client=mock_client)
# Act
with (
patch("backend.pashub_fetcher.pashub_service.upload_file_to_s3"),
patch(
"backend.pashub_fetcher.pashub_service.parse_site_notes_pdf",
return_value=parsed,
),
patch(
"backend.pashub_fetcher.pashub_service.save_epc_property_data"
) as mock_save,
patch("backend.pashub_fetcher.pashub_service.db_session"),
patch("backend.pashub_fetcher.pashub_service.os.remove"),
):
service.run(make_request(uprn="12345"))
# Assert
saved: EpcPropertyData = mock_save.call_args[0][1]
assert saved.energy_rating_current == 78
assert saved.current_energy_efficiency_band == Epc.C
assert saved.co2_emissions_current is None
assert saved.energy_consumption_current is None
def test_run_raises_and_skips_persistence_when_summary_fetch_fails() -> None:
# Arrange — the RdSAP Site Note is present but its summary cannot be fetched
mock_client = _site_note_client()
mock_client.get_rdsap_summary_by_job_id.side_effect = RuntimeError("summary down")
service = make_service(pashub_client=mock_client)
# Act / Assert
with (
patch("backend.pashub_fetcher.pashub_service.upload_file_to_s3") as mock_s3,
patch(
"backend.pashub_fetcher.pashub_service.save_epc_property_data"
) as mock_save,
patch("backend.pashub_fetcher.pashub_service.db_session"),
patch("backend.pashub_fetcher.pashub_service.os.remove"),
):
with pytest.raises(RuntimeError):
service.run(make_request(uprn="12345"))
mock_save.assert_not_called()
mock_s3.assert_called() # S3 upload happened before the loud site-note save
def test_run_does_not_fetch_summary_for_evidence_only_job() -> None:
# Arrange — a plain Site Note (not an RdSAP Site Note) carries no summary
mock_client = _site_note_client(core=["/tmp/SiteNote_001.pdf"])
service = make_service(pashub_client=mock_client)
# Act
with (
patch("backend.pashub_fetcher.pashub_service.upload_file_to_s3"),
patch("backend.pashub_fetcher.pashub_service.db_session"),
patch("backend.pashub_fetcher.pashub_service.os.remove"),
):
service.run(make_request(uprn="12345"))
# Assert
mock_client.get_rdsap_summary_by_job_id.assert_not_called()
def test_run_fetches_summary_from_coordination_client_on_primary_auth_failure() -> None:
# Arrange — primary credentials 401 on the summary; coordination succeeds
pas_client = _site_note_client()
pas_client.get_rdsap_summary_by_job_id.side_effect = UnauthorizedError()
coord_client = MagicMock(spec=PashubClient)
coord_client.get_rdsap_summary_by_job_id.return_value = RdSapSummary(
pre_sap_rating=78.0,
pre_current_co2_emissions=1.70,
pre_current_energy_consumption=117.0,
)
factory = MagicMock(return_value=coord_client)
parsed = make_epc_property_data()
service = make_service(
pashub_client=pas_client, coordination_client_factory=factory
)
# Act
with (
patch("backend.pashub_fetcher.pashub_service.upload_file_to_s3"),
patch(
"backend.pashub_fetcher.pashub_service.parse_site_notes_pdf",
return_value=parsed,
),
patch(
"backend.pashub_fetcher.pashub_service.save_epc_property_data"
) as mock_save,
patch("backend.pashub_fetcher.pashub_service.db_session"),
patch("backend.pashub_fetcher.pashub_service.os.remove"),
):
service.run(make_request(uprn="12345"))
# Assert
coord_client.get_rdsap_summary_by_job_id.assert_called_once()
saved: EpcPropertyData = mock_save.call_args[0][1]
assert saved.energy_rating_current == 78