From bbac351f034438f436d59f11a08ed91baadfefad Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 22 Mar 2026 20:01:04 +0100 Subject: [PATCH] test(e2e): add read-only user permissions journey Logs in as the seeded "reader" user (READ_ALL only) and asserts that all write controls are absent from every page. Refs #48 Co-Authored-By: Claude Sonnet 4.6 --- frontend/e2e/permissions.spec.ts | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/frontend/e2e/permissions.spec.ts b/frontend/e2e/permissions.spec.ts index a7416856..63e9bc1a 100644 --- a/frontend/e2e/permissions.spec.ts +++ b/frontend/e2e/permissions.spec.ts @@ -1,4 +1,14 @@ import { test, expect } from '@playwright/test'; +import { login } from './helpers/auth'; + +/** + * Permission E2E tests. + * + * Two describe blocks form the full story: + * 1. Admin user — can see all write controls. + * 2. Read-only user ("reader", seeded in DataInitializer with READ_ALL only) — + * can browse content but sees no write controls anywhere. + */ test.describe('Write permissions — admin user', () => { test('admin user sees Neues Dokument link on home page', async ({ page }) => { @@ -29,3 +39,49 @@ test.describe('Write permissions — admin user', () => { await expect(page.getByRole('button', { name: /Bearbeiten/i })).toBeVisible(); }); }); + +// ── Read-only user journey ───────────────────────────────────────────────────── +// +// The "reader" user is seeded by DataInitializer (e2e profile) with READ_ALL only. +// They can browse documents and persons but must not see any mutation controls. + +test.describe('Read-only user — no write controls visible', () => { + // Fresh session — no shared admin cookies + test.use({ storageState: { cookies: [], origins: [] } }); + + test.beforeEach(async ({ page }) => { + await login(page, 'reader', 'reader123'); + }); + + test('read-only user is redirected to home after login', async ({ page }) => { + await expect(page).toHaveURL('/'); + await page.screenshot({ path: 'test-results/e2e/permissions-reader-home.png' }); + }); + + test('home page does not show the "Neues Dokument" link', async ({ page }) => { + await expect(page.getByRole('link', { name: /Neues Dokument/i })).not.toBeVisible(); + await page.screenshot({ path: 'test-results/e2e/permissions-reader-no-new-doc.png' }); + }); + + test('persons page does not show the "Neue Person" link', async ({ page }) => { + await page.goto('/persons'); + await expect(page.getByRole('link', { name: /Neue Person/i })).not.toBeVisible(); + await page.screenshot({ path: 'test-results/e2e/permissions-reader-no-new-person.png' }); + }); + + test('person detail page does not show the edit button', async ({ page }) => { + await page.goto('/persons'); + const firstPerson = page.locator('a[href^="/persons/"]:not([href="/persons/new"])').first(); + await firstPerson.click(); + await page.waitForSelector('[data-hydrated]'); + await expect(page.getByRole('button', { name: /Bearbeiten/i })).not.toBeVisible(); + await page.screenshot({ path: 'test-results/e2e/permissions-reader-no-edit.png' }); + }); + + test('navigating directly to /documents/new redirects away', async ({ page }) => { + await page.goto('/documents/new'); + // Read-only user should not be able to access the new document form + await expect(page).not.toHaveURL('/documents/new'); + await page.screenshot({ path: 'test-results/e2e/permissions-reader-no-new-doc-direct.png' }); + }); +});