Files
ocean/backend/tests/test_users_api.py
T
2026-02-01 15:57:42 +08:00

253 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
用户管理 API 测试(依据 API 文档 2.2 节)
仅管理员可创建、修改、删除用户。测试对已启动服务发起 HTTP 请求,使用 admin token。
"""
import uuid
def _auth_header(token: str) -> dict:
return {"Authorization": f"Bearer {token}"}
# ---------- POST /api/users/create ----------
def test_users_create_without_token_returns_401(client):
"""创建用户无 token 时返回 401"""
r = client.post(
"/api/users/create",
json={"username": "u1", "password": "123456", "role": "工程部"},
)
assert r.status_code == 401
def test_users_create_non_admin_returns_403(client, engineer_token):
"""非管理员创建用户返回 403"""
r = client.post(
"/api/users/create",
headers=_auth_header(engineer_token),
json={"username": "u_engineer_cannot", "password": "123456", "role": "工程部"},
)
assert r.status_code == 403
assert r.json().get("code") == 403
def test_users_create_admin_returns_201_with_id_and_message(client, auth_token):
"""管理员创建用户返回 201 且包含 id 和 message「创建成功」"""
username = f"testuser_create_{uuid.uuid4().hex[:8]}"
r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={
"username": username,
"password": "123456",
"role": "技经部",
"displayName": "测试创建用户",
},
)
assert r.status_code == 201
body = r.json()
assert "id" in body
assert body.get("message") == "创建成功"
def test_users_create_missing_username_returns_400(client, auth_token):
"""创建用户缺少 username 时返回 400"""
r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"password": "123456", "role": "工程部"},
)
assert r.status_code == 400
assert r.json().get("code") == 400
def test_users_create_missing_password_returns_400(client, auth_token):
"""创建用户缺少 password 时返回 400"""
r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": "testuser_nopwd", "role": "工程部"},
)
assert r.status_code == 400
assert r.json().get("code") == 400
def test_users_create_missing_role_returns_400(client, auth_token):
"""创建用户缺少 role 时返回 400"""
r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": "testuser_norole", "password": "123456"},
)
assert r.status_code == 400
assert r.json().get("code") == 400
# ---------- POST /api/users/update ----------
def test_users_update_without_token_returns_401(client):
"""更新用户无 token 时返回 401"""
r = client.post("/api/users/update", json={"id": "any-id"})
assert r.status_code == 401
def test_users_update_non_admin_returns_403(client, engineer_token, auth_token):
"""非管理员更新用户返回 403"""
username = f"testuser_for_update_{uuid.uuid4().hex[:8]}"
create_r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": username, "password": "123456", "role": "财务部"},
)
assert create_r.status_code == 201
uid = create_r.json()["id"]
r = client.post(
"/api/users/update",
headers=_auth_header(engineer_token),
json={"id": uid, "displayName": "不应成功"},
)
assert r.status_code == 403
assert r.json().get("code") == 403
def test_users_update_admin_returns_200_with_id_and_message(client, auth_token):
"""管理员更新用户返回 200 且包含 id 和 message「保存成功」"""
username = f"testuser_update_{uuid.uuid4().hex[:8]}"
create_r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": username, "password": "123456", "role": "物贸部"},
)
assert create_r.status_code == 201
uid = create_r.json()["id"]
r = client.post(
"/api/users/update",
headers=_auth_header(auth_token),
json={"id": uid, "displayName": "更新后的显示名", "role": "财务部"},
)
assert r.status_code == 200
body = r.json()
assert body.get("id") == uid
assert body.get("message") == "保存成功"
def test_users_update_nonexistent_returns_404(client, auth_token):
"""更新不存在用户返回 404"""
r = client.post(
"/api/users/update",
headers=_auth_header(auth_token),
json={"id": "non-existent-user-id", "displayName": "任意"},
)
assert r.status_code == 404
assert r.json().get("code") == 404
# ---------- POST /api/users/delete ----------
def test_users_delete_without_token_returns_401(client):
"""删除用户无 token 时返回 401"""
r = client.post("/api/users/delete", json={"id": "any-id"})
assert r.status_code == 401
def test_users_delete_non_admin_returns_403(client, engineer_token, auth_token):
"""非管理员删除用户返回 403"""
username = f"testuser_for_del_{uuid.uuid4().hex[:8]}"
create_r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": username, "password": "123456", "role": "工程部"},
)
assert create_r.status_code == 201
uid = create_r.json()["id"]
r = client.post(
"/api/users/delete",
headers=_auth_header(engineer_token),
json={"id": uid},
)
assert r.status_code == 403
assert r.json().get("code") == 403
def test_users_delete_admin_returns_200_with_message(client, auth_token):
"""管理员删除用户返回 200 且 message「删除成功」"""
username = f"testuser_delete_{uuid.uuid4().hex[:8]}"
create_r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": username, "password": "123456", "role": "工程部"},
)
assert create_r.status_code == 201
uid = create_r.json()["id"]
r = client.post(
"/api/users/delete",
headers=_auth_header(auth_token),
json={"id": uid},
)
assert r.status_code == 200
assert r.json().get("message") == "删除成功"
def test_users_delete_nonexistent_returns_404(client, auth_token):
"""删除不存在用户返回 404"""
r = client.post(
"/api/users/delete",
headers=_auth_header(auth_token),
json={"id": "non-existent-user-id"},
)
assert r.status_code == 404
assert r.json().get("code") == 404
def test_users_delete_self_returns_400(client, auth_token):
"""管理员不能删除当前登录用户自己,返回 400"""
# 先登录拿到当前用户 id(从 login 响应的 user.id
login_r = client.post("/api/auth/login", json={"username": "admin", "password": "123456"})
assert login_r.status_code == 200
current_user_id = login_r.json()["user"]["id"]
r = client.post(
"/api/users/delete",
headers=_auth_header(auth_token),
json={"id": current_user_id},
)
assert r.status_code == 400
body = r.json()
assert body.get("code") == 400
assert "message" in body
# ---------- E2E:管理员 创建 → 修改 → 删除 用户 ----------
def test_e2e_admin_create_then_update_then_delete_user(client, auth_token):
"""E2E:管理员创建用户 → 修改用户 → 删除用户"""
username = f"testuser_e2e_{uuid.uuid4().hex[:8]}"
create_r = client.post(
"/api/users/create",
headers=_auth_header(auth_token),
json={"username": username, "password": "123456", "role": "市场部", "displayName": "E2E初始"},
)
assert create_r.status_code == 201
uid = create_r.json()["id"]
assert uid
update_r = client.post(
"/api/users/update",
headers=_auth_header(auth_token),
json={"id": uid, "displayName": "E2E已修改", "role": "技经部"},
)
assert update_r.status_code == 200
assert update_r.json().get("message") == "保存成功"
delete_r = client.post(
"/api/users/delete",
headers=_auth_header(auth_token),
json={"id": uid},
)
assert delete_r.status_code == 200
assert delete_r.json().get("message") == "删除成功"