website refactor

This commit is contained in:
2026-01-18 00:17:01 +01:00
parent 69d4cce7f1
commit 4b66c682a0
18 changed files with 847 additions and 87 deletions

View File

@@ -1,6 +1,7 @@
import { describe, it, expect } from 'vitest';
import { getWebsiteRouteContracts } from '../../shared/website/RouteContractSpec';
import { getWebsiteRouteContracts, ScenarioRole } from '../../shared/website/RouteContractSpec';
import { WebsiteRouteManager } from '../../shared/website/WebsiteRouteManager';
import { RouteScenarioMatrix } from '../../shared/website/RouteScenarioMatrix';
describe('RouteContractSpec', () => {
const contracts = getWebsiteRouteContracts();
@@ -24,7 +25,46 @@ describe('RouteContractSpec', () => {
it('should have expectedStatus set for every contract', () => {
contracts.forEach(contract => {
expect(contract.expectedStatus).toBeDefined();
expect(['ok', 'redirect', 'notFoundAllowed', 'errorRoute']).toContain(contract.expectedStatus);
expect(['ok', 'redirect', 'forbidden', 'notFoundAllowed', 'errorRoute']).toContain(contract.expectedStatus);
});
});
it('should have required scenarios based on access level', () => {
contracts.forEach(contract => {
const scenarios = Object.keys(contract.scenarios) as ScenarioRole[];
// All routes must have unauth, auth, admin, sponsor scenarios
expect(scenarios).toContain('unauth');
expect(scenarios).toContain('auth');
expect(scenarios).toContain('admin');
expect(scenarios).toContain('sponsor');
// Admin and Sponsor routes must also have wrong-role scenario
if (contract.accessLevel === 'admin' || contract.accessLevel === 'sponsor') {
expect(scenarios).toContain('wrong-role');
}
});
});
it('should have correct scenario expectations for admin routes', () => {
const adminContracts = contracts.filter(c => c.accessLevel === 'admin');
adminContracts.forEach(contract => {
expect(contract.scenarios.unauth?.expectedStatus).toBe('redirect');
expect(contract.scenarios.auth?.expectedStatus).toBe('redirect');
expect(contract.scenarios.admin?.expectedStatus).toBe('ok');
expect(contract.scenarios.sponsor?.expectedStatus).toBe('redirect');
expect(contract.scenarios['wrong-role']?.expectedStatus).toBe('redirect');
});
});
it('should have correct scenario expectations for sponsor routes', () => {
const sponsorContracts = contracts.filter(c => c.accessLevel === 'sponsor');
sponsorContracts.forEach(contract => {
expect(contract.scenarios.unauth?.expectedStatus).toBe('redirect');
expect(contract.scenarios.auth?.expectedStatus).toBe('redirect');
expect(contract.scenarios.admin?.expectedStatus).toBe('redirect');
expect(contract.scenarios.sponsor?.expectedStatus).toBe('ok');
expect(contract.scenarios['wrong-role']?.expectedStatus).toBe('redirect');
});
});
@@ -50,4 +90,20 @@ describe('RouteContractSpec', () => {
expect(contract.ssrMustNotContain).toContain('Application error: a client-side exception has occurred');
});
});
describe('RouteScenarioMatrix', () => {
it('should match the number of contracts', () => {
expect(RouteScenarioMatrix.length).toBe(contracts.length);
});
it('should correctly identify routes with param edge cases', () => {
const edgeCaseRoutes = RouteScenarioMatrix.filter(m => m.hasParamEdgeCases);
// Based on WebsiteRouteManager.getParamEdgeCases(), we expect at least /races/[id] and /leagues/[id]
expect(edgeCaseRoutes.length).toBeGreaterThanOrEqual(2);
const paths = edgeCaseRoutes.map(m => m.path);
expect(paths.some(p => p.startsWith('/races/'))).toBe(true);
expect(paths.some(p => p.startsWith('/leagues/'))).toBe(true);
});
});
});