fix(transcription): defensively cap @mention fetch with limit=5
Adds &limit=5 to the /api/persons request so the client signals its intent and stays consistent with the SEARCH_RESULT_LIMIT slice. Backend enforcement (and the broader PersonSummaryDTO response-shape audit) is tracked separately. Markus on PR #629. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -196,7 +196,11 @@ onMount(() => {
|
||||
const runSearch = async (query: string) => {
|
||||
const id = requestId;
|
||||
try {
|
||||
const res = await fetch(`/api/persons?q=${encodeURIComponent(query)}`);
|
||||
// Defensive client-side cap — server-side enforcement is tracked
|
||||
// separately. Markus on PR #629.
|
||||
const res = await fetch(
|
||||
`/api/persons?q=${encodeURIComponent(query)}&limit=${SEARCH_RESULT_LIMIT}`
|
||||
);
|
||||
if (id !== requestId) return;
|
||||
if (!res.ok) {
|
||||
dropdownState.items = [];
|
||||
|
||||
@@ -125,6 +125,20 @@ describe('PersonMentionEditor — typeahead', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('appends &limit=5 to the fetch URL (defensive client-side cap, Markus on PR #629)', async () => {
|
||||
const fetchMock = vi
|
||||
.fn()
|
||||
.mockResolvedValue({ ok: true, json: vi.fn().mockResolvedValue([AUGUSTE]) });
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
renderHost();
|
||||
|
||||
await userEvent.type(page.getByRole('textbox'), '@Aug');
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('limit=5'));
|
||||
});
|
||||
});
|
||||
|
||||
it('shows life dates next to the name in the dropdown', async () => {
|
||||
mockFetchWithPersons();
|
||||
renderHost();
|
||||
@@ -237,6 +251,27 @@ describe('PersonMentionEditor — AC-2/3: search input drives fetch', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Whitespace-only query (Elicit AC-4 ambiguity on PR #629) ───────────────
|
||||
|
||||
describe('PersonMentionEditor — whitespace-only query', () => {
|
||||
it('keeps the "Namen eingeben…" prompt and fires no fetch when @ is followed only by spaces', async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue({ ok: true, json: vi.fn().mockResolvedValue([]) });
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
renderHost();
|
||||
|
||||
await userEvent.type(page.getByRole('textbox'), '@ ');
|
||||
await vi.waitFor(async () => {
|
||||
await expect.element(page.getByRole('searchbox')).toBeVisible();
|
||||
});
|
||||
|
||||
// Wait beyond the debounce window so any trailing call would have fired.
|
||||
await new Promise((r) => setTimeout(r, 300));
|
||||
|
||||
await expect.element(page.getByText(m.person_mention_search_prompt())).toBeInTheDocument();
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Stale-response race (Sara on PR #629) ───────────────────────────────────
|
||||
|
||||
describe('PersonMentionEditor — stale-response race', () => {
|
||||
|
||||
Reference in New Issue
Block a user