import { describe, it, expect } from 'vitest'; import * as fs from 'fs/promises'; import * as path from 'path'; describe('Website boundary: pages must consume ViewModels only (no DTO imports)', () => { it('rejects forbidden imports for specific pages', async () => { const websiteRoot = path.resolve(__dirname, '../..'); const candidates = [ 'app/races/[id]/page.tsx', 'app/leagues/[id]/stewarding/protests/[protestId]/page.tsx', ].map((p) => path.resolve(websiteRoot, p)); const forbiddenImportRegex = /^\s*import[\s\S]*from\s+['"][^'"]*(\/mappers\/|\/lib\/types\/|\/types\/generated\/)[^'"]*['"]/gm; const offenders: Array<{ file: string; matches: string[] }> = []; for (const file of candidates) { const content = await fs.readFile(file, 'utf-8'); const matches = Array.from(content.matchAll(forbiddenImportRegex)) .map((m) => m[0]) .filter(Boolean); if (matches.length > 0) { offenders.push({ file: path.relative(websiteRoot, file), matches, }); } } expect( offenders, `Forbidden imports found:\n${offenders .map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`) .join('\n')}`, ).toEqual([]); }); it('rejects DTO identifier usage in these page modules', async () => { const websiteRoot = path.resolve(__dirname, '../..'); const candidates = [ 'app/races/[id]/page.tsx', 'app/leagues/[id]/stewarding/protests/[protestId]/page.tsx', ].map((p) => path.resolve(websiteRoot, p)); const dtoIdentifierRegex = /\b[A-Za-z0-9_]+DTO\b/g; const offenders: Array<{ file: string; matches: string[] }> = []; for (const file of candidates) { const content = await fs.readFile(file, 'utf-8'); const matches = Array.from(content.matchAll(dtoIdentifierRegex)).map((m) => m[0]).filter(Boolean); if (matches.length > 0) { offenders.push({ file: path.relative(websiteRoot, file), matches: Array.from(new Set(matches)).sort(), }); } } expect( offenders, `DTO identifiers found:\n${offenders .map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`) .join('\n')}`, ).toEqual([]); }); });