import { render, screen, fireEvent } from '@testing-library/react' import { CommandResultItem } from '../CommandResultItem' // lucide-react icons are SVGs — mock them as simple elements so tests are // not sensitive to SVG implementation details while still being renderable. jest.mock('lucide-react', () => ({ Search: (props: React.SVGProps) => ( ), ArrowRight: (props: React.SVGProps) => ( ), })) const StarIcon = (props: React.SVGProps) => ( ) describe('CommandResultItem', () => { const defaultProps = { label: 'Go to Dashboard', selected: false, onClick: jest.fn(), } beforeEach(() => { jest.clearAllMocks() }) describe('label', () => { it('renders the label text', () => { render() expect(screen.getByText('Go to Dashboard')).toBeInTheDocument() }) }) describe('detail', () => { it('renders detail text when provided', () => { render() expect(screen.getByText('Overview of metrics')).toBeInTheDocument() }) it('does not render detail element when omitted', () => { render() // Only the label paragraph should be present; no second

const paragraphs = document.querySelectorAll('p') expect(paragraphs).toHaveLength(1) }) }) describe('shortcut', () => { it('renders the shortcut in a kbd element when provided', () => { render() const kbd = screen.getByText('⌘K') expect(kbd.tagName).toBe('KBD') }) it('does not render a kbd element when shortcut is omitted', () => { const { container } = render() expect(container.querySelector('kbd')).not.toBeInTheDocument() }) }) describe('icon', () => { it('renders the provided icon', () => { render() expect(screen.getByTestId('icon-star')).toBeInTheDocument() }) it('falls back to Search icon when no icon prop is given', () => { render() expect(screen.getByTestId('icon-search')).toBeInTheDocument() }) }) describe('showArrow', () => { it('does not render ArrowRight by default', () => { render() expect(screen.queryByTestId('icon-arrow-right')).not.toBeInTheDocument() }) it('renders ArrowRight when showArrow is true', () => { render() expect(screen.getByTestId('icon-arrow-right')).toBeInTheDocument() }) }) describe('selected state', () => { it('sets aria-selected="true" when selected', () => { render() const item = screen.getByRole('option') expect(item).toHaveAttribute('aria-selected', 'true') }) it('sets aria-selected="false" when not selected', () => { render() const item = screen.getByRole('option') expect(item).toHaveAttribute('aria-selected', 'false') }) it('applies bg-blue-50 highlight class when selected', () => { render() const item = screen.getByRole('option') expect(item.className).toMatch(/bg-blue-50/) }) it('does not apply bg-blue-50 when not selected', () => { render() const item = screen.getByRole('option') expect(item.className).not.toMatch(/bg-blue-50/) }) }) describe('colorClass', () => { it('applies the default color class to the icon container', () => { const { container } = render() const iconContainer = container.querySelector('.w-8.h-8') expect(iconContainer?.className).toMatch(/bg-gray-100/) expect(iconContainer?.className).toMatch(/text-gray-600/) }) it('applies a custom colorClass to the icon container', () => { const { container } = render( ) const iconContainer = container.querySelector('.w-8.h-8') expect(iconContainer?.className).toMatch(/bg-blue-100/) expect(iconContainer?.className).toMatch(/text-blue-600/) }) }) describe('onClick', () => { it('fires onClick when the item is clicked', () => { const onClick = jest.fn() render() fireEvent.click(screen.getByRole('option')) expect(onClick).toHaveBeenCalledTimes(1) }) it('does not fire onClick when a different element is clicked', () => { const onClick = jest.fn() render(

) fireEvent.click(screen.getByTestId('other')) expect(onClick).not.toHaveBeenCalled() }) }) describe('label typography without detail', () => { it('uses text-gray-700 on label when no detail is present', () => { render() const label = screen.getByText('Go to Dashboard') expect(label.className).toMatch(/text-gray-700/) }) it('uses text-gray-900 on label when detail is present', () => { render() const label = screen.getByText('Go to Dashboard') expect(label.className).toMatch(/text-gray-900/) }) }) })