diff --git a/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts b/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts index 4262f3bc..e21eb412 100644 --- a/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts +++ b/frontend/src/lib/shared/discussion/PersonMentionEditor.svelte.spec.ts @@ -319,6 +319,37 @@ describe('PersonMentionEditor — stale-response race', () => { }); }); +// ─── Server failure characterization (Sara #2 on PR #629) ─────────────────── + +describe('PersonMentionEditor — server failure', () => { + it('on 500 response keeps the dropdown open with the empty-state copy (silent failure pinned; distinct error UX tracked separately)', async () => { + const fetchMock = vi + .fn() + .mockResolvedValue({ ok: false, status: 500, json: vi.fn().mockResolvedValue({}) }); + vi.stubGlobal('fetch', fetchMock); + renderHost(); + + await userEvent.type(page.getByRole('textbox'), '@Aug'); + await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS)); + + // Pins current silent-failure behaviour. The day someone implements a + // distinct error UX (toast / "Suche fehlgeschlagen" copy), this test + // goes red and forces them to update the assertion. + await expect.element(page.getByText(m.person_mention_popup_empty())).toBeInTheDocument(); + }); + + it('on a fetch reject (network failure) keeps the dropdown open with the empty-state copy', async () => { + const fetchMock = vi.fn().mockRejectedValue(new TypeError('NetworkError')); + vi.stubGlobal('fetch', fetchMock); + renderHost(); + + await userEvent.type(page.getByRole('textbox'), '@Aug'); + await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS)); + + await expect.element(page.getByText(m.person_mention_popup_empty())).toBeInTheDocument(); + }); +}); + // ─── onExit cancels pending debounce (Felix #1 on PR #629) ─────────────────── describe('PersonMentionEditor — onExit cancels pending debounce', () => {