diff --git a/api-v3/test/unit/phase-f4-recurrence.test.ts b/api-v3/test/unit/phase-f4-recurrence.test.ts new file mode 100644 index 0000000..edad9e3 --- /dev/null +++ b/api-v3/test/unit/phase-f4-recurrence.test.ts @@ -0,0 +1,39 @@ +import 'reflect-metadata'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import test from 'node:test'; +import { REQUIRED_PERMISSIONS_KEY } from '../../src/authorization/decorators/require-permissions.decorator'; +import { InspectionFindingRecurrenceController } from '../../src/inspection-findings/inspection-finding-recurrence.controller'; + +const root = process.cwd(); +const read = (relative: string) => fs.readFileSync(path.join(root, relative), 'utf8'); + +function permissions(method: string): string[] { + const handler = InspectionFindingRecurrenceController.prototype[ + method as keyof InspectionFindingRecurrenceController + ]; + return Reflect.getMetadata(REQUIRED_PERMISSIONS_KEY, handler) as string[]; +} + +test('F4 exposes recurrence candidates for the selected Inventory and creates a new Finding', () => { + assert.deepEqual(permissions('candidates'), ['inspection_findings.read']); + assert.deepEqual(permissions('create'), ['inspection_findings.create']); +}); + +test('F4 recurrence only accepts an unresolved prior Finding from the same Inventory context', () => { + const service = read('src/inspection-findings/inspection-finding-recurrence.service.ts'); + assert.match(service, /finding\.status = 'OPEN'/); + assert.match(service, /INSPECTION_FINDING_ANTECEDENT_RESOLVED/); + assert.match(service, /INSPECTION_FINDING_RECURRENCE_ASSET_NOT_IN_ACT/); + assert.match(service, /finding\.act_id <> \$2/); +}); + +test('F4 creates recurrence append-only as a new Finding linked to its antecedent', () => { + const service = read('src/inspection-findings/inspection-finding-recurrence.service.ts'); + assert.match(service, /is_recurrence/); + assert.match(service, /antecedent_finding_id/); + assert.match(service, /INSERT INTO inspection_finding_versions/); + assert.match(service, /recurrence: true/); + assert.doesNotMatch(service, /UPDATE inspection_findings[\s\S]*antecedentFindingId/); +});