import { mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import AppTopBarPillNavInternal from '../../components/internal/AppTopBarPillNavInternal.vue' describe('AppTopBarPillNavInternal', () => { it('accepts string shorthand items', async () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { currentItemId: 'Overview', items: ['Overview', 'Analysis'], }, }) expect(wrapper.findAll('.mint-pill-nav__item').map(item => item.text())).toEqual([ 'Overview', 'Analysis', ]) await wrapper.findAll('.mint-pill-nav__item')[1].trigger('click') expect(wrapper.emitted('select')).toEqual([[{ id: 'Analysis', label: 'Analysis' }]]) }) it('emits select for button items but not linked items', async () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { currentItemId: 'overview', items: [ { id: 'overview', label: 'Overview' }, { id: 'docs', label: 'Docs', href: '/docs' }, ], }, }) await wrapper.findAll('.mint-pill-nav__item')[0].trigger('click') await wrapper.findAll('.mint-pill-nav__item')[1].trigger('click') expect(wrapper.emitted('select')).toEqual([[{ id: 'overview', label: 'Overview' }]]) }) it('renders SVG icons from item metadata', () => { const icon = ['M4 12h16', 'M12 4v16'] const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [ { id: 'run', label: 'Run', icon }, { id: 'results', label: 'Results', icon: 'not-a-path' }, ], }, }) const icons = wrapper.findAll('.mint-pill-nav__icon') expect(icons).toHaveLength(1) expect(icons[0].findAll('path').map(path => path.attributes('d'))).toEqual(icon) expect(wrapper.findAll('.mint-pill-nav__item').map(item => item.text())).toEqual([ 'Run', 'Results', ]) }) it('prevents disabled link navigation and selection', async () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [ { id: 'docs', label: 'Docs', href: '/docs', disabled: true }, ], }, }) const link = wrapper.get('a') expect(link.attributes('href')).toBeUndefined() expect(link.attributes('aria-disabled')).toBe('true') await link.trigger('click') expect(wrapper.emitted('select')).toBeUndefined() }) it('supports dropdown child items for grouped pill navigation', async () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { currentItemId: 'pca', items: [ { id: 'charts', label: 'Charts' }, { id: 'visualize', label: 'Visualize', children: [ { id: 'pca', label: 'PCA', description: 'Principal component analysis' }, { id: 'heatmap', label: 'Heatmap', description: 'Metabolite heatmap' }, ], }, ], }, }) const visualizeButton = wrapper.findAll('.mint-pill-nav__item')[1] expect(visualizeButton.classes()).toContain('mint-pill-nav__item--active') expect(wrapper.find('.mint-pill-nav__dropdown').exists()).toBe(false) await visualizeButton.trigger('click') expect(wrapper.find('.mint-pill-nav__dropdown').exists()).toBe(true) expect(wrapper.findAll('.mint-pill-nav__dropdown-item').map(item => item.text())).toEqual([ 'PCAPrincipal component analysis', 'HeatmapMetabolite heatmap', ]) await wrapper.findAll('.mint-pill-nav__dropdown-item')[1].trigger('click') expect(wrapper.emitted('option-select')).toEqual([ [ { id: 'heatmap', label: 'Heatmap', description: 'Metabolite heatmap' }, { id: 'visualize', label: 'Visualize', children: [ { id: 'pca', label: 'PCA', description: 'Principal component analysis' }, { id: 'heatmap', label: 'Heatmap', description: 'Metabolite heatmap' }, ], }, ], ]) }) it('should render option dropdowns on the shared popover surface when opened', async () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [{ id: 'visualize', label: 'Visualize', children: [{ id: 'pca', label: 'PCA' }] }], }, }) await wrapper.get('.mint-pill-nav__item').trigger('click') expect(wrapper.get('.mint-pill-nav__dropdown').classes()).toContain('mint-popover') }) it('should render a dot when the item sets dot', () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [ { id: 'home', label: 'Home' }, { id: 'instruments', label: 'Instruments', dot: true }, ], }, }) expect(wrapper.findAll('.mint-pill-nav__item')[1].find('.mint-pill-nav__dot').exists()).toBe(true) }) it('should name the dot for assistive technology', () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [{ id: 'instruments', label: 'Instruments', dot: true }] }, }) const dot = wrapper.get('.mint-pill-nav__dot') expect([dot.attributes('role'), dot.attributes('aria-label'), dot.attributes('aria-hidden')]).toEqual(['img', 'Needs attention', undefined]) }) it('should not render a dot when the item leaves dot unset', () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { items: [{ id: 'home', label: 'Home' }] }, }) expect(wrapper.find('.mint-pill-nav__dot').exists()).toBe(false) }) it('should label a dropdown parent with its active child when a child is current', () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { currentItemId: 'projects', items: [{ id: 'records', label: 'Records', children: [ { id: 'experiments', label: 'Experiments' }, { id: 'projects', label: 'Projects' }, ], }], }, }) expect(wrapper.find('.mint-pill-nav__item').text()).toBe('Projects') }) it('should label a dropdown parent with its own label when no child is current', () => { const wrapper = mount(AppTopBarPillNavInternal, { props: { currentItemId: 'home', items: [{ id: 'records', label: 'Records', children: [{ id: 'projects', label: 'Projects' }], }], }, }) expect(wrapper.find('.mint-pill-nav__item').text()).toBe('Records') }) })