87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import type { Requirement } from './requirement';
|
|
import {
|
|
buildRequirementScopeTree,
|
|
filterRequirementsByScope,
|
|
type RequirementScopeSelection,
|
|
} from './requirement-scope';
|
|
|
|
const baseRequirement = {
|
|
code: 'REQ-001',
|
|
title: 'Requirement',
|
|
description: '',
|
|
sourceType: 'internal',
|
|
sourceTarget: '',
|
|
platforms: [] as string[],
|
|
typeId: '',
|
|
priority: 'P2',
|
|
effort: 'M',
|
|
creator: 'tester',
|
|
createdAt: '2026-06-29T00:00:00.000Z',
|
|
};
|
|
|
|
function req(id: string, productId: string, projectId: string, status: Requirement['status'] = 'pending_review'): Requirement {
|
|
return {
|
|
...baseRequirement,
|
|
id,
|
|
code: id.toUpperCase(),
|
|
productId,
|
|
projectId,
|
|
status,
|
|
} as Requirement;
|
|
}
|
|
|
|
const overview = [
|
|
{
|
|
id: 'product-1',
|
|
name: 'CRM',
|
|
projects: [
|
|
{ id: 'project-1', name: 'Mobile', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
|
|
{ id: 'project-2', name: 'Admin', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
|
|
],
|
|
versions: [],
|
|
},
|
|
{
|
|
id: 'product-2',
|
|
name: 'BI',
|
|
projects: [
|
|
{ id: 'project-3', name: 'Dashboard', description: '', createdAt: '2026-06-29T00:00:00.000Z' },
|
|
],
|
|
versions: [],
|
|
},
|
|
];
|
|
|
|
test('filters requirements by all product and project scopes', () => {
|
|
const requirements = [
|
|
req('req-1', 'product-1', 'project-1'),
|
|
req('req-2', 'product-1', 'project-2'),
|
|
req('req-3', 'product-2', 'project-3'),
|
|
];
|
|
|
|
const allScope: RequirementScopeSelection = { type: 'all' };
|
|
const productScope: RequirementScopeSelection = { type: 'product', productId: 'product-1' };
|
|
const projectScope: RequirementScopeSelection = { type: 'project', projectId: 'project-2' };
|
|
|
|
assert.deepEqual(filterRequirementsByScope(requirements, allScope).map((item) => item.id), ['req-1', 'req-2', 'req-3']);
|
|
assert.deepEqual(filterRequirementsByScope(requirements, productScope).map((item) => item.id), ['req-1', 'req-2']);
|
|
assert.deepEqual(filterRequirementsByScope(requirements, projectScope).map((item) => item.id), ['req-2']);
|
|
});
|
|
|
|
test('builds product and project tree counts from requirements', () => {
|
|
const tree = buildRequirementScopeTree(overview, [
|
|
req('req-1', 'product-1', 'project-1', 'pending_review'),
|
|
req('req-2', 'product-1', 'project-1', 'developing'),
|
|
req('req-3', 'product-1', 'project-2', 'closed'),
|
|
req('req-4', 'product-2', 'project-3', 'adopted'),
|
|
]);
|
|
|
|
assert.equal(tree[0].count.total, 3);
|
|
assert.equal(tree[0].count.byStatus.pending_review, 1);
|
|
assert.equal(tree[0].projects[0].count.total, 2);
|
|
assert.equal(tree[0].projects[0].count.byStatus.developing, 1);
|
|
assert.equal(tree[0].projects[1].count.total, 1);
|
|
assert.equal(tree[1].count.total, 1);
|
|
});
|