test: inject real ConfirmService via context (batch 1/2)
Replaces the vi.mock('$lib/shared/services/confirm.svelte') stub with a
real createConfirmService() provided through render's context map, mirroring
the existing admin/tags/[id]/page.svelte.spec.ts pattern. The generic
confirm.test-fixture.svelte renders only ConfirmDialog and cannot wrap an
arbitrary page; none of these specs trigger confirm(), so the children's
getConfirmService() simply reads the provided context instead of a module
mock. No vi.mock of confirm.svelte remains in these 5 specs. Part of #560.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,9 +2,7 @@ import { describe, it, expect, vi, afterEach } from 'vitest';
|
|||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { page } from 'vitest/browser';
|
import { page } from 'vitest/browser';
|
||||||
|
|
||||||
vi.mock('$lib/shared/services/confirm.svelte', () => ({
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
||||||
getConfirmService: () => ({ confirm: async () => false })
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { default: TranscriptionEditView } = await import('./TranscriptionEditView.svelte');
|
const { default: TranscriptionEditView } = await import('./TranscriptionEditView.svelte');
|
||||||
import type { TranscriptionBlockData } from '$lib/shared/types';
|
import type { TranscriptionBlockData } from '$lib/shared/types';
|
||||||
@@ -37,7 +35,10 @@ const baseProps = (overrides: Record<string, unknown> = {}) => ({
|
|||||||
|
|
||||||
describe('TranscriptionEditView', () => {
|
describe('TranscriptionEditView', () => {
|
||||||
it('renders the empty-state coach when there are no blocks', async () => {
|
it('renders the empty-state coach when there are no blocks', async () => {
|
||||||
render(TranscriptionEditView, { props: baseProps() });
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: baseProps()
|
||||||
|
});
|
||||||
|
|
||||||
// TranscribeCoachEmptyState renders some German text
|
// TranscribeCoachEmptyState renders some German text
|
||||||
expect(document.body.textContent).toMatch(/markier|block|transkrip/i);
|
expect(document.body.textContent).toMatch(/markier|block|transkrip/i);
|
||||||
@@ -45,6 +46,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders the review progress counter when there are blocks', async () => {
|
it('renders the review progress counter when there are blocks', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock({ id: 'b1', reviewed: false }), baseBlock({ id: 'b2', reviewed: true })]
|
blocks: [baseBlock({ id: 'b1', reviewed: false }), baseBlock({ id: 'b2', reviewed: true })]
|
||||||
})
|
})
|
||||||
@@ -55,6 +57,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('shows the "alle als fertig markieren" button when onMarkAllReviewed is provided', async () => {
|
it('shows the "alle als fertig markieren" button when onMarkAllReviewed is provided', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
onMarkAllReviewed: async () => {}
|
onMarkAllReviewed: async () => {}
|
||||||
@@ -66,6 +69,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('disables the mark-all-reviewed button when all blocks are reviewed', async () => {
|
it('disables the mark-all-reviewed button when all blocks are reviewed', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock({ reviewed: true })],
|
blocks: [baseBlock({ reviewed: true })],
|
||||||
onMarkAllReviewed: async () => {}
|
onMarkAllReviewed: async () => {}
|
||||||
@@ -80,6 +84,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('enables the mark-all-reviewed button when not all blocks are reviewed', async () => {
|
it('enables the mark-all-reviewed button when not all blocks are reviewed', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock({ reviewed: false })],
|
blocks: [baseBlock({ reviewed: false })],
|
||||||
onMarkAllReviewed: async () => {}
|
onMarkAllReviewed: async () => {}
|
||||||
@@ -93,7 +98,10 @@ describe('TranscriptionEditView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('hides the mark-all-reviewed button when onMarkAllReviewed is not provided', async () => {
|
it('hides the mark-all-reviewed button when onMarkAllReviewed is not provided', async () => {
|
||||||
render(TranscriptionEditView, { props: baseProps({ blocks: [baseBlock()] }) });
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: baseProps({ blocks: [baseBlock()] })
|
||||||
|
});
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.element(page.getByRole('button', { name: /alle als fertig/i }))
|
.element(page.getByRole('button', { name: /alle als fertig/i }))
|
||||||
@@ -102,6 +110,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders the OcrTrigger only when canRunOcr is true and onTriggerOcr is provided', async () => {
|
it('renders the OcrTrigger only when canRunOcr is true and onTriggerOcr is provided', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canRunOcr: true,
|
canRunOcr: true,
|
||||||
@@ -116,6 +125,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('hides the OcrTrigger when canRunOcr is false', async () => {
|
it('hides the OcrTrigger when canRunOcr is false', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canRunOcr: false,
|
canRunOcr: false,
|
||||||
@@ -129,6 +139,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders the training-label chips when canWrite=true and there are blocks', async () => {
|
it('renders the training-label chips when canWrite=true and there are blocks', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canWrite: true,
|
canWrite: true,
|
||||||
@@ -143,6 +154,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('hides the training-label section when canWrite is false', async () => {
|
it('hides the training-label section when canWrite is false', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canWrite: false
|
canWrite: false
|
||||||
@@ -155,6 +167,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
it('toggles the training label chip when clicked', async () => {
|
it('toggles the training label chip when clicked', async () => {
|
||||||
const onToggleTrainingLabel = vi.fn().mockResolvedValue(undefined);
|
const onToggleTrainingLabel = vi.fn().mockResolvedValue(undefined);
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canWrite: true,
|
canWrite: true,
|
||||||
@@ -174,6 +187,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders blocks sorted by sortOrder', async () => {
|
it('renders blocks sorted by sortOrder', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [
|
blocks: [
|
||||||
baseBlock({ id: 'b3', sortOrder: 3, text: 'Third' }),
|
baseBlock({ id: 'b3', sortOrder: 3, text: 'Third' }),
|
||||||
@@ -193,6 +207,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders both blocks with their text after rerender with a new activeAnnotationId', async () => {
|
it('renders both blocks with their text after rerender with a new activeAnnotationId', async () => {
|
||||||
const { rerender } = render(TranscriptionEditView, {
|
const { rerender } = render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [
|
blocks: [
|
||||||
baseBlock({ id: 'b1', annotationId: 'ann-1', sortOrder: 1, text: 'First' }),
|
baseBlock({ id: 'b1', annotationId: 'ann-1', sortOrder: 1, text: 'First' }),
|
||||||
@@ -223,6 +238,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
it('handleMarkAllReviewed calls onMarkAllReviewed when clicked', async () => {
|
it('handleMarkAllReviewed calls onMarkAllReviewed when clicked', async () => {
|
||||||
const onMarkAllReviewed = vi.fn().mockResolvedValue(undefined);
|
const onMarkAllReviewed = vi.fn().mockResolvedValue(undefined);
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock({ reviewed: false })],
|
blocks: [baseBlock({ reviewed: false })],
|
||||||
onMarkAllReviewed
|
onMarkAllReviewed
|
||||||
@@ -238,6 +254,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders all blocks with their text', async () => {
|
it('renders all blocks with their text', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [
|
blocks: [
|
||||||
baseBlock({ id: 'b1', text: 'Erster Block' }),
|
baseBlock({ id: 'b1', text: 'Erster Block' }),
|
||||||
@@ -252,6 +269,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('shows the next-block CTA when there are blocks', async () => {
|
it('shows the next-block CTA when there are blocks', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()]
|
blocks: [baseBlock()]
|
||||||
})
|
})
|
||||||
@@ -263,6 +281,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('shows the active training label highlighted when included in trainingLabels', async () => {
|
it('shows the active training label highlighted when included in trainingLabels', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canWrite: true,
|
canWrite: true,
|
||||||
@@ -281,6 +300,7 @@ describe('TranscriptionEditView', () => {
|
|||||||
|
|
||||||
it('renders the inactive training-label chip class when not in trainingLabels', async () => {
|
it('renders the inactive training-label chip class when not in trainingLabels', async () => {
|
||||||
render(TranscriptionEditView, {
|
render(TranscriptionEditView, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: baseProps({
|
props: baseProps({
|
||||||
blocks: [baseBlock()],
|
blocks: [baseBlock()],
|
||||||
canWrite: true,
|
canWrite: true,
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
import { describe, it, expect, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { page } from 'vitest/browser';
|
import { page } from 'vitest/browser';
|
||||||
|
|
||||||
vi.mock('$lib/shared/services/confirm.svelte', () => ({
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
||||||
getConfirmService: () => ({ confirm: async () => false })
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { default: AdminGroupEditPage } = await import('./+page.svelte');
|
const { default: AdminGroupEditPage } = await import('./+page.svelte');
|
||||||
|
|
||||||
@@ -19,13 +17,17 @@ const baseGroup = (overrides: Record<string, unknown> = {}) => ({
|
|||||||
|
|
||||||
describe('admin/groups/[id] page', () => {
|
describe('admin/groups/[id] page', () => {
|
||||||
it('renders the edit heading with the group name', async () => {
|
it('renders the edit heading with the group name', async () => {
|
||||||
render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } });
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: { group: baseGroup() }, form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByRole('heading', { name: /familie/i })).toBeVisible();
|
await expect.element(page.getByRole('heading', { name: /familie/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hydrates the name input from data.group.name', async () => {
|
it('hydrates the name input from data.group.name', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: { group: baseGroup({ name: 'Admins' }) }, form: undefined }
|
props: { data: { group: baseGroup({ name: 'Admins' }) }, form: undefined }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ describe('admin/groups/[id] page', () => {
|
|||||||
|
|
||||||
it('checks the permission checkboxes that are in data.group.permissions', async () => {
|
it('checks the permission checkboxes that are in data.group.permissions', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: { group: baseGroup({ permissions: ['READ_ALL', 'ADMIN_TAG'] }) },
|
data: { group: baseGroup({ permissions: ['READ_ALL', 'ADMIN_TAG'] }) },
|
||||||
form: undefined
|
form: undefined
|
||||||
@@ -57,6 +60,7 @@ describe('admin/groups/[id] page', () => {
|
|||||||
|
|
||||||
it('shows the success banner when form.success is true', async () => {
|
it('shows the success banner when form.success is true', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: { group: baseGroup() }, form: { success: true } }
|
props: { data: { group: baseGroup() }, form: { success: true } }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,6 +69,7 @@ describe('admin/groups/[id] page', () => {
|
|||||||
|
|
||||||
it('shows the error banner when form.error is set', async () => {
|
it('shows the error banner when form.error is set', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: { group: baseGroup() },
|
data: { group: baseGroup() },
|
||||||
form: { error: 'Name darf nicht leer sein.' }
|
form: { error: 'Name darf nicht leer sein.' }
|
||||||
@@ -75,21 +80,30 @@ describe('admin/groups/[id] page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the cancel link to /admin/groups', async () => {
|
it('renders the cancel link to /admin/groups', async () => {
|
||||||
render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } });
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: { group: baseGroup() }, form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const links = document.querySelectorAll('a[href="/admin/groups"]');
|
const links = document.querySelectorAll('a[href="/admin/groups"]');
|
||||||
expect(links.length).toBeGreaterThan(0);
|
expect(links.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the delete and save buttons', async () => {
|
it('renders the delete and save buttons', async () => {
|
||||||
render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } });
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: { group: baseGroup() }, form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
|
await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
|
||||||
await expect.element(page.getByRole('button', { name: /speichern/i })).toBeVisible();
|
await expect.element(page.getByRole('button', { name: /speichern/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not render success banner when form is undefined', async () => {
|
it('does not render success banner when form is undefined', async () => {
|
||||||
render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } });
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: { group: baseGroup() }, form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const banner = document.querySelector('.bg-green-50');
|
const banner = document.querySelector('.bg-green-50');
|
||||||
expect(banner).toBeNull();
|
expect(banner).toBeNull();
|
||||||
@@ -97,6 +111,7 @@ describe('admin/groups/[id] page', () => {
|
|||||||
|
|
||||||
it('does not render error-banner div when form.success is true (success path only)', async () => {
|
it('does not render error-banner div when form.success is true (success path only)', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: { group: baseGroup() }, form: { success: true } }
|
props: { data: { group: baseGroup() }, form: { success: true } }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,7 +121,10 @@ describe('admin/groups/[id] page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders all 8 permission checkboxes (4 standard + 4 admin)', async () => {
|
it('renders all 8 permission checkboxes (4 standard + 4 admin)', async () => {
|
||||||
render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } });
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: { group: baseGroup() }, form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const checkboxes = document.querySelectorAll('input[name="permissions"]');
|
const checkboxes = document.querySelectorAll('input[name="permissions"]');
|
||||||
expect(checkboxes.length).toBe(8);
|
expect(checkboxes.length).toBe(8);
|
||||||
@@ -114,6 +132,7 @@ describe('admin/groups/[id] page', () => {
|
|||||||
|
|
||||||
it('handles a group with empty permissions array', async () => {
|
it('handles a group with empty permissions array', async () => {
|
||||||
render(AdminGroupEditPage, {
|
render(AdminGroupEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: { group: baseGroup({ permissions: [] }) }, form: undefined }
|
props: { data: { group: baseGroup({ permissions: [] }) }, form: undefined }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
import { describe, it, expect, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { page } from 'vitest/browser';
|
import { page } from 'vitest/browser';
|
||||||
|
|
||||||
vi.mock('$lib/shared/services/confirm.svelte', () => ({
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
||||||
getConfirmService: () => ({ confirm: async () => false })
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { default: AdminUserEditPage } = await import('./+page.svelte');
|
const { default: AdminUserEditPage } = await import('./+page.svelte');
|
||||||
|
|
||||||
@@ -32,13 +30,19 @@ const baseData = (overrides: Record<string, unknown> = {}) => ({
|
|||||||
|
|
||||||
describe('admin/users/[id] page', () => {
|
describe('admin/users/[id] page', () => {
|
||||||
it('renders the edit heading with the user email', async () => {
|
it('renders the edit heading with the user email', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByRole('heading', { name: /anna@example/i })).toBeVisible();
|
await expect.element(page.getByRole('heading', { name: /anna@example/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders all three card sections', async () => {
|
it('renders all three card sections', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByRole('heading', { name: /persönliche daten/i })).toBeVisible();
|
await expect.element(page.getByRole('heading', { name: /persönliche daten/i })).toBeVisible();
|
||||||
await expect.element(page.getByRole('heading', { name: /^gruppen$/i })).toBeVisible();
|
await expect.element(page.getByRole('heading', { name: /^gruppen$/i })).toBeVisible();
|
||||||
@@ -46,13 +50,17 @@ describe('admin/users/[id] page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('shows the update success banner when form.success is true', async () => {
|
it('shows the update success banner when form.success is true', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: { success: true } } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: { success: true } }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByText('Änderungen gespeichert.')).toBeVisible();
|
await expect.element(page.getByText('Änderungen gespeichert.')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows the update error banner when form.error is set', async () => {
|
it('shows the update error banner when form.error is set', async () => {
|
||||||
render(AdminUserEditPage, {
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData(), form: { error: 'E-Mail bereits vergeben' } }
|
props: { data: baseData(), form: { error: 'E-Mail bereits vergeben' } }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,7 +68,10 @@ describe('admin/users/[id] page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('preselects the user groups in UserGroupsSection', async () => {
|
it('preselects the user groups in UserGroupsSection', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const checkboxes = Array.from(
|
const checkboxes = Array.from(
|
||||||
document.querySelectorAll('input[name="groupIds"]')
|
document.querySelectorAll('input[name="groupIds"]')
|
||||||
@@ -70,27 +81,39 @@ describe('admin/users/[id] page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders cancel link to /admin/users', async () => {
|
it('renders cancel link to /admin/users', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const cancel = document.querySelector('a[href="/admin/users"]');
|
const cancel = document.querySelector('a[href="/admin/users"]');
|
||||||
expect(cancel).not.toBeNull();
|
expect(cancel).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the delete button', async () => {
|
it('renders the delete button', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
|
await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show success banner when form is undefined', async () => {
|
it('does not show success banner when form is undefined', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: undefined } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const banner = document.querySelector('.bg-green-50');
|
const banner = document.querySelector('.bg-green-50');
|
||||||
expect(banner).toBeNull();
|
expect(banner).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show error banner when form.error is undefined', async () => {
|
it('does not show error banner when form.error is undefined', async () => {
|
||||||
render(AdminUserEditPage, { props: { data: baseData(), form: { success: false } } });
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: { success: false } }
|
||||||
|
});
|
||||||
|
|
||||||
// The error banner has both border-red-200 AND text-red-700 — the delete button has red-50
|
// The error banner has both border-red-200 AND text-red-700 — the delete button has red-50
|
||||||
// background but is a button, not a div. Look for the specific error <div>.
|
// background but is a button, not a div. Look for the specific error <div>.
|
||||||
@@ -100,6 +123,7 @@ describe('admin/users/[id] page', () => {
|
|||||||
|
|
||||||
it('handles a user with empty groups list (selectedGroupIds defaults to [])', async () => {
|
it('handles a user with empty groups list (selectedGroupIds defaults to [])', async () => {
|
||||||
render(AdminUserEditPage, {
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({ editUser: { ...baseEditUser, groups: [] } }),
|
data: baseData({ editUser: { ...baseEditUser, groups: [] } }),
|
||||||
form: undefined
|
form: undefined
|
||||||
@@ -117,6 +141,7 @@ describe('admin/users/[id] page', () => {
|
|||||||
const editUser = { ...baseEditUser } as typeof baseEditUser & { groups?: undefined };
|
const editUser = { ...baseEditUser } as typeof baseEditUser & { groups?: undefined };
|
||||||
delete (editUser as { groups?: unknown }).groups;
|
delete (editUser as { groups?: unknown }).groups;
|
||||||
render(AdminUserEditPage, {
|
render(AdminUserEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ editUser }), form: undefined }
|
props: { data: baseData({ editUser }), form: undefined }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
|
|
||||||
vi.mock('$lib/shared/services/confirm.svelte', () => ({
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
||||||
getConfirmService: () => ({ confirm: async () => false })
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { default: DocumentEditPage } = await import('./+page.svelte');
|
const { default: DocumentEditPage } = await import('./+page.svelte');
|
||||||
|
|
||||||
@@ -31,7 +29,10 @@ const baseData = (overrides: Record<string, unknown> = {}) => ({
|
|||||||
|
|
||||||
describe('documents/[id]/edit page', () => {
|
describe('documents/[id]/edit page', () => {
|
||||||
it('renders the page with the DocumentEditLayout', async () => {
|
it('renders the page with the DocumentEditLayout', async () => {
|
||||||
render(DocumentEditPage, { props: { data: baseData(), form: undefined } });
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
// At minimum, the body has content
|
// At minimum, the body has content
|
||||||
const main = document.body.firstElementChild;
|
const main = document.body.firstElementChild;
|
||||||
@@ -39,7 +40,10 @@ describe('documents/[id]/edit page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders both hidden submit-target forms', async () => {
|
it('renders both hidden submit-target forms', async () => {
|
||||||
render(DocumentEditPage, { props: { data: baseData(), form: undefined } });
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const reviewForm = document.querySelector('form#mark-for-review-form');
|
const reviewForm = document.querySelector('form#mark-for-review-form');
|
||||||
const deleteForm = document.querySelector('form#delete-form');
|
const deleteForm = document.querySelector('form#delete-form');
|
||||||
@@ -48,7 +52,10 @@ describe('documents/[id]/edit page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the action bar with delete, cancel, mark-for-review, and save buttons/links', async () => {
|
it('renders the action bar with delete, cancel, mark-for-review, and save buttons/links', async () => {
|
||||||
render(DocumentEditPage, { props: { data: baseData(), form: undefined } });
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
// Find delete button
|
// Find delete button
|
||||||
const deleteBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
const deleteBtn = Array.from(document.querySelectorAll('button')).find((b) =>
|
||||||
@@ -58,13 +65,17 @@ describe('documents/[id]/edit page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('uses doc.title in the document title when set', async () => {
|
it('uses doc.title in the document title when set', async () => {
|
||||||
render(DocumentEditPage, { props: { data: baseData(), form: undefined } });
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('falls back to originalFilename when title is empty', async () => {
|
it('falls back to originalFilename when title is empty', async () => {
|
||||||
render(DocumentEditPage, {
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({ document: { ...baseDoc, title: '', originalFilename: 'fallback.pdf' } }),
|
data: baseData({ document: { ...baseDoc, title: '', originalFilename: 'fallback.pdf' } }),
|
||||||
form: undefined
|
form: undefined
|
||||||
@@ -75,7 +86,10 @@ describe('documents/[id]/edit page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders the cancel link to the document detail page', async () => {
|
it('renders the cancel link to the document detail page', async () => {
|
||||||
render(DocumentEditPage, { props: { data: baseData(), form: undefined } });
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData(), form: undefined }
|
||||||
|
});
|
||||||
|
|
||||||
const link = document.querySelector('a[href="/documents/d1"]');
|
const link = document.querySelector('a[href="/documents/d1"]');
|
||||||
expect(link).not.toBeNull();
|
expect(link).not.toBeNull();
|
||||||
@@ -83,6 +97,7 @@ describe('documents/[id]/edit page', () => {
|
|||||||
|
|
||||||
it('passes form.error to DocumentEditLayout when form is set', async () => {
|
it('passes form.error to DocumentEditLayout when form is set', async () => {
|
||||||
render(DocumentEditPage, {
|
render(DocumentEditPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData(), form: { error: 'Save failed' } }
|
props: { data: baseData(), form: { error: 'Save failed' } }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ vi.mock('$app/navigation', () => ({
|
|||||||
onNavigate: () => () => {}
|
onNavigate: () => () => {}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('$lib/shared/services/confirm.svelte', () => ({
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
||||||
getConfirmService: () => ({ confirm: async () => false })
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { default: DocumentDetailPage } = await import('./+page.svelte');
|
const { default: DocumentDetailPage } = await import('./+page.svelte');
|
||||||
|
|
||||||
@@ -63,7 +61,10 @@ const baseData = (overrides: Record<string, unknown> = {}) => ({
|
|||||||
describe('documents/[id] page', () => {
|
describe('documents/[id] page', () => {
|
||||||
it('renders the DocumentTopBar and resolves the document title in svelte:head', async () => {
|
it('renders the DocumentTopBar and resolves the document title in svelte:head', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d1');
|
mockPage.url = new URL('http://localhost/documents/d1');
|
||||||
render(DocumentDetailPage, { props: { data: baseData() } });
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData() }
|
||||||
|
});
|
||||||
|
|
||||||
expect(document.querySelector('[data-topbar]')).not.toBeNull();
|
expect(document.querySelector('[data-topbar]')).not.toBeNull();
|
||||||
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
||||||
@@ -71,7 +72,10 @@ describe('documents/[id] page', () => {
|
|||||||
|
|
||||||
it('mounts the page region with the [data-hydrated] container', async () => {
|
it('mounts the page region with the [data-hydrated] container', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d1');
|
mockPage.url = new URL('http://localhost/documents/d1');
|
||||||
render(DocumentDetailPage, { props: { data: baseData() } });
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData() }
|
||||||
|
});
|
||||||
|
|
||||||
expect(document.querySelector('[data-hydrated]')).not.toBeNull();
|
expect(document.querySelector('[data-hydrated]')).not.toBeNull();
|
||||||
});
|
});
|
||||||
@@ -79,7 +83,10 @@ describe('documents/[id] page', () => {
|
|||||||
it('persists last-visited document ID to localStorage on mount', async () => {
|
it('persists last-visited document ID to localStorage on mount', async () => {
|
||||||
localStorage.removeItem('familienarchiv.lastVisited');
|
localStorage.removeItem('familienarchiv.lastVisited');
|
||||||
mockPage.url = new URL('http://localhost/documents/d1');
|
mockPage.url = new URL('http://localhost/documents/d1');
|
||||||
render(DocumentDetailPage, { props: { data: baseData() } });
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData() }
|
||||||
|
});
|
||||||
|
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
const stored = localStorage.getItem('familienarchiv.lastVisited');
|
const stored = localStorage.getItem('familienarchiv.lastVisited');
|
||||||
@@ -89,7 +96,10 @@ describe('documents/[id] page', () => {
|
|||||||
|
|
||||||
it('uses doc.title as the document title when set', async () => {
|
it('uses doc.title as the document title when set', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d1');
|
mockPage.url = new URL('http://localhost/documents/d1');
|
||||||
render(DocumentDetailPage, { props: { data: baseData() } });
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData() }
|
||||||
|
});
|
||||||
|
|
||||||
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
await vi.waitFor(() => expect(document.title).toContain('Brief an Helene'));
|
||||||
});
|
});
|
||||||
@@ -97,6 +107,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('falls back to originalFilename when title is empty', async () => {
|
it('falls back to originalFilename when title is empty', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d2');
|
mockPage.url = new URL('http://localhost/documents/d2');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: { ...baseDoc, id: 'd2', title: '', originalFilename: 'fallback.pdf' }
|
document: { ...baseDoc, id: 'd2', title: '', originalFilename: 'fallback.pdf' }
|
||||||
@@ -110,6 +121,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('falls back to "Dokument" when title and originalFilename are empty', async () => {
|
it('falls back to "Dokument" when title and originalFilename are empty', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d3');
|
mockPage.url = new URL('http://localhost/documents/d3');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: { ...baseDoc, id: 'd3', title: '', originalFilename: '' }
|
document: { ...baseDoc, id: 'd3', title: '', originalFilename: '' }
|
||||||
@@ -122,7 +134,10 @@ describe('documents/[id] page', () => {
|
|||||||
|
|
||||||
it('renders the topbar Edit-link affordance when canWrite is true', async () => {
|
it('renders the topbar Edit-link affordance when canWrite is true', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d4');
|
mockPage.url = new URL('http://localhost/documents/d4');
|
||||||
render(DocumentDetailPage, { props: { data: baseData({ canWrite: true }) } });
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
|
props: { data: baseData({ canWrite: true }) }
|
||||||
|
});
|
||||||
|
|
||||||
await expect.element(browserPage.getByRole('link', { name: 'Bearbeiten' })).toBeVisible();
|
await expect.element(browserPage.getByRole('link', { name: 'Bearbeiten' })).toBeVisible();
|
||||||
});
|
});
|
||||||
@@ -130,6 +145,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar when geschichten and inferredRelationship are passed through', async () => {
|
it('renders the topbar when geschichten and inferredRelationship are passed through', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d5');
|
mockPage.url = new URL('http://localhost/documents/d5');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
geschichten: [{ id: 'g1', title: 'Story', publishedAt: null }],
|
geschichten: [{ id: 'g1', title: 'Story', publishedAt: null }],
|
||||||
@@ -146,6 +162,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar even when doc.id is empty (defensive)', async () => {
|
it('renders the topbar even when doc.id is empty (defensive)', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-empty');
|
mockPage.url = new URL('http://localhost/documents/d-empty');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: '', title: 'No ID' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: '', title: 'No ID' } }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,6 +173,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders sender data in the metadata drawer when sender is populated', async () => {
|
it('renders sender data in the metadata drawer when sender is populated', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d7');
|
mockPage.url = new URL('http://localhost/documents/d7');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: {
|
document: {
|
||||||
@@ -176,6 +194,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar when filePath is set on the document', async () => {
|
it('renders the topbar when filePath is set on the document', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d8');
|
mockPage.url = new URL('http://localhost/documents/d8');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: {
|
document: {
|
||||||
@@ -195,6 +214,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar with a complete user object passed through', async () => {
|
it('renders the topbar with a complete user object passed through', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d9');
|
mockPage.url = new URL('http://localhost/documents/d9');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: { ...baseDoc, id: 'd9' },
|
document: { ...baseDoc, id: 'd9' },
|
||||||
@@ -209,6 +229,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('Escape keydown leaves the transcribe panel hidden when not already in transcribe mode', async () => {
|
it('Escape keydown leaves the transcribe panel hidden when not already in transcribe mode', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d10');
|
mockPage.url = new URL('http://localhost/documents/d10');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd10' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd10' } }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -220,6 +241,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('non-Escape keydown does not affect the transcribe panel state', async () => {
|
it('non-Escape keydown does not affect the transcribe panel state', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d11');
|
mockPage.url = new URL('http://localhost/documents/d11');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd11' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd11' } }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -232,6 +254,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar with a deep-link comment query param', async () => {
|
it('renders the topbar with a deep-link comment query param', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d12?comment=c-abc');
|
mockPage.url = new URL('http://localhost/documents/d12?comment=c-abc');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd12' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd12' } }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -241,6 +264,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders sender name and Edit affordance with all metadata populated', async () => {
|
it('renders sender name and Edit affordance with all metadata populated', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-meta');
|
mockPage.url = new URL('http://localhost/documents/d-meta');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: {
|
document: {
|
||||||
@@ -278,6 +302,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('enters transcribe mode and shows the panel close button when ?task=transcribe is set', async () => {
|
it('enters transcribe mode and shows the panel close button when ?task=transcribe is set', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-task?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-task?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: { ...baseDoc, id: 'd-task' },
|
document: { ...baseDoc, id: 'd-task' },
|
||||||
@@ -296,6 +321,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-fail?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-fail?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({ document: { ...baseDoc, id: 'd-fail' } })
|
data: baseData({ document: { ...baseDoc, id: 'd-fail' } })
|
||||||
}
|
}
|
||||||
@@ -328,6 +354,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-blocks?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-blocks?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd-blocks' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd-blocks' } }) }
|
||||||
});
|
});
|
||||||
await expect.element(browserPage.getByText('Erster')).toBeVisible();
|
await expect.element(browserPage.getByText('Erster')).toBeVisible();
|
||||||
@@ -343,6 +370,7 @@ describe('documents/[id] page', () => {
|
|||||||
);
|
);
|
||||||
mockPage.url = new URL('http://localhost/documents/d-new');
|
mockPage.url = new URL('http://localhost/documents/d-new');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({ document: { ...baseDoc, id: 'd-new', title: 'New Doc' } })
|
data: baseData({ document: { ...baseDoc, id: 'd-new', title: 'New Doc' } })
|
||||||
}
|
}
|
||||||
@@ -360,6 +388,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-fail?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-fail?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ canWrite: true, document: { ...baseDoc, id: 'd-ocr-fail' } }) }
|
props: { data: baseData({ canWrite: true, document: { ...baseDoc, id: 'd-ocr-fail' } }) }
|
||||||
});
|
});
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
@@ -391,6 +420,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-run?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-run?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ canWrite: true, document: { ...baseDoc, id: 'd-ocr-run' } }) }
|
props: { data: baseData({ canWrite: true, document: { ...baseDoc, id: 'd-ocr-run' } }) }
|
||||||
});
|
});
|
||||||
await expect.element(browserPage.getByText('OCR läuft')).toBeVisible();
|
await expect.element(browserPage.getByText('OCR läuft')).toBeVisible();
|
||||||
@@ -402,6 +432,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('renders the topbar when the document has all OCR-relevant fields populated', async () => {
|
it('renders the topbar when the document has all OCR-relevant fields populated', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-meta?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-meta?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: {
|
document: {
|
||||||
@@ -424,6 +455,7 @@ describe('documents/[id] page', () => {
|
|||||||
it('treats undefined geschichten as the empty array (geschichten ?? [] branch)', async () => {
|
it('treats undefined geschichten as the empty array (geschichten ?? [] branch)', async () => {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-no-stories');
|
mockPage.url = new URL('http://localhost/documents/d-no-stories');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: {
|
props: {
|
||||||
data: baseData({
|
data: baseData({
|
||||||
document: { ...baseDoc, id: 'd-no-stories' },
|
document: { ...baseDoc, id: 'd-no-stories' },
|
||||||
@@ -449,6 +481,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-done?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-done?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-done' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-done' } }) }
|
||||||
});
|
});
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
@@ -474,6 +507,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-no-job?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-no-job?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-no-job' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-no-job' } }) }
|
||||||
});
|
});
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
@@ -496,6 +530,7 @@ describe('documents/[id] page', () => {
|
|||||||
try {
|
try {
|
||||||
mockPage.url = new URL('http://localhost/documents/d-ocr-throw?task=transcribe');
|
mockPage.url = new URL('http://localhost/documents/d-ocr-throw?task=transcribe');
|
||||||
render(DocumentDetailPage, {
|
render(DocumentDetailPage, {
|
||||||
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
||||||
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-throw' } }) }
|
props: { data: baseData({ document: { ...baseDoc, id: 'd-ocr-throw' } }) }
|
||||||
});
|
});
|
||||||
await vi.waitFor(() => {
|
await vi.waitFor(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user