- transcription/: TranscriptionBlock, Column, EditView, PanelHeader, ReadView, Section + transcriptionMarkers, blockConflictMerge, saveBlockWithConflictRetry + useBlockAutoSave, useBlockDragDrop hooks - annotation/: AnnotationLayer, AnnotationShape, AnnotationEditOverlay - viewer/: PdfViewer, PdfControls + useFileLoader, usePdfRenderer hooks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
2.5 KiB
TypeScript
99 lines
2.5 KiB
TypeScript
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
import { createFileLoader } from './useFileLoader.svelte';
|
|
|
|
const FAKE_URL = 'blob:fake-url';
|
|
|
|
function setupFetch(ok: boolean, body?: Blob) {
|
|
const blob = body ?? new Blob(['fake'], { type: 'application/pdf' });
|
|
vi.stubGlobal(
|
|
'fetch',
|
|
vi.fn().mockResolvedValue({
|
|
ok,
|
|
blob: vi.fn().mockResolvedValue(blob)
|
|
})
|
|
);
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('createFileLoader', () => {
|
|
it('sets fileUrl after a successful fetch', async () => {
|
|
vi.stubGlobal('URL', {
|
|
createObjectURL: vi.fn().mockReturnValue(FAKE_URL),
|
|
revokeObjectURL: vi.fn()
|
|
});
|
|
setupFetch(true);
|
|
|
|
const loader = createFileLoader();
|
|
await loader.loadFile('/api/documents/1/file');
|
|
|
|
expect(loader.fileUrl).toBe(FAKE_URL);
|
|
expect(loader.isLoading).toBe(false);
|
|
expect(loader.fileError).toBe('');
|
|
});
|
|
|
|
it('sets fileError on a failed fetch (non-ok response)', async () => {
|
|
vi.stubGlobal('URL', {
|
|
createObjectURL: vi.fn(),
|
|
revokeObjectURL: vi.fn()
|
|
});
|
|
setupFetch(false);
|
|
|
|
const loader = createFileLoader();
|
|
await loader.loadFile('/api/documents/1/file');
|
|
|
|
expect(loader.fileUrl).toBe('');
|
|
expect(loader.fileError).not.toBe('');
|
|
expect(loader.isLoading).toBe(false);
|
|
});
|
|
|
|
it('revokes the previous URL before creating a new one', async () => {
|
|
const revokeObjectURL = vi.fn();
|
|
vi.stubGlobal('URL', {
|
|
createObjectURL: vi.fn().mockReturnValue(FAKE_URL),
|
|
revokeObjectURL
|
|
});
|
|
setupFetch(true);
|
|
|
|
const loader = createFileLoader();
|
|
await loader.loadFile('/api/documents/1/file');
|
|
// First load: no previous URL to revoke
|
|
expect(revokeObjectURL).not.toHaveBeenCalled();
|
|
|
|
await loader.loadFile('/api/documents/2/file');
|
|
// Second load: previous URL should be revoked
|
|
expect(revokeObjectURL).toHaveBeenCalledWith(FAKE_URL);
|
|
});
|
|
|
|
it('revokes the URL on destroy', async () => {
|
|
const revokeObjectURL = vi.fn();
|
|
vi.stubGlobal('URL', {
|
|
createObjectURL: vi.fn().mockReturnValue(FAKE_URL),
|
|
revokeObjectURL
|
|
});
|
|
setupFetch(true);
|
|
|
|
const loader = createFileLoader();
|
|
await loader.loadFile('/api/documents/1/file');
|
|
loader.destroy();
|
|
|
|
expect(revokeObjectURL).toHaveBeenCalledWith(FAKE_URL);
|
|
});
|
|
|
|
it('does not revoke when no URL has been set', () => {
|
|
const revokeObjectURL = vi.fn();
|
|
vi.stubGlobal('URL', {
|
|
createObjectURL: vi.fn(),
|
|
revokeObjectURL
|
|
});
|
|
|
|
const loader = createFileLoader();
|
|
loader.destroy();
|
|
|
|
expect(revokeObjectURL).not.toHaveBeenCalled();
|
|
});
|
|
});
|