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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/boards')
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js19
-rw-r--r--spec/frontend/boards/board_list_helper.js2
-rw-r--r--spec/frontend/boards/board_list_spec.js2
-rw-r--r--spec/frontend/boards/components/board_card_spec.js37
-rw-r--r--spec/frontend/boards/components/board_form_spec.js19
-rw-r--r--spec/frontend/boards/components/boards_selector_spec.js79
-rw-r--r--spec/frontend/boards/components/issue_board_filtered_search_spec.js5
-rw-r--r--spec/frontend/boards/mock_data.js10
8 files changed, 107 insertions, 66 deletions
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 95b5712bab0..8314cbda7a1 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -10,6 +10,7 @@ import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import IssuableBlockedIcon from '~/vue_shared/components/issuable_blocked_icon/issuable_blocked_icon.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
+import isShowingLabelsQuery from '~/graphql_shared/client/is_showing_labels.query.graphql';
import WorkItemTypeIcon from '~/work_items/components/work_item_type_icon.vue';
import eventHub from '~/boards/eventhub';
import defaultStore from '~/boards/stores';
@@ -63,17 +64,23 @@ describe('Board card component', () => {
actions: {
performSearch: performSearchMock,
},
- state: {
- ...defaultStore.state,
- isShowingLabels: true,
- },
+ state: defaultStore.state,
});
};
+ const mockApollo = createMockApollo();
+
const createWrapper = ({ props = {}, isEpicBoard = false, isGroupBoard = true } = {}) => {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: isShowingLabelsQuery,
+ data: {
+ isShowingLabels: true,
+ },
+ });
+
wrapper = mountExtended(BoardCardInner, {
store,
- apolloProvider: createMockApollo(),
+ apolloProvider: mockApollo,
propsData: {
list,
item: issue,
@@ -235,7 +242,7 @@ describe('Board card component', () => {
expect(tooltip).toBeDefined();
expect(findHiddenIssueIcon().attributes('title')).toBe(
- 'This issue is hidden because its author has been banned',
+ 'This issue is hidden because its author has been banned.',
);
});
});
diff --git a/spec/frontend/boards/board_list_helper.js b/spec/frontend/boards/board_list_helper.js
index 7367b34c4df..5bafd9a8d0e 100644
--- a/spec/frontend/boards/board_list_helper.js
+++ b/spec/frontend/boards/board_list_helper.js
@@ -122,5 +122,7 @@ export default function createComponent({
},
});
+ jest.spyOn(store, 'dispatch').mockImplementation(() => {});
+
return component;
}
diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js
index e0a110678b1..30bb4fba4e3 100644
--- a/spec/frontend/boards/board_list_spec.js
+++ b/spec/frontend/boards/board_list_spec.js
@@ -202,8 +202,6 @@ describe('Board list component', () => {
describe('handleDragOnEnd', () => {
beforeEach(() => {
- jest.spyOn(wrapper.vm, 'moveItem').mockImplementation(() => {});
-
startDrag();
});
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index f0d40af94fe..11f9a4f6ff2 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -4,11 +4,14 @@ import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
+import waitForPromises from 'helpers/wait_for_promises';
import createMockApollo from 'helpers/mock_apollo_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import BoardCard from '~/boards/components/board_card.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
import { inactiveId } from '~/boards/constants';
+import selectedBoardItemsQuery from '~/boards/graphql/client/selected_board_items.query.graphql';
+import isShowingLabelsQuery from '~/graphql_shared/client/is_showing_labels.query.graphql';
import { mockLabelList, mockIssue, DEFAULT_COLOR } from '../mock_data';
describe('Board card', () => {
@@ -20,9 +23,11 @@ describe('Board card', () => {
Vue.use(VueApollo);
const mockSetActiveBoardItemResolver = jest.fn();
+ const mockSetSelectedBoardItemsResolver = jest.fn();
const mockApollo = createMockApollo([], {
Mutation: {
setActiveBoardItem: mockSetActiveBoardItemResolver,
+ setSelectedBoardItems: mockSetSelectedBoardItemsResolver,
},
});
@@ -49,7 +54,21 @@ describe('Board card', () => {
provide = {},
stubs = { BoardCardInner },
item = mockIssue,
+ selectedBoardItems = [],
} = {}) => {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: isShowingLabelsQuery,
+ data: {
+ isShowingLabels: true,
+ },
+ });
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: selectedBoardItemsQuery,
+ data: {
+ selectedBoardItems,
+ },
+ });
+
wrapper = shallowMountExtended(BoardCard, {
apolloProvider: mockApollo,
stubs: {
@@ -99,7 +118,7 @@ describe('Board card', () => {
describe('when GlLabel is clicked in BoardCardInner', () => {
it('doesnt call toggleBoardItem', () => {
- createStore({ initialState: { isShowingLabels: true } });
+ createStore();
mountComponent();
wrapper.findComponent(GlLabel).trigger('mouseup');
@@ -132,10 +151,9 @@ describe('Board card', () => {
createStore({
initialState: {
activeId: inactiveId,
- selectedBoardItems: [mockIssue],
},
});
- mountComponent();
+ mountComponent({ selectedBoardItems: [mockIssue.id] });
expect(wrapper.classes()).toContain('multi-select');
expect(wrapper.classes()).not.toContain('is-active');
@@ -163,13 +181,17 @@ describe('Board card', () => {
window.gon = { features: { boardMultiSelect: true } };
});
- it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
+ it('should call setSelectedBoardItemsMutation with correct parameters', async () => {
await multiSelectCard();
- expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledTimes(1);
- expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledWith(
+ expect(mockSetSelectedBoardItemsResolver).toHaveBeenCalledTimes(1);
+ expect(mockSetSelectedBoardItemsResolver).toHaveBeenCalledWith(
expect.any(Object),
- mockIssue,
+ {
+ itemId: mockIssue.id,
+ },
+ expect.anything(),
+ expect.anything(),
);
});
});
@@ -240,6 +262,7 @@ describe('Board card', () => {
it('set active board item on client when clicking on card', async () => {
await selectCard();
+ await waitForPromises();
expect(mockSetActiveBoardItemResolver).toHaveBeenCalledWith(
{},
diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js
index 15ee3976fb1..a0dacf085e2 100644
--- a/spec/frontend/boards/components/board_form_spec.js
+++ b/spec/frontend/boards/components/board_form_spec.js
@@ -14,6 +14,7 @@ import createBoardMutation from '~/boards/graphql/board_create.mutation.graphql'
import destroyBoardMutation from '~/boards/graphql/board_destroy.mutation.graphql';
import updateBoardMutation from '~/boards/graphql/board_update.mutation.graphql';
import eventHub from '~/boards/eventhub';
+import * as cacheUpdates from '~/boards/graphql/cache_updates';
import { visitUrl } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
@@ -55,12 +56,10 @@ describe('BoardForm', () => {
const findInput = () => wrapper.find('#board-new-name');
const setBoardMock = jest.fn();
- const setErrorMock = jest.fn();
const store = new Vuex.Store({
actions: {
setBoard: setBoardMock,
- setError: setErrorMock,
},
});
@@ -113,6 +112,10 @@ describe('BoardForm', () => {
});
};
+ beforeEach(() => {
+ cacheUpdates.setError = jest.fn();
+ });
+
describe('when user can not admin the board', () => {
beforeEach(() => {
createComponent({
@@ -237,7 +240,7 @@ describe('BoardForm', () => {
await waitForPromises();
expect(setBoardMock).not.toHaveBeenCalled();
- expect(setErrorMock).toHaveBeenCalled();
+ expect(cacheUpdates.setError).toHaveBeenCalled();
});
describe('when Apollo boards FF is on', () => {
@@ -353,7 +356,7 @@ describe('BoardForm', () => {
await waitForPromises();
expect(setBoardMock).not.toHaveBeenCalled();
- expect(setErrorMock).toHaveBeenCalled();
+ expect(cacheUpdates.setError).toHaveBeenCalled();
});
describe('when Apollo boards FF is on', () => {
@@ -434,9 +437,11 @@ describe('BoardForm', () => {
await waitForPromises();
expect(visitUrl).not.toHaveBeenCalled();
- expect(store.dispatch).toHaveBeenCalledWith('setError', {
- message: 'Failed to delete board. Please try again.',
- });
+ expect(cacheUpdates.setError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: 'Failed to delete board. Please try again.',
+ }),
+ );
});
});
});
diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js
index fa18b47cf54..0a628af9939 100644
--- a/spec/frontend/boards/components/boards_selector_spec.js
+++ b/spec/frontend/boards/components/boards_selector_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
+import { GlCollapsibleListbox } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
// eslint-disable-next-line no-restricted-imports
@@ -13,7 +13,7 @@ import projectRecentBoardsQuery from '~/boards/graphql/project_recent_boards.que
import * as cacheUpdates from '~/boards/graphql/cache_updates';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import createMockApollo from 'helpers/mock_apollo_helper';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
mockBoard,
mockGroupAllBoardsResponse,
@@ -47,17 +47,11 @@ describe('BoardsSelector', () => {
});
};
- const fillSearchBox = (filterTerm) => {
- const searchBox = wrapper.findComponent({ ref: 'searchBox' });
- const searchBoxInput = searchBox.find('input');
- searchBoxInput.setValue(filterTerm);
- searchBoxInput.trigger('input');
- };
+ const findDropdown = () => wrapper.findComponent(GlCollapsibleListbox);
- const getDropdownItems = () => wrapper.findAllByTestId('dropdown-item');
- const getDropdownHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
- const getLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const fillSearchBox = async (filterTerm) => {
+ await findDropdown().vm.$emit('search', filterTerm);
+ };
const projectBoardsQueryHandlerSuccess = jest
.fn()
@@ -96,7 +90,7 @@ describe('BoardsSelector', () => {
[groupRecentBoardsQuery, groupRecentBoardsQueryHandlerSuccess],
]);
- wrapper = mountExtended(BoardsSelector, {
+ wrapper = shallowMountExtended(BoardsSelector, {
store,
apolloProvider: fakeApollo,
propsData: {
@@ -142,13 +136,19 @@ describe('BoardsSelector', () => {
});
it('shows loading spinner', async () => {
+ createComponent({
+ provide: {
+ isApolloBoard: true,
+ },
+ props: {
+ isCurrentBoardLoading: true,
+ },
+ });
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
+ findDropdown().vm.$emit('shown');
await nextTick();
- expect(getLoadingIcon().exists()).toBe(true);
- expect(getDropdownHeaders()).toHaveLength(0);
- expect(getDropdownItems()).toHaveLength(0);
+ expect(findDropdown().props('loading')).toBe(true);
});
});
@@ -158,7 +158,7 @@ describe('BoardsSelector', () => {
await nextTick();
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
+ findDropdown().vm.$emit('shown');
await nextTick();
});
@@ -167,9 +167,8 @@ describe('BoardsSelector', () => {
expect(projectBoardsQueryHandlerSuccess).toHaveBeenCalled();
});
- it('hides loading spinner', async () => {
- await nextTick();
- expect(getLoadingIcon().exists()).toBe(false);
+ it('hides loading spinner', () => {
+ expect(findDropdown().props('loading')).toBe(false);
});
describe('filtering', () => {
@@ -178,25 +177,26 @@ describe('BoardsSelector', () => {
});
it('shows all boards without filtering', () => {
- expect(getDropdownItems()).toHaveLength(boards.length + recentIssueBoards.length);
+ expect(findDropdown().props('items')[0].text).toBe('Recent');
+ expect(findDropdown().props('items')[0].options).toHaveLength(recentIssueBoards.length);
+ expect(findDropdown().props('items')[1].text).toBe('All');
+ expect(findDropdown().props('items')[1].options).toHaveLength(
+ boards.length - recentIssueBoards.length,
+ );
});
it('shows only matching boards when filtering', async () => {
const filterTerm = 'board1';
const expectedCount = boards.filter((board) => board.name.includes(filterTerm)).length;
- fillSearchBox(filterTerm);
-
- await nextTick();
- expect(getDropdownItems()).toHaveLength(expectedCount);
+ await fillSearchBox(filterTerm);
+ expect(findDropdown().props('items')).toHaveLength(expectedCount);
});
it('shows message if there are no matching boards', async () => {
- fillSearchBox('does not exist');
+ await fillSearchBox('does not exist');
- await nextTick();
- expect(getDropdownItems()).toHaveLength(0);
- expect(wrapper.text().includes('No matching boards found')).toBe(true);
+ expect(findDropdown().props('noResultsText')).toBe('No matching boards found');
});
});
@@ -204,14 +204,18 @@ describe('BoardsSelector', () => {
it('shows only when boards are greater than 10', async () => {
await nextTick();
expect(projectRecentBoardsQueryHandlerSuccess).toHaveBeenCalled();
- expect(getDropdownHeaders()).toHaveLength(2);
+
+ expect(findDropdown().props('items')).toHaveLength(2);
+ expect(findDropdown().props('items')[0].text).toBe('Recent');
+ expect(findDropdown().props('items')[1].text).toBe('All');
});
it('does not show when boards are less than 10', async () => {
createComponent({ projectBoardsQueryHandler: smallBoardsQueryHandlerSuccess });
await nextTick();
- expect(getDropdownHeaders()).toHaveLength(0);
+
+ expect(findDropdown().props('items')).toHaveLength(0);
});
it('does not show when recentIssueBoards api returns empty array', async () => {
@@ -220,14 +224,14 @@ describe('BoardsSelector', () => {
});
await nextTick();
- expect(getDropdownHeaders()).toHaveLength(0);
+ expect(findDropdown().props('items')).toHaveLength(0);
});
it('does not show when search is active', async () => {
fillSearchBox('Random string');
await nextTick();
- expect(getDropdownHeaders()).toHaveLength(0);
+ expect(findDropdown().props('items')).toHaveLength(0);
});
});
});
@@ -248,7 +252,7 @@ describe('BoardsSelector', () => {
await nextTick();
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
+ findDropdown().vm.$emit('shown');
await nextTick();
@@ -272,7 +276,7 @@ describe('BoardsSelector', () => {
await nextTick();
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
- findDropdown().vm.$emit('show');
+ findDropdown().vm.$emit('shown');
await waitForPromises();
@@ -286,6 +290,7 @@ describe('BoardsSelector', () => {
createStore();
createComponent({ provide: { multipleIssueBoardsAvailable: true } });
expect(findDropdown().exists()).toBe(true);
+ expect(findDropdown().props('toggleText')).toBe('Select board');
});
});
@@ -296,6 +301,7 @@ describe('BoardsSelector', () => {
provide: { multipleIssueBoardsAvailable: false, hasMissingBoards: true },
});
expect(findDropdown().exists()).toBe(true);
+ expect(findDropdown().props('toggleText')).toBe('Select board');
});
});
@@ -317,6 +323,7 @@ describe('BoardsSelector', () => {
provide: { isApolloBoard: true },
});
expect(findDropdown().props('loading')).toBe(true);
+ expect(findDropdown().props('toggleText')).toBe('Select board');
});
});
});
diff --git a/spec/frontend/boards/components/issue_board_filtered_search_spec.js b/spec/frontend/boards/components/issue_board_filtered_search_spec.js
index 16ad54f0854..1edb6812af0 100644
--- a/spec/frontend/boards/components/issue_board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/issue_board_filtered_search_spec.js
@@ -26,14 +26,11 @@ describe('IssueBoardFilter', () => {
});
};
- let fetchUsersSpy;
let fetchLabelsSpy;
beforeEach(() => {
- fetchUsersSpy = jest.fn();
fetchLabelsSpy = jest.fn();
issueBoardFilters.mockReturnValue({
- fetchUsers: fetchUsersSpy,
fetchLabels: fetchLabelsSpy,
});
});
@@ -61,7 +58,7 @@ describe('IssueBoardFilter', () => {
({ isSignedIn }) => {
createComponent({ isSignedIn });
- const tokens = mockTokens(fetchLabelsSpy, fetchUsersSpy, isSignedIn);
+ const tokens = mockTokens(fetchLabelsSpy, isSignedIn);
expect(findBoardsFilteredSearch().props('tokens')).toEqual(orderBy(tokens, ['title']));
},
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index dfcdb4c05d0..dfc8b18e197 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -827,7 +827,7 @@ export const mockConfidentialToken = {
],
};
-export const mockTokens = (fetchLabels, fetchUsers, isSignedIn) => [
+export const mockTokens = (fetchLabels, isSignedIn) => [
{
icon: 'user',
title: TOKEN_TITLE_ASSIGNEE,
@@ -836,7 +836,8 @@ export const mockTokens = (fetchLabels, fetchUsers, isSignedIn) => [
token: UserToken,
dataType: 'user',
unique: true,
- fetchUsers,
+ fullPath: 'gitlab-org',
+ isProject: false,
preloadedUsers: [],
},
{
@@ -848,7 +849,8 @@ export const mockTokens = (fetchLabels, fetchUsers, isSignedIn) => [
token: UserToken,
dataType: 'user',
unique: true,
- fetchUsers,
+ fullPath: 'gitlab-org',
+ isProject: false,
preloadedUsers: [],
},
{
@@ -973,7 +975,7 @@ export const boardListQueryResponse = ({
boardList: {
__typename: 'BoardList',
id: listId,
- totalWeight: 5,
+ totalIssueWeight: '5',
issuesCount,
},
},