import { buildAdminNav, buildAppNav, findActiveNav, isItemActive, } from '@/components/shell/nav-config'; const t = (key: string) => key; const tShell = (key: string) => key; describe('isItemActive', () => { it('exige une correspondance exacte pour la racine de l espace', () => { expect(isItemActive('/dashboard', '/dashboard', 'app')).toBe(true); // Sans cette regle, « Tableau de bord » resterait actif sur toutes les pages. expect(isItemActive('/dashboard', '/dashboard/bookings', 'app')).toBe(false); }); it('active un item sur ses descendants', () => { expect(isItemActive('/dashboard/bookings', '/dashboard/bookings', 'app')).toBe(true); expect(isItemActive('/dashboard/bookings', '/dashboard/bookings/42', 'app')).toBe(true); }); it('ne confond pas deux routes de meme prefixe textuel', () => { // /dashboard/settings/users ne doit pas activer /dashboard/settings/user expect(isItemActive('/dashboard/settings/user', '/dashboard/settings/users', 'app')).toBe( false ); }); it('applique la meme regle a la racine admin', () => { expect(isItemActive('/admin', '/admin', 'admin')).toBe(true); expect(isItemActive('/admin', '/admin/users', 'admin')).toBe(false); }); }); describe('buildAppNav', () => { it('regroupe la navigation en trois sections', () => { const groups = buildAppNav({ t, tShell, role: 'USER' }); expect(groups.map(g => g.key)).toEqual(['pilotage', 'resources', 'organization']); }); it('masque la gestion des utilisateurs hors ADMIN et MANAGER', () => { const asUser = buildAppNav({ t, tShell, role: 'USER' }); const orgUser = asUser.find(g => g.key === 'organization')!; expect(orgUser.items.map(i => i.key)).not.toContain('users'); for (const role of ['ADMIN', 'MANAGER']) { const groups = buildAppNav({ t, tShell, role }); const org = groups.find(g => g.key === 'organization')!; expect(org.items.map(i => i.key)).toContain('users'); } }); it('porte les fonctionnalites requises par le plan', () => { const groups = buildAppNav({ t, tShell, role: 'ADMIN' }); const byKey = Object.fromEntries( groups.flatMap(g => g.items).map(i => [i.key, i.requiredFeature]) ); expect(byKey.wiki).toBe('wiki'); expect(byKey.apiKeys).toBe('api_access'); expect(byKey.users).toBe('user_management'); // Les reservations et documents restent accessibles sur tous les plans. expect(byKey.bookings).toBeUndefined(); expect(byKey.documents).toBeUndefined(); }); }); describe('buildAdminNav', () => { it('expose les huit destinations d administration', () => { const groups = buildAdminNav({ t, tShell }); const keys = groups.flatMap(g => g.items).map(i => i.key); expect(keys).toEqual([ 'users', 'organizations', 'bookings', 'documents', 'csvRates', 'blog', 'assistant', 'logs', ]); }); }); describe('findActiveNav', () => { const groups = buildAppNav({ t, tShell, role: 'ADMIN' }); it('retrouve le groupe et l item de la route courante', () => { const found = findActiveNav(groups, '/dashboard/bookings', 'app'); expect(found?.group.key).toBe('pilotage'); expect(found?.item.key).toBe('bookings'); }); it('retient la correspondance la plus specifique', () => { const found = findActiveNav(groups, '/dashboard/settings/api-keys', 'app'); expect(found?.item.key).toBe('apiKeys'); expect(found?.group.key).toBe('organization'); }); it('resout la racine sur le tableau de bord', () => { expect(findActiveNav(groups, '/dashboard', 'app')?.item.key).toBe('dashboard'); }); it('renvoie null sur une route hors navigation', () => { expect(findActiveNav(groups, '/dashboard/profile', 'app')).toBeNull(); }); });