Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/boards')
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js20
-rw-r--r--spec/frontend/boards/board_list_spec.js7
-rw-r--r--spec/frontend/boards/boards_util_spec.js112
-rw-r--r--spec/frontend/boards/components/__snapshots__/board_blocked_icon_spec.js.snap2
-rw-r--r--spec/frontend/boards/components/board_card_spec.js38
-rw-r--r--spec/frontend/boards/components/board_content_sidebar_spec.js32
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js4
-rw-r--r--spec/frontend/boards/components/board_form_spec.js20
-rw-r--r--spec/frontend/boards/components/board_list_header_deprecated_spec.js13
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js14
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js137
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js178
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js11
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js13
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js6
-rw-r--r--spec/frontend/boards/project_select_deprecated_spec.js8
-rw-r--r--spec/frontend/boards/stores/actions_spec.js171
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js47
19 files changed, 325 insertions, 514 deletions
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 36043b09636..15ea5d4eec4 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -1,4 +1,4 @@
-import { GlLabel } from '@gitlab/ui';
+import { GlLabel, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { range } from 'lodash';
import Vuex from 'vuex';
@@ -63,6 +63,7 @@ describe('Board card component', () => {
},
stubs: {
GlLabel: true,
+ GlLoadingIcon: true,
},
mocks: {
$apollo: {
@@ -121,6 +122,10 @@ describe('Board card component', () => {
expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(false);
});
+ it('does not render loading icon', () => {
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
+ });
+
describe('blocked', () => {
it('renders blocked icon if issue is blocked', async () => {
createWrapper({
@@ -399,4 +404,17 @@ describe('Board card component', () => {
});
});
});
+
+ describe('loading', () => {
+ it('renders loading icon', async () => {
+ createWrapper({
+ item: {
+ ...issue,
+ isLoading: true,
+ },
+ });
+
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js
index bf39c3f3e42..76629c96f22 100644
--- a/spec/frontend/boards/board_list_spec.js
+++ b/spec/frontend/boards/board_list_spec.js
@@ -80,6 +80,7 @@ const createComponent = ({
rootPath: '/',
weightFeatureAvailable: false,
boardWeight: null,
+ canAdminList: true,
},
stubs: {
BoardCard,
@@ -181,12 +182,6 @@ describe('Board list component', () => {
});
});
- it('loads more issues after scrolling', () => {
- wrapper.vm.listRef.dispatchEvent(new Event('scroll'));
-
- expect(actions.fetchItemsForList).toHaveBeenCalled();
- });
-
it('does not load issues if already loading', () => {
wrapper = createComponent({
state: { listsFlags: { 'gid://gitlab/List/1': { isLoadingMore: true } } },
diff --git a/spec/frontend/boards/boards_util_spec.js b/spec/frontend/boards/boards_util_spec.js
index 0feb1411003..289905a1948 100644
--- a/spec/frontend/boards/boards_util_spec.js
+++ b/spec/frontend/boards/boards_util_spec.js
@@ -1,17 +1,103 @@
-import { transformNotFilters } from '~/boards/boards_util';
+import { filterVariables } from '~/boards/boards_util';
-describe('transformNotFilters', () => {
- const filters = {
- 'not[labelName]': ['label'],
- 'not[assigneeUsername]': 'assignee',
- };
-
- it('formats not filters, transforms epicId to fullEpicId', () => {
- const result = transformNotFilters(filters);
-
- expect(result).toEqual({
- labelName: ['label'],
- assigneeUsername: 'assignee',
+describe('filterVariables', () => {
+ it.each([
+ [
+ 'correctly processes array filter values',
+ {
+ filters: {
+ 'not[filterA]': ['val1', 'val2'],
+ },
+ expected: {
+ not: {
+ filterA: ['val1', 'val2'],
+ },
+ },
+ },
+ ],
+ [
+ "renames a filter if 'remap' method is available",
+ {
+ filters: {
+ filterD: 'some value',
+ },
+ expected: {
+ filterA: 'some value',
+ not: {},
+ },
+ },
+ ],
+ [
+ 'correctly processes a negated filter that supports negation',
+ {
+ filters: {
+ 'not[filterA]': 'some value 1',
+ 'not[filterB]': 'some value 2',
+ },
+ expected: {
+ not: {
+ filterA: 'some value 1',
+ },
+ },
+ },
+ ],
+ [
+ 'correctly removes an unsupported filter depending on issuableType',
+ {
+ issuableType: 'epic',
+ filters: {
+ filterA: 'some value 1',
+ filterE: 'some value 2',
+ },
+ expected: {
+ filterE: 'some value 2',
+ not: {},
+ },
+ },
+ ],
+ [
+ 'applies a transform when the filter value needs to be modified',
+ {
+ filters: {
+ filterC: 'abc',
+ 'not[filterC]': 'def',
+ },
+ expected: {
+ filterC: 'ABC',
+ not: {
+ filterC: 'DEF',
+ },
+ },
+ },
+ ],
+ ])('%s', (_, { filters, issuableType = 'issue', expected }) => {
+ const result = filterVariables({
+ filters,
+ issuableType,
+ filterInfo: {
+ filterA: {
+ negatedSupport: true,
+ },
+ filterB: {
+ negatedSupport: false,
+ },
+ filterC: {
+ negatedSupport: true,
+ transform: (val) => val.toUpperCase(),
+ },
+ filterD: {
+ remap: () => 'filterA',
+ },
+ filterE: {
+ negatedSupport: true,
+ },
+ },
+ filterFields: {
+ issue: ['filterA', 'filterB', 'filterC', 'filterD'],
+ epic: ['filterE'],
+ },
});
+
+ expect(result).toEqual(expected);
});
});
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();
});
});
});
diff --git a/spec/frontend/boards/project_select_deprecated_spec.js b/spec/frontend/boards/project_select_deprecated_spec.js
index 37f519ef5b9..4494de43083 100644
--- a/spec/frontend/boards/project_select_deprecated_spec.js
+++ b/spec/frontend/boards/project_select_deprecated_spec.js
@@ -5,7 +5,7 @@ import AxiosMockAdapter from 'axios-mock-adapter';
import ProjectSelect from '~/boards/components/project_select_deprecated.vue';
import { ListType } from '~/boards/constants';
import eventHub from '~/boards/eventhub';
-import { deprecatedCreateFlash as flash } from '~/flash';
+import createFlash from '~/flash';
import httpStatus from '~/lib/utils/http_status';
import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
@@ -237,8 +237,10 @@ describe('ProjectSelect component', () => {
await searchForProject('foobar');
- expect(flash).toHaveBeenCalledTimes(1);
- expect(flash).toHaveBeenCalledWith('Something went wrong while fetching projects');
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'Something went wrong while fetching projects',
+ });
});
describe('with non-empty search result', () => {
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 09343b5704f..b28412f2127 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -15,6 +15,7 @@ import {
formatIssueInput,
formatIssue,
getMoveData,
+ updateListPosition,
} from '~/boards/boards_util';
import destroyBoardListMutation from '~/boards/graphql/board_list_destroy.mutation.graphql';
import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql';
@@ -29,13 +30,13 @@ import {
mockIssue2,
rawIssue,
mockIssues,
- mockMilestone,
labels,
mockActiveIssue,
mockGroupProjects,
mockMoveIssueParams,
mockMoveState,
mockMoveData,
+ mockList,
} from '../mock_data';
jest.mock('~/flash');
@@ -70,27 +71,28 @@ describe('setFilters', () => {
[
'with correct filters as payload',
{
- filters: { labelName: 'label' },
- updatedFilters: { labelName: 'label', not: {} },
+ filters: { labelName: 'label', foobar: 'not-a-filter', search: 'quick brown fox' },
+ filterVariables: { labelName: 'label', search: 'quick brown fox', not: {} },
},
],
[
- 'and updates assigneeWildcardId',
+ "and use 'assigneeWildcardId' as filter variable for 'assigneId' param",
{
filters: { assigneeId: 'None' },
- updatedFilters: { assigneeWildcardId: 'NONE', not: {} },
+ filterVariables: { assigneeWildcardId: 'NONE', not: {} },
},
],
- ])('should commit mutation SET_FILTERS %s', (_, { filters, updatedFilters }) => {
+ ])('should commit mutation SET_FILTERS %s', (_, { filters, filterVariables }) => {
const state = {
filters: {},
+ issuableType: issuableTypes.issue,
};
testAction(
actions.setFilters,
filters,
state,
- [{ type: types.SET_FILTERS, payload: updatedFilters }],
+ [{ type: types.SET_FILTERS, payload: filterVariables }],
[],
);
});
@@ -373,6 +375,24 @@ describe('createIssueList', () => {
});
});
+describe('addList', () => {
+ const getters = {
+ getListByTitle: jest.fn().mockReturnValue(mockList),
+ };
+
+ it('should commit RECEIVE_ADD_LIST_SUCCESS mutation and dispatch fetchItemsForList action', () => {
+ testAction({
+ action: actions.addList,
+ payload: mockLists[1],
+ state: { ...getters },
+ expectedMutations: [
+ { type: types.RECEIVE_ADD_LIST_SUCCESS, payload: updateListPosition(mockLists[1]) },
+ ],
+ expectedActions: [{ type: 'fetchItemsForList', payload: { listId: mockList.id } }],
+ });
+ });
+});
+
describe('fetchLabels', () => {
it('should commit mutation RECEIVE_LABELS_SUCCESS on success', async () => {
const queryResponse = {
@@ -520,7 +540,8 @@ describe('toggleListCollapsed', () => {
describe('removeList', () => {
let state;
- const list = mockLists[0];
+ let getters;
+ const list = mockLists[1];
const listId = list.id;
const mutationVariables = {
mutation: destroyBoardListMutation,
@@ -534,6 +555,9 @@ describe('removeList', () => {
boardLists: mockListsById,
issuableType: issuableTypes.issue,
};
+ getters = {
+ getListByTitle: jest.fn().mockReturnValue(mockList),
+ };
});
afterEach(() => {
@@ -543,13 +567,15 @@ describe('removeList', () => {
it('optimistically deletes the list', () => {
const commit = jest.fn();
- actions.removeList({ commit, state }, listId);
+ actions.removeList({ commit, state, getters, dispatch: () => {} }, listId);
expect(commit.mock.calls).toEqual([[types.REMOVE_LIST, listId]]);
});
it('keeps the updated list if remove succeeds', async () => {
const commit = jest.fn();
+ const dispatch = jest.fn();
+
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
destroyBoardList: {
@@ -558,17 +584,18 @@ describe('removeList', () => {
},
});
- await actions.removeList({ commit, state }, listId);
+ await actions.removeList({ commit, state, getters, dispatch }, listId);
expect(gqlClient.mutate).toHaveBeenCalledWith(mutationVariables);
expect(commit.mock.calls).toEqual([[types.REMOVE_LIST, listId]]);
+ expect(dispatch.mock.calls).toEqual([['fetchItemsForList', { listId: mockList.id }]]);
});
it('restores the list if update fails', async () => {
const commit = jest.fn();
jest.spyOn(gqlClient, 'mutate').mockResolvedValue(Promise.reject());
- await actions.removeList({ commit, state }, listId);
+ await actions.removeList({ commit, state, getters, dispatch: () => {} }, listId);
expect(gqlClient.mutate).toHaveBeenCalledWith(mutationVariables);
expect(commit.mock.calls).toEqual([
@@ -587,7 +614,7 @@ describe('removeList', () => {
},
});
- await actions.removeList({ commit, state }, listId);
+ await actions.removeList({ commit, state, getters, dispatch: () => {} }, listId);
expect(gqlClient.mutate).toHaveBeenCalledWith(mutationVariables);
expect(commit.mock.calls).toEqual([
@@ -649,6 +676,10 @@ describe('fetchItemsForList', () => {
state,
[
{
+ type: types.RESET_ITEMS_FOR_LIST,
+ payload: listId,
+ },
+ {
type: types.REQUEST_ITEMS_FOR_LIST,
payload: { listId, fetchNext: false },
},
@@ -671,6 +702,10 @@ describe('fetchItemsForList', () => {
state,
[
{
+ type: types.RESET_ITEMS_FOR_LIST,
+ payload: listId,
+ },
+ {
type: types.REQUEST_ITEMS_FOR_LIST,
payload: { listId, fetchNext: false },
},
@@ -1114,6 +1149,7 @@ describe('addListItem', () => {
listId: mockLists[0].id,
itemId: mockIssue.id,
atIndex: 0,
+ inProgress: false,
},
},
{ type: types.UPDATE_BOARD_ITEM, payload: mockIssue },
@@ -1244,8 +1280,9 @@ describe('addListNewIssue', () => {
type: 'addListItem',
payload: {
list: fakeList,
- item: formatIssue({ ...mockIssue, id: 'tmp' }),
+ item: formatIssue({ ...mockIssue, id: 'tmp', isLoading: true }),
position: 0,
+ inProgress: true,
},
},
{ type: 'removeListItem', payload: { listId: fakeList.id, itemId: 'tmp' } },
@@ -1286,8 +1323,9 @@ describe('addListNewIssue', () => {
type: 'addListItem',
payload: {
list: fakeList,
- item: formatIssue({ ...mockIssue, id: 'tmp' }),
+ item: formatIssue({ ...mockIssue, id: 'tmp', isLoading: true }),
position: 0,
+ inProgress: true,
},
},
{ type: 'removeListItem', payload: { listId: fakeList.id, itemId: 'tmp' } },
@@ -1348,57 +1386,6 @@ describe('setActiveIssueLabels', () => {
});
});
-describe('setActiveIssueDueDate', () => {
- const state = { boardItems: { [mockIssue.id]: mockIssue } };
- const getters = { activeBoardItem: mockIssue };
- const testDueDate = '2020-02-20';
- const input = {
- dueDate: testDueDate,
- projectPath: 'h/b',
- };
-
- it('should commit due date after setting the issue', (done) => {
- jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
- data: {
- updateIssue: {
- issue: {
- dueDate: testDueDate,
- },
- errors: [],
- },
- },
- });
-
- const payload = {
- itemId: getters.activeBoardItem.id,
- prop: 'dueDate',
- value: testDueDate,
- };
-
- testAction(
- actions.setActiveIssueDueDate,
- input,
- { ...state, ...getters },
- [
- {
- type: types.UPDATE_BOARD_ITEM_BY_ID,
- payload,
- },
- ],
- [],
- done,
- );
- });
-
- it('throws error if fails', async () => {
- jest
- .spyOn(gqlClient, 'mutate')
- .mockResolvedValue({ data: { updateIssue: { errors: ['failed mutation'] } } });
-
- await expect(actions.setActiveIssueDueDate({ getters }, input)).rejects.toThrow(Error);
- });
-});
-
describe('setActiveItemSubscribed', () => {
const state = {
boardItems: {
@@ -1456,60 +1443,6 @@ describe('setActiveItemSubscribed', () => {
});
});
-describe('setActiveIssueMilestone', () => {
- const state = { boardItems: { [mockIssue.id]: mockIssue } };
- const getters = { activeBoardItem: mockIssue };
- const testMilestone = {
- ...mockMilestone,
- id: 'gid://gitlab/Milestone/1',
- };
- const input = {
- milestoneId: testMilestone.id,
- projectPath: 'h/b',
- };
-
- it('should commit milestone after setting the issue', (done) => {
- jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
- data: {
- updateIssue: {
- issue: {
- milestone: testMilestone,
- },
- errors: [],
- },
- },
- });
-
- const payload = {
- itemId: getters.activeBoardItem.id,
- prop: 'milestone',
- value: testMilestone,
- };
-
- testAction(
- actions.setActiveIssueMilestone,
- input,
- { ...state, ...getters },
- [
- {
- type: types.UPDATE_BOARD_ITEM_BY_ID,
- payload,
- },
- ],
- [],
- done,
- );
- });
-
- it('throws error if fails', async () => {
- jest
- .spyOn(gqlClient, 'mutate')
- .mockResolvedValue({ data: { updateIssue: { errors: ['failed mutation'] } } });
-
- await expect(actions.setActiveIssueMilestone({ getters }, input)).rejects.toThrow(Error);
- });
-});
-
describe('setActiveItemTitle', () => {
const state = {
boardItems: { [mockIssue.id]: mockIssue },
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index d89abcc79ae..5b38f04e77b 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -273,6 +273,53 @@ describe('Board Store Mutations', () => {
});
});
+ describe('RESET_ITEMS_FOR_LIST', () => {
+ it('should remove issues from boardItemsByListId state', () => {
+ const listId = 'gid://gitlab/List/1';
+ const boardItemsByListId = {
+ [listId]: [mockIssue.id],
+ };
+
+ state = {
+ ...state,
+ boardItemsByListId,
+ };
+
+ mutations[types.RESET_ITEMS_FOR_LIST](state, listId);
+
+ expect(state.boardItemsByListId[listId]).toEqual([]);
+ });
+ });
+
+ describe('REQUEST_ITEMS_FOR_LIST', () => {
+ const listId = 'gid://gitlab/List/1';
+ const boardItemsByListId = {
+ [listId]: [mockIssue.id],
+ };
+
+ it.each`
+ fetchNext | isLoading | isLoadingMore
+ ${true} | ${undefined} | ${true}
+ ${false} | ${true} | ${undefined}
+ `(
+ 'sets isLoading to $isLoading and isLoadingMore to $isLoadingMore when fetchNext is $fetchNext',
+ ({ fetchNext, isLoading, isLoadingMore }) => {
+ state = {
+ ...state,
+ boardItemsByListId,
+ listsFlags: {
+ [listId]: {},
+ },
+ };
+
+ mutations[types.REQUEST_ITEMS_FOR_LIST](state, { listId, fetchNext });
+
+ expect(state.listsFlags[listId].isLoading).toBe(isLoading);
+ expect(state.listsFlags[listId].isLoadingMore).toBe(isLoadingMore);
+ },
+ );
+ });
+
describe('RECEIVE_ITEMS_FOR_LIST_SUCCESS', () => {
it('updates boardItemsByListId and issues on state', () => {
const listIssues = {