Update admin theme/layout and refresh README details.

Align the project baseline with the latest admin interface styling and layout structure while documenting setup and usage updates in README.
This commit is contained in:
vlad
2026-07-14 17:12:28 +03:00
commit 86cc3fa541
278 changed files with 19416 additions and 0 deletions
@@ -0,0 +1,170 @@
from tests.fixtures import make_test_png
from tests.helpers import latest_token, register_and_verify, register_verify_login
def _admin_headers(client) -> dict[str, str]:
login = client.post(
"/api/v1/auth/login",
json={"email": "admin@compton.example", "password": "Admin1234"},
)
token = login.json()["access_token"]
return {"Authorization": f"Bearer {token}"}
def test_auth_refresh_and_logout(client):
register_and_verify(client, "refresh@example.com")
login = client.post(
"/api/v1/auth/login",
json={"email": "refresh@example.com", "password": "Valid123"},
)
assert login.status_code == 200
assert "refresh_token" in login.cookies
refresh = client.post("/api/v1/auth/refresh", headers={"Origin": "http://localhost:5173"})
assert refresh.status_code == 200
assert "access_token" in refresh.json()
logout = client.post("/api/v1/auth/logout", headers={"Origin": "http://localhost:5173"})
assert logout.status_code == 200
def test_auth_invalid_login(client):
response = client.post(
"/api/v1/auth/login",
json={"email": "missing@example.com", "password": "Valid123"},
)
assert response.status_code == 401
def test_users_patch_and_password_and_avatar(client):
headers = register_verify_login(client, "patch@example.com")
patch = client.patch("/api/v1/users/me", headers=headers, json={"display_name": "Patched"})
assert patch.status_code == 200
assert patch.json()["profile"]["display_name"] == "Patched"
bad_password = client.post(
"/api/v1/users/me/password",
headers=headers,
json={"current_password": "wrong", "new_password": "NewValid1"},
)
assert bad_password.status_code == 400
avatar = client.post(
"/api/v1/users/me/avatar",
headers=headers,
files={"file": ("avatar.png", make_test_png(), "image/png")},
)
assert avatar.status_code == 200
assert avatar.json()["profile"]["avatar_url"]
def test_users_unauthorized(client):
response = client.get("/api/v1/users/me")
assert response.status_code == 401
def test_content_crud_flow(client):
headers = _admin_headers(client)
created = client.post(
"/api/v1/content/pages",
headers=headers,
json={"slug": "terms", "title": "Terms", "body": "<p>Terms</p>", "status": "draft"},
)
assert created.status_code == 200
page_id = created.json()["id"]
listed = client.get("/api/v1/content/pages")
assert listed.status_code == 200
updated = client.patch(
f"/api/v1/content/pages/{page_id}",
headers=headers,
json={"status": "published"},
)
assert updated.status_code == 200
fetched = client.get("/api/v1/content/pages/terms")
assert fetched.status_code == 200
deleted = client.delete(f"/api/v1/content/pages/{page_id}", headers=headers)
assert deleted.status_code == 200
def test_admin_stats_and_patch_user(client):
headers = _admin_headers(client)
stats = client.get("/api/v1/admin/stats", headers=headers)
assert stats.status_code == 200
user_headers = register_verify_login(client, "blockme@example.com")
me = client.get("/api/v1/users/me", headers=user_headers)
user_id = me.json()["user"]["id"]
blocked = client.patch(
f"/api/v1/admin/users/{user_id}",
headers=headers,
json={"status": "blocked"},
)
assert blocked.status_code == 200
assert blocked.json()["status"] == "blocked"
def test_auth_pending_user_cannot_login(client):
client.post("/api/v1/auth/register", json={"email": "pending@example.com", "password": "Valid123"})
response = client.post(
"/api/v1/auth/login",
json={"email": "pending@example.com", "password": "Valid123"},
)
assert response.status_code == 403
assert response.json()["detail"] == "EMAIL_NOT_VERIFIED"
def test_pending_user_cannot_access_profile(client):
from app.core.security import create_access_token
from app.modules.users.repository import get_user_by_email
client.post("/api/v1/auth/register", json={"email": "pendingme@example.com", "password": "Valid123"})
user = get_user_by_email("pendingme@example.com")
token = create_access_token(user.id, user.role)
response = client.get("/api/v1/users/me", headers={"Authorization": f"Bearer {token}"})
assert response.status_code == 403
assert response.json()["detail"] == "EMAIL_NOT_VERIFIED"
def test_auth_invalid_refresh_token(client):
response = client.post("/api/v1/auth/refresh")
assert response.status_code == 401
client.cookies.set("refresh_token", "invalid-token", path="/api/v1/auth")
invalid = client.post("/api/v1/auth/refresh", headers={"Origin": "http://localhost:5173"})
assert invalid.status_code == 401
def test_auth_resend_and_reset_password(client):
client.post("/api/v1/auth/register", json={"email": "resetme@example.com", "password": "Valid123"})
resend = client.post("/api/v1/auth/resend-verification", json={"email": "resetme@example.com"})
assert resend.status_code == 200
verify_token = latest_token("resetme@example.com", "verify_email")
verify = client.post("/api/v1/auth/verify-email", json={"token": verify_token})
assert verify.status_code == 200
forgot = client.post("/api/v1/auth/forgot-password", json={"email": "resetme@example.com"})
assert forgot.status_code == 200
reset_token = latest_token("resetme@example.com", "reset_password")
reset = client.post(
"/api/v1/auth/reset-password",
json={"token": reset_token, "new_password": "NewValid1"},
)
assert reset.status_code == 200
login = client.post(
"/api/v1/auth/login",
json={"email": "resetme@example.com", "password": "NewValid1"},
)
assert login.status_code == 200
invalid = client.post(
"/api/v1/auth/reset-password",
json={"token": "invalid-token", "new_password": "NewValid1"},
)
assert invalid.status_code == 400