Why: the rdm-audit entry was an unconditional builtin, so on a plain base without any rdm.inspect.* commands the workspace opened straight into a rejected receipt (400) - diagnosed 2026-10-12. The page also rendered raw receipt JSON instead of a readable error. Evidence: vitest 23 files / 112 tests pass incl. the new contract matrix (workspaces.test.ts, rdm-errors.test.ts) and design-guard; tsc -b && vite build pass; e2e plain-base scenario added (driven by dev-repo scripts/e2e.sh phase 4). Impact: audit entry shows only when GET /api/commands lists all seven rdm.inspect.* commands enabled (store.rdmAuditAvailable, refreshed with the workspace list); audit errors classify into capability-missing / auth-expired / query-failed with the raw receipt kept in a Collapsible. Refs: 2026-10-12 diagnostic report, increment 2.
40 lines
1.8 KiB
TypeScript
40 lines
1.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
||
import { classifyRdmError } from '../src/rdmErrors'
|
||
|
||
// 2026-10-12 增量 2(审计错误四分类):审计页不再把原始报错(400 回执 JSON)直出,
|
||
// 改为「能力缺失 / 登录已失效 / 查询失败」文案并保留原始回执供诊断;
|
||
// 「无可审计项目」由组件空态承担,不走本分类。
|
||
// 分类依据:api.ts json() 抛 `${status}: ${body}`;后端 unknown/disabled 命令
|
||
// 回 400 + "unknown or disabled command"(cmdbus.go Dispatch),总线未挂载回
|
||
// 503 "commands disabled"(server.go execCommand)。
|
||
describe('classifyRdmError', () => {
|
||
it('400 unknown or disabled command → 能力缺失', () => {
|
||
const raw = '400: {"receipt":{"state":"rejected","error":"unknown or disabled command: rdm.inspect.capabilities"}}'
|
||
const e = classifyRdmError(new Error(raw))
|
||
expect(e.kind).toBe('capability')
|
||
expect(e.message).toContain('当前服务未提供审计能力')
|
||
expect(e.raw).toContain('unknown or disabled command')
|
||
})
|
||
|
||
it('503 commands disabled → 能力缺失', () => {
|
||
expect(classifyRdmError('503: commands disabled').kind).toBe('capability')
|
||
})
|
||
|
||
it('401/403 → 登录已失效', () => {
|
||
expect(classifyRdmError('401: session expired').kind).toBe('auth')
|
||
expect(classifyRdmError(new Error('403: forbidden')).kind).toBe('auth')
|
||
})
|
||
|
||
it('其余错误 → 查询失败,保留原始串', () => {
|
||
const e = classifyRdmError('500: boom')
|
||
expect(e.kind).toBe('query')
|
||
expect(e.message).toContain('查询失败')
|
||
expect(e.raw).toBe('500: boom')
|
||
})
|
||
|
||
it('非 Error 输入可容忍', () => {
|
||
expect(classifyRdmError(undefined).kind).toBe('query')
|
||
expect(classifyRdmError({ weird: true }).kind).toBe('query')
|
||
})
|
||
})
|