Commit 38364325 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Added missing createCustomStage action specs

Added missing updateStage action specs

Ensures we correctly handle fetch
reqeust failures in the success actions
parent a49b0d95
...@@ -24,7 +24,7 @@ const handleErrorOrRethrow = ({ action, error }) => { ...@@ -24,7 +24,7 @@ const handleErrorOrRethrow = ({ action, error }) => {
const isStageNameExistsError = ({ status, errors }) => { const isStageNameExistsError = ({ status, errors }) => {
const ERROR_NAME_RESERVED = 'is reserved'; const ERROR_NAME_RESERVED = 'is reserved';
if (status === httpStatus.UNPROCESSABLE_ENTITY) { if (status === httpStatus.UNPROCESSABLE_ENTITY) {
if (errors.name && errors.name[0] === ERROR_NAME_RESERVED) return true; if (errors?.name.includes(ERROR_NAME_RESERVED)) return true;
} }
return false; return false;
}; };
...@@ -278,16 +278,24 @@ export const receiveCreateCustomStageSuccess = ({ commit, dispatch }, { data: { ...@@ -278,16 +278,24 @@ export const receiveCreateCustomStageSuccess = ({ commit, dispatch }, { data: {
commit(types.RECEIVE_CREATE_CUSTOM_STAGE_SUCCESS); commit(types.RECEIVE_CREATE_CUSTOM_STAGE_SUCCESS);
createFlash(sprintf(__(`Your custom stage '%{title}' was created`), { title }), 'notice'); createFlash(sprintf(__(`Your custom stage '%{title}' was created`), { title }), 'notice');
return dispatch('fetchGroupStagesAndEvents').then(() => dispatch('fetchSummaryData')); return Promise.resolve()
.then(() => dispatch('fetchGroupStagesAndEvents'))
.then(() => dispatch('fetchSummaryData'))
.catch(() => {
createFlash(__('There was a problem refreshing the data, please try again'));
});
}; };
export const receiveCreateCustomStageError = ({ commit }, { status, message, errors, data }) => { export const receiveCreateCustomStageError = (
commit(types.RECEIVE_CREATE_CUSTOM_STAGE_ERROR, { status, message, errors, data }); { commit },
{ status = 400, errors = {}, data = {} } = {},
const { name } = data; ) => {
const flashMessage = isStageNameExistsError({ status, errors }) commit(types.RECEIVE_CREATE_CUSTOM_STAGE_ERROR, { errors });
? sprintf(__(`'%{name}' stage already exists`), { name }) const { name = null } = data;
: __('There was a problem saving your custom stage, please try again'); const flashMessage =
name && isStageNameExistsError({ status, errors })
? sprintf(__(`'%{name}' stage already exists`), { name })
: __('There was a problem saving your custom stage, please try again');
createFlash(flashMessage); createFlash(flashMessage);
}; };
...@@ -299,12 +307,12 @@ export const createCustomStage = ({ dispatch, state }, data) => { ...@@ -299,12 +307,12 @@ export const createCustomStage = ({ dispatch, state }, data) => {
dispatch('requestCreateCustomStage'); dispatch('requestCreateCustomStage');
return Api.cycleAnalyticsCreateStage(fullPath, data) return Api.cycleAnalyticsCreateStage(fullPath, data)
.then(response => dispatch('receiveCreateCustomStageSuccess', response)) .then(response => {
.catch(({ response }) => { const { status, data: responseData } = response;
const { return dispatch('receiveCreateCustomStageSuccess', { status, data: responseData });
data: { message, errors }, })
status, .catch(({ response } = {}) => {
} = response; const { data: { message, errors } = null, status = 400 } = response;
dispatch('receiveCreateCustomStageError', { data, message, errors, status }); dispatch('receiveCreateCustomStageError', { data, message, errors, status });
}); });
...@@ -356,8 +364,12 @@ export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) => ...@@ -356,8 +364,12 @@ export const receiveUpdateStageSuccess = ({ commit, dispatch }, updatedData) =>
commit(types.RECEIVE_UPDATE_STAGE_SUCCESS); commit(types.RECEIVE_UPDATE_STAGE_SUCCESS);
createFlash(__('Stage data updated'), 'notice'); createFlash(__('Stage data updated'), 'notice');
dispatch('fetchGroupStagesAndEvents'); return Promise.all([
dispatch('setSelectedStage', updatedData); dispatch('fetchGroupStagesAndEvents'),
dispatch('setSelectedStage', updatedData),
]).catch(() => {
createFlash(__('There was a problem refreshing the data, please try again'));
});
}; };
export const receiveUpdateStageError = ( export const receiveUpdateStageError = (
......
...@@ -435,8 +435,8 @@ describe 'Group Value Stream Analytics', :js do ...@@ -435,8 +435,8 @@ describe 'Group Value Stream Analytics', :js do
context 'with all required fields set' do context 'with all required fields set' do
before do before do
select_dropdown_label 'custom-stage-start-event-label', 2 select_dropdown_label 'custom-stage-start-event-label', 1
select_dropdown_label 'custom-stage-stop-event-label', 3 select_dropdown_label 'custom-stage-stop-event-label', 2
end end
it_behaves_like 'submits the form successfully', custom_stage_with_labels_name it_behaves_like 'submits the form successfully', custom_stage_with_labels_name
......
...@@ -682,6 +682,53 @@ describe('Cycle analytics actions', () => { ...@@ -682,6 +682,53 @@ describe('Cycle analytics actions', () => {
done(); done();
}); });
}); });
describe('receiveUpdateStageSuccess', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
const response = {
title: 'NEW - COOL',
};
it('will dispatch fetchGroupStagesAndEvents and fetchSummaryData', () =>
testAction(
actions.receiveUpdateStageSuccess,
response,
state,
[{ type: types.RECEIVE_UPDATE_STAGE_SUCCESS }],
[{ type: 'fetchGroupStagesAndEvents' }, { type: 'setSelectedStage', payload: response }],
));
it('will flash a success message', () =>
actions
.receiveUpdateStageSuccess(
{
dispatch: () => {},
commit: () => {},
},
response,
)
.then(() => {
shouldFlashAMessage('Stage data updated');
}));
describe('with an error', () => {
it('will flash an error message', () =>
actions
.receiveUpdateStageSuccess(
{
dispatch: () => Promise.reject(),
commit: () => {},
},
response,
)
.then(() => {
shouldFlashAMessage('There was a problem refreshing the data, please try again');
}));
});
});
}); });
describe('removeStage', () => { describe('removeStage', () => {
...@@ -1276,4 +1323,150 @@ describe('Cycle analytics actions', () => { ...@@ -1276,4 +1323,150 @@ describe('Cycle analytics actions', () => {
); );
}); });
}); });
describe('createCustomStage', () => {
describe('with valid data', () => {
const customStageData = {
startEventIdentifier: 'start_event',
endEventIdentifier: 'end_event',
name: 'cool-new-stage',
};
beforeEach(() => {
state = { ...state, selectedGroup };
mock.onPost(endpoints.baseStagesEndpointstageData).reply(201, customStageData);
});
it(`dispatches the 'receiveCreateCustomStageSuccess' action`, () =>
testAction(
actions.createCustomStage,
customStageData,
state,
[],
[
{ type: 'requestCreateCustomStage' },
{
type: 'receiveCreateCustomStageSuccess',
payload: { data: customStageData, status: 201 },
},
],
));
});
describe('with errors', () => {
const message = 'failed';
const errors = {
endEventIdentifier: ['Cant be blank'],
};
const customStageData = {
startEventIdentifier: 'start_event',
endEventIdentifier: '',
name: 'cool-new-stage',
};
beforeEach(() => {
state = { ...state, selectedGroup };
mock.onPost(endpoints.baseStagesEndpointstageData).reply(422, {
message,
errors,
});
});
it(`dispatches the 'receiveCreateCustomStageError' action`, () =>
testAction(
actions.createCustomStage,
customStageData,
state,
[],
[
{ type: 'requestCreateCustomStage' },
{
type: 'receiveCreateCustomStageError',
payload: {
data: customStageData,
errors,
message,
status: 422,
},
},
],
));
});
});
describe('receiveCreateCustomStageError', () => {
const response = {
data: { name: 'uh oh' },
};
beforeEach(() => {
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 flash an error message', done => {
actions.receiveCreateCustomStageError(
{
commit: () => {},
},
response,
);
shouldFlashAMessage('There was a problem saving your custom stage, please try again');
done();
});
describe('with a stage name error', () => {
it('will flash an error message', done => {
actions.receiveCreateCustomStageError(
{
commit: () => {},
},
{ ...response, status: 422, errors: { name: ['is reserved'] } },
);
shouldFlashAMessage("'uh oh' stage already exists");
done();
});
});
});
describe('receiveCreateCustomStageSuccess', () => {
const response = {
data: {
title: 'COOL',
},
};
it('will dispatch fetchGroupStagesAndEvents and fetchSummaryData', () =>
testAction(
actions.receiveCreateCustomStageSuccess,
response,
state,
[{ type: types.RECEIVE_CREATE_CUSTOM_STAGE_SUCCESS }],
[{ type: 'fetchGroupStagesAndEvents' }, { type: 'fetchSummaryData' }],
));
describe('with an error', () => {
beforeEach(() => {
setFixtures('<div class="flash-container"></div>');
});
it('will flash an error message', () =>
actions
.receiveCreateCustomStageSuccess(
{
dispatch: () => Promise.reject(),
commit: () => {},
},
response,
)
.then(() => {
shouldFlashAMessage('There was a problem refreshing the data, please try again');
}));
});
});
}); });
...@@ -19326,6 +19326,9 @@ msgstr "" ...@@ -19326,6 +19326,9 @@ msgstr ""
msgid "There was a problem communicating with your device." msgid "There was a problem communicating with your device."
msgstr "" msgstr ""
msgid "There was a problem refreshing the data, please try again"
msgstr ""
msgid "There was a problem saving your custom stage, please try again" msgid "There was a problem saving your custom stage, please try again"
msgstr "" msgstr ""
......
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