import { AudioService } from '../src/services/audioService'; import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; describe('AudioService Audio Context Initialization', () => { let audioService: AudioService; beforeEach(() => { // Reset the singleton instance before each test AudioService.resetInstance(); audioService = AudioService.getInstance(); // Mock AudioContext for testing global.window.AudioContext = vi.fn().mockImplementation(() => ({ state: 'suspended', sampleRate: 44100, resume: vi.fn().mockResolvedValue(undefined), close: vi.fn().mockResolvedValue(undefined), onstatechange: null, suspend: vi.fn().mockResolvedValue(undefined) })) as any; }); afterEach(() => { // Clean up any audio contexts if (audioService['audioContext']) { audioService['audioContext'].close?.().catch(() => {}); } // Clean up mock delete global.window.AudioContext; }); it('should initialize audio context successfully', async () => { const context = await audioService.initializeAudioContext(); expect(context).toBeDefined(); expect(context.state).toBe('suspended'); // Should start suspended expect(audioService['audioContext']).toBe(context); }); it('should handle audio context resume', async () => { // Initialize context first await audioService.initializeAudioContext(); // Mock user gesture by resuming const resumeSpy = vi.spyOn(audioService['audioContext']!, 'resume'); // This should attempt to resume the context await audioService['handleAudioContextResume'](); expect(resumeSpy).toHaveBeenCalled(); }); it('should share audio context with WaveSurfer', async () => { // Initialize audio context await audioService.initializeAudioContext(); // Create mock WaveSurfer instance const mockWaveSurfer = { backend: { audioContext: null } }; // Call the sharing method audioService['shareAudioContextWithWaveSurfer'](mockWaveSurfer); // Verify context was shared expect(mockWaveSurfer.backend.audioContext).toBe(audioService['audioContext']); }); it('should handle WaveSurfer without backend gracefully', async () => { // Initialize audio context await audioService.initializeAudioContext(); // Create mock WaveSurfer instance without backend const mockWaveSurfer = { getAudioContext: vi.fn() }; // This should not throw expect(() => { audioService['shareAudioContextWithWaveSurfer'](mockWaveSurfer); }).not.toThrow(); }); it('should check initialization state correctly', async () => { // Initially should not be initialized expect(audioService.isInitialized()).toBe(false); // After audio context initialization, still not fully initialized await audioService.initializeAudioContext(); expect(audioService.isInitialized()).toBe(false); // Note: Full initialization would require WaveSurfer instance // which we can't easily mock here without DOM }); });