Portal Delete run (Super Admin), lab codes #3/#4, Z23 pointer #45, T1017 #46, payer note, login security-image wait

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ManikandanandClaude Opus 5.5 committed 2026-10-29 12:30:38 +05:30
1 parent a8af44e673
commit fafa5285eb
21 files changed
+1509 -63

No files matched your search

+83
View File
@@ -105,6 +105,16 @@ class FakeRepo:
self._maybe_fail()
return [dict(r) for r in self._rows if claim_no in r["claim_no"]]
delete_fails = None
def delete_run(self, run_at):
self.calls.append(("delete_run", run_at))
if self.delete_fails:
raise self.delete_fails
kept = [r for r in self._rows if r["run_at"] != run_at]
gone, self._rows = len(self._rows) - len(kept), kept
return gone
TESTER_PASSWORD = "tester-password-1"
@@ -581,6 +591,63 @@ def the_error_page_names_what_went_wrong():
assert "Smith" not in r.text, "the driver's message is never shown"
# ── Delete a run (Super Admin only, operator 2026-10-28) ─────────────────────
def _delete_run(client, app, run_at=RUN_PM, token=None):
return client.post("/admin/runs/delete", headers=_GOOD_ORIGIN,
data={"run_at": run_at.isoformat(),
"token": token or app.state.run_token},
follow_redirects=False)
@case
def a_super_admin_deletes_one_run_and_the_delete_is_recorded():
repo = FakeRepo()
client, app = signed_in(repo, FakeRunner(), role="Super Admin")
page = client.get(f"/day/{DAY.isoformat()}").text
assert page.count("Delete run") == 2, "one button per run of the day"
r = _delete_run(client, app)
assert r.status_code == 303, r.status_code
assert r.headers["location"].startswith(f"/day/{DAY.isoformat()}?"), \
r.headers["location"]
assert [x["run_at"] for x in repo._rows] == [RUN_AM], \
"only that run's rows go"
shown = client.get(r.headers["location"]).text
assert "2 claims deleted" in shown, shown
history = client.get("/admin/signins").text
assert "run deleted" in history and "10/16/2026 2:15 PM" in history, \
history
@case
def an_admin_or_viewer_cannot_see_or_use_delete_run():
for role in ("Admin", "Viewer"):
repo = FakeRepo()
client, app = signed_in(repo, FakeRunner(), role=role)
assert "Delete run" not in client.get(f"/day/{DAY.isoformat()}").text
assert _delete_run(client, app).status_code == 403, role
assert len(repo._rows) == 3, (role, "nothing deleted")
repo = FakeRepo()
client, app = signed_in(repo, FakeRunner(), role="Super Admin")
assert _delete_run(client, app, token="wrong").status_code == 403, \
"a page on another site cannot send it"
assert len(repo._rows) == 3
@case
def delete_run_without_the_sql_permission_says_so():
class DbError(Exception):
pass
repo = FakeRepo()
repo.delete_fails = DbError("42000", "The DELETE permission was denied")
client, app = signed_in(repo, FakeRunner(), role="Super Admin")
r = _quiet(_delete_run, client, app)
assert r.status_code == 503, r.status_code
assert "No permission to delete" in r.text, r.text
assert "GRANT DELETE" in r.text, r.text
# ── repo SQL ─────────────────────────────────────────────────────────────────
class FakeCursor:
@@ -590,6 +657,7 @@ class FakeCursor:
def execute(self, sql, params):
self.log.append((sql, list(params)))
self.rowcount = len(self.rows)
return self
def fetchall(self):
@@ -599,10 +667,14 @@ class FakeCursor:
class FakeConn:
def __init__(self, rows=(), cols=()):
self.log, self.rows, self.cols, self.closed = [], list(rows), cols, False
self.committed = False
def cursor(self):
return FakeCursor(self.log, self.rows, self.cols)
def commit(self):
self.committed = True
def close(self):
self.closed = True
@@ -611,6 +683,17 @@ def _repo(conn):
return SqlResultsRepo("DSN=x", connect=lambda cs, timeout: conn)
@case
def repo_deletes_exactly_one_run_and_commits():
conn = FakeConn(rows=[None] * 20) # the driver's rowcount: 20
assert _repo(conn).delete_run(RUN_PM) == 20
(sql, params), = conn.log
assert re.fullmatch(r"DELETE FROM dbo\.CV_ChargeSummary WHERE run_at = \?",
sql), sql
assert params == [RUN_PM], params
assert conn.committed and conn.closed
@case
def repo_turns_a_text_run_at_or_day_into_a_datetime_or_date():
"""The legacy {SQL Server} driver returns DATETIME2 / DATE as text."""