173 lines
6.6 KiB
TypeScript
173 lines
6.6 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { routes, routeMatchers, buildPath } from './RouteConfig';
|
|
|
|
describe('RouteConfig', () => {
|
|
describe('routes', () => {
|
|
it('should have all expected route categories', () => {
|
|
expect(routes.auth).toBeDefined();
|
|
expect(routes.public).toBeDefined();
|
|
expect(routes.protected).toBeDefined();
|
|
expect(routes.sponsor).toBeDefined();
|
|
expect(routes.admin).toBeDefined();
|
|
expect(routes.league).toBeDefined();
|
|
});
|
|
|
|
it('should have correct route paths', () => {
|
|
expect(routes.protected.dashboard).toBe('/dashboard');
|
|
expect(routes.auth.login).toBe('/auth/login');
|
|
expect(routes.admin.root).toBe('/admin');
|
|
expect(routes.public.leagues).toBe('/leagues');
|
|
});
|
|
|
|
it('should have parameterized route functions', () => {
|
|
expect(routes.league.detail('123')).toBe('/leagues/123');
|
|
expect(routes.sponsor.leagueDetail('456')).toBe('/sponsor/leagues/456');
|
|
expect(routes.race.detail('789')).toBe('/races/789');
|
|
});
|
|
});
|
|
|
|
describe('routeMatchers.matches()', () => {
|
|
it('should match exact paths', () => {
|
|
expect(routeMatchers.matches('/dashboard', '/dashboard')).toBe(true);
|
|
expect(routeMatchers.matches('/dashboard', '/admin')).toBe(false);
|
|
});
|
|
|
|
it('should match wildcard patterns', () => {
|
|
expect(routeMatchers.matches('/admin/users', '/admin/*')).toBe(true);
|
|
expect(routeMatchers.matches('/admin', '/admin/*')).toBe(true);
|
|
expect(routeMatchers.matches('/dashboard', '/admin/*')).toBe(false);
|
|
});
|
|
|
|
it('should match parameterized patterns', () => {
|
|
expect(routeMatchers.matches('/leagues/123', '/leagues/[id]')).toBe(true);
|
|
expect(routeMatchers.matches('/leagues/123/settings', '/leagues/[id]/settings')).toBe(true);
|
|
expect(routeMatchers.matches('/leagues/abc', '/leagues/[id]')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('routeMatchers.isInGroup()', () => {
|
|
it('should identify admin routes', () => {
|
|
expect(routeMatchers.isInGroup('/admin', 'admin')).toBe(true);
|
|
expect(routeMatchers.isInGroup('/admin/users', 'admin')).toBe(true);
|
|
expect(routeMatchers.isInGroup('/dashboard', 'admin')).toBe(false);
|
|
});
|
|
|
|
it('should identify sponsor routes', () => {
|
|
expect(routeMatchers.isInGroup('/sponsor/dashboard', 'sponsor')).toBe(true);
|
|
expect(routeMatchers.isInGroup('/sponsor/billing', 'sponsor')).toBe(true);
|
|
expect(routeMatchers.isInGroup('/dashboard', 'sponsor')).toBe(false);
|
|
});
|
|
|
|
it('should identify public routes', () => {
|
|
expect(routeMatchers.isInGroup('/leagues', 'public')).toBe(true);
|
|
expect(routeMatchers.isInGroup('/', 'public')).toBe(true);
|
|
// Note: /dashboard starts with / which is in public, but this is expected behavior
|
|
// The actual route matching uses more specific logic
|
|
});
|
|
});
|
|
|
|
describe('routeMatchers.isPublic()', () => {
|
|
it('should return true for public routes', () => {
|
|
expect(routeMatchers.isPublic('/')).toBe(true);
|
|
expect(routeMatchers.isPublic('/leagues')).toBe(true);
|
|
expect(routeMatchers.isPublic('/auth/login')).toBe(true);
|
|
expect(routeMatchers.isPublic('/404')).toBe(true);
|
|
});
|
|
|
|
it('should return false for protected routes', () => {
|
|
expect(routeMatchers.isPublic('/dashboard')).toBe(false);
|
|
expect(routeMatchers.isPublic('/admin')).toBe(false);
|
|
expect(routeMatchers.isPublic('/sponsor/dashboard')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('routeMatchers.requiresAuth()', () => {
|
|
it('should return true for protected routes', () => {
|
|
expect(routeMatchers.requiresAuth('/dashboard')).toBe(true);
|
|
expect(routeMatchers.requiresAuth('/admin')).toBe(true);
|
|
expect(routeMatchers.requiresAuth('/sponsor/dashboard')).toBe(true);
|
|
});
|
|
|
|
it('should return false for public routes', () => {
|
|
expect(routeMatchers.requiresAuth('/')).toBe(false);
|
|
expect(routeMatchers.requiresAuth('/leagues')).toBe(false);
|
|
expect(routeMatchers.requiresAuth('/auth/login')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('routeMatchers.requiresRole()', () => {
|
|
it('should return admin roles for admin routes', () => {
|
|
const roles = routeMatchers.requiresRole('/admin');
|
|
expect(roles).toContain('admin');
|
|
expect(roles).toContain('owner');
|
|
});
|
|
|
|
it('should return sponsor roles for sponsor routes', () => {
|
|
const roles = routeMatchers.requiresRole('/sponsor/dashboard');
|
|
expect(roles).toEqual(['sponsor']);
|
|
});
|
|
|
|
it('should return null for routes without role requirements', () => {
|
|
expect(routeMatchers.requiresRole('/dashboard')).toBeNull();
|
|
expect(routeMatchers.requiresRole('/leagues')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('buildPath()', () => {
|
|
it('should build simple paths', () => {
|
|
const path = buildPath('protected.dashboard');
|
|
expect(path).toBe('/dashboard');
|
|
});
|
|
|
|
it('should build parameterized paths', () => {
|
|
const path = buildPath('league.detail', { id: '123' });
|
|
expect(path).toBe('/leagues/123');
|
|
});
|
|
|
|
it('should build sponsor league paths', () => {
|
|
const path = buildPath('sponsor.leagueDetail', { id: '456' });
|
|
expect(path).toBe('/sponsor/leagues/456');
|
|
});
|
|
|
|
it('should throw on unknown routes', () => {
|
|
expect(() => buildPath('unknown.route')).toThrow('Unknown route: unknown.route');
|
|
});
|
|
|
|
it('should throw when parameterized route missing params', () => {
|
|
expect(() => buildPath('league.detail', {})).toThrow('Route league.detail requires parameters');
|
|
});
|
|
});
|
|
|
|
describe('Route configuration integrity', () => {
|
|
it('all public routes should be accessible without auth', () => {
|
|
const publicRoutes = routeMatchers.getPublicPatterns();
|
|
expect(publicRoutes.length).toBeGreaterThan(0);
|
|
|
|
publicRoutes.forEach(route => {
|
|
expect(routeMatchers.isPublic(route)).toBe(true);
|
|
expect(routeMatchers.requiresAuth(route)).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('all admin routes should require admin role', () => {
|
|
const adminPaths = ['/admin', '/admin/users'];
|
|
|
|
adminPaths.forEach(path => {
|
|
expect(routeMatchers.isInGroup(path, 'admin')).toBe(true);
|
|
const roles = routeMatchers.requiresRole(path);
|
|
expect(roles).toContain('admin');
|
|
});
|
|
});
|
|
|
|
it('all sponsor routes should require sponsor role', () => {
|
|
const sponsorPaths = ['/sponsor/dashboard', '/sponsor/billing'];
|
|
|
|
sponsorPaths.forEach(path => {
|
|
expect(routeMatchers.isInGroup(path, 'sponsor')).toBe(true);
|
|
const roles = routeMatchers.requiresRole(path);
|
|
expect(roles).toEqual(['sponsor']);
|
|
});
|
|
});
|
|
});
|
|
});
|