diff options
Diffstat (limited to 'spec/frontend/issuable_list/components/issuable_list_root_spec.js')
-rw-r--r-- | spec/frontend/issuable_list/components/issuable_list_root_spec.js | 124 |
1 files changed, 97 insertions, 27 deletions
diff --git a/spec/frontend/issuable_list/components/issuable_list_root_spec.js b/spec/frontend/issuable_list/components/issuable_list_root_spec.js index 9c57233548c..38d6d6d86bc 100644 --- a/spec/frontend/issuable_list/components/issuable_list_root_spec.js +++ b/spec/frontend/issuable_list/components/issuable_list_root_spec.js @@ -1,5 +1,6 @@ import { GlSkeletonLoading, GlPagination } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import VueDraggable from 'vuedraggable'; import { TEST_HOST } from 'helpers/test_constants'; @@ -11,7 +12,7 @@ import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filte import { mockIssuableListProps, mockIssuables } from '../mock_data'; const createComponent = ({ props = mockIssuableListProps, data = {} } = {}) => - mount(IssuableListRoot, { + shallowMount(IssuableListRoot, { propsData: props, data() { return data; @@ -24,20 +25,29 @@ const createComponent = ({ props = mockIssuableListProps, data = {} } = {}) => <p class="js-issuable-empty-state">Issuable empty state</p> `, }, + stubs: { + IssuableTabs, + }, }); describe('IssuableListRoot', () => { let wrapper; - beforeEach(() => { - wrapper = createComponent(); - }); + const findFilteredSearchBar = () => wrapper.findComponent(FilteredSearchBar); + const findGlPagination = () => wrapper.findComponent(GlPagination); + const findIssuableItem = () => wrapper.findComponent(IssuableItem); + const findIssuableTabs = () => wrapper.findComponent(IssuableTabs); + const findVueDraggable = () => wrapper.findComponent(VueDraggable); afterEach(() => { wrapper.destroy(); }); describe('computed', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + const mockCheckedIssuables = { [mockIssuables[0].iid]: { checked: true, issuable: mockIssuables[0] }, [mockIssuables[1].iid]: { checked: true, issuable: mockIssuables[1] }, @@ -108,6 +118,10 @@ describe('IssuableListRoot', () => { }); describe('watch', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + describe('issuables', () => { it('populates `checkedIssuables` prop with all issuables', async () => { wrapper.setProps({ @@ -147,6 +161,10 @@ describe('IssuableListRoot', () => { }); describe('methods', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + describe('issuableId', () => { it('returns id value from provided issuable object', () => { expect(wrapper.vm.issuableId({ id: 1 })).toBe(1); @@ -171,12 +189,16 @@ describe('IssuableListRoot', () => { }); describe('template', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + it('renders component container element with class "issuable-list-container"', () => { expect(wrapper.classes()).toContain('issuable-list-container'); }); it('renders issuable-tabs component', () => { - const tabsEl = wrapper.find(IssuableTabs); + const tabsEl = findIssuableTabs(); expect(tabsEl.exists()).toBe(true); expect(tabsEl.props()).toMatchObject({ @@ -187,14 +209,14 @@ describe('IssuableListRoot', () => { }); it('renders contents for slot "nav-actions" within issuable-tab component', () => { - const buttonEl = wrapper.find(IssuableTabs).find('button.js-new-issuable'); + const buttonEl = findIssuableTabs().find('button.js-new-issuable'); expect(buttonEl.exists()).toBe(true); expect(buttonEl.text()).toBe('New issuable'); }); it('renders filtered-search-bar component', () => { - const searchEl = wrapper.find(FilteredSearchBar); + const searchEl = findFilteredSearchBar(); const { namespace, recentSearchesStorageKey, @@ -224,11 +246,13 @@ describe('IssuableListRoot', () => { await wrapper.vm.$nextTick(); - expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(wrapper.vm.skeletonItemCount); + expect(wrapper.findAllComponents(GlSkeletonLoading)).toHaveLength( + wrapper.vm.skeletonItemCount, + ); }); it('renders issuable-item component for each item within `issuables` array', () => { - const itemsEl = wrapper.findAll(IssuableItem); + const itemsEl = wrapper.findAllComponents(IssuableItem); const mockIssuable = mockIssuableListProps.issuables[0]; expect(itemsEl).toHaveLength(mockIssuableListProps.issuables.length); @@ -257,7 +281,7 @@ describe('IssuableListRoot', () => { await wrapper.vm.$nextTick(); - const paginationEl = wrapper.find(GlPagination); + const paginationEl = findGlPagination(); expect(paginationEl.exists()).toBe(true); expect(paginationEl.props()).toMatchObject({ perPage: 20, @@ -271,10 +295,8 @@ describe('IssuableListRoot', () => { }); describe('events', () => { - let wrapperChecked; - beforeEach(() => { - wrapperChecked = createComponent({ + wrapper = createComponent({ data: { checkedIssuables: { [mockIssuables[0].iid]: { checked: true, issuable: mockIssuables[0] }, @@ -283,34 +305,30 @@ describe('IssuableListRoot', () => { }); }); - afterEach(() => { - wrapperChecked.destroy(); - }); - it('issuable-tabs component emits `click-tab` event on `click-tab` event', () => { - wrapper.find(IssuableTabs).vm.$emit('click'); + findIssuableTabs().vm.$emit('click'); expect(wrapper.emitted('click-tab')).toBeTruthy(); }); it('sets all issuables as checked when filtered-search-bar component emits `checked-input` event', async () => { - const searchEl = wrapperChecked.find(FilteredSearchBar); + const searchEl = findFilteredSearchBar(); searchEl.vm.$emit('checked-input', true); - await wrapperChecked.vm.$nextTick(); + await wrapper.vm.$nextTick(); expect(searchEl.emitted('checked-input')).toBeTruthy(); expect(searchEl.emitted('checked-input').length).toBe(1); - expect(wrapperChecked.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({ + expect(wrapper.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({ checked: true, issuable: mockIssuables[0], }); }); it('filtered-search-bar component emits `filter` event on `onFilter` & `sort` event on `onSort` events', () => { - const searchEl = wrapper.find(FilteredSearchBar); + const searchEl = findFilteredSearchBar(); searchEl.vm.$emit('onFilter'); expect(wrapper.emitted('filter')).toBeTruthy(); @@ -319,21 +337,33 @@ describe('IssuableListRoot', () => { }); it('sets an issuable as checked when issuable-item component emits `checked-input` event', async () => { - const issuableItem = wrapperChecked.findAll(IssuableItem).at(0); + const issuableItem = wrapper.findAllComponents(IssuableItem).at(0); issuableItem.vm.$emit('checked-input', true); - await wrapperChecked.vm.$nextTick(); + await wrapper.vm.$nextTick(); expect(issuableItem.emitted('checked-input')).toBeTruthy(); expect(issuableItem.emitted('checked-input').length).toBe(1); - expect(wrapperChecked.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({ + expect(wrapper.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({ checked: true, issuable: mockIssuables[0], }); }); + it('emits `update-legacy-bulk-edit` when filtered-search-bar checkbox is checked', () => { + findFilteredSearchBar().vm.$emit('checked-input'); + + expect(wrapper.emitted('update-legacy-bulk-edit')).toEqual([[]]); + }); + + it('emits `update-legacy-bulk-edit` when issuable-item checkbox is checked', () => { + findIssuableItem().vm.$emit('checked-input'); + + expect(wrapper.emitted('update-legacy-bulk-edit')).toEqual([[]]); + }); + it('gl-pagination component emits `page-change` event on `input` event', async () => { wrapper.setProps({ showPaginationControls: true, @@ -341,8 +371,48 @@ describe('IssuableListRoot', () => { await wrapper.vm.$nextTick(); - wrapper.find(GlPagination).vm.$emit('input'); + findGlPagination().vm.$emit('input'); expect(wrapper.emitted('page-change')).toBeTruthy(); }); }); + + describe('manual sorting', () => { + describe('when enabled', () => { + beforeEach(() => { + wrapper = createComponent({ + props: { + ...mockIssuableListProps, + isManualOrdering: true, + }, + }); + }); + + it('renders VueDraggable component', () => { + expect(findVueDraggable().exists()).toBe(true); + }); + + it('IssuableItem has grab cursor', () => { + expect(findIssuableItem().classes()).toContain('gl-cursor-grab'); + }); + + it('emits a "reorder" event when user updates the issue order', () => { + const oldIndex = 4; + const newIndex = 6; + + findVueDraggable().vm.$emit('update', { oldIndex, newIndex }); + + expect(wrapper.emitted('reorder')).toEqual([[{ oldIndex, newIndex }]]); + }); + }); + + describe('when disabled', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + it('does not render VueDraggable component', () => { + expect(findVueDraggable().exists()).toBe(false); + }); + }); + }); }); |