a0f6582914
- 后台密钥管理「代理设置」列改为完整明文展示(含账号密码),便于运维核对; 新增 full 字段仅对代理模块下发,密钥两列保持脱敏 - 新增 biz_user_secret_usage_daily(V117):用户 × 模块 × 天累计真实对外请求次数 - 计次口径:LLM 每次真实 HTTP 请求(含重试)计 1 次;代理每次成功提取计 1 次 - LLM 埋点走 SecretUsageContext 上下文(批次外设置、线程池内快照恢复) - 新增内部上报接口 /api/internal/user-secret-usage(X-Internal-Token) - 新增后台页「密钥用量统计」:日期范围 + 用户名 + 分组筛选,含范围内汇总
75 lines
3.3 KiB
TypeScript
75 lines
3.3 KiB
TypeScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { existsSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { readSource, occurrences } from './helpers.ts'
|
|
import { adminPages } from '../src/router/routes.ts'
|
|
|
|
const ROUTER = 'src/router/index.ts'
|
|
const NOT_FOUND = 'src/pages/error/NotFoundPage.vue'
|
|
|
|
test('test_task_012_route_error_page_normal_primary_path', () => {
|
|
// 正常主路径:未知路径注册到路由级错误页兜底。
|
|
const router = readSource(ROUTER)
|
|
assert.match(router, /path:\s*':pathMatch\(\.\*\)\*'/)
|
|
assert.match(router, /NotFoundPage/)
|
|
assert.match(router, /页面不存在/)
|
|
})
|
|
|
|
test('test_task_012_route_error_page_normal_variant_input', () => {
|
|
// 正常变体:错误页在 AdminLayout children 内,保留壳层 chrome。
|
|
const router = readSource(ROUTER)
|
|
const catchAllIndex = router.indexOf(':pathMatch(.*)*')
|
|
const registryIndex = router.indexOf('adminRouteRecords.map')
|
|
assert.ok(catchAllIndex > registryIndex, 'catch-all 应在业务路由之后注册')
|
|
assert.match(router, /path: '\/',/)
|
|
})
|
|
|
|
test('test_task_012_route_error_page_normal_repeated_operation_is_idempotent', () => {
|
|
// 正常重复:错误页注册不重复追加。
|
|
const first = readSource(ROUTER)
|
|
assert.equal(occurrences(first, ':pathMatch(.*)*'), 1)
|
|
})
|
|
|
|
test('test_task_012_route_error_page_boundary_empty_input', () => {
|
|
// 边界空值:错误页文件存在,且不进入业务路由注册表。
|
|
assert.equal(existsSync(join(process.cwd(), NOT_FOUND)), true)
|
|
// 业务路由条目与页面定义一一对应;错误页不占用其中任何一条。
|
|
const router = readSource(ROUTER)
|
|
assert.equal(occurrences(router, '...adminRouteRecords'), 1, '错误页不应计入业务路由')
|
|
assert.ok(adminPages.length >= 18, '业务页至少 18(随版本递增,不设上限断言)')
|
|
})
|
|
|
|
test('test_task_012_route_error_page_boundary_single_item', () => {
|
|
// 边界单元素:错误页是单一 Vue 页面组件。
|
|
const source = readSource(NOT_FOUND)
|
|
assert.equal(occurrences(source, '<template>'), 1)
|
|
assert.match(source, /el-result/)
|
|
})
|
|
|
|
test('test_task_012_route_error_page_boundary_limit_or_missing_field', () => {
|
|
// 边界上限:catch-all 不参与菜单权限门禁(无 menuKey)。
|
|
const router = readSource(ROUTER)
|
|
const tail = router.slice(router.indexOf('component: NotFoundPage'))
|
|
assert.equal(tail.slice(0, 80).includes('menuKey'), false, '错误页不应带菜单 key')
|
|
})
|
|
|
|
test('test_task_012_route_error_page_invalid_input_rejected', () => {
|
|
// 异常输入:深层未知路径也能被通配兜底,且提供返回首页动作。
|
|
const router = readSource(ROUTER)
|
|
assert.match(router, /:pathMatch\(\.\*\)\*/, '通配需覆盖多段未知路径')
|
|
const page = readSource(NOT_FOUND)
|
|
assert.match(page, /router\.replace\('\/'\)/)
|
|
})
|
|
|
|
test('test_task_012_route_error_page_dependency_failure_returns_actionable_message', () => {
|
|
// 依赖失败:标题/样式/返回动作齐全,加载失败有明确入口。
|
|
const page = readSource(NOT_FOUND)
|
|
assert.match(page, /返回首页/)
|
|
assert.match(page, /404/)
|
|
const css = readSource('src/styles/main.css')
|
|
assert.match(css, /\.not-found/)
|
|
const router = readSource(ROUTER)
|
|
assert.match(router, /meta: \{ title: '页面不存在' \}/)
|
|
})
|