Files
ftb-project-management/apps/web/lib/requirement-selector.test.ts

65 lines
1.8 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
getProjectAdoptedRequirementCandidates,
getVersionLinkedRequirementCandidates,
mergeSelectedRequirementOptions,
} from './requirement-selector';
import type { Requirement } from './requirement';
const base = {
description: '',
productId: 'product-1',
sourceType: 'internal',
sourceTarget: '',
platforms: [] as string[],
typeId: '',
priority: 'P2',
effort: 'M',
creator: 'tester',
createdAt: '2026-06-25',
};
function req(id: string, projectId: string, status: Requirement['status']): Requirement {
return {
...base,
id,
code: id.toUpperCase(),
title: `Requirement ${id}`,
projectId,
status,
} as Requirement;
}
test('returns only adopted requirements from current project', () => {
const result = getProjectAdoptedRequirementCandidates([
req('r1', 'project-1', 'adopted'),
req('r2', 'project-1', 'pending_review'),
req('r3', 'project-2', 'adopted'),
], 'project-1');
assert.deepEqual(result.map((r: Requirement) => r.id), ['r1']);
});
test('returns only requirements already linked to current version', () => {
const result = getVersionLinkedRequirementCandidates([
req('r1', 'project-1', 'adopted'),
req('r2', 'project-1', 'developing'),
req('r3', 'project-1', 'adopted'),
req('r4', 'project-2', 'adopted'),
], ['r2', 'r1']);
assert.deepEqual(result.map((r: Requirement) => r.id), ['r2', 'r1']);
});
test('keeps historical selected requirements as non-candidate options', () => {
const options = mergeSelectedRequirementOptions(
[req('r1', 'project-1', 'adopted')],
[req('r1', 'project-1', 'adopted'), req('r2', 'project-1', 'developing')],
['r1', 'r2'],
);
assert.equal(options.find((o: { id: string; isHistorical?: boolean }) => o.id === 'r2')?.isHistorical, true);
});