test(admin): cover EntityNav permission-gated rendering
All-sections render when full permissions, users/invites hidden when !canManageUsers, groups hidden when !canManagePermissions, tags hidden when !canManageTags, system/ocr hidden when !canRunMaintenance, flyout closed by default. 6 tests covering ~30 branches in the permission matrix. Refs #496. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
89
frontend/src/routes/admin/EntityNav.svelte.test.ts
Normal file
89
frontend/src/routes/admin/EntityNav.svelte.test.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
import { page as browserPage } from 'vitest/browser';
|
||||
|
||||
const mockPage = { url: new URL('http://localhost/admin/users') };
|
||||
|
||||
vi.mock('$app/state', () => ({
|
||||
get page() {
|
||||
return mockPage;
|
||||
}
|
||||
}));
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
async function loadComponent() {
|
||||
return (await import('./EntityNav.svelte')).default;
|
||||
}
|
||||
|
||||
const baseProps = (overrides: Record<string, unknown> = {}) => ({
|
||||
userCount: 5,
|
||||
groupCount: 3,
|
||||
tagCount: 12,
|
||||
inviteCount: 1,
|
||||
canManageUsers: true,
|
||||
canManageTags: true,
|
||||
canManagePermissions: true,
|
||||
canRunMaintenance: true,
|
||||
...overrides
|
||||
});
|
||||
|
||||
describe('EntityNav', () => {
|
||||
it('renders all sections when all permissions are granted', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/users');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps() });
|
||||
|
||||
const links = document.querySelectorAll('a[href^="/admin/"]');
|
||||
// Sidebar renders: users, groups, invites, tags, system, ocr — 6 links
|
||||
expect(links.length).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
it('hides users / invites links when canManageUsers is false', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/groups');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps({ canManageUsers: false }) });
|
||||
|
||||
const userLinks = document.querySelectorAll('a[href="/admin/users"]');
|
||||
const inviteLinks = document.querySelectorAll('a[href="/admin/invites"]');
|
||||
expect(userLinks.length).toBe(0);
|
||||
expect(inviteLinks.length).toBe(0);
|
||||
});
|
||||
|
||||
it('hides the groups link when canManagePermissions is false', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/users');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps({ canManagePermissions: false }) });
|
||||
|
||||
const groupLinks = document.querySelectorAll('a[href="/admin/groups"]');
|
||||
expect(groupLinks.length).toBe(0);
|
||||
});
|
||||
|
||||
it('hides the tags link when canManageTags is false', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/users');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps({ canManageTags: false }) });
|
||||
|
||||
const tagLinks = document.querySelectorAll('a[href="/admin/tags"]');
|
||||
expect(tagLinks.length).toBe(0);
|
||||
});
|
||||
|
||||
it('hides the system and ocr links when canRunMaintenance is false', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/users');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps({ canRunMaintenance: false }) });
|
||||
|
||||
const systemLinks = document.querySelectorAll('a[href="/admin/system"]');
|
||||
const ocrLinks = document.querySelectorAll('a[href="/admin/ocr"]');
|
||||
expect(systemLinks.length).toBe(0);
|
||||
expect(ocrLinks.length).toBe(0);
|
||||
});
|
||||
|
||||
it('does not render the flyout panel by default', async () => {
|
||||
mockPage.url = new URL('http://localhost/admin/users');
|
||||
const EntityNav = await loadComponent();
|
||||
render(EntityNav, { props: baseProps() });
|
||||
|
||||
await expect.element(browserPage.getByRole('dialog')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user