import { render, fireEvent, screen } from '@testing-library/react' import { describe, it, expect } from 'vitest' import { MultiSelector, MultiSelectorContent, MultiSelectorInput, MultiSelectorItem, MultiSelectorList, MultiSelectorTrigger, } from './index' import { useState } from 'react' // This fixes a "ReferenceError: ResizeObserver is not defined" error in the test class ResizeObserver { observe() {} unobserve() {} disconnect() {} } global.ResizeObserver = ResizeObserver function MultiSelectDemo() { const [selectedValues, setSelectedValues] = useState([]) return ( Apple Banana Cherry Date Elderberrie Fig Grape Kiwi Mango Strawberry ) } describe('multi-select', () => { it('opens the dropdown when the MultiSelectorTrigger is clicked', () => { render() const trigger = screen.getByRole('combobox') expect(screen.queryByText('Apple')).not.toBeInTheDocument() // Dropdown should be closed initially fireEvent.click(trigger) // Click on the trigger to open expect(screen.getByText('Apple')).toBeInTheDocument() // Apple should be visible in the dropdown }) it('adds and removes value when toggling MultiSelectorItem', () => { render() const trigger = screen.getByRole('combobox') fireEvent.click(trigger) // Open the dropdown const appleItem = screen.getByText('Apple') fireEvent.click(appleItem) // Select the "Apple" item expect(trigger).toHaveTextContent('Apple') // "Apple" should appear in the selected values fireEvent.click(appleItem) // Select the "Apple" item expect(trigger).not.toHaveTextContent('Apple') // "Apple" should not be selected anymore }) it('closes the dropdown when clicking outside the component', () => { render() const trigger = screen.getByRole('combobox') fireEvent.click(trigger) // Open the dropdown expect(screen.getByText('Apple')).toBeInTheDocument() // Ensure it's open fireEvent.click(document.body) // Click outside the component setTimeout(() => { expect(screen.queryByText('Apple')).not.toBeInTheDocument() // The dropdown should be closed }, 100) }) it('removes the last value when hitting Backspace', () => { render() const trigger = screen.getByRole('combobox') fireEvent.click(trigger) // Open the dropdown const appleItem = screen.getByText('Apple') fireEvent.click(appleItem) // Select the "Apple" item expect(trigger).toHaveTextContent('Apple') // "Apple" should be in the selected values fireEvent.keyDown(trigger, { key: 'Backspace' }) // Press Backspace expect(trigger).not.toHaveTextContent('Apple') // "Apple" should be removed }) it('supports searching and filtering items', () => { render() const trigger = screen.getByRole('combobox') fireEvent.click(trigger) // Open the dropdown const searchInput = screen.getByPlaceholderText('Search fruits') fireEvent.change(searchInput, { target: { value: 'Ap' } }) // Search for "Ap" expect(screen.getByText('Apple')).toBeInTheDocument() // "Apple" should be visible expect(screen.queryByText('Banana')).not.toBeInTheDocument() // "Banana" should not be visible }) it('prevents selecting disabled items', () => { render() const trigger = screen.getByRole('combobox') fireEvent.click(trigger) // Open the dropdown const disabledItem = screen.getByText('Mango') fireEvent.click(disabledItem) expect(trigger).not.toHaveTextContent('Mango') // Mango should not be selectable }) })