xpeditis2.0/apps/frontend/src/__tests__/components/nav-config.test.ts
David 8957eeb511 feat(ui): console d assistant pour l administration
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
2026-09-07 21:40:54 +02:00

108 lines
3.7 KiB
TypeScript

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();
});
});