import { expect, test } from '@playwright/test'; import { login as loginAs, logout } from './helpers'; // Asking a colleague to check something, end to end and without the model: // the author asks, the document is marked as unsettled for everyone, the // colleague answers, and the mark goes away with the answer. test.setTimeout(120_000); test('a question travels with the document until the colleague answers it', async ({ page }) => { await loginAs(page, 'pablo@pablan.dev'); // A published document everyone may read, so Max is a candidate reviewer. const created = await ( await page.request.post('/api/documents', { data: { title: 'Notfallnummern Halle 1', visibility: 'public' } }) ).json(); const documentId = created.id; await page.request.patch(`/api/documents/${documentId}`, { data: { content_md: '## Notfall\n\nDie Nummer der Instandhaltung ist die 4455.' } }); await page.request.post(`/api/documents/${documentId}/publish`); await page.goto(`/documents/${documentId}`); await page.locator('body[data-hydrated]').waitFor(); await page.getByTestId('document-menu').click(); await page.getByTestId('document-ask-review').click(); await page.getByTestId('reviewer-select').selectOption({ label: 'Max' }); await page.getByTestId('review-question').fill('Stimmt die 4455 noch?'); await page.getByTestId('review-ask-send').click(); // The question is on the document, and it says who is waiting on whom. await expect(page.getByTestId('open-reviews')).toContainText('Stimmt die 4455 noch?'); await expect(page.getByTestId('open-reviews')).toContainText('Max'); // The author cannot answer their own question, only drop it. await expect(page.getByTestId('review-confirm')).toHaveCount(0); await expect(page.getByTestId('review-close')).toBeVisible(); await logout(page); // Max was asked: it is in his queue, he may edit it, and he answers. await loginAs(page, 'max@pablan.dev'); await page.goto('/documents?review=1'); await page.locator('body[data-hydrated]').waitFor(); await expect(page.getByTestId('document-list')).toContainText('Notfallnummern Halle 1'); await expect(page.getByTestId('open-review-badge').first()).toBeVisible(); await page.goto(`/documents/${documentId}`); await page.locator('body[data-hydrated]').waitFor(); await expect(page.getByTestId('document-edit')).toBeVisible(); await page.getByTestId('review-confirm').click(); // Answered: no open question left, and the record says who checked it. await expect(page.getByTestId('open-reviews')).toHaveCount(0); await expect(page.getByTestId('answered-reviews')).toContainText('Max'); // The grant went with the answer — Max may read it, not change it. await expect(page.getByTestId('document-edit')).toHaveCount(0); await logout(page); await loginAs(page, 'pablo@pablan.dev'); await page.request.delete(`/api/documents/${documentId}`); await page.request.post('/api/auth/logout'); }); test('answering on a draft hands it back instead of dropping you on a 404', async ({ page }) => { await loginAs(page, 'pablo@pablan.dev'); const created = await ( await page.request.post('/api/documents', { data: { title: 'Entwurf zum Gegenlesen', visibility: 'public' } }) ).json(); const documentId = created.id; await page.request.patch(`/api/documents/${documentId}`, { data: { content_md: '## Stand\n\nNoch nicht fertig.' } }); const max = ( await (await page.request.get(`/api/documents/${documentId}/reviewers`)).json() ).find((candidate: { name: string }) => candidate.name === 'Max'); await page.request.post(`/api/documents/${documentId}/reviews`, { data: { reviewer_id: max.id, question: 'Passt der Stand so?' } }); await logout(page); // Max only sees the draft because he was asked, and the page says so. await loginAs(page, 'max@pablan.dev'); await page.goto(`/documents/${documentId}`); await page.locator('body[data-hydrated]').waitFor(); await expect(page.getByTestId('open-reviews')).toContainText('Passt der Stand so?'); // He can see who may read it, and change neither that nor the publish state. await page.getByTestId('access-chip').click(); await expect(page.getByTestId('access-controls')).toBeVisible(); await expect(page.getByTestId('visibility-select')).toHaveCount(0); await expect(page.getByTestId('share-save')).toHaveCount(0); await page.keyboard.press('Escape'); await expect(page.getByTestId('publish-button')).toHaveCount(0); // Answering ends that access, so the page thanks him instead of 404ing. await page.getByTestId('review-confirm').click(); await expect(page.getByTestId('review-done')).toBeVisible(); await logout(page); await loginAs(page, 'pablo@pablan.dev'); await page.request.delete(`/api/documents/${documentId}`); await page.request.post('/api/auth/logout'); });