Bound admin list endpoint limits, add status filter to pending-transactions (B-45)
/admin/rounds and /admin/audit-log accepted any limit, including -1 (which SQLite treats as "no limit"), and /admin/pending-transactions had no limit at all -- it grows without end. Add Query(default=..., ge=1, le=500) to all three, plus an optional status filter on pending-transactions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -277,3 +277,90 @@ async def test_pause_cannot_be_toggled_through_the_config_endpoint(client):
|
||||
resp = await client.put("/admin/config", headers=headers, json={"paused": True})
|
||||
assert resp.status_code in (200, 422) # ignored or refused, but never applied
|
||||
assert (await client.get("/admin/config", headers=headers)).json()["paused"] is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("endpoint", ["/admin/rounds", "/admin/audit-log", "/admin/pending-transactions"])
|
||||
@pytest.mark.parametrize("bad_limit", [0, -1, 501])
|
||||
async def test_admin_list_endpoints_reject_out_of_range_limit(client, endpoint, bad_limit):
|
||||
"""B-45: `limit` had no bounds — `-1` means "everything" on SQLite, so an
|
||||
unvalidated limit could dump the entire table in one response."""
|
||||
headers = {"X-Admin-Token": "test-admin-token"}
|
||||
resp = await client.get(endpoint, headers=headers, params={"limit": bad_limit})
|
||||
assert resp.status_code == 422
|
||||
|
||||
|
||||
async def test_admin_list_rounds_respects_limit(client):
|
||||
from app.db import base as db_base
|
||||
from app.db.models import Round
|
||||
|
||||
async with db_base.AsyncSessionLocal() as session:
|
||||
session.add_all([Round(status="closed") for _ in range(3)])
|
||||
await session.commit()
|
||||
|
||||
headers = {"X-Admin-Token": "test-admin-token"}
|
||||
resp = await client.get("/admin/rounds", headers=headers, params={"limit": 2})
|
||||
assert resp.status_code == 200
|
||||
assert len(resp.json()) == 2
|
||||
|
||||
|
||||
async def test_admin_audit_log_respects_limit(client):
|
||||
from app.db import base as db_base
|
||||
from app.audit.log import write_audit_log
|
||||
|
||||
async with db_base.AsyncSessionLocal() as session:
|
||||
for _ in range(3):
|
||||
await write_audit_log(session, "test_event", {})
|
||||
await session.commit()
|
||||
|
||||
headers = {"X-Admin-Token": "test-admin-token"}
|
||||
resp = await client.get("/admin/audit-log", headers=headers, params={"limit": 2})
|
||||
assert resp.status_code == 200
|
||||
assert len(resp.json()) == 2
|
||||
|
||||
|
||||
async def _make_pending_transaction(session, *, kind="bet", status="pending"):
|
||||
from app.db.models import PendingTransaction
|
||||
import secrets as _secrets
|
||||
|
||||
tx = PendingTransaction(
|
||||
kind=kind,
|
||||
current_txid=_secrets.token_hex(32),
|
||||
fee_rate_sat_vb=1,
|
||||
raw_tx_hex="00",
|
||||
status=status,
|
||||
)
|
||||
session.add(tx)
|
||||
return tx
|
||||
|
||||
|
||||
async def test_admin_pending_transactions_respects_limit(client):
|
||||
from app.db import base as db_base
|
||||
|
||||
async with db_base.AsyncSessionLocal() as session:
|
||||
for _ in range(3):
|
||||
await _make_pending_transaction(session)
|
||||
await session.commit()
|
||||
|
||||
headers = {"X-Admin-Token": "test-admin-token"}
|
||||
resp = await client.get("/admin/pending-transactions", headers=headers, params={"limit": 2})
|
||||
assert resp.status_code == 200
|
||||
assert len(resp.json()) == 2
|
||||
|
||||
|
||||
async def test_admin_pending_transactions_status_filter(client):
|
||||
from app.db import base as db_base
|
||||
|
||||
async with db_base.AsyncSessionLocal() as session:
|
||||
await _make_pending_transaction(session, status="pending")
|
||||
await _make_pending_transaction(session, status="confirmed")
|
||||
await _make_pending_transaction(session, status="failed")
|
||||
await session.commit()
|
||||
|
||||
headers = {"X-Admin-Token": "test-admin-token"}
|
||||
resp = await client.get(
|
||||
"/admin/pending-transactions", headers=headers, params={"status": "confirmed"}
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
entries = resp.json()
|
||||
assert len(entries) == 1
|
||||
assert entries[0]["status"] == "confirmed"
|
||||
|
||||
Reference in New Issue
Block a user