/** * scaffold-routes — the page-existence cross-check uses the scaffolder's own * naming (render/page-files.ts). Before 2026-09 (audit B-WARN-13) it looked for * `${entity}sListPage` under `src/pages/{module}/…`, so it warned on EVERY * canonical run and could never catch a real miss. */ import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { mkdirSync, mkdtempSync, rmSync, unlinkSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import path from 'node:path' import { validate } from '../validate.js' let root: string beforeEach(() => { root = mkdtempSync(path.join(tmpdir(), 'ssroutes-pages-')) mkdirSync(path.join(root, 'src'), { recursive: true }) }) afterEach(() => rmSync(root, { recursive: true, force: true })) const put = (rel: string): void => { const abs = path.join(root, rel) mkdirSync(path.dirname(abs), { recursive: true }) writeFileSync(abs, 'export default () => null\n', 'utf8') } const DIR = 'src/pages/myapp/rh/jours-feries' const spec = (entity: Record) => ({ module: 'rh', appCode: 'myapp', projectPath: root, entities: [{ name: 'JourFerie', section: 'jours-feries', ...entity }] }) const missing = (warnings: string[]): string[] => warnings.filter((w) => w.startsWith('Page missing')) describe('checkPagesExist — the scaffolder’s names, the scaffolder’s directory', () => { it('SILENT when the canonical pages exist (create + edit share the form page; kanban is ignored)', () => { for (const f of ['JourFeriesListPage.tsx', 'JourFerieDetailPage.tsx', 'JourFerieFormPage.tsx']) put(`${DIR}/${f}`) const r = validate(spec({ views: ['list', 'detail', 'create', 'edit', 'kanban'] })) expect(r.valid, r.errors.join('\n')).toBe(true) expect(missing(r.warnings)).toEqual([]) expect(r.warnings.some((w) => w.includes("legacy 'kanban' view token ignored"))).toBe(true) }) it('warns ONCE, with the real expected path, when the form page is missing', () => { for (const f of ['JourFeriesListPage.tsx', 'JourFerieDetailPage.tsx']) put(`${DIR}/${f}`) const r = validate(spec({ views: ['list', 'detail', 'create', 'edit'] })) expect(missing(r.warnings)).toEqual([ `Page missing for JourFerie.create: expected at ${DIR}/JourFerieFormPage.tsx — run scaffold-component first, otherwise the registry will reference a phantom import (Vite fails at launch on those).`, ]) }) it('honours pluralName and a pageFilePaths override', () => { put(`${DIR}/JoursFeriesListPage.tsx`) expect(missing(validate(spec({ views: ['list'], pluralName: 'JoursFeries' })).warnings)).toEqual([]) unlinkSync(path.join(root, `${DIR}/JoursFeriesListPage.tsx`)) put('src/pages/legacy/JoursListPage.tsx') expect(missing(validate(spec({ views: ['list'], pageFilePaths: { list: 'src/pages/legacy/JoursListPage.tsx' } })).warnings)).toEqual([]) }) it('a nested resource is expected under its parent section', () => { put('src/pages/myapp/rh/types-affaire/jours-feries/JourFerieDetailPage.tsx') expect(missing(validate(spec({ views: ['detail'], parentSection: 'types-affaire' })).warnings)).toEqual([]) }) })