Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
108 lines
3.7 KiB
TypeScript
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();
|
|
});
|
|
});
|