35 lines
2.0 KiB
TypeScript
35 lines
2.0 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { render } from 'svelte/server';
|
|
|
|
const { page } = await vi.hoisted(async () => {
|
|
const { writable } = await import('svelte/store');
|
|
return { page: writable({ url: new URL('http://localhost/servers/t5_zombie_theater_1'), data: { user: { role: 'admin' } } }) };
|
|
});
|
|
vi.mock('$app/stores', () => ({ page }));
|
|
import Breadcrumbs from '../../src/lib/ui/components/primitives/Breadcrumbs.svelte';
|
|
|
|
const items = [{ label: 'Fleet', href: '/' }, { label: 'Kino Der Toten' }];
|
|
describe('contextual breadcrumbs', () => {
|
|
it('restores the parent list filters in its only parent link', () => {
|
|
page.set({ url: new URL('http://localhost/servers/t5_zombie_theater_1?returnTo=%2F%3Ffilter%3Doccupied%26sort%3Dround'), data: { user: { role: 'admin' } } });
|
|
const html = render(Breadcrumbs, { props: { items } }).body;
|
|
expect(html).toContain('href="/?filter=occupied&sort=round"');
|
|
expect(html.match(/<a\b/g)).toHaveLength(1);
|
|
expect(html).toContain('aria-current="page"');
|
|
});
|
|
it('names a contextual parent and retains its saved section', () => {
|
|
page.set({ url: new URL('http://localhost/servers/t5_zombie_theater_1?returnTo=%2Fmaintenance%3Fview%3Dactivity'), data: { user: { role: 'admin' } } });
|
|
const html = render(Breadcrumbs, { props: { items } }).body;
|
|
expect(html).toContain('href="/maintenance?view=activity"');
|
|
expect(html).toContain('Maintenance');
|
|
});
|
|
it('rejects external and API destinations while preserving the filtered fallback', () => {
|
|
for (const returnTo of ['https://evil.invalid/', '/api/auth/logout']) {
|
|
page.set({ url: new URL(`http://localhost/servers/t5_zombie_theater_1?returnTo=${encodeURIComponent(returnTo)}`), data: { user: { role: 'admin' } } });
|
|
const html = render(Breadcrumbs, { props: { items, fallback: '/?filter=pinned' } }).body;
|
|
expect(html).toContain('href="/?filter=pinned"');
|
|
expect(html).not.toContain(returnTo);
|
|
}
|
|
});
|
|
});
|