import { describe, it, expect, vi, beforeEach } from 'vitest'; import React from 'react'; // Mock IntersectionObserver class MockIntersectionObserver { observe = vi.fn(); unobserve = vi.fn(); disconnect = vi.fn(); } vi.stubGlobal('IntersectionObserver', MockIntersectionObserver); import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { AudioPlayer } from './AudioPlayer'; import { LayoutProvider } from '../../../contexts/LayoutContext'; // Mock useLayout since it's used inside AudioPlayer vi.mock('../../../contexts/LayoutContext', async () => { const actual = await vi.importActual('../../../contexts/LayoutContext'); return { ...actual, useLayout: vi.fn(() => ({ sidebarExpanded: true, sidebarWidth: 280, assistenteExpanded: false, })), }; }); // Mock HTMLAudioElement beforeEach(() => { vi.clearAllMocks(); window.HTMLMediaElement.prototype.play = vi.fn().mockResolvedValue(undefined); window.HTMLMediaElement.prototype.pause = vi.fn(); window.HTMLMediaElement.prototype.load = vi.fn(); }); describe('AudioPlayer (Unified)', () => { describe('Bar Variant', () => { it('renders nothing when isOpen is false', () => { const { container } = render( ); expect(container.firstChild).toBeNull(); }); it('renders correctly when open', () => { render( ); expect(screen.getByText('Test Track')).toBeInTheDocument(); }); it('calls onClose when close button is clicked', () => { const onClose = vi.fn(); render( ); const closeButton = screen.getByLabelText('Fechar player'); fireEvent.click(closeButton); expect(onClose).toHaveBeenCalled(); }); }); describe('Card Variant', () => { it('renders card layout by default', () => { render( ); expect(screen.getByText('Card Track')).toBeInTheDocument(); // Should NOT have fixed position by default const player = screen.getByText('Card Track').closest('.fixed'); expect(player).toBeNull(); }); }); describe('Functionality', () => { it('toggles playback status icons', async () => { render( ); const playButton = screen.getByRole('button', { name: /Reproduzir/i }); fireEvent.click(playButton); // The 'bar' variant uses createPortal into document.body, so we must // search the entire document for the audio element, not just the container. const audio = document.body.querySelector('audio'); if (audio) fireEvent(audio, new Event('play')); await waitFor(() => { expect(screen.getByRole('button', { name: /Pausar/i })).toBeInTheDocument(); }); }); }); });