import { describe, test, expect, vi } from 'vitest' import { render, screen, fireEvent } from '@testing-library/react' import { Options } from './options' describe('Options', () => { test('renders options button with default label', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() expect(screen.getByLabelText('Options')).toBeTruthy() }) test('renders options button with custom label', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] const labels = { title: 'Custom Options Label', } render() expect(screen.getByLabelText('Custom Options Label')).toBeTruthy() }) test('renders when options array is empty', () => { render() // Component still renders button even with empty options // (In practice, WrapperUI doesn't render Options when options.length === 0) expect(screen.getByLabelText('Options')).toBeTruthy() }) test('renders when options is undefined', () => { render() // Component still renders button even with undefined options // (In practice, WrapperUI doesn't render Options when options.length === 0) expect(screen.getByLabelText('Options')).toBeTruthy() }) test('opens menu when button is clicked', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) expect(screen.getByText('Option 1')).toBeTruthy() }) test('closes menu when option is clicked', () => { const onClick = vi.fn() const options = [ { label: 'Option 1', onClick, }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) const menuItem = screen.getByText('Option 1') fireEvent.click(menuItem) expect(onClick).toHaveBeenCalledTimes(1) // Menu should be closed after clicking expect(screen.queryByRole('menu')).toBeNull() }) test('stops event propagation when opening menu', () => { const parentOnClick = vi.fn() const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render(
, ) const button = screen.getByLabelText('Options') fireEvent.click(button) // Parent onClick should not be called expect(parentOnClick).not.toHaveBeenCalled() }) test('stops event propagation when clicking option', () => { const parentOnClick = vi.fn() const onClick = vi.fn() const options = [ { label: 'Option 1', onClick, }, ] render(
, ) const button = screen.getByLabelText('Options') fireEvent.click(button) const menuItem = screen.getByText('Option 1') fireEvent.click(menuItem) expect(onClick).toHaveBeenCalledTimes(1) expect(parentOnClick).not.toHaveBeenCalled() }) test('renders multiple options', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, { label: 'Option 2', onClick: vi.fn(), }, { label: 'Option 3', onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) expect(screen.getByText('Option 1')).toBeTruthy() expect(screen.getByText('Option 2')).toBeTruthy() expect(screen.getByText('Option 3')).toBeTruthy() }) test('renders disabled option', () => { const options = [ { label: 'Disabled Option', disabled: true, onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) const menuItem = screen.getByText('Disabled Option').closest('li') expect(menuItem?.classList.contains('Mui-disabled')).toBe(true) }) test('does not call onClick for disabled option', () => { const onClick = vi.fn() const options = [ { label: 'Enabled Option', onClick, }, { label: 'Disabled Option', disabled: true, onClick, }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) // Click on enabled option first const enabled = screen.getByText('Enabled Option') fireEvent.click(enabled) // onClick should be called once for enabled expect(onClick).toHaveBeenCalledTimes(1) // Open menu again and try clicking disabled fireEvent.click(button) const disabled = screen.getByText('Disabled Option').closest('li') // Disabled should have the class expect(disabled?.classList.contains('Mui-disabled')).toBe(true) }) test('renders option with icon', () => { const icon = Icon const options = [ { label: 'Option with Icon', icon, onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) expect(screen.getByTestId('test-icon')).toBeTruthy() expect(screen.getByText('Option with Icon')).toBeTruthy() }) test('renders option without icon', () => { const options = [ { label: 'Option without Icon', onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) expect(screen.getByText('Option without Icon')).toBeTruthy() }) test('closes menu when clicking outside', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') fireEvent.click(button) // Menu should be open expect(screen.getByText('Option 1')).toBeTruthy() // Click outside (on the backdrop) const backdrop = document.querySelector('.MuiBackdrop-root') if (backdrop) { fireEvent.click(backdrop) } // Menu should be closed expect(screen.queryByRole('menu')).toBeNull() }) test('handles multiple option clicks correctly', () => { const onClick1 = vi.fn() const onClick2 = vi.fn() const options = [ { label: 'Option 1', onClick: onClick1, }, { label: 'Option 2', onClick: onClick2, }, ] render() // Open menu and click first option const button = screen.getByLabelText('Options') fireEvent.click(button) fireEvent.click(screen.getByText('Option 1')) expect(onClick1).toHaveBeenCalledTimes(1) expect(onClick2).not.toHaveBeenCalled() // Open menu again and click second option fireEvent.click(button) fireEvent.click(screen.getByText('Option 2')) expect(onClick1).toHaveBeenCalledTimes(1) expect(onClick2).toHaveBeenCalledTimes(1) }) test('renders MoreVert icon', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() // Check that the button is rendered const button = screen.getByLabelText('Options') expect(button).toBeTruthy() }) test('menu has correct attributes', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() const button = screen.getByLabelText('Options') expect(button.getAttribute('aria-label')).toBe('Options') expect(button.getAttribute('aria-controls')).toBe('options-menu') expect(button.getAttribute('aria-haspopup')).toBe('true') }) })