/** * Tests for the ContextMenu component. */ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { render } from '../utils'; import { ContextMenu } from '../../components/ContextMenu'; describe('ContextMenu', () => { const mockOnClose = vi.fn(); const menuItems = [ { label: 'Edit', onClick: vi.fn() }, { label: 'Delete', onClick: vi.fn(), danger: true }, { label: 'Download', onClick: vi.fn() }, ]; beforeEach(() => { vi.clearAllMocks(); }); describe('rendering', () => { it('renders menu items', () => { render( ); expect(screen.getByText('Edit')).toBeInTheDocument(); expect(screen.getByText('Delete')).toBeInTheDocument(); expect(screen.getByText('Download')).toBeInTheDocument(); }); it('positions menu at specified coordinates', () => { render( ); // Menu should be rendered with items visible expect(screen.getByText('Edit')).toBeInTheDocument(); }); }); describe('interactions', () => { it('calls onClick when item is clicked', async () => { const user = userEvent.setup(); render( ); await user.click(screen.getByText('Edit')); expect(menuItems[0].onClick).toHaveBeenCalled(); }); it('calls onClose after item click', async () => { const user = userEvent.setup(); render( ); await user.click(screen.getByText('Edit')); expect(mockOnClose).toHaveBeenCalled(); }); }); describe('styling', () => { it('applies danger styling', () => { render( ); // Delete item has danger: true, so should have red styling const deleteButton = screen.getByText('Delete'); expect(deleteButton).toBeInTheDocument(); }); }); describe('dividers', () => { it('supports divider property on items', () => { // Just verify the ContextMenuItem interface accepts divider prop const itemsWithDivider = [ { label: 'Edit', onClick: vi.fn() }, { label: 'Copy', onClick: vi.fn(), divider: true }, ]; // Interface should accept these items without error expect(itemsWithDivider[1].divider).toBe(true); }); }); });