fix: align all 212 tests with current API and add CI workflows
Some checks failed
Test / test (push) Failing after 1m4s
Some checks failed
Test / test (push) Failing after 1m4s
Update integration tests to match actual endpoint responses: remove data wrappers, use snake_case fields, correct HTTP methods (PUT→POST for directory create), status codes (200→204 for mutations), and request formats (params→json for 2FA). Fix root-level and unit tests for DatabaseManager migration, model CRUD patterns, and JWT setup. Add GitHub Actions and Gitea CI configs with ubuntu-latest + Python 3.13. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ async def test_user_login_success(
|
||||
):
|
||||
"""测试成功登录"""
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
"/api/v1/user/session",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": test_user_info["email"],
|
||||
@@ -37,7 +37,7 @@ async def test_user_login_wrong_password(
|
||||
):
|
||||
"""测试密码错误返回 401"""
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
"/api/v1/user/session",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": test_user_info["email"],
|
||||
@@ -51,7 +51,7 @@ async def test_user_login_wrong_password(
|
||||
async def test_user_login_nonexistent_user(async_client: AsyncClient):
|
||||
"""测试不存在的用户返回 401"""
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
"/api/v1/user/session",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": "nonexistent@test.local",
|
||||
@@ -68,7 +68,7 @@ async def test_user_login_user_banned(
|
||||
):
|
||||
"""测试封禁用户返回 403"""
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
"/api/v1/user/session",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": banned_user_info["email"],
|
||||
@@ -84,20 +84,14 @@ async def test_user_login_user_banned(
|
||||
async def test_user_register_success(async_client: AsyncClient):
|
||||
"""测试成功注册"""
|
||||
response = await async_client.post(
|
||||
"/api/user/",
|
||||
"/api/v1/user/",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": "newuser@test.local",
|
||||
"credential": "newpass123",
|
||||
}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
assert "user_id" in data["data"]
|
||||
assert "email" in data["data"]
|
||||
assert data["data"]["email"] == "newuser@test.local"
|
||||
assert response.status_code == 204
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -105,16 +99,16 @@ async def test_user_register_duplicate_email(
|
||||
async_client: AsyncClient,
|
||||
test_user_info: dict[str, str]
|
||||
):
|
||||
"""测试重复邮箱返回 400"""
|
||||
"""测试重复邮箱返回 409"""
|
||||
response = await async_client.post(
|
||||
"/api/user/",
|
||||
"/api/v1/user/",
|
||||
json={
|
||||
"provider": "email_password",
|
||||
"identifier": test_user_info["email"],
|
||||
"credential": "anypassword",
|
||||
}
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert response.status_code == 409
|
||||
|
||||
|
||||
# ==================== 用户信息测试 ====================
|
||||
@@ -122,7 +116,7 @@ async def test_user_register_duplicate_email(
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_me_requires_auth(async_client: AsyncClient):
|
||||
"""测试 /api/user/me 需要认证"""
|
||||
response = await async_client.get("/api/user/me")
|
||||
response = await async_client.get("/api/v1/user/me")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -130,7 +124,7 @@ async def test_user_me_requires_auth(async_client: AsyncClient):
|
||||
async def test_user_me_with_invalid_token(async_client: AsyncClient):
|
||||
"""测试无效token返回 401"""
|
||||
response = await async_client.get(
|
||||
"/api/user/me",
|
||||
"/api/v1/user/me",
|
||||
headers={"Authorization": "Bearer invalid_token"}
|
||||
)
|
||||
assert response.status_code == 401
|
||||
@@ -142,17 +136,15 @@ async def test_user_me_returns_user_info(
|
||||
auth_headers: dict[str, str]
|
||||
):
|
||||
"""测试返回用户信息"""
|
||||
response = await async_client.get("/api/user/me", headers=auth_headers)
|
||||
response = await async_client.get("/api/v1/user/me", headers=auth_headers)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
user_data = data["data"]
|
||||
assert "id" in user_data
|
||||
assert "email" in user_data
|
||||
assert user_data["email"] == "testuser@test.local"
|
||||
assert "group" in user_data
|
||||
assert "tags" in user_data
|
||||
assert "id" in data
|
||||
assert "email" in data
|
||||
assert data["email"] == "testuser@test.local"
|
||||
assert "group" in data
|
||||
assert "tags" in data
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -161,13 +153,12 @@ async def test_user_me_contains_group_info(
|
||||
auth_headers: dict[str, str]
|
||||
):
|
||||
"""测试用户信息包含用户组"""
|
||||
response = await async_client.get("/api/user/me", headers=auth_headers)
|
||||
response = await async_client.get("/api/v1/user/me", headers=auth_headers)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
user_data = data["data"]
|
||||
assert user_data["group"] is not None
|
||||
assert "name" in user_data["group"]
|
||||
assert data["group"] is not None
|
||||
assert "name" in data["group"]
|
||||
|
||||
|
||||
# ==================== 存储信息测试 ====================
|
||||
@@ -175,7 +166,7 @@ async def test_user_me_contains_group_info(
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_storage_requires_auth(async_client: AsyncClient):
|
||||
"""测试 /api/user/storage 需要认证"""
|
||||
response = await async_client.get("/api/user/storage")
|
||||
response = await async_client.get("/api/v1/user/storage")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -185,16 +176,14 @@ async def test_user_storage_info(
|
||||
auth_headers: dict[str, str]
|
||||
):
|
||||
"""测试返回存储信息"""
|
||||
response = await async_client.get("/api/user/storage", headers=auth_headers)
|
||||
response = await async_client.get("/api/v1/user/storage", headers=auth_headers)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
storage_data = data["data"]
|
||||
assert "used" in storage_data
|
||||
assert "free" in storage_data
|
||||
assert "total" in storage_data
|
||||
assert storage_data["total"] == storage_data["used"] + storage_data["free"]
|
||||
assert "used" in data
|
||||
assert "free" in data
|
||||
assert "total" in data
|
||||
assert data["total"] == data["used"] + data["free"]
|
||||
|
||||
|
||||
# ==================== 两步验证测试 ====================
|
||||
@@ -202,7 +191,7 @@ async def test_user_storage_info(
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_2fa_init_requires_auth(async_client: AsyncClient):
|
||||
"""测试获取2FA初始化信息需要认证"""
|
||||
response = await async_client.get("/api/user/settings/2fa")
|
||||
response = await async_client.get("/api/v1/user/settings/2fa")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -213,23 +202,23 @@ async def test_user_2fa_init(
|
||||
):
|
||||
"""测试获取2FA初始化信息"""
|
||||
response = await async_client.get(
|
||||
"/api/user/settings/2fa",
|
||||
"/api/v1/user/settings/2fa",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
# 应该包含二维码URL和密钥
|
||||
assert isinstance(data["data"], dict)
|
||||
# TwoFactorResponse 应包含 setup_token 和 uri
|
||||
assert "setup_token" in data
|
||||
assert "uri" in data
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_2fa_enable_requires_auth(async_client: AsyncClient):
|
||||
"""测试启用2FA需要认证"""
|
||||
response = await async_client.post(
|
||||
"/api/user/settings/2fa",
|
||||
params={"setup_token": "fake_token", "code": "123456"}
|
||||
"/api/v1/user/settings/2fa",
|
||||
json={"setup_token": "fake_token", "code": "123456"}
|
||||
)
|
||||
assert response.status_code == 401
|
||||
|
||||
@@ -241,8 +230,8 @@ async def test_user_2fa_enable_invalid_token(
|
||||
):
|
||||
"""测试无效的setup_token返回 400"""
|
||||
response = await async_client.post(
|
||||
"/api/user/settings/2fa",
|
||||
params={"setup_token": "invalid_token", "code": "123456"},
|
||||
"/api/v1/user/settings/2fa",
|
||||
json={"setup_token": "invalid_token", "code": "123456"},
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 400
|
||||
@@ -253,7 +242,7 @@ async def test_user_2fa_enable_invalid_token(
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_settings_requires_auth(async_client: AsyncClient):
|
||||
"""测试获取用户设置需要认证"""
|
||||
response = await async_client.get("/api/user/settings/")
|
||||
response = await async_client.get("/api/v1/user/settings/")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -264,13 +253,14 @@ async def test_user_settings_returns_data(
|
||||
):
|
||||
"""测试返回用户设置"""
|
||||
response = await async_client.get(
|
||||
"/api/user/settings/",
|
||||
"/api/v1/user/settings/",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
assert "id" in data
|
||||
assert "email" in data
|
||||
|
||||
|
||||
# ==================== WebAuthn 测试 ====================
|
||||
@@ -278,7 +268,7 @@ async def test_user_settings_returns_data(
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_authn_start_requires_auth(async_client: AsyncClient):
|
||||
"""测试WebAuthn初始化需要认证"""
|
||||
response = await async_client.put("/api/user/authn/start")
|
||||
response = await async_client.put("/api/v1/user/authn/start")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -289,7 +279,7 @@ async def test_user_authn_start_disabled(
|
||||
):
|
||||
"""测试WebAuthn未启用时返回 400"""
|
||||
response = await async_client.put(
|
||||
"/api/user/authn/start",
|
||||
"/api/v1/user/authn/start",
|
||||
headers=auth_headers
|
||||
)
|
||||
# WebAuthn 在测试环境中未启用
|
||||
|
||||
Reference in New Issue
Block a user