import { mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import ResourcePickerListInternal from '../../components/internal/ResourcePickerListInternal.vue' interface Item { id: number code: string name: string } const items: Item[] = [ { id: 1, code: 'EXP-042', name: 'Liver microsome stability' }, { id: 2, code: 'EXP-041', name: 'Plasma protein binding' }, ] function setup(props: Record = {}, slots: Record = {}) { return mount(ResourcePickerListInternal, { props: { items, itemKey: (item: unknown) => (item as Item).id, describe: (item: unknown) => ({ code: (item as Item).code, title: (item as Item).name, meta: ['Zhang'], date: '09-24', }), search: '', label: 'Experiments', ...props, }, slots, }) } describe('ResourcePickerListInternal', () => { it('should render one option per item', () => { expect(setup().findAll('[role="option"]')).toHaveLength(2) }) it('should render the code in its own mono element', () => { expect(setup().get('.mint-resource-picker__code').text()).toBe('EXP-042') }) it('should render the code as the shared gray code pill', () => { expect(setup().get('.mint-resource-picker__code').classes()).toContain('mint-exp-code') }) it('should tint the status by its variant', () => { const wrapper = setup({ describe: (item: unknown) => ({ title: (item as Item).name, status: { label: 'Completed', variant: 'success' } }), }) expect(wrapper.get('.mint-resource-picker__status').classes()).toContain('mint-resource-picker__status--success') }) it('should keep the title line to the title alone', () => { expect(setup().get('.mint-resource-picker__title').text()).toBe('Liver microsome stability') }) it('should lead the second line with the code and meta', () => { expect(setup().get('.mint-resource-picker__meta').text()).toBe('EXP-042Zhang') }) it('should put the date in the right-hand column', () => { expect(setup().get('.mint-resource-picker__aside .mint-resource-picker__date').text()).toBe('09-24') }) it('should mark the selected row', () => { const wrapper = setup({ selectedKey: 2 }) expect(wrapper.findAll('[role="option"]')[1]!.attributes('aria-selected')).toBe('true') }) it('should fill the selected row only', () => { expect(setup({ selectedKey: 2 }).findAll('.mint-resource-picker__row--selected')).toHaveLength(1) }) it('should emit select when a row is clicked', async () => { const wrapper = setup() await wrapper.findAll('[role="option"]')[1]!.trigger('click') expect(wrapper.emitted('select')?.[0]).toEqual([items[1]]) }) it('should point the search at the arrow-highlighted option', async () => { const wrapper = setup() await wrapper.trigger('keydown', { key: 'ArrowDown' }) expect(wrapper.get('input').attributes('aria-activedescendant')).toBe( wrapper.findAll('[role="option"]')[0]!.attributes('id'), ) }) it('should emit the highlighted item on Enter', async () => { const wrapper = setup() await wrapper.trigger('keydown', { key: 'ArrowDown' }) await wrapper.trigger('keydown', { key: 'ArrowDown' }) await wrapper.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('select')?.[0]).toEqual([items[1]]) }) it('should leave Enter to a control inside the row actions', async () => { const wrapper = setup({}, { actions: '' }) await wrapper.trigger('keydown', { key: 'ArrowDown' }) await wrapper.get('.row-action').trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('select')).toBeUndefined() }) it('should emit the typed search text', async () => { const wrapper = setup() await wrapper.get('input').setValue('plasma') expect(wrapper.emitted('update:search')?.[0]).toEqual(['plasma']) }) it('should head each group with its label and a count', () => { const wrapper = setup({ groups: [{ label: 'Recent', items }] }) expect(wrapper.get('.mint-resource-picker__group').text()).toBe('Recent2') }) it('should hide the rows of a collapsed group', async () => { const wrapper = setup({ groups: [{ label: 'Recent', items }] }) await wrapper.get('.mint-resource-picker__group').trigger('click') expect(wrapper.findAll('[role="option"]')).toHaveLength(0) }) it('should show skeleton rows while loading', () => { expect(setup({ loading: true }).findAll('.mint-resource-picker__skeleton-row')).toHaveLength(4) }) it('should show the error as an alert', () => { expect(setup({ error: 'Could not load' }).get('[role="alert"]').text()).toBe('Could not load') }) it('should show the empty title when there are no items', () => { expect(setup({ items: [], emptyTitle: 'Nothing here' }).text()).toContain('Nothing here') }) it('should leave Enter to a group header while a row is highlighted', async () => { const wrapper = setup({ groups: [{ label: 'Recent', items }] }) await wrapper.findAll('[role="option"]')[0]!.trigger('mouseenter') await wrapper.get('.mint-resource-picker__group').trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('select')).toBeUndefined() }) })