@mozaic-ds/vue
Version:
Mozaic-Vue is the Vue.js implementation of ADEO Design system
112 lines (97 loc) • 3.69 kB
text/typescript
import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import MBuiltInMenu, { type MenuItem } from './MBuiltInMenu.vue';
import { defineComponent } from 'vue';
// Dummy icon component to simulate passed icon
const DummyIcon = defineComponent({
name: 'DummyIcon',
template: '<svg class="dummy-icon" />',
});
const items: MenuItem[] = [
{ label: 'Item 1', icon: DummyIcon },
{ label: 'Item 2', href: '/foo', target: '_blank' },
{ label: 'Item 3' },
];
describe('MBuiltInMenu', () => {
it('renders all item labels', () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
const labels = wrapper.findAll('.mc-built-in-menu__label');
expect(labels.length).toBe(3);
expect(labels[0].text()).toBe('Item 1');
expect(labels[1].text()).toBe('Item 2');
expect(labels[2].text()).toBe('Item 3');
});
it('uses correct tags for link and buttons', () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
expect(wrapper.findAll('a').length).toBe(1);
expect(wrapper.findAll('button').length).toBe(2);
const links = wrapper.findAll('.mc-built-in-menu__link');
const buttons = wrapper.findAll('.mc-built-in-menu__button');
expect(links.length).toBe(1);
expect(buttons.length).toBe(2);
});
it('renders an anchor with href and provided target', () => {
const items: MenuItem[] = [
{ label: 'Anchor', href: '/path', target: '_blank' },
];
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
const a = wrapper.find('a');
expect(a).not.toBeNull();
expect(a?.attributes('href')).toBe('/path');
expect(a?.attributes('target')).toBe('_blank');
});
it('renders a router-link with to and default target when target omitted', () => {
const items: MenuItem[] = [{ label: 'Router', to: '/route' }];
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
const routerLink = wrapper.find('router-link');
expect(routerLink).not.toBeNull();
expect(routerLink?.attributes('to')).toBe('/route');
expect(routerLink?.attributes('target')).toBe('_self');
});
it('emits update:modelValue when an item is clicked', async () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
const menuItems = wrapper.findAll(
'.mc-built-in-menu__button, .mc-built-in-menu__link',
);
await menuItems[1].trigger('click');
const emitted = wrapper.emitted('update:modelValue');
expect(emitted).toBeTruthy();
expect(emitted![0][0]).toBe(1);
});
it('marks the selected item with aria-current and selected class', () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: 2 },
});
const lis = wrapper.findAll('li');
const selectedItem = lis[2];
expect(selectedItem.attributes('aria-current')).toBe('true');
expect(selectedItem.classes()).toContain(
'mc-built-in-menu__item--selected',
);
});
it('renders provided icon component inside the item', () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined },
});
const firstItem = wrapper.findAll('li')[0];
expect(firstItem.find('.dummy-icon').exists()).toBe(true);
});
it('applies outlined class when outlined prop is true', () => {
const wrapper = mount(MBuiltInMenu, {
props: { items, modelValue: undefined, outlined: true },
});
expect(wrapper.find('nav').classes()).toContain(
'mc-built-in-menu--outlined',
);
});
});