diff --git a/frontend/src/routes/documents/bulk-edit/+page.server.ts b/frontend/src/routes/documents/bulk-edit/+page.server.ts new file mode 100644 index 00000000..33c845a0 --- /dev/null +++ b/frontend/src/routes/documents/bulk-edit/+page.server.ts @@ -0,0 +1,10 @@ +import { redirect } from '@sveltejs/kit'; + +export async function load({ locals }: { locals: App.Locals }) { + const canWrite = + locals.user?.groups?.some((g: { permissions: string[] }) => + g.permissions.includes('WRITE_ALL') + ) ?? false; + if (!canWrite) throw redirect(303, '/documents'); + return { canWrite }; +} diff --git a/frontend/src/routes/documents/bulk-edit/+page.svelte b/frontend/src/routes/documents/bulk-edit/+page.svelte new file mode 100644 index 00000000..b4018b8e --- /dev/null +++ b/frontend/src/routes/documents/bulk-edit/+page.svelte @@ -0,0 +1,53 @@ + + + + {m.bulk_edit_title()} – Familienarchiv + + +{#if loading} +
+{:else if error} +
+ {error} +
+{:else if entries.length > 0} + +{/if} diff --git a/frontend/src/routes/documents/bulk-edit/page.server.spec.ts b/frontend/src/routes/documents/bulk-edit/page.server.spec.ts new file mode 100644 index 00000000..9f52a1a0 --- /dev/null +++ b/frontend/src/routes/documents/bulk-edit/page.server.spec.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest'; +import { load } from './+page.server'; + +describe('/documents/bulk-edit +page.server.ts', () => { + it('redirects to /documents when user lacks WRITE_ALL', async () => { + const locals = { user: { groups: [{ permissions: ['READ_ALL'] }] } }; + try { + // @ts-expect-error — partial event shape sufficient for this guard + await load({ locals }); + throw new Error('expected redirect to be thrown'); + } catch (e) { + const err = e as { status?: number; location?: string }; + expect(err.status).toBe(303); + expect(err.location).toBe('/documents'); + } + }); + + it('redirects when user has no groups', async () => { + const locals = { user: { groups: [] } }; + try { + // @ts-expect-error — partial event shape sufficient for this guard + await load({ locals }); + throw new Error('expected redirect'); + } catch (e) { + expect((e as { status?: number }).status).toBe(303); + } + }); + + it('redirects when no user is logged in', async () => { + const locals = {}; + try { + // @ts-expect-error — partial event shape sufficient for this guard + await load({ locals }); + throw new Error('expected redirect'); + } catch (e) { + expect((e as { status?: number }).status).toBe(303); + } + }); + + it('returns canWrite=true for a WRITE_ALL user', async () => { + const locals = { user: { groups: [{ permissions: ['WRITE_ALL', 'READ_ALL'] }] } }; + // @ts-expect-error — partial event shape sufficient for this guard + const result = await load({ locals }); + expect(result).toEqual({ canWrite: true }); + }); +});