101 lines
4.4 KiB
TypeScript
101 lines
4.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
navigationGroups,
|
|
navigationItemActive,
|
|
navigationLocation,
|
|
visibleNavigation
|
|
} from '../../src/lib/navigation.js';
|
|
|
|
describe('application navigation', () => {
|
|
it.each([
|
|
['/servers/t5_zombie_theater_1', 'fleet', '/'],
|
|
['/collections/launches/42', 'fleet', '/collections'],
|
|
['/hosts/42', 'fleet', '/hosts'],
|
|
['/hosts/operations', 'fleet', '/hosts'],
|
|
['/provisioning', 'activity', '/provisioning'],
|
|
['/provisioning/job-1', 'activity', '/provisioning'],
|
|
['/deployments/job-1', 'activity', '/provisioning'],
|
|
['/betas/new', 'releases', '/betas'],
|
|
['/campaigns/42', 'releases', '/campaigns'],
|
|
['/configs/42', 'releases', '/configs'],
|
|
['/leaderboard/players/42', 'players', '/leaderboard'],
|
|
['/bank', 'players', '/bank'],
|
|
['/afk', 'players', '/afk'],
|
|
['/moderation', 'players', '/moderation'],
|
|
['/settings/users', 'admin', '/settings/users'],
|
|
['/server-keys', 'admin', '/server-keys']
|
|
])('gives %s exactly one canonical home', (path, group, href) => {
|
|
expect(navigationLocation(path, 'admin')?.group.id).toBe(group);
|
|
expect(
|
|
navigationGroups
|
|
.flatMap((group) => group.items)
|
|
.filter((item) => navigationItemActive(item, path))
|
|
.map((item) => item.href)
|
|
).toEqual([href]);
|
|
});
|
|
|
|
it('keeps Provisioning and Maintenance in Activity without the retired log or shortcut', () => {
|
|
expect(
|
|
navigationGroups
|
|
.find((group) => group.id === 'activity')
|
|
?.items.map((item) => item.label)
|
|
).toEqual(['Provisioning', 'Maintenance']);
|
|
const items = navigationGroups.flatMap((group) => group.items);
|
|
expect(items.some((item) => ['/activity', '/operations'].includes(item.href))).toBe(false);
|
|
expect(items.some((item) => item.shortcut === 'd')).toBe(false);
|
|
});
|
|
|
|
it('keeps administration and its shortcuts out of operator and viewer navigation', () => {
|
|
for (const role of ['operator', 'viewer'] as const) {
|
|
expect(visibleNavigation(role).map((group) => group.id)).not.toContain('admin');
|
|
expect(navigationLocation('/server-keys', role)).toBeNull();
|
|
expect(
|
|
visibleNavigation(role)
|
|
.flatMap((group) => group.items)
|
|
.filter((item) => ['h', 'k'].includes(item.shortcut ?? ''))
|
|
).toEqual([]);
|
|
}
|
|
});
|
|
|
|
it('gives Super Viewers all administrator destinations and shortcuts', () => {
|
|
expect(visibleNavigation('super_viewer')).toEqual(visibleNavigation('admin'));
|
|
expect(navigationLocation('/settings/users', 'super_viewer')?.group.id).toBe('admin');
|
|
expect(navigationLocation('/server-keys', 'super_viewer')?.item.shortcut).toBe('k');
|
|
});
|
|
|
|
it('keeps AFK beside Bank for every signed-in role', () => {
|
|
for (const role of ['viewer', 'super_viewer', 'operator', 'moderator', 'admin'] as const) {
|
|
const items = visibleNavigation(role).find((group) => group.id === 'players')!.items;
|
|
const bankIndex = items.findIndex((item) => item.href === '/bank');
|
|
expect(items[bankIndex + 1]).toMatchObject({ label: 'AFK', href: '/afk' });
|
|
}
|
|
});
|
|
|
|
it('reserves private moderation navigation for moderators, administrators, and Super Viewers', () => {
|
|
for (const role of ['admin', 'moderator', 'super_viewer'] as const)
|
|
expect(navigationLocation('/moderation', role)?.group.id).toBe('players');
|
|
for (const role of ['operator', 'viewer'] as const)
|
|
expect(navigationLocation('/moderation', role)).toBeNull();
|
|
});
|
|
|
|
it('groups file releases together and retains Campaigns as its own destination', () => {
|
|
expect(navigationGroups.map((group) => group.label)).toEqual([
|
|
'Fleet',
|
|
'Releases',
|
|
'Activity',
|
|
'Players',
|
|
'Admin'
|
|
]);
|
|
expect(
|
|
navigationGroups
|
|
.find((group) => group.id === 'releases')
|
|
?.items.map((item) => item.label)
|
|
).toEqual(['Scripts', 'Configs', 'Plugins', 'Game files', 'Betas', 'Campaigns']);
|
|
expect(
|
|
navigationGroups
|
|
.flatMap((group) => group.items)
|
|
.some((item) => /rollout/i.test(item.label))
|
|
).toBe(false);
|
|
});
|
|
});
|