From 797852b494b97486ebbb10b7d4939d5752c7c7e1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 7 May 2026 22:26:53 +0200 Subject: [PATCH] test(dashboard): add partial-failure resilience test + fix i18n Dok. key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - page.server.spec.ts: new test verifies topPersons=[] when that fetch rejects, rest of reader data still loads — addresses @Sara concern - ReaderPersonChips: replaces hardcoded "Dok." with dashboard_reader_doc_count_suffix Paraglide key (de/en/es) — addresses @Felix suggestion Co-Authored-By: Claude Sonnet 4.6 --- frontend/messages/de.json | 1 + frontend/messages/en.json | 1 + frontend/messages/es.json | 1 + .../shared/dashboard/ReaderPersonChips.svelte | 4 ++- frontend/src/routes/page.server.spec.ts | 35 +++++++++++++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/frontend/messages/de.json b/frontend/messages/de.json index 1ac6f5f8..4bfa4b62 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -460,6 +460,7 @@ "dashboard_badge_new": "Neu", "dashboard_badge_updated": "Aktualisiert", "dashboard_reader_all_stories": "Alle Geschichten →", + "dashboard_reader_doc_count_suffix": "Dok.", "dashboard_resume_label": "Zuletzt geöffnet:", "dashboard_resume_fallback": "Unbekanntes Dokument", "doc_status_placeholder": "Platzhalter", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 37fa2e75..b7bdff0b 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -460,6 +460,7 @@ "dashboard_badge_new": "New", "dashboard_badge_updated": "Updated", "dashboard_reader_all_stories": "All Stories →", + "dashboard_reader_doc_count_suffix": "docs.", "dashboard_resume_label": "Last opened:", "dashboard_resume_fallback": "Unknown document", "doc_status_placeholder": "Placeholder", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index cfbeff87..5300ef4d 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -460,6 +460,7 @@ "dashboard_badge_new": "Nuevo", "dashboard_badge_updated": "Actualizado", "dashboard_reader_all_stories": "Todas las historias →", + "dashboard_reader_doc_count_suffix": "docs.", "dashboard_resume_label": "Último abierto:", "dashboard_resume_fallback": "Documento desconocido", "doc_status_placeholder": "Marcador", diff --git a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte index 8aa8d8c3..57a602df 100644 --- a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte +++ b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte @@ -45,7 +45,9 @@ const { persons }: Props = $props(); {p.displayName ?? p.lastName} - {p.documentCount ?? 0} Dok. + {p.documentCount ?? 0} {m.dashboard_reader_doc_count_suffix()} {/each} diff --git a/frontend/src/routes/page.server.spec.ts b/frontend/src/routes/page.server.spec.ts index 1aae2752..b51540c3 100644 --- a/frontend/src/routes/page.server.spec.ts +++ b/frontend/src/routes/page.server.spec.ts @@ -375,4 +375,39 @@ describe('home page load — reader branch (isReader = !canWrite && !canAnnotate expect(result.isReader).toBe(false); }); + + it('returns topPersons=[] when topPersons fetch fails, rest of data still loads', async () => { + const okStats = { + response: { ok: true, status: 200 }, + data: { totalDocuments: 5, totalPersons: 2, totalStories: 1 } + }; + const failPersons = Promise.reject(new Error('timeout')); + const okSearch = { response: { ok: true, status: 200 }, data: { items: [] } }; + const okStories = { response: { ok: true, status: 200 }, data: [] }; + + const mockGet = vi + .fn() + .mockResolvedValueOnce({ response: { ok: true, status: 200 }, data: [] }) // initial persons check + .mockResolvedValueOnce(okStats) + .mockReturnValueOnce(failPersons) + .mockResolvedValueOnce(okSearch) + .mockResolvedValueOnce(okStories); + vi.mocked(createApiClient).mockReturnValue({ GET: mockGet } as ReturnType< + typeof createApiClient + >); + + const result = await load({ + url: makeUrl(), + fetch: vi.fn() as unknown as typeof fetch, + parent: vi + .fn() + .mockResolvedValue({ canWrite: false, canAnnotate: false, canBlogWrite: false }) + } as Parameters[0]); + + expect(result.isReader).toBe(true); + if (result.isReader) { + expect(result.topPersons).toEqual([]); + expect(result.readerStats?.totalDocuments).toBe(5); + } + }); });