import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; const root = process.cwd(); const readWeb = (relative: string) => fs.readFileSync(path.join(root, '..', 'web-v2', 'src', relative), 'utf8'); const f4Api = readWeb('lib/inspectionActF4Api.ts'); const actsPage = readWeb('pages/ActsPage.tsx'); const actsPanel = readWeb('features/inspections/InspectionActsPanel.tsx'); const actDetail = readWeb('pages/InspectionActEditorPage.tsx'); const closurePanel = readWeb('features/inspections/InspectionClosurePanel.tsx'); const presentation = readWeb('features/inspections/inspectionActPresentation.ts'); test('F4 WEB has an explicit LOCKED and SEALED act contract', () => { assert.match(f4Api, /export type InspectionActStatusF4/); assert.match(f4Api, /\| 'LOCKED'/); assert.match(f4Api, /\| 'SEALED'/); assert.match(f4Api, /lockedAt: string \| null/); assert.match(f4Api, /lockedSha256: string \| null/); assert.match(f4Api, /sealedAt: string \| null/); assert.match(f4Api, /urgency: InspectionActUrgencyF4/); assert.match(f4Api, /deadlineAt: string \| null/); }); test('F4 document center and inspection detail consume the F4 act client', () => { assert.match(actsPage, /listInspectionActsGlobalF4/); assert.match(actsPage, /value: 'LOCKED'/); assert.match(actsPage, /value: 'SEALED'/); assert.match(actsPanel, /listInspectionActsF4/); assert.match(actDetail, /getInspectionActF4/); assert.match(actDetail, /act\?\.status === 'SEALED'/); }); test('F4 closure UI treats sealing as the definitive act state', () => { assert.match(closurePanel, /getInspectionClosureF4/); assert.match(closurePanel, /act\.status === 'SEALED'/); assert.match(closurePanel, /ACTA SELLADA/); assert.match(closurePanel, /manifestación de la empresa puede completarse/); assert.match(closurePanel, /Pendiente de evento válido/); assert.doesNotMatch(closurePanel, /reabrir ni cerrar el acta/); }); test('F4 presentation keeps new lifecycle labels while retaining explicit legacy readability', () => { assert.match(presentation, /LOCKED: 'Bloqueada/); assert.match(presentation, /SEALED: 'Sellada'/); assert.match(presentation, /READY: 'Lista para cerrar · legado'/); assert.match(presentation, /CLOSED: 'Cerrada · legado'/); });