162 lines
4 KiB
TypeScript
162 lines
4 KiB
TypeScript
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);
|
|
});
|
|
});
|