test(dashboard): add partial-failure resilience test + fix i18n Dok. key
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -460,6 +460,7 @@
|
|||||||
"dashboard_badge_new": "Neu",
|
"dashboard_badge_new": "Neu",
|
||||||
"dashboard_badge_updated": "Aktualisiert",
|
"dashboard_badge_updated": "Aktualisiert",
|
||||||
"dashboard_reader_all_stories": "Alle Geschichten →",
|
"dashboard_reader_all_stories": "Alle Geschichten →",
|
||||||
|
"dashboard_reader_doc_count_suffix": "Dok.",
|
||||||
"dashboard_resume_label": "Zuletzt geöffnet:",
|
"dashboard_resume_label": "Zuletzt geöffnet:",
|
||||||
"dashboard_resume_fallback": "Unbekanntes Dokument",
|
"dashboard_resume_fallback": "Unbekanntes Dokument",
|
||||||
"doc_status_placeholder": "Platzhalter",
|
"doc_status_placeholder": "Platzhalter",
|
||||||
|
|||||||
@@ -460,6 +460,7 @@
|
|||||||
"dashboard_badge_new": "New",
|
"dashboard_badge_new": "New",
|
||||||
"dashboard_badge_updated": "Updated",
|
"dashboard_badge_updated": "Updated",
|
||||||
"dashboard_reader_all_stories": "All Stories →",
|
"dashboard_reader_all_stories": "All Stories →",
|
||||||
|
"dashboard_reader_doc_count_suffix": "docs.",
|
||||||
"dashboard_resume_label": "Last opened:",
|
"dashboard_resume_label": "Last opened:",
|
||||||
"dashboard_resume_fallback": "Unknown document",
|
"dashboard_resume_fallback": "Unknown document",
|
||||||
"doc_status_placeholder": "Placeholder",
|
"doc_status_placeholder": "Placeholder",
|
||||||
|
|||||||
@@ -460,6 +460,7 @@
|
|||||||
"dashboard_badge_new": "Nuevo",
|
"dashboard_badge_new": "Nuevo",
|
||||||
"dashboard_badge_updated": "Actualizado",
|
"dashboard_badge_updated": "Actualizado",
|
||||||
"dashboard_reader_all_stories": "Todas las historias →",
|
"dashboard_reader_all_stories": "Todas las historias →",
|
||||||
|
"dashboard_reader_doc_count_suffix": "docs.",
|
||||||
"dashboard_resume_label": "Último abierto:",
|
"dashboard_resume_label": "Último abierto:",
|
||||||
"dashboard_resume_fallback": "Documento desconocido",
|
"dashboard_resume_fallback": "Documento desconocido",
|
||||||
"doc_status_placeholder": "Marcador",
|
"doc_status_placeholder": "Marcador",
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ const { persons }: Props = $props();
|
|||||||
</span>
|
</span>
|
||||||
<span class="flex min-w-0 flex-col">
|
<span class="flex min-w-0 flex-col">
|
||||||
<span class="text-ink-1 truncate font-serif text-sm">{p.displayName ?? p.lastName}</span>
|
<span class="text-ink-1 truncate font-serif text-sm">{p.displayName ?? p.lastName}</span>
|
||||||
<span class="font-sans text-xs text-ink-3">{p.documentCount ?? 0} Dok.</span>
|
<span class="font-sans text-xs text-ink-3"
|
||||||
|
>{p.documentCount ?? 0} {m.dashboard_reader_doc_count_suffix()}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -375,4 +375,39 @@ describe('home page load — reader branch (isReader = !canWrite && !canAnnotate
|
|||||||
|
|
||||||
expect(result.isReader).toBe(false);
|
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<typeof load>[0]);
|
||||||
|
|
||||||
|
expect(result.isReader).toBe(true);
|
||||||
|
if (result.isReader) {
|
||||||
|
expect(result.topPersons).toEqual([]);
|
||||||
|
expect(result.readerStats?.totalDocuments).toBe(5);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user