This commit is contained in:
amb
2026-09-01 13:00:36 +08:00
parent 1d8621717a
commit dfd38c99a0
35 changed files with 3141 additions and 21 deletions
+208
View File
@@ -0,0 +1,208 @@
"""Phase 3 认证测试:注册、登录、登出、鉴权、IDOR 防护。"""
from fastapi.testclient import TestClient
from app.main import app
def _client() -> TestClient:
return TestClient(app, raise_server_exceptions=False)
# --- 注册 ---
def test_register_success() -> None:
with _client() as client:
resp = client.post("/api/auth/register", json={
"username": "alice",
"email": "alice@example.com",
"password": "password123",
})
assert resp.status_code == 201
body = resp.json()
assert body["username"] == "alice"
assert body["email"] == "alice@example.com"
assert body["storage_quota"] == 104_857_600
# Cookie 已签发
assert "session_id" in resp.cookies
def test_register_duplicate_username() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "bob",
"email": "bob@example.com",
"password": "password123",
})
resp = client.post("/api/auth/register", json={
"username": "bob",
"email": "bob2@example.com",
"password": "password123",
})
assert resp.status_code == 409
assert resp.json()["code"] == "USERNAME_TAKEN"
def test_register_duplicate_email() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "carol",
"email": "carol@example.com",
"password": "password123",
})
resp = client.post("/api/auth/register", json={
"username": "carol2",
"email": "carol@example.com",
"password": "password123",
})
assert resp.status_code == 409
assert resp.json()["code"] == "EMAIL_TAKEN"
def test_register_short_password() -> None:
with _client() as client:
resp = client.post("/api/auth/register", json={
"username": "dave",
"email": "dave@example.com",
"password": "short",
})
assert resp.status_code == 422
# --- 登录 ---
def test_login_by_username() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "eve",
"email": "eve@example.com",
"password": "password123",
})
resp = client.post("/api/auth/login", json={
"username_or_email": "eve",
"password": "password123",
})
assert resp.status_code == 200
assert resp.json()["username"] == "eve"
assert "session_id" in resp.cookies
def test_login_by_email() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "frank",
"email": "frank@example.com",
"password": "password123",
})
resp = client.post("/api/auth/login", json={
"username_or_email": "frank@example.com",
"password": "password123",
})
assert resp.status_code == 200
assert resp.json()["username"] == "frank"
def test_login_wrong_password() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "grace",
"email": "grace@example.com",
"password": "password123",
})
resp = client.post("/api/auth/login", json={
"username_or_email": "grace",
"password": "wrongpassword",
})
assert resp.status_code == 401
assert resp.json()["code"] == "AUTH_INVALID_CREDENTIALS"
def test_login_nonexistent_user() -> None:
with _client() as client:
resp = client.post("/api/auth/login", json={
"username_or_email": "nobody",
"password": "password123",
})
assert resp.status_code == 401
# --- 登出 ---
def test_logout() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "heidi",
"email": "heidi@example.com",
"password": "password123",
})
resp = client.post("/api/auth/logout")
assert resp.status_code == 204
# --- /api/me ---
def test_me_authenticated() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "ivan",
"email": "ivan@example.com",
"password": "password123",
})
resp = client.get("/api/auth/me")
assert resp.status_code == 200
body = resp.json()
assert body["username"] == "ivan"
assert body["storage_used"] == 0
def test_me_unauthenticated() -> None:
with _client() as client:
resp = client.get("/api/auth/me")
assert resp.status_code == 401
assert resp.json()["code"] == "AUTH_REQUIRED"
# --- IDOR 防护 ---
def test_user_a_cannot_see_user_b() -> None:
"""用户A 登录后,session 只能访问自己的 /me。"""
with _client() as client:
client.post("/api/auth/register", json={
"username": "user_a",
"email": "a@example.com",
"password": "password123",
})
# user_a 已登录(Cookie 自动携带)
me_resp = client.get("/api/auth/me")
assert me_resp.status_code == 200
assert me_resp.json()["username"] == "user_a"
def test_storage_endpoint() -> None:
with _client() as client:
client.post("/api/auth/register", json={
"username": "storage_user",
"email": "storage@example.com",
"password": "password123",
})
resp = client.get("/api/auth/storage")
assert resp.status_code == 200
body = resp.json()
assert body["storage_used"] == 0
assert body["storage_quota"] == 104_857_600
assert body["storage_quota_mb"] == 100.0
# --- free plan seed ---
def test_free_plan_auto_created() -> None:
"""free plan 应在应用启动时自动创建。"""
with _client() as client:
client.post("/api/auth/register", json={
"username": "plan_user",
"email": "plan@example.com",
"password": "password123",
})
resp = client.get("/api/auth/me")
assert resp.status_code == 200
assert resp.json()["storage_quota"] == 104_857_600