UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

368 lines (312 loc) 10.2 kB
import { mount, flushPromises } from '@vue/test-utils' import { h } from 'vue' import { CAutocompleteOptions } from '../CAutocompleteOptions' const mockOptions = [ { label: 'Apple', value: 1 }, { label: 'Banana', value: 2 }, { label: 'Cherry', value: 3 }, { label: 'Date', value: 4 }, ] const mockOptionsWithGroups = [ { label: 'Fruits', options: [ { label: 'Apple', value: 1 }, { label: 'Banana', value: 2 }, ], }, { label: 'Vegetables', options: [ { label: 'Carrot', value: 3 }, { label: 'Spinach', value: 4 }, ], }, ] describe('CAutocompleteOptions', () => { test('loads and displays CAutocompleteOptions component', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) expect(wrapper.html()).toMatchSnapshot() }) test('CAutocompleteOptions renders all options', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) expect(wrapper.text()).toContain('Apple') expect(wrapper.text()).toContain('Banana') expect(wrapper.text()).toContain('Cherry') expect(wrapper.text()).toContain('Date') }) test('CAutocompleteOptions renders option groups', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptionsWithGroups, selected: null, }, }) expect(wrapper.text()).toContain('Fruits') expect(wrapper.text()).toContain('Vegetables') expect(wrapper.text()).toContain('Apple') expect(wrapper.text()).toContain('Carrot') }) test('CAutocompleteOptions marks selected option', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: mockOptions[0], }, }) const selectedOption = wrapper.find('.autocomplete-option.selected') expect(selectedOption.exists()).toBe(true) expect(selectedOption.text()).toContain('Apple') }) test('CAutocompleteOptions calls onOptionClick when option clicked', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) const option = wrapper.find('.autocomplete-option') await option.trigger('click') await flushPromises() expect(wrapper.emitted('optionClick')).toBeTruthy() expect(wrapper.emitted('optionClick')![0]).toEqual([mockOptions[0]]) }) test('CAutocompleteOptions handles Enter key press', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) const option = wrapper.find('.autocomplete-option') await option.trigger('keydown', { key: 'Enter' }) await flushPromises() expect(wrapper.emitted('optionClick')).toBeTruthy() expect(wrapper.emitted('optionClick')![0]).toEqual([mockOptions[0]]) }) test('CAutocompleteOptions handles Space key press', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) const option = wrapper.find('.autocomplete-option') await option.trigger('keydown', { code: 'Space' }) await flushPromises() expect(wrapper.emitted('optionClick')).toBeTruthy() expect(wrapper.emitted('optionClick')![0]).toEqual([mockOptions[0]]) }) test('CAutocompleteOptions navigates with arrow keys', async () => { // Mock the DOM navigation functions const mockGetNextSibling = vi.fn().mockReturnValue({ focus: vi.fn(), }) // Mock the utils import vi.mock('../../utils', () => ({ getNextSibling: mockGetNextSibling, getPreviousSibling: vi.fn(), })) const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, attachTo: document.body, }) const firstOption = wrapper.find('.autocomplete-option') await firstOption.trigger('keydown', { key: 'ArrowDown' }) expect(mockGetNextSibling).toHaveBeenCalled() }) test('CAutocompleteOptions shows no results message', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: [], selected: null, searchNoResultsLabel: 'No options found', }, }) expect(wrapper.text()).toContain('No options found') expect(wrapper.find('.autocomplete-options-empty').exists()).toBe(true) }) test('CAutocompleteOptions highlights search matches', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, highlightOptionsOnSearch: true, searchValue: 'app', }, }) const option = wrapper.find('.autocomplete-option') expect(option.exists()).toBe(true) // Check if the option contains highlighted content expect(option.html()).toContain('Apple') }) test('CAutocompleteOptions uses custom option template', async () => { const customTemplate = (option: any) => h('div', { class: 'custom-option' }, `${option.label} - ${option.value}`) const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, optionsTemplate: customTemplate, }, }) expect(wrapper.text()).toContain('Apple - 1') expect(wrapper.text()).toContain('Banana - 2') }) test('CAutocompleteOptions uses custom group template', async () => { const customGroupTemplate = (group: any) => h('div', { class: 'custom-group' }, group.label.toUpperCase()) const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptionsWithGroups, selected: null, optionsGroupsTemplate: customGroupTemplate, }, }) expect(wrapper.text()).toContain('FRUITS') expect(wrapper.text()).toContain('VEGETABLES') }) test('CAutocompleteOptions shows loading state', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, loading: true, }, global: { stubs: { CElementCover: true, }, }, }) expect(wrapper.findComponent({ name: 'CElementCover' }).exists()).toBe(true) }) test('CAutocompleteOptions renders with virtual scroller', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, virtualScroller: true, visibleItems: 2, }, global: { stubs: { CVirtualScroller: true, }, }, }) expect(wrapper.findComponent({ name: 'CVirtualScroller' }).exists()).toBe(true) }) test('CAutocompleteOptions sets max height', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, optionsMaxHeight: 200, }, }) const optionsContainer = wrapper.find('.autocomplete-options') expect(optionsContainer.attributes('style')).toContain('max-height: 200px') }) test('CAutocompleteOptions marks disabled options', async () => { const optionsWithDisabled = [ { label: 'Apple', value: 1 }, { label: 'Banana', value: 2, disabled: true }, ] const wrapper = mount(CAutocompleteOptions, { props: { options: optionsWithDisabled, selected: null, }, }) const disabledOption = wrapper.find('.autocomplete-option.disabled') expect(disabledOption.exists()).toBe(true) expect(disabledOption.text()).toContain('Banana') }) test('CAutocompleteOptions has correct accessibility attributes', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: mockOptions, selected: null, }, }) const listbox = wrapper.find('[role="listbox"]') expect(listbox.exists()).toBe(true) const options = wrapper.findAll('.autocomplete-option') expect(options).toHaveLength(4) options.forEach((option) => { expect(option.attributes('tabindex')).toBe('0') }) }) test('CAutocompleteOptions handles string options', async () => { const stringOptions = ['Apple', 'Banana', 'Cherry'] const wrapper = mount(CAutocompleteOptions, { props: { options: stringOptions, selected: null, }, }) expect(wrapper.text()).toContain('Apple') expect(wrapper.text()).toContain('Banana') expect(wrapper.text()).toContain('Cherry') }) test('CAutocompleteOptions handles mixed option types', async () => { const mixedOptions = [ 'Simple String', { label: 'Object Option', value: 1 }, { label: 'Group', options: [ { label: 'Grouped Option', value: 2 }, ], }, ] const wrapper = mount(CAutocompleteOptions, { props: { options: mixedOptions, selected: null, }, }) expect(wrapper.text()).toContain('Simple String') expect(wrapper.text()).toContain('Object Option') expect(wrapper.text()).toContain('Group') expect(wrapper.text()).toContain('Grouped Option') }) test('CAutocompleteOptions emits optionClick for all option types', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: ['String Option'], selected: null, }, }) const option = wrapper.find('.autocomplete-option') await option.trigger('click') await flushPromises() expect(wrapper.emitted('optionClick')).toBeTruthy() expect(wrapper.emitted('optionClick')![0]).toEqual(['String Option']) }) test('CAutocompleteOptions handles empty searchNoResultsLabel correctly', async () => { const wrapper = mount(CAutocompleteOptions, { props: { options: [], selected: null, searchNoResultsLabel: false, }, }) expect(wrapper.find('.autocomplete-options-empty').exists()).toBe(true) expect(wrapper.find('.autocomplete-options-empty').text()).toBe('false') }) })