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/components')
-rw-r--r--spec/frontend/boards/components/board_add_new_column_form_spec.js166
-rw-r--r--spec/frontend/boards/components/board_add_new_column_spec.js115
-rw-r--r--spec/frontend/boards/components/board_card_deprecated_spec.js219
-rw-r--r--spec/frontend/boards/components/board_card_layout_deprecated_spec.js2
-rw-r--r--spec/frontend/boards/components/board_card_layout_spec.js116
-rw-r--r--spec/frontend/boards/components/board_card_spec.js265
-rw-r--r--spec/frontend/boards/components/board_form_spec.js9
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js76
-rw-r--r--spec/frontend/boards/components/board_new_issue_spec.js3
-rw-r--r--spec/frontend/boards/components/filtered_search_spec.js65
-rw-r--r--spec/frontend/boards/components/item_count_spec.js (renamed from spec/frontend/boards/components/issue_count_spec.js)26
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js8
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js4
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js8
-rw-r--r--spec/frontend/boards/components/sidebar/remove_issue_spec.js28
17 files changed, 738 insertions, 384 deletions
diff --git a/spec/frontend/boards/components/board_add_new_column_form_spec.js b/spec/frontend/boards/components/board_add_new_column_form_spec.js
new file mode 100644
index 00000000000..3702f55f17b
--- /dev/null
+++ b/spec/frontend/boards/components/board_add_new_column_form_spec.js
@@ -0,0 +1,166 @@
+import { GlFormGroup, GlSearchBoxByType, GlSkeletonLoader } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+import Vuex from 'vuex';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import BoardAddNewColumnForm from '~/boards/components/board_add_new_column_form.vue';
+import defaultState from '~/boards/stores/state';
+import { mockLabelList } from '../mock_data';
+
+Vue.use(Vuex);
+
+describe('Board card layout', () => {
+ let wrapper;
+
+ const createStore = ({ actions = {}, getters = {}, state = {} } = {}) => {
+ return new Vuex.Store({
+ state: {
+ ...defaultState,
+ ...state,
+ },
+ actions,
+ getters,
+ });
+ };
+
+ const mountComponent = ({
+ loading = false,
+ formDescription = '',
+ searchLabel = '',
+ searchPlaceholder = '',
+ selectedId,
+ actions,
+ slots,
+ } = {}) => {
+ wrapper = extendedWrapper(
+ shallowMount(BoardAddNewColumnForm, {
+ stubs: {
+ GlFormGroup: true,
+ },
+ propsData: {
+ loading,
+ formDescription,
+ searchLabel,
+ searchPlaceholder,
+ selectedId,
+ },
+ slots,
+ store: createStore({
+ actions: {
+ setAddColumnFormVisibility: jest.fn(),
+ ...actions,
+ },
+ }),
+ }),
+ );
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const formTitle = () => wrapper.findByTestId('board-add-column-form-title').text();
+ const findSearchInput = () => wrapper.find(GlSearchBoxByType);
+ const findSearchLabel = () => wrapper.find(GlFormGroup);
+ const cancelButton = () => wrapper.findByTestId('cancelAddNewColumn');
+ const submitButton = () => wrapper.findByTestId('addNewColumnButton');
+
+ it('shows form title & search input', () => {
+ mountComponent();
+
+ expect(formTitle()).toEqual(BoardAddNewColumnForm.i18n.newList);
+ expect(findSearchInput().exists()).toBe(true);
+ });
+
+ it('clicking cancel hides the form', () => {
+ const setAddColumnFormVisibility = jest.fn();
+ mountComponent({
+ actions: {
+ setAddColumnFormVisibility,
+ },
+ });
+
+ cancelButton().vm.$emit('click');
+
+ expect(setAddColumnFormVisibility).toHaveBeenCalledWith(expect.anything(), false);
+ });
+
+ it('sets placeholder and description from props', () => {
+ const props = {
+ formDescription: 'Some description of a list',
+ };
+
+ mountComponent(props);
+
+ expect(wrapper.html()).toHaveText(props.formDescription);
+ });
+
+ describe('items', () => {
+ const mountWithItems = (loading) =>
+ mountComponent({
+ loading,
+ slots: {
+ items: '<div class="item-slot">Some kind of list</div>',
+ },
+ });
+
+ it('hides items slot and shows skeleton while loading', () => {
+ mountWithItems(true);
+
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
+ expect(wrapper.find('.item-slot').exists()).toBe(false);
+ });
+
+ it('shows items slot and hides skeleton while not loading', () => {
+ mountWithItems(false);
+
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(false);
+ expect(wrapper.find('.item-slot').exists()).toBe(true);
+ });
+ });
+
+ describe('search box', () => {
+ it('sets label and placeholder text from props', () => {
+ const props = {
+ searchLabel: 'Some items',
+ searchPlaceholder: 'Search for an item',
+ };
+
+ mountComponent(props);
+
+ expect(findSearchLabel().attributes('label')).toEqual(props.searchLabel);
+ expect(findSearchInput().attributes('placeholder')).toEqual(props.searchPlaceholder);
+ });
+
+ it('emits filter event on input', () => {
+ mountComponent();
+
+ const searchText = 'some text';
+
+ findSearchInput().vm.$emit('input', searchText);
+
+ expect(wrapper.emitted('filter-items')).toEqual([[searchText]]);
+ });
+ });
+
+ describe('Add list button', () => {
+ it('is disabled if no item is selected', () => {
+ mountComponent();
+
+ expect(submitButton().props('disabled')).toBe(true);
+ });
+
+ it('emits add-list event on click', async () => {
+ mountComponent({
+ selectedId: mockLabelList.label.id,
+ });
+
+ await nextTick();
+
+ submitButton().vm.$emit('click');
+
+ expect(wrapper.emitted('add-list')).toEqual([[]]);
+ });
+ });
+});
diff --git a/spec/frontend/boards/components/board_add_new_column_spec.js b/spec/frontend/boards/components/board_add_new_column_spec.js
new file mode 100644
index 00000000000..60584eaf6cf
--- /dev/null
+++ b/spec/frontend/boards/components/board_add_new_column_spec.js
@@ -0,0 +1,115 @@
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+import Vuex from 'vuex';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import BoardAddNewColumn from '~/boards/components/board_add_new_column.vue';
+import BoardAddNewColumnForm from '~/boards/components/board_add_new_column_form.vue';
+import defaultState from '~/boards/stores/state';
+import { mockLabelList } from '../mock_data';
+
+Vue.use(Vuex);
+
+describe('Board card layout', () => {
+ let wrapper;
+
+ const createStore = ({ actions = {}, getters = {}, state = {} } = {}) => {
+ return new Vuex.Store({
+ state: {
+ ...defaultState,
+ ...state,
+ },
+ actions,
+ getters,
+ });
+ };
+
+ const mountComponent = ({
+ selectedId,
+ labels = [],
+ getListByLabelId = jest.fn(),
+ actions = {},
+ } = {}) => {
+ wrapper = extendedWrapper(
+ shallowMount(BoardAddNewColumn, {
+ data() {
+ return {
+ selectedId,
+ };
+ },
+ store: createStore({
+ actions: {
+ fetchLabels: jest.fn(),
+ setAddColumnFormVisibility: jest.fn(),
+ ...actions,
+ },
+ getters: {
+ shouldUseGraphQL: () => true,
+ getListByLabelId: () => getListByLabelId,
+ },
+ state: {
+ labels,
+ labelsLoading: false,
+ isEpicBoard: false,
+ },
+ }),
+ provide: {
+ scopedLabelsAvailable: true,
+ },
+ }),
+ );
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('Add list button', () => {
+ it('calls addList', async () => {
+ const getListByLabelId = jest.fn().mockReturnValue(null);
+ const highlightList = jest.fn();
+ const createList = jest.fn();
+
+ mountComponent({
+ labels: [mockLabelList.label],
+ selectedId: mockLabelList.label.id,
+ getListByLabelId,
+ actions: {
+ createList,
+ highlightList,
+ },
+ });
+
+ wrapper.findComponent(BoardAddNewColumnForm).vm.$emit('add-list');
+
+ await nextTick();
+
+ expect(highlightList).not.toHaveBeenCalled();
+ expect(createList).toHaveBeenCalledWith(expect.anything(), {
+ labelId: mockLabelList.label.id,
+ });
+ });
+
+ it('highlights existing list if trying to re-add', async () => {
+ const getListByLabelId = jest.fn().mockReturnValue(mockLabelList);
+ const highlightList = jest.fn();
+ const createList = jest.fn();
+
+ mountComponent({
+ labels: [mockLabelList.label],
+ selectedId: mockLabelList.label.id,
+ getListByLabelId,
+ actions: {
+ createList,
+ highlightList,
+ },
+ });
+
+ wrapper.findComponent(BoardAddNewColumnForm).vm.$emit('add-list');
+
+ await nextTick();
+
+ expect(highlightList).toHaveBeenCalledWith(expect.anything(), mockLabelList.id);
+ expect(createList).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/boards/components/board_card_deprecated_spec.js b/spec/frontend/boards/components/board_card_deprecated_spec.js
new file mode 100644
index 00000000000..266cbc7106d
--- /dev/null
+++ b/spec/frontend/boards/components/board_card_deprecated_spec.js
@@ -0,0 +1,219 @@
+/* global List */
+/* global ListAssignee */
+/* global ListLabel */
+
+import { mount } from '@vue/test-utils';
+
+import MockAdapter from 'axios-mock-adapter';
+import waitForPromises from 'helpers/wait_for_promises';
+import BoardCardDeprecated from '~/boards/components/board_card_deprecated.vue';
+import issueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
+import eventHub from '~/boards/eventhub';
+import store from '~/boards/stores';
+import boardsStore from '~/boards/stores/boards_store';
+import axios from '~/lib/utils/axios_utils';
+
+import sidebarEventHub from '~/sidebar/event_hub';
+import '~/boards/models/label';
+import '~/boards/models/assignee';
+import '~/boards/models/list';
+import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
+
+describe('BoardCard', () => {
+ let wrapper;
+ let mock;
+ let list;
+
+ const findIssueCardInner = () => wrapper.find(issueCardInner);
+ const findUserAvatarLink = () => wrapper.find(userAvatarLink);
+
+ // this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
+ const mountComponent = (propsData) => {
+ wrapper = mount(BoardCardDeprecated, {
+ stubs: {
+ issueCardInner,
+ },
+ store,
+ propsData: {
+ list,
+ issue: list.issues[0],
+ disabled: false,
+ index: 0,
+ ...propsData,
+ },
+ provide: {
+ groupId: null,
+ rootPath: '/',
+ scopedLabelsAvailable: false,
+ },
+ });
+ };
+
+ const setupData = async () => {
+ list = new List(listObj);
+ boardsStore.create();
+ boardsStore.detail.issue = {};
+ const label1 = new ListLabel({
+ id: 3,
+ title: 'testing 123',
+ color: '#000cff',
+ text_color: 'white',
+ description: 'test',
+ });
+ await waitForPromises();
+
+ list.issues[0].labels.push(label1);
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onAny().reply(boardsMockInterceptor);
+ setMockEndpoints();
+ return setupData();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ list = null;
+ mock.restore();
+ });
+
+ it('when details issue is empty does not show the element', () => {
+ mountComponent();
+ expect(wrapper.find('[data-testid="board_card"').classes()).not.toContain('is-active');
+ });
+
+ it('when detailIssue is equal to card issue shows the element', () => {
+ [boardsStore.detail.issue] = list.issues;
+ mountComponent();
+
+ expect(wrapper.classes()).toContain('is-active');
+ });
+
+ it('when multiSelect does not contain issue removes multi select class', () => {
+ mountComponent();
+ expect(wrapper.classes()).not.toContain('multi-select');
+ });
+
+ it('when multiSelect contain issue add multi select class', () => {
+ boardsStore.multiSelect.list = [list.issues[0]];
+ mountComponent();
+
+ expect(wrapper.classes()).toContain('multi-select');
+ });
+
+ it('adds user-can-drag class if not disabled', () => {
+ mountComponent();
+ expect(wrapper.classes()).toContain('user-can-drag');
+ });
+
+ it('does not add user-can-drag class disabled', () => {
+ mountComponent({ disabled: true });
+
+ expect(wrapper.classes()).not.toContain('user-can-drag');
+ });
+
+ it('does not add disabled class', () => {
+ mountComponent();
+ expect(wrapper.classes()).not.toContain('is-disabled');
+ });
+
+ it('adds disabled class is disabled is true', () => {
+ mountComponent({ disabled: true });
+
+ expect(wrapper.classes()).toContain('is-disabled');
+ });
+
+ describe('mouse events', () => {
+ it('does not set detail issue if showDetail is false', () => {
+ mountComponent();
+ expect(boardsStore.detail.issue).toEqual({});
+ });
+
+ it('does not set detail issue if link is clicked', () => {
+ mountComponent();
+ findIssueCardInner().find('a').trigger('mouseup');
+
+ expect(boardsStore.detail.issue).toEqual({});
+ });
+
+ it('does not set detail issue if img is clicked', () => {
+ mountComponent({
+ issue: {
+ ...list.issues[0],
+ assignees: [
+ new ListAssignee({
+ id: 1,
+ name: 'testing 123',
+ username: 'test',
+ avatar: 'test_image',
+ }),
+ ],
+ },
+ });
+
+ findUserAvatarLink().trigger('mouseup');
+
+ expect(boardsStore.detail.issue).toEqual({});
+ });
+
+ it('does not set detail issue if showDetail is false after mouseup', () => {
+ mountComponent();
+ wrapper.trigger('mouseup');
+
+ expect(boardsStore.detail.issue).toEqual({});
+ });
+
+ it('sets detail issue to card issue on mouse up', () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+
+ mountComponent();
+
+ wrapper.trigger('mousedown');
+ wrapper.trigger('mouseup');
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', wrapper.vm.issue, false);
+ expect(boardsStore.detail.list).toEqual(wrapper.vm.list);
+ });
+
+ it('resets detail issue to empty if already set', () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ const [issue] = list.issues;
+ boardsStore.detail.issue = issue;
+ mountComponent();
+
+ wrapper.trigger('mousedown');
+ wrapper.trigger('mouseup');
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', false);
+ });
+ });
+
+ describe('sidebarHub events', () => {
+ it('closes all sidebars before showing an issue if no issues are opened', () => {
+ jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
+ boardsStore.detail.issue = {};
+ mountComponent();
+
+ // sets conditional so that event is emitted.
+ wrapper.trigger('mousedown');
+
+ wrapper.trigger('mouseup');
+
+ expect(sidebarEventHub.$emit).toHaveBeenCalledWith('sidebar.closeAll');
+ });
+
+ it('it does not closes all sidebars before showing an issue if an issue is opened', () => {
+ jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
+ const [issue] = list.issues;
+ boardsStore.detail.issue = issue;
+ mountComponent();
+
+ wrapper.trigger('mousedown');
+
+ expect(sidebarEventHub.$emit).not.toHaveBeenCalledWith('sidebar.closeAll');
+ });
+ });
+});
diff --git a/spec/frontend/boards/components/board_card_layout_deprecated_spec.js b/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
index 426c5289ba6..9853c9f434f 100644
--- a/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
+++ b/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
@@ -11,7 +11,7 @@ import '~/boards/models/label';
import '~/boards/models/assignee';
import '~/boards/models/list';
import BoardCardLayout from '~/boards/components/board_card_layout_deprecated.vue';
-import issueCardInner from '~/boards/components/issue_card_inner.vue';
+import issueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
import { ISSUABLE } from '~/boards/constants';
import boardsVuexStore from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
diff --git a/spec/frontend/boards/components/board_card_layout_spec.js b/spec/frontend/boards/components/board_card_layout_spec.js
deleted file mode 100644
index 3fa8714807c..00000000000
--- a/spec/frontend/boards/components/board_card_layout_spec.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import Vuex from 'vuex';
-
-import BoardCardLayout from '~/boards/components/board_card_layout.vue';
-import IssueCardInner from '~/boards/components/issue_card_inner.vue';
-import { ISSUABLE } from '~/boards/constants';
-import defaultState from '~/boards/stores/state';
-import { mockLabelList, mockIssue } from '../mock_data';
-
-describe('Board card layout', () => {
- let wrapper;
- let store;
-
- const localVue = createLocalVue();
- localVue.use(Vuex);
-
- const createStore = ({ getters = {}, actions = {} } = {}) => {
- store = new Vuex.Store({
- state: defaultState,
- actions,
- getters,
- });
- };
-
- // this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
- const mountComponent = ({ propsData = {}, provide = {} } = {}) => {
- wrapper = shallowMount(BoardCardLayout, {
- localVue,
- stubs: {
- IssueCardInner,
- },
- store,
- propsData: {
- list: mockLabelList,
- issue: mockIssue,
- disabled: false,
- index: 0,
- ...propsData,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- scopedLabelsAvailable: false,
- ...provide,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('mouse events', () => {
- it('sets showDetail to true on mousedown', async () => {
- createStore();
- mountComponent();
-
- wrapper.trigger('mousedown');
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.showDetail).toBe(true);
- });
-
- it('sets showDetail to false on mousemove', async () => {
- createStore();
- mountComponent();
- wrapper.trigger('mousedown');
- await wrapper.vm.$nextTick();
- expect(wrapper.vm.showDetail).toBe(true);
- wrapper.trigger('mousemove');
- await wrapper.vm.$nextTick();
- expect(wrapper.vm.showDetail).toBe(false);
- });
-
- it("calls 'setActiveId'", async () => {
- const setActiveId = jest.fn();
- createStore({
- actions: {
- setActiveId,
- },
- });
- mountComponent();
-
- wrapper.trigger('mouseup');
- await wrapper.vm.$nextTick();
-
- expect(setActiveId).toHaveBeenCalledTimes(1);
- expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
- id: mockIssue.id,
- sidebarType: ISSUABLE,
- });
- });
-
- it("calls 'setActiveId' when epic swimlanes is active", async () => {
- const setActiveId = jest.fn();
- const isSwimlanesOn = () => true;
- createStore({
- getters: { isSwimlanesOn },
- actions: {
- setActiveId,
- },
- });
- mountComponent();
-
- wrapper.trigger('mouseup');
- await wrapper.vm.$nextTick();
-
- expect(setActiveId).toHaveBeenCalledTimes(1);
- expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
- id: mockIssue.id,
- sidebarType: ISSUABLE,
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index 5f26ae1bb3b..022f8c05e1e 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -1,43 +1,50 @@
-/* global List */
-/* global ListAssignee */
-/* global ListLabel */
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
-import { mount } from '@vue/test-utils';
-
-import MockAdapter from 'axios-mock-adapter';
-import waitForPromises from 'helpers/wait_for_promises';
import BoardCard from '~/boards/components/board_card.vue';
-import issueCardInner from '~/boards/components/issue_card_inner.vue';
-import eventHub from '~/boards/eventhub';
-import store from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-
-import sidebarEventHub from '~/sidebar/event_hub';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/list';
-import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
-import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
-
-describe('BoardCard', () => {
- let wrapper;
- let mock;
- let list;
+import BoardCardInner from '~/boards/components/board_card_inner.vue';
+import { inactiveId } from '~/boards/constants';
+import { mockLabelList, mockIssue } from '../mock_data';
- const findIssueCardInner = () => wrapper.find(issueCardInner);
- const findUserAvatarLink = () => wrapper.find(userAvatarLink);
+describe('Board card', () => {
+ let wrapper;
+ let store;
+ let mockActions;
+
+ const localVue = createLocalVue();
+ localVue.use(Vuex);
+
+ const createStore = ({ initialState = {}, isSwimlanesOn = false } = {}) => {
+ mockActions = {
+ toggleBoardItem: jest.fn(),
+ toggleBoardItemMultiSelection: jest.fn(),
+ };
+
+ store = new Vuex.Store({
+ state: {
+ activeId: inactiveId,
+ selectedBoardItems: [],
+ ...initialState,
+ },
+ actions: mockActions,
+ getters: {
+ isSwimlanesOn: () => isSwimlanesOn,
+ isEpicBoard: () => false,
+ },
+ });
+ };
// this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
- const mountComponent = (propsData) => {
- wrapper = mount(BoardCard, {
+ const mountComponent = ({ propsData = {}, provide = {} } = {}) => {
+ wrapper = shallowMount(BoardCard, {
+ localVue,
stubs: {
- issueCardInner,
+ BoardCardInner,
},
store,
propsData: {
- list,
- issue: list.issues[0],
+ list: mockLabelList,
+ item: mockIssue,
disabled: false,
index: 0,
...propsData,
@@ -46,174 +53,94 @@ describe('BoardCard', () => {
groupId: null,
rootPath: '/',
scopedLabelsAvailable: false,
+ ...provide,
},
});
};
- const setupData = async () => {
- list = new List(listObj);
- boardsStore.create();
- boardsStore.detail.issue = {};
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: '#000cff',
- text_color: 'white',
- description: 'test',
- });
- await waitForPromises();
-
- list.issues[0].labels.push(label1);
+ const selectCard = async () => {
+ wrapper.trigger('mouseup');
+ await wrapper.vm.$nextTick();
};
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- setMockEndpoints();
- return setupData();
- });
+ const multiSelectCard = async () => {
+ wrapper.trigger('mouseup', { ctrlKey: true });
+ await wrapper.vm.$nextTick();
+ };
afterEach(() => {
wrapper.destroy();
wrapper = null;
- list = null;
- mock.restore();
- });
-
- it('when details issue is empty does not show the element', () => {
- mountComponent();
- expect(wrapper.find('[data-testid="board_card"').classes()).not.toContain('is-active');
- });
-
- it('when detailIssue is equal to card issue shows the element', () => {
- [boardsStore.detail.issue] = list.issues;
- mountComponent();
-
- expect(wrapper.classes()).toContain('is-active');
- });
-
- it('when multiSelect does not contain issue removes multi select class', () => {
- mountComponent();
- expect(wrapper.classes()).not.toContain('multi-select');
- });
-
- it('when multiSelect contain issue add multi select class', () => {
- boardsStore.multiSelect.list = [list.issues[0]];
- mountComponent();
-
- expect(wrapper.classes()).toContain('multi-select');
- });
-
- it('adds user-can-drag class if not disabled', () => {
- mountComponent();
- expect(wrapper.classes()).toContain('user-can-drag');
- });
-
- it('does not add user-can-drag class disabled', () => {
- mountComponent({ disabled: true });
-
- expect(wrapper.classes()).not.toContain('user-can-drag');
- });
-
- it('does not add disabled class', () => {
- mountComponent();
- expect(wrapper.classes()).not.toContain('is-disabled');
+ store = null;
});
- it('adds disabled class is disabled is true', () => {
- mountComponent({ disabled: true });
-
- expect(wrapper.classes()).toContain('is-disabled');
- });
-
- describe('mouse events', () => {
- it('does not set detail issue if showDetail is false', () => {
+ describe.each`
+ isSwimlanesOn
+ ${true} | ${false}
+ `('when isSwimlanesOn is $isSwimlanesOn', ({ isSwimlanesOn }) => {
+ it('should not highlight the card by default', async () => {
+ createStore({ isSwimlanesOn });
mountComponent();
- expect(boardsStore.detail.issue).toEqual({});
- });
- it('does not set detail issue if link is clicked', () => {
- mountComponent();
- findIssueCardInner().find('a').trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
+ expect(wrapper.classes()).not.toContain('is-active');
+ expect(wrapper.classes()).not.toContain('multi-select');
});
- it('does not set detail issue if img is clicked', () => {
- mountComponent({
- issue: {
- ...list.issues[0],
- assignees: [
- new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- }),
- ],
+ it('should highlight the card with a correct style when selected', async () => {
+ createStore({
+ initialState: {
+ activeId: mockIssue.id,
},
+ isSwimlanesOn,
});
-
- findUserAvatarLink().trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('does not set detail issue if showDetail is false after mouseup', () => {
- mountComponent();
- wrapper.trigger('mouseup');
-
- expect(boardsStore.detail.issue).toEqual({});
- });
-
- it('sets detail issue to card issue on mouse up', () => {
- jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
-
mountComponent();
- wrapper.trigger('mousedown');
- wrapper.trigger('mouseup');
-
- expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', wrapper.vm.issue, false);
- expect(boardsStore.detail.list).toEqual(wrapper.vm.list);
+ expect(wrapper.classes()).toContain('is-active');
+ expect(wrapper.classes()).not.toContain('multi-select');
});
- it('resets detail issue to empty if already set', () => {
- jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
- const [issue] = list.issues;
- boardsStore.detail.issue = issue;
+ it('should highlight the card with a correct style when multi-selected', async () => {
+ createStore({
+ initialState: {
+ activeId: inactiveId,
+ selectedBoardItems: [mockIssue],
+ },
+ isSwimlanesOn,
+ });
mountComponent();
- wrapper.trigger('mousedown');
- wrapper.trigger('mouseup');
-
- expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', false);
+ expect(wrapper.classes()).toContain('multi-select');
+ expect(wrapper.classes()).not.toContain('is-active');
});
- });
-
- describe('sidebarHub events', () => {
- it('closes all sidebars before showing an issue if no issues are opened', () => {
- jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
- boardsStore.detail.issue = {};
- mountComponent();
-
- // sets conditional so that event is emitted.
- wrapper.trigger('mousedown');
- wrapper.trigger('mouseup');
+ describe('when mouseup event is called on the card', () => {
+ beforeEach(() => {
+ createStore({ isSwimlanesOn });
+ mountComponent();
+ });
- expect(sidebarEventHub.$emit).toHaveBeenCalledWith('sidebar.closeAll');
- });
+ describe('when not using multi-select', () => {
+ it('should call vuex action "toggleBoardItem" with correct parameters', async () => {
+ await selectCard();
- it('it does not closes all sidebars before showing an issue if an issue is opened', () => {
- jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
- const [issue] = list.issues;
- boardsStore.detail.issue = issue;
- mountComponent();
+ expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(1);
+ expect(mockActions.toggleBoardItem).toHaveBeenCalledWith(expect.any(Object), {
+ boardItem: mockIssue,
+ });
+ });
+ });
- wrapper.trigger('mousedown');
+ describe('when using multi-select', () => {
+ it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
+ await multiSelectCard();
- expect(sidebarEventHub.$emit).not.toHaveBeenCalledWith('sidebar.closeAll');
+ expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledTimes(1);
+ expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledWith(
+ expect.any(Object),
+ mockIssue,
+ );
+ });
+ });
});
});
});
diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js
index 858efea99ad..32499bd5480 100644
--- a/spec/frontend/boards/components/board_form_spec.js
+++ b/spec/frontend/boards/components/board_form_spec.js
@@ -8,6 +8,7 @@ import { formType } from '~/boards/constants';
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';
@@ -48,6 +49,13 @@ describe('BoardForm', () => {
const findDeleteConfirmation = () => wrapper.find('[data-testid="delete-confirmation-message"]');
const findInput = () => wrapper.find('#board-new-name');
+ const store = createStore({
+ getters: {
+ isGroupBoard: () => true,
+ isProjectBoard: () => false,
+ },
+ });
+
const createComponent = (props, data) => {
wrapper = shallowMount(BoardForm, {
propsData: { ...defaultProps, ...props },
@@ -64,6 +72,7 @@ describe('BoardForm', () => {
mutate,
},
},
+ store,
attachTo: document.body,
});
};
diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js
index f30e3792435..d2dfb4148b3 100644
--- a/spec/frontend/boards/components/board_list_header_spec.js
+++ b/spec/frontend/boards/components/board_list_header_spec.js
@@ -1,5 +1,6 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { mockLabelList } from 'jest/boards/mock_data';
import BoardListHeader from '~/boards/components/board_list_header.vue';
@@ -14,6 +15,7 @@ describe('Board List Header Component', () => {
let store;
const updateListSpy = jest.fn();
+ const toggleListCollapsedSpy = jest.fn();
afterEach(() => {
wrapper.destroy();
@@ -43,38 +45,39 @@ describe('Board List Header Component', () => {
if (withLocalStorage) {
localStorage.setItem(
- `boards.${boardId}.${listMock.listType}.${listMock.id}.expanded`,
- (!collapsed).toString(),
+ `boards.${boardId}.${listMock.listType}.${listMock.id}.collapsed`,
+ collapsed.toString(),
);
}
store = new Vuex.Store({
state: {},
- actions: { updateList: updateListSpy },
- getters: {},
+ actions: { updateList: updateListSpy, toggleListCollapsed: toggleListCollapsedSpy },
+ getters: { isEpicBoard: () => false },
});
- wrapper = shallowMount(BoardListHeader, {
- store,
- localVue,
- propsData: {
- disabled: false,
- list: listMock,
- },
- provide: {
- boardId,
- weightFeatureAvailable: false,
- currentUserId,
- },
- });
+ wrapper = extendedWrapper(
+ shallowMount(BoardListHeader, {
+ store,
+ localVue,
+ propsData: {
+ disabled: false,
+ list: listMock,
+ },
+ provide: {
+ boardId,
+ weightFeatureAvailable: false,
+ currentUserId,
+ },
+ }),
+ );
};
const isCollapsed = () => wrapper.vm.list.collapsed;
- const isExpanded = () => !isCollapsed;
const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' });
const findTitle = () => wrapper.find('.board-title');
- const findCaret = () => wrapper.find('.board-title-caret');
+ const findCaret = () => wrapper.findByTestId('board-title-caret');
describe('Add issue button', () => {
const hasNoAddButton = [ListType.closed];
@@ -114,40 +117,29 @@ describe('Board List Header Component', () => {
});
describe('expanding / collapsing the column', () => {
- it('does not collapse when clicking the header', async () => {
+ it('should display collapse icon when column is expanded', async () => {
createComponent();
- expect(isCollapsed()).toBe(false);
-
- wrapper.find('[data-testid="board-list-header"]').trigger('click');
+ const icon = findCaret();
- await wrapper.vm.$nextTick();
-
- expect(isCollapsed()).toBe(false);
+ expect(icon.props('icon')).toBe('chevron-right');
});
- it('collapses expanded Column when clicking the collapse icon', async () => {
- createComponent();
-
- expect(isCollapsed()).toBe(false);
-
- findCaret().vm.$emit('click');
+ it('should display expand icon when column is collapsed', async () => {
+ createComponent({ collapsed: true });
- await wrapper.vm.$nextTick();
+ const icon = findCaret();
- expect(isCollapsed()).toBe(true);
+ expect(icon.props('icon')).toBe('chevron-down');
});
- it('expands collapsed Column when clicking the expand icon', async () => {
- createComponent({ collapsed: true });
-
- expect(isCollapsed()).toBe(true);
+ it('should dispatch toggleListCollapse when clicking the collapse icon', async () => {
+ createComponent();
findCaret().vm.$emit('click');
await wrapper.vm.$nextTick();
-
- expect(isCollapsed()).toBe(false);
+ expect(toggleListCollapsedSpy).toHaveBeenCalledTimes(1);
});
it("when logged in it calls list update and doesn't set localStorage", async () => {
@@ -157,7 +149,7 @@ describe('Board List Header Component', () => {
await wrapper.vm.$nextTick();
expect(updateListSpy).toHaveBeenCalledTimes(1);
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(null);
+ expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(null);
});
it("when logged out it doesn't call list update and sets localStorage", async () => {
@@ -167,7 +159,7 @@ describe('Board List Header Component', () => {
await wrapper.vm.$nextTick();
expect(updateListSpy).not.toHaveBeenCalled();
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(String(isExpanded()));
+ expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.collapsed`)).toBe(String(isCollapsed()));
});
});
diff --git a/spec/frontend/boards/components/board_new_issue_spec.js b/spec/frontend/boards/components/board_new_issue_spec.js
index ce8c95527e9..737a18294bc 100644
--- a/spec/frontend/boards/components/board_new_issue_spec.js
+++ b/spec/frontend/boards/components/board_new_issue_spec.js
@@ -2,7 +2,6 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import BoardNewIssue from '~/boards/components/board_new_issue.vue';
-import '~/boards/models/list';
import { mockList, mockGroupProjects } from '../mock_data';
const localVue = createLocalVue();
@@ -31,7 +30,7 @@ describe('Issue boards new issue form', () => {
const store = new Vuex.Store({
state: { selectedProject: mockGroupProjects[0] },
actions: { addListNewIssue: addListNewIssuesSpy },
- getters: {},
+ getters: { isGroupBoard: () => false, isProjectBoard: () => true },
});
wrapper = shallowMount(BoardNewIssue, {
diff --git a/spec/frontend/boards/components/filtered_search_spec.js b/spec/frontend/boards/components/filtered_search_spec.js
new file mode 100644
index 00000000000..7f238aa671f
--- /dev/null
+++ b/spec/frontend/boards/components/filtered_search_spec.js
@@ -0,0 +1,65 @@
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import FilteredSearch from '~/boards/components/filtered_search.vue';
+import { createStore } from '~/boards/stores';
+import * as commonUtils from '~/lib/utils/common_utils';
+import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('FilteredSearch', () => {
+ let wrapper;
+ let store;
+
+ const createComponent = () => {
+ wrapper = shallowMount(FilteredSearch, {
+ localVue,
+ propsData: { search: '' },
+ store,
+ attachTo: document.body,
+ });
+ };
+
+ beforeEach(() => {
+ // this needed for actions call for performSearch
+ window.gon = { features: {} };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('default', () => {
+ beforeEach(() => {
+ store = createStore();
+
+ jest.spyOn(store, 'dispatch');
+
+ createComponent();
+ });
+
+ it('finds FilteredSearch', () => {
+ expect(wrapper.find(FilteredSearchBarRoot).exists()).toBe(true);
+ });
+
+ describe('when onFilter is emitted', () => {
+ it('calls performSearch', () => {
+ wrapper.find(FilteredSearchBarRoot).vm.$emit('onFilter', [{ value: { data: '' } }]);
+
+ expect(store.dispatch).toHaveBeenCalledWith('performSearch');
+ });
+
+ it('calls historyPushState', () => {
+ commonUtils.historyPushState = jest.fn();
+ wrapper
+ .find(FilteredSearchBarRoot)
+ .vm.$emit('onFilter', [{ value: { data: 'searchQuery' } }]);
+
+ expect(commonUtils.historyPushState).toHaveBeenCalledWith(
+ 'http://test.host/?search=searchQuery',
+ );
+ });
+ });
+ });
+});
diff --git a/spec/frontend/boards/components/issue_count_spec.js b/spec/frontend/boards/components/item_count_spec.js
index f1870e9cc9e..45980c36f1c 100644
--- a/spec/frontend/boards/components/issue_count_spec.js
+++ b/spec/frontend/boards/components/item_count_spec.js
@@ -1,10 +1,10 @@
import { shallowMount } from '@vue/test-utils';
-import IssueCount from '~/boards/components/issue_count.vue';
+import IssueCount from '~/boards/components/item_count.vue';
describe('IssueCount', () => {
let vm;
let maxIssueCount;
- let issuesSize;
+ let itemsSize;
const createComponent = (props) => {
vm = shallowMount(IssueCount, { propsData: props });
@@ -12,20 +12,20 @@ describe('IssueCount', () => {
afterEach(() => {
maxIssueCount = 0;
- issuesSize = 0;
+ itemsSize = 0;
if (vm) vm.destroy();
});
describe('when maxIssueCount is zero', () => {
beforeEach(() => {
- issuesSize = 3;
+ itemsSize = 3;
- createComponent({ maxIssueCount: 0, issuesSize });
+ createComponent({ maxIssueCount: 0, itemsSize });
});
it('contains issueSize in the template', () => {
- expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
+ expect(vm.find('[data-testid="board-items-count"]').text()).toEqual(String(itemsSize));
});
it('does not contains maxIssueCount in the template', () => {
@@ -36,9 +36,9 @@ describe('IssueCount', () => {
describe('when maxIssueCount is greater than zero', () => {
beforeEach(() => {
maxIssueCount = 2;
- issuesSize = 1;
+ itemsSize = 1;
- createComponent({ maxIssueCount, issuesSize });
+ createComponent({ maxIssueCount, itemsSize });
});
afterEach(() => {
@@ -46,7 +46,7 @@ describe('IssueCount', () => {
});
it('contains issueSize in the template', () => {
- expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
+ expect(vm.find('[data-testid="board-items-count"]').text()).toEqual(String(itemsSize));
});
it('contains maxIssueCount in the template', () => {
@@ -60,10 +60,10 @@ describe('IssueCount', () => {
describe('when issueSize is greater than maxIssueCount', () => {
beforeEach(() => {
- issuesSize = 3;
+ itemsSize = 3;
maxIssueCount = 2;
- createComponent({ maxIssueCount, issuesSize });
+ createComponent({ maxIssueCount, itemsSize });
});
afterEach(() => {
@@ -71,7 +71,7 @@ describe('IssueCount', () => {
});
it('contains issueSize in the template', () => {
- expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
+ expect(vm.find('[data-testid="board-items-count"]').text()).toEqual(String(itemsSize));
});
it('contains maxIssueCount in the template', () => {
@@ -79,7 +79,7 @@ describe('IssueCount', () => {
});
it('has text-danger class', () => {
- expect(vm.find('.text-danger').text()).toEqual(String(issuesSize));
+ expect(vm.find('.text-danger').text()).toEqual(String(itemsSize));
});
});
});
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
index 7838b5a0b2f..8fd178a0856 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
@@ -24,7 +24,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
const createWrapper = ({ dueDate = null } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, dueDate } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, dueDate } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarDueDate, {
@@ -61,7 +61,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = TEST_DUE_DATE;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = TEST_DUE_DATE;
});
findDatePicker().vm.$emit('input', TEST_PARSED_DATE);
await wrapper.vm.$nextTick();
@@ -86,7 +86,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = null;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = null;
});
findDatePicker().vm.$emit('clear');
await wrapper.vm.$nextTick();
@@ -104,7 +104,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper({ dueDate: TEST_DUE_DATE });
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = null;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = null;
});
findResetButton().vm.$emit('click');
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
index bc7df1c76c6..723d0345f76 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
@@ -34,7 +34,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
const createWrapper = (issue = TEST_ISSUE_A) => {
store = createStore();
- store.state.issues = { [issue.id]: { ...issue } };
+ store.state.boardItems = { [issue.id]: { ...issue } };
store.dispatch('setActiveId', { id: issue.id });
wrapper = shallowMount(BoardSidebarIssueTitle, {
@@ -74,7 +74,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueTitle').mockImplementation(() => {
- store.state.issues[TEST_ISSUE_A.id].title = TEST_TITLE;
+ store.state.boardItems[TEST_ISSUE_A.id].title = TEST_TITLE;
});
findFormInput().vm.$emit('input', TEST_TITLE);
findForm().vm.$emit('submit', { preventDefault: () => {} });
@@ -147,7 +147,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
createWrapper(TEST_ISSUE_B);
jest.spyOn(wrapper.vm, 'setActiveIssueTitle').mockImplementation(() => {
- store.state.issues[TEST_ISSUE_B.id].title = TEST_TITLE;
+ store.state.boardItems[TEST_ISSUE_B.id].title = TEST_TITLE;
});
findFormInput().vm.$emit('input', TEST_TITLE);
findCancelButton().vm.$emit('click');
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 12b873ba7d8..98ac211238c 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
@@ -25,7 +25,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
const createWrapper = ({ labels = [] } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, labels } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, labels } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarLabelsSelect, {
@@ -66,7 +66,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveIssueLabels').mockImplementation(() => TEST_LABELS);
findLabelsSelect().vm.$emit('updateSelectedLabels', TEST_LABELS_PAYLOAD);
- store.state.issues[TEST_ISSUE.id].labels = TEST_LABELS;
+ store.state.boardItems[TEST_ISSUE.id].labels = TEST_LABELS;
await wrapper.vm.$nextTick();
});
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
index 8820ec7ae63..8706424a296 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
@@ -22,7 +22,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
const createWrapper = ({ milestone = null, loading = false } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, milestone } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, milestone } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarMilestoneSelect, {
@@ -113,7 +113,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].milestone = TEST_MILESTONE;
+ store.state.boardItems[TEST_ISSUE.id].milestone = TEST_MILESTONE;
});
findDropdownItem().vm.$emit('click');
await wrapper.vm.$nextTick();
@@ -137,7 +137,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
createWrapper({ milestone: TEST_MILESTONE });
jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].milestone = null;
+ store.state.boardItems[TEST_ISSUE.id].milestone = null;
});
findUnsetMilestoneItem().vm.$emit('click');
await wrapper.vm.$nextTick();
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 3e6b0be0267..cfd7f32b2cc 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
@@ -22,7 +22,7 @@ describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () =
const createComponent = (activeIssue = { ...mockActiveIssue }) => {
store = createStore();
- store.state.issues = { [activeIssue.id]: activeIssue };
+ store.state.boardItems = { [activeIssue.id]: activeIssue };
store.state.activeId = activeIssue.id;
wrapper = mount(BoardSidebarSubscription, {
@@ -45,6 +45,12 @@ describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () =
expect(findNotificationHeader().text()).toBe('Notifications');
});
+ it('renders toggle with label', () => {
+ createComponent();
+
+ expect(findToggle().props('label')).toBe(BoardSidebarSubscription.i18n.header.title);
+ });
+
it('renders toggle as "off" when currently not subscribed', () => {
createComponent();
diff --git a/spec/frontend/boards/components/sidebar/remove_issue_spec.js b/spec/frontend/boards/components/sidebar/remove_issue_spec.js
deleted file mode 100644
index 1f740c10106..00000000000
--- a/spec/frontend/boards/components/sidebar/remove_issue_spec.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-
-import RemoveIssue from '~/boards/components/sidebar/remove_issue.vue';
-
-describe('boards sidebar remove issue', () => {
- let wrapper;
-
- const findButton = () => wrapper.find(GlButton);
-
- const createComponent = (propsData) => {
- wrapper = shallowMount(RemoveIssue, {
- propsData: {
- issue: {},
- list: {},
- ...propsData,
- },
- });
- };
-
- beforeEach(() => {
- createComponent();
- });
-
- it('renders remove button', () => {
- expect(findButton().exists()).toBe(true);
- });
-});