From 090e4b71389384153f0672d5cce99c2f2453ff74 Mon Sep 17 00:00:00 2001 From: Dmitriy E Date: Thu, 30 Apr 2026 11:37:52 +0300 Subject: [PATCH] test(upload): add unit tests for useVideoUpload hook --- src/hooks/useVideoUpload.test.ts | 419 +++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 src/hooks/useVideoUpload.test.ts diff --git a/src/hooks/useVideoUpload.test.ts b/src/hooks/useVideoUpload.test.ts new file mode 100644 index 00000000..368532b5 --- /dev/null +++ b/src/hooks/useVideoUpload.test.ts @@ -0,0 +1,419 @@ +// ABOUTME: Tests for useVideoUpload hook +// ABOUTME: Covers segment combining, duration extraction, Blossom upload, progress tracking, and error handling + +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { renderHook, waitFor, act } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import React from 'react'; +import { useVideoUpload } from './useVideoUpload'; + +// ── Module mocks ────────────────────────────────────────────────────────────── + +const mockMutateAsync = vi.fn(); +vi.mock('@/hooks/useUploadFile', () => ({ + useUploadFile: () => ({ mutateAsync: mockMutateAsync }), +})); + +const mockToast = vi.fn(); +vi.mock('@/hooks/useToast', () => ({ + useToast: () => ({ toast: mockToast }), +})); + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +function createWrapper() { + const queryClient = new QueryClient({ + defaultOptions: { + queries: { retry: false }, + mutations: { retry: false }, + }, + }); + return ({ children }: { children: React.ReactNode }) => + React.createElement(QueryClientProvider, { client: queryClient }, children); +} + +function makeSegment(blobUrl = 'blob:segment-1') { + return { + blob: new Blob(['video-data'], { type: 'video/webm' }), + blobUrl, + }; +} + +// ── Tests ───────────────────────────────────────────────────────────────────── + +describe('useVideoUpload', () => { + let mockCreateObjectURL: ReturnType; + let mockRevokeObjectURL: ReturnType; + + let videoEl: { + preload: string; + duration: number; + _src: string; + onloadedmetadata: (() => void) | null; + onerror: (() => void) | null; + }; + let videoShouldError: boolean; + + beforeEach(() => { + vi.resetAllMocks(); + videoShouldError = false; + + // Re-stub URL blob APIs after reset (jsdom does not implement them) + mockCreateObjectURL = vi.fn().mockReturnValue('blob:mock-url'); + mockRevokeObjectURL = vi.fn(); + Object.defineProperty(URL, 'createObjectURL', { + value: mockCreateObjectURL, + writable: true, + configurable: true, + }); + Object.defineProperty(URL, 'revokeObjectURL', { + value: mockRevokeObjectURL, + writable: true, + configurable: true, + }); + + // Mock