fad458b2a7
- UIUX 文档:填充 19 个缺口(多主体画像/健康度/AI+看板/增长域/洞察域/创始人端/OODA/助推/商密) - UIUX 文档:插入 6 个新章节(十四~十九),旧章节重编号为二十~三十一,更新目录和交叉引用 - 作业指导书 x5:导航改为 6 域分组,新增 Context Bar/工作模式/Insight Rail/决策线程/多工作区等 UI 概念 - 新建 docs/2-task-uiux.md:50 个代码落地开发任务,按 P0-P6 分优先级 + 8 Sprint 规划 - 后端/前端:大量新增模型、路由、组件(来自之前 Phase 开发)
164 lines
5.3 KiB
Python
164 lines
5.3 KiB
Python
"""认证流程测试。
|
|
|
|
测试注册、登录、获取当前用户、刷新 token 的完整流程。
|
|
"""
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
class TestRegister:
|
|
"""注册测试。"""
|
|
|
|
def test_register_success(self, client: TestClient):
|
|
"""RED→GREEN: 正常注册应返回 token。"""
|
|
response = client.post(
|
|
"/api/v1/auth/register",
|
|
json={
|
|
"email": "test@example.com",
|
|
"password": "password123",
|
|
"name": "测试用户",
|
|
"tenant_name": "测试投资机构",
|
|
"role": "founder",
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["code"] == 0
|
|
assert data["data"]["access_token"] is not None
|
|
assert data["data"]["refresh_token"] is not None
|
|
assert data["data"]["token_type"] == "bearer"
|
|
|
|
def test_register_duplicate_email(self, client: TestClient):
|
|
"""RED→GREEN: 重复邮箱注册应返回 409。"""
|
|
response = client.post(
|
|
"/api/v1/auth/register",
|
|
json={
|
|
"email": "test@example.com",
|
|
"password": "password123",
|
|
"name": "重复用户",
|
|
"tenant_name": "另一个机构",
|
|
"role": "founder",
|
|
},
|
|
)
|
|
assert response.status_code == 409
|
|
|
|
def test_register_short_password(self, client: TestClient):
|
|
"""RED→GREEN: 密码太短应返回 422。"""
|
|
response = client.post(
|
|
"/api/v1/auth/register",
|
|
json={
|
|
"email": "short@example.com",
|
|
"password": "123",
|
|
"name": "短密码",
|
|
"tenant_name": "测试机构",
|
|
"role": "founder",
|
|
},
|
|
)
|
|
assert response.status_code == 422
|
|
|
|
|
|
class TestLogin:
|
|
"""登录测试。"""
|
|
|
|
def test_login_success(self, client: TestClient):
|
|
"""RED→GREEN: 正确邮箱密码登录成功。"""
|
|
response = client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"email": "test@example.com",
|
|
"password": "password123",
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["code"] == 0
|
|
assert data["data"]["access_token"] is not None
|
|
|
|
def test_login_wrong_password(self, client: TestClient):
|
|
"""RED→GREEN: 错误密码应返回 401。"""
|
|
response = client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"email": "test@example.com",
|
|
"password": "wrongpassword",
|
|
},
|
|
)
|
|
assert response.status_code == 401
|
|
|
|
def test_login_nonexistent_email(self, client: TestClient):
|
|
"""RED→GREEN: 不存在的邮箱应返回 401。"""
|
|
response = client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"email": "nonexistent@example.com",
|
|
"password": "password123",
|
|
},
|
|
)
|
|
assert response.status_code == 401
|
|
|
|
|
|
class TestGetMe:
|
|
"""获取当前用户信息测试。"""
|
|
|
|
def test_get_me_with_valid_token(self, client: TestClient):
|
|
"""RED→GREEN: 有效 token 应返回用户信息。"""
|
|
# 先登录获取 token
|
|
login_resp = client.post(
|
|
"/api/v1/auth/login",
|
|
json={"email": "test@example.com", "password": "password123"},
|
|
)
|
|
token = login_resp.json()["data"]["access_token"]
|
|
|
|
response = client.get(
|
|
"/api/v1/auth/me",
|
|
headers={"Authorization": f"Bearer {token}"},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["code"] == 0
|
|
assert data["data"]["email"] == "test@example.com"
|
|
assert data["data"]["name"] == "测试用户"
|
|
|
|
def test_get_me_without_token(self, client: TestClient):
|
|
"""RED→GREEN: 无 token 应返回 401。"""
|
|
response = client.get("/api/v1/auth/me")
|
|
assert response.status_code == 401
|
|
|
|
def test_get_me_with_invalid_token(self, client: TestClient):
|
|
"""RED→GREEN: 无效 token 应返回 401。"""
|
|
response = client.get(
|
|
"/api/v1/auth/me",
|
|
headers={"Authorization": "Bearer invalid-token-string"},
|
|
)
|
|
assert response.status_code == 401
|
|
|
|
|
|
class TestRefreshToken:
|
|
"""刷新 token 测试。"""
|
|
|
|
def test_refresh_success(self, client: TestClient):
|
|
"""RED→GREEN: 有效 refresh token 应返回新 token。"""
|
|
login_resp = client.post(
|
|
"/api/v1/auth/login",
|
|
json={"email": "test@example.com", "password": "password123"},
|
|
)
|
|
refresh_token = login_resp.json()["data"]["refresh_token"]
|
|
|
|
response = client.post(
|
|
"/api/v1/auth/refresh",
|
|
json={"refresh_token": refresh_token},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["code"] == 0
|
|
assert data["data"]["access_token"] is not None
|
|
|
|
def test_refresh_with_invalid_token(self, client: TestClient):
|
|
"""RED→GREEN: 无效 refresh token 应返回 401。"""
|
|
response = client.post(
|
|
"/api/v1/auth/refresh",
|
|
json={"refresh_token": "invalid-token"},
|
|
)
|
|
assert response.status_code == 401
|