"""Post-review services load from src; Emmaforo clamp contracts stay downgrade-only.""" from __future__ import annotations from pathlib import Path from backend.periscopex.models import Finding from backend.services.billing_hook import NullBilling, get_billing from backend.services.dedupe_findings import _build_deduped from backend.services.normalize_findings import _build_normalized import backend.services.billing_hook as billing_hook import backend.services.dedupe_findings as dedupe_findings import backend.services.normalize_findings as normalize_findings def test_postpass_modules_are_src(): for mod, name in ( (normalize_findings, "normalize_findings.py"), (dedupe_findings, "dedupe_findings.py"), (billing_hook, "billing_hook.py"), ): path = Path(mod.__file__).resolve() assert path.name == name assert "src" in path.parts assert "Native Periscope overlay" not in path.read_text(encoding="utf-8")[:500] def test_self_host_billing_is_null(): hook = get_billing() assert isinstance(hook, NullBilling) assert hook.credits_for_api_cost(12.0) == 0.0 def test_emmaforo_uart_normalize_cannot_promote_warning(): """U2-001 class: hedged UART abs-max must stay WARNING.""" originals = [ Finding( designator="U2", mpn="CH340E", finding="5V UART into MCU", why="Unverified: abs-max for PA14 not confirmed", status="WARNING", recommendation="level shift", source_page=11, source_quote="", reference="", ) ] raw = [{ "merged_from": [1], "finding": "CH340E 5V will damage the MCU", "why": "will damage the MCU", "status": "ERROR", "recommendation": "level shift", "change_rationale": "graded ERROR", }] built = _build_normalized(raw, [], originals) assert built is not None kept, _ = built assert kept[0].status == "WARNING" assert kept[0].why.lower().startswith("unverified:") def test_emmaforo_uart_dedupe_collapses_both_endpoints(): originals = [ Finding( designator="U2", mpn="CH340E", finding="5V out on UART", why="w", status="ERROR", recommendation="", source_page=11, source_quote="q2", reference="r2", ), Finding( designator="U3", mpn="ESP32", finding="PA14 overvoltage", why="w", status="ERROR", recommendation="", source_page=25, source_quote="q3", reference="r3", ), ] groups = [{ "member_indices": [1, 2], "primary_index": 2, "finding": "CH340E 5V into MCU UART pin", "why": "same UART interface", "status": "ERROR", "recommendation": "level shift", "change_rationale": "merged 1+2", }] built = _build_deduped(groups, originals) assert built is not None assert len(built) == 1 assert built[0].designator == "U3" assert built[0].source_page == 25