"""Regression: GET /api/acks, /api/ta1-acks, /api/277ca-acks must be reachable for an authenticated admin. The PERMISSIONS matrix only listed the ``POST /api/acks`` (parse-999) entry, so the GET list/detail endpoints returned 403 to admins and broke the Inbox / 999 ACKs pages on the UI. This test exercises the matrix via the public login route — not by flipping ``AUTH_DISABLED`` — so a missing ``("GET", "/api/-acks"): ALL_ROLES`` entry would surface as 403. """ from __future__ import annotations import pytest from fastapi.testclient import TestClient from sqlalchemy import delete from cyclone.api import app from cyclone.auth import users from cyclone.db import Session as DbSession from cyclone.db import SessionLocal, User @pytest.fixture(autouse=True) def _clear(monkeypatch): monkeypatch.setattr("cyclone.auth.deps.AUTH_DISABLED", False) with SessionLocal()() as db: db.execute(delete(DbSession)) db.execute(delete(User)) db.commit() yield with SessionLocal()() as db: db.execute(delete(DbSession)) db.execute(delete(User)) db.commit() @pytest.fixture def client(): return TestClient(app) @pytest.fixture def admin_client(client): with SessionLocal()() as db: users.create(db, username="admin", password="adminpassword1", role="admin") resp = client.post( "/api/auth/login", json={"username": "admin", "password": "adminpassword1"}, ) assert resp.status_code == 200 return client @pytest.mark.parametrize("path", [ "/api/acks", "/api/acks/0", "/api/ta1-acks", "/api/ta1-acks/0", "/api/277ca-acks", "/api/277ca-acks/0", ]) def test_admin_can_list_and_detail_all_ack_kinds(admin_client, path): resp = admin_client.get(path, headers={"Accept": "application/json"}) # 200 for the list endpoint (empty rows is fine), 404 for the detail # of a non-existent id (the gate must let the request through). assert resp.status_code in (200, 404), ( f"{path} returned {resp.status_code}: {resp.text}" ) assert resp.status_code != 403, ( f"{path} returned 403 — PERMISSIONS matrix is missing a GET entry" )