veza/apps/web/src/context/AudioContext.test.tsx

163 lines
4 KiB
TypeScript
Raw Normal View History

import { renderHook, act } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AudioProvider, useAudio } from './AudioContext';
import { ReactNode } from 'react';
import { Track } from '@/types';
const wrapper = ({ children }: { children: ReactNode }) => (
<AudioProvider>{children}</AudioProvider>
);
const mockTrack: Track = {
id: '1',
title: 'Test Track',
artist: 'Test Artist',
duration: '3:45',
durationSec: 225,
plays: 100,
likes: 10,
};
describe('AudioContext', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it('should provide audio context', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
expect(result.current).toBeDefined();
expect(result.current).toHaveProperty('currentTrack');
expect(result.current).toHaveProperty('isPlaying');
expect(result.current).toHaveProperty('queue');
expect(result.current).toHaveProperty('playTrack');
expect(result.current).toHaveProperty('togglePlay');
});
it('should have initial track', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
expect(result.current.currentTrack).toBeDefined();
expect(result.current.currentTrack).toHaveProperty('title');
});
it('should play a track', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
act(() => {
result.current.playTrack(mockTrack);
});
expect(result.current.currentTrack).toEqual(mockTrack);
});
it('should toggle play/pause', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
const initialPlaying = result.current.isPlaying;
act(() => {
result.current.togglePlay();
});
expect(result.current.isPlaying).toBe(!initialPlaying);
});
it('should set volume', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
act(() => {
result.current.setVolume(50);
});
expect(result.current.volume).toBe(50);
});
it('should toggle mute', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
const initialMuted = result.current.isMuted;
act(() => {
result.current.toggleMute();
});
expect(result.current.isMuted).toBe(!initialMuted);
});
it('should toggle shuffle', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
const initialShuffle = result.current.shuffle;
act(() => {
result.current.toggleShuffle();
});
expect(result.current.shuffle).toBe(!initialShuffle);
});
it('should toggle repeat mode', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
act(() => {
result.current.toggleRepeat();
});
expect(['off', 'all', 'one']).toContain(result.current.repeatMode);
});
it('should seek to position', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
act(() => {
result.current.seek(50);
});
expect(result.current.progress).toBe(50);
});
it('should add track to queue', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
const initialQueueLength = result.current.queue.length;
act(() => {
result.current.addToQueue(mockTrack);
});
expect(result.current.queue.length).toBe(initialQueueLength + 1);
});
it('should remove track from queue', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
const initialQueueLength = result.current.queue.length;
if (initialQueueLength > 0) {
const trackId = result.current.queue[0].id;
act(() => {
result.current.removeFromQueue(trackId);
});
expect(result.current.queue.length).toBe(initialQueueLength - 1);
}
});
it('should clear queue', () => {
const { result } = renderHook(() => useAudio(), { wrapper });
act(() => {
result.current.clearQueue();
});
expect(result.current.queue.length).toBe(0);
});
});