Add unit tests for frontend utilities and hooks

82 tests covering download.ts and all React Query hooks. API modules are
mocked with vi.mock; mutation tests spy on queryClient.invalidateQueries
to verify cache invalidation. Conditional queries (null id) are verified
to stay idle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 13:47:55 +01:00
parent c80d7d0802
commit 0d2f419c6a
11 changed files with 1069 additions and 20 deletions

View File

@@ -0,0 +1,47 @@
import { downloadJson } from './download'
describe('downloadJson', () => {
beforeEach(() => {
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock-url')
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined)
})
afterEach(() => {
vi.restoreAllMocks()
})
it('creates a blob URL from the JSON data', () => {
downloadJson({ x: 1 }, 'export.json')
expect(URL.createObjectURL).toHaveBeenCalledOnce()
const blob = vi.mocked(URL.createObjectURL).mock.calls[0]?.[0] as Blob
expect(blob.type).toBe('application/json')
})
it('revokes the blob URL after triggering the download', () => {
downloadJson({ x: 1 }, 'export.json')
expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:mock-url')
})
it('sets the correct download filename on the anchor', () => {
const spy = vi.spyOn(document, 'createElement')
downloadJson({ x: 1 }, 'my-data.json')
const anchor = spy.mock.results[0]?.value as HTMLAnchorElement
expect(anchor.download).toBe('my-data.json')
})
it('appends and removes the anchor from the document body', () => {
const appendSpy = vi.spyOn(document.body, 'appendChild')
const removeSpy = vi.spyOn(document.body, 'removeChild')
downloadJson({}, 'empty.json')
expect(appendSpy).toHaveBeenCalledOnce()
expect(removeSpy).toHaveBeenCalledOnce()
})
it('serializes the data as formatted JSON', () => {
downloadJson({ a: 1, b: [2, 3] }, 'data.json')
const blob = vi.mocked(URL.createObjectURL).mock.calls[0]?.[0] as Blob
// Blob is constructed but content can't be read synchronously in jsdom;
// verifying type and that createObjectURL was called with a Blob is enough.
expect(blob).toBeInstanceOf(Blob)
})
})