@mozaic-ds/vue
Version:
Mozaic-Vue is the Vue.js implementation of ADEO Design system
277 lines (233 loc) • 7.45 kB
text/typescript
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount } from '@vue/test-utils';
import MSidebarFooter from './MSidebarFooter.vue';
import {
TOGGLE_SIDEBAR_KEY,
EXPANDED_SIDEBAR_KEY,
} from '../sidebar/MSidebar.const';
import { nextTick, ref } from 'vue';
const onTriggerKeydown = vi.fn();
const onListboxKeydown = vi.fn();
const hideFloatingItem = vi.fn();
vi.mock('../sidebar/use-floating-item.composable', () => {
return {
useFloatingItem: () => {
const floatingItemIsDisplayed = ref(false);
return {
floatingItemIsDisplayed,
showFloatingItem: () => (floatingItemIsDisplayed.value = true),
hideFloatingItem: () => {
floatingItemIsDisplayed.value = false;
hideFloatingItem();
},
onTriggerKeydown,
onListboxKeydown,
};
},
};
});
vi.mock('../../utils/use-is-mobile.composable.ts', () => {
return {
useIsMobile: () => {
return {
isMobile: false,
};
},
};
});
describe('MSidebarFooter', () => {
const toggleSidebar = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
});
it('does not render profile when no img/title/subtitle provided', () => {
const wrapper = mount(MSidebarFooter, {
global: {
provide: {
[TOGGLE_SIDEBAR_KEY]: vi.fn(),
[EXPANDED_SIDEBAR_KEY]: false,
},
},
});
expect(wrapper.find('.mc-sidebar__footer-profile').exists()).toBe(false);
expect(wrapper.find('button').exists()).toBe(true);
});
it('renders img, title and subtitle when provided', () => {
const props = {
avatar: '/avatar.png',
title: 'John Doe',
subtitle: 'Designer',
href: '/profile',
};
const wrapper = mount(MSidebarFooter, {
props,
global: {
provide: {
[TOGGLE_SIDEBAR_KEY]: vi.fn(),
[EXPANDED_SIDEBAR_KEY]: true,
},
},
});
const profile = wrapper.find('.mc-sidebar__footer-profile');
expect(profile.exists()).toBe(true);
const img = wrapper.find('.mc-sidebar__footer-avatar');
expect(img.exists()).toBe(true);
expect(img.attributes('src')).toBe('/avatar.png');
expect(img.attributes('alt')).toBe('John Doe');
expect(wrapper.find('.mc-sidebar__footer-title').text()).toBe('John Doe');
expect(wrapper.find('.mc-sidebar__footer-subtitle').text()).toBe(
'Designer',
);
});
it('hides expand button when expandable prop is false', () => {
const wrapper = mount(MSidebarFooter, {
props: { expendable: false },
global: {
provide: {
[TOGGLE_SIDEBAR_KEY]: vi.fn(),
[EXPANDED_SIDEBAR_KEY]: false,
},
},
});
expect(wrapper.find('.mc-sidebar__footer-expand').exists()).toBe(false);
});
it('binds aria-expanded and calls toggle function when clicked', async () => {
const toggle = vi.fn();
const wrapper = mount(MSidebarFooter, {
global: {
provide: {
[TOGGLE_SIDEBAR_KEY]: toggle,
[EXPANDED_SIDEBAR_KEY]: true,
},
},
});
const button = wrapper.find('button');
expect(button.attributes('aria-expanded')).toBe('true');
await button.trigger('click');
expect(toggle).toHaveBeenCalled();
});
it('emits "log-out" when log out button is clicked', async () => {
const wrapper = mount(MSidebarFooter, {
props: {
title: 'John Doe',
logOutLabel: 'Log out',
},
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: true,
[TOGGLE_SIDEBAR_KEY]: vi.fn(),
},
stubs: {
MDivider: true,
MButton: true,
MSidebarNavItem: {
template: `
<div data-test="logout" @click="$emit('click')">
Log out
</div>
`,
},
},
},
});
const logoutItem = wrapper.find('[data-test="logout"]');
expect(logoutItem.exists()).toBe(true);
await logoutItem.trigger('click');
expect(wrapper.emitted('log-out')).toBeTruthy();
});
it('shows floating item on mouseenter when collapsed', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const trigger = wrapper.find('button.mc-sidebar__footer-trigger');
expect(trigger.exists()).toBe(true);
expect(trigger.attributes('aria-expanded')).toBe('false');
await trigger.trigger('mouseenter');
await nextTick();
expect(trigger.attributes('aria-expanded')).toBe('true');
});
it('hides floating item on mouseleave and blur when collapsed', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const trigger = wrapper.find('button.mc-sidebar__footer-trigger');
await trigger.trigger('mouseenter');
await nextTick();
await trigger.trigger('mouseleave');
expect(hideFloatingItem).toHaveBeenCalledTimes(1);
await trigger.trigger('blur');
expect(hideFloatingItem).toHaveBeenCalledTimes(2);
});
it('calls onTriggerKeydown on keydown when collapsed', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const trigger = wrapper.find('button.mc-sidebar__footer-trigger');
await trigger.trigger('keydown', { key: 'ArrowDown' });
expect(onTriggerKeydown).toHaveBeenCalled();
});
it('calls onListboxKeydown when keydown is emitted on the listbox', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const listbox = wrapper.find('#listbox-footer');
expect(listbox.exists()).toBe(true);
await listbox.trigger('keydown');
expect(onListboxKeydown).toHaveBeenCalled();
});
it('calls hideFloatingItem on mouseleave and blur on the listbox', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const listbox = wrapper.find('#listbox-footer');
await listbox.trigger('mouseleave');
expect(hideFloatingItem).toHaveBeenCalledTimes(1);
await listbox.trigger('blur');
expect(hideFloatingItem).toHaveBeenCalledTimes(2);
});
it('calls toggleSidebar when expand button is clicked', async () => {
const wrapper = mount(MSidebarFooter, {
props: { title: 'John Doe' },
global: {
provide: {
[EXPANDED_SIDEBAR_KEY]: false,
[TOGGLE_SIDEBAR_KEY]: toggleSidebar,
},
},
});
const expandButton = wrapper.find('.mc-sidebar__footer-expand');
expect(expandButton.exists()).toBe(true);
await expandButton.trigger('click');
expect(toggleSidebar).toHaveBeenCalledTimes(1);
});
});