Spaces:
Runtime error
Runtime error
| """Tests for messy-notes routing into per-section RICS buckets. | |
| These tests pin the deterministic keyword router (no LLM). The router has | |
| to be reliable offline because the front-end calls it on every upload, and | |
| the LLM refinement pass is opt-in. | |
| """ | |
| from __future__ import annotations | |
| import pytest | |
| from app.generator.notes_router import route_notes | |
| async def test_route_explicit_section_code_wins() -> None: | |
| lines = ["E2: tiles slipped on north pitch"] | |
| out = await route_notes(lines, survey_level=3) | |
| assert out.bullets_by_section.get("E2") == ["E2: tiles slipped on north pitch"] | |
| async def test_route_roof_keywords_to_E2() -> None: | |
| lines = ["several roof tiles slipped at the ridge"] | |
| out = await route_notes(lines, survey_level=3) | |
| assert "E2" in out.bullets_by_section | |
| assert any("tiles slipped" in b for b in out.bullets_by_section["E2"]) | |
| async def test_route_boiler_to_G2() -> None: | |
| lines = ["boiler 18 years old, no recent service certificate"] | |
| out = await route_notes(lines, survey_level=3) | |
| assert "G2" in out.bullets_by_section | |
| async def test_route_damp_to_F9() -> None: | |
| lines = ["rising damp visible at rear hallway skirting"] | |
| out = await route_notes(lines, survey_level=3) | |
| # damp is the F9 primary signal; skirting also touches F7 — confirm damp wins | |
| assert "F9" in out.bullets_by_section | |
| async def test_route_unmatched_line_returned_in_unrouted() -> None: | |
| lines = ["[surveyor signature on file]"] | |
| out = await route_notes(lines, survey_level=3) | |
| # Generic chatter that doesn't map cleanly to any section | |
| assert out.unrouted_lines == lines or "__unrouted__" not in out.bullets_by_section | |
| async def test_route_mixed_dump_splits_across_sections() -> None: | |
| lines = [ | |
| "tile slipped on rear pitch", | |
| "gutters overflowing at front elevation", | |
| "consumer unit pre-2008, no RCD", | |
| "rising damp at rear hallway", | |
| ] | |
| out = await route_notes(lines, survey_level=3) | |
| codes = set(out.bullets_by_section.keys()) | |
| # Each of these should land in a distinct section | |
| assert "E2" in codes # roof tile | |
| assert "E3" in codes # gutters | |
| assert "G1" in codes # consumer unit / RCD | |
| assert "F9" in codes # damp | |
| async def test_route_respects_survey_level() -> None: | |
| lines = ["roof tiles slipped"] | |
| out_l1 = await route_notes(lines, survey_level=1) | |
| out_l3 = await route_notes(lines, survey_level=3) | |
| # Both packs have an E2-like roof section; the routing should succeed for both. | |
| assert any(k.startswith("E") for k in out_l1.bullets_by_section) | |
| assert any(k.startswith("E") for k in out_l3.bullets_by_section) | |