139 lines
3.9 KiB
TypeScript
139 lines
3.9 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { filterDuplicateDecomposeDrafts } from './ai-decompose-dedupe';
|
|
import type { AgentDecomposeResult } from '@ftb/shared';
|
|
import type { DevTask } from './dev-task';
|
|
import type { TestCase } from './test-case';
|
|
import type { TaskCategory } from './task-category';
|
|
|
|
const categories: TaskCategory[] = [
|
|
{
|
|
id: 'cat-frontend',
|
|
code: 'frontend_interaction',
|
|
name: '前端交互',
|
|
group: 'development',
|
|
sortOrder: 1,
|
|
isSystem: true,
|
|
},
|
|
{
|
|
id: 'cat-test-functional',
|
|
code: 'test_functional',
|
|
name: '功能测试',
|
|
group: 'testing',
|
|
sortOrder: 2,
|
|
isSystem: true,
|
|
},
|
|
];
|
|
|
|
const requirements = [{ id: 'req-1', code: 'REQ001' }];
|
|
|
|
function makeResult(patch: Partial<AgentDecomposeResult>): AgentDecomposeResult {
|
|
return {
|
|
report: { matched: [], reqOnly: [], prototypeOnly: [], ambiguous: [] },
|
|
devTaskDrafts: [],
|
|
testCaseDrafts: [],
|
|
...patch,
|
|
};
|
|
}
|
|
|
|
test('filters dev task drafts already adopted into existing tasks', () => {
|
|
const existingDevTasks = [
|
|
{
|
|
id: 'task-1',
|
|
title: '实现拖拽排序',
|
|
categoryId: 'cat-frontend',
|
|
references: [
|
|
{ type: 'requirement', id: 'req-1', label: 'REQ001 拖拽排序' },
|
|
{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' },
|
|
],
|
|
},
|
|
] as DevTask[];
|
|
|
|
const result = filterDuplicateDecomposeDrafts(
|
|
makeResult({
|
|
devTaskDrafts: [
|
|
{
|
|
title: '实现拖拽排序',
|
|
categoryCode: 'frontend_interaction',
|
|
priority: 'P2',
|
|
aiEstimateHours: 0.25,
|
|
references: [
|
|
{ type: 'requirement', id: 'REQ001', label: 'REQ001 拖拽排序' },
|
|
{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' },
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
{ existingDevTasks, existingTestCases: [], categories, requirements },
|
|
);
|
|
|
|
assert.equal(result.removedDevTaskCount, 1);
|
|
assert.equal(result.result.devTaskDrafts.length, 0);
|
|
});
|
|
|
|
test('filters test case drafts already adopted into existing test cases', () => {
|
|
const existingTestCases = [
|
|
{
|
|
id: 'tc-1',
|
|
title: '验证拖拽排序成功',
|
|
categoryId: 'cat-test-functional',
|
|
references: [
|
|
{ type: 'requirement', id: 'req-1', label: 'REQ001 拖拽排序' },
|
|
{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' },
|
|
],
|
|
},
|
|
] as TestCase[];
|
|
|
|
const result = filterDuplicateDecomposeDrafts(
|
|
makeResult({
|
|
testCaseDrafts: [
|
|
{
|
|
title: '验证拖拽排序成功',
|
|
description: '拖拽后顺序保存',
|
|
categoryCode: 'test_functional',
|
|
priority: 'P2',
|
|
aiEstimateHours: 0.2,
|
|
references: [
|
|
{ type: 'requirement', id: 'REQ001', label: 'REQ001 拖拽排序' },
|
|
{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' },
|
|
],
|
|
},
|
|
],
|
|
}),
|
|
{ existingDevTasks: [], existingTestCases, categories, requirements },
|
|
);
|
|
|
|
assert.equal(result.removedTestCaseCount, 1);
|
|
assert.equal(result.result.testCaseDrafts.length, 0);
|
|
});
|
|
|
|
test('keeps drafts with same references but different normalized title', () => {
|
|
const existingDevTasks = [
|
|
{
|
|
id: 'task-1',
|
|
title: '实现拖拽排序',
|
|
categoryId: 'cat-frontend',
|
|
references: [{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' }],
|
|
},
|
|
] as DevTask[];
|
|
|
|
const result = filterDuplicateDecomposeDrafts(
|
|
makeResult({
|
|
devTaskDrafts: [
|
|
{
|
|
title: '保存拖拽排序结果',
|
|
categoryCode: 'frontend_interaction',
|
|
priority: 'P2',
|
|
aiEstimateHours: 0.5,
|
|
references: [{ type: 'prototype_note', id: 'QY0001', label: 'QY0001' }],
|
|
},
|
|
],
|
|
}),
|
|
{ existingDevTasks, existingTestCases: [], categories, requirements },
|
|
);
|
|
|
|
assert.equal(result.removedDevTaskCount, 0);
|
|
assert.equal(result.result.devTaskDrafts.length, 1);
|
|
});
|