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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /spec/frontend/boards/components
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'spec/frontend/boards/components')
-rw-r--r--spec/frontend/boards/components/board_card_spec.js126
-rw-r--r--spec/frontend/boards/components/board_content_sidebar_spec.js4
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js146
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js32
4 files changed, 241 insertions, 67 deletions
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index 022f8c05e1e..ceafa6ead94 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -1,4 +1,5 @@
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlLabel } from '@gitlab/ui';
+import { createLocalVue, shallowMount, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import BoardCard from '~/boards/components/board_card.vue';
@@ -14,10 +15,11 @@ describe('Board card', () => {
const localVue = createLocalVue();
localVue.use(Vuex);
- const createStore = ({ initialState = {}, isSwimlanesOn = false } = {}) => {
+ const createStore = ({ initialState = {} } = {}) => {
mockActions = {
toggleBoardItem: jest.fn(),
toggleBoardItemMultiSelection: jest.fn(),
+ performSearch: jest.fn(),
};
store = new Vuex.Store({
@@ -28,19 +30,21 @@ describe('Board card', () => {
},
actions: mockActions,
getters: {
- isSwimlanesOn: () => isSwimlanesOn,
isEpicBoard: () => false,
},
});
};
// this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
- const mountComponent = ({ propsData = {}, provide = {} } = {}) => {
- wrapper = shallowMount(BoardCard, {
+ const mountComponent = ({
+ propsData = {},
+ provide = {},
+ mountFn = shallowMount,
+ stubs = { BoardCardInner },
+ } = {}) => {
+ wrapper = mountFn(BoardCard, {
localVue,
- stubs: {
- BoardCardInner,
- },
+ stubs,
store,
propsData: {
list: mockLabelList,
@@ -74,72 +78,76 @@ describe('Board card', () => {
store = null;
});
- describe.each`
- isSwimlanesOn
- ${true} | ${false}
- `('when isSwimlanesOn is $isSwimlanesOn', ({ isSwimlanesOn }) => {
- it('should not highlight the card by default', async () => {
- createStore({ isSwimlanesOn });
- mountComponent();
+ describe('when GlLabel is clicked in BoardCardInner', () => {
+ it('doesnt call toggleBoardItem', () => {
+ createStore({ initialState: { isShowingLabels: true } });
+ mountComponent({ mountFn: mount, stubs: {} });
+
+ wrapper.find(GlLabel).trigger('mouseup');
- expect(wrapper.classes()).not.toContain('is-active');
- expect(wrapper.classes()).not.toContain('multi-select');
+ expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(0);
});
+ });
- it('should highlight the card with a correct style when selected', async () => {
- createStore({
- initialState: {
- activeId: mockIssue.id,
- },
- isSwimlanesOn,
- });
- mountComponent();
+ it('should not highlight the card by default', async () => {
+ createStore();
+ mountComponent();
- expect(wrapper.classes()).toContain('is-active');
- expect(wrapper.classes()).not.toContain('multi-select');
+ expect(wrapper.classes()).not.toContain('is-active');
+ expect(wrapper.classes()).not.toContain('multi-select');
+ });
+
+ it('should highlight the card with a correct style when selected', async () => {
+ createStore({
+ initialState: {
+ activeId: mockIssue.id,
+ },
});
+ mountComponent();
- it('should highlight the card with a correct style when multi-selected', async () => {
- createStore({
- initialState: {
- activeId: inactiveId,
- selectedBoardItems: [mockIssue],
- },
- isSwimlanesOn,
- });
- mountComponent();
+ expect(wrapper.classes()).toContain('is-active');
+ expect(wrapper.classes()).not.toContain('multi-select');
+ });
- expect(wrapper.classes()).toContain('multi-select');
- expect(wrapper.classes()).not.toContain('is-active');
+ it('should highlight the card with a correct style when multi-selected', async () => {
+ createStore({
+ initialState: {
+ activeId: inactiveId,
+ selectedBoardItems: [mockIssue],
+ },
});
+ mountComponent();
- describe('when mouseup event is called on the card', () => {
- beforeEach(() => {
- createStore({ isSwimlanesOn });
- mountComponent();
- });
+ expect(wrapper.classes()).toContain('multi-select');
+ expect(wrapper.classes()).not.toContain('is-active');
+ });
- describe('when not using multi-select', () => {
- it('should call vuex action "toggleBoardItem" with correct parameters', async () => {
- await selectCard();
+ describe('when mouseup event is called on the card', () => {
+ beforeEach(() => {
+ createStore();
+ mountComponent();
+ });
+
+ describe('when not using multi-select', () => {
+ it('should call vuex action "toggleBoardItem" with correct parameters', async () => {
+ await selectCard();
- expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(1);
- expect(mockActions.toggleBoardItem).toHaveBeenCalledWith(expect.any(Object), {
- boardItem: mockIssue,
- });
+ expect(mockActions.toggleBoardItem).toHaveBeenCalledTimes(1);
+ expect(mockActions.toggleBoardItem).toHaveBeenCalledWith(expect.any(Object), {
+ boardItem: mockIssue,
});
});
+ });
- describe('when using multi-select', () => {
- it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
- await multiSelectCard();
+ describe('when using multi-select', () => {
+ it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
+ await multiSelectCard();
- expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledTimes(1);
- expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledWith(
- expect.any(Object),
- mockIssue,
- );
- });
+ expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledTimes(1);
+ expect(mockActions.toggleBoardItemMultiSelection).toHaveBeenCalledWith(
+ expect.any(Object),
+ mockIssue,
+ );
});
});
});
diff --git a/spec/frontend/boards/components/board_content_sidebar_spec.js b/spec/frontend/boards/components/board_content_sidebar_spec.js
index 7f949739891..01c99a02db2 100644
--- a/spec/frontend/boards/components/board_content_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_content_sidebar_spec.js
@@ -6,9 +6,9 @@ import BoardContentSidebar from '~/boards/components/board_content_sidebar.vue';
import BoardSidebarDueDate from '~/boards/components/sidebar/board_sidebar_due_date.vue';
import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue';
import BoardSidebarMilestoneSelect from '~/boards/components/sidebar/board_sidebar_milestone_select.vue';
-import BoardSidebarSubscription from '~/boards/components/sidebar/board_sidebar_subscription.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
import { ISSUABLE } from '~/boards/constants';
+import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
import { mockIssue, mockIssueGroupPath, mockIssueProjectPath } from '../mock_data';
describe('BoardContentSidebar', () => {
@@ -111,7 +111,7 @@ describe('BoardContentSidebar', () => {
});
it('renders BoardSidebarSubscription', () => {
- expect(wrapper.find(BoardSidebarSubscription).exists()).toBe(true);
+ expect(wrapper.find(SidebarSubscriptionsWidget).exists()).toBe(true);
});
it('renders BoardSidebarMilestoneSelect', () => {
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
new file mode 100644
index 00000000000..e27badca9de
--- /dev/null
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -0,0 +1,146 @@
+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';
+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';
+
+Vue.use(Vuex);
+
+describe('BoardFilteredSearch', () => {
+ let wrapper;
+ let store;
+ const tokens = [
+ {
+ icon: 'labels',
+ title: __('Label'),
+ type: 'label_name',
+ operators: [
+ { value: '=', description: 'is' },
+ { value: '!=', description: 'is not' },
+ ],
+ token: LabelToken,
+ unique: false,
+ symbol: '~',
+ fetchLabels: () => new Promise(() => {}),
+ },
+ {
+ icon: 'pencil',
+ title: __('Author'),
+ type: 'author_username',
+ operators: [
+ { value: '=', description: 'is' },
+ { value: '!=', description: 'is not' },
+ ],
+ symbol: '@',
+ token: AuthorToken,
+ unique: true,
+ fetchAuthors: () => new Promise(() => {}),
+ },
+ ];
+
+ const createComponent = ({ initialFilterParams = {} } = {}) => {
+ wrapper = shallowMount(BoardFilteredSearch, {
+ provide: { initialFilterParams, fullPath: '' },
+ store,
+ propsData: {
+ tokens,
+ },
+ });
+ };
+
+ const findFilteredSearch = () => wrapper.findComponent(FilteredSearchBarRoot);
+
+ beforeEach(() => {
+ // this needed for actions call for performSearch
+ window.gon = { features: {} };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('default', () => {
+ beforeEach(() => {
+ store = createStore();
+
+ jest.spyOn(store, 'dispatch');
+
+ createComponent();
+ });
+
+ it('renders FilteredSearch', () => {
+ expect(findFilteredSearch().exists()).toBe(true);
+ });
+
+ it('passes the correct tokens to FilteredSearch', () => {
+ expect(findFilteredSearch().props('tokens')).toEqual(tokens);
+ });
+
+ describe('when onFilter is emitted', () => {
+ it('calls performSearch', () => {
+ findFilteredSearch().vm.$emit('onFilter', [{ value: { data: '' } }]);
+
+ expect(store.dispatch).toHaveBeenCalledWith('performSearch');
+ });
+
+ it('calls historyPushState', () => {
+ jest.spyOn(urlUtility, 'updateHistory');
+ findFilteredSearch().vm.$emit('onFilter', [{ value: { data: 'searchQuery' } }]);
+
+ expect(urlUtility.updateHistory).toHaveBeenCalledWith({
+ replace: true,
+ title: '',
+ url: 'http://test.host/',
+ });
+ });
+ });
+ });
+
+ describe('when searching', () => {
+ beforeEach(() => {
+ store = createStore();
+
+ jest.spyOn(store, 'dispatch');
+
+ createComponent();
+ });
+
+ it('sets the url params to the correct results', async () => {
+ const mockFilters = [
+ { type: 'author_username', value: { data: 'root', operator: '=' } },
+ { type: 'label_name', value: { data: 'label', operator: '=' } },
+ { type: 'label_name', value: { data: 'label2', operator: '=' } },
+ ];
+ jest.spyOn(urlUtility, 'updateHistory');
+ findFilteredSearch().vm.$emit('onFilter', mockFilters);
+
+ expect(urlUtility.updateHistory).toHaveBeenCalledWith({
+ title: '',
+ replace: true,
+ url: 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2',
+ });
+ });
+ });
+
+ describe('when url params are already set', () => {
+ beforeEach(() => {
+ store = createStore();
+
+ jest.spyOn(store, 'dispatch');
+
+ createComponent({ initialFilterParams: { authorUsername: 'root', labelName: ['label'] } });
+ });
+
+ it('passes the correct props to FilterSearchBar', () => {
+ expect(findFilteredSearch().props('initialFilterValue')).toEqual([
+ { type: 'author_username', value: { data: 'root', operator: '=' } },
+ { type: 'label_name', value: { data: 'label', operator: '=' } },
+ ]);
+ });
+ });
+});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
index 153d0640b23..ad682774ee6 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
@@ -1,7 +1,11 @@
import { GlLabel } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { TEST_HOST } from 'helpers/test_constants';
-import { labels as TEST_LABELS, mockIssue as TEST_ISSUE } from 'jest/boards/mock_data';
+import {
+ labels as TEST_LABELS,
+ mockIssue as TEST_ISSUE,
+ mockIssueFullPath as TEST_ISSUE_FULLPATH,
+} from 'jest/boards/mock_data';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue';
import { createStore } from '~/boards/stores';
@@ -23,7 +27,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
wrapper = null;
});
- const createWrapper = ({ labels = [] } = {}) => {
+ const createWrapper = ({ labels = [], providedValues = {} } = {}) => {
store = createStore();
store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, labels } };
store.state.activeId = TEST_ISSUE.id;
@@ -32,9 +36,9 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
store,
provide: {
canUpdate: true,
- labelsFetchPath: TEST_HOST,
labelsManagePath: TEST_HOST,
labelsFilterBasePath: TEST_HOST,
+ ...providedValues,
},
stubs: {
BoardEditableItem,
@@ -48,6 +52,22 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
wrapper.findAll(GlLabel).wrappers.map((item) => item.props('title'));
const findCollapsed = () => wrapper.find('[data-testid="collapsed-content"]');
+ describe('when labelsFetchPath is provided', () => {
+ it('uses injected labels fetch path', () => {
+ createWrapper({ providedValues: { labelsFetchPath: 'foobar' } });
+
+ expect(findLabelsSelect().props('labelsFetchPath')).toEqual('foobar');
+ });
+ });
+
+ it('uses the default project label endpoint', () => {
+ createWrapper();
+
+ expect(findLabelsSelect().props('labelsFetchPath')).toEqual(
+ `/${TEST_ISSUE_FULLPATH}/-/labels?include_ancestor_groups=true`,
+ );
+ });
+
it('renders "None" when no labels are selected', () => {
createWrapper();
@@ -78,7 +98,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
it('commits change to the server', () => {
expect(wrapper.vm.setActiveBoardItemLabels).toHaveBeenCalledWith({
addLabelIds: TEST_LABELS.map((label) => label.id),
- projectPath: 'gitlab-org/test-subgroup/gitlab-test',
+ projectPath: TEST_ISSUE_FULLPATH,
removeLabelIds: [],
});
});
@@ -103,7 +123,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
expect(wrapper.vm.setActiveBoardItemLabels).toHaveBeenCalledWith({
addLabelIds: [5, 7],
removeLabelIds: [6],
- projectPath: 'gitlab-org/test-subgroup/gitlab-test',
+ projectPath: TEST_ISSUE_FULLPATH,
});
});
});
@@ -122,7 +142,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
expect(wrapper.vm.setActiveBoardItemLabels).toHaveBeenCalledWith({
removeLabelIds: [getIdFromGraphQLId(testLabel.id)],
- projectPath: 'gitlab-org/test-subgroup/gitlab-test',
+ projectPath: TEST_ISSUE_FULLPATH,
});
});
});