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 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 "
| {header} | " in html, header assert "SERVICE DATE" not in html[html.index("
|---|