diff --git a/backend/documents_parser/tests/test_summary_pdf_mapper_chain.py b/backend/documents_parser/tests/test_summary_pdf_mapper_chain.py index 18e68a60..557ea037 100644 --- a/backend/documents_parser/tests/test_summary_pdf_mapper_chain.py +++ b/backend/documents_parser/tests/test_summary_pdf_mapper_chain.py @@ -58,6 +58,7 @@ _SUMMARY_000516_PDF = _FIXTURES / "Summary_000516.pdf" _SUMMARY_001479_PDF = _FIXTURES / "Summary_001479.pdf" _SUMMARY_000897_PDF = _FIXTURES / "Summary_000897.pdf" _SUMMARY_000784_PDF = _FIXTURES / "Summary_000784.pdf" +_SUMMARY_000899_PDF = _FIXTURES / "Summary_000899.pdf" # GOV.UK EPB API JSON for cert 001479 — the API-path counterpart of the # Summary_001479.pdf fixture. Together they drive the API ≡ Summary @@ -491,6 +492,34 @@ def test_summary_0330_full_chain_sap_matches_worksheet_pdf_exactly() -> None: assert abs(result.sap_score_continuous - worksheet_unrounded_sap) < 1e-4 +def test_summary_0380_full_chain_sap_matches_worksheet_pdf_exactly() -> None: + # Arrange — cert 0380-2471-3250-2596-8761 (Summary_000899.pdf / + # dr87-0001-000899.pdf) is the first heat-pump cert under per-cert + # Summary-path mapper validation: Mitsubishi PUZ-WM50VHA ASHP + # (PCDB index 104568), semi-detached bungalow age D, TFA 60.43 m². + # Worksheet PDF "SAP value" line lodges unrounded SAP **88.5104**. + # API-path cohort already pinned at the ±0.07 spec-precision floor + # (SAP 88.5698, Δ +0.0594); the Summary path becomes the canonical + # reference once it closes to 1e-4 — same pattern boilers 001479 + # and 0330 followed. Diagnostic probe at handover baseline: the + # Elmhurst mapper surfaces main_heating_index_number=104568 but + # leaves main_heating_category=None, so the cascade misroutes off + # the heat-pump path and lands at SAP 33.7920 (Δ -54.7184). + pages = _summary_pdf_to_textract_style_pages(_SUMMARY_000899_PDF) + site_notes = ElmhurstSiteNotesExtractor(pages).extract() + epc = EpcPropertyDataMapper.from_elmhurst_site_notes(site_notes) + + # Act + result = calculate_sap_from_inputs( + cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES) + ) + + # Assert — 1e-4 pin, no widening, no xfail (project memory + # `feedback_zero_error_strict`). + worksheet_unrounded_sap = 88.5104 + assert abs(result.sap_score_continuous - worksheet_unrounded_sap) < 1e-4 + + _API_0330_JSON = ( Path(__file__).parents[3] / "domain/sap10_calculator/rdsap/tests/fixtures/golden"