From 9fd0d7f5124bcab98b3838bb78ccf89c79a1384e Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 10 May 2026 00:54:48 +0200 Subject: [PATCH] test(admin/ocr): cover index and per-person page branches admin/ocr index: heading, sender-models heading, global-history link, defensive defaults for missing trainingInfo fields. admin/ocr/[personId]: person name from personNames lookup, Unknown fallback when not found, back-link href, missing-personNames defensive handling. 8 tests across two pages. Refs #496. Co-Authored-By: Claude Sonnet 4.6 --- .../admin/ocr/[personId]/page.svelte.test.ts | 68 +++++++++++++++++++ .../src/routes/admin/ocr/page.svelte.test.ts | 52 ++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 frontend/src/routes/admin/ocr/[personId]/page.svelte.test.ts create mode 100644 frontend/src/routes/admin/ocr/page.svelte.test.ts diff --git a/frontend/src/routes/admin/ocr/[personId]/page.svelte.test.ts b/frontend/src/routes/admin/ocr/[personId]/page.svelte.test.ts new file mode 100644 index 00000000..3b59ef2f --- /dev/null +++ b/frontend/src/routes/admin/ocr/[personId]/page.svelte.test.ts @@ -0,0 +1,68 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import AdminOcrPersonPage from './+page.svelte'; + +afterEach(cleanup); + +describe('admin/ocr/[personId] page', () => { + it('renders the person name from personNames lookup', async () => { + render(AdminOcrPersonPage, { + props: { + data: { + personId: 'p-1', + history: { + runs: [], + personNames: { 'p-1': 'Anna Schmidt' } + } + } + } + }); + + await expect.element(page.getByRole('heading', { name: /anna schmidt/i })).toBeVisible(); + }); + + it('falls back to "Unknown" when the personNames lookup misses', async () => { + render(AdminOcrPersonPage, { + props: { + data: { + personId: 'p-1', + history: { + runs: [], + personNames: {} + } + } + } + }); + + await expect.element(page.getByRole('heading', { name: /unknown/i })).toBeVisible(); + }); + + it('renders the back link to /admin/ocr', async () => { + render(AdminOcrPersonPage, { + props: { + data: { + personId: 'p-1', + history: { runs: [], personNames: { 'p-1': 'Anna Schmidt' } } + } + } + }); + + await expect + .element(page.getByRole('link', { name: /^ocr$/i })) + .toHaveAttribute('href', '/admin/ocr'); + }); + + it('handles missing personNames object gracefully', async () => { + render(AdminOcrPersonPage, { + props: { + data: { + personId: 'p-1', + history: { runs: undefined, personNames: undefined } + } + } + }); + + await expect.element(page.getByRole('heading', { name: /unknown/i })).toBeVisible(); + }); +}); diff --git a/frontend/src/routes/admin/ocr/page.svelte.test.ts b/frontend/src/routes/admin/ocr/page.svelte.test.ts new file mode 100644 index 00000000..d22ab4dd --- /dev/null +++ b/frontend/src/routes/admin/ocr/page.svelte.test.ts @@ -0,0 +1,52 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import AdminOcrPage from './+page.svelte'; + +afterEach(cleanup); + +const baseTrainingInfo = (overrides: Record = {}) => ({ + ocrServiceAvailable: true, + availableBlocks: 100, + totalOcrBlocks: 200, + availableDocuments: 50, + availableSegBlocks: 30, + senderModels: [], + personNames: {}, + runs: [], + ...overrides +}); + +describe('admin/ocr index page', () => { + it('renders the OCR heading', async () => { + render(AdminOcrPage, { props: { data: { trainingInfo: baseTrainingInfo() } } }); + + await expect.element(page.getByRole('heading', { level: 1, name: /^ocr$/i })).toBeVisible(); + }); + + it('renders the sender-models heading', async () => { + render(AdminOcrPage, { props: { data: { trainingInfo: baseTrainingInfo() } } }); + + await expect.element(page.getByRole('heading', { name: /sender-modelle/i })).toBeVisible(); + }); + + it('renders the global-history link to /admin/ocr/global', async () => { + render(AdminOcrPage, { props: { data: { trainingInfo: baseTrainingInfo() } } }); + + await expect + .element(page.getByRole('link', { name: /globaler verlauf/i })) + .toHaveAttribute('href', '/admin/ocr/global'); + }); + + it('handles missing trainingInfo fields with defaults', async () => { + render(AdminOcrPage, { + props: { + data: { + trainingInfo: { ocrServiceAvailable: false } + } + } + }); + + await expect.element(page.getByRole('heading', { level: 1, name: /^ocr$/i })).toBeVisible(); + }); +});