- POST /approvals and PATCH /approvals/{id} require a console admin session
(EndpointDef auth:"session"); API keys incl. admin scope get 403, so an
organize.execute key can no longer approve its own plan (S1)
- tests for single-use approval checks: expired, revision/payload hash
mismatch, consumed, revoked, pending/rejected, plan mismatch; re-approve
after plan change succeeds once and cannot be replayed (S4)
- one redact key table in @umt/contracts shared by server logger and agent
redactForModel: rsskey, torrent_pass, authkey, downhash, c_secure_pass,
passkey variants, x-api-key, cookie headers, nested objects/arrays (S2)
- TMDB network errors: message and cause redacted via redactUrl (S3)
- web Agent ?mock=1 only in DEV builds or when pi.provider is fake (S7)
- EndpointDef auth annotations for /auth/*, asserted against
PUBLIC_AUTH_PATHS (S10); doc drift fixes (S11)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
28 lines
1.6 KiB
Markdown
28 lines
1.6 KiB
Markdown
# @umt/testkit
|
|
|
|
测试夹具与 mock 服务,只供测试依赖,不进入生产构建:
|
|
|
|
| 入口 | 模拟对象 |
|
|
|---|---|
|
|
| `createMockQb` | qBittorrent WebUI v2(见下文"落盘") |
|
|
| `createMockNexusPhpSite`、`createMockMteamApi`、`createMockFetch` | 观众(NexusPHP)站点页面、馒头 M-Team API(见 `src/sites/README.md`) |
|
|
| `createMockRssServer` | RSS / Atom Feed(见 `src/rss/README.md`) |
|
|
| `createMockTmdb` | TMDB v3(api_key 与 Bearer 两种鉴权,`fault()` 注入 429/5xx/延迟) |
|
|
| `createMockEmby` | Emby / Jellyfin(`flavor`),`/Users`、`/Items`、`/Shows/{id}/Seasons|Episodes`,夹具 `EMBY_FIXTURE_ITEMS` |
|
|
| `createMockCamofox` | camofox-browser(tabs / navigate / snapshot / screenshot,可选 accessKey;快照里故意带密码、Cookie、passkey 供脱敏测试) |
|
|
| `createTempTree` | 临时目录树(可写库根哨兵) |
|
|
|
|
## mock qB 落盘
|
|
|
|
`createMockQb()` 默认只改内存状态。e2e 需要"下载完成 → Copy 入库"时:
|
|
|
|
```ts
|
|
const qb = await createMockQb();
|
|
// files 的 path 相对任务 save_path(多文件种子含根目录);写随机内容,大小与清单一致,返回绝对路径
|
|
const paths = await qb.complete(hash, { files: [{ path: "Show.S01/Show.S01E01.mkv", size: 4 * 1024 * 1024 }] });
|
|
```
|
|
|
|
- `createMockQb({ materializeFiles: true })` 让所有 `complete()` 按现有文件清单落盘;单次总量上限 `maxMaterializeBytes`(默认 64 MiB)。
|
|
- `torrents/delete` 带 `deleteFiles=true` 时同步删除落盘文件和因此变空的目录(不越过 save_path)。
|
|
- save_path 请用临时目录(`mkdtemp`),不要用 `/downloads` 这类真实路径。
|