UNPKG

@mekari/mekari-ui-vue

Version:

--- General web components in Mekari. The components are made using vue.js as its framework. Styling of components on Mekari UI Vue uses [Mekari UI Toolkit](https://bitbucket.org/mid-kelola-indonesia/mekari-ui-toolkit/src/master/). Don't forget to import

263 lines (234 loc) 8.96 kB
import MDropdown from './index.vue'; import MDropdownSearch from './components/DropdownSearch.vue'; import MDropdownTrigger from './components/DropdownTrigger.vue'; import MDropdownMenu from './components/DropdownMenu.vue'; import MDropdownItem from './components/DropdownItem.vue'; import MDropdownPlugin from '../../plugins/Dropdown'; import { createLocalVue, shallowMount } from '@vue/test-utils'; const localVue = createLocalVue(); localVue.use(MDropdownPlugin); describe('Mekari UI Dropdown Component: index.vue', () => { let wrapper; const dummyContent = [{ id: 1, content: 'Content of dropdown 1', children: [], }]; const multiDropdownDummyContent = [ { id: 1, content: 'Content of dropdown 1', children: [ { id: 3, content: 'Content 1 children with id 3', children: [{ id: 4, content: 'Content 3 children with id 4', children: [], }], }, { id: 5, content: 'Content 1 children with id 5', children: [{ id: 6, content: 'Content 5 children with id 6', children: [], }], }, ], }, { id: 2, content: 'Content of dropdown 2', children: [], }, ]; const slotDummy = (action = 'mouseenter', slotName = 'menu-1', options = { isSelectingItem: true }) => ` <template #${slotName}="{ content, setItemAction, menuNumber, activeItemId, isChildrenActive }"> <m-dropdown-item v-for="item in content" :key="item.id" @${action}.native="setItemAction(item, menuNumber, $event, { isSelectingItem: ${options.isSelectingItem}, isHiddenAfterAction: ${options.isHiddenAfterAction} })" :isActive="isChildrenActive && item.id === activeItemId" > {{ item.content }} </m-dropdown-item> </template> `; function defaultWrapper() { return shallowMount(MDropdown, { localVue, propsData: { content: dummyContent, }, scopedSlots: { 'menu-1': slotDummy('mouseenter'), }, stubs: { 'm-dropdown-item': MDropdownItem, }, attachTo: document.body.querySelector('#shadow-element'), }); } beforeEach(() => { const shadowElement = document.createElement('div'); shadowElement.id = 'shadow-element'; document.body.appendChild(shadowElement); }); afterEach(() => { wrapper.destroy(); jest.restoreAllMocks(); }); it('should match snapshot', () => { wrapper = defaultWrapper(); expect(wrapper.element).toMatchSnapshot(); }); it('should toggle dropdown visibility after button trigger', async () => { wrapper = defaultWrapper(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(false); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', false); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(false); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); }); it('should emit dropdown data if dropdown item clicked', async () => { wrapper = defaultWrapper(); wrapper.setProps({ enableMultiLevel: true }); await wrapper.vm.$nextTick(); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); await wrapper.vm.$nextTick(); wrapper.findComponent(MDropdownItem).trigger('mouseenter'); await wrapper.vm.$nextTick(); expect(wrapper.emitted('selected-dropdown')[0]).toEqual(dummyContent); }); it('should call window addEventListener on mousedown', () => { jest.spyOn(window, 'addEventListener').mockImplementationOnce(); wrapper = defaultWrapper(); wrapper.findComponent(MDropdownTrigger).trigger('mousedown'); expect(window.addEventListener).toHaveBeenCalledTimes(1); }); it('should call window removeEventListener on vue destory', () => { jest.spyOn(window, 'removeEventListener').mockImplementationOnce(); wrapper = defaultWrapper(); wrapper.destroy(); expect(window.removeEventListener).toHaveBeenCalledTimes(1); }); it('should keep the dropdown menu shown after item clicked if isHiddenAfterAction props is false', async () => { const slotOptions = { isSelectingItem: false, isHiddenAfterAction: false, }; wrapper = shallowMount(MDropdown, { localVue, propsData: { content: dummyContent, }, scopedSlots: { 'menu-1': slotDummy('click', 'menu-1', slotOptions), }, stubs: { 'm-dropdown-item': MDropdownItem, }, attachTo: document.body.querySelector('#shadow-element'), }); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); wrapper.findComponent(MDropdownItem).trigger('click'); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); }); it('should hide the dropdown menu shown after item clicked if isHiddenAfterAction options is true', async () => { const slotOptions = { isSelectingItem: true, isHiddenAfterAction: true, }; wrapper = shallowMount(MDropdown, { localVue, propsData: { enableMultiLevel: true, content: multiDropdownDummyContent, }, scopedSlots: { 'menu-1': slotDummy('click', 'menu-1', slotOptions), 'menu-2': slotDummy('click', 'menu-2', slotOptions), }, stubs: { 'm-dropdown-item': MDropdownItem, }, attachTo: document.body.querySelector('#shadow-element'), }); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); wrapper.findAllComponents(MDropdownItem).at(0).trigger('click'); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(false); }); const multiLevelWrapperWithSearch = () => ( shallowMount(MDropdown, { localVue, propsData: { enableMultiLevel: true, enableSearch: [true, false, true], content: multiDropdownDummyContent, }, scopedSlots: { 'menu-1': slotDummy('mouseenter', 'menu-1', { isSelectingItem: false }), 'menu-2': slotDummy('mouseenter', 'menu-2', { isSelectingItem: false }), 'menu-3': slotDummy('mouseenter', 'menu-3', {}), }, stubs: { 'm-dropdown-item': MDropdownItem, }, attachTo: document.body.querySelector('#shadow-element'), }) ); it('should show search input if the enable search is set to true', async () => { wrapper = multiLevelWrapperWithSearch(); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); wrapper.findAllComponents(MDropdownItem).at(0).trigger('mouseenter'); await wrapper.vm.$nextTick(); expect(wrapper.findAllComponents(MDropdownSearch).length).toBe(2); }); it('should show item based on search input', async () => { wrapper = multiLevelWrapperWithSearch(); wrapper.findComponent(MDropdownTrigger).vm.$emit('dropdown-trigger', true); wrapper.findAllComponents(MDropdownItem).at(0).trigger('mouseenter'); await wrapper.vm.$nextTick(); wrapper.findAllComponents(MDropdownSearch).at(0).vm.$emit('input', { value: 'hehe', inputId: 0, }); await wrapper.vm.$nextTick(); expect(wrapper.findAllComponents(MDropdownMenu).at(0).findAllComponents(MDropdownItem).length).toBe(0); wrapper.findAllComponents(MDropdownSearch).at(0).vm.$emit('input', { value: 'Content', inputId: 0, }); await wrapper.vm.$nextTick(); expect(wrapper.findAllComponents(MDropdownMenu).at(0).findAllComponents(MDropdownItem).length).toBe(2); }); it('should not show any item if content is empty', () => { wrapper = shallowMount(MDropdown, { localVue }); wrapper.findComponent(MDropdownTrigger).trigger('mousedown'); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(false); }); it('should update visibility of dropdown menu based on property toggleShowDropdown', async () => { wrapper = defaultWrapper(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(false); wrapper.setProps({ toggleShowDropdown: true }); await wrapper.vm.$nextTick(); expect(wrapper.findComponent(MDropdownMenu).isVisible()).toBe(true); }); });