Align the project baseline with the latest admin interface styling and layout structure while documenting setup and usage updates in README.
171 lines
5.9 KiB
Python
171 lines
5.9 KiB
Python
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
|