Files
gaokao-volunteer-system/admin/tests/test_routes_users.py
Hermes Agent 3f46811e49
Some checks failed
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
release: cut v2.1
2026-06-13 14:49:58 +08:00

158 lines
5.0 KiB
Python

"""T6.3 用户管理端点测试。
覆盖:
- 鉴权: /api/admin/users 与 /api/admin/users/{user_key} 401
- 列表: 按用户聚合、分页骨架、遮罩展示
- 搜索: 支持手机号 / 姓名关键字
- 详情: 返回该用户的订单明细,且敏感字段保持遮罩
- 未命中: 404
"""
from __future__ import annotations
import os
from datetime import datetime, timedelta, timezone
from data.orders.dao import OrdersDAO
from data.orders.models import Order, generate_order_id
os.environ.setdefault("GAOKAO_ORDERS_FERNET_KEY", "test-secret-for-admin-users")
def _iso_at(dt: datetime) -> str:
return dt.replace(microsecond=0).isoformat()
def _seed_users(db_path: str) -> None:
now = datetime.now(timezone.utc).replace(microsecond=0, hour=12, minute=0, second=0)
with OrdersDAO.connect(db_path) as dao:
dao.create(
Order(
id=generate_order_id(),
source="web",
service_version="basic",
amount_cents=9900,
status="pending",
customer_name="李明",
customer_phone="13800001234",
customer_wechat="wx-li",
candidate_name="李小明",
candidate_id_card="430102200501011234",
candidate_province="湖南",
created_at=_iso_at(now - timedelta(days=1)),
)
)
dao.create(
Order(
id=generate_order_id(),
source="wechat",
service_version="standard",
amount_cents=12900,
status="paid",
customer_name="李明",
customer_phone="13800001234",
customer_wechat="wx-li",
candidate_name="李小明",
candidate_id_card="430102200501011234",
candidate_province="湖南",
created_at=_iso_at(now),
)
)
dao.create(
Order(
id=generate_order_id(),
source="xianyu",
service_version="premium",
amount_cents=15900,
status="serving",
customer_name="王芳",
customer_phone="13911112222",
customer_wechat="wx-wang",
candidate_name="王小芳",
candidate_id_card="430102200601019876",
candidate_province="浙江",
created_at=_iso_at(now - timedelta(days=2)),
)
)
def test_users_requires_auth(client):
resp = client.get("/api/admin/users")
assert resp.status_code == 401
def test_users_list_groups_and_masks_pii(client, auth_headers, settings):
_seed_users(settings.orders_db_path)
resp = client.get("/api/admin/users", headers=auth_headers)
assert resp.status_code == 200
body = resp.json()
assert body["total"] == 2
assert body["limit"] == 50
assert body["offset"] == 0
assert body["query"] is None
assert len(body["items"]) == 2
li = next(item for item in body["items"] if item["customer_phone"] == "138****1234")
assert li["customer_name"] == "李*"
assert li["customer_wechat"] == "wx*li"
assert li["candidate_name"] == "李*明"
assert li["order_count"] == 2
assert li["latest_status"] == "paid"
assert li["total_amount_cents"] == 22800
assert li["latest_order_at"]
def test_users_search_by_phone_and_name(client, auth_headers, settings):
_seed_users(settings.orders_db_path)
by_phone = client.get(
"/api/admin/users",
params={"q": "13800001234"},
headers=auth_headers,
)
assert by_phone.status_code == 200
body = by_phone.json()
assert body["total"] == 1
assert len(body["items"]) == 1
assert body["items"][0]["customer_phone"] == "138****1234"
by_name = client.get(
"/api/admin/users",
params={"q": "王芳"},
headers=auth_headers,
)
assert by_name.status_code == 200
body = by_name.json()
assert body["total"] == 1
assert body["items"][0]["customer_name"] == "王*"
def test_user_detail_returns_masked_orders(client, auth_headers, settings):
_seed_users(settings.orders_db_path)
listed = client.get("/api/admin/users", headers=auth_headers)
user_key = next(
item["user_key"] for item in listed.json()["items"] if item["order_count"] == 2
)
resp = client.get(f"/api/admin/users/{user_key}", headers=auth_headers)
assert resp.status_code == 200
body = resp.json()
assert body["user_key"] == user_key
assert body["order_count"] == 2
assert len(body["orders"]) == 2
assert all(order["customer_phone"] == "138****1234" for order in body["orders"])
assert all(order["customer_wechat"] == "wx*li" for order in body["orders"])
assert all(
order["candidate_id_card"] == "430102********1234" for order in body["orders"]
)
def test_user_detail_404_for_unknown(client, auth_headers):
resp = client.get("/api/admin/users/unknown-key", headers=auth_headers)
assert resp.status_code == 404