import test from 'node:test'; import assert from 'node:assert/strict'; import type { Bug } from './bug'; import { applyBugTransition } from './bug-workflow'; function bug(patch: Partial = {}): Bug { return { id: 'bug-1', bugNo: 'BUG-001', versionId: 'version-1', testCaseId: 'tc-1', title: '排序未保存', description: '拖拽后刷新丢失', severity: 'major', priority: 'P1', reportedBy: 'QA', assigneeId: 'Dev', status: 'open', logs: [], createdAt: '2026-06-25T00:00:00.000Z', updatedAt: '2026-06-25T00:00:00.000Z', ...patch, }; } test('open to fixing returns a single bug status patch', () => { const result = applyBugTransition(bug(), 'fixing', 'Dev', { now: new Date('2026-06-25T01:00:00.000Z'), }); assert.equal(result.ok, true); assert.equal(result.patch?.status, 'fixing'); assert.equal(result.patch?.logs?.length, 1); }); test('fixing to fixed writes resolvedAt and resolution', () => { const result = applyBugTransition(bug({ status: 'fixing' }), 'fixed', 'Dev', { now: new Date('2026-06-25T02:00:00.000Z'), resolution: '补充保存接口', }); assert.equal(result.ok, true); assert.equal(result.patch?.resolvedAt, '2026-06-25T02:00:00.000Z'); assert.equal(result.patch?.resolution, '补充保存接口'); }); test('verifying to closed writes closedAt', () => { const result = applyBugTransition(bug({ status: 'verifying' }), 'closed', 'QA', { now: new Date('2026-06-25T03:00:00.000Z'), }); assert.equal(result.ok, true); assert.equal(result.patch?.closedAt, '2026-06-25T03:00:00.000Z'); }); test('invalid bug transition is rejected', () => { const result = applyBugTransition(bug(), 'closed', 'QA'); assert.equal(result.ok, false); });