71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
||
import test from 'node:test';
|
||
import type { VersionWithContext } from './derive';
|
||
import { filterXiaobaoWarningVersions, formatRemainingWork, sanitizeRiskInsight } from './xiaobao-warning-view';
|
||
|
||
function version(patch: Partial<VersionWithContext> = {}): VersionWithContext {
|
||
return {
|
||
id: 'ver-1',
|
||
name: 'V1.0',
|
||
status: 'developing',
|
||
releaseDate: null,
|
||
createdAt: '2026-06-29T00:00:00.000Z',
|
||
productId: 'prod-1',
|
||
productName: 'FTB',
|
||
projectId: 'proj-1',
|
||
projectName: 'Project',
|
||
expectedReleaseDate: '2026-07-05T10:00:00.000Z',
|
||
members: [{ name: 'Alice', role: 'frontend' }],
|
||
...patch,
|
||
};
|
||
}
|
||
|
||
test('filterXiaobaoWarningVersions lets managers see every unfinished version', () => {
|
||
const result = filterXiaobaoWarningVersions(
|
||
[
|
||
version({ id: 'ver-1', status: 'developing', members: [{ name: 'Alice', role: 'frontend' }] }),
|
||
version({ id: 'ver-2', status: 'planned', members: [{ name: 'Bob', role: 'testing' }] }),
|
||
version({ id: 'ver-3', status: 'released', members: [{ name: 'Alice', role: 'frontend' }] }),
|
||
],
|
||
{ canManage: true, userName: 'Alice' },
|
||
);
|
||
|
||
assert.deepEqual(result.map((item) => item.id), ['ver-1', 'ver-2']);
|
||
});
|
||
|
||
test('filterXiaobaoWarningVersions limits non-managers to versions where they are a member', () => {
|
||
const result = filterXiaobaoWarningVersions(
|
||
[
|
||
version({ id: 'ver-1', status: 'developing', members: [{ name: 'Alice', role: 'frontend' }] }),
|
||
version({ id: 'ver-2', status: 'developing', members: [{ name: 'Bob', role: 'testing' }] }),
|
||
version({ id: 'ver-3', status: 'closed', members: [{ name: 'Alice', role: 'frontend' }] }),
|
||
],
|
||
{ canManage: false, userName: 'Alice' },
|
||
);
|
||
|
||
assert.deepEqual(result.map((item) => item.id), ['ver-1']);
|
||
});
|
||
|
||
test('formatRemainingWork keeps hours and adds work-day conversion', () => {
|
||
assert.equal(formatRemainingWork(0), '0h / 0天');
|
||
assert.equal(formatRemainingWork(8), '8h / 1天');
|
||
assert.equal(formatRemainingWork(12), '12h / 1.5天');
|
||
assert.equal(formatRemainingWork(0.5), '0.5h / 0.1天');
|
||
});
|
||
|
||
test('sanitizeRiskInsight filters invalid page refresh suggested actions', () => {
|
||
const result = sanitizeRiskInsight({
|
||
summary: '风险上升',
|
||
why: ['P1 Bug 增加'],
|
||
forecast: '预计延期 1 天',
|
||
suggestedActions: [
|
||
'手动触发页面刷新,等待小宝预警自动更新',
|
||
'优先处理 3 个 P1 Bug,并同步测试负责人复测',
|
||
],
|
||
ownerHints: ['研发负责人协调修复顺序'],
|
||
generatedAt: '2026-06-30T10:00:00.000Z',
|
||
});
|
||
|
||
assert.deepEqual(result.suggestedActions, ['优先处理 3 个 P1 Bug,并同步测试负责人复测']);
|
||
});
|