website refactor
This commit is contained in:
142
apps/website/tests/guardrails/architecture-guardrails.test.ts
Normal file
142
apps/website/tests/guardrails/architecture-guardrails.test.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
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<string, number>);
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user