/** * render/page-files ↔ the renderers — for every materialised view, the file * the REAL generate() emits is exactly what pageFilePathFor() predicts. This is * what lets scaffold-routes' page check and audit-dev-frontend DEV-UI-001/008 * read the helper instead of re-typing the names (audit 2026-09-24, * B-WARN-13 / C-CRIT-06). */ import { describe, it, expect } from 'vitest' import { generate } from '../generate.js' import { validate } from '../validate.js' import { FOLDED_VIEWS, PAGE_FILE_VIEWS, pageFileName, pageFilePathFor, pageFileViewOf, pluralOf } from '../render/page-files.js' const ENTITY = 'JourFerie' function rendered(views: string[], pluralName?: string): string[] { const v = validate({ module: 'rh', appCode: 'MyApp', entity: ENTITY, section: 'jours-feries', views, ...(pluralName ? { pluralName } : {}), fields: [{ name: 'label', type: 'string' }, { name: 'date', type: 'date' }], projectPath: '/web', }) expect(v.valid, v.errors.join('\n')).toBe(true) return generate(v.data!).map((f) => f.path.replace(/\\/g, '/')) } describe('page-files — SSOT ↔ renderers', () => { for (const view of PAGE_FILE_VIEWS) { it(`${view}: generate() emits exactly pageFilePathFor(...)`, () => { const expected = pageFilePathFor({ appCode: 'MyApp', module: 'rh', section: 'jours-feries', entity: ENTITY, view }) expect(rendered([view])).toContain(expected) expect(expected.startsWith('src/pages/myapp/rh/jours-feries/')).toBe(true) // app segment lower-cased like the generator }) } it('pluralName drives the list and hub file names, pluralize() otherwise', () => { expect(rendered(['list'], 'JoursFeries')).toContain('src/pages/myapp/rh/jours-feries/JoursFeriesListPage.tsx') expect(pageFileName('list', ENTITY, 'JoursFeries')).toBe('JoursFeriesListPage.tsx') expect(pageFileName('list', 'Category')).toBe('CategoriesListPage.tsx') expect(pluralOf('Category')).toBe('Categories') expect(pageFileName('module-home', ENTITY)).toBe('JourFeriesModuleHomePage.tsx') }) it('folded and aliased view tokens never demand a file of their own', () => { expect(pageFileViewOf('kanban')).toBeNull() expect(pageFileViewOf('card')).toBeNull() expect(pageFileViewOf('create')).toBe('form') expect(pageFileViewOf('edit')).toBe('form') expect(pageFileViewOf('detail')).toBe('detail') expect(pageFileViewOf('bogus')).toBeNull() expect(Object.keys(FOLDED_VIEWS).sort()).toEqual(['card', 'create', 'edit', 'kanban']) }) it('a pagespec filePath is honoured verbatim; a nested resource lands under its parent section', () => { expect(pageFilePathFor({ appCode: 'MyApp', module: 'rh', section: 'jours-feries', entity: ENTITY, view: 'list', filePath: 'src\\pages\\legacy\\JoursListPage.tsx' })).toBe('src/pages/legacy/JoursListPage.tsx') expect(pageFilePathFor({ appCode: 'gaf', module: 'referentiels', section: 'types-audit', parentSection: 'types-affaire', entity: 'TypeAudit', view: 'detail' })).toBe('src/pages/gaf/referentiels/types-affaire/types-audit/TypeAuditDetailPage.tsx') }) })