import { flushPromises, mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import SearchableSelect from '../../components/SearchableSelect.vue'
const options = [
{ value: 'alpha', label: 'Alpha', description: 'First option' },
{ value: 'beta', label: 'Beta', disabled: true, disabledReason: 'Unavailable' },
{ value: 'gamma', label: 'Gamma', meta: 'count' },
]
describe('SearchableSelect', () => {
it('filters rich options and explains disabled choices', async () => {
const wrapper = mount(SearchableSelect, { props: { options } })
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
await wrapper.get('input').setValue('bet')
expect(wrapper.findAll('[role="option"]')).toHaveLength(1)
expect(wrapper.get('[role="option"]').text()).toContain('Unavailable')
expect(wrapper.get('[role="option"]').attributes('aria-disabled')).toBe('true')
})
it('skips disabled options during keyboard selection', async () => {
const wrapper = mount(SearchableSelect, { props: { options } })
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
await flushPromises()
await wrapper.get('input').trigger('keydown', { key: 'ArrowDown' })
await wrapper.get('input').trigger('keydown', { key: 'Enter' })
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['gamma'])
expect(wrapper.get('.mint-searchable-select__trigger').text()).toContain('Select an option')
})
it('keeps footer actions reachable until focus leaves the select', async () => {
const wrapper = mount(SearchableSelect, {
attachTo: document.body,
props: { options },
slots: { footer: '' },
})
const outside = document.createElement('button')
document.body.append(outside)
try {
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
await wrapper.get('input').trigger('keydown', { key: 'Tab' })
expect(wrapper.find('.mint-searchable-select__footer').exists()).toBe(true)
const footer = wrapper.get('.mint-searchable-select__footer button')
footer.element.focus()
await flushPromises()
expect(document.activeElement).toBe(footer.element)
expect(wrapper.find('[role="listbox"]').exists()).toBe(true)
outside.focus()
await flushPromises()
expect(wrapper.find('[role="listbox"]').exists()).toBe(false)
} finally {
wrapper.unmount()
outside.remove()
}
})
it('should render the panel on the shared popover surface when opened', async () => {
const wrapper = mount(SearchableSelect, { props: { options } })
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
expect(wrapper.get('.mint-searchable-select__panel').classes()).toContain('mint-popover')
})
it('should mark the selected option as a selected menu item when opened', async () => {
const wrapper = mount(SearchableSelect, { props: { options, modelValue: 'alpha' } })
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
expect(wrapper.findAll('[role="option"]')[0].classes()).toContain('mint-menu-item--selected')
})
it('should reserve the check column on unselected options when opened', async () => {
const wrapper = mount(SearchableSelect, { props: { options, modelValue: 'alpha' } })
await wrapper.get('.mint-searchable-select__trigger').trigger('click')
expect(wrapper.findAll('[role="option"]')[2].find('.mint-menu-item__check').exists()).toBe(true)
})
})