diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/frontend/milestones | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/frontend/milestones')
-rw-r--r-- | spec/frontend/milestones/stores/actions_spec.js | 140 | ||||
-rw-r--r-- | spec/frontend/milestones/stores/getter_spec.js | 15 | ||||
-rw-r--r-- | spec/frontend/milestones/stores/mutations_spec.js | 159 |
3 files changed, 314 insertions, 0 deletions
diff --git a/spec/frontend/milestones/stores/actions_spec.js b/spec/frontend/milestones/stores/actions_spec.js new file mode 100644 index 00000000000..ad73d0e4238 --- /dev/null +++ b/spec/frontend/milestones/stores/actions_spec.js @@ -0,0 +1,140 @@ +import testAction from 'helpers/vuex_action_helper'; +import createState from '~/milestones/stores/state'; +import * as actions from '~/milestones/stores/actions'; +import * as types from '~/milestones/stores/mutation_types'; + +let mockProjectMilestonesReturnValue; +let mockProjectSearchReturnValue; + +jest.mock('~/api', () => ({ + // `__esModule: true` is required when mocking modules with default exports: + // https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options + __esModule: true, + default: { + projectMilestones: () => mockProjectMilestonesReturnValue, + projectSearch: () => mockProjectSearchReturnValue, + }, +})); + +describe('Milestone combobox Vuex store actions', () => { + let state; + + beforeEach(() => { + state = createState(); + }); + + describe('setProjectId', () => { + it(`commits ${types.SET_PROJECT_ID} with the new project ID`, () => { + const projectId = '4'; + testAction(actions.setProjectId, projectId, state, [ + { type: types.SET_PROJECT_ID, payload: projectId }, + ]); + }); + }); + + describe('setSelectedMilestones', () => { + it(`commits ${types.SET_SELECTED_MILESTONES} with the new selected milestones name`, () => { + const selectedMilestones = ['v1.2.3']; + testAction(actions.setSelectedMilestones, selectedMilestones, state, [ + { type: types.SET_SELECTED_MILESTONES, payload: selectedMilestones }, + ]); + }); + }); + + describe('toggleMilestones', () => { + const selectedMilestone = 'v1.2.3'; + it(`commits ${types.ADD_SELECTED_MILESTONE} with the new selected milestone name`, () => { + testAction(actions.toggleMilestones, selectedMilestone, state, [ + { type: types.ADD_SELECTED_MILESTONE, payload: selectedMilestone }, + ]); + }); + + it(`commits ${types.REMOVE_SELECTED_MILESTONE} with the new selected milestone name`, () => { + state.selectedMilestones = [selectedMilestone]; + testAction(actions.toggleMilestones, selectedMilestone, state, [ + { type: types.REMOVE_SELECTED_MILESTONE, payload: selectedMilestone }, + ]); + }); + }); + + describe('search', () => { + it(`commits ${types.SET_QUERY} with the new search query`, () => { + const query = 'v1.0'; + testAction( + actions.search, + query, + state, + [{ type: types.SET_QUERY, payload: query }], + [{ type: 'searchMilestones' }], + ); + }); + }); + + describe('searchMilestones', () => { + describe('when the search is successful', () => { + const projectSearchApiResponse = { data: [{ title: 'v1.0' }] }; + + beforeEach(() => { + mockProjectSearchReturnValue = Promise.resolve(projectSearchApiResponse); + }); + + it(`commits ${types.REQUEST_START}, ${types.RECEIVE_PROJECT_MILESTONES_SUCCESS} with the response from the API, and ${types.REQUEST_FINISH}`, () => { + return testAction(actions.searchMilestones, undefined, state, [ + { type: types.REQUEST_START }, + { type: types.RECEIVE_PROJECT_MILESTONES_SUCCESS, payload: projectSearchApiResponse }, + { type: types.REQUEST_FINISH }, + ]); + }); + }); + + describe('when the search fails', () => { + const error = new Error('Something went wrong!'); + + beforeEach(() => { + mockProjectSearchReturnValue = Promise.reject(error); + }); + + it(`commits ${types.REQUEST_START}, ${types.RECEIVE_PROJECT_MILESTONES_ERROR} with the error object, and ${types.REQUEST_FINISH}`, () => { + return testAction(actions.searchMilestones, undefined, state, [ + { type: types.REQUEST_START }, + { type: types.RECEIVE_PROJECT_MILESTONES_ERROR, payload: error }, + { type: types.REQUEST_FINISH }, + ]); + }); + }); + }); + + describe('fetchMilestones', () => { + describe('when the fetch is successful', () => { + const projectMilestonesApiResponse = { data: [{ title: 'v1.0' }] }; + + beforeEach(() => { + mockProjectMilestonesReturnValue = Promise.resolve(projectMilestonesApiResponse); + }); + + it(`commits ${types.REQUEST_START}, ${types.RECEIVE_PROJECT_MILESTONES_SUCCESS} with the response from the API, and ${types.REQUEST_FINISH}`, () => { + return testAction(actions.fetchMilestones, undefined, state, [ + { type: types.REQUEST_START }, + { type: types.RECEIVE_PROJECT_MILESTONES_SUCCESS, payload: projectMilestonesApiResponse }, + { type: types.REQUEST_FINISH }, + ]); + }); + }); + + describe('when the fetch fails', () => { + const error = new Error('Something went wrong!'); + + beforeEach(() => { + mockProjectMilestonesReturnValue = Promise.reject(error); + }); + + it(`commits ${types.REQUEST_START}, ${types.RECEIVE_PROJECT_MILESTONES_ERROR} with the error object, and ${types.REQUEST_FINISH}`, () => { + return testAction(actions.fetchMilestones, undefined, state, [ + { type: types.REQUEST_START }, + { type: types.RECEIVE_PROJECT_MILESTONES_ERROR, payload: error }, + { type: types.REQUEST_FINISH }, + ]); + }); + }); + }); +}); diff --git a/spec/frontend/milestones/stores/getter_spec.js b/spec/frontend/milestones/stores/getter_spec.js new file mode 100644 index 00000000000..df7c3d28e67 --- /dev/null +++ b/spec/frontend/milestones/stores/getter_spec.js @@ -0,0 +1,15 @@ +import * as getters from '~/milestones/stores/getters'; + +describe('Milestone comboxbox Vuex store getters', () => { + describe('isLoading', () => { + it.each` + requestCount | isLoading + ${2} | ${true} + ${1} | ${true} + ${0} | ${false} + ${-1} | ${false} + `('returns true when at least one request is in progress', ({ requestCount, isLoading }) => { + expect(getters.isLoading({ requestCount })).toBe(isLoading); + }); + }); +}); diff --git a/spec/frontend/milestones/stores/mutations_spec.js b/spec/frontend/milestones/stores/mutations_spec.js new file mode 100644 index 00000000000..8f8ce3c87ad --- /dev/null +++ b/spec/frontend/milestones/stores/mutations_spec.js @@ -0,0 +1,159 @@ +import createState from '~/milestones/stores/state'; +import mutations from '~/milestones/stores/mutations'; +import * as types from '~/milestones/stores/mutation_types'; + +describe('Milestones combobox Vuex store mutations', () => { + let state; + + beforeEach(() => { + state = createState(); + }); + + describe('initial state', () => { + it('is created with the correct structure and initial values', () => { + expect(state).toEqual({ + projectId: null, + groupId: null, + query: '', + matches: { + projectMilestones: { + list: [], + totalCount: 0, + error: null, + }, + }, + selectedMilestones: [], + requestCount: 0, + }); + }); + }); + + describe(`${types.SET_PROJECT_ID}`, () => { + it('updates the project ID', () => { + const newProjectId = '4'; + mutations[types.SET_PROJECT_ID](state, newProjectId); + + expect(state.projectId).toBe(newProjectId); + }); + }); + + describe(`${types.SET_SELECTED_MILESTONES}`, () => { + it('sets the selected milestones', () => { + const selectedMilestones = ['v1.2.3']; + mutations[types.SET_SELECTED_MILESTONES](state, selectedMilestones); + + expect(state.selectedMilestones).toEqual(['v1.2.3']); + }); + }); + + describe(`${types.ADD_SELECTED_MILESTONESs}`, () => { + it('adds the selected milestones', () => { + const selectedMilestone = 'v1.2.3'; + mutations[types.ADD_SELECTED_MILESTONE](state, selectedMilestone); + + expect(state.selectedMilestones).toEqual(['v1.2.3']); + }); + }); + + describe(`${types.REMOVE_SELECTED_MILESTONES}`, () => { + it('removes the selected milestones', () => { + const selectedMilestone = 'v1.2.3'; + + mutations[types.SET_SELECTED_MILESTONES](state, [selectedMilestone]); + expect(state.selectedMilestones).toEqual(['v1.2.3']); + + mutations[types.REMOVE_SELECTED_MILESTONE](state, selectedMilestone); + expect(state.selectedMilestones).toEqual([]); + }); + }); + + describe(`${types.SET_QUERY}`, () => { + it('updates the search query', () => { + const newQuery = 'hello'; + mutations[types.SET_QUERY](state, newQuery); + + expect(state.query).toBe(newQuery); + }); + }); + + describe(`${types.REQUEST_START}`, () => { + it('increments requestCount by 1', () => { + mutations[types.REQUEST_START](state); + expect(state.requestCount).toBe(1); + + mutations[types.REQUEST_START](state); + expect(state.requestCount).toBe(2); + + mutations[types.REQUEST_START](state); + expect(state.requestCount).toBe(3); + }); + }); + + describe(`${types.REQUEST_FINISH}`, () => { + it('decrements requestCount by 1', () => { + state.requestCount = 3; + + mutations[types.REQUEST_FINISH](state); + expect(state.requestCount).toBe(2); + + mutations[types.REQUEST_FINISH](state); + expect(state.requestCount).toBe(1); + + mutations[types.REQUEST_FINISH](state); + expect(state.requestCount).toBe(0); + }); + }); + + describe(`${types.RECEIVE_PROJECT_MILESTONES_SUCCESS}`, () => { + it('updates state.matches.projectMilestones based on the provided API response', () => { + const response = { + data: [ + { + title: 'v0.1', + }, + { + title: 'v0.2', + }, + ], + headers: { + 'x-total': 2, + }, + }; + + mutations[types.RECEIVE_PROJECT_MILESTONES_SUCCESS](state, response); + + expect(state.matches.projectMilestones).toEqual({ + list: [ + { + title: 'v0.1', + }, + { + title: 'v0.2', + }, + ], + error: null, + totalCount: 2, + }); + }); + + describe(`${types.RECEIVE_PROJECT_MILESTONES_ERROR}`, () => { + it('updates state.matches.projectMilestones to an empty state with the error object', () => { + const error = new Error('Something went wrong!'); + + state.matches.projectMilestones = { + list: [{ title: 'v0.1' }], + totalCount: 1, + error: null, + }; + + mutations[types.RECEIVE_PROJECT_MILESTONES_ERROR](state, error); + + expect(state.matches.projectMilestones).toEqual({ + list: [], + totalCount: 0, + error, + }); + }); + }); + }); +}); |