UNPKG

@mozaic-ds/vue

Version:

Mozaic-Vue is the Vue.js implementation of ADEO Design system

156 lines (130 loc) 4.06 kB
import { mount } from '@vue/test-utils'; import { describe, it, expect, vi } from 'vitest'; import { nextTick } from 'vue'; import MPageHeaderContext from './MPageHeaderContext.vue'; const options = [ { label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 }, ]; const stubs = { MOptionListbox: { name: 'MOptionListbox', props: ['modelValue', 'options', 'multiple', 'id'], emits: ['update:modelValue'], template: '<div class="option-listbox-stub" />', }, }; describe('MPageHeaderContext', () => { it('renders selected option label in single mode', () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: 2, options, }, global: { stubs }, }); expect(wrapper.find('.mc-page-header__context-switcher').text()).toContain( 'Option 2', ); }); it('falls back to provided label when no option matches modelValue', () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: 999, options, label: 'Fallback context', }, global: { stubs }, }); expect(wrapper.find('.mc-page-header__context-switcher').text()).toContain( 'Fallback context', ); }); it('always uses label in multiple mode', () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: [1], options, multiple: true, label: 'Multi context', }, global: { stubs }, }); expect(wrapper.find('.mc-page-header__context-switcher').text()).toContain( 'Multi context', ); }); it('toggles listbox visibility when switcher button is clicked', async () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: null, options, }, global: { stubs }, }); const listbox = wrapper.find('.mc-page-header__context-switcher-listbox'); expect(listbox.classes()).toContain( 'mc-page-header__context-switcher-listbox--hidden', ); await wrapper.find('.mc-page-header__context-switcher').trigger('click'); expect(listbox.classes()).not.toContain( 'mc-page-header__context-switcher-listbox--hidden', ); }); it('emits update:modelValue when the listbox emits an update', async () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: null, options, }, global: { stubs }, }); wrapper .findComponent({ name: 'MOptionListbox' }) .vm.$emit('update:modelValue', 1); await nextTick(); expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([1]); }); it('closes the listbox on outside click', async () => { const wrapper = mount(MPageHeaderContext, { props: { modelValue: null, options, }, global: { stubs }, attachTo: document.body, }); await wrapper.find('.mc-page-header__context-switcher').trigger('click'); expect( wrapper .find('.mc-page-header__context-switcher-listbox') .classes() .includes('mc-page-header__context-switcher-listbox--hidden'), ).toBe(false); document.body.dispatchEvent(new MouseEvent('click', { bubbles: true })); await nextTick(); expect( wrapper .find('.mc-page-header__context-switcher-listbox') .classes() .includes('mc-page-header__context-switcher-listbox--hidden'), ).toBe(true); wrapper.unmount(); }); it('registers and removes click listener on mount lifecycle', () => { const addSpy = vi.spyOn(document, 'addEventListener'); const removeSpy = vi.spyOn(document, 'removeEventListener'); const wrapper = mount(MPageHeaderContext, { props: { modelValue: null, options, }, global: { stubs }, }); expect(addSpy).toHaveBeenCalledWith('click', expect.any(Function)); wrapper.unmount(); expect(removeSpy).toHaveBeenCalledWith('click', expect.any(Function)); addSpy.mockRestore(); removeSpy.mockRestore(); }); });