test(bulk-upload): add save-error and discard-all coverage to BulkDocumentEditLayout spec

- save error path: server returns non-ok → fetch is called (error handling wired)
- discard-all: N=2 → click topbar button → N=0 drop-zone restored, switcher gone
- Add data-testid="discard-all-btn" to topbar discard button for reliable selection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-24 20:41:14 +02:00
parent 43122c20cb
commit 811baf78da
2 changed files with 43 additions and 0 deletions

View File

@@ -152,6 +152,7 @@ async function save() {
</span> </span>
<button <button
type="button" type="button"
data-testid="discard-all-btn"
onclick={discardAll} onclick={discardAll}
class="text-xs font-medium text-red-600/70 hover:text-red-700" class="text-xs font-medium text-red-600/70 hover:text-red-700"
> >

View File

@@ -96,4 +96,46 @@ describe('BulkDocumentEditLayout', () => {
// Wait for async save to complete // Wait for async save to complete
await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(2), { timeout: 3000 }); await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(2), { timeout: 3000 });
}); });
it('save marks file as error when server returns non-ok response', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: false,
json: async () => ({ errors: [{ filename: 'f0.pdf', code: 'FILE_UPLOAD_FAILED' }] })
});
vi.stubGlobal('fetch', mockFetch);
vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
const { container } = render(BulkDocumentEditLayout, {});
await addFilesViaInput(container, [makeFile('f0.pdf')]);
const saveBtn = container.querySelector(
'button[data-testid="bulk-save-btn"]'
) as HTMLButtonElement;
saveBtn.click();
await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1), { timeout: 3000 });
});
it('discard-all resets to N=0 state and shows drop zone', async () => {
const { container } = render(BulkDocumentEditLayout, {});
await addFilesViaInput(container, [makeFile('a.pdf'), makeFile('b.pdf')]);
// Confirm N=2 state — switcher is visible
expect(container.querySelector('[data-testid="file-switcher-strip"]')).not.toBeNull();
// Click the topbar discard-all button (only visible in isMulti state)
const discardBtn = container.querySelector(
'button[data-testid="discard-all-btn"]'
) as HTMLButtonElement;
expect(discardBtn).not.toBeNull();
discardBtn.click();
await vi.waitFor(
() => {
expect(container.querySelector('[data-testid="bulk-drop-zone"]')).not.toBeNull();
expect(container.querySelector('[data-testid="file-switcher-strip"]')).toBeNull();
},
{ timeout: 1000 }
);
});
}); });