Spaces:
Build error
Build error
| import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; | |
| import { render, screen, fireEvent, act } from '@testing-library/react'; | |
| import { GenerationCard } from './generation-card'; | |
| import type { GenerationResponse } from '@/lib/api'; | |
| // Mock dependencies | |
| vi.mock('@/hooks/use-websocket', () => ({ | |
| useGenerationWebSocket: () => ({ lastMessage: null }) | |
| })); | |
| interface SliderMockProps { | |
| value: number[]; | |
| onValueChange: (v: number[]) => void; | |
| className?: string; | |
| } | |
| 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} | |
| /> | |
| ) | |
| })); | |
| // Mock Audio element | |
| const mockPlay = vi.fn().mockResolvedValue(undefined); | |
| const mockPause = vi.fn(); | |
| describe('User Story Verification: Playback Control', () => { | |
| const originalPlay = window.HTMLMediaElement.prototype.play; | |
| const originalPause = window.HTMLMediaElement.prototype.pause; | |
| beforeEach(() => { | |
| window.HTMLMediaElement.prototype.play = mockPlay; | |
| window.HTMLMediaElement.prototype.pause = mockPause; | |
| }); | |
| afterEach(() => { | |
| window.HTMLMediaElement.prototype.play = originalPlay; | |
| window.HTMLMediaElement.prototype.pause = originalPause; | |
| vi.clearAllMocks(); | |
| }); | |
| const mockGeneration: GenerationResponse = { | |
| id: 'test-gen-123', | |
| status: 'completed', | |
| prompt: 'A test track', | |
| audio_path: '/music/test.wav', | |
| created_at: new Date().toISOString(), | |
| metadata: { | |
| prompt: 'A test track', | |
| analysis: { | |
| style: 'lo-fi', | |
| tempo: 90, | |
| mood: 'chill' | |
| } | |
| } | |
| }; | |
| it('Scenario: User initiates playback and updates UI', async () => { | |
| render(<GenerationCard generation={mockGeneration} />); | |
| // 1. Validate Initial State | |
| // "play" button should be visible | |
| const playButton = screen.getByLabelText('Play'); | |
| expect(playButton).toBeInTheDocument(); | |
| // "pause" button should NOT be visible | |
| expect(screen.queryByLabelText('Pause')).not.toBeInTheDocument(); | |
| // Card should NOT have the highlight class (checking specifically for the ring-primary class) | |
| const card = screen.getByText('A test track').closest('.bg-card'); | |
| expect(card).not.toHaveClass('ring-primary'); | |
| // 2. Action: Press "play" button | |
| await act(async () => { | |
| fireEvent.click(playButton); | |
| }); | |
| // 3. Verify Functionality: Initiate playback | |
| expect(mockPlay).toHaveBeenCalledTimes(1); | |
| // 4. Validate UI Rendering: Update to reflect playing state | |
| // "pause" button SHOULD be visible/enabled | |
| const pauseButton = screen.getByLabelText('Pause'); | |
| expect(pauseButton).toBeInTheDocument(); | |
| // "play" button should NOT be visible | |
| expect(screen.queryByLabelText('Play')).not.toBeInTheDocument(); | |
| // 5. Validate UI Rendering: Visual Highlight | |
| // Card SHOULD have the highlight class | |
| expect(card).toHaveClass('ring-primary'); | |
| expect(card).toHaveClass('border-primary'); | |
| expect(card).toHaveClass('shadow-[0_0_15px_rgba(var(--primary),0.2)]'); | |
| // 6. Action: Press "pause" button | |
| await act(async () => { | |
| fireEvent.click(pauseButton); | |
| }); | |
| // 7. Verify Functionality: Pause playback | |
| expect(mockPause).toHaveBeenCalledTimes(1); | |
| // 8. Validate UI Rendering: Return to paused state | |
| expect(screen.getByLabelText('Play')).toBeInTheDocument(); | |
| expect(card).not.toHaveClass('ring-primary'); | |
| }); | |
| }); | |