/** * uat-plan E2E — emit the artifacts to disk, reload them, and re-validate. Proves * the deterministic pipeline (DiscoveryResult → plan → YAML + signature) yields a * file that round-trips and holds every invariant. The live SQL path is covered by * discover's pure tests + the M5 live gate. */ import { describe, it, expect } from 'vitest'; import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { load } from 'js-yaml'; import { generatePlan } from '../generate.js'; import { parsePlan } from '../../lib/plantest-schema.js'; import type { DiscoveryResult } from '../types.js'; const here = dirname(fileURLToPath(import.meta.url)); describe('uat-plan E2E (disk round-trip)', () => { it('writes a plan + signature that reload and re-validate with zero violations', () => { const disc = JSON.parse(readFileSync(join(here, 'fixtures', 'personas.json'), 'utf8')) as DiscoveryResult; const gen = generatePlan(disc, { name: 'administration', outDir: '.application-test/uat/administration', modes: ['bfs', 'goto'], includeApi: true, generatedAt: '2026-06-05T00:00:00.000Z', }); const root = mkdtempSync(join(tmpdir(), 'uat-e2e-')); try { for (const f of gen.files) { const abs = join(root, f.path); mkdirSync(dirname(abs), { recursive: true }); writeFileSync(abs, f.content, 'utf8'); } const base = join(root, '.application-test/uat/administration'); const reloaded = parsePlan(load(readFileSync(join(base, 'administration.plantest.yml'), 'utf8'))); expect(reloaded.ok).toBe(true); if (reloaded.ok) { expect(reloaded.violations).toEqual([]); expect(reloaded.plan.routes.length).toBe(gen.plan.routes.length); expect(reloaded.plan.endpoints.length).toBe(gen.plan.endpoints.length); } expect(JSON.parse(readFileSync(join(base, 'administration.plantest.signature'), 'utf8'))).toEqual(gen.signature); } finally { rmSync(root, { recursive: true, force: true }); } }); });