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 { return { report: { matched: [], reqOnly: [], noteOnly: [], 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); });