summaryrefslogtreecommitdiff
path: root/spec/frontend/boards
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/boards')
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js33
-rw-r--r--spec/frontend/boards/board_list_deprecated_spec.js274
-rw-r--r--spec/frontend/boards/board_new_issue_deprecated_spec.js211
-rw-r--r--spec/frontend/boards/boards_store_spec.js1013
-rw-r--r--spec/frontend/boards/components/board_add_new_column_spec.js1
-rw-r--r--spec/frontend/boards/components/board_app_spec.js54
-rw-r--r--spec/frontend/boards/components/board_card_deprecated_spec.js219
-rw-r--r--spec/frontend/boards/components/board_card_layout_deprecated_spec.js158
-rw-r--r--spec/frontend/boards/components/board_column_deprecated_spec.js106
-rw-r--r--spec/frontend/boards/components/board_content_spec.js75
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js22
-rw-r--r--spec/frontend/boards/components/board_list_header_deprecated_spec.js174
-rw-r--r--spec/frontend/boards/components/board_settings_sidebar_spec.js142
-rw-r--r--spec/frontend/boards/components/boards_selector_deprecated_spec.js214
-rw-r--r--spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js64
-rw-r--r--spec/frontend/boards/issue_card_deprecated_spec.js332
-rw-r--r--spec/frontend/boards/issue_spec.js162
-rw-r--r--spec/frontend/boards/list_spec.js230
-rw-r--r--spec/frontend/boards/mock_data.js89
-rw-r--r--spec/frontend/boards/project_select_deprecated_spec.js263
-rw-r--r--spec/frontend/boards/stores/actions_spec.js23
-rw-r--r--spec/frontend/boards/stores/getters_spec.js16
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js6
23 files changed, 235 insertions, 3646 deletions
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 7d3ecc773a6..e0446811f64 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -2,6 +2,7 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
@@ -44,6 +45,7 @@ describe('Board card component', () => {
const findEpicBadgeProgress = () => wrapper.findByTestId('epic-progress');
const findEpicCountablesTotalWeight = () => wrapper.findByTestId('epic-countables-total-weight');
const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content');
+ const findHiddenIssueIcon = () => wrapper.findByTestId('hidden-icon');
const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => {
store = new Vuex.Store({
@@ -72,6 +74,9 @@ describe('Board card component', () => {
GlLabel: true,
GlLoadingIcon: true,
},
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
mocks: {
$apollo: {
queries: {
@@ -122,6 +127,10 @@ describe('Board card component', () => {
expect(wrapper.find('.confidential-icon').exists()).toBe(false);
});
+ it('does not render hidden issue icon', () => {
+ expect(findHiddenIssueIcon().exists()).toBe(false);
+ });
+
it('renders issue ID with #', () => {
expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.iid}`);
});
@@ -184,6 +193,30 @@ describe('Board card component', () => {
});
});
+ describe('hidden issue', () => {
+ beforeEach(() => {
+ wrapper.setProps({
+ item: {
+ ...wrapper.props('item'),
+ hidden: true,
+ },
+ });
+ });
+
+ it('renders hidden issue icon', () => {
+ expect(findHiddenIssueIcon().exists()).toBe(true);
+ });
+
+ it('displays a tooltip which explains the meaning of the icon', () => {
+ const tooltip = getBinding(findHiddenIssueIcon().element, 'gl-tooltip');
+
+ expect(tooltip).toBeDefined();
+ expect(findHiddenIssueIcon().attributes('title')).toBe(
+ 'This issue is hidden because its author has been banned',
+ );
+ });
+ });
+
describe('with assignee', () => {
describe('with avatar', () => {
beforeEach(() => {
diff --git a/spec/frontend/boards/board_list_deprecated_spec.js b/spec/frontend/boards/board_list_deprecated_spec.js
deleted file mode 100644
index b71564f7858..00000000000
--- a/spec/frontend/boards/board_list_deprecated_spec.js
+++ /dev/null
@@ -1,274 +0,0 @@
-/* global List */
-/* global ListIssue */
-import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-import waitForPromises from 'helpers/wait_for_promises';
-import BoardList from '~/boards/components/board_list_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 '~/boards/models/issue';
-import '~/boards/models/list';
-import { listObj, boardsMockInterceptor } from './mock_data';
-
-const createComponent = ({ done, listIssueProps = {}, componentProps = {}, listProps = {} }) => {
- const el = document.createElement('div');
-
- document.body.appendChild(el);
- const mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- boardsStore.create();
-
- const BoardListComp = Vue.extend(BoardList);
- const list = new List({ ...listObj, ...listProps });
- const issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [],
- assignees: [],
- ...listIssueProps,
- });
- if (!Object.prototype.hasOwnProperty.call(listProps, 'issuesSize')) {
- list.issuesSize = 1;
- }
- list.issues.push(issue);
-
- const component = new BoardListComp({
- el,
- store,
- propsData: {
- disabled: false,
- list,
- issues: list.issues,
- ...componentProps,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- },
- }).$mount();
-
- Vue.nextTick(() => {
- done();
- });
-
- return { component, mock };
-};
-
-describe('Board list component', () => {
- let mock;
- let component;
- let getIssues;
- function generateIssues(compWrapper) {
- for (let i = 1; i < 20; i += 1) {
- const issue = { ...compWrapper.list.issues[0] };
- issue.id += i;
- compWrapper.list.issues.push(issue);
- }
- }
-
- describe('When Expanded', () => {
- beforeEach((done) => {
- getIssues = jest.spyOn(List.prototype, 'getIssues').mockReturnValue(new Promise(() => {}));
- ({ mock, component } = createComponent({ done }));
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- it('loads first page of issues', () => {
- return waitForPromises().then(() => {
- expect(getIssues).toHaveBeenCalled();
- });
- });
-
- it('renders component', () => {
- expect(component.$el.classList.contains('board-list-component')).toBe(true);
- });
-
- it('renders loading icon', () => {
- component.list.loading = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-loading')).not.toBeNull();
- });
- });
-
- it('renders issues', () => {
- expect(component.$el.querySelectorAll('.board-card').length).toBe(1);
- });
-
- it('sets data attribute with issue id', () => {
- expect(component.$el.querySelector('.board-card').getAttribute('data-issue-id')).toBe('1');
- });
-
- it('shows new issue form', () => {
- component.toggleForm();
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
-
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- });
- });
-
- it('shows new issue form after eventhub event', () => {
- eventHub.$emit(`toggle-issue-form-${component.list.id}`);
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).not.toBeNull();
-
- expect(component.$el.querySelector('.is-smaller')).not.toBeNull();
- });
- });
-
- it('does not show new issue form for closed list', () => {
- component.list.type = 'closed';
- component.toggleForm();
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-new-issue-form')).toBeNull();
- });
- });
-
- it('shows count list item', () => {
- component.showCount = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count')).not.toBeNull();
-
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing all issues',
- );
- });
- });
-
- it('sets data attribute with invalid id', () => {
- component.showCount = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count').getAttribute('data-issue-id')).toBe(
- '-1',
- );
- });
- });
-
- it('shows how many more issues to load', () => {
- component.showCount = true;
- component.list.issuesSize = 20;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count').textContent.trim()).toBe(
- 'Showing 1 of 20 issues',
- );
- });
- });
-
- it('loads more issues after scrolling', () => {
- jest.spyOn(component.list, 'nextPage').mockImplementation(() => {});
- generateIssues(component);
- component.$refs.list.dispatchEvent(new Event('scroll'));
-
- return waitForPromises().then(() => {
- expect(component.list.nextPage).toHaveBeenCalled();
- });
- });
-
- it('does not load issues if already loading', () => {
- component.list.nextPage = jest
- .spyOn(component.list, 'nextPage')
- .mockReturnValue(new Promise(() => {}));
-
- component.onScroll();
- component.onScroll();
-
- return waitForPromises().then(() => {
- expect(component.list.nextPage).toHaveBeenCalledTimes(1);
- });
- });
-
- it('shows loading more spinner', () => {
- component.showCount = true;
- component.list.loadingMore = true;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.board-list-count .gl-spinner')).not.toBeNull();
- });
- });
- });
-
- describe('When Collapsed', () => {
- beforeEach((done) => {
- getIssues = jest.spyOn(List.prototype, 'getIssues').mockReturnValue(new Promise(() => {}));
- ({ mock, component } = createComponent({
- done,
- listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
- }));
- generateIssues(component);
- component.scrollHeight = jest.spyOn(component, 'scrollHeight').mockReturnValue(0);
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- it('does not load all issues', () => {
- return waitForPromises().then(() => {
- // Initial getIssues from list constructor
- expect(getIssues).toHaveBeenCalledTimes(1);
- });
- });
- });
-
- describe('max issue count warning', () => {
- beforeEach((done) => {
- ({ mock, component } = createComponent({
- done,
- listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
- }));
- });
-
- afterEach(() => {
- mock.restore();
- component.$destroy();
- });
-
- describe('when issue count exceeds max issue count', () => {
- it('sets background to bg-danger-100', () => {
- component.list.issuesSize = 4;
- component.list.maxIssueCount = 3;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).not.toBeNull();
- });
- });
- });
-
- describe('when list issue count does NOT exceed list max issue count', () => {
- it('does not sets background to bg-danger-100', () => {
- component.list.issuesSize = 2;
- component.list.maxIssueCount = 3;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
- });
- });
- });
-
- describe('when list max issue count is 0', () => {
- it('does not sets background to bg-danger-100', () => {
- component.list.maxIssueCount = 0;
-
- return Vue.nextTick().then(() => {
- expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/board_new_issue_deprecated_spec.js b/spec/frontend/boards/board_new_issue_deprecated_spec.js
deleted file mode 100644
index 3beaf870bf5..00000000000
--- a/spec/frontend/boards/board_new_issue_deprecated_spec.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* global List */
-
-import { mount } from '@vue/test-utils';
-import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-import Vuex from 'vuex';
-import boardNewIssue from '~/boards/components/board_new_issue_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-
-import '~/boards/models/list';
-import { listObj, boardsMockInterceptor } from './mock_data';
-
-Vue.use(Vuex);
-
-describe('Issue boards new issue form', () => {
- let wrapper;
- let vm;
- let list;
- let mock;
- let newIssueMock;
- const promiseReturn = {
- data: {
- iid: 100,
- },
- };
-
- const submitIssue = () => {
- const dummySubmitEvent = {
- preventDefault() {},
- };
- wrapper.vm.$refs.submitButton = wrapper.find({ ref: 'submitButton' });
- return wrapper.vm.submit(dummySubmitEvent);
- };
-
- beforeEach(() => {
- const BoardNewIssueComp = Vue.extend(boardNewIssue);
-
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
-
- boardsStore.create();
-
- list = new List(listObj);
-
- newIssueMock = Promise.resolve(promiseReturn);
- jest.spyOn(list, 'newIssue').mockImplementation(() => newIssueMock);
-
- const store = new Vuex.Store({
- getters: { isGroupBoard: () => false },
- });
-
- wrapper = mount(BoardNewIssueComp, {
- propsData: {
- disabled: false,
- list,
- },
- store,
- provide: {
- groupId: null,
- },
- });
-
- vm = wrapper.vm;
-
- return Vue.nextTick();
- });
-
- afterEach(() => {
- wrapper.destroy();
- mock.restore();
- });
-
- it('calls submit if submit button is clicked', () => {
- jest.spyOn(wrapper.vm, 'submit').mockImplementation();
- vm.title = 'Testing Title';
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(wrapper.vm.submit).toHaveBeenCalled();
- });
- });
-
- it('disables submit button if title is empty', () => {
- expect(wrapper.find({ ref: 'submitButton' }).props().disabled).toBe(true);
- });
-
- it('enables submit button if title is not empty', () => {
- wrapper.setData({ title: 'Testing Title' });
-
- return Vue.nextTick().then(() => {
- expect(wrapper.find({ ref: 'input' }).element.value).toBe('Testing Title');
- expect(wrapper.find({ ref: 'submitButton' }).props().disabled).toBe(false);
- });
- });
-
- it('clears title after clicking cancel', () => {
- wrapper.find({ ref: 'cancelButton' }).trigger('click');
-
- return Vue.nextTick().then(() => {
- expect(vm.title).toBe('');
- });
- });
-
- it('does not create new issue if title is empty', () => {
- return submitIssue().then(() => {
- expect(list.newIssue).not.toHaveBeenCalled();
- });
- });
-
- describe('submit success', () => {
- it('creates new issue', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(list.newIssue).toHaveBeenCalled();
- });
- });
-
- it('enables button after submit', () => {
- jest.spyOn(wrapper.vm, 'submit').mockImplementation();
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(wrapper.vm.$refs.submitButton.props().disabled).toBe(false);
- });
- });
-
- it('clears title after submit', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(vm.title).toBe('');
- });
- });
-
- it('sets detail issue after submit', () => {
- expect(boardsStore.detail.issue.title).toBe(undefined);
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.issue.title).toBe('create issue');
- });
- });
-
- it('sets detail list after submit', () => {
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.id).toBe(list.id);
- });
- });
-
- it('sets detail weight after submit', () => {
- boardsStore.weightFeatureAvailable = true;
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.weight).toBe(list.weight);
- });
- });
-
- it('does not set detail weight after submit', () => {
- boardsStore.weightFeatureAvailable = false;
- wrapper.setData({ title: 'create issue' });
-
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(boardsStore.detail.list.weight).toBe(list.weight);
- });
- });
- });
-
- describe('submit error', () => {
- beforeEach(() => {
- newIssueMock = Promise.reject(new Error('My hovercraft is full of eels!'));
- vm.title = 'error';
- });
-
- it('removes issue', () => {
- const lengthBefore = list.issues.length;
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(list.issues.length).toBe(lengthBefore);
- });
- });
-
- it('shows error', () => {
- return Vue.nextTick()
- .then(submitIssue)
- .then(() => {
- expect(vm.error).toBe(true);
- });
- });
- });
-});
diff --git a/spec/frontend/boards/boards_store_spec.js b/spec/frontend/boards/boards_store_spec.js
deleted file mode 100644
index 02881333273..00000000000
--- a/spec/frontend/boards/boards_store_spec.js
+++ /dev/null
@@ -1,1013 +0,0 @@
-import AxiosMockAdapter from 'axios-mock-adapter';
-import { TEST_HOST } from 'helpers/test_constants';
-import eventHub from '~/boards/eventhub';
-
-import ListIssue from '~/boards/models/issue';
-import List from '~/boards/models/list';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, listObjDuplicate } from './mock_data';
-
-jest.mock('js-cookie');
-
-const createTestIssue = () => ({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [],
- assignees: [],
-});
-
-describe('boardsStore', () => {
- const dummyResponse = "without type checking this doesn't matter";
- const boardId = 'dummy-board-id';
- const endpoints = {
- boardsEndpoint: `${TEST_HOST}/boards`,
- listsEndpoint: `${TEST_HOST}/lists`,
- bulkUpdatePath: `${TEST_HOST}/bulk/update`,
- recentBoardsEndpoint: `${TEST_HOST}/recent/boards`,
- };
-
- let axiosMock;
-
- beforeEach(() => {
- axiosMock = new AxiosMockAdapter(axios);
- boardsStore.setEndpoints({
- ...endpoints,
- boardId,
- });
- });
-
- afterEach(() => {
- axiosMock.restore();
- });
-
- const setupDefaultResponses = () => {
- axiosMock
- .onGet(`${endpoints.listsEndpoint}/${listObj.id}/issues?id=${listObj.id}&page=1`)
- .reply(200, { issues: [createTestIssue()] });
- axiosMock.onPost(endpoints.listsEndpoint).reply(200, listObj);
- axiosMock.onPut();
- };
-
- describe('all', () => {
- it('makes a request to fetch lists', () => {
- axiosMock.onGet(endpoints.listsEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.all()).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(endpoints.listsEndpoint).replyOnce(500);
-
- return expect(boardsStore.all()).rejects.toThrow();
- });
- });
-
- describe('createList', () => {
- const entityType = 'moorhen';
- const entityId = 'quack';
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({ list: { [entityType]: entityId } }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(endpoints.listsEndpoint).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.createList(entityId, entityType))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.createList(entityId, entityType))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('updateList', () => {
- const id = 'David Webb';
- const position = 'unknown';
- const collapsed = false;
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({ list: { position, collapsed } }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPut(`${endpoints.listsEndpoint}/${id}`).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to update a list position', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.updateList(id, position, collapsed))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.updateList(id, position, collapsed))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('destroyList', () => {
- const id = '-42';
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock
- .onDelete(`${endpoints.listsEndpoint}/${id}`)
- .replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to delete a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.destroyList(id))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalled();
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.destroyList(id))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalled();
- });
- });
- });
-
- describe('saveList', () => {
- let list;
-
- beforeEach(() => {
- list = new List(listObj);
- setupDefaultResponses();
- });
-
- it('makes a request to save a list', () => {
- const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] });
- const expectedListValue = {
- id: listObj.id,
- position: listObj.position,
- type: listObj.list_type,
- label: listObj.label,
- };
- expect(list.id).toBe(listObj.id);
- expect(list.position).toBe(listObj.position);
- expect(list).toMatchObject(expectedListValue);
-
- return expect(boardsStore.saveList(list)).resolves.toEqual(expectedResponse);
- });
- });
-
- describe('getListIssues', () => {
- let list;
-
- beforeEach(() => {
- list = new List(listObj);
- setupDefaultResponses();
- });
-
- it('makes a request to get issues', () => {
- const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] });
- expect(list.issues).toEqual([]);
-
- return expect(boardsStore.getListIssues(list, true)).resolves.toEqual(expectedResponse);
- });
- });
-
- describe('getIssuesForList', () => {
- const id = 'TOO-MUCH';
- const url = `${endpoints.listsEndpoint}/${id}/issues?id=${id}`;
-
- it('makes a request to fetch list issues', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssuesForList(id)).resolves.toEqual(expectedResponse);
- });
-
- it('makes a request to fetch list issues with filter', () => {
- const filter = { algal: 'scrubber' };
- axiosMock.onGet(`${url}&algal=scrubber`).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssuesForList(id, filter)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.getIssuesForList(id)).rejects.toThrow();
- });
- });
-
- describe('moveIssue', () => {
- const urlRoot = 'potato';
- const id = 'over 9000';
- const fromListId = 'left';
- const toListId = 'right';
- const moveBeforeId = 'up';
- const moveAfterId = 'down';
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- from_list_id: fromListId,
- to_list_id: toListId,
- move_before_id: moveBeforeId,
- move_after_id: moveAfterId,
- }),
- });
-
- let requestSpy;
-
- beforeAll(() => {
- global.gon.relative_url_root = urlRoot;
- });
-
- afterAll(() => {
- delete global.gon.relative_url_root;
- });
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock
- .onPut(`${urlRoot}/-/boards/${boardId}/issues/${id}`)
- .replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to move an issue between lists', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('newIssue', () => {
- const id = 1;
- const issue = { some: 'issue data' };
- const url = `${endpoints.listsEndpoint}/${id}/issues`;
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- issue,
- }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(url).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a new issue', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.newIssue(id, issue))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.newIssue(id, issue))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('getBacklog', () => {
- const urlRoot = 'deep';
- const url = `${urlRoot}/-/boards/${boardId}/issues.json?not=relevant`;
- const requestParams = {
- not: 'relevant',
- };
-
- beforeAll(() => {
- global.gon.relative_url_root = urlRoot;
- });
-
- afterAll(() => {
- delete global.gon.relative_url_root;
- });
-
- it('makes a request to fetch backlog', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getBacklog(requestParams)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.getBacklog(requestParams)).rejects.toThrow();
- });
- });
-
- describe('bulkUpdate', () => {
- const issueIds = [1, 2, 3];
- const extraData = { moar: 'data' };
- const expectedRequest = expect.objectContaining({
- data: JSON.stringify({
- update: {
- ...extraData,
- issuable_ids: '1,2,3',
- },
- }),
- });
-
- let requestSpy;
-
- beforeEach(() => {
- requestSpy = jest.fn();
- axiosMock.onPost(endpoints.bulkUpdatePath).replyOnce((config) => requestSpy(config));
- });
-
- it('makes a request to create a list', () => {
- requestSpy.mockReturnValue([200, dummyResponse]);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.bulkUpdate(issueIds, extraData))
- .resolves.toEqual(expectedResponse)
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
-
- it('fails for error response', () => {
- requestSpy.mockReturnValue([500]);
-
- return expect(boardsStore.bulkUpdate(issueIds, extraData))
- .rejects.toThrow()
- .then(() => {
- expect(requestSpy).toHaveBeenCalledWith(expectedRequest);
- });
- });
- });
-
- describe('getIssueInfo', () => {
- const dummyEndpoint = `${TEST_HOST}/some/where`;
-
- it('makes a request to the given endpoint', () => {
- axiosMock.onGet(dummyEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.getIssueInfo(dummyEndpoint)).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(dummyEndpoint).replyOnce(500);
-
- return expect(boardsStore.getIssueInfo(dummyEndpoint)).rejects.toThrow();
- });
- });
-
- describe('toggleIssueSubscription', () => {
- const dummyEndpoint = `${TEST_HOST}/some/where`;
-
- it('makes a request to the given endpoint', () => {
- axiosMock.onPost(dummyEndpoint).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).resolves.toEqual(
- expectedResponse,
- );
- });
-
- it('fails for error response', () => {
- axiosMock.onPost(dummyEndpoint).replyOnce(500);
-
- return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).rejects.toThrow();
- });
- });
-
- describe('recentBoards', () => {
- const url = `${endpoints.recentBoardsEndpoint}.json`;
-
- it('makes a request to fetch all boards', () => {
- axiosMock.onGet(url).replyOnce(200, dummyResponse);
- const expectedResponse = expect.objectContaining({ data: dummyResponse });
-
- return expect(boardsStore.recentBoards()).resolves.toEqual(expectedResponse);
- });
-
- it('fails for error response', () => {
- axiosMock.onGet(url).replyOnce(500);
-
- return expect(boardsStore.recentBoards()).rejects.toThrow();
- });
- });
-
- describe('when created', () => {
- beforeEach(() => {
- setupDefaultResponses();
-
- jest.spyOn(boardsStore, 'moveIssue').mockReturnValue(Promise.resolve());
- jest.spyOn(boardsStore, 'moveMultipleIssues').mockReturnValue(Promise.resolve());
-
- boardsStore.create();
- });
-
- it('starts with a blank state', () => {
- expect(boardsStore.state.lists.length).toBe(0);
- });
-
- describe('addList', () => {
- it('sorts by position', () => {
- boardsStore.addList({ position: 2 });
- boardsStore.addList({ position: 1 });
-
- expect(boardsStore.state.lists.map(({ position }) => position)).toEqual([1, 2]);
- });
- });
-
- describe('toggleFilter', () => {
- const dummyFilter = 'x=42';
- let updateTokensSpy;
-
- beforeEach(() => {
- updateTokensSpy = jest.fn();
- eventHub.$once('updateTokens', updateTokensSpy);
-
- // prevent using window.history
- jest.spyOn(boardsStore, 'updateFiltersUrl').mockReturnValue();
- });
-
- it('adds the filter if it is not present', () => {
- boardsStore.filter.path = 'something';
-
- boardsStore.toggleFilter(dummyFilter);
-
- expect(boardsStore.filter.path).toEqual(`something&${dummyFilter}`);
- expect(updateTokensSpy).toHaveBeenCalled();
- expect(boardsStore.updateFiltersUrl).toHaveBeenCalled();
- });
-
- it('removes the filter if it is present', () => {
- boardsStore.filter.path = `something&${dummyFilter}`;
-
- boardsStore.toggleFilter(dummyFilter);
-
- expect(boardsStore.filter.path).toEqual('something');
- expect(updateTokensSpy).toHaveBeenCalled();
- expect(boardsStore.updateFiltersUrl).toHaveBeenCalled();
- });
- });
-
- describe('lists', () => {
- it('creates new list without persisting to DB', () => {
- expect(boardsStore.state.lists.length).toBe(0);
-
- boardsStore.addList(listObj);
-
- expect(boardsStore.state.lists.length).toBe(1);
- });
-
- it('finds list by ID', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('id', listObj.id);
-
- expect(list.id).toBe(listObj.id);
- });
-
- it('finds list by type', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('type', 'label');
-
- expect(list).toBeDefined();
- });
-
- it('finds list by label ID', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findListByLabelId(listObj.label.id);
-
- expect(list.id).toBe(listObj.id);
- });
-
- it('gets issue when new list added', () => {
- boardsStore.addList(listObj);
- const list = boardsStore.findList('id', listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- return axios.waitForAll().then(() => {
- expect(list.issues.length).toBe(1);
- expect(list.issues[0].id).toBe(1);
- });
- });
-
- it('persists new list', () => {
- boardsStore.new({
- title: 'Test',
- list_type: 'label',
- label: {
- id: 1,
- title: 'Testing',
- color: 'red',
- description: 'testing;',
- },
- });
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- return axios.waitForAll().then(() => {
- const list = boardsStore.findList('id', listObj.id);
-
- expect(list).toEqual(
- expect.objectContaining({
- id: listObj.id,
- position: 0,
- }),
- );
- });
- });
-
- it('removes list from state', () => {
- boardsStore.addList(listObj);
-
- expect(boardsStore.state.lists.length).toBe(1);
-
- boardsStore.removeList(listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(0);
- });
-
- it('moves the position of lists', () => {
- const listOne = boardsStore.addList(listObj);
- boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- boardsStore.moveList(listOne, [listObjDuplicate.id, listObj.id]);
-
- expect(listOne.position).toBe(1);
- });
-
- it('moves an issue from one list to another', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(1));
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(1);
- });
- });
-
- it('moves an issue from backlog to a list', () => {
- const backlog = boardsStore.addList({
- ...listObj,
- list_type: 'backlog',
- });
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(backlog.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(backlog, listTwo, backlog.findIssue(1));
-
- expect(backlog.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(1);
- });
- });
-
- it('moves issue to top of another list', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- listOne.issues[0].id = 2;
-
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 0);
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(2);
- expect(listTwo.issues[0].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, null, 1);
- });
- });
-
- it('moves issue to bottom of another list', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- listOne.issues[0].id = 2;
-
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 1);
-
- expect(listOne.issues.length).toBe(0);
- expect(listTwo.issues.length).toBe(2);
- expect(listTwo.issues[1].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, 1, null);
- });
- });
-
- it('moves issue in list', () => {
- const issue = new ListIssue({
- title: 'Testing',
- id: 2,
- iid: 2,
- confidential: false,
- labels: [],
- assignees: [],
- });
- const list = boardsStore.addList(listObj);
-
- return axios.waitForAll().then(() => {
- list.addIssue(issue);
-
- expect(list.issues.length).toBe(2);
-
- boardsStore.moveIssueInList(list, issue, 0, 1, [1, 2]);
-
- expect(list.issues[0].id).toBe(2);
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, null, null, 1, null);
- });
- });
- });
-
- describe('setListDetail', () => {
- it('sets the list detail', () => {
- boardsStore.detail.list = 'not a list';
-
- const dummyValue = 'new list';
- boardsStore.setListDetail(dummyValue);
-
- expect(boardsStore.detail.list).toEqual(dummyValue);
- });
- });
-
- describe('clearDetailIssue', () => {
- it('resets issue details', () => {
- boardsStore.detail.issue = 'something';
-
- boardsStore.clearDetailIssue();
-
- expect(boardsStore.detail.issue).toEqual({});
- });
- });
-
- describe('setIssueDetail', () => {
- it('sets issue details', () => {
- boardsStore.detail.issue = 'some details';
-
- const dummyValue = 'new details';
- boardsStore.setIssueDetail(dummyValue);
-
- expect(boardsStore.detail.issue).toEqual(dummyValue);
- });
- });
-
- describe('startMoving', () => {
- it('stores list and issue', () => {
- const dummyIssue = 'some issue';
- const dummyList = 'some list';
-
- boardsStore.startMoving(dummyList, dummyIssue);
-
- expect(boardsStore.moving.issue).toEqual(dummyIssue);
- expect(boardsStore.moving.list).toEqual(dummyList);
- });
- });
-
- describe('setTimeTrackingLimitToHours', () => {
- it('sets the timeTracking.LimitToHours option', () => {
- boardsStore.timeTracking.limitToHours = false;
-
- boardsStore.setTimeTrackingLimitToHours('true');
-
- expect(boardsStore.timeTracking.limitToHours).toEqual(true);
- });
- });
-
- describe('setCurrentBoard', () => {
- const dummyBoard = 'hoverboard';
-
- it('sets the current board', () => {
- const { state } = boardsStore;
- state.currentBoard = null;
-
- boardsStore.setCurrentBoard(dummyBoard);
-
- expect(state.currentBoard).toEqual(dummyBoard);
- });
- });
-
- describe('toggleMultiSelect', () => {
- let basicIssueObj;
-
- beforeAll(() => {
- basicIssueObj = { id: 987654 };
- });
-
- afterEach(() => {
- boardsStore.clearMultiSelect();
- });
-
- it('adds issue when not present', () => {
- boardsStore.toggleMultiSelect(basicIssueObj);
-
- const selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(true);
- });
-
- it('removes issue when issue is present', () => {
- boardsStore.toggleMultiSelect(basicIssueObj);
- let selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(true);
-
- boardsStore.toggleMultiSelect(basicIssueObj);
- selectedIds = boardsStore.multiSelect.list.map(({ id }) => id);
-
- expect(selectedIds.includes(basicIssueObj.id)).toEqual(false);
- });
- });
-
- describe('clearMultiSelect', () => {
- it('clears all the multi selected issues', () => {
- const issue1 = { id: 12345 };
- const issue2 = { id: 12346 };
-
- boardsStore.toggleMultiSelect(issue1);
- boardsStore.toggleMultiSelect(issue2);
-
- expect(boardsStore.multiSelect.list.length).toEqual(2);
-
- boardsStore.clearMultiSelect();
-
- expect(boardsStore.multiSelect.list.length).toEqual(0);
- });
- });
-
- describe('moveMultipleIssuesToList', () => {
- it('move issues on the new index', () => {
- const listOne = boardsStore.addList(listObj);
- const listTwo = boardsStore.addList(listObjDuplicate);
-
- expect(boardsStore.state.lists.length).toBe(2);
-
- return axios.waitForAll().then(() => {
- expect(listOne.issues.length).toBe(1);
- expect(listTwo.issues.length).toBe(1);
-
- boardsStore.moveMultipleIssuesToList({
- listFrom: listOne,
- listTo: listTwo,
- issues: listOne.issues,
- newIndex: 0,
- });
-
- expect(listTwo.issues.length).toBe(1);
- });
- });
- });
-
- describe('moveMultipleIssuesInList', () => {
- it('moves multiple issues in list', () => {
- const issueObj = {
- title: 'Issue #1',
- id: 12345,
- iid: 2,
- confidential: false,
- labels: [],
- assignees: [],
- };
- const issue1 = new ListIssue(issueObj);
- const issue2 = new ListIssue({
- ...issueObj,
- title: 'Issue #2',
- id: 12346,
- });
-
- const list = boardsStore.addList(listObj);
-
- return axios.waitForAll().then(() => {
- list.addIssue(issue1);
- list.addIssue(issue2);
-
- expect(list.issues.length).toBe(3);
- expect(list.issues[0].id).not.toBe(issue2.id);
-
- boardsStore.moveMultipleIssuesInList({
- list,
- issues: [issue1, issue2],
- oldIndicies: [0],
- newIndex: 1,
- idArray: [1, 12345, 12346],
- });
-
- expect(list.issues[0].id).toBe(issue1.id);
-
- expect(boardsStore.moveMultipleIssues).toHaveBeenCalledWith({
- ids: [issue1.id, issue2.id],
- fromListId: null,
- toListId: null,
- moveBeforeId: 1,
- moveAfterId: null,
- });
- });
- });
- });
-
- describe('addListIssue', () => {
- let list;
- const issue1 = new ListIssue({
- title: 'Testing',
- id: 2,
- iid: 2,
- confidential: false,
- labels: [
- {
- color: '#ff0000',
- description: 'testing;',
- id: 5000,
- priority: undefined,
- textColor: 'white',
- title: 'Test',
- },
- ],
- assignees: [],
- });
- const issue2 = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [
- {
- id: 1,
- title: 'test',
- color: 'red',
- description: 'testing',
- },
- ],
- assignees: [
- {
- id: 1,
- name: 'name',
- username: 'username',
- avatar_url: 'http://avatar_url',
- },
- ],
- real_path: 'path/to/issue',
- });
-
- beforeEach(() => {
- list = new List(listObj);
- list.addIssue(issue1);
- setupDefaultResponses();
- });
-
- it('adds issues that are not already on the list', () => {
- expect(list.findIssue(issue2.id)).toBe(undefined);
- expect(list.issues).toEqual([issue1]);
-
- boardsStore.addListIssue(list, issue2);
- expect(list.findIssue(issue2.id)).toBe(issue2);
- expect(list.issues.length).toBe(2);
- expect(list.issues).toEqual([issue1, issue2]);
- });
- });
-
- describe('updateIssue', () => {
- let issue;
- let patchSpy;
-
- beforeEach(() => {
- issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [
- {
- id: 1,
- title: 'test',
- color: 'red',
- description: 'testing',
- },
- ],
- assignees: [
- {
- id: 1,
- name: 'name',
- username: 'username',
- avatar_url: 'http://avatar_url',
- },
- ],
- real_path: 'path/to/issue',
- });
-
- patchSpy = jest.fn().mockReturnValue([200, { labels: [] }]);
- axiosMock.onPatch(`path/to/issue.json`).reply(({ data }) => patchSpy(JSON.parse(data)));
- });
-
- it('passes assignee ids when there are assignees', () => {
- boardsStore.updateIssue(issue);
- return boardsStore.updateIssue(issue).then(() => {
- expect(patchSpy).toHaveBeenCalledWith({
- issue: {
- milestone_id: null,
- assignee_ids: [1],
- label_ids: [1],
- },
- });
- });
- });
-
- it('passes assignee ids of [0] when there are no assignees', () => {
- issue.removeAllAssignees();
-
- return boardsStore.updateIssue(issue).then(() => {
- expect(patchSpy).toHaveBeenCalledWith({
- issue: {
- milestone_id: null,
- assignee_ids: [0],
- label_ids: [1],
- },
- });
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_add_new_column_spec.js b/spec/frontend/boards/components/board_add_new_column_spec.js
index 61f210f566b..5fae1c4359f 100644
--- a/spec/frontend/boards/components/board_add_new_column_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_spec.js
@@ -48,7 +48,6 @@ describe('Board card layout', () => {
...actions,
},
getters: {
- shouldUseGraphQL: () => true,
getListByLabelId: () => getListByLabelId,
},
state: {
diff --git a/spec/frontend/boards/components/board_app_spec.js b/spec/frontend/boards/components/board_app_spec.js
new file mode 100644
index 00000000000..dee097bfb08
--- /dev/null
+++ b/spec/frontend/boards/components/board_app_spec.js
@@ -0,0 +1,54 @@
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+
+import BoardApp from '~/boards/components/board_app.vue';
+
+describe('BoardApp', () => {
+ let wrapper;
+ let store;
+
+ Vue.use(Vuex);
+
+ const createStore = ({ mockGetters = {} } = {}) => {
+ store = new Vuex.Store({
+ state: {},
+ actions: {
+ performSearch: jest.fn(),
+ },
+ getters: {
+ isSidebarOpen: () => true,
+ ...mockGetters,
+ },
+ });
+ };
+
+ const createComponent = ({ provide = { disabled: true } } = {}) => {
+ wrapper = shallowMount(BoardApp, {
+ store,
+ provide: {
+ ...provide,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ store = null;
+ });
+
+ it("should have 'is-compact' class when sidebar is open", () => {
+ createStore();
+ createComponent();
+
+ expect(wrapper.classes()).toContain('is-compact');
+ });
+
+ it("should not have 'is-compact' class when sidebar is closed", () => {
+ createStore({ mockGetters: { isSidebarOpen: () => false } });
+ createComponent();
+
+ expect(wrapper.classes()).not.toContain('is-compact');
+ });
+});
diff --git a/spec/frontend/boards/components/board_card_deprecated_spec.js b/spec/frontend/boards/components/board_card_deprecated_spec.js
deleted file mode 100644
index 266cbc7106d..00000000000
--- a/spec/frontend/boards/components/board_card_deprecated_spec.js
+++ /dev/null
@@ -1,219 +0,0 @@
-/* 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
deleted file mode 100644
index 9853c9f434f..00000000000
--- a/spec/frontend/boards/components/board_card_layout_deprecated_spec.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* global List */
-/* global ListLabel */
-
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-
-import MockAdapter from 'axios-mock-adapter';
-import Vuex from 'vuex';
-import waitForPromises from 'helpers/wait_for_promises';
-
-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_deprecated.vue';
-import { ISSUABLE } from '~/boards/constants';
-import boardsVuexStore from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
-
-describe('Board card layout', () => {
- let wrapper;
- let mock;
- let list;
- let store;
-
- const localVue = createLocalVue();
- localVue.use(Vuex);
-
- const createStore = ({ getters = {}, actions = {} } = {}) => {
- store = new Vuex.Store({
- ...boardsVuexStore,
- 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,
- issue: list.issues[0],
- disabled: false,
- index: 0,
- ...propsData,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- scopedLabelsAvailable: false,
- ...provide,
- },
- });
- };
-
- const setupData = () => {
- 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',
- });
- return waitForPromises().then(() => {
- 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();
- });
-
- 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' when 'graphqlBoardLists' feature flag is turned on", async () => {
- const setActiveId = jest.fn();
- createStore({
- actions: {
- setActiveId,
- },
- });
- mountComponent({
- provide: {
- glFeatures: { graphqlBoardLists: true },
- },
- });
-
- wrapper.trigger('mouseup');
- await wrapper.vm.$nextTick();
-
- expect(setActiveId).toHaveBeenCalledTimes(1);
- expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
- id: list.issues[0].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: list.issues[0].id,
- sidebarType: ISSUABLE,
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_column_deprecated_spec.js b/spec/frontend/boards/components/board_column_deprecated_spec.js
deleted file mode 100644
index e6d65e48c3f..00000000000
--- a/spec/frontend/boards/components/board_column_deprecated_spec.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import Vue, { nextTick } from 'vue';
-
-import { TEST_HOST } from 'helpers/test_constants';
-import { listObj } from 'jest/boards/mock_data';
-import Board from '~/boards/components/board_column_deprecated.vue';
-import { ListType } from '~/boards/constants';
-import List from '~/boards/models/list';
-import axios from '~/lib/utils/axios_utils';
-
-describe('Board Column Component', () => {
- let wrapper;
- let axiosMock;
-
- beforeEach(() => {
- window.gon = {};
- axiosMock = new AxiosMockAdapter(axios);
- axiosMock.onGet(`${TEST_HOST}/lists/1/issues`).reply(200, { issues: [] });
- });
-
- afterEach(() => {
- axiosMock.restore();
-
- wrapper.destroy();
-
- localStorage.clear();
- });
-
- const createComponent = ({
- listType = ListType.backlog,
- collapsed = false,
- highlighted = false,
- withLocalStorage = true,
- } = {}) => {
- const boardId = '1';
-
- const listMock = {
- ...listObj,
- list_type: listType,
- highlighted,
- collapsed,
- };
-
- if (listType === ListType.assignee) {
- delete listMock.label;
- listMock.user = {};
- }
-
- // Making List reactive
- const list = Vue.observable(new List(listMock));
-
- if (withLocalStorage) {
- localStorage.setItem(
- `boards.${boardId}.${list.type}.${list.id}.expanded`,
- (!collapsed).toString(),
- );
- }
-
- wrapper = shallowMount(Board, {
- propsData: {
- boardId,
- disabled: false,
- list,
- },
- provide: {
- boardId,
- },
- });
- };
-
- const isExpandable = () => wrapper.classes('is-expandable');
- const isCollapsed = () => wrapper.classes('is-collapsed');
-
- describe('Given different list types', () => {
- it('is expandable when List Type is `backlog`', () => {
- createComponent({ listType: ListType.backlog });
-
- expect(isExpandable()).toBe(true);
- });
- });
-
- describe('expanded / collapsed column', () => {
- it('has class is-collapsed when list is collapsed', () => {
- createComponent({ collapsed: false });
-
- expect(wrapper.vm.list.isExpanded).toBe(true);
- });
-
- it('does not have class is-collapsed when list is expanded', () => {
- createComponent({ collapsed: true });
-
- expect(isCollapsed()).toBe(true);
- });
- });
-
- describe('highlighting', () => {
- it('scrolls to column when highlighted', async () => {
- createComponent({ highlighted: true });
-
- await nextTick();
-
- expect(wrapper.element.scrollIntoView).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_content_spec.js b/spec/frontend/boards/components/board_content_spec.js
index 5a799b6388e..f535679b8a0 100644
--- a/spec/frontend/boards/components/board_content_spec.js
+++ b/spec/frontend/boards/components/board_content_spec.js
@@ -5,9 +5,10 @@ import Draggable from 'vuedraggable';
import Vuex from 'vuex';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import getters from 'ee_else_ce/boards/stores/getters';
-import BoardColumnDeprecated from '~/boards/components/board_column_deprecated.vue';
+import BoardColumn from '~/boards/components/board_column.vue';
import BoardContent from '~/boards/components/board_content.vue';
-import { mockLists, mockListsWithModel } from '../mock_data';
+import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue';
+import { mockLists } from '../mock_data';
Vue.use(Vuex);
@@ -23,6 +24,7 @@ describe('BoardContent', () => {
isShowingEpicsSwimlanes: false,
boardLists: mockLists,
error: undefined,
+ issuableType: 'issue',
};
const createStore = (state = defaultState) => {
@@ -33,25 +35,19 @@ describe('BoardContent', () => {
});
};
- const createComponent = ({
- state,
- props = {},
- graphqlBoardListsEnabled = false,
- canAdminList = true,
- } = {}) => {
+ const createComponent = ({ state, props = {}, canAdminList = true } = {}) => {
const store = createStore({
...defaultState,
...state,
});
wrapper = shallowMount(BoardContent, {
propsData: {
- lists: mockListsWithModel,
+ lists: mockLists,
disabled: false,
...props,
},
provide: {
canAdminList,
- glFeatures: { graphqlBoardLists: graphqlBoardListsEnabled },
},
store,
});
@@ -61,53 +57,48 @@ describe('BoardContent', () => {
wrapper.destroy();
});
- it('renders a BoardColumnDeprecated component per list', () => {
- createComponent();
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
- expect(wrapper.findAllComponents(BoardColumnDeprecated)).toHaveLength(
- mockListsWithModel.length,
- );
- });
+ it('renders a BoardColumn component per list', () => {
+ expect(wrapper.findAllComponents(BoardColumn)).toHaveLength(mockLists.length);
+ });
- it('does not display EpicsSwimlanes component', () => {
- createComponent();
+ it('renders BoardContentSidebar', () => {
+ expect(wrapper.find(BoardContentSidebar).exists()).toBe(true);
+ });
- expect(wrapper.find(EpicsSwimlanes).exists()).toBe(false);
- expect(wrapper.find(GlAlert).exists()).toBe(false);
+ it('does not display EpicsSwimlanes component', () => {
+ expect(wrapper.find(EpicsSwimlanes).exists()).toBe(false);
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
});
- describe('graphqlBoardLists feature flag enabled', () => {
+ describe('when issuableType is not issue', () => {
beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true });
- gon.features = {
- graphqlBoardLists: true,
- };
+ createComponent({ state: { issuableType: 'foo' } });
});
- describe('can admin list', () => {
- beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true, canAdminList: true });
- });
-
- it('renders draggable component', () => {
- expect(wrapper.find(Draggable).exists()).toBe(true);
- });
+ it('does not render BoardContentSidebar', () => {
+ expect(wrapper.find(BoardContentSidebar).exists()).toBe(false);
});
+ });
- describe('can not admin list', () => {
- beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: true, canAdminList: false });
- });
+ describe('can admin list', () => {
+ beforeEach(() => {
+ createComponent({ canAdminList: true });
+ });
- it('does not render draggable component', () => {
- expect(wrapper.find(Draggable).exists()).toBe(false);
- });
+ it('renders draggable component', () => {
+ expect(wrapper.find(Draggable).exists()).toBe(true);
});
});
- describe('graphqlBoardLists feature flag disabled', () => {
+ describe('can not admin list', () => {
beforeEach(() => {
- createComponent({ graphqlBoardListsEnabled: false });
+ createComponent({ canAdminList: false });
});
it('does not render draggable component', () => {
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
index 50f86e92adb..dc93890f27a 100644
--- a/spec/frontend/boards/components/board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue';
-import { createStore } from '~/boards/stores';
import * as urlUtility from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
@@ -44,6 +43,12 @@ describe('BoardFilteredSearch', () => {
];
const createComponent = ({ initialFilterParams = {} } = {}) => {
+ store = new Vuex.Store({
+ actions: {
+ performSearch: jest.fn(),
+ },
+ });
+
wrapper = shallowMount(BoardFilteredSearch, {
provide: { initialFilterParams, fullPath: '' },
store,
@@ -55,22 +60,15 @@ describe('BoardFilteredSearch', () => {
const findFilteredSearch = () => wrapper.findComponent(FilteredSearchBarRoot);
- beforeEach(() => {
- // this needed for actions call for performSearch
- window.gon = { features: {} };
- });
-
afterEach(() => {
wrapper.destroy();
});
describe('default', () => {
beforeEach(() => {
- store = createStore();
+ createComponent();
jest.spyOn(store, 'dispatch');
-
- createComponent();
});
it('renders FilteredSearch', () => {
@@ -103,8 +101,6 @@ describe('BoardFilteredSearch', () => {
describe('when searching', () => {
beforeEach(() => {
- store = createStore();
-
createComponent();
jest.spyOn(wrapper.vm, 'performSearch').mockImplementation();
@@ -133,11 +129,9 @@ describe('BoardFilteredSearch', () => {
describe('when url params are already set', () => {
beforeEach(() => {
- store = createStore();
+ createComponent({ initialFilterParams: { authorUsername: 'root', labelName: ['label'] } });
jest.spyOn(store, 'dispatch');
-
- createComponent({ initialFilterParams: { authorUsername: 'root', labelName: ['label'] } });
});
it('passes the correct props to FilterSearchBar', () => {
diff --git a/spec/frontend/boards/components/board_list_header_deprecated_spec.js b/spec/frontend/boards/components/board_list_header_deprecated_spec.js
deleted file mode 100644
index db79e67fe78..00000000000
--- a/spec/frontend/boards/components/board_list_header_deprecated_spec.js
+++ /dev/null
@@ -1,174 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-
-import { TEST_HOST } from 'helpers/test_constants';
-import { listObj } from 'jest/boards/mock_data';
-import BoardListHeader from '~/boards/components/board_list_header_deprecated.vue';
-import { ListType } from '~/boards/constants';
-import List from '~/boards/models/list';
-import axios from '~/lib/utils/axios_utils';
-
-describe('Board List Header Component', () => {
- let wrapper;
- let axiosMock;
-
- beforeEach(() => {
- window.gon = {};
- axiosMock = new AxiosMockAdapter(axios);
- axiosMock.onGet(`${TEST_HOST}/lists/1/issues`).reply(200, { issues: [] });
- });
-
- afterEach(() => {
- axiosMock.restore();
-
- wrapper.destroy();
-
- localStorage.clear();
- });
-
- const createComponent = ({
- listType = ListType.backlog,
- collapsed = false,
- withLocalStorage = true,
- currentUserId = 1,
- } = {}) => {
- const boardId = '1';
-
- const listMock = {
- ...listObj,
- list_type: listType,
- collapsed,
- };
-
- if (listType === ListType.assignee) {
- delete listMock.label;
- listMock.user = {};
- }
-
- // Making List reactive
- const list = Vue.observable(new List(listMock));
-
- if (withLocalStorage) {
- localStorage.setItem(
- `boards.${boardId}.${list.type}.${list.id}.expanded`,
- (!collapsed).toString(),
- );
- }
-
- wrapper = shallowMount(BoardListHeader, {
- propsData: {
- disabled: false,
- list,
- },
- provide: {
- boardId,
- currentUserId,
- },
- });
- };
-
- const isCollapsed = () => !wrapper.props().list.isExpanded;
- const isExpanded = () => wrapper.vm.list.isExpanded;
-
- const findAddIssueButton = () => wrapper.find({ ref: 'newIssueBtn' });
- const findCaret = () => wrapper.find('.board-title-caret');
-
- describe('Add issue button', () => {
- const hasNoAddButton = [ListType.closed];
- const hasAddButton = [
- ListType.backlog,
- ListType.label,
- ListType.milestone,
- ListType.iteration,
- ListType.assignee,
- ];
-
- it.each(hasNoAddButton)('does not render when List Type is `%s`', (listType) => {
- createComponent({ listType });
-
- expect(findAddIssueButton().exists()).toBe(false);
- });
-
- it.each(hasAddButton)('does render when List Type is `%s`', (listType) => {
- createComponent({ listType });
-
- expect(findAddIssueButton().exists()).toBe(true);
- });
-
- it('has a test for each list type', () => {
- Object.values(ListType).forEach((value) => {
- expect([...hasAddButton, ...hasNoAddButton]).toContain(value);
- });
- });
-
- it('does not render when logged out', () => {
- createComponent({
- currentUserId: null,
- });
-
- expect(findAddIssueButton().exists()).toBe(false);
- });
- });
-
- describe('expanding / collapsing the column', () => {
- it('does not collapse when clicking the header', () => {
- createComponent();
-
- expect(isCollapsed()).toBe(false);
- wrapper.find('[data-testid="board-list-header"]').trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(false);
- });
- });
-
- it('collapses expanded Column when clicking the collapse icon', () => {
- createComponent();
-
- expect(isExpanded()).toBe(true);
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(true);
- });
- });
-
- it('expands collapsed Column when clicking the expand icon', () => {
- createComponent({ collapsed: true });
-
- expect(isCollapsed()).toBe(true);
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(isCollapsed()).toBe(false);
- });
- });
-
- it("when logged in it calls list update and doesn't set localStorage", () => {
- jest.spyOn(List.prototype, 'update');
-
- createComponent({ withLocalStorage: false });
-
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.list.update).toHaveBeenCalledTimes(1);
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(null);
- });
- });
-
- it("when logged out it doesn't call list update and sets localStorage", () => {
- jest.spyOn(List.prototype, 'update');
-
- createComponent({ currentUserId: null });
-
- findCaret().vm.$emit('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.list.update).not.toHaveBeenCalled();
- expect(localStorage.getItem(`${wrapper.vm.uniqueKey}.expanded`)).toBe(String(isExpanded()));
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/board_settings_sidebar_spec.js b/spec/frontend/boards/components/board_settings_sidebar_spec.js
index 20a08be6c19..46dd109ffb1 100644
--- a/spec/frontend/boards/components/board_settings_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_settings_sidebar_spec.js
@@ -1,38 +1,55 @@
-import '~/boards/models/list';
import { GlDrawer, GlLabel } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
+import { shallowMount } from '@vue/test-utils';
import { MountingPortal } from 'portal-vue';
+import Vue from 'vue';
import Vuex from 'vuex';
+import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue';
import { inactiveId, LIST } from '~/boards/constants';
-import { createStore } from '~/boards/stores';
-import boardsStore from '~/boards/stores/boards_store';
+import actions from '~/boards/stores/actions';
+import getters from '~/boards/stores/getters';
+import mutations from '~/boards/stores/mutations';
import sidebarEventHub from '~/sidebar/event_hub';
+import { mockLabelList } from '../mock_data';
-const localVue = createLocalVue();
-
-localVue.use(Vuex);
+Vue.use(Vuex);
describe('BoardSettingsSidebar', () => {
let wrapper;
- let mock;
- let store;
- const labelTitle = 'test';
- const labelColor = '#FFFF';
- const listId = 1;
+ const labelTitle = mockLabelList.label.title;
+ const labelColor = mockLabelList.label.color;
+ const listId = mockLabelList.id;
const findRemoveButton = () => wrapper.findByTestId('remove-list');
- const createComponent = ({ canAdminList = false } = {}) => {
+ const createComponent = ({
+ canAdminList = false,
+ list = {},
+ sidebarType = LIST,
+ activeId = inactiveId,
+ } = {}) => {
+ const boardLists = {
+ [listId]: list,
+ };
+ const store = new Vuex.Store({
+ state: { sidebarType, activeId, boardLists },
+ getters,
+ mutations,
+ actions,
+ });
+
wrapper = extendedWrapper(
shallowMount(BoardSettingsSidebar, {
store,
- localVue,
provide: {
canAdminList,
+ scopedLabelsAvailable: false,
+ },
+ stubs: {
+ GlDrawer: stubComponent(GlDrawer, {
+ template: '<div><slot name="header"></slot><slot></slot></div>',
+ }),
},
}),
);
@@ -40,16 +57,10 @@ describe('BoardSettingsSidebar', () => {
const findLabel = () => wrapper.find(GlLabel);
const findDrawer = () => wrapper.find(GlDrawer);
- beforeEach(() => {
- store = createStore();
- store.state.activeId = inactiveId;
- store.state.sidebarType = LIST;
- boardsStore.create();
- });
-
afterEach(() => {
jest.restoreAllMocks();
wrapper.destroy();
+ wrapper = null;
});
it('finds a MountingPortal component', () => {
@@ -100,86 +111,40 @@ describe('BoardSettingsSidebar', () => {
});
describe('when activeId is greater than zero', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
- store.state.activeId = 1;
- store.state.sidebarType = LIST;
- });
-
- afterEach(() => {
- boardsStore.removeList(listId);
- });
-
- it('renders GlDrawer with open false', () => {
- createComponent();
+ it('renders GlDrawer with open true', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
expect(findDrawer().props('open')).toBe(true);
});
});
- describe('when activeId is in boardsStore', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
-
- store.state.activeId = listId;
- store.state.sidebarType = LIST;
-
- createComponent();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
+ describe('when activeId is in state', () => {
it('renders label title', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
+
expect(findLabel().props('title')).toBe(labelTitle);
});
it('renders label background color', () => {
+ createComponent({ list: mockLabelList, activeId: listId });
+
expect(findLabel().props('backgroundColor')).toBe(labelColor);
});
});
- describe('when activeId is not in boardsStore', () => {
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- boardsStore.addList({ id: listId, label: { title: labelTitle, color: labelColor } });
-
- store.state.activeId = inactiveId;
-
- createComponent();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
+ describe('when activeId is not in state', () => {
it('does not render GlLabel', () => {
+ createComponent({ list: mockLabelList });
+
expect(findLabel().exists()).toBe(false);
});
});
});
describe('when sidebarType is not List', () => {
- beforeEach(() => {
- store.state.sidebarType = '';
- createComponent();
- });
-
it('does not render GlDrawer', () => {
+ createComponent({ sidebarType: '' });
+
expect(findDrawer().exists()).toBe(false);
});
});
@@ -191,20 +156,9 @@ describe('BoardSettingsSidebar', () => {
});
describe('when user can admin the boards list', () => {
- beforeEach(() => {
- store.state.activeId = listId;
- store.state.sidebarType = LIST;
-
- boardsStore.addList({
- id: listId,
- label: { title: labelTitle, color: labelColor },
- list_type: 'label',
- });
-
- createComponent({ canAdminList: true });
- });
-
it('renders "Remove list" button', () => {
+ createComponent({ canAdminList: true, activeId: listId, list: mockLabelList });
+
expect(findRemoveButton().exists()).toBe(true);
});
});
diff --git a/spec/frontend/boards/components/boards_selector_deprecated_spec.js b/spec/frontend/boards/components/boards_selector_deprecated_spec.js
deleted file mode 100644
index cc078861d75..00000000000
--- a/spec/frontend/boards/components/boards_selector_deprecated_spec.js
+++ /dev/null
@@ -1,214 +0,0 @@
-import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import { TEST_HOST } from 'spec/test_constants';
-import BoardsSelector from '~/boards/components/boards_selector_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-
-const throttleDuration = 1;
-
-function boardGenerator(n) {
- return new Array(n).fill().map((board, index) => {
- const id = `${index}`;
- const name = `board${id}`;
-
- return {
- id,
- name,
- };
- });
-}
-
-describe('BoardsSelector', () => {
- let wrapper;
- let allBoardsResponse;
- let recentBoardsResponse;
- const boards = boardGenerator(20);
- const recentBoards = boardGenerator(5);
-
- const fillSearchBox = (filterTerm) => {
- const searchBox = wrapper.find({ ref: 'searchBox' });
- const searchBoxInput = searchBox.find('input');
- searchBoxInput.setValue(filterTerm);
- searchBoxInput.trigger('input');
- };
-
- const getDropdownItems = () => wrapper.findAll('.js-dropdown-item');
- const getDropdownHeaders = () => wrapper.findAll(GlDropdownSectionHeader);
- const getLoadingIcon = () => wrapper.find(GlLoadingIcon);
- const findDropdown = () => wrapper.find(GlDropdown);
-
- beforeEach(() => {
- const $apollo = {
- queries: {
- boards: {
- loading: false,
- },
- },
- };
-
- boardsStore.setEndpoints({
- boardsEndpoint: '',
- recentBoardsEndpoint: '',
- listsEndpoint: '',
- bulkUpdatePath: '',
- boardId: '',
- });
-
- allBoardsResponse = Promise.resolve({
- data: {
- group: {
- boards: {
- edges: boards.map((board) => ({ node: board })),
- },
- },
- },
- });
- recentBoardsResponse = Promise.resolve({
- data: recentBoards,
- });
-
- boardsStore.allBoards = jest.fn(() => allBoardsResponse);
- boardsStore.recentBoards = jest.fn(() => recentBoardsResponse);
-
- wrapper = mount(BoardsSelector, {
- propsData: {
- throttleDuration,
- currentBoard: {
- id: 1,
- name: 'Development',
- milestone_id: null,
- weight: null,
- assignee_id: null,
- labels: [],
- },
- boardBaseUrl: `${TEST_HOST}/board/base/url`,
- hasMissingBoards: false,
- canAdminBoard: true,
- multipleIssueBoardsAvailable: true,
- labelsPath: `${TEST_HOST}/labels/path`,
- labelsWebUrl: `${TEST_HOST}/labels`,
- projectId: 42,
- groupId: 19,
- scopedIssueBoardFeatureEnabled: true,
- weights: [],
- },
- mocks: { $apollo },
- attachTo: document.body,
- });
-
- wrapper.vm.$apollo.addSmartQuery = jest.fn((_, options) => {
- wrapper.setData({
- [options.loadingKey]: true,
- });
- });
-
- // Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('loading', () => {
- // we are testing loading state, so don't resolve responses until after the tests
- afterEach(() => {
- return Promise.all([allBoardsResponse, recentBoardsResponse]).then(() => nextTick());
- });
-
- it('shows loading spinner', () => {
- expect(getDropdownHeaders()).toHaveLength(0);
- expect(getDropdownItems()).toHaveLength(0);
- expect(getLoadingIcon().exists()).toBe(true);
- });
- });
-
- describe('loaded', () => {
- beforeEach(async () => {
- await wrapper.setData({
- loadingBoards: false,
- });
- return Promise.all([allBoardsResponse, recentBoardsResponse]).then(() => nextTick());
- });
-
- it('hides loading spinner', () => {
- expect(getLoadingIcon().exists()).toBe(false);
- });
-
- describe('filtering', () => {
- beforeEach(() => {
- wrapper.setData({
- boards,
- });
-
- return nextTick();
- });
-
- it('shows all boards without filtering', () => {
- expect(getDropdownItems()).toHaveLength(boards.length + recentBoards.length);
- });
-
- it('shows only matching boards when filtering', () => {
- const filterTerm = 'board1';
- const expectedCount = boards.filter((board) => board.name.includes(filterTerm)).length;
-
- fillSearchBox(filterTerm);
-
- return nextTick().then(() => {
- expect(getDropdownItems()).toHaveLength(expectedCount);
- });
- });
-
- it('shows message if there are no matching boards', () => {
- fillSearchBox('does not exist');
-
- return nextTick().then(() => {
- expect(getDropdownItems()).toHaveLength(0);
- expect(wrapper.text().includes('No matching boards found')).toBe(true);
- });
- });
- });
-
- describe('recent boards section', () => {
- it('shows only when boards are greater than 10', () => {
- wrapper.setData({
- boards,
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(2);
- });
- });
-
- it('does not show when boards are less than 10', () => {
- wrapper.setData({
- boards: boards.slice(0, 5),
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
-
- it('does not show when recentBoards api returns empty array', () => {
- wrapper.setData({
- recentBoards: [],
- });
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
-
- it('does not show when search is active', () => {
- fillSearchBox('Random string');
-
- return nextTick().then(() => {
- expect(getDropdownHeaders()).toHaveLength(0);
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js b/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js
deleted file mode 100644
index fafebaf3a4e..00000000000
--- a/spec/frontend/boards/components/issue_time_estimate_deprecated_spec.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import IssueTimeEstimate from '~/boards/components/issue_time_estimate_deprecated.vue';
-import boardsStore from '~/boards/stores/boards_store';
-
-describe('Issue Time Estimate component', () => {
- let wrapper;
-
- beforeEach(() => {
- boardsStore.create();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when limitToHours is false', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = false;
- wrapper = shallowMount(IssueTimeEstimate, {
- propsData: {
- estimate: 374460,
- },
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(wrapper.find('time').text().trim()).toEqual('2w 3d 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('2 weeks 3 days 1 minute');
- });
-
- it('prevents tooltip xss', (done) => {
- const alertSpy = jest.spyOn(window, 'alert');
- wrapper.setProps({ estimate: 'Foo <script>alert("XSS")</script>' });
- wrapper.vm.$nextTick(() => {
- expect(alertSpy).not.toHaveBeenCalled();
- expect(wrapper.find('time').text().trim()).toEqual('0m');
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('0m');
- done();
- });
- });
- });
-
- describe('when limitToHours is true', () => {
- beforeEach(() => {
- boardsStore.timeTracking.limitToHours = true;
- wrapper = shallowMount(IssueTimeEstimate, {
- propsData: {
- estimate: 374460,
- },
- });
- });
-
- it('renders the correct time estimate', () => {
- expect(wrapper.find('time').text().trim()).toEqual('104h 1m');
- });
-
- it('renders expanded time estimate in tooltip', () => {
- expect(wrapper.find('.js-issue-time-estimate').text()).toContain('104 hours 1 minute');
- });
- });
-});
diff --git a/spec/frontend/boards/issue_card_deprecated_spec.js b/spec/frontend/boards/issue_card_deprecated_spec.js
deleted file mode 100644
index 909be275030..00000000000
--- a/spec/frontend/boards/issue_card_deprecated_spec.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/* global ListAssignee, ListLabel, ListIssue */
-import { GlLabel } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { range } from 'lodash';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import IssueCardInner from '~/boards/components/issue_card_inner_deprecated.vue';
-import store from '~/boards/stores';
-import { listObj } from './mock_data';
-
-describe('Issue card component', () => {
- const user = new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- });
-
- const label1 = new ListLabel({
- id: 3,
- title: 'testing 123',
- color: '#000CFF',
- text_color: 'white',
- description: 'test',
- });
-
- let wrapper;
- let issue;
- let list;
-
- beforeEach(() => {
- list = { ...listObj, type: 'label' };
- issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [list.label],
- assignees: [],
- reference_path: '#1',
- real_path: '/test/1',
- weight: 1,
- });
- wrapper = mount(IssueCardInner, {
- propsData: {
- list,
- issue,
- },
- store,
- stubs: {
- GlLabel: true,
- },
- provide: {
- groupId: null,
- rootPath: '/',
- },
- });
- });
-
- it('renders issue title', () => {
- expect(wrapper.find('.board-card-title').text()).toContain(issue.title);
- });
-
- it('includes issue base in link', () => {
- expect(wrapper.find('.board-card-title a').attributes('href')).toContain('/test');
- });
-
- it('includes issue title on link', () => {
- expect(wrapper.find('.board-card-title a').attributes('title')).toBe(issue.title);
- });
-
- it('does not render confidential icon', () => {
- expect(wrapper.find('.confidential-icon').exists()).toBe(false);
- });
-
- it('does not render blocked icon', () => {
- expect(wrapper.find('.issue-blocked-icon').exists()).toBe(false);
- });
-
- it('renders confidential icon', (done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- confidential: true,
- },
- });
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.confidential-icon').exists()).toBe(true);
- done();
- });
- });
-
- it('renders issue ID with #', () => {
- expect(wrapper.find('.board-card-number').text()).toContain(`#${issue.id}`);
- });
-
- describe('assignee', () => {
- it('does not render assignee', () => {
- expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(false);
- });
-
- describe('exists', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [user],
- updateData(newData) {
- Object.assign(this, newData);
- },
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('renders assignee', () => {
- expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(true);
- });
-
- it('sets title', () => {
- expect(wrapper.find('.js-assignee-tooltip').text()).toContain(`${user.name}`);
- });
-
- it('sets users path', () => {
- expect(wrapper.find('.board-card-assignee a').attributes('href')).toBe('/test');
- });
-
- it('renders avatar', () => {
- expect(wrapper.find('.board-card-assignee img').exists()).toBe(true);
- });
-
- it('renders the avatar using avatar_url property', (done) => {
- wrapper.props('issue').updateData({
- ...wrapper.props('issue'),
- assignees: [
- {
- id: '1',
- name: 'test',
- state: 'active',
- username: 'test_name',
- avatar_url: 'test_image_from_avatar_url',
- },
- ],
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.board-card-assignee img').attributes('src')).toBe(
- 'test_image_from_avatar_url?width=24',
- );
- done();
- });
- });
- });
-
- describe('assignee default avatar', () => {
- beforeEach((done) => {
- global.gon.default_avatar_url = 'default_avatar';
-
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [
- new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- }),
- ],
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- afterEach(() => {
- global.gon.default_avatar_url = null;
- });
-
- it('displays defaults avatar if users avatar is null', () => {
- expect(wrapper.find('.board-card-assignee img').exists()).toBe(true);
- expect(wrapper.find('.board-card-assignee img').attributes('src')).toBe(
- 'default_avatar?width=24',
- );
- });
- });
- });
-
- describe('multiple assignees', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees: [
- new ListAssignee({
- id: 2,
- name: 'user2',
- username: 'user2',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 3,
- name: 'user3',
- username: 'user3',
- avatar: 'test_image',
- }),
- new ListAssignee({
- id: 4,
- name: 'user4',
- username: 'user4',
- avatar: 'test_image',
- }),
- ],
- },
- });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('renders all three assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(3);
- });
-
- describe('more than three assignees', () => {
- beforeEach((done) => {
- const { assignees } = wrapper.props('issue');
- assignees.push(
- new ListAssignee({
- id: 5,
- name: 'user5',
- username: 'user5',
- avatar: 'test_image',
- }),
- );
-
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees,
- },
- });
- wrapper.vm.$nextTick(done);
- });
-
- it('renders more avatar counter', () => {
- expect(wrapper.find('.board-card-assignee .avatar-counter').text().trim()).toEqual('+2');
- });
-
- it('renders two assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(2);
- });
-
- it('renders 99+ avatar counter', (done) => {
- const assignees = [
- ...wrapper.props('issue').assignees,
- ...range(5, 103).map(
- (i) =>
- new ListAssignee({
- id: i,
- name: 'name',
- username: 'username',
- avatar: 'test_image',
- }),
- ),
- ];
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- assignees,
- },
- });
-
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.board-card-assignee .avatar-counter').text().trim()).toEqual('99+');
- done();
- });
- });
- });
- });
-
- describe('labels', () => {
- beforeEach((done) => {
- issue.addLabel(label1);
- wrapper.setProps({ issue: { ...issue } });
-
- wrapper.vm.$nextTick(done);
- });
-
- it('does not render list label but renders all other labels', () => {
- expect(wrapper.findAll(GlLabel).length).toBe(1);
- const label = wrapper.find(GlLabel);
- expect(label.props('title')).toEqual(label1.title);
- expect(label.props('description')).toEqual(label1.description);
- expect(label.props('backgroundColor')).toEqual(label1.color);
- });
-
- it('does not render label if label does not have an ID', (done) => {
- issue.addLabel(
- new ListLabel({
- title: 'closed',
- }),
- );
- wrapper.setProps({ issue: { ...issue } });
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.findAll(GlLabel).length).toBe(1);
- expect(wrapper.text()).not.toContain('closed');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('blocked', () => {
- beforeEach((done) => {
- wrapper.setProps({
- issue: {
- ...wrapper.props('issue'),
- blocked: true,
- },
- });
- wrapper.vm.$nextTick(done);
- });
-
- it('renders blocked icon if issue is blocked', () => {
- expect(wrapper.find('.issue-blocked-icon').exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/boards/issue_spec.js b/spec/frontend/boards/issue_spec.js
deleted file mode 100644
index 1f354fb04db..00000000000
--- a/spec/frontend/boards/issue_spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* global ListIssue */
-
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import boardsStore from '~/boards/stores/boards_store';
-import { setMockEndpoints, mockIssue } from './mock_data';
-
-describe('Issue model', () => {
- let issue;
-
- beforeEach(() => {
- setMockEndpoints();
- boardsStore.create();
-
- issue = new ListIssue(mockIssue);
- });
-
- it('has label', () => {
- expect(issue.labels.length).toBe(1);
- });
-
- it('add new label', () => {
- issue.addLabel({
- id: 2,
- title: 'bug',
- color: 'blue',
- description: 'bugs!',
- });
-
- expect(issue.labels.length).toBe(2);
- });
-
- it('does not add label if label id exists', () => {
- issue.addLabel({
- id: 1,
- title: 'test 2',
- color: 'blue',
- description: 'testing',
- });
-
- expect(issue.labels.length).toBe(1);
- expect(issue.labels[0].color).toBe('#F0AD4E');
- });
-
- it('adds other label with same title', () => {
- issue.addLabel({
- id: 2,
- title: 'test',
- color: 'blue',
- description: 'other test',
- });
-
- expect(issue.labels.length).toBe(2);
- });
-
- it('finds label', () => {
- const label = issue.findLabel(issue.labels[0]);
-
- expect(label).toBeDefined();
- });
-
- it('removes label', () => {
- const label = issue.findLabel(issue.labels[0]);
- issue.removeLabel(label);
-
- expect(issue.labels.length).toBe(0);
- });
-
- it('removes multiple labels', () => {
- issue.addLabel({
- id: 2,
- title: 'bug',
- color: 'blue',
- description: 'bugs!',
- });
-
- expect(issue.labels.length).toBe(2);
-
- issue.removeLabels([issue.labels[0], issue.labels[1]]);
-
- expect(issue.labels.length).toBe(0);
- });
-
- it('adds assignee', () => {
- issue.addAssignee({
- id: 2,
- name: 'Bruce Wayne',
- username: 'batman',
- avatar_url: 'http://batman',
- });
-
- expect(issue.assignees.length).toBe(2);
- });
-
- it('finds assignee', () => {
- const assignee = issue.findAssignee(issue.assignees[0]);
-
- expect(assignee).toBeDefined();
- });
-
- it('removes assignee', () => {
- const assignee = issue.findAssignee(issue.assignees[0]);
- issue.removeAssignee(assignee);
-
- expect(issue.assignees.length).toBe(0);
- });
-
- it('removes all assignees', () => {
- issue.removeAllAssignees();
-
- expect(issue.assignees.length).toBe(0);
- });
-
- it('sets position to infinity if no position is stored', () => {
- expect(issue.position).toBe(Infinity);
- });
-
- it('sets position', () => {
- const relativePositionIssue = new ListIssue({
- title: 'Testing',
- iid: 1,
- confidential: false,
- relative_position: 1,
- labels: [],
- assignees: [],
- });
-
- expect(relativePositionIssue.position).toBe(1);
- });
-
- it('updates data', () => {
- issue.updateData({ subscribed: true });
-
- expect(issue.subscribed).toBe(true);
- });
-
- it('sets fetching state', () => {
- expect(issue.isFetching.subscriptions).toBe(true);
-
- issue.setFetchingState('subscriptions', false);
-
- expect(issue.isFetching.subscriptions).toBe(false);
- });
-
- it('sets loading state', () => {
- issue.setLoadingState('foo', true);
-
- expect(issue.isLoading.foo).toBe(true);
- });
-
- describe('update', () => {
- it('passes update to boardsStore', () => {
- jest.spyOn(boardsStore, 'updateIssue').mockImplementation();
-
- issue.update();
-
- expect(boardsStore.updateIssue).toHaveBeenCalledWith(issue);
- });
- });
-});
diff --git a/spec/frontend/boards/list_spec.js b/spec/frontend/boards/list_spec.js
deleted file mode 100644
index 4d6a82bdff0..00000000000
--- a/spec/frontend/boards/list_spec.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/* global List */
-/* global ListAssignee */
-/* global ListIssue */
-/* global ListLabel */
-import MockAdapter from 'axios-mock-adapter';
-import waitForPromises from 'helpers/wait_for_promises';
-import '~/boards/models/label';
-import '~/boards/models/assignee';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import { ListType } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
-import axios from '~/lib/utils/axios_utils';
-import { listObj, listObjDuplicate, boardsMockInterceptor } from './mock_data';
-
-describe('List model', () => {
- let list;
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- boardsStore.create();
- boardsStore.setEndpoints({
- listsEndpoint: '/test/-/boards/1/lists',
- });
-
- list = new List(listObj);
- return waitForPromises();
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('list type', () => {
- const notExpandableList = ['blank'];
-
- const table = Object.keys(ListType).map((k) => {
- const value = ListType[k];
- return [value, !notExpandableList.includes(value)];
- });
- it.each(table)(`when list_type is %s boards isExpandable is %p`, (type, result) => {
- expect(new List({ id: 1, list_type: type }).isExpandable).toBe(result);
- });
- });
-
- it('gets issues when created', () => {
- expect(list.issues.length).toBe(1);
- });
-
- it('saves list and returns ID', () => {
- list = new List({
- title: 'test',
- label: {
- id: 1,
- title: 'test',
- color: '#ff0000',
- text_color: 'white',
- },
- });
- return list.save().then(() => {
- expect(list.id).toBe(listObj.id);
- expect(list.type).toBe('label');
- expect(list.position).toBe(0);
- expect(list.label).toEqual(listObj.label);
- });
- });
-
- it('destroys the list', () => {
- boardsStore.addList(listObj);
- list = boardsStore.findList('id', listObj.id);
-
- expect(boardsStore.state.lists.length).toBe(1);
- list.destroy();
-
- return waitForPromises().then(() => {
- expect(boardsStore.state.lists.length).toBe(0);
- });
- });
-
- it('gets issue from list', () => {
- const issue = list.findIssue(1);
-
- expect(issue).toBeDefined();
- });
-
- it('removes issue', () => {
- const issue = list.findIssue(1);
-
- expect(list.issues.length).toBe(1);
- list.removeIssue(issue);
-
- expect(list.issues.length).toBe(0);
- });
-
- it('sends service request to update issue label', () => {
- const listDup = new List(listObjDuplicate);
- const issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [list.label, listDup.label],
- assignees: [],
- });
-
- list.issues.push(issue);
- listDup.issues.push(issue);
-
- jest.spyOn(boardsStore, 'moveIssue');
-
- listDup.updateIssueLabel(issue, list);
-
- expect(boardsStore.moveIssue).toHaveBeenCalledWith(
- issue.id,
- list.id,
- listDup.id,
- undefined,
- undefined,
- );
- });
-
- describe('page number', () => {
- beforeEach(() => {
- jest.spyOn(list, 'getIssues').mockImplementation(() => {});
- list.issues = [];
- });
-
- it('increase page number if current issue count is more than the page size', () => {
- for (let i = 0; i < 30; i += 1) {
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: i,
- iid: i,
- confidential: false,
- labels: [list.label],
- assignees: [],
- }),
- );
- }
- list.issuesSize = 50;
-
- expect(list.issues.length).toBe(30);
-
- list.nextPage();
-
- expect(list.page).toBe(2);
- expect(list.getIssues).toHaveBeenCalled();
- });
-
- it('does not increase page number if issue count is less than the page size', () => {
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: 1,
- confidential: false,
- labels: [list.label],
- assignees: [],
- }),
- );
- list.issuesSize = 2;
-
- list.nextPage();
-
- expect(list.page).toBe(1);
- expect(list.getIssues).toHaveBeenCalled();
- });
- });
-
- describe('newIssue', () => {
- beforeEach(() => {
- jest.spyOn(boardsStore, 'newIssue').mockReturnValue(
- Promise.resolve({
- data: {
- id: 42,
- subscribed: false,
- assignable_labels_endpoint: '/issue/42/labels',
- toggle_subscription_endpoint: '/issue/42/subscriptions',
- issue_sidebar_endpoint: '/issue/42/sidebar_info',
- },
- }),
- );
- list.issues = [];
- });
-
- it('adds new issue to top of list', (done) => {
- const user = new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- });
-
- list.issues.push(
- new ListIssue({
- title: 'Testing',
- id: 1,
- confidential: false,
- labels: [new ListLabel(list.label)],
- assignees: [],
- }),
- );
- const dummyIssue = new ListIssue({
- title: 'new issue',
- id: 2,
- confidential: false,
- labels: [new ListLabel(list.label)],
- assignees: [user],
- subscribed: false,
- });
-
- list
- .newIssue(dummyIssue)
- .then(() => {
- expect(list.issues.length).toBe(2);
- expect(list.issues[0]).toBe(dummyIssue);
- expect(list.issues[0].subscribed).toBe(false);
- expect(list.issues[0].assignableLabelsEndpoint).toBe('/issue/42/labels');
- expect(list.issues[0].toggleSubscriptionEndpoint).toBe('/issue/42/subscriptions');
- expect(list.issues[0].sidebarInfoEndpoint).toBe('/issue/42/sidebar_info');
- expect(list.issues[0].labels).toBe(dummyIssue.labels);
- expect(list.issues[0].assignees).toBe(dummyIssue.assignees);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index 106f7b04c4b..6a4f344bbfb 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -1,12 +1,8 @@
-/* global List */
-
import { GlFilteredSearchToken } from '@gitlab/ui';
import { keyBy } from 'lodash';
-import Vue from 'vue';
-import '~/boards/models/list';
import { ListType } from '~/boards/constants';
-import boardsStore from '~/boards/stores/boards_store';
import { __ } from '~/locale';
+import { DEFAULT_MILESTONES_GRAPHQL } from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
@@ -196,8 +192,7 @@ export const mockIssue = {
export const mockActiveIssue = {
...mockIssue,
- fullId: 'gid://gitlab/Issue/436',
- id: 436,
+ id: 'gid://gitlab/Issue/436',
iid: '27',
subscribed: false,
emailsDisabled: false,
@@ -289,20 +284,6 @@ export const boardsMockInterceptor = (config) => {
return [200, body];
};
-export const setMockEndpoints = (opts = {}) => {
- const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/-/boards.json';
- const listsEndpoint = opts.listsEndpoint || '/test/-/boards/1/lists';
- const bulkUpdatePath = opts.bulkUpdatePath || '';
- const boardId = opts.boardId || '1';
-
- boardsStore.setEndpoints({
- boardsEndpoint,
- listsEndpoint,
- bulkUpdatePath,
- boardId,
- });
-};
-
export const mockList = {
id: 'gid://gitlab/List/1',
title: 'Open',
@@ -335,14 +316,26 @@ export const mockLabelList = {
issuesCount: 0,
};
+export const mockMilestoneList = {
+ id: 'gid://gitlab/List/3',
+ title: 'To Do',
+ position: 0,
+ listType: 'milestone',
+ collapsed: false,
+ label: null,
+ assignee: null,
+ milestone: {
+ webUrl: 'https://gitlab.com/h5bp/html5-boilerplate/-/milestones/1',
+ title: 'Backlog',
+ },
+ loading: false,
+ issuesCount: 0,
+};
+
export const mockLists = [mockList, mockLabelList];
export const mockListsById = keyBy(mockLists, 'id');
-export const mockListsWithModel = mockLists.map((listMock) =>
- Vue.observable(new List({ ...listMock, doNotFetchIssues: true })),
-);
-
export const mockIssuesByListId = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue3.id, mockIssue4.id],
'gid://gitlab/List/2': mockIssues.map(({ id }) => id),
@@ -547,17 +540,17 @@ export const mockMoveData = {
export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
{
- icon: 'labels',
- title: __('Label'),
- type: 'label_name',
+ icon: 'user',
+ title: __('Assignee'),
+ type: 'assignee_username',
operators: [
{ value: '=', description: 'is' },
{ value: '!=', description: 'is not' },
],
- token: LabelToken,
- unique: false,
- symbol: '~',
- fetchLabels,
+ token: AuthorToken,
+ unique: true,
+ fetchAuthors,
+ preloadedAuthors: [],
},
{
icon: 'pencil',
@@ -574,17 +567,27 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
preloadedAuthors: [],
},
{
- icon: 'user',
- title: __('Assignee'),
- type: 'assignee_username',
+ icon: 'labels',
+ title: __('Label'),
+ type: 'label_name',
operators: [
{ value: '=', description: 'is' },
{ value: '!=', description: 'is not' },
],
- token: AuthorToken,
+ token: LabelToken,
+ unique: false,
+ symbol: '~',
+ fetchLabels,
+ },
+ {
+ icon: 'clock',
+ title: __('Milestone'),
+ symbol: '%',
+ type: 'milestone_title',
+ token: MilestoneToken,
unique: true,
- fetchAuthors,
- preloadedAuthors: [],
+ defaultMilestones: DEFAULT_MILESTONES_GRAPHQL,
+ fetchMilestones,
},
{
icon: 'issues',
@@ -599,16 +602,6 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
],
},
{
- icon: 'clock',
- title: __('Milestone'),
- symbol: '%',
- type: 'milestone_title',
- token: MilestoneToken,
- unique: true,
- defaultMilestones: [],
- fetchMilestones,
- },
- {
icon: 'weight',
title: __('Weight'),
type: 'weight',
diff --git a/spec/frontend/boards/project_select_deprecated_spec.js b/spec/frontend/boards/project_select_deprecated_spec.js
deleted file mode 100644
index 4494de43083..00000000000
--- a/spec/frontend/boards/project_select_deprecated_spec.js
+++ /dev/null
@@ -1,263 +0,0 @@
-import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import axios from 'axios';
-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 createFlash from '~/flash';
-import httpStatus from '~/lib/utils/http_status';
-import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
-
-import { listObj, mockRawGroupProjects } from './mock_data';
-
-jest.mock('~/boards/eventhub');
-jest.mock('~/flash');
-
-const dummyGon = {
- api_version: 'v4',
- relative_url_root: '/gitlab',
-};
-
-const mockGroupId = 1;
-const mockProjectsList1 = mockRawGroupProjects.slice(0, 1);
-const mockProjectsList2 = mockRawGroupProjects.slice(1);
-const mockDefaultFetchOptions = {
- with_issues_enabled: true,
- with_shared: false,
- include_subgroups: true,
- order_by: 'similarity',
- archived: false,
-};
-
-const itemsPerPage = 20;
-
-describe('ProjectSelect component', () => {
- let wrapper;
- let axiosMock;
-
- const findLabel = () => wrapper.find("[data-testid='header-label']");
- const findGlDropdown = () => wrapper.find(GlDropdown);
- const findGlDropdownLoadingIcon = () =>
- findGlDropdown().find('button:first-child').find(GlLoadingIcon);
- const findGlSearchBoxByType = () => wrapper.find(GlSearchBoxByType);
- const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
- const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
- const findInMenuLoadingIcon = () => wrapper.find("[data-testid='dropdown-text-loading-icon']");
- const findEmptySearchMessage = () => wrapper.find("[data-testid='empty-result-message']");
-
- const mockGetRequest = (data = [], statusCode = httpStatus.OK) => {
- axiosMock
- .onGet(`/gitlab/api/v4/groups/${mockGroupId}/projects.json`)
- .replyOnce(statusCode, data);
- };
-
- const searchForProject = async (keyword, waitForAll = true) => {
- findGlSearchBoxByType().vm.$emit('input', keyword);
-
- if (waitForAll) {
- await axios.waitForAll();
- }
- };
-
- const createWrapper = async ({ list = listObj } = {}, waitForAll = true) => {
- wrapper = mount(ProjectSelect, {
- propsData: {
- list,
- },
- provide: {
- groupId: 1,
- },
- });
-
- if (waitForAll) {
- await axios.waitForAll();
- }
- };
-
- beforeEach(() => {
- axiosMock = new AxiosMockAdapter(axios);
- window.gon = dummyGon;
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- axiosMock.restore();
- jest.clearAllMocks();
- });
-
- it('displays a header title', async () => {
- createWrapper({});
-
- expect(findLabel().text()).toBe('Projects');
- });
-
- it('renders a default dropdown text', async () => {
- createWrapper({});
-
- expect(findGlDropdown().exists()).toBe(true);
- expect(findGlDropdown().text()).toContain('Select a project');
- });
-
- describe('when mounted', () => {
- it('displays a loading icon while projects are being fetched', async () => {
- mockGetRequest([]);
-
- createWrapper({}, false);
-
- expect(findGlDropdownLoadingIcon().exists()).toBe(true);
-
- await axios.waitForAll();
-
- expect(axiosMock.history.get[0].params).toMatchObject({ search: '' });
- expect(axiosMock.history.get[0].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
-
- expect(findGlDropdownLoadingIcon().exists()).toBe(false);
- });
- });
-
- describe('when dropdown menu is open', () => {
- describe('by default', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
- });
-
- it('shows GlSearchBoxByType with default attributes', () => {
- expect(findGlSearchBoxByType().exists()).toBe(true);
- expect(findGlSearchBoxByType().vm.$attrs).toMatchObject({
- placeholder: 'Search projects',
- debounce: '250',
- });
- });
-
- it("displays the fetched project's name", () => {
- expect(findFirstGlDropdownItem().exists()).toBe(true);
- expect(findFirstGlDropdownItem().text()).toContain(mockProjectsList1[0].name);
- });
-
- it("doesn't render loading icon in the menu", () => {
- expect(findInMenuLoadingIcon().isVisible()).toBe(false);
- });
-
- it('renders empty search result message', async () => {
- await createWrapper();
-
- expect(findEmptySearchMessage().exists()).toBe(true);
- });
- });
-
- describe('when a project is selected', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
-
- await findFirstGlDropdownItem().find('button').trigger('click');
- });
-
- it('emits setSelectedProject with correct project metadata', () => {
- expect(eventHub.$emit).toHaveBeenCalledWith('setSelectedProject', {
- id: mockProjectsList1[0].id,
- path: mockProjectsList1[0].path_with_namespace,
- name: mockProjectsList1[0].name,
- namespacedName: mockProjectsList1[0].name_with_namespace,
- });
- });
-
- it('renders the name of the selected project', () => {
- expect(findGlDropdown().find('.gl-new-dropdown-button-text').text()).toBe(
- mockProjectsList1[0].name,
- );
- });
- });
-
- describe('when user searches for a project', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList1);
-
- await createWrapper();
- });
-
- it('calls API with correct parameters with default fetch options', async () => {
- await searchForProject('foobar');
-
- const expectedApiParams = {
- search: 'foobar',
- per_page: itemsPerPage,
- ...mockDefaultFetchOptions,
- };
-
- expect(axiosMock.history.get[1].params).toMatchObject(expectedApiParams);
- expect(axiosMock.history.get[1].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
- });
-
- describe("when list type is defined and isn't backlog", () => {
- it('calls API with an additional fetch option (min_access_level)', async () => {
- axiosMock.reset();
-
- await createWrapper({ list: { ...listObj, type: ListType.label } });
-
- await searchForProject('foobar');
-
- const expectedApiParams = {
- search: 'foobar',
- per_page: itemsPerPage,
- ...mockDefaultFetchOptions,
- min_access_level: featureAccessLevel.EVERYONE,
- };
-
- expect(axiosMock.history.get[1].params).toMatchObject(expectedApiParams);
- expect(axiosMock.history.get[1].url).toBe(
- `/gitlab/api/v4/groups/${mockGroupId}/projects.json`,
- );
- });
- });
-
- it('displays and hides gl-loading-icon while and after fetching data', async () => {
- await searchForProject('some keyword', false);
-
- await wrapper.vm.$nextTick();
-
- expect(findInMenuLoadingIcon().isVisible()).toBe(true);
-
- await axios.waitForAll();
-
- expect(findInMenuLoadingIcon().isVisible()).toBe(false);
- });
-
- it('flashes an error message when fetching fails', async () => {
- mockGetRequest([], httpStatus.INTERNAL_SERVER_ERROR);
-
- await searchForProject('foobar');
-
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith({
- message: 'Something went wrong while fetching projects',
- });
- });
-
- describe('with non-empty search result', () => {
- beforeEach(async () => {
- mockGetRequest(mockProjectsList2);
-
- await searchForProject('foobar');
- });
-
- it('displays the retrieved list of projects', async () => {
- expect(findFirstGlDropdownItem().text()).toContain(mockProjectsList2[0].name);
- });
-
- it('does not render empty search result message', async () => {
- expect(findEmptySearchMessage().exists()).toBe(false);
- });
- });
- });
- });
-});
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 1272a573d2f..62e0fa7a68a 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -26,7 +26,6 @@ import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql'
import actions, { gqlClient } from '~/boards/stores/actions';
import * as types from '~/boards/stores/mutation_types';
import mutations from '~/boards/stores/mutations';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import {
mockLists,
@@ -107,12 +106,7 @@ describe('setFilters', () => {
});
describe('performSearch', () => {
- it('should dispatch setFilters action', (done) => {
- testAction(actions.performSearch, {}, {}, [], [{ type: 'setFilters', payload: {} }], done);
- });
-
- it('should dispatch setFilters, fetchLists and resetIssues action when graphqlBoardLists FF is on', (done) => {
- window.gon = { features: { graphqlBoardLists: true } };
+ it('should dispatch setFilters, fetchLists and resetIssues action', (done) => {
testAction(
actions.performSearch,
{},
@@ -496,12 +490,9 @@ describe('fetchLabels', () => {
jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
const commit = jest.fn();
- const getters = {
- shouldUseGraphQL: () => true,
- };
const state = { boardType: 'group' };
- await actions.fetchLabels({ getters, state, commit });
+ await actions.fetchLabels({ state, commit });
expect(commit).toHaveBeenCalledWith(types.RECEIVE_LABELS_SUCCESS, labels);
});
@@ -954,7 +945,7 @@ describe('moveIssue', () => {
});
describe('moveIssueCard and undoMoveIssueCard', () => {
- describe('card should move without clonning', () => {
+ describe('card should move without cloning', () => {
let state;
let params;
let moveMutations;
@@ -1221,8 +1212,8 @@ describe('updateMovedIssueCard', () => {
describe('updateIssueOrder', () => {
const issues = {
- 436: mockIssue,
- 437: mockIssue2,
+ [mockIssue.id]: mockIssue,
+ [mockIssue2.id]: mockIssue2,
};
const state = {
@@ -1231,7 +1222,7 @@ describe('updateIssueOrder', () => {
};
const moveData = {
- itemId: 436,
+ itemId: mockIssue.id,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
};
@@ -1490,7 +1481,7 @@ describe('addListNewIssue', () => {
type: 'addListItem',
payload: {
list: fakeList,
- item: formatIssue({ ...mockIssue, id: getIdFromGraphQLId(mockIssue.id) }),
+ item: formatIssue(mockIssue),
position: 0,
},
},
diff --git a/spec/frontend/boards/stores/getters_spec.js b/spec/frontend/boards/stores/getters_spec.js
index c0774dd3ae1..b30968c45d7 100644
--- a/spec/frontend/boards/stores/getters_spec.js
+++ b/spec/frontend/boards/stores/getters_spec.js
@@ -77,12 +77,12 @@ describe('Boards - Getters', () => {
});
describe('getBoardItemById', () => {
- const state = { boardItems: { 1: 'issue' } };
+ const state = { boardItems: { 'gid://gitlab/Issue/1': 'issue' } };
it.each`
- id | expected
- ${'1'} | ${'issue'}
- ${''} | ${{}}
+ id | expected
+ ${'gid://gitlab/Issue/1'} | ${'issue'}
+ ${''} | ${{}}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
expect(getters.getBoardItemById(state)(id)).toEqual(expected);
});
@@ -90,11 +90,11 @@ describe('Boards - Getters', () => {
describe('activeBoardItem', () => {
it.each`
- id | expected
- ${'1'} | ${'issue'}
- ${''} | ${{ id: '', iid: '', fullId: '' }}
+ id | expected
+ ${'gid://gitlab/Issue/1'} | ${'issue'}
+ ${''} | ${{ id: '', iid: '' }}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
- const state = { boardItems: { 1: 'issue' }, activeId: id };
+ const state = { boardItems: { 'gid://gitlab/Issue/1': 'issue' }, activeId: id };
expect(getters.activeBoardItem(state)).toEqual(expected);
});
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index a2ba1e9eb5e..0e830258327 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -407,7 +407,7 @@ describe('Board Store Mutations', () => {
describe('MUTATE_ISSUE_SUCCESS', () => {
it('updates issue in issues state', () => {
const issues = {
- 436: { id: rawIssue.id },
+ [rawIssue.id]: { id: rawIssue.id },
};
state = {
@@ -419,7 +419,7 @@ describe('Board Store Mutations', () => {
issue: rawIssue,
});
- expect(state.boardItems).toEqual({ 436: { ...mockIssue, id: 436 } });
+ expect(state.boardItems).toEqual({ [mockIssue.id]: mockIssue });
});
});
@@ -545,7 +545,7 @@ describe('Board Store Mutations', () => {
expect(state.groupProjectsFlags.isLoading).toBe(true);
});
- it('Should set isLoading in groupProjectsFlags to true in state when fetchNext is true', () => {
+ it('Should set isLoadingMore in groupProjectsFlags to true in state when fetchNext is true', () => {
mutations[types.REQUEST_GROUP_PROJECTS](state, true);
expect(state.groupProjectsFlags.isLoadingMore).toBe(true);