import { describe, it, expect, vi, beforeEach } from 'vitest'; // Mock the videoSession store (playback.ts imports it) vi.mock('$lib/stores/videoSession.svelte', () => ({ session: { duration: 120, currentTime: 0, fps: 30, isPlaying: false, keyframePositions: [], }, })); import { setVideoElement, togglePiP, isPiPActive, toggleFullscreen, isFullscreenActive, setPlaybackRate, getPlaybackRate, } from '$lib/transport/playback'; function createMockVideoElement(): HTMLVideoElement { const el = document.createElement('video'); // PiP (el as any).requestPictureInPicture = vi.fn().mockResolvedValue({}); // Fullscreen el.requestFullscreen = vi.fn().mockResolvedValue(undefined); return el; } describe('playback — PiP helpers', () => { let mockVideo: HTMLVideoElement; beforeEach(() => { mockVideo = createMockVideoElement(); setVideoElement(mockVideo); // Reset PiP state Object.defineProperty(document, 'pictureInPictureElement', { value: null, writable: true, configurable: true, }); Object.defineProperty(document, 'pictureInPictureEnabled', { value: true, writable: true, configurable: true, }); }); it('isPiPActive returns false when no PiP element', () => { expect(isPiPActive()).toBe(false); }); it('togglePiP calls requestPictureInPicture', () => { togglePiP(); expect((mockVideo as any).requestPictureInPicture).toHaveBeenCalled(); }); it('isPiPActive returns true when PiP element exists', () => { Object.defineProperty(document, 'pictureInPictureElement', { value: mockVideo, writable: true, configurable: true, }); expect(isPiPActive()).toBe(true); }); }); describe('playback — fullscreen helpers', () => { let mockVideo: HTMLVideoElement; beforeEach(() => { mockVideo = createMockVideoElement(); setVideoElement(mockVideo); Object.defineProperty(document, 'fullscreenElement', { value: null, writable: true, configurable: true, }); }); it('isFullscreenActive returns false when not fullscreen', () => { expect(isFullscreenActive()).toBe(false); }); it('toggleFullscreen calls requestFullscreen when not fullscreen', () => { toggleFullscreen(); expect(mockVideo.requestFullscreen).toHaveBeenCalled(); }); it('isFullscreenActive returns true when fullscreen element exists', () => { Object.defineProperty(document, 'fullscreenElement', { value: mockVideo, writable: true, configurable: true, }); expect(isFullscreenActive()).toBe(true); }); }); describe('playback — playback rate helpers', () => { let mockVideo: HTMLVideoElement; beforeEach(() => { mockVideo = createMockVideoElement(); setVideoElement(mockVideo); }); it('getPlaybackRate returns 1 by default', () => { expect(getPlaybackRate()).toBe(1); }); it('setPlaybackRate changes the video playback rate', () => { setPlaybackRate(1.5); expect(mockVideo.playbackRate).toBe(1.5); }); it('getPlaybackRate returns the current rate', () => { setPlaybackRate(2); expect(getPlaybackRate()).toBe(2); }); it('getPlaybackRate returns 1 when no video element', () => { setVideoElement(null); expect(getPlaybackRate()).toBe(1); }); });