import { describe, it, expect } from 'vitest'; import { ArchitectureGuardrails } from './ArchitectureGuardrails'; /** * Architecture Guardrail Tests * * These tests enforce the architectural contract for the website. * They use an allowlist to permit existing violations while preventing new ones. * * The goal is to shrink the allowlist slice-by-slice until zero violations remain. */ describe('Architecture Guardrails', () => { const guardrails = new ArchitectureGuardrails(); it('should detect all violations in the codebase', () => { const allViolations = guardrails.scan(); // This test documents the current state // It will always pass but shows what violations exist console.log(`\n๐Ÿ“Š Total violations found: ${allViolations.length}`); if (allViolations.length > 0) { console.log('\n๐Ÿ“‹ Violations by rule:'); const byRule = allViolations.reduce((acc, v) => { acc[v.ruleName] = (acc[v.ruleName] || 0) + 1; return acc; }, {} as Record); Object.entries(byRule).forEach(([rule, count]) => { console.log(` - ${rule}: ${count}`); }); } // We expect violations to exist initially expect(allViolations.length).toBeGreaterThanOrEqual(0); }); it('should have no violations after filtering by allowlist', () => { const filteredViolations = guardrails.getFilteredViolations(); console.log(`\n๐Ÿ” Filtered violations (after allowlist): ${filteredViolations.length}`); if (filteredViolations.length > 0) { console.log('\nโŒ New violations not in allowlist:'); filteredViolations.forEach(v => { console.log(` - ${v.toString()}`); }); } // This is the main assertion - no new violations allowed expect(filteredViolations.length).toBe(0); }); it('should not have stale allowlist entries', () => { const staleEntries = guardrails.findStaleAllowlistEntries(); console.log(`\n๐Ÿงน Stale allowlist entries: ${staleEntries.length}`); if (staleEntries.length > 0) { console.log('\nโš ๏ธ These allowlist entries no longer match any violations:'); staleEntries.forEach(entry => { console.log(` - ${entry}`); }); console.log('\n๐Ÿ’ก Consider removing them from allowed-violations.ts'); } // Stale entries should be removed to keep allowlist clean expect(staleEntries.length).toBe(0); }); it('should enforce: no ContainerManager in server page queries', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-container-manager-in-server' ); expect(violations.length).toBe(0); }); it('should enforce: no PageDataFetcher.fetch() in server page queries', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-page-data-fetcher-fetch-in-server' ); expect(violations.length).toBe(0); }); it('should enforce: no view-models imports in server code', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-view-models-in-server' ); expect(violations.length).toBe(0); }); it('should enforce: no view-models/display-objects in templates', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-view-models-in-templates' ); expect(violations.length).toBe(0); }); it('should enforce: no Intl.* or toLocale* in presentation paths', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-intl-in-presentation' ); expect(violations.length).toBe(0); }); it('should enforce: no client-side write fetch', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-client-write-fetch' ); expect(violations.length).toBe(0); }); it('should enforce: no *Template.tsx under app/', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-templates-in-app' ); expect(violations.length).toBe(0); }); it('should enforce: no hooks directory in apps/website/', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-hooks-directory' ); expect(violations.length).toBe(0); }); it('should enforce: no as any usage', () => { const violations = guardrails.getFilteredViolations().filter( v => v.ruleName === 'no-as-any' ); expect(violations.length).toBe(0); }); });