Refactor: split serve/server.py (3220 lines) into focused modules
serve/server.py is now 69 lines — app factory, middleware, and router
registration only.
New modules:
deps.py (168 lines) — module-level globals + auth dependency functions
models.py (85 lines) — all Pydantic request/response models
tasks.py (136 lines) — background workers and job tracker
routers/ — one file per domain (10 routers, ~2750 lines total)
auth.py, me.py, admin.py, activities.py, uploads.py,
segments.py, strava.py, garmin.py, ideas.py, feed.py
cli.py updated to set globals on deps instead of server.
88 new regression tests in tests/serve/ cover auth guards and key
behaviours for every router; 294 total passing after the split.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
"""Pre-split regression tests for /api/admin/* routes."""
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
class TestAdminUsers:
|
||||
def test_unauthenticated_returns_401(self, client: TestClient):
|
||||
assert client.get("/api/admin/users").status_code == 401
|
||||
|
||||
def test_non_admin_returns_403(self, user_client: TestClient):
|
||||
assert user_client.get("/api/admin/users").status_code == 403
|
||||
|
||||
def test_admin_returns_user_list(self, admin_client: TestClient):
|
||||
r = admin_client.get("/api/admin/users")
|
||||
assert r.status_code == 200
|
||||
assert isinstance(r.json(), list)
|
||||
|
||||
|
||||
class TestAdminJobs:
|
||||
def test_unauthenticated_returns_401(self, client: TestClient):
|
||||
assert client.get("/api/admin/jobs").status_code == 401
|
||||
|
||||
def test_non_admin_returns_403(self, user_client: TestClient):
|
||||
assert user_client.get("/api/admin/jobs").status_code == 403
|
||||
|
||||
def test_admin_returns_jobs_list(self, admin_client: TestClient):
|
||||
r = admin_client.get("/api/admin/jobs")
|
||||
assert r.status_code == 200
|
||||
assert isinstance(r.json(), list)
|
||||
|
||||
|
||||
class TestAdminDisk:
|
||||
def test_unauthenticated_returns_401(self, client: TestClient):
|
||||
assert client.get("/api/admin/disk").status_code == 401
|
||||
|
||||
def test_non_admin_returns_403(self, user_client: TestClient):
|
||||
assert user_client.get("/api/admin/disk").status_code == 403
|
||||
|
||||
def test_admin_returns_disk_info(self, admin_client: TestClient):
|
||||
r = admin_client.get("/api/admin/disk")
|
||||
assert r.status_code == 200
|
||||
data = r.json()
|
||||
assert "users" in data
|
||||
assert "total_gb" in data.get("disk", {})
|
||||
|
||||
|
||||
class TestAdminUserOps:
|
||||
def test_reset_password_code_requires_admin(self, client: TestClient, user_client: TestClient):
|
||||
assert client.post("/api/admin/users/alice/reset-password-code").status_code == 401
|
||||
assert user_client.post("/api/admin/users/admin/reset-password-code").status_code == 403
|
||||
|
||||
def test_suspend_requires_admin(self, client: TestClient):
|
||||
assert client.post("/api/admin/users/alice/suspend").status_code == 401
|
||||
|
||||
def test_unsuspend_requires_admin(self, client: TestClient):
|
||||
assert client.post("/api/admin/users/alice/unsuspend").status_code == 401
|
||||
|
||||
def test_delete_account_requires_admin(self, client: TestClient):
|
||||
assert client.delete("/api/admin/users/alice/account").status_code == 401
|
||||
|
||||
def test_admin_reset_password_code(self, admin_client: TestClient, tmp_data):
|
||||
from bincio.serve.db import create_user, open_db
|
||||
db = open_db(tmp_data)
|
||||
try:
|
||||
create_user(db, "target", "Target", "targetpass1")
|
||||
except Exception:
|
||||
pass
|
||||
r = admin_client.post("/api/admin/users/target/reset-password-code")
|
||||
assert r.status_code == 200
|
||||
assert "code" in r.json()
|
||||
Reference in New Issue
Block a user