test(account): 一键查询 / 官方兑换记录 / 生命周期用例

围绕这几轮改动补齐用例(本文件共 53 条):

- **判定规则**:只看官方兑换记录;全局库存**永不**推出「该账号已拥有」
  (回归用例 —— 正是第一版踩的坑);字段缺失是 None(未知)而不是 False(没有)
- **失败隔离**:单项外部调用失败不影响其余,且如实写进 errors
- **只读性**:一键查询不发事件、不改生命周期状态
- **官方记录补成事件**:带**真实兑换时间**(不是"发现它的时刻")、
  幂等(重复查询不重复落)、无 commodityId 时跳过
- **排序回归**:「最近一次兑换」按事件时间,不是插入 id
- **时间归一化**:0 / "0" / 空 / 负数 → None(1970 那个 bug 的回归)
- **迁移安全**:不得在迁移里 commit(op.get_bind());加列前必须有存在性检查
  (扫代码时**跳过注释** —— 注释里正解释着"不要这样做",第一版用例因此假红)
- **接口契约**:详情返回快照与查询时间、列表**不**带整份快照;
  断言一律看 model_dump()(只看属性会假绿 —— AccountOut 有手写
  @model_serializer,字段没列进去时属性有值、JSON 里没有)

另修两条**把 bug 当期望值**的既有用例:

1. 「最近一次兑换」原断言的是最后**插入**的那条(旧行为按 id 排),
   改为真正最近的(按事件时间);
2. 按用户名查找夹具不可靠(make_account("key") 每次建新账号、库里一直累积),
   改为按 id 精确查找。
This commit is contained in:
yml2213
2026-10-04 20:04:11 +08:00
parent f416397cc8
commit 6865b916ba
3 changed files with 444 additions and 7 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ TESTS_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = TESTS_DIR.parent
VERSIONS_DIR = PROJECT_ROOT / "web" / "backend" / "migrations" / "versions"
HEAD_REVISION = "20261004_0047"
HEAD_REVISION = "20261004_0048"
# 迁移新增、但不声明在模型里的复合查询索引。
EXTRA_INDEXES = (