diff options
Diffstat (limited to 'spec/frontend/boards/components')
13 files changed, 102 insertions, 372 deletions
diff --git a/spec/frontend/boards/components/__snapshots__/board_blocked_icon_spec.js.snap b/spec/frontend/boards/components/__snapshots__/board_blocked_icon_spec.js.snap index c000f300e4d..3fb0706fd10 100644 --- a/spec/frontend/boards/components/__snapshots__/board_blocked_icon_spec.js.snap +++ b/spec/frontend/boards/components/__snapshots__/board_blocked_icon_spec.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`BoardBlockedIcon on mouseenter on blocked icon with more than three blocking issues matches the snapshot 1`] = ` -"<div class=\\"gl-display-inline\\"><svg data-testid=\\"issue-blocked-icon\\" aria-hidden=\\"true\\" class=\\"issue-blocked-icon gl-mr-2 gl-cursor-pointer gl-icon s16\\" id=\\"blocked-icon-uniqueId\\"> +"<div class=\\"gl-display-inline\\"><svg data-testid=\\"issue-blocked-icon\\" role=\\"img\\" aria-hidden=\\"true\\" class=\\"issue-blocked-icon gl-mr-2 gl-cursor-pointer gl-icon s16\\" id=\\"blocked-icon-uniqueId\\"> <use href=\\"#issue-block\\"></use> </svg> <div class=\\"gl-popover\\"> diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js index ceafa6ead94..9a9ce7b8dc1 100644 --- a/spec/frontend/boards/components/board_card_spec.js +++ b/spec/frontend/boards/components/board_card_spec.js @@ -1,5 +1,6 @@ import { GlLabel } from '@gitlab/ui'; -import { createLocalVue, shallowMount, mount } from '@vue/test-utils'; +import { shallowMount, mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import BoardCard from '~/boards/components/board_card.vue'; @@ -12,8 +13,7 @@ describe('Board card', () => { let store; let mockActions; - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); const createStore = ({ initialState = {} } = {}) => { mockActions = { @@ -41,14 +41,14 @@ describe('Board card', () => { provide = {}, mountFn = shallowMount, stubs = { BoardCardInner }, + item = mockIssue, } = {}) => { wrapper = mountFn(BoardCard, { - localVue, stubs, store, propsData: { list: mockLabelList, - item: mockIssue, + item, disabled: false, index: 0, ...propsData, @@ -72,6 +72,10 @@ describe('Board card', () => { await wrapper.vm.$nextTick(); }; + beforeEach(() => { + window.gon = { features: {} }; + }); + afterEach(() => { wrapper.destroy(); wrapper = null; @@ -140,6 +144,10 @@ describe('Board card', () => { }); describe('when using multi-select', () => { + beforeEach(() => { + window.gon = { features: { boardMultiSelect: true } }; + }); + it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => { await multiSelectCard(); @@ -151,4 +159,24 @@ describe('Board card', () => { }); }); }); + + describe('when card is loading', () => { + it('card is disabled and user cannot drag', () => { + createStore(); + mountComponent({ item: { ...mockIssue, isLoading: true } }); + + expect(wrapper.classes()).toContain('is-disabled'); + expect(wrapper.classes()).not.toContain('user-can-drag'); + }); + }); + + describe('when card is not loading', () => { + it('user can drag', () => { + createStore(); + mountComponent(); + + expect(wrapper.classes()).not.toContain('is-disabled'); + expect(wrapper.classes()).toContain('user-can-drag'); + }); + }); }); diff --git a/spec/frontend/boards/components/board_content_sidebar_spec.js b/spec/frontend/boards/components/board_content_sidebar_spec.js index 01c99a02db2..10d739c65f5 100644 --- a/spec/frontend/boards/components/board_content_sidebar_spec.js +++ b/spec/frontend/boards/components/board_content_sidebar_spec.js @@ -1,13 +1,13 @@ import { GlDrawer } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import Vuex from 'vuex'; +import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue'; import { stubComponent } from 'helpers/stub_component'; import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue'; -import BoardSidebarDueDate from '~/boards/components/sidebar/board_sidebar_due_date.vue'; import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue'; -import BoardSidebarMilestoneSelect from '~/boards/components/sidebar/board_sidebar_milestone_select.vue'; import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue'; import { ISSUABLE } from '~/boards/constants'; +import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue'; import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue'; import { mockIssue, mockIssueGroupPath, mockIssueProjectPath } from '../mock_data'; @@ -68,6 +68,9 @@ describe('BoardContentSidebar', () => { iterations: { loading: false, }, + attributesList: { + loading: false, + }, }, }, }, @@ -84,38 +87,41 @@ describe('BoardContentSidebar', () => { }); it('confirms we render GlDrawer', () => { - expect(wrapper.find(GlDrawer).exists()).toBe(true); + expect(wrapper.findComponent(GlDrawer).exists()).toBe(true); }); it('does not render GlDrawer when isSidebarOpen is false', () => { createStore({ mockGetters: { isSidebarOpen: () => false } }); createComponent(); - expect(wrapper.find(GlDrawer).exists()).toBe(false); + expect(wrapper.findComponent(GlDrawer).exists()).toBe(false); }); it('applies an open attribute', () => { - expect(wrapper.find(GlDrawer).props('open')).toBe(true); + expect(wrapper.findComponent(GlDrawer).props('open')).toBe(true); }); it('renders BoardSidebarLabelsSelect', () => { - expect(wrapper.find(BoardSidebarLabelsSelect).exists()).toBe(true); + expect(wrapper.findComponent(BoardSidebarLabelsSelect).exists()).toBe(true); }); it('renders BoardSidebarTitle', () => { - expect(wrapper.find(BoardSidebarTitle).exists()).toBe(true); + expect(wrapper.findComponent(BoardSidebarTitle).exists()).toBe(true); }); - it('renders BoardSidebarDueDate', () => { - expect(wrapper.find(BoardSidebarDueDate).exists()).toBe(true); + it('renders SidebarDateWidget', () => { + expect(wrapper.findComponent(SidebarDateWidget).exists()).toBe(true); }); it('renders BoardSidebarSubscription', () => { - expect(wrapper.find(SidebarSubscriptionsWidget).exists()).toBe(true); + expect(wrapper.findComponent(SidebarSubscriptionsWidget).exists()).toBe(true); }); - it('renders BoardSidebarMilestoneSelect', () => { - expect(wrapper.find(BoardSidebarMilestoneSelect).exists()).toBe(true); + it('renders SidebarDropdownWidget for milestones', () => { + expect(wrapper.findComponent(SidebarDropdownWidget).exists()).toBe(true); + expect(wrapper.findComponent(SidebarDropdownWidget).props('issuableAttribute')).toEqual( + 'milestone', + ); }); describe('when we emit close', () => { @@ -128,7 +134,7 @@ describe('BoardContentSidebar', () => { }); it('calls toggleBoardItem with correct parameters', async () => { - wrapper.find(GlDrawer).vm.$emit('close'); + wrapper.findComponent(GlDrawer).vm.$emit('close'); expect(toggleBoardItem).toHaveBeenCalledTimes(1); expect(toggleBoardItem).toHaveBeenCalledWith(expect.any(Object), { diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js index e27badca9de..6ac5d16e5a3 100644 --- a/spec/frontend/boards/components/board_filtered_search_spec.js +++ b/spec/frontend/boards/components/board_filtered_search_spec.js @@ -105,9 +105,9 @@ describe('BoardFilteredSearch', () => { beforeEach(() => { store = createStore(); - jest.spyOn(store, 'dispatch'); - createComponent(); + + jest.spyOn(wrapper.vm, 'performSearch').mockImplementation(); }); it('sets the url params to the correct results', async () => { diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js index 24fcdd528d5..80d740458dc 100644 --- a/spec/frontend/boards/components/board_form_spec.js +++ b/spec/frontend/boards/components/board_form_spec.js @@ -9,14 +9,12 @@ import createBoardMutation from '~/boards/graphql/board_create.mutation.graphql' import destroyBoardMutation from '~/boards/graphql/board_destroy.mutation.graphql'; import updateBoardMutation from '~/boards/graphql/board_update.mutation.graphql'; import { createStore } from '~/boards/stores'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; import { visitUrl } from '~/lib/utils/url_utility'; jest.mock('~/lib/utils/url_utility', () => ({ visitUrl: jest.fn().mockName('visitUrlMock'), stripFinalUrlSegment: jest.requireActual('~/lib/utils/url_utility').stripFinalUrlSegment, })); -jest.mock('~/flash'); const currentBoard = { id: 1, @@ -194,9 +192,11 @@ describe('BoardForm', () => { expect(visitUrl).toHaveBeenCalledWith('test-path'); }); - it('shows an error flash if GraphQL mutation fails', async () => { + it('shows a GlAlert if GraphQL mutation fails', async () => { mutate = jest.fn().mockRejectedValue('Houston, we have a problem'); createComponent({ canAdminBoard: true, currentPage: formType.new }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); + fillForm(); await waitForPromises(); @@ -205,7 +205,7 @@ describe('BoardForm', () => { await waitForPromises(); expect(visitUrl).not.toHaveBeenCalled(); - expect(createFlash).toHaveBeenCalled(); + expect(wrapper.vm.setError).toHaveBeenCalled(); }); }); }); @@ -290,9 +290,11 @@ describe('BoardForm', () => { expect(visitUrl).toHaveBeenCalledWith('test-path?group_by=epic'); }); - it('shows an error flash if GraphQL mutation fails', async () => { + it('shows a GlAlert if GraphQL mutation fails', async () => { mutate = jest.fn().mockRejectedValue('Houston, we have a problem'); createComponent({ canAdminBoard: true, currentPage: formType.edit }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); + findInput().trigger('keyup.enter', { metaKey: true }); await waitForPromises(); @@ -301,7 +303,7 @@ describe('BoardForm', () => { await waitForPromises(); expect(visitUrl).not.toHaveBeenCalled(); - expect(createFlash).toHaveBeenCalled(); + expect(wrapper.vm.setError).toHaveBeenCalled(); }); }); @@ -335,9 +337,11 @@ describe('BoardForm', () => { expect(visitUrl).toHaveBeenCalledWith('root'); }); - it('shows an error flash if GraphQL mutation fails', async () => { + it('dispatches `setError` action when GraphQL mutation fails', async () => { mutate = jest.fn().mockRejectedValue('Houston, we have a problem'); createComponent({ canAdminBoard: true, currentPage: formType.delete }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); + findModal().vm.$emit('primary'); await waitForPromises(); @@ -346,7 +350,7 @@ describe('BoardForm', () => { await waitForPromises(); expect(visitUrl).not.toHaveBeenCalled(); - expect(createFlash).toHaveBeenCalled(); + expect(wrapper.vm.setError).toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/boards/components/board_list_header_deprecated_spec.js b/spec/frontend/boards/components/board_list_header_deprecated_spec.js index fdc7cd2b1d4..db79e67fe78 100644 --- a/spec/frontend/boards/components/board_list_header_deprecated_spec.js +++ b/spec/frontend/boards/components/board_list_header_deprecated_spec.js @@ -31,6 +31,7 @@ describe('Board List Header Component', () => { listType = ListType.backlog, collapsed = false, withLocalStorage = true, + currentUserId = 1, } = {}) => { const boardId = '1'; @@ -62,6 +63,7 @@ describe('Board List Header Component', () => { }, provide: { boardId, + currentUserId, }, }); }; @@ -100,10 +102,12 @@ describe('Board List Header Component', () => { }); }); - it('does render when logged out', () => { - createComponent(); + it('does not render when logged out', () => { + createComponent({ + currentUserId: null, + }); - expect(findAddIssueButton().exists()).toBe(true); + expect(findAddIssueButton().exists()).toBe(false); }); }); @@ -143,7 +147,6 @@ describe('Board List Header Component', () => { it("when logged in it calls list update and doesn't set localStorage", () => { jest.spyOn(List.prototype, 'update'); - window.gon.current_user_id = 1; createComponent({ withLocalStorage: false }); @@ -158,7 +161,7 @@ describe('Board List Header Component', () => { it("when logged out it doesn't call list update and sets localStorage", () => { jest.spyOn(List.prototype, 'update'); - createComponent(); + createComponent({ currentUserId: null }); findCaret().vm.$emit('click'); diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js index d2dfb4148b3..0abb00e0fa5 100644 --- a/spec/frontend/boards/components/board_list_header_spec.js +++ b/spec/frontend/boards/components/board_list_header_spec.js @@ -28,7 +28,7 @@ describe('Board List Header Component', () => { listType = ListType.backlog, collapsed = false, withLocalStorage = true, - currentUserId = null, + currentUserId = 1, } = {}) => { const boardId = '1'; @@ -109,10 +109,12 @@ describe('Board List Header Component', () => { }); }); - it('does render when logged out', () => { - createComponent(); + it('does not render when logged out', () => { + createComponent({ + currentUserId: null, + }); - expect(findAddIssueButton().exists()).toBe(true); + expect(findAddIssueButton().exists()).toBe(false); }); }); @@ -153,7 +155,9 @@ describe('Board List Header Component', () => { }); it("when logged out it doesn't call list update and sets localStorage", async () => { - createComponent(); + createComponent({ + currentUserId: null, + }); findCaret().vm.$emit('click'); await wrapper.vm.$nextTick(); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js deleted file mode 100644 index 8fd178a0856..00000000000 --- a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -import { GlDatepicker } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue'; -import BoardSidebarDueDate from '~/boards/components/sidebar/board_sidebar_due_date.vue'; -import { createStore } from '~/boards/stores'; -import createFlash from '~/flash'; - -const TEST_DUE_DATE = '2020-02-20'; -const TEST_FORMATTED_DUE_DATE = 'Feb 20, 2020'; -const TEST_PARSED_DATE = new Date(2020, 1, 20); -const TEST_ISSUE = { id: 'gid://gitlab/Issue/1', iid: 9, dueDate: null, referencePath: 'h/b#2' }; - -jest.mock('~/flash'); - -describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => { - let wrapper; - let store; - - afterEach(() => { - wrapper.destroy(); - store = null; - wrapper = null; - }); - - const createWrapper = ({ dueDate = null } = {}) => { - store = createStore(); - store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, dueDate } }; - store.state.activeId = TEST_ISSUE.id; - - wrapper = shallowMount(BoardSidebarDueDate, { - store, - provide: { - canUpdate: true, - }, - stubs: { - 'board-editable-item': BoardEditableItem, - }, - }); - }; - - const findDatePicker = () => wrapper.find(GlDatepicker); - const findResetButton = () => wrapper.find('[data-testid="reset-button"]'); - const findCollapsed = () => wrapper.find('[data-testid="collapsed-content"]'); - - it('renders "None" when no due date is set', () => { - createWrapper(); - - expect(findCollapsed().text()).toBe('None'); - expect(findResetButton().exists()).toBe(false); - }); - - it('renders formatted due date with reset button when set', () => { - createWrapper({ dueDate: TEST_DUE_DATE }); - - expect(findCollapsed().text()).toContain(TEST_FORMATTED_DUE_DATE); - expect(findResetButton().exists()).toBe(true); - }); - - describe('when due date is submitted', () => { - beforeEach(async () => { - createWrapper(); - - jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => { - store.state.boardItems[TEST_ISSUE.id].dueDate = TEST_DUE_DATE; - }); - findDatePicker().vm.$emit('input', TEST_PARSED_DATE); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders formatted due date with reset button', () => { - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toContain(TEST_FORMATTED_DUE_DATE); - expect(findResetButton().exists()).toBe(true); - }); - - it('commits change to the server', () => { - expect(wrapper.vm.setActiveIssueDueDate).toHaveBeenCalledWith({ - dueDate: TEST_DUE_DATE, - projectPath: 'h/b', - }); - }); - }); - - describe('when due date is cleared', () => { - beforeEach(async () => { - createWrapper(); - - jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => { - store.state.boardItems[TEST_ISSUE.id].dueDate = null; - }); - findDatePicker().vm.$emit('clear'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders "None"', () => { - expect(wrapper.vm.setActiveIssueDueDate).toHaveBeenCalled(); - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toBe('None'); - }); - }); - - describe('when due date is resetted', () => { - beforeEach(async () => { - createWrapper({ dueDate: TEST_DUE_DATE }); - - jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => { - store.state.boardItems[TEST_ISSUE.id].dueDate = null; - }); - findResetButton().vm.$emit('click'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders "None"', () => { - expect(wrapper.vm.setActiveIssueDueDate).toHaveBeenCalled(); - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toBe('None'); - }); - }); - - describe('when the mutation fails', () => { - beforeEach(async () => { - createWrapper({ dueDate: TEST_DUE_DATE }); - - jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => { - throw new Error(['failed mutation']); - }); - findDatePicker().vm.$emit('input', 'Invalid date'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders former issue due date', () => { - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toContain(TEST_FORMATTED_DUE_DATE); - expect(createFlash).toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js index ad682774ee6..8992a5780f3 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js @@ -9,11 +9,8 @@ import { import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue'; import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue'; import { createStore } from '~/boards/stores'; -import createFlash from '~/flash'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -jest.mock('~/flash'); - const TEST_LABELS_PAYLOAD = TEST_LABELS.map((label) => ({ ...label, set: true })); const TEST_LABELS_TITLES = TEST_LABELS.map((label) => label.title); @@ -154,6 +151,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => { jest.spyOn(wrapper.vm, 'setActiveBoardItemLabels').mockImplementation(() => { throw new Error(['failed mutation']); }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); findLabelsSelect().vm.$emit('updateSelectedLabels', [{ id: '?' }]); await wrapper.vm.$nextTick(); }); @@ -161,7 +159,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => { it('collapses sidebar and renders former issue weight', () => { expect(findCollapsed().isVisible()).toBe(true); expect(findLabelsTitles()).toEqual(TEST_LABELS_TITLES); - expect(createFlash).toHaveBeenCalled(); + expect(wrapper.vm.setError).toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js deleted file mode 100644 index 8706424a296..00000000000 --- a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js +++ /dev/null @@ -1,178 +0,0 @@ -import { GlLoadingIcon, GlDropdown } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import { mockMilestone as TEST_MILESTONE } from 'jest/boards/mock_data'; -import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue'; -import BoardSidebarMilestoneSelect from '~/boards/components/sidebar/board_sidebar_milestone_select.vue'; -import { createStore } from '~/boards/stores'; -import createFlash from '~/flash'; - -const TEST_ISSUE = { id: 'gid://gitlab/Issue/1', iid: 9, referencePath: 'h/b#2' }; - -jest.mock('~/flash'); - -describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () => { - let wrapper; - let store; - - afterEach(() => { - wrapper.destroy(); - store = null; - wrapper = null; - }); - - const createWrapper = ({ milestone = null, loading = false } = {}) => { - store = createStore(); - store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, milestone } }; - store.state.activeId = TEST_ISSUE.id; - - wrapper = shallowMount(BoardSidebarMilestoneSelect, { - store, - provide: { - canUpdate: true, - }, - data: () => ({ - milestones: [TEST_MILESTONE], - }), - stubs: { - 'board-editable-item': BoardEditableItem, - }, - mocks: { - $apollo: { - loading, - }, - }, - }); - }; - - const findCollapsed = () => wrapper.find('[data-testid="collapsed-content"]'); - const findLoader = () => wrapper.find(GlLoadingIcon); - const findDropdown = () => wrapper.find(GlDropdown); - const findBoardEditableItem = () => wrapper.find(BoardEditableItem); - const findDropdownItem = () => wrapper.find('[data-testid="milestone-item"]'); - const findUnsetMilestoneItem = () => wrapper.find('[data-testid="no-milestone-item"]'); - const findNoMilestonesFoundItem = () => wrapper.find('[data-testid="no-milestones-found"]'); - - describe('when not editing', () => { - it('opens the milestone dropdown on clicking edit', async () => { - createWrapper(); - wrapper.vm.$refs.dropdown.show = jest.fn(); - - await findBoardEditableItem().vm.$emit('open'); - - expect(wrapper.vm.$refs.dropdown.show).toHaveBeenCalledTimes(1); - }); - }); - - describe('when editing', () => { - beforeEach(() => { - createWrapper(); - jest.spyOn(wrapper.vm.$refs.sidebarItem, 'collapse'); - }); - - it('collapses BoardEditableItem on clicking edit', async () => { - await findBoardEditableItem().vm.$emit('close'); - - expect(wrapper.vm.$refs.sidebarItem.collapse).toHaveBeenCalledTimes(1); - }); - - it('collapses BoardEditableItem on hiding dropdown', async () => { - await findDropdown().vm.$emit('hide'); - - expect(wrapper.vm.$refs.sidebarItem.collapse).toHaveBeenCalledTimes(1); - }); - }); - - it('renders "None" when no milestone is selected', () => { - createWrapper(); - - expect(findCollapsed().text()).toBe('None'); - }); - - it('renders milestone title when set', () => { - createWrapper({ milestone: TEST_MILESTONE }); - - expect(findCollapsed().text()).toContain(TEST_MILESTONE.title); - }); - - it('shows loader while Apollo is loading', async () => { - createWrapper({ milestone: TEST_MILESTONE, loading: true }); - - expect(findLoader().exists()).toBe(true); - }); - - it('shows message when error or no milestones found', async () => { - createWrapper(); - - await wrapper.setData({ milestones: [] }); - - expect(findNoMilestonesFoundItem().text()).toBe('No milestones found'); - }); - - describe('when milestone is selected', () => { - beforeEach(async () => { - createWrapper(); - - jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => { - store.state.boardItems[TEST_ISSUE.id].milestone = TEST_MILESTONE; - }); - findDropdownItem().vm.$emit('click'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders selected milestone', () => { - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toContain(TEST_MILESTONE.title); - }); - - it('commits change to the server', () => { - expect(wrapper.vm.setActiveIssueMilestone).toHaveBeenCalledWith({ - milestoneId: TEST_MILESTONE.id, - projectPath: 'h/b', - }); - }); - }); - - describe('when milestone is set to "None"', () => { - beforeEach(async () => { - createWrapper({ milestone: TEST_MILESTONE }); - - jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => { - store.state.boardItems[TEST_ISSUE.id].milestone = null; - }); - findUnsetMilestoneItem().vm.$emit('click'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders "None"', () => { - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toBe('None'); - }); - - it('commits change to the server', () => { - expect(wrapper.vm.setActiveIssueMilestone).toHaveBeenCalledWith({ - milestoneId: null, - projectPath: 'h/b', - }); - }); - }); - - describe('when the mutation fails', () => { - const testMilestone = { id: '1', title: 'Former milestone' }; - - beforeEach(async () => { - createWrapper({ milestone: testMilestone }); - - jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => { - throw new Error(['failed mutation']); - }); - findDropdownItem().vm.$emit('click'); - await wrapper.vm.$nextTick(); - }); - - it('collapses sidebar and renders former milestone', () => { - expect(findCollapsed().isVisible()).toBe(true); - expect(findCollapsed().text()).toContain(testMilestone.title); - expect(createFlash).toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js index 7976e73ff2f..8847f626c1f 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js @@ -5,11 +5,8 @@ import Vuex from 'vuex'; import BoardSidebarSubscription from '~/boards/components/sidebar/board_sidebar_subscription.vue'; import { createStore } from '~/boards/stores'; import * as types from '~/boards/stores/mutation_types'; -import createFlash from '~/flash'; import { mockActiveIssue } from '../../mock_data'; -jest.mock('~/flash.js'); - Vue.use(Vuex); describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () => { @@ -153,13 +150,15 @@ describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () = jest.spyOn(wrapper.vm, 'setActiveItemSubscribed').mockImplementation(async () => { throw new Error(); }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); findToggle().trigger('click'); await wrapper.vm.$nextTick(); - expect(createFlash).toHaveBeenNthCalledWith(1, { - message: wrapper.vm.$options.i18n.updateSubscribedErrorMessage, - }); + expect(wrapper.vm.setError).toHaveBeenCalled(); + expect(wrapper.vm.setError.mock.calls[0][0].message).toBe( + wrapper.vm.$options.i18n.updateSubscribedErrorMessage, + ); }); }); }); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js index 03924bfa8d3..74441e147cf 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js @@ -26,6 +26,7 @@ describe('BoardSidebarTimeTracker', () => { store = createStore(); store.state.boardItems = { 1: { + iid: 1, timeEstimate: 3600, totalTimeSpent: 1800, humanTimeEstimate: '1h', @@ -46,12 +47,16 @@ describe('BoardSidebarTimeTracker', () => { createComponent({ provide: { timeTrackingLimitToHours } }); expect(wrapper.find(IssuableTimeTracker).props()).toEqual({ - timeEstimate: 3600, - timeSpent: 1800, - humanTimeEstimate: '1h', - humanTimeSpent: '30min', limitToHours: timeTrackingLimitToHours, showCollapsed: false, + issuableIid: '1', + fullPath: '', + initialTimeTracking: { + timeEstimate: 3600, + totalTimeSpent: 1800, + humanTimeEstimate: '1h', + humanTotalTimeSpent: '30min', + }, }); }, ); diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js index c8ccd4c88a5..4a8eda298f2 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js @@ -3,7 +3,6 @@ import { shallowMount } from '@vue/test-utils'; import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue'; import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue'; import { createStore } from '~/boards/stores'; -import createFlash from '~/flash'; const TEST_TITLE = 'New item title'; const TEST_ISSUE_A = { @@ -19,8 +18,6 @@ const TEST_ISSUE_B = { referencePath: 'h/b#2', }; -jest.mock('~/flash'); - describe('~/boards/components/sidebar/board_sidebar_title.vue', () => { let wrapper; let store; @@ -168,6 +165,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => { jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => { throw new Error(['failed mutation']); }); + jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {}); findFormInput().vm.$emit('input', 'Invalid title'); findForm().vm.$emit('submit', { preventDefault: () => {} }); await wrapper.vm.$nextTick(); @@ -176,7 +174,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => { it('collapses sidebar and renders former item title', () => { expect(findCollapsed().isVisible()).toBe(true); expect(findTitle().text()).toContain(TEST_ISSUE_B.title); - expect(createFlash).toHaveBeenCalled(); + expect(wrapper.vm.setError).toHaveBeenCalled(); }); }); }); |