106 行
4.7 KiB
TypeScript
106 行
4.7 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';
|
|
import { routes } from '../src/routes.ts';
|
|
import defaultI18n from '../src/locale/index.ts';
|
|
|
|
const adminRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const radarLogPagePath = path.join(adminRoot, 'src/pages/crm/radar-log/index.tsx');
|
|
const radarLogLocalePath = path.join(
|
|
adminRoot,
|
|
'src/pages/crm/radar-log/locale/index.ts'
|
|
);
|
|
|
|
function flattenRouteKeys(items: typeof routes): string[] {
|
|
return items.flatMap((item) => [
|
|
item.key,
|
|
...(item.children ? flattenRouteKeys(item.children) : []),
|
|
]);
|
|
}
|
|
|
|
test('1. routes.ts 必须包含 key crm/radar-log,供 layout glob 加载', () => {
|
|
const keys = flattenRouteKeys(routes);
|
|
assert.ok(keys.includes('crm'), '应存在一级菜单 key: crm');
|
|
assert.ok(keys.includes('crm/radar-log'), '应存在路由 key: crm/radar-log');
|
|
|
|
const crmGroup = routes.find((item) => item.key === 'crm');
|
|
assert.ok(crmGroup, '应存在 menu.crm 分组');
|
|
assert.equal(crmGroup?.name, 'menu.crm');
|
|
assert.ok(
|
|
crmGroup?.children?.some(
|
|
(child) =>
|
|
child.key === 'crm/radar-log' && child.name === 'menu.crm.radarLog'
|
|
),
|
|
'crm 分组下应有 menu.crm.radarLog / crm/radar-log'
|
|
);
|
|
});
|
|
|
|
test('2. locale 必须包含 menu.crm.radarLog 中英文案', () => {
|
|
assert.equal(defaultI18n['en-US']['menu.crm.radarLog'], 'Visitor Logs');
|
|
assert.equal(defaultI18n['zh-CN']['menu.crm.radarLog'], '访客足迹');
|
|
});
|
|
|
|
test('3. radar-log/index.tsx 必须请求 admin/crm/radar/page 并使用 Arco Table', () => {
|
|
assert.ok(fs.existsSync(radarLogPagePath), '访客足迹页面必须存在');
|
|
const content = fs.readFileSync(radarLogPagePath, 'utf-8');
|
|
|
|
assert.ok(
|
|
content.includes('admin/crm/radar/page'),
|
|
'必须请求 POST /api/admin/crm/radar/page'
|
|
);
|
|
assert.ok(content.includes('Table'), '必须使用 Arco Table');
|
|
assert.ok(
|
|
content.includes("from '@arco-design/web-react'"),
|
|
'必须从 @arco-design/web-react 引入组件'
|
|
);
|
|
assert.ok(content.includes('Form'), '必须使用 Arco Form');
|
|
assert.ok(content.includes('Select'), '必须使用 Arco Select');
|
|
assert.ok(content.includes('Tag'), '必须使用 Arco Tag');
|
|
assert.ok(
|
|
content.includes('code === 1000') || content.includes('code ===1000'),
|
|
'必须按 Cool-Admin code === 1000 判断成功'
|
|
);
|
|
assert.ok(content.includes('Message.error'), '失败必须使用 Arco Message.error');
|
|
assert.ok(
|
|
!content.includes('Mock.js') && !content.includes("from 'mockjs'"),
|
|
'禁止用 Mock.js 假数据冒充成功'
|
|
);
|
|
assert.ok(!/\bany\b/.test(content), '禁止使用 any');
|
|
});
|
|
|
|
test('4. radar-log/index.tsx 必须按 RadarTrack / TouchType 渲染足迹列与筛选', () => {
|
|
const content = fs.readFileSync(radarLogPagePath, 'utf-8');
|
|
|
|
assert.ok(
|
|
content.includes('RadarTrack') && content.includes('TouchType'),
|
|
'必须引用 RadarTrack / TouchType'
|
|
);
|
|
assert.ok(content.includes("from '@/types/omni'"), '必须复用 admin/src/types/omni.ts');
|
|
assert.ok(content.includes('touchType'), '必须包含 touchType 筛选与列');
|
|
assert.ok(content.includes("'nfc'") && content.includes("'qr'") && content.includes("'link'"), 'touchType 必须覆盖 nfc/qr/link');
|
|
assert.ok(content.includes('cardId'), '必须支持 cardId 筛选');
|
|
assert.ok(content.includes('country'), '必须支持 country 筛选');
|
|
assert.ok(content.includes('keyWord'), '请求体必须包含 keyWord');
|
|
assert.ok(
|
|
content.includes('createTime') && content.includes('createdAt'),
|
|
'必须兼容 createTime / createdAt'
|
|
);
|
|
assert.ok(content.includes('visitorId'), '必须展示 visitorId');
|
|
assert.ok(content.includes('stayDurationMs'), '必须展示 stayDurationMs');
|
|
assert.ok(content.includes('scrollDepth'), '必须展示 scrollDepth');
|
|
assert.ok(content.includes('viewedBlocks'), '必须展示 viewedBlocks');
|
|
assert.ok(content.includes('setData([])'), '失败必须清空表格');
|
|
});
|
|
|
|
test('5. 页面 locale 必须覆盖筛选与列文案,且禁止 any', () => {
|
|
assert.ok(fs.existsSync(radarLogLocalePath), '访客足迹 locale 必须存在');
|
|
const content = fs.readFileSync(radarLogLocalePath, 'utf-8');
|
|
assert.ok(content.includes('radarLog.filter.cardId'), '必须有 cardId 筛选文案');
|
|
assert.ok(content.includes('radarLog.filter.touchType'), '必须有 touchType 筛选文案');
|
|
assert.ok(content.includes('radarLog.filter.country'), '必须有 country 筛选文案');
|
|
assert.ok(content.includes('radarLog.columns.viewedBlocks'), '必须有 viewedBlocks 列文案');
|
|
assert.ok(!/\bany\b/.test(content), 'locale 禁止使用 any');
|
|
});
|