summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters')
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js448
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data.js50
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mutations_spec.js116
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper.js11
4 files changed, 625 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js
new file mode 100644
index 00000000000..1dd5f08e76a
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/actions_spec.js
@@ -0,0 +1,448 @@
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { mockBranches } from 'jest/vue_shared/components/filtered_search_bar/mock_data';
+import * as actions from '~/vue_shared/components/filtered_search_bar/store/modules/filters/actions';
+import * as types from '~/vue_shared/components/filtered_search_bar/store/modules/filters/mutation_types';
+import initialState from '~/vue_shared/components/filtered_search_bar/store/modules/filters/state';
+import httpStatusCodes from '~/lib/utils/http_status';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
+import Api from '~/api';
+import { filterMilestones, filterUsers, filterLabels } from './mock_data';
+
+const milestonesEndpoint = 'fake_milestones_endpoint';
+const labelsEndpoint = 'fake_labels_endpoint';
+const groupEndpoint = 'fake_group_endpoint';
+const projectEndpoint = 'fake_project_endpoint';
+
+jest.mock('~/flash');
+
+describe('Filters actions', () => {
+ let state;
+ let mock;
+ let mockDispatch;
+ let mockCommit;
+
+ beforeEach(() => {
+ state = initialState();
+ mock = new MockAdapter(axios);
+
+ mockDispatch = jest.fn().mockResolvedValue();
+ mockCommit = jest.fn();
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('initialize', () => {
+ const initialData = {
+ milestonesEndpoint,
+ labelsEndpoint,
+ groupEndpoint,
+ projectEndpoint,
+ selectedAuthor: 'Mr cool',
+ selectedMilestone: 'NEXT',
+ };
+
+ it('does not dispatch', () => {
+ const result = actions.initialize(
+ {
+ state,
+ dispatch: mockDispatch,
+ commit: mockCommit,
+ },
+ initialData,
+ );
+ expect(result).toBeUndefined();
+ expect(mockDispatch).not.toHaveBeenCalled();
+ });
+
+ it(`commits the ${types.SET_SELECTED_FILTERS}`, () => {
+ actions.initialize(
+ {
+ state,
+ dispatch: mockDispatch,
+ commit: mockCommit,
+ },
+ initialData,
+ );
+ expect(mockCommit).toHaveBeenCalledWith(types.SET_SELECTED_FILTERS, initialData);
+ });
+ });
+
+ describe('setFilters', () => {
+ const nextFilters = {
+ selectedAuthor: 'Mr cool',
+ selectedMilestone: 'NEXT',
+ };
+
+ it('dispatches the root/setFilters action', () => {
+ return testAction(
+ actions.setFilters,
+ nextFilters,
+ state,
+ [
+ {
+ payload: nextFilters,
+ type: types.SET_SELECTED_FILTERS,
+ },
+ ],
+ [
+ {
+ type: 'setFilters',
+ payload: nextFilters,
+ },
+ ],
+ );
+ });
+ });
+
+ describe('setEndpoints', () => {
+ it('sets the api paths', () => {
+ return testAction(
+ actions.setEndpoints,
+ { milestonesEndpoint, labelsEndpoint, groupEndpoint, projectEndpoint },
+ state,
+ [
+ { payload: 'fake_milestones_endpoint', type: types.SET_MILESTONES_ENDPOINT },
+ { payload: 'fake_labels_endpoint', type: types.SET_LABELS_ENDPOINT },
+ { payload: 'fake_group_endpoint', type: types.SET_GROUP_ENDPOINT },
+ { payload: 'fake_project_endpoint', type: types.SET_PROJECT_ENDPOINT },
+ ],
+ [],
+ );
+ });
+ });
+
+ describe('fetchBranches', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ const url = Api.buildUrl(Api.createBranchPath).replace(
+ ':id',
+ encodeURIComponent(projectEndpoint),
+ );
+ mock.onGet(url).replyOnce(httpStatusCodes.OK, mockBranches);
+ });
+
+ it('dispatches RECEIVE_BRANCHES_SUCCESS with received data', () => {
+ return testAction(
+ actions.fetchBranches,
+ null,
+ { ...state, projectEndpoint },
+ [
+ { type: types.REQUEST_BRANCHES },
+ { type: types.RECEIVE_BRANCHES_SUCCESS, payload: mockBranches },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(data).toBe(mockBranches);
+ });
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.SERVICE_UNAVAILABLE);
+ });
+
+ it('dispatches RECEIVE_BRANCHES_ERROR', () => {
+ return testAction(
+ actions.fetchBranches,
+ null,
+ state,
+ [
+ { type: types.REQUEST_BRANCHES },
+ {
+ type: types.RECEIVE_BRANCHES_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => expect(createFlash).toHaveBeenCalled());
+ });
+ });
+ });
+
+ describe('fetchAuthors', () => {
+ let restoreVersion;
+ beforeEach(() => {
+ restoreVersion = gon.api_version;
+ gon.api_version = 'v1';
+ });
+
+ afterEach(() => {
+ gon.api_version = restoreVersion;
+ });
+
+ describe('success', () => {
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.OK, filterUsers);
+ });
+
+ it('dispatches RECEIVE_AUTHORS_SUCCESS with received data and groupEndpoint set', () => {
+ return testAction(
+ actions.fetchAuthors,
+ null,
+ { ...state, groupEndpoint },
+ [
+ { type: types.REQUEST_AUTHORS },
+ { type: types.RECEIVE_AUTHORS_SUCCESS, payload: filterUsers },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(mock.history.get[0].url).toBe('/api/v1/groups/fake_group_endpoint/members');
+ expect(data).toBe(filterUsers);
+ });
+ });
+
+ it('dispatches RECEIVE_AUTHORS_SUCCESS with received data and projectEndpoint set', () => {
+ return testAction(
+ actions.fetchAuthors,
+ null,
+ { ...state, projectEndpoint },
+ [
+ { type: types.REQUEST_AUTHORS },
+ { type: types.RECEIVE_AUTHORS_SUCCESS, payload: filterUsers },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(mock.history.get[0].url).toBe('/api/v1/projects/fake_project_endpoint/users');
+ expect(data).toBe(filterUsers);
+ });
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.SERVICE_UNAVAILABLE);
+ });
+
+ it('dispatches RECEIVE_AUTHORS_ERROR and groupEndpoint set', () => {
+ return testAction(
+ actions.fetchAuthors,
+ null,
+ { ...state, groupEndpoint },
+ [
+ { type: types.REQUEST_AUTHORS },
+ {
+ type: types.RECEIVE_AUTHORS_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => {
+ expect(mock.history.get[0].url).toBe('/api/v1/groups/fake_group_endpoint/members');
+ expect(createFlash).toHaveBeenCalled();
+ });
+ });
+
+ it('dispatches RECEIVE_AUTHORS_ERROR and projectEndpoint set', () => {
+ return testAction(
+ actions.fetchAuthors,
+ null,
+ { ...state, projectEndpoint },
+ [
+ { type: types.REQUEST_AUTHORS },
+ {
+ type: types.RECEIVE_AUTHORS_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => {
+ expect(mock.history.get[0].url).toBe('/api/v1/projects/fake_project_endpoint/users');
+ expect(createFlash).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+
+ describe('fetchMilestones', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ mock.onGet(milestonesEndpoint).replyOnce(httpStatusCodes.OK, filterMilestones);
+ });
+
+ it('dispatches RECEIVE_MILESTONES_SUCCESS with received data', () => {
+ return testAction(
+ actions.fetchMilestones,
+ null,
+ { ...state, milestonesEndpoint },
+ [
+ { type: types.REQUEST_MILESTONES },
+ { type: types.RECEIVE_MILESTONES_SUCCESS, payload: filterMilestones },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(data).toBe(filterMilestones);
+ });
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.SERVICE_UNAVAILABLE);
+ });
+
+ it('dispatches RECEIVE_MILESTONES_ERROR', () => {
+ return testAction(
+ actions.fetchMilestones,
+ null,
+ state,
+ [
+ { type: types.REQUEST_MILESTONES },
+ {
+ type: types.RECEIVE_MILESTONES_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => expect(createFlash).toHaveBeenCalled());
+ });
+ });
+ });
+
+ describe('fetchAssignees', () => {
+ describe('success', () => {
+ let restoreVersion;
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.OK, filterUsers);
+ restoreVersion = gon.api_version;
+ gon.api_version = 'v1';
+ });
+
+ afterEach(() => {
+ gon.api_version = restoreVersion;
+ });
+
+ it('dispatches RECEIVE_ASSIGNEES_SUCCESS with received data and groupEndpoint set', () => {
+ return testAction(
+ actions.fetchAssignees,
+ null,
+ { ...state, milestonesEndpoint, groupEndpoint },
+ [
+ { type: types.REQUEST_ASSIGNEES },
+ { type: types.RECEIVE_ASSIGNEES_SUCCESS, payload: filterUsers },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(mock.history.get[0].url).toBe('/api/v1/groups/fake_group_endpoint/members');
+ expect(data).toBe(filterUsers);
+ });
+ });
+
+ it('dispatches RECEIVE_ASSIGNEES_SUCCESS with received data and projectEndpoint set', () => {
+ return testAction(
+ actions.fetchAssignees,
+ null,
+ { ...state, milestonesEndpoint, projectEndpoint },
+ [
+ { type: types.REQUEST_ASSIGNEES },
+ { type: types.RECEIVE_ASSIGNEES_SUCCESS, payload: filterUsers },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(mock.history.get[0].url).toBe('/api/v1/projects/fake_project_endpoint/users');
+ expect(data).toBe(filterUsers);
+ });
+ });
+ });
+
+ describe('error', () => {
+ let restoreVersion;
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.SERVICE_UNAVAILABLE);
+ restoreVersion = gon.api_version;
+ gon.api_version = 'v1';
+ });
+
+ afterEach(() => {
+ gon.api_version = restoreVersion;
+ });
+
+ it('dispatches RECEIVE_ASSIGNEES_ERROR and groupEndpoint set', () => {
+ return testAction(
+ actions.fetchAssignees,
+ null,
+ { ...state, groupEndpoint },
+ [
+ { type: types.REQUEST_ASSIGNEES },
+ {
+ type: types.RECEIVE_ASSIGNEES_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => {
+ expect(mock.history.get[0].url).toBe('/api/v1/groups/fake_group_endpoint/members');
+ expect(createFlash).toHaveBeenCalled();
+ });
+ });
+
+ it('dispatches RECEIVE_ASSIGNEES_ERROR and projectEndpoint set', () => {
+ return testAction(
+ actions.fetchAssignees,
+ null,
+ { ...state, projectEndpoint },
+ [
+ { type: types.REQUEST_ASSIGNEES },
+ {
+ type: types.RECEIVE_ASSIGNEES_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => {
+ expect(mock.history.get[0].url).toBe('/api/v1/projects/fake_project_endpoint/users');
+ expect(createFlash).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+
+ describe('fetchLabels', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ mock.onGet(labelsEndpoint).replyOnce(httpStatusCodes.OK, filterLabels);
+ });
+
+ it('dispatches RECEIVE_LABELS_SUCCESS with received data', () => {
+ return testAction(
+ actions.fetchLabels,
+ null,
+ { ...state, labelsEndpoint },
+ [
+ { type: types.REQUEST_LABELS },
+ { type: types.RECEIVE_LABELS_SUCCESS, payload: filterLabels },
+ ],
+ [],
+ ).then(({ data }) => {
+ expect(data).toBe(filterLabels);
+ });
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onAny().replyOnce(httpStatusCodes.SERVICE_UNAVAILABLE);
+ });
+
+ it('dispatches RECEIVE_LABELS_ERROR', () => {
+ return testAction(
+ actions.fetchLabels,
+ null,
+ state,
+ [
+ { type: types.REQUEST_LABELS },
+ {
+ type: types.RECEIVE_LABELS_ERROR,
+ payload: httpStatusCodes.SERVICE_UNAVAILABLE,
+ },
+ ],
+ [],
+ ).then(() => expect(createFlash).toHaveBeenCalled());
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data.js
new file mode 100644
index 00000000000..6afac9f752a
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mock_data.js
@@ -0,0 +1,50 @@
+export const filterMilestones = [
+ { id: 1, title: 'None', name: 'Any' },
+ { id: 101, title: 'Any', name: 'None' },
+ { id: 1001, title: 'v1.0', name: 'v1.0' },
+ { id: 10101, title: 'v0.0', name: 'v0.0' },
+];
+
+export const filterUsers = [
+ {
+ id: 31,
+ name: 'VSM User2',
+ username: 'vsm-user-2-1589776313',
+ state: 'active',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/762398957a8c6e04eed16da88098899d?s=80\u0026d=identicon',
+ web_url: 'http://127.0.0.1:3001/vsm-user-2-1589776313',
+ access_level: 30,
+ expires_at: null,
+ },
+ {
+ id: 32,
+ name: 'VSM User3',
+ username: 'vsm-user-3-1589776313',
+ state: 'active',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/f78932237e8a5c5376b65a709824802f?s=80\u0026d=identicon',
+ web_url: 'http://127.0.0.1:3001/vsm-user-3-1589776313',
+ access_level: 30,
+ expires_at: null,
+ },
+ {
+ id: 33,
+ name: 'VSM User4',
+ username: 'vsm-user-4-1589776313',
+ state: 'active',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/ab506dc600d1a941e4d77d5ceeeba73f?s=80\u0026d=identicon',
+ web_url: 'http://127.0.0.1:3001/vsm-user-4-1589776313',
+ access_level: 30,
+ expires_at: null,
+ },
+];
+
+export const filterLabels = [
+ { id: 194, title: 'Afterfunc-Phureforge-781', color: '#990000', text_color: '#FFFFFF' },
+ { id: 10, title: 'Afternix', color: '#16ecf2', text_color: '#FFFFFF' },
+ { id: 176, title: 'Panasync-Pens-266', color: '#990000', text_color: '#FFFFFF' },
+ { id: 79, title: 'Passat', color: '#f1a3d4', text_color: '#333333' },
+ { id: 197, title: 'Phast-Onesync-395', color: '#990000', text_color: '#FFFFFF' },
+];
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mutations_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mutations_spec.js
new file mode 100644
index 00000000000..263a4ee178f
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/mutations_spec.js
@@ -0,0 +1,116 @@
+import { get } from 'lodash';
+import { mockBranches } from 'jest/vue_shared/components/filtered_search_bar/mock_data';
+import initialState from '~/vue_shared/components/filtered_search_bar/store/modules/filters/state';
+import mutations from '~/vue_shared/components/filtered_search_bar/store/modules/filters/mutations';
+import * as types from '~/vue_shared/components/filtered_search_bar/store/modules/filters/mutation_types';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { filterMilestones, filterUsers, filterLabels } from './mock_data';
+
+let state = null;
+
+const branches = mockBranches.map(convertObjectPropsToCamelCase);
+const milestones = filterMilestones.map(convertObjectPropsToCamelCase);
+const users = filterUsers.map(convertObjectPropsToCamelCase);
+const labels = filterLabels.map(convertObjectPropsToCamelCase);
+
+const filterValue = { value: 'foo' };
+
+describe('Filters mutations', () => {
+ const errorCode = 500;
+ beforeEach(() => {
+ state = initialState();
+ });
+
+ afterEach(() => {
+ state = null;
+ });
+
+ it.each`
+ mutation | stateKey | value
+ ${types.SET_MILESTONES_ENDPOINT} | ${'milestonesEndpoint'} | ${'new-milestone-endpoint'}
+ ${types.SET_LABELS_ENDPOINT} | ${'labelsEndpoint'} | ${'new-label-endpoint'}
+ ${types.SET_GROUP_ENDPOINT} | ${'groupEndpoint'} | ${'new-group-endpoint'}
+ `('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => {
+ mutations[mutation](state, value);
+
+ expect(state[stateKey]).toEqual(value);
+ });
+
+ it.each`
+ mutation | stateKey | filterName | value
+ ${types.SET_SELECTED_FILTERS} | ${'branches.source.selected'} | ${'selectedSourceBranch'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.source.selected'} | ${'selectedSourceBranch'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.source.selectedList'} | ${'selectedSourceBranchList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.source.selectedList'} | ${'selectedSourceBranchList'} | ${[filterValue]}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.target.selected'} | ${'selectedTargetBranch'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.target.selected'} | ${'selectedTargetBranch'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.target.selectedList'} | ${'selectedTargetBranchList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'branches.target.selectedList'} | ${'selectedTargetBranchList'} | ${[filterValue]}
+ ${types.SET_SELECTED_FILTERS} | ${'authors.selected'} | ${'selectedAuthor'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'authors.selected'} | ${'selectedAuthor'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'authors.selectedList'} | ${'selectedAuthorList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'authors.selectedList'} | ${'selectedAuthorList'} | ${[filterValue]}
+ ${types.SET_SELECTED_FILTERS} | ${'milestones.selected'} | ${'selectedMilestone'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'milestones.selected'} | ${'selectedMilestone'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'milestones.selectedList'} | ${'selectedMilestoneList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'milestones.selectedList'} | ${'selectedMilestoneList'} | ${[filterValue]}
+ ${types.SET_SELECTED_FILTERS} | ${'assignees.selected'} | ${'selectedAssignee'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'assignees.selected'} | ${'selectedAssignee'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'assignees.selectedList'} | ${'selectedAssigneeList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'assignees.selectedList'} | ${'selectedAssigneeList'} | ${[filterValue]}
+ ${types.SET_SELECTED_FILTERS} | ${'labels.selected'} | ${'selectedLabel'} | ${null}
+ ${types.SET_SELECTED_FILTERS} | ${'labels.selected'} | ${'selectedLabel'} | ${filterValue}
+ ${types.SET_SELECTED_FILTERS} | ${'labels.selectedList'} | ${'selectedLabelList'} | ${[]}
+ ${types.SET_SELECTED_FILTERS} | ${'labels.selectedList'} | ${'selectedLabelList'} | ${[filterValue]}
+ `(
+ '$mutation will set $stateKey with a given value',
+ ({ mutation, stateKey, filterName, value }) => {
+ mutations[mutation](state, { [filterName]: value });
+
+ expect(get(state, stateKey)).toEqual(value);
+ },
+ );
+
+ it.each`
+ mutation | rootKey | stateKey | value
+ ${types.REQUEST_BRANCHES} | ${'branches'} | ${'isLoading'} | ${true}
+ ${types.RECEIVE_BRANCHES_SUCCESS} | ${'branches'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_BRANCHES_SUCCESS} | ${'branches'} | ${'data'} | ${branches}
+ ${types.RECEIVE_BRANCHES_SUCCESS} | ${'branches'} | ${'errorCode'} | ${null}
+ ${types.RECEIVE_BRANCHES_ERROR} | ${'branches'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_BRANCHES_ERROR} | ${'branches'} | ${'data'} | ${[]}
+ ${types.RECEIVE_BRANCHES_ERROR} | ${'branches'} | ${'errorCode'} | ${errorCode}
+ ${types.REQUEST_MILESTONES} | ${'milestones'} | ${'isLoading'} | ${true}
+ ${types.RECEIVE_MILESTONES_SUCCESS} | ${'milestones'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_MILESTONES_SUCCESS} | ${'milestones'} | ${'data'} | ${milestones}
+ ${types.RECEIVE_MILESTONES_SUCCESS} | ${'milestones'} | ${'errorCode'} | ${null}
+ ${types.RECEIVE_MILESTONES_ERROR} | ${'milestones'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_MILESTONES_ERROR} | ${'milestones'} | ${'data'} | ${[]}
+ ${types.RECEIVE_MILESTONES_ERROR} | ${'milestones'} | ${'errorCode'} | ${errorCode}
+ ${types.REQUEST_AUTHORS} | ${'authors'} | ${'isLoading'} | ${true}
+ ${types.RECEIVE_AUTHORS_SUCCESS} | ${'authors'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_AUTHORS_SUCCESS} | ${'authors'} | ${'data'} | ${users}
+ ${types.RECEIVE_AUTHORS_SUCCESS} | ${'authors'} | ${'errorCode'} | ${null}
+ ${types.RECEIVE_AUTHORS_ERROR} | ${'authors'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_AUTHORS_ERROR} | ${'authors'} | ${'data'} | ${[]}
+ ${types.RECEIVE_AUTHORS_ERROR} | ${'authors'} | ${'errorCode'} | ${errorCode}
+ ${types.REQUEST_LABELS} | ${'labels'} | ${'isLoading'} | ${true}
+ ${types.RECEIVE_LABELS_SUCCESS} | ${'labels'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_LABELS_SUCCESS} | ${'labels'} | ${'data'} | ${labels}
+ ${types.RECEIVE_LABELS_SUCCESS} | ${'labels'} | ${'errorCode'} | ${null}
+ ${types.RECEIVE_LABELS_ERROR} | ${'labels'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_LABELS_ERROR} | ${'labels'} | ${'data'} | ${[]}
+ ${types.RECEIVE_LABELS_ERROR} | ${'labels'} | ${'errorCode'} | ${errorCode}
+ ${types.REQUEST_ASSIGNEES} | ${'assignees'} | ${'isLoading'} | ${true}
+ ${types.RECEIVE_ASSIGNEES_SUCCESS} | ${'assignees'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_ASSIGNEES_SUCCESS} | ${'assignees'} | ${'data'} | ${users}
+ ${types.RECEIVE_ASSIGNEES_SUCCESS} | ${'assignees'} | ${'errorCode'} | ${null}
+ ${types.RECEIVE_ASSIGNEES_ERROR} | ${'assignees'} | ${'isLoading'} | ${false}
+ ${types.RECEIVE_ASSIGNEES_ERROR} | ${'assignees'} | ${'data'} | ${[]}
+ ${types.RECEIVE_ASSIGNEES_ERROR} | ${'assignees'} | ${'errorCode'} | ${errorCode}
+ `('$mutation will set $stateKey with a given value', ({ mutation, rootKey, stateKey, value }) => {
+ mutations[mutation](state, value);
+
+ expect(state[rootKey][stateKey]).toEqual(value);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper.js b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper.js
new file mode 100644
index 00000000000..1b7c80a5252
--- /dev/null
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/store/modules/filters/test_helper.js
@@ -0,0 +1,11 @@
+export function getFilterParams(tokens, options = {}) {
+ const { key = 'value', operator = '=', prop = 'title' } = options;
+ return tokens.map(token => {
+ return { [key]: token[prop], operator };
+ });
+}
+
+export function getFilterValues(tokens, options = {}) {
+ const { prop = 'title' } = options;
+ return tokens.map(token => token[prop]);
+}