test(discussion): expand MentionEditor coverage further

Adds mousedown-to-select flow, Enter-to-select with highlighted
result, fetch network throw handling.

3 new tests covering ~6 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-10 06:58:20 +02:00
parent 51f86e1fae
commit 91d750bc97

View File

@@ -222,4 +222,71 @@ describe('MentionEditor', () => {
const popup = document.querySelector('[role="listbox"]');
expect(popup).not.toBeNull();
});
it('selects a user via mousedown click and fills the textarea', async () => {
render(MentionEditor, {
props: { value: '', mentionCandidates: [] }
});
const ta = document.querySelector('textarea') as HTMLTextAreaElement;
ta.focus();
ta.value = '@An';
ta.selectionStart = 3;
ta.selectionEnd = 3;
ta.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 350));
const firstOption = document.querySelector('[role="option"]') as HTMLElement;
firstOption?.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
await new Promise((r) => setTimeout(r, 50));
// After select, popup is closed
const popup = document.querySelector('[role="listbox"]');
expect(popup).toBeNull();
});
it('selects via Enter when results are present', async () => {
render(MentionEditor, {
props: { value: '', mentionCandidates: [] }
});
const ta = document.querySelector('textarea') as HTMLTextAreaElement;
ta.focus();
ta.value = '@An';
ta.selectionStart = 3;
ta.selectionEnd = 3;
ta.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 350));
// Move highlight to first result with ArrowDown then Enter
ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
await new Promise((r) => setTimeout(r, 30));
ta.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
await new Promise((r) => setTimeout(r, 50));
// Popup closed after select
const popup = document.querySelector('[role="listbox"]');
expect(popup).toBeNull();
});
it('handles fetch network throw gracefully', async () => {
fetchSpy.mockImplementationOnce(async () => {
throw new Error('network down');
});
render(MentionEditor, {
props: { value: '', mentionCandidates: [] }
});
const ta = document.querySelector('textarea') as HTMLTextAreaElement;
ta.focus();
ta.value = '@An';
ta.selectionStart = 3;
ta.selectionEnd = 3;
ta.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 350));
// Empty popup label after thrown fetch
await expect.element(page.getByText(/keine nutzer gefunden/i)).toBeVisible();
});
});