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();
});
});
});
});