Commit 5a43aa01 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Updating existing cycle analytics store specs

Updating action specs with the changes
for the new vuex module

Update existing mutation specs
parent 43c7b116
......@@ -42,14 +42,20 @@ export const receiveStageDataError = ({ commit }) => {
createFlash(__('There was an error fetching data for the selected stage'));
};
export const fetchStageData = ({ state, dispatch, getters }, slug) => {
export const fetchStageData = ({ state, dispatch, getters }) => {
const { cycleAnalyticsRequestParams = {} } = getters;
const {
selectedGroup: { fullPath },
stages,
} = state;
dispatch('requestStageData');
const [firstStage] = stages;
const { slug } = firstStage;
dispatch('setSelectedStage', firstStage);
return Api.cycleAnalyticsStageEvents(fullPath, slug, cycleAnalyticsRequestParams)
.then(({ data }) => dispatch('receiveStageDataSuccess', data))
.catch(error => dispatch('receiveStageDataError', error));
......@@ -103,9 +109,8 @@ export const receiveCycleAnalyticsDataSuccess = ({ commit, dispatch }) => {
dispatch('typeOfWork/fetchTopRankedGroupLabels');
};
export const receiveCycleAnalyticsDataError = ({ commit }, error) => {
console.log('error', error);
const { status = null } = error; // non api errors thrown wont have a status field
export const receiveCycleAnalyticsDataError = ({ commit }, { response }) => {
const { status = null } = response; // non api errors thrown wont have a status field
commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR, status);
if (!status || status !== httpStatus.FORBIDDEN)
......@@ -133,9 +138,10 @@ export const receiveGroupStagesError = ({ commit }, error) => {
export const receiveGroupStagesSuccess = ({ commit, dispatch }, stages) => {
commit(types.RECEIVE_GROUP_STAGES_SUCCESS, stages);
if (stages.length) {
const [firstStage] = stages;
dispatch('setSelectedStage', firstStage);
dispatch('fetchStageData', firstStage.slug);
// console.log('receiveGroupStagesSuccess::stages', stages);
// const [firstStage] = stages;
// dispatch('setSelectedStage', firstStage);
dispatch('fetchStageData');
} else {
createFlash(__('There was an error while fetching value stream analytics data.'));
}
......@@ -182,7 +188,7 @@ export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) =>
};
export const receiveUpdateStageError = (
{ commit },
{ commit, dispatch },
{ status, responseData: { errors = null } = {}, data = {} },
) => {
commit(types.RECEIVE_UPDATE_STAGE_ERROR, { errors, data });
......@@ -193,6 +199,7 @@ export const receiveUpdateStageError = (
? sprintf(__(`'%{name}' stage already exists`), { name })
: __('There was a problem saving your custom stage, please try again');
dispatch('customStages/setStageFormErrors', errors);
createFlash(__(message));
};
......
......@@ -14,6 +14,8 @@ const isStageNameExistsError = ({ status, errors }) => {
};
export const setStageEvents = ({ commit }, data) => commit(types.SET_STAGE_EVENTS, data);
export const setStageFormErrors = ({ commit }, errors) =>
commit(types.SET_STAGE_FORM_ERRORS, errors);
export const hideForm = ({ commit }) => {
commit(types.HIDE_FORM);
......@@ -59,22 +61,24 @@ export const receiveCreateStageSuccess = ({ commit, dispatch }, { data: { title
return Promise.resolve()
.then(() => dispatch('fetchGroupStagesAndEvents'))
.catch(() => {
.catch(err => {
console.log('err', err);
createFlash(__('There was a problem refreshing the data, please try again'));
});
};
export const receiveCreateStageError = (
{ commit },
{ commit, dispatch },
{ status = 400, errors = {}, data = {} } = {},
) => {
commit(types.RECEIVE_CREATE_STAGE_ERROR, { errors });
commit(types.RECEIVE_CREATE_STAGE_ERROR);
const { name = null } = data;
const flashMessage =
name && isStageNameExistsError({ status, errors })
? sprintf(__(`'%{name}' stage already exists`), { name })
: __('There was a problem saving your custom stage, please try again');
dispatch('setStageFormErrors', errors);
createFlash(flashMessage);
};
......
export const SET_STAGE_EVENTS = 'SET_STAGE_EVENTS';
export const SET_STAGE_FORM_ERRORS = 'SET_STAGE_FORM_ERRORS';
export const HIDE_FORM = 'SHOW_FORM';
export const SHOW_CREATE_FORM = 'SHOW_CREATE_FORM';
......
......@@ -5,17 +5,24 @@ export default {
[types.SET_STAGE_EVENTS](state, data = []) {
state.formEvents = data.map(ev => convertObjectPropsToCamelCase(ev, { deep: true }));
},
[types.SET_STAGE_FORM_ERRORS](state, errors) {
state.isSavingCustomStage = false;
state.formErrors = convertObjectPropsToCamelCase(errors, { deep: true });
},
[types.SHOW_CREATE_FORM](state) {
state.isEditingCustomStage = false;
state.isCreatingCustomStage = true;
state.formInitialData = null;
state.formErrors = null;
},
[types.SHOW_EDIT_FORM](state, initialData) {
state.isCreatingCustomStage = false;
state.isEditingCustomStage = true;
state.formInitialData = initialData;
state.formErrors = null;
},
[types.HIDE_FORM](state) {
state.isSavingCustomStage = false;
state.isEditingCustomStage = false;
state.isCreatingCustomStage = false;
state.formInitialData = null;
......@@ -28,9 +35,8 @@ export default {
state.isSavingCustomStage = true;
state.formErrors = {};
},
[types.RECEIVE_CREATE_STAGE_ERROR](state, { errors = null } = {}) {
[types.RECEIVE_CREATE_STAGE_ERROR](state) {
state.isSavingCustomStage = false;
state.formErrors = convertObjectPropsToCamelCase(errors, { deep: true });
},
[types.RECEIVE_CREATE_STAGE_SUCCESS](state) {
state.isSavingCustomStage = false;
......
......@@ -22,8 +22,6 @@ export default {
},
[types.REQUEST_CYCLE_ANALYTICS_DATA](state) {
state.isLoading = true;
state.isCreatingCustomStage = false;
state.isEditingCustomStage = false;
},
[types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS](state) {
state.errorCode = null;
......@@ -74,21 +72,12 @@ export default {
},
[types.REQUEST_UPDATE_STAGE](state) {
state.isLoading = true;
state.isSavingCustomStage = true;
state.customStageFormErrors = null;
},
[types.RECEIVE_UPDATE_STAGE_SUCCESS](state) {
state.isLoading = false;
state.isSavingCustomStage = false;
state.isEditingCustomStage = false;
state.customStageFormErrors = null;
state.customStageFormInitialData = null;
},
[types.RECEIVE_UPDATE_STAGE_ERROR](state, { errors = null, data } = {}) {
[types.RECEIVE_UPDATE_STAGE_ERROR](state) {
state.isLoading = false;
state.isSavingCustomStage = false;
state.customStageFormErrors = convertObjectPropsToCamelCase(errors, { deep: true });
state.customStageFormInitialData = convertObjectPropsToCamelCase(data, { deep: true });
},
[types.REQUEST_REMOVE_STAGE](state) {
state.isLoading = true;
......
......@@ -85,8 +85,8 @@ function createComponent({
...selectedGroup,
});
comp.vm.$store.dispatch('receiveGroupStagesAndEventsSuccess', {
...mockData.customizableStagesAndEvents,
comp.vm.$store.dispatch('receiveGroupStagesSuccess', {
...mockData.customizableStagesAndEvents.stages,
});
comp.vm.$store.dispatch('receiveStageDataSuccess', mockData.issueEvents);
......
......@@ -60,7 +60,7 @@ export const customizableStagesAndEvents = getJSONFixture(
const dummyState = {};
// prepare the raw stage data for our components
mutations[types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS](dummyState, customizableStagesAndEvents);
mutations[types.RECEIVE_GROUP_STAGES_SUCCESS](dummyState, customizableStagesAndEvents.stages);
export const issueStage = getStageByTitle(dummyState.stages, 'issue');
export const planStage = getStageByTitle(dummyState.stages, 'plan');
......
......@@ -4,6 +4,8 @@ import testAction from 'helpers/vuex_action_helper';
import * as getters from 'ee/analytics/cycle_analytics/store/getters';
import * as actions from 'ee/analytics/cycle_analytics/store/actions';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import * as customStageActions from 'ee/analytics/cycle_analytics/store/modules/custom_stages/actions';
import * as customStageTypes from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types';
import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
import {
......@@ -250,7 +252,7 @@ describe('Cycle analytics actions', () => {
dispatch: jest
.fn()
.mockResolvedValueOnce()
.mockImplementation(actions.receiveGroupStagesAndEventsError({ commit: () => {} })),
.mockImplementation(actions.receiveGroupStagesError({ commit: () => {} })),
commit: () => {},
state: { ...state },
getters,
......@@ -299,10 +301,10 @@ describe('Cycle analytics actions', () => {
it('will flash an error when there are no stages', () => {
[[], null].forEach(emptyStages => {
actions.receiveGroupStagesAndEventsSuccess(
actions.receiveGroupStagesSuccess(
{
commit: () => {},
state: { stages: emptyStages },
state: emptyStages,
getters,
},
{},
......@@ -365,20 +367,20 @@ describe('Cycle analytics actions', () => {
});
});
describe('receiveGroupStagesAndEventsSuccess', () => {
describe('receiveGroupStagesSuccess', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it(`commits the ${types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS} mutation`, done => {
it(`commits the ${types.RECEIVE_GROUP_STAGES_SUCCESS} mutation`, done => {
testAction(
actions.receiveGroupStagesAndEventsSuccess,
{ ...customizableStagesAndEvents },
actions.receiveGroupStagesSuccess,
{ ...customizableStagesAndEvents.stages },
state,
[
{
type: types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS,
payload: { ...customizableStagesAndEvents },
type: types.RECEIVE_GROUP_STAGES_SUCCESS,
payload: { ...customizableStagesAndEvents.stages },
},
],
[],
......@@ -387,19 +389,14 @@ describe('Cycle analytics actions', () => {
});
it("dispatches the 'fetchStageData' action", done => {
const stateWithStages = {
...state,
stages,
};
testAction(
actions.receiveGroupStagesAndEventsSuccess,
{ ...customizableStagesAndEvents },
stateWithStages,
actions.receiveGroupStagesSuccess,
stages,
{},
[
{
type: types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS,
payload: { ...customizableStagesAndEvents },
type: types.RECEIVE_GROUP_STAGES_SUCCESS,
payload: stages,
},
],
[
......@@ -412,10 +409,10 @@ describe('Cycle analytics actions', () => {
it('will flash an error when there are no stages', () => {
[[], null].forEach(emptyStages => {
actions.receiveGroupStagesAndEventsSuccess(
actions.receiveGroupStagesSuccess(
{
commit: () => {},
state: { stages: emptyStages },
state: emptyStages,
},
{},
);
......@@ -759,7 +756,7 @@ describe('Cycle analytics actions', () => {
});
});
describe('createCustomStage', () => {
describe('createStage', () => {
describe('with valid data', () => {
const customStageData = {
startEventIdentifier: 'start_event',
......@@ -772,16 +769,16 @@ describe('Cycle analytics actions', () => {
mock.onPost(endpoints.baseStagesEndpointstageData).reply(201, customStageData);
});
it(`dispatches the 'receiveCreateCustomStageSuccess' action`, () =>
it(`dispatches the 'receiveCreateStageSuccess' action`, () =>
testAction(
actions.createCustomStage,
customStageActions.createStage,
customStageData,
state,
[],
[
{ type: 'requestCreateCustomStage' },
{ type: 'requestCreateStage' },
{
type: 'receiveCreateCustomStageSuccess',
type: 'receiveCreateStageSuccess',
payload: { data: customStageData, status: 201 },
},
],
......@@ -809,16 +806,16 @@ describe('Cycle analytics actions', () => {
});
});
it(`dispatches the 'receiveCreateCustomStageError' action`, () =>
it(`dispatches the 'receiveCreateStageError' action`, () =>
testAction(
actions.createCustomStage,
customStageActions.createStage,
customStageData,
state,
[],
[
{ type: 'requestCreateCustomStage' },
{ type: 'requestCreateStage' },
{
type: 'receiveCreateCustomStageError',
type: 'receiveCreateStageError',
payload: {
data: customStageData,
errors,
......@@ -831,7 +828,7 @@ describe('Cycle analytics actions', () => {
});
});
describe('receiveCreateCustomStageError', () => {
describe('receiveCreateStageError', () => {
const response = {
data: { name: 'uh oh' },
};
......@@ -840,13 +837,13 @@ describe('Cycle analytics actions', () => {
setFixtures('<div class="flash-container"></div>');
});
it('will commit the RECEIVE_CREATE_CUSTOM_STAGE_ERROR mutation', () =>
testAction(actions.receiveCreateCustomStageError, response, state, [
{ type: types.RECEIVE_CREATE_CUSTOM_STAGE_ERROR, payload: { errors: {} } },
it('will commit the RECEIVE_CREATE_STAGE_ERROR mutation', () =>
testAction(customStageActions.receiveCreateStageError, response, state, [
{ type: customStageTypes.RECEIVE_CREATE_STAGE_ERROR, payload: { errors: {} } },
]));
it('will flash an error message', done => {
actions.receiveCreateCustomStageError(
customStageActions.receiveCreateStageError(
{
commit: () => {},
},
......@@ -859,7 +856,7 @@ describe('Cycle analytics actions', () => {
describe('with a stage name error', () => {
it('will flash an error message', done => {
actions.receiveCreateCustomStageError(
customStageActions.receiveCreateStageError(
{
commit: () => {},
},
......@@ -935,7 +932,7 @@ describe('Cycle analytics actions', () => {
));
});
describe('receiveCreateCustomStageSuccess', () => {
describe('receiveCreateStageSuccess', () => {
const response = {
data: {
title: 'COOL',
......@@ -944,10 +941,10 @@ describe('Cycle analytics actions', () => {
it('will dispatch fetchGroupStagesAndEvents', () =>
testAction(
actions.receiveCreateCustomStageSuccess,
customStageActions.receiveCreateStageSuccess,
response,
state,
[{ type: types.RECEIVE_CREATE_CUSTOM_STAGE_SUCCESS }],
[{ type: customStageTypes.RECEIVE_CREATE_STAGE_SUCCESS }],
[{ type: 'fetchGroupStagesAndEvents' }],
));
......@@ -957,8 +954,8 @@ describe('Cycle analytics actions', () => {
});
it('will flash an error message', () =>
actions
.receiveCreateCustomStageSuccess(
customStageActions
.receiveCreateStageSuccess(
{
dispatch: () => Promise.reject(),
commit: () => {},
......
import mutations from 'ee/analytics/cycle_analytics/store/mutations';
import * as types from 'ee/analytics/cycle_analytics/store/mutation_types';
import customStageMutations from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutations';
import * as customStageTypes from 'ee/analytics/cycle_analytics/store/modules/custom_stages/mutation_types';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import {
......@@ -30,37 +32,15 @@ describe('Cycle analytics mutations', () => {
it.each`
mutation | stateKey | value
${types.HIDE_CUSTOM_STAGE_FORM} | ${'isCreatingCustomStage'} | ${false}
${types.HIDE_CUSTOM_STAGE_FORM} | ${'isEditingCustomStage'} | ${false}
${types.HIDE_CUSTOM_STAGE_FORM} | ${'customStageFormErrors'} | ${null}
${types.HIDE_CUSTOM_STAGE_FORM} | ${'customStageFormInitialData'} | ${null}
${types.SHOW_CUSTOM_STAGE_FORM} | ${'isCreatingCustomStage'} | ${true}
${types.SHOW_CUSTOM_STAGE_FORM} | ${'isEditingCustomStage'} | ${false}
${types.SHOW_CUSTOM_STAGE_FORM} | ${'customStageFormErrors'} | ${null}
${types.SHOW_EDIT_CUSTOM_STAGE_FORM} | ${'isEditingCustomStage'} | ${true}
${types.SHOW_EDIT_CUSTOM_STAGE_FORM} | ${'isCreatingCustomStage'} | ${false}
${types.SHOW_EDIT_CUSTOM_STAGE_FORM} | ${'customStageFormErrors'} | ${null}
${types.REQUEST_STAGE_DATA} | ${'isLoadingStage'} | ${true}
${types.RECEIVE_STAGE_DATA_ERROR} | ${'isEmptyStage'} | ${true}
${types.RECEIVE_STAGE_DATA_ERROR} | ${'isLoadingStage'} | ${false}
${types.REQUEST_CYCLE_ANALYTICS_DATA} | ${'isLoading'} | ${true}
${types.RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR} | ${'stages'} | ${[]}
${types.REQUEST_GROUP_STAGES_AND_EVENTS} | ${'stages'} | ${[]}
${types.RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR} | ${'customStageFormEvents'} | ${[]}
${types.REQUEST_GROUP_STAGES_AND_EVENTS} | ${'customStageFormEvents'} | ${[]}
${types.REQUEST_CREATE_CUSTOM_STAGE} | ${'isSavingCustomStage'} | ${true}
${types.RECEIVE_CREATE_CUSTOM_STAGE_SUCCESS} | ${'isSavingCustomStage'} | ${false}
${types.RECEIVE_CREATE_CUSTOM_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false}
${types.RECEIVE_CREATE_CUSTOM_STAGE_ERROR} | ${'customStageFormErrors'} | ${{}}
${types.RECEIVE_GROUP_STAGES_ERROR} | ${'stages'} | ${[]}
${types.REQUEST_GROUP_STAGES} | ${'stages'} | ${[]}
${types.REQUEST_UPDATE_STAGE} | ${'isLoading'} | ${true}
${types.REQUEST_UPDATE_STAGE} | ${'isSavingCustomStage'} | ${true}
${types.REQUEST_UPDATE_STAGE} | ${'customStageFormErrors'} | ${null}
${types.RECEIVE_UPDATE_STAGE_SUCCESS} | ${'isLoading'} | ${false}
${types.RECEIVE_UPDATE_STAGE_SUCCESS} | ${'isSavingCustomStage'} | ${false}
${types.RECEIVE_UPDATE_STAGE_SUCCESS} | ${'isEditingCustomStage'} | ${false}
${types.RECEIVE_UPDATE_STAGE_SUCCESS} | ${'customStageFormErrors'} | ${null}
${types.RECEIVE_UPDATE_STAGE_ERROR} | ${'isLoading'} | ${false}
${types.RECEIVE_UPDATE_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false}
${types.REQUEST_REMOVE_STAGE} | ${'isLoading'} | ${true}
${types.RECEIVE_REMOVE_STAGE_RESPONSE} | ${'isLoading'} | ${false}
${types.REQUEST_STAGE_MEDIANS} | ${'medians'} | ${{}}
......@@ -91,41 +71,45 @@ describe('Cycle analytics mutations', () => {
},
);
describe(`${types.RECEIVE_STAGE_DATA_SUCCESS}`, () => {
it('will set the currentStageEvents state item with the camelCased events', () => {
mutations[types.RECEIVE_STAGE_DATA_SUCCESS](state, rawIssueEvents);
expect(state.currentStageEvents).toEqual(transformedEvents);
});
it('will set isLoadingStage=false', () => {
mutations[types.RECEIVE_STAGE_DATA_SUCCESS](state);
expect(state.isLoadingStage).toEqual(false);
describe('Custom stage mutations', () => {
beforeEach(() => {
state = {};
});
it('will set isEmptyStage=false if currentStageEvents.length > 0', () => {
mutations[types.RECEIVE_STAGE_DATA_SUCCESS](state, rawIssueEvents);
expect(state.isEmptyStage).toEqual(false);
afterEach(() => {
state = null;
});
it('will set isEmptyStage=true if currentStageEvents.length <= 0', () => {
mutations[types.RECEIVE_STAGE_DATA_SUCCESS](state);
it.each`
mutation | stateKey | value
${customStageTypes.HIDE_FORM} | ${'isCreatingCustomStage'} | ${false}
${customStageTypes.HIDE_FORM} | ${'isEditingCustomStage'} | ${false}
${customStageTypes.HIDE_FORM} | ${'formErrors'} | ${null}
${customStageTypes.HIDE_FORM} | ${'formInitialData'} | ${null}
${customStageTypes.SHOW_CREATE_FORM} | ${'isCreatingCustomStage'} | ${true}
${customStageTypes.SHOW_CREATE_FORM} | ${'isEditingCustomStage'} | ${false}
${customStageTypes.SHOW_CREATE_FORM} | ${'formErrors'} | ${null}
${customStageTypes.SHOW_EDIT_FORM} | ${'isEditingCustomStage'} | ${true}
${customStageTypes.SHOW_EDIT_FORM} | ${'isCreatingCustomStage'} | ${false}
${customStageTypes.SHOW_EDIT_FORM} | ${'formErrors'} | ${null}
${customStageTypes.REQUEST_CREATE_STAGE} | ${'isSavingCustomStage'} | ${true}
${customStageTypes.RECEIVE_CREATE_STAGE_SUCCESS} | ${'isSavingCustomStage'} | ${false}
${customStageTypes.RECEIVE_CREATE_STAGE_ERROR} | ${'isSavingCustomStage'} | ${false}
${customStageTypes.SET_STAGE_FORM_ERRORS} | ${'isSavingCustomStage'} | ${false}
`('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => {
customStageMutations[mutation](state);
expect(state.isEmptyStage).toEqual(true);
});
expect(state[stateKey]).toEqual(value);
});
describe(`types.RECEIVE_UPDATE_STAGE_ERROR`, () => {
const mockFormError = { errors: { start_identifier: ['Cant be blank'] } };
it('will set customStageFormErrors', () => {
describe(`${customStageTypes.SET_STAGE_FORM_ERRORS}`, () => {
const mockFormError = { start_identifier: ['Cant be blank'] };
it('will set formErrors', () => {
state = {};
mutations[types.RECEIVE_UPDATE_STAGE_ERROR](state, mockFormError);
customStageMutations[customStageTypes.SET_STAGE_FORM_ERRORS](state, mockFormError);
expect(state.customStageFormErrors).toEqual(
convertObjectPropsToCamelCase(mockFormError.errors),
);
expect(state.formErrors).toEqual(convertObjectPropsToCamelCase(mockFormError));
});
});
});
......@@ -141,13 +125,10 @@ describe('Cycle analytics mutations', () => {
});
});
describe(`${types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS}`, () => {
describe(`${types.RECEIVE_GROUP_STAGES_SUCCESS}`, () => {
describe('with data', () => {
beforeEach(() => {
mutations[types.RECEIVE_GROUP_STAGES_AND_EVENTS_SUCCESS](
state,
customizableStagesAndEvents,
);
mutations[types.RECEIVE_GROUP_STAGES_SUCCESS](state, customizableStagesAndEvents.stages);
});
it('will convert the stats object to stages', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment