feat(transcription): decouple @mention display text from person search (#380) #629

Merged
marcel merged 41 commits from feat/issue-380-decouple-mention-search into main 2026-05-20 20:36:39 +02:00
Showing only changes of commit cc4a8aed14 - Show all commits

View File

@@ -219,20 +219,30 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
expect(fetchesAfterSearch).toBe(1);
});
it('fires exactly one /api/persons fetch when the user types @Walter (debounced)', async () => {
it('fires exactly one /api/persons fetch when the user searches for Walter (debounced)', async () => {
const fetchMock = vi
.fn()
.mockResolvedValue({ ok: true, json: vi.fn().mockResolvedValue([AUGUSTE]) });
vi.stubGlobal('fetch', fetchMock);
renderHost();
await userEvent.type(page.getByRole('textbox'), '@Walter');
// Open the dropdown first so the search input is reachable. `fill` then
// drives the searchbox in one input event — sidesteps per-keystroke
// debounce timing on CI that Sara flagged on PR #629 round 2.
await userEvent.type(page.getByRole('textbox'), '@');
await vi.waitFor(async () => {
await expect.element(page.getByRole('searchbox')).toBeVisible();
});
const fetchesBeforeSearch = fetchMock.mock.calls.length;
await page.getByRole('searchbox').fill('Walter');
await new Promise((r) => setTimeout(r, SEARCH_DEBOUNCE_MS + POST_DEBOUNCE_SLACK_MS));
const personsFetches = fetchMock.mock.calls.filter(
([url]) => typeof url === 'string' && url.startsWith('/api/persons')
);
const personsFetches = fetchMock.mock.calls
.slice(fetchesBeforeSearch)
.filter(([url]) => typeof url === 'string' && url.startsWith('/api/persons'));
expect(personsFetches.length).toBe(1);
});