文件
OmniCard/admin/tests/ai-sandbox.test.ts
wikiboss eec259a3a7 feat: 完成全系统30个功能点开发与E2E全链路验收 (8轮调度32个子代理闭环)
- 模块一: 出海案例作品集、博客动态发布、人名发音语音条、RTL阿语多语言切换
- 模块二: AI顾问人设配置、行业术语库润色、RAG切片沙盒调试、流式会话与意向留资卡片
- 模块三: 全球访客雷达大屏、多维加权意向算分、外部CRM对接推送、团队公海池流转
- 模块四: 移动端NFC安全挂失、NFC动态路由规则配置、动态防伪验签、展会制卡Zip批量导出
- 模块五: 组织架构与名片分配、移动端个人中心设置、离职交接与历史线索迁移、安全审计日志
- 模块六: Stripe国际信用卡订阅Webhook、独立二级域名与SSL检测、坐席配额预警、多币种发票
- 模块七: 纸质名片OCR解析入库、国际商务日程RFC 5545 ICS日历、微官网离线SWR预加载、展会实时排行榜大屏
- 模块八: 全球出海SEO OpenGraph元标签注入与社交爬虫探测、30点端到端全链路业务流集成测试套件
2026-09-20 23:47:47 +08:00

69 行
3.8 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const adminRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const knowledgePagePath = path.join(adminRoot, 'src/pages/ai/knowledge/index.tsx');
const knowledgeLocalePath = path.join(adminRoot, 'src/pages/ai/knowledge/locale/index.ts');
test('1. 知识库页面必须包含召回沙盒调试入口与 Arco Drawer/Progress 组件', () => {
assert.ok(fs.existsSync(knowledgePagePath), '知识库页面必须存在');
const content = fs.readFileSync(knowledgePagePath, 'utf-8');
assert.ok(content.includes('Drawer'), '必须使用 Arco Drawer 抽屉展示沙盒调试器');
assert.ok(content.includes('Progress'), '必须使用 Arco Progress 进度条展示置信度');
assert.ok(
content.includes('admin/ai/knowledge/sandbox-test'),
'必须调用 POST /api/admin/ai/knowledge/sandbox-test 调试接口'
);
assert.ok(
content.includes('KnowledgeChunk') || content.includes('KnowledgeSandboxResult'),
'必须使用 KnowledgeChunk 或 KnowledgeSandboxResult 契约类型'
);
assert.ok(content.includes('lightColors'), '必须引用 lightColors 设计 Token');
assert.ok(!/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(content), '严禁硬编码十六进制颜色');
assert.ok(!/\bany\b/.test(content), '页面严禁使用 any');
// 严禁包含 emoji
assert.ok(!/[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u27BF]/.test(content), '严禁使用 emoji');
});
test('2. 召回沙盒支持输入测试提问、切片卡片渲染与置信度分数进度条', () => {
const content = fs.readFileSync(knowledgePagePath, 'utf-8');
assert.ok(content.includes('sandboxVisible') || content.includes('sandboxDrawer') || content.includes('openSandbox'), '必须包含沙盒显示控制状态');
assert.ok(content.includes('query') || content.includes('sandboxQuery'), '必须支持测试提问 query 输入');
assert.ok(content.includes('recallList') || content.includes('recalledList') || content.includes('recallResults'), '必须维护召回切片结果列表');
assert.ok(content.includes('score'), '必须展示切片置信度 score');
assert.ok(content.includes('percent'), 'Progress 必须配置 percent 计算属性');
assert.ok(content.includes('chunkSize') || content.includes('topK'), '沙盒应支持调试参数配置');
});
test('3. 知识库多语言字典必须包含沙盒调试相关词条,且无 any 与无 emoji', () => {
assert.ok(fs.existsSync(knowledgeLocalePath), '语言包必须存在');
const content = fs.readFileSync(knowledgeLocalePath, 'utf-8');
assert.ok(content.includes('aiKnowledge.sandbox.title'), '必须包含沙盒标题文案');
assert.ok(content.includes('aiKnowledge.sandbox.query'), '必须包含测试提问文案');
assert.ok(content.includes('aiKnowledge.sandbox.test'), '必须包含沙盒测试执行按钮文案');
assert.ok(content.includes('aiKnowledge.sandbox.score'), '必须包含置信度分数文案');
assert.ok(!/\bany\b/.test(content), '语言包严禁使用 any');
assert.ok(!/[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u27BF]/.test(content), '语言包严禁使用 emoji');
});
test('4. 沙盒置信度分数与进度条数值转换契约测试', () => {
// 模拟置信度归一化算法,验证 0~1 的 score 转换为 0~100 的 percent
const calculatePercent = (score?: number): number => {
if (score === undefined || Number.isNaN(score) || score <= 0) return 0;
if (score >= 1) return 100;
return Math.round(score * 100);
};
assert.equal(calculatePercent(0), 0);
assert.equal(calculatePercent(0.852), 85);
assert.equal(calculatePercent(0.999), 100);
assert.equal(calculatePercent(1.0), 100);
assert.equal(calculatePercent(undefined), 0);
});