@mozaic-ds/vue
Version:
Mozaic-Vue is the Vue.js implementation of ADEO Design system
128 lines (107 loc) • 3.91 kB
text/typescript
import { mount } from '@vue/test-utils';
import { describe, it, expect, vi, beforeEach } from 'vitest';
const showFloatingItemMock = vi.fn();
const hideFloatingItemMock = vi.fn();
vi.mock('../sidebar/use-floating-item.composable', () => ({
useFloatingItem: () => ({
showFloatingItem: showFloatingItemMock,
hideFloatingItem: hideFloatingItemMock,
}),
}));
import MSidebarNavItem from './MSidebarNavItem.vue';
import { h } from 'vue';
import { EXPANDED_SIDEBAR_KEY, SUB_ITEM_KEY } from '../sidebar/MSidebar.const';
const DummyIcon = {
name: 'DummyIcon',
render() {
return h('svg', { class: 'dummy-icon' });
},
};
describe('MSidebarNavItem', () => {
it('renders label, href and aria-label', () => {
const wrapper = mount(MSidebarNavItem, {
props: { label: 'Home', href: '/home' },
global: {
provide: { [EXPANDED_SIDEBAR_KEY]: true, [SUB_ITEM_KEY]: false },
},
});
const a = wrapper.get('a');
expect(a.attributes('href')).toBe('/home');
expect(a.attributes('aria-label')).toBe('Home');
expect(wrapper.get('.mc-sidebar__text').text()).toBe('Home');
});
it('renders the passed icon component', () => {
const wrapper = mount(MSidebarNavItem, {
props: { label: 'Item', href: '#', icon: DummyIcon },
global: {
provide: { [EXPANDED_SIDEBAR_KEY]: true, [SUB_ITEM_KEY]: false },
},
});
expect(wrapper.find('.mc-sidebar__icon').exists()).toBe(true);
expect(wrapper.find('.dummy-icon').exists()).toBe(true);
});
it('uses _blank target and shows ExternalLink24 when external is true', () => {
const wrapper = mount(MSidebarNavItem, {
props: { label: 'Ext', href: '/ext', external: true },
global: {
provide: { [EXPANDED_SIDEBAR_KEY]: true, [SUB_ITEM_KEY]: false },
},
});
const a = wrapper.get('a');
expect(a.attributes('target')).toBe('_blank');
});
it('shows Lock24 and locked class when locked is true', () => {
const wrapper = mount(MSidebarNavItem, {
props: { label: 'Locked', href: '/locked', locked: true },
global: {
provide: { [EXPANDED_SIDEBAR_KEY]: true, [SUB_ITEM_KEY]: false },
},
});
const a = wrapper.get('a');
expect(a.classes()).toContain('mc-sidebar__link--locked');
});
it('applies selected class when active is true', () => {
const wrapper = mount(MSidebarNavItem, {
props: { label: 'Active', href: '/active', active: true },
global: {
provide: { [EXPANDED_SIDEBAR_KEY]: true, [SUB_ITEM_KEY]: false },
},
});
const a = wrapper.get('a');
expect(a.classes()).toContain('mc-sidebar__link--selected');
});
describe('Component events', () => {
let wrapper: ReturnType<typeof mount>;
beforeEach(() => {
showFloatingItemMock.mockClear();
hideFloatingItemMock.mockClear();
wrapper = mount(MSidebarNavItem, {
props: { label: 'Item label', href: '#' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: true,
[SUB_ITEM_KEY]: false,
},
},
});
});
it('calls showFloatingItem on mouseenter and focus', async () => {
const anchor = wrapper.find('a');
await anchor.trigger('mouseenter');
await anchor.trigger('focus');
expect(showFloatingItemMock).toHaveBeenCalledTimes(2);
});
it('calls hideFloatingItem on mouseleave and blur', async () => {
const anchor = wrapper.find('a');
await anchor.trigger('mouseleave');
await anchor.trigger('blur');
expect(hideFloatingItemMock).toHaveBeenCalledTimes(2);
});
it('emits click when anchor is clicked', async () => {
const anchor = wrapper.find('a');
await anchor.trigger('click');
expect(wrapper.emitted()).toHaveProperty('click');
expect(wrapper.emitted('click')?.[0]).toHaveLength(1);
});
});
});