From 1d2c529436616065b2a14c4ec997b33360d5d1a9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 1 Jun 2026 20:43:47 +0200 Subject: [PATCH] test(document): exercise the real render-failure path in PdfViewer test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "render failure" test rejected getDocument().promise — the load path, not the render path — and only asserted a template constant. Now the fake loads the document successfully and rejects the page render (the actual #708 wasm-decode failure class), plus a negative companion asserting the message is absent on a successful render. Also reset renderTask to null on the render-error path. Addresses re-review: Felix, Sara (mislabeled test / asserted a constant). Refs #708 Co-Authored-By: Claude Opus 4.8 --- .../document/viewer/PdfViewer.svelte.test.ts | 30 ++++++++++++++++--- .../document/viewer/usePdfRenderer.svelte.ts | 1 + 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/document/viewer/PdfViewer.svelte.test.ts b/frontend/src/lib/document/viewer/PdfViewer.svelte.test.ts index f4d2eab9..2d05d25b 100644 --- a/frontend/src/lib/document/viewer/PdfViewer.svelte.test.ts +++ b/frontend/src/lib/document/viewer/PdfViewer.svelte.test.ts @@ -7,11 +7,22 @@ import { m } from '$lib/paraglide/messages.js'; afterEach(cleanup); -function makeFailingLibLoader() { +// Document loads fine, but rendering the page rejects with a non-cancellation +// error — exactly the wasm-decode failure class from #708. Exercises the real +// renderCurrentPage path, not the load path. +function makeRenderFailingLibLoader() { + const page = { + getViewport: vi.fn().mockReturnValue({ width: 100, height: 100 }), + render: vi.fn().mockReturnValue({ + promise: Promise.reject(new Error('JBig2 failed to initialize')), + cancel: vi.fn() + }), + streamTextContent: vi.fn().mockReturnValue(new ReadableStream()) + }; const lib = { GlobalWorkerOptions: { workerSrc: '' }, getDocument: vi.fn().mockReturnValue({ - promise: Promise.reject(new Error('JBig2 failed to initialize')) + promise: Promise.resolve({ numPages: 1, getPage: vi.fn().mockResolvedValue(page) }) }), TextLayer: class { render() { @@ -24,16 +35,27 @@ function makeFailingLibLoader() { } describe('PdfViewer — render failure', () => { - it('shows the localized failure message and a download link, not a blank canvas', async () => { + it('shows the localized failure message and a download link when the page render rejects', async () => { render(PdfViewer, { url: '/api/documents/test/file', documentId: 'test', - libLoader: makeFailingLibLoader() + libLoader: makeRenderFailingLibLoader() }); await expect.element(page.getByText(m.doc_render_failed())).toBeVisible(); await expect.element(page.getByRole('link', { name: m.doc_download_link() })).toBeVisible(); }); + + it('does not show the failure message when the page renders successfully', async () => { + render(PdfViewer, { + url: '/api/documents/test/file', + documentId: 'test', + libLoader: makeFakeLibLoader() + }); + + await expect.element(page.getByRole('button', { name: 'Zurück' })).toBeVisible(); + expect(document.body.textContent).not.toContain(m.doc_render_failed()); + }); }); describe('PdfViewer — empty / error states', () => { diff --git a/frontend/src/lib/document/viewer/usePdfRenderer.svelte.ts b/frontend/src/lib/document/viewer/usePdfRenderer.svelte.ts index 99724cf1..e7e9186b 100644 --- a/frontend/src/lib/document/viewer/usePdfRenderer.svelte.ts +++ b/frontend/src/lib/document/viewer/usePdfRenderer.svelte.ts @@ -111,6 +111,7 @@ export function createPdfRenderer(libLoader: LibLoader = defaultLibLoader) { // A real decode/render failure (e.g. a wasm decoder that could not // initialise) — surface a localized message instead of leaving a // silent blank canvas. Never leak the raw pdf.js error text. + renderTask = null; error = m.doc_render_failed(); return; }