Files
danyang-match/tests
WorkBuddy 2162612892 fix(service-appointment): 状态冲突/越权改为 4xx,修并发下 500 与弱断言漏判
CI E2E (live stack) 在 main@63c18d8 上失败:test_appointment_concurrent_safety
并发「用户取消」与「运营确认」得到 [200, 500]。根因是 ServiceAppointmentService
四处状态/权限守卫抛裸 RuntimeException,GlobalExceptionHandler 无对应映射,
只能兜底成 HTTP 500 —— 「预约不存在」「状态不允许」「越权」被报成服务端故障。

改动:
- ServiceAppointmentService:四处守卫改用 BusinessException + ApiResponseCode
  (不存在→404 NOT_FOUND,越权→403 FORBIDDEN,状态冲突→409 REDUNDANT_OPERATION)。
- ReferralService.confirmReferral:同一家族的四条守卫同样收敛(预约/报名的
  不存在、越权、非转介类型)。
- tests/e2e/service_appointment_test.py:把 3 处 `!= 200` 的弱断言收紧为 4xx。
  弱断言会把 500 当成「越权被拒」放行 —— 这正是该缺陷长期未被发现的原因,
  此前只有并发用例的 `< 500` 断言咬了它一口。
- ServiceAppointmentOwnerGuardTest:新增「终态不可再确认/取消」「预约不存在」
  用例,并把越权断言从 RuntimeException 收紧到具体业务码(403)。

验证:
- 定向后端测试 35 passed(ServiceAppointment* / MatchmakerReferralPhase13Test)。
- 本机真实栈(重建 backend 镜像):service_appointment_test.py 8/8、全量 E2E 65 passed。
- 负向注入(把守卫改回裸 RuntimeException):2 例精准变红,工作区哈希前后一致。
2026-09-22 19:36:59 +08:00
..

测试基础设施

测试目录结构

tests/
├── invariants/       # 核心不变量测试(每次CI必跑)
│   ├── INV-001_Required不可自动放宽.test.ts
│   ├── INV-002_未Mutual不可聊天.test.ts
│   ├── INV-003_Block后双方不可互动.test.ts
│   ├── INV-004_双向并发Like只创建一个Match.test.ts
│   ├── INV-005_Activity最后一个名额不可超卖.test.ts
│   ├── INV-006_单向活动意向不可泄露.test.ts
│   ├── INV-007_红娘不能替用户Like.test.ts
│   ├── INV-008_非授权Operator不能读取身份证.test.ts
│   ├── INV-009_非案件上下文不能读取聊天.test.ts
│   └── INV-010_跨Organization不能越权.test.ts
├── unit/             # 单元测试
├── integration/      # 集成测试
├── api/              # API 测试
├── permission/       # 权限测试
├── concurrency/      # 并发测试
└── e2e/              # 端到端测试

Phase 01 测试骨架

每个测试文件至少包含:

  • 测试描述
  • 前置条件
  • 操作步骤
  • 预期结果
  • 断言

运行测试

# Backend 单元测试
cd backend
./mvnw test

# Backend 集成测试
./mvnw verify

# Admin Web 构建检查
cd admin-web
pnpm build

# Miniapp 编译检查
cd miniapp
npx tsc --noEmit