dingdanquanliucheng/backend/tests/test_auth_extended.py
2026-06-19 23:03:14 +08:00

152 lines
5.1 KiB
Python

"""认证授权扩展测试。
测试用例:
- AUTH-004c: 空用户名登录
- AUTH-004d: 空密码登录
- AUTH-006c: Token 自动续期
- AUTH-012b: 微信登录无效 code
- AUTH-012c: 绑定 OpenID
"""
from __future__ import annotations
import pytest
@pytest.mark.auth
@pytest.mark.p1
class TestLoginValidation:
"""登录参数校验测试。"""
def test_empty_username(self, client):
"""AUTH-004c: 空用户名登录应失败。"""
resp = client.post("/api/auth/login", json={
"username": "",
"password": "admin123",
"role_type": "admin",
})
assert resp.status_code in (400, 401, 422)
def test_empty_password(self, client):
"""AUTH-004d: 空密码登录应失败。"""
resp = client.post("/api/auth/login", json={
"username": "admin01",
"password": "",
"role_type": "admin",
})
assert resp.status_code in (400, 401, 422)
def test_missing_role_type(self, client):
"""缺少 role_type 可能成功或失败(取决于 API 默认值)。"""
resp = client.post("/api/auth/login", json={
"username": "admin01",
"password": "admin123",
})
assert resp.status_code in (200, 400, 401, 422)
def test_invalid_role_type(self, client):
"""无效 role_type 应失败。"""
resp = client.post("/api/auth/login", json={
"username": "admin01",
"password": "admin123",
"role_type": "invalid_role",
})
assert resp.status_code in (400, 401, 403, 422)
@pytest.mark.auth
@pytest.mark.p1
class TestTokenManagement:
"""Token 管理测试。"""
def test_me_endpoint_returns_user_info(self, client, admin_headers):
"""AUTH-010/011: /me 返回用户信息、菜单、权限。"""
resp = client.get("/api/auth/me", headers=admin_headers)
assert resp.status_code == 200
data = resp.json()["data"]
assert "user_id" in data
assert "role_code" in data
def test_me_without_token(self, client):
"""无 token 访问 /me 应返回 401。"""
resp = client.get("/api/auth/me")
assert resp.status_code == 401
def test_me_with_invalid_token(self, client):
"""无效 token 访问 /me 应返回 401。"""
resp = client.get("/api/auth/me", headers={
"Authorization": "Bearer invalid_token_here",
})
assert resp.status_code == 401
def test_logout(self, client, admin_headers):
"""登出成功。"""
resp = client.post("/api/auth/logout", headers=admin_headers)
assert resp.status_code == 200
def test_token_after_logout(self, client, admin_headers):
"""登出后 token 应失效。"""
# 先登出
client.post("/api/auth/logout", headers=admin_headers)
# 再用同一 token 访问
resp = client.get("/api/auth/me", headers=admin_headers)
assert resp.status_code == 401
@pytest.mark.auth
@pytest.mark.p1
class TestWeChatAuth:
"""微信登录测试。"""
def test_wechat_login_invalid_code(self, client):
"""AUTH-012b: 微信登录无效 code。"""
resp = client.post("/api/auth/wechat-login", json={
"code": "invalid_wx_code",
})
assert resp.status_code in (400, 401, 422, 500)
def test_bind_openid(self, client, admin_headers):
"""AUTH-012c: 绑定 OpenID。"""
resp = client.post("/api/auth/bind-openid", headers=admin_headers, json={
"open_id": "test_open_id_123",
})
assert resp.status_code in (200, 400, 422)
@pytest.mark.auth
@pytest.mark.p1
class TestRolePermissionBoundary:
"""角色权限边界测试。"""
def test_all_roles_can_login(self, client):
"""所有角色都能正常登录。"""
accounts = [
("admin01", "admin123", "admin"),
("sales01", "sales123", "salesman"),
("manager01", "manager123", "manager"),
("driver01", "driver123", "driver"),
]
for username, password, role_type in accounts:
resp = client.post("/api/auth/login", json={
"username": username,
"password": password,
"role_type": role_type,
})
assert resp.status_code == 200, f"{username} login failed"
def test_driver_cannot_access_financial_data(self, client, driver_headers, make_order):
"""司机不能访问财务数据。"""
order = make_order()
resp = client.get(f"/api/orders/{order.id}", headers=driver_headers)
# 司机应被拒绝或看不到财务字段
assert resp.status_code in (200, 403)
def test_salesman_cannot_view_reports(self, client, salesman_headers):
"""业务员不能查看绩效报表。"""
resp = client.get("/api/reports/performance", headers=salesman_headers)
assert resp.status_code == 403
def test_driver_cannot_view_reports(self, client, driver_headers):
"""司机不能查看绩效报表。"""
resp = client.get("/api/reports/performance", headers=driver_headers)
assert resp.status_code == 403