import type { Item } from './index'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import Select, { PortalSelect, SimpleSelect } from './index'
const items: Item[] = [
{ value: 'apple', name: 'Apple' },
{ value: 'banana', name: 'Banana' },
{ value: 'citrus', name: 'Citrus' },
]
describe('Select', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// Rendering and edge behavior for default select.
describe('Rendering', () => {
it('should show the default selected item when defaultValue matches an item', () => {
render(
,
)
expect(screen.getByTitle('Banana')).toBeInTheDocument()
})
})
// User interactions for default select.
describe('User Interactions', () => {
it('should call onSelect when choosing an option from default select', async () => {
const user = userEvent.setup()
const onSelect = vi.fn()
render(
,
)
await user.click(screen.getByTitle('Banana'))
await user.click(screen.getByText('Citrus'))
expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
value: 'citrus',
name: 'Citrus',
}))
})
it('should not open or select when default select is disabled', async () => {
const user = userEvent.setup()
const onSelect = vi.fn()
render(
,
)
await user.click(screen.getByTitle('Banana'))
expect(screen.queryByText('Citrus')).not.toBeInTheDocument()
expect(onSelect).not.toHaveBeenCalled()
})
})
})
describe('SimpleSelect', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// Rendering and placeholder fallback behavior.
describe('Rendering', () => {
it('should render i18n placeholder when no selection exists', () => {
render(
,
)
expect(screen.getByText(/select/i)).toBeInTheDocument()
})
it('should render custom placeholder when provided', () => {
render(
,
)
expect(screen.getByText('Pick one')).toBeInTheDocument()
})
})
// User interactions and callback behavior.
describe('User Interactions', () => {
it('should call onSelect and update display when an option is chosen', async () => {
const user = userEvent.setup()
const onSelect = vi.fn()
render(
,
)
await user.click(screen.getByRole('button'))
await user.click(screen.getByText('Apple'))
expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
value: 'apple',
name: 'Apple',
}))
expect(screen.getByText('Apple')).toBeInTheDocument()
})
it('should pass open state into renderTrigger', async () => {
const user = userEvent.setup()
render(
(
{`${selected?.name ?? 'none'}-${open ? 'open' : 'closed'}`}
)}
/>,
)
expect(screen.getByText('none-closed')).toBeInTheDocument()
await user.click(screen.getByText('none-closed'))
expect(screen.getByText('none-open')).toBeInTheDocument()
})
})
})
describe('PortalSelect', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// Rendering for edge case when value is empty.
describe('Rendering', () => {
it('should show placeholder when value is empty', () => {
render(
,
)
expect(screen.getByText(/select/i)).toBeInTheDocument()
})
})
// Interaction and readonly behavior.
describe('User Interactions', () => {
it('should call onSelect when choosing an option from portal dropdown', async () => {
const user = userEvent.setup()
const onSelect = vi.fn()
render(
,
)
await user.click(screen.getByText(/select/i))
await user.click(screen.getByText('Citrus'))
expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
value: 'citrus',
name: 'Citrus',
}))
})
it('should not open the portal dropdown when readonly is true', async () => {
const user = userEvent.setup()
render(
,
)
await user.click(screen.getByText(/select/i))
expect(screen.queryByTitle('Citrus')).not.toBeInTheDocument()
})
})
})