import { describe, it, expect, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/svelte'; import { Check, X, Trash2 } from 'lucide-svelte'; import RowActionsMenu from './RowActionsMenu.svelte'; describe('RowActionsMenu', () => { it('renders the primary action inline', () => { const onApprove = vi.fn(); render(RowActionsMenu, { props: { primary: { icon: Check, label: 'Approve', onclick: onApprove }, secondary: [] } }); expect(screen.getByText('Approve')).toBeInTheDocument(); }); it('fires the primary action onclick', async () => { const onApprove = vi.fn(); render(RowActionsMenu, { props: { primary: { icon: Check, label: 'Approve', onclick: onApprove }, secondary: [] } }); await fireEvent.click(screen.getByText('Approve')); expect(onApprove).toHaveBeenCalledOnce(); }); it('renders secondary action labels and exposes the overflow trigger', () => { render(RowActionsMenu, { props: { primary: { icon: Check, label: 'Approve', onclick: vi.fn() }, secondary: [ { icon: X, label: 'Reassign', onclick: vi.fn() }, { icon: Trash2, label: 'Delete', onclick: vi.fn(), danger: true } ] } }); // Both inline (md:flex) and overflow-trigger (md:hidden) markup are // present in jsdom; the test confirms labels exist and the overflow // trigger is in the DOM. expect(screen.getAllByText('Reassign').length).toBeGreaterThan(0); expect(screen.getAllByText('Delete').length).toBeGreaterThan(0); expect(screen.getByLabelText('More actions')).toBeInTheDocument(); }); it('opens the overflow menu when ⋮ is clicked', async () => { render(RowActionsMenu, { props: { primary: { icon: Check, label: 'Approve', onclick: vi.fn() }, secondary: [{ icon: X, label: 'Reassign', onclick: vi.fn() }] } }); const trigger = screen.getByLabelText('More actions'); expect(trigger.getAttribute('aria-expanded')).toBe('false'); await fireEvent.click(trigger); expect(trigger.getAttribute('aria-expanded')).toBe('true'); }); it('omits the overflow trigger when secondary is empty', () => { render(RowActionsMenu, { props: { primary: { icon: Check, label: 'Approve', onclick: vi.fn() }, secondary: [] } }); expect(screen.queryByLabelText('More actions')).not.toBeInTheDocument(); }); });