Files
shaguabijia-app-server/tests/test_onboarding.py
T
marco e8bd12cc1f feat(onboarding): force_onboarding 改设备维度 + admin 设备管理 + status 查询
废弃 force_onboarding(运营按用户强制引导,客户端不认——被 onboarding_completed 压过),
改用 onboarding_completion(设备+账号 维度),admin 直接增删该表记录控制重走。

- 删 force_onboarding: User 列 + auth/admin schema + admin 接口 + mutations + repo
  clear + /onboarding/complete 调用 + 3 测试;新增 alembic 迁移删列
- admin 设备管理: 列设备(按 device 聚合) / 重置单设备 / 全部重置(清 onboarding_completion)
- 新增 GET /api/v1/user/onboarding/status: 客户端已登录启动查"本设备是否要重走引导"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 00:51:47 +08:00

68 lines
2.6 KiB
Python

"""新手引导"按 设备+账号 只触发一次"的后端闭环测试。
覆盖:
- 全新 (账号, 设备) 登录 → onboarding_completed=False(照常走引导)
- 标记完成后,同 (账号, 设备) 再登录 → True(跳过引导,跨"重装"= 同 device_id 重新登录)
- 同账号换设备(device_id 不同)→ False(新设备重新引导)
- 标记幂等;缺 device_id 时按未完成处理
"""
from __future__ import annotations
def _login(client, phone: str, device_id: str | None):
body = {"phone": phone, "code": "123456"}
if device_id is not None:
body["device_id"] = device_id
r = client.post("/api/v1/auth/sms/login", json=body)
assert r.status_code == 200, r.text
return r.json()
def _mark_complete(client, access: str, device_id: str):
return client.post(
"/api/v1/user/onboarding/complete",
json={"device_id": device_id},
headers={"Authorization": f"Bearer {access}"},
)
def test_onboarding_once_per_device_and_account(client) -> None:
phone = "13800138001"
dev_a = "android-id-aaaa"
dev_b = "android-id-bbbb"
# ① 全新账号+设备:未完成
data = _login(client, phone, dev_a)
assert data["onboarding_completed"] is False
access = data["access_token"]
# ② 走完引导 → 标记完成(幂等:再标一次也 200)
assert _mark_complete(client, access, dev_a).status_code == 200
assert _mark_complete(client, access, dev_a).json()["ok"] is True
# ③ 同账号 + 同设备(模拟卸载重装后重新登录)→ 已完成,跳过引导
assert _login(client, phone, dev_a)["onboarding_completed"] is True
# ④ 同账号 + 新设备 → 仍未完成,新设备重新走引导
assert _login(client, phone, dev_b)["onboarding_completed"] is False
def test_onboarding_mark_on_one_device_does_not_leak_to_other(client) -> None:
"""B 设备标记完成,不影响 A 设备(逐设备独立)。"""
phone = "13800138002"
data_a = _login(client, phone, "devA")
assert data_a["onboarding_completed"] is False
data_b = _login(client, phone, "devB")
assert _mark_complete(client, data_b["access_token"], "devB").status_code == 200
assert _login(client, phone, "devB")["onboarding_completed"] is True
assert _login(client, phone, "devA")["onboarding_completed"] is False
def test_onboarding_missing_device_id_treated_as_incomplete(client) -> None:
"""老客户端不传 device_id:按未完成处理,不报错、不误跳过。"""
phone = "13800138003"
data = _login(client, phone, device_id=None)
assert data["onboarding_completed"] is False