File size: 3,262 Bytes
6423ff2
 
 
 
 
 
5bf2d26
 
 
 
 
 
6423ff2
5bf2d26
6423ff2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { AudioPlayer } from './audio-player';

// Mock the Slider component
// We mock it to expose its props (value, onValueChange) for easier testing
interface SliderMockProps {
  value: number[];
  onValueChange: (v: number[]) => void;
  className?: string;
  [key: string]: unknown;
}
vi.mock('@/components/ui/slider', () => ({
  Slider: ({ value, onValueChange, className, ...props }: SliderMockProps) => (
    <input 
      type="range"
      data-testid="mock-slider"
      value={value[0]} 
      onChange={(e) => onValueChange([parseFloat(e.target.value)])}
      className={className}
      {...props}
    />
  )
}));

describe('AudioPlayer', () => {
  const originalPlay = window.HTMLMediaElement.prototype.play;
  const originalPause = window.HTMLMediaElement.prototype.pause;

  beforeEach(() => {
    window.HTMLMediaElement.prototype.play = vi.fn().mockResolvedValue(undefined);
    window.HTMLMediaElement.prototype.pause = vi.fn();
  });

  afterEach(() => {
    window.HTMLMediaElement.prototype.play = originalPlay;
    window.HTMLMediaElement.prototype.pause = originalPause;
    vi.clearAllMocks();
  });

  it('renders correctly with given src', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    
    // Check for Play button
    expect(screen.getByRole('button', { name: /play/i })).toBeInTheDocument();
    
    // Check if audio element exists with correct src
    const audioEl = document.querySelector('audio');
    expect(audioEl).toBeInTheDocument();
    expect(audioEl).toHaveAttribute('src', '/test-audio.wav');
  });

  it('toggles play and pause', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    
    const playButton = screen.getByRole('button', { name: /play/i });

    // Click Play
    fireEvent.click(playButton);
    expect(window.HTMLMediaElement.prototype.play).toHaveBeenCalled();
    expect(screen.getByRole('button', { name: /pause/i })).toBeInTheDocument();

    // Click Pause
    const pauseButton = screen.getByRole('button', { name: /pause/i });
    fireEvent.click(pauseButton);
    expect(window.HTMLMediaElement.prototype.pause).toHaveBeenCalled();
    expect(screen.getByRole('button', { name: /play/i })).toBeInTheDocument();
  });

  it('handles volume changes', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    const audioEl = document.querySelector('audio');
    expect(audioEl?.volume).toBe(1);

    const volumeSlider = screen.getByLabelText('Volume');

    if (volumeSlider) {
      fireEvent.change(volumeSlider, { target: { value: 0.5 } });
      expect(audioEl?.volume).toBe(0.5);
    }
  });

  it('toggles mute', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    const audioEl = document.querySelector('audio');
    
    const muteButton = screen.getByRole('button', { name: /mute/i });

    fireEvent.click(muteButton);
    expect(audioEl?.muted).toBe(true);
    expect(screen.getByRole('button', { name: /unmute/i })).toBeInTheDocument();

    const unmuteButton = screen.getByRole('button', { name: /unmute/i });
    fireEvent.click(unmuteButton);
    expect(audioEl?.muted).toBe(false);
  });
});