r""" web/app.py and web/repo.py — the results portal, against a fake repository and a fake database connection (no SQL Server needed). Spec: docs/superpowers/specs/2026-10-19-results-portal-redesign-design.md. python tests\test_web_app.py Claim numbers here are made up. """ import io import re import sys import json import pathlib import tempfile import contextlib from datetime import date, datetime, timedelta from decimal import Decimal ROOT = pathlib.Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT / "src")) from fastapi.testclient import TestClient # noqa: E402 from web import app as web_app # noqa: E402 from web.repo import SqlResultsRepo # noqa: E402 from ecw_bot.core import results_db as rdb # noqa: E402 from web import users as portal_users # noqa: E402 sys.path.insert(0, str(ROOT / "tests")) from test_portal_users import FakeUserStore # noqa: E402 CASES = [] def case(fn): CASES.append(fn) return fn DAY = date(2026, 10, 16) RUN_AM = datetime(2026, 10, 16, 10, 30, 0) # 10 claims run RUN_PM = datetime(2026, 10, 16, 14, 15, 0) # 20 claims run, same day RUN_OLD = datetime(2026, 10, 15, 11, 0, 0) def _row(claim, category, s_no, run_at=RUN_PM, **over): row = {c: None for _, c in rdb.COLUMNS} row.update({"id": s_no, "run_at": run_at, "run_mode": "VERIFY", "s_no": s_no, "claim_no": claim, "category": category, "service_date": date(2026, 7, 31), "payer": "Medicaid", "charges": Decimal("1365.00"), "comments": f"comment {claim}", "current_status": "Corrections pending (not saved)", "details_json": json.dumps({"fired": ["dummy_codes"]})}) row.update(over) return row def _day(day, claims, runs, p, f, r): return {"day": day, "claims": claims, "runs": runs, "pass_count": p, "fail_count": f, "review_count": r} class FakeRepo: def __init__(self, days=None, rows=None, fail=False): self._days = days if days is not None else [ _day(DAY, 3, 2, 1, 1, 1), _day(RUN_OLD.date(), 2, 1, 2, 0, 0)] self._rows = rows if rows is not None else [ _row("9000001", "Pass", 1, RUN_AM), _row("9000002", "Fail", 1, details_json=None), _row("9000003", "Review", 2, payer="HCFA Medicare")] self.fail = fail self.calls = [] def _maybe_fail(self): if self.fail: raise self.fail if isinstance(self.fail, Exception) \ else RuntimeError("Login failed for user") def runs(self): self._maybe_fail() return [{"run_at": RUN_PM, "run_mode": "VERIFY", "claims": 2, "pass_count": 0, "fail_count": 1, "review_count": 1}] def results(self, run_at, category=None, claim_no=None): self.calls.append(("results", run_at, category, claim_no)) self._maybe_fail() return [r for r in self._rows if (not category or r["category"] == category)] def days(self, limit=90): self.calls.append(("days",)) self._maybe_fail() return self._days def day_results(self, day): self.calls.append(("day_results", day)) self._maybe_fail() return [dict(r) for r in self._rows if r["run_at"].date() == day] def claim_history(self, claim_no): self.calls.append(("claim_history", claim_no)) self._maybe_fail() return [dict(r) for r in self._rows if claim_no in r["claim_no"]] TESTER_PASSWORD = "tester-password-1" def signed_in(repo, runner, base_url="http://127.0.0.1:8000", role="Admin", **kw): """(client, app): the Portal with one Portal User, signed in — every page needs a Sign-in since 2026-10-22 (EEWA-32). A foreign host gets its 400 before any Sign-in, so there it is not tried.""" store = FakeUserStore() portal_users.Accounts(store).create_user("tester", "Tester", role, TESTER_PASSWORD) # No run events unless a test brings its own: the real Logs\ would # make the Dashboard's last-run banner depend on the PC. kw.setdefault("logs_dir", tempfile.mkdtemp()) app = web_app.create_app(repo, runner=runner, users_store=store, **kw) client = TestClient(app, base_url=base_url) if base_url in web_app.ALLOWED_ORIGINS: r = client.post("/signin", headers={"Origin": base_url}, data={ "username": "tester", "password": TESTER_PASSWORD, "token": app.state.run_token, "next": "/account/password"}) # A page that reads no database: FakeRepo(fail=True) must not # break the Sign-in itself. assert r.status_code == 200, r.status_code assert r.url.path == "/account/password", r.url return client, app def _client(repo=None, base_url="http://127.0.0.1:8000"): repo = repo or FakeRepo() client, _ = signed_in(repo, FakeRunner(), base_url=base_url) return client, repo class FakeRunner: def __init__(self, running=False, stop_fails=None): self.running = running self.stop_fails = stop_fails self.calls = [] def _st(self): return {"running": self.running, "starting": False, "pid": 1, "started_at": "2026-10-14T10:00:00", "ended_at": None, "exit_code": None, "stopped_by_operator": False, "source": "web", "log_path": None, "out_path": None} def start(self, started_by=""): self.calls.append("start") self.started_by = started_by if self.running: raise web_app.AlreadyRunning("A run is already going (started x)") self.running = True return self._st() def stop(self, stopped_by=""): self.calls.append("stop") self.stopped_by = stopped_by if self.stop_fails: raise web_app.StopFailed(self.stop_fails) if not self.running: raise web_app.NotRunning("No run is going") self.running = False return self._st() def status(self): return self._st() def _bot_client(runner=None): runner = runner or FakeRunner() client, app = signed_in(FakeRepo(), runner) return (client, runner, app.state.run_token) _GOOD_ORIGIN = {"Origin": "http://127.0.0.1:8000"} _PAGES = ("/", "/days", f"/day/{DAY.isoformat()}", "/claim?claim_no=9000") def _quiet(fn, *a, **k): with contextlib.redirect_stdout(io.StringIO()): return fn(*a, **k) def _css_rule(html, selector): """What `selector { ... }` in the page's ")] rule = css[css.index("\n " + selector + " {"):] return rule[:rule.index("}")] # ── Dashboard ──────────────────────────────────────────────────────────────── @case def the_dashboard_has_no_claims_table(): """Operator, 2026-10-19: the claims table (three quarters of the page) is not on the home page — the Bot run card, today's counts, Find a claim and one Claim status button are.""" client, repo = _client() html = client.get("/").text assert "