mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Mirrors the Elmhurst `UnmappedElmhurstLabel` coverage gate on the GOV.UK API path. The same failure mode (silently routing an unknown enum to a default / None hides cascade gaps until a downstream SAP- delta investigation surfaces them) was hitting the API mapper: existing helpers like `_api_floor_construction_str` returned None on unrecognised codes per the comment "Only the values observed across the 10 golden fixtures (1, 2) are mapped; unrecognised codes fall through to None." Adds `UnmappedApiCode(ValueError)` at the API mapper boundary and threads it through five strict helpers: - `_api_party_wall_construction_int` (RdSAP10 Table 15) - `_api_floor_construction_str` (Slice 88 floor signal) - `_api_floor_type_str` (RdSAP10 §5 rule (12)) - `_api_roof_construction_str` (Slice 89 cos(30°) factor) - `_api_sheltered_sides` (SAP10.2 §S5) Each helper distinguishes: - "lodging absent" → return None (unchanged behaviour) - "lodging present and mapped" → translate (unchanged behaviour) - "lodging present but unrecognised" → raise UnmappedApiCode (NEW) Two coverage gaps surfaced immediately at strict-run, both fixed in the same slice with the worksheet-backed lodged-floor descriptions: 1. `floor_heat_loss=2` — cert 7536 Main lodges this (floors[] description "To unheated space, insulated"); also lodged on cert 2031 / etc. Added mapping → "To unheated space". 2. `floor_heat_loss=3` — cert 7536 Ext2 lodges this with the same floors[] description as Main code 2 — same cascade signal. 3. `floor_heat_loss=6` — cert 9501 + cert 9390 (top-floor flats) lodge this with floors[] description "(another dwelling below)". The cascade routes party-floor handling via property_type=Flat + cert.floors[] description independently of this string, so the explicit None entry preserves the cascade match (cert 9501 stays at exact 1e-4 SAP vs worksheet 68.5252) while distinguishing "decided no string" from "unknown". Six new tests document the contract: - Five unit tests inject an out-of-range integer (99) into a real cohort cert JSON and assert UnmappedApiCode raises with the right `field` and `value`. - One coverage forcing function (`test_all_golden_fixtures_extract _via_api_without_unmapped_code_raise`) loops every JSON under `fixtures/golden/` through `from_api_response` and asserts no raise — future fixtures with unmapped enums fail this test until a dict entry is added. 763 → 769 pass + 0 fail (5 unit + 1 cohort-coverage test added). Pyright net-zero (32 → 32 baseline preserved). The pattern is ready to extend to other silently-falling-through helpers — e.g., `_api_glazing_transmission` (codes 4-12, 15+ noted in the existing comment as "not yet mapped — incremental coverage as new fixtures surface them"), `_api_cascade_glazing_type` (pass- through is intentional, so probably leave alone). Each addition is its own slice. |
||
|---|---|---|
| .. | ||
| epc | ||
| magicplan | ||
| __init__.py | ||
| datatypes.py | ||
| enums.py | ||