Commit 3894edef authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Fatih Acet

Move cycle analytics endpoints to api.js

Moves the summary data request and the
group stages and events request to the api.js
module
parent b0182221
...@@ -92,8 +92,6 @@ export default { ...@@ -92,8 +92,6 @@ export default {
'fetchCycleAnalyticsData', 'fetchCycleAnalyticsData',
'fetchStageData', 'fetchStageData',
'fetchGroupStagesAndEvents', 'fetchGroupStagesAndEvents',
'setCycleAnalyticsDataEndpoint',
'setStageDataEndpoint',
'setSelectedGroup', 'setSelectedGroup',
'setSelectedProjects', 'setSelectedProjects',
'setSelectedTimeframe', 'setSelectedTimeframe',
...@@ -106,7 +104,6 @@ export default { ...@@ -106,7 +104,6 @@ export default {
'fetchTasksByTypeData', 'fetchTasksByTypeData',
]), ]),
onGroupSelect(group) { onGroupSelect(group) {
this.setCycleAnalyticsDataEndpoint(group.full_path);
this.setSelectedGroup(group); this.setSelectedGroup(group);
this.fetchCycleAnalyticsData(); this.fetchCycleAnalyticsData();
}, },
...@@ -118,8 +115,7 @@ export default { ...@@ -118,8 +115,7 @@ export default {
onStageSelect(stage) { onStageSelect(stage) {
this.hideCustomStageForm(); this.hideCustomStageForm();
this.setSelectedStageId(stage.id); this.setSelectedStageId(stage.id);
this.setStageDataEndpoint(this.currentStage.slug); this.fetchStageData(this.currentStage.slug);
this.fetchStageData(this.currentStage.name);
}, },
onShowAddStageForm() { onShowAddStageForm() {
this.showCustomStageForm(); this.showCustomStageForm();
......
import axios from '~/lib/utils/axios_utils';
import createFlash, { hideFlash } from '~/flash'; import createFlash, { hideFlash } from '~/flash';
import { __ } from '~/locale'; import { __ } from '~/locale';
import Api from 'ee/api'; import Api from 'ee/api';
...@@ -13,11 +12,6 @@ const removeError = () => { ...@@ -13,11 +12,6 @@ const removeError = () => {
} }
}; };
export const setCycleAnalyticsDataEndpoint = ({ commit }, groupPath) =>
commit(types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT, groupPath);
export const setStageDataEndpoint = ({ commit }, stageSlug) =>
commit(types.SET_STAGE_DATA_ENDPOINT, stageSlug);
export const setSelectedGroup = ({ commit }, group) => commit(types.SET_SELECTED_GROUP, group); export const setSelectedGroup = ({ commit }, group) => commit(types.SET_SELECTED_GROUP, group);
export const setSelectedProjects = ({ commit }, projectIds) => export const setSelectedProjects = ({ commit }, projectIds) =>
commit(types.SET_SELECTED_PROJECTS, projectIds); commit(types.SET_SELECTED_PROJECTS, projectIds);
...@@ -44,14 +38,19 @@ export const receiveStageDataError = ({ commit }) => { ...@@ -44,14 +38,19 @@ export const receiveStageDataError = ({ commit }) => {
createFlash(__('There was an error fetching data for the selected stage')); createFlash(__('There was an error fetching data for the selected stage'));
}; };
export const fetchStageData = ({ state, dispatch, getters }) => { export const fetchStageData = ({ state, dispatch, getters }, slug) => {
const { cycleAnalyticsRequestParams = {} } = getters; const { cycleAnalyticsRequestParams = {} } = getters;
dispatch('requestStageData'); dispatch('requestStageData');
axios const {
.get(state.endpoints.stageData, { selectedGroup: { fullPath },
params: nestQueryStringKeys(cycleAnalyticsRequestParams, 'cycle_analytics'), } = state;
})
return Api.cycleAnalyticsStageEvents(
fullPath,
slug,
nestQueryStringKeys(cycleAnalyticsRequestParams, 'cycle_analytics'),
)
.then(({ data }) => dispatch('receiveStageDataSuccess', data)) .then(({ data }) => dispatch('receiveStageDataSuccess', data))
.catch(error => dispatch('receiveStageDataError', error)); .catch(error => dispatch('receiveStageDataError', error));
}; };
...@@ -94,10 +93,14 @@ export const fetchSummaryData = ({ state, dispatch, getters }) => { ...@@ -94,10 +93,14 @@ export const fetchSummaryData = ({ state, dispatch, getters }) => {
const { cycleAnalyticsRequestParams = {} } = getters; const { cycleAnalyticsRequestParams = {} } = getters;
dispatch('requestSummaryData'); dispatch('requestSummaryData');
return axios const {
.get(state.endpoints.cycleAnalyticsData, { selectedGroup: { fullPath },
params: nestQueryStringKeys(cycleAnalyticsRequestParams, 'cycle_analytics'), } = state;
})
return Api.cycleAnalyticsSummaryData(
fullPath,
nestQueryStringKeys(cycleAnalyticsRequestParams, 'cycle_analytics'),
)
.then(({ data }) => dispatch('receiveSummaryDataSuccess', data)) .then(({ data }) => dispatch('receiveSummaryDataSuccess', data))
.catch(error => dispatch('receiveSummaryDataError', error)); .catch(error => dispatch('receiveSummaryDataError', error));
}; };
...@@ -139,23 +142,26 @@ export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch }, ...@@ -139,23 +142,26 @@ export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch },
const { stages = [] } = state; const { stages = [] } = state;
if (stages && stages.length) { if (stages && stages.length) {
const { slug } = stages[0]; const { slug } = stages[0];
dispatch('setStageDataEndpoint', slug); dispatch('fetchStageData', slug);
dispatch('fetchStageData');
} else { } else {
createFlash(__('There was an error while fetching cycle analytics data.')); createFlash(__('There was an error while fetching cycle analytics data.'));
} }
}; };
export const fetchGroupStagesAndEvents = ({ state, dispatch, getters }) => { export const fetchGroupStagesAndEvents = ({ state, dispatch, getters }) => {
const {
selectedGroup: { fullPath },
} = state;
const { const {
cycleAnalyticsRequestParams: { created_after, project_ids }, cycleAnalyticsRequestParams: { created_after, project_ids },
} = getters; } = getters;
dispatch('requestGroupStagesAndEvents'); dispatch('requestGroupStagesAndEvents');
return axios return Api.cycleAnalyticsGroupStagesAndEvents(
.get(state.endpoints.cycleAnalyticsStagesAndEvents, { fullPath,
params: nestQueryStringKeys({ start_date: created_after, project_ids }, 'cycle_analytics'), nestQueryStringKeys({ start_date: created_after, project_ids }, 'cycle_analytics'),
}) )
.then(({ data }) => dispatch('receiveGroupStagesAndEventsSuccess', data)) .then(({ data }) => dispatch('receiveGroupStagesAndEventsSuccess', data))
.catch(error => dispatch('receiveGroupStagesAndEventsError', error)); .catch(error => dispatch('receiveGroupStagesAndEventsError', error));
}; };
...@@ -173,6 +179,8 @@ export const receiveCreateCustomStageError = ({ commit }, { error, data }) => { ...@@ -173,6 +179,8 @@ export const receiveCreateCustomStageError = ({ commit }, { error, data }) => {
const { name } = data; const { name } = data;
const { status } = error; const { status } = error;
// TODO: check for 403, 422 etc
// Follow up issue to investigate https://gitlab.com/gitlab-org/gitlab/issues/36685
const message = const message =
status !== httpStatus.UNPROCESSABLE_ENTITY status !== httpStatus.UNPROCESSABLE_ENTITY
? __(`'${name}' stage already exists'`) ? __(`'${name}' stage already exists'`)
...@@ -186,11 +194,9 @@ export const createCustomStage = ({ dispatch, state }, data) => { ...@@ -186,11 +194,9 @@ export const createCustomStage = ({ dispatch, state }, data) => {
selectedGroup: { fullPath }, selectedGroup: { fullPath },
} = state; } = state;
const endpoint = `/-/analytics/cycle_analytics/stages?group_id=${fullPath}`;
dispatch('requestCreateCustomStage'); dispatch('requestCreateCustomStage');
axios return Api.cycleAnalyticsCreateStage(fullPath, data)
.post(endpoint, data)
.then(response => dispatch('receiveCreateCustomStageSuccess', response)) .then(response => dispatch('receiveCreateCustomStageSuccess', response))
.catch(error => dispatch('receiveCreateCustomStageError', { error, data })); .catch(error => dispatch('receiveCreateCustomStageError', { error, data }));
}; };
......
export const SET_CYCLE_ANALYTICS_DATA_ENDPOINT = 'SET_CYCLE_ANALYTICS_DATA_ENDPOINT';
export const SET_STAGE_DATA_ENDPOINT = 'SET_STAGE_DATA_ENDPOINT';
export const SET_SELECTED_GROUP = 'SET_SELECTED_GROUP'; export const SET_SELECTED_GROUP = 'SET_SELECTED_GROUP';
export const SET_SELECTED_PROJECTS = 'SET_SELECTED_PROJECTS'; export const SET_SELECTED_PROJECTS = 'SET_SELECTED_PROJECTS';
export const SET_SELECTED_STAGE_ID = 'SET_SELECTED_STAGE_ID'; export const SET_SELECTED_STAGE_ID = 'SET_SELECTED_STAGE_ID';
......
...@@ -3,18 +3,6 @@ import * as types from './mutation_types'; ...@@ -3,18 +3,6 @@ import * as types from './mutation_types';
import { transformRawStages } from '../utils'; import { transformRawStages } from '../utils';
export default { export default {
[types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT](state, groupPath) {
// TODO: this endpoint will be removed when the /-/analytics endpoints are ready
// https://gitlab.com/gitlab-org/gitlab/issues/34751
state.endpoints.cycleAnalyticsData = `/groups/${groupPath}/-/cycle_analytics`;
state.endpoints.cycleAnalyticsStagesAndEvents = `/-/analytics/cycle_analytics/stages?group_id=${groupPath}`;
},
[types.SET_STAGE_DATA_ENDPOINT](state, stageSlug) {
// TODO: this endpoint will be replaced with a /-/analytics... endpoint when backend is ready
// https://gitlab.com/gitlab-org/gitlab/issues/34751
const { fullPath } = state.selectedGroup;
state.endpoints.stageData = `/groups/${fullPath}/-/cycle_analytics/events/${stageSlug}.json`;
},
[types.SET_SELECTED_GROUP](state, group) { [types.SET_SELECTED_GROUP](state, group) {
state.selectedGroup = convertObjectPropsToCamelCase(group, { deep: true }); state.selectedGroup = convertObjectPropsToCamelCase(group, { deep: true });
state.selectedProjectIds = []; state.selectedProjectIds = [];
......
import { TASKS_BY_TYPE_SUBJECT_ISSUE } from '../constants'; import { TASKS_BY_TYPE_SUBJECT_ISSUE } from '../constants';
export default () => ({ export default () => ({
endpoints: {
cycleAnalyticsData: null,
stageData: null,
cycleAnalyticsStagesAndEvents: null,
summaryData: null,
},
startDate: null, startDate: null,
endDate: null, endDate: null,
......
...@@ -19,6 +19,9 @@ export default { ...@@ -19,6 +19,9 @@ export default {
projectPackagesPath: '/api/:version/projects/:id/packages', projectPackagesPath: '/api/:version/projects/:id/packages',
projectPackagePath: '/api/:version/projects/:id/packages/:package_id', projectPackagePath: '/api/:version/projects/:id/packages/:package_id',
cycleAnalyticsTasksByTypePath: '/-/analytics/type_of_work/tasks_by_type', cycleAnalyticsTasksByTypePath: '/-/analytics/type_of_work/tasks_by_type',
cycleAnalyticsSummaryDataPath: '/groups/:group_id/-/cycle_analytics',
cycleAnalyticsGroupStagesAndEventsPath: '/-/analytics/cycle_analytics/stages',
cycleAnalyticsStageEventsPath: '/groups/:group_id/-/cycle_analytics/events/:stage_id.json',
userSubscription(namespaceId) { userSubscription(namespaceId) {
const url = Api.buildUrl(this.subscriptionPath).replace(':id', encodeURIComponent(namespaceId)); const url = Api.buildUrl(this.subscriptionPath).replace(':id', encodeURIComponent(namespaceId));
...@@ -141,4 +144,33 @@ export default { ...@@ -141,4 +144,33 @@ export default {
const url = Api.buildUrl(this.cycleAnalyticsTasksByTypePath); const url = Api.buildUrl(this.cycleAnalyticsTasksByTypePath);
return axios.get(url, { params }); return axios.get(url, { params });
}, },
cycleAnalyticsSummaryData(groupId, params = {}) {
const url = Api.buildUrl(this.cycleAnalyticsSummaryDataPath).replace(':group_id', groupId);
return axios.get(url, { params });
},
cycleAnalyticsGroupStagesAndEvents(groupId, params = {}) {
const url = Api.buildUrl(this.cycleAnalyticsGroupStagesAndEventsPath);
return axios.get(url, {
params: { group_id: groupId, ...params },
});
},
cycleAnalyticsStageEvents(groupId, stageId, params = {}) {
const url = Api.buildUrl(this.cycleAnalyticsStageEventsPath)
.replace(':group_id', groupId)
.replace(':stage_id', stageId);
return axios.get(url, { params });
},
cycleAnalyticsCreateStage(groupId, data) {
const url = Api.buildUrl(this.cycleAnalyticsGroupStagesAndEventsPath);
return axios.post(url, data, {
params: { group_id: groupId },
});
},
}; };
...@@ -309,7 +309,7 @@ describe('Cycle Analytics component', () => { ...@@ -309,7 +309,7 @@ describe('Cycle Analytics component', () => {
}, },
fetchGroupStagesAndEvents: { fetchGroupStagesAndEvents: {
status: defaultStatus, status: defaultStatus,
endpoint: `/-/analytics/cycle_analytics/stages?group_id=${groupId}`, endpoint: `/-/analytics/cycle_analytics/stages`,
response: { ...mockData.customizableStagesAndEvents }, response: { ...mockData.customizableStagesAndEvents },
}, },
fetchGroupLabels: { fetchGroupLabels: {
......
import axios from 'axios'; import axios from 'axios';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { TEST_HOST } from 'helpers/test_constants';
import createFlash from '~/flash'; import createFlash from '~/flash';
import * as getters from 'ee/analytics/cycle_analytics/store/getters'; import * as getters from 'ee/analytics/cycle_analytics/store/getters';
import * as actions from 'ee/analytics/cycle_analytics/store/actions'; import * as actions from 'ee/analytics/cycle_analytics/store/actions';
...@@ -18,10 +17,14 @@ import { ...@@ -18,10 +17,14 @@ import {
const stageData = { events: [] }; const stageData = { events: [] };
const error = new Error('Request failed with status code 404'); const error = new Error('Request failed with status code 404');
const groupPath = 'cool-group';
const groupLabelsEndpoint = `/groups/${groupPath}/-/labels`;
const flashErrorMessage = 'There was an error while fetching cycle analytics data.'; const flashErrorMessage = 'There was an error while fetching cycle analytics data.';
const selectedGroup = { fullPath: groupPath }; const selectedGroup = { fullPath: group.path };
const [{ id: selectedStageSlug }] = stages;
const endpoints = {
groupLabels: `/groups/${group.path}/-/labels`,
cycleAnalyticsData: `/groups/${group.path}/-/cycle_analytics`,
stageData: `/groups/${group.path}/-/cycle_analytics/events/${selectedStageSlug}.json`,
};
describe('Cycle analytics actions', () => { describe('Cycle analytics actions', () => {
let state; let state;
...@@ -33,10 +36,6 @@ describe('Cycle analytics actions', () => { ...@@ -33,10 +36,6 @@ describe('Cycle analytics actions', () => {
beforeEach(() => { beforeEach(() => {
state = { state = {
endpoints: {
cycleAnalyticsData: `${TEST_HOST}/groups/${group.path}/-/cycle_analytics`,
stageData: `${TEST_HOST}/groups/${group.path}/-/cycle_analytics/events/${cycleAnalyticsData.stats[0].name}.json`,
},
stages: [], stages: [],
getters, getters,
}; };
...@@ -49,12 +48,10 @@ describe('Cycle analytics actions', () => { ...@@ -49,12 +48,10 @@ describe('Cycle analytics actions', () => {
}); });
it.each` it.each`
action | type | stateKey | payload action | type | stateKey | payload
${'setCycleAnalyticsDataEndpoint'} | ${'SET_CYCLE_ANALYTICS_DATA_ENDPOINT'} | ${'endpoints.cycleAnalyticsData'} | ${'coolGroupName'} ${'setSelectedGroup'} | ${'SET_SELECTED_GROUP'} | ${'selectedGroup'} | ${'someNewGroup'}
${'setStageDataEndpoint'} | ${'SET_STAGE_DATA_ENDPOINT'} | ${'endpoints.stageData'} | ${'new_stage_name'} ${'setSelectedProjects'} | ${'SET_SELECTED_PROJECTS'} | ${'selectedProjectIds'} | ${[10, 20, 30, 40]}
${'setSelectedGroup'} | ${'SET_SELECTED_GROUP'} | ${'selectedGroup'} | ${'someNewGroup'} ${'setSelectedStageId'} | ${'SET_SELECTED_STAGE_ID'} | ${'selectedStageId'} | ${'someNewGroup'}
${'setSelectedProjects'} | ${'SET_SELECTED_PROJECTS'} | ${'selectedProjectIds'} | ${[10, 20, 30, 40]}
${'setSelectedStageId'} | ${'SET_SELECTED_STAGE_ID'} | ${'selectedStageId'} | ${'someNewGroup'}
`('$action should set $stateKey with $payload and type $type', ({ action, type, payload }) => { `('$action should set $stateKey with $payload and type $type', ({ action, type, payload }) => {
testAction( testAction(
actions[action], actions[action],
...@@ -87,13 +84,14 @@ describe('Cycle analytics actions', () => { ...@@ -87,13 +84,14 @@ describe('Cycle analytics actions', () => {
describe('fetchStageData', () => { describe('fetchStageData', () => {
beforeEach(() => { beforeEach(() => {
mock.onGet(state.endpoints.stageData).replyOnce(200, { events: [] }); state = { ...state, selectedGroup };
mock.onGet(endpoints.stageData).replyOnce(200, { events: [] });
}); });
it('dispatches receiveStageDataSuccess with received data on success', done => { it('dispatches receiveStageDataSuccess with received data on success', done => {
testAction( testAction(
actions.fetchStageData, actions.fetchStageData,
null, selectedStageSlug,
state, state,
[], [],
[ [
...@@ -108,17 +106,10 @@ describe('Cycle analytics actions', () => { ...@@ -108,17 +106,10 @@ describe('Cycle analytics actions', () => {
}); });
it('dispatches receiveStageDataError on error', done => { it('dispatches receiveStageDataError on error', done => {
const brokenState = {
...state,
endpoints: {
stageData: 'this will break',
},
};
testAction( testAction(
actions.fetchStageData, actions.fetchStageData,
null, null,
brokenState, state,
[], [],
[ [
{ type: 'requestStageData' }, { type: 'requestStageData' },
...@@ -176,7 +167,7 @@ describe('Cycle analytics actions', () => { ...@@ -176,7 +167,7 @@ describe('Cycle analytics actions', () => {
describe('fetchGroupLabels', () => { describe('fetchGroupLabels', () => {
beforeEach(() => { beforeEach(() => {
state = { ...state, selectedGroup }; state = { ...state, selectedGroup };
mock.onGet(groupLabelsEndpoint).replyOnce(200, groupLabels); mock.onGet(endpoints.groupLabels).replyOnce(200, groupLabels);
}); });
it('dispatches receiveGroupLabels if the request succeeds', done => { it('dispatches receiveGroupLabels if the request succeeds', done => {
...@@ -251,7 +242,7 @@ describe('Cycle analytics actions', () => { ...@@ -251,7 +242,7 @@ describe('Cycle analytics actions', () => {
beforeEach(() => { beforeEach(() => {
setFixtures('<div class="flash-container"></div>'); setFixtures('<div class="flash-container"></div>');
mock.onGet(state.endpoints.cycleAnalyticsData).replyOnce(200, cycleAnalyticsData); mock.onGet(endpoints.cycleAnalyticsData).replyOnce(200, cycleAnalyticsData);
state = { ...state, selectedGroup, startDate, endDate }; state = { ...state, selectedGroup, startDate, endDate };
}); });
...@@ -354,8 +345,7 @@ describe('Cycle analytics actions', () => { ...@@ -354,8 +345,7 @@ describe('Cycle analytics actions', () => {
}); });
}); });
it("dispatches the 'setStageDataEndpoint' and 'fetchStageData' actions", done => { it("dispatches the 'fetchStageData' action", done => {
const { id } = stages[0];
const stateWithStages = { const stateWithStages = {
...state, ...state,
stages, stages,
...@@ -371,7 +361,7 @@ describe('Cycle analytics actions', () => { ...@@ -371,7 +361,7 @@ describe('Cycle analytics actions', () => {
payload: { ...customizableStagesAndEvents }, payload: { ...customizableStagesAndEvents },
}, },
], ],
[{ type: 'setStageDataEndpoint', payload: id }, { type: 'fetchStageData' }], [{ type: 'fetchStageData', payload: selectedStageSlug }],
done, done,
); );
}); });
...@@ -463,8 +453,7 @@ describe('Cycle analytics actions', () => { ...@@ -463,8 +453,7 @@ describe('Cycle analytics actions', () => {
); );
}); });
it("dispatches the 'setStageDataEndpoint' and 'fetchStageData' actions", done => { it("dispatches the 'fetchStageData' actions", done => {
const { id } = stages[0];
const stateWithStages = { const stateWithStages = {
...state, ...state,
stages, stages,
...@@ -480,7 +469,7 @@ describe('Cycle analytics actions', () => { ...@@ -480,7 +469,7 @@ describe('Cycle analytics actions', () => {
payload: { ...customizableStagesAndEvents }, payload: { ...customizableStagesAndEvents },
}, },
], ],
[{ type: 'setStageDataEndpoint', payload: id }, { type: 'fetchStageData' }], [{ type: 'fetchStageData', payload: selectedStageSlug }],
done, done,
); );
}); });
......
...@@ -57,13 +57,11 @@ describe('Cycle analytics mutations', () => { ...@@ -57,13 +57,11 @@ describe('Cycle analytics mutations', () => {
}); });
it.each` it.each`
mutation | payload | expectedState mutation | payload | expectedState
${types.SET_CYCLE_ANALYTICS_DATA_ENDPOINT} | ${'cool-beans'} | ${{ endpoints: { cycleAnalyticsStagesAndEvents: '/-/analytics/cycle_analytics/stages?group_id=cool-beans' } }} ${types.SET_SELECTED_GROUP} | ${{ fullPath: 'cool-beans' }} | ${{ selectedGroup: { fullPath: 'cool-beans' }, selectedProjectIds: [] }}
${types.SET_STAGE_DATA_ENDPOINT} | ${'rad-stage'} | ${{ endpoints: { stageData: '/groups/rad-stage/-/cycle_analytics/events/rad-stage.json' } }} ${types.SET_SELECTED_PROJECTS} | ${[606, 707, 808, 909]} | ${{ selectedProjectIds: [606, 707, 808, 909] }}
${types.SET_SELECTED_GROUP} | ${{ fullPath: 'cool-beans' }} | ${{ selectedGroup: { fullPath: 'cool-beans' }, selectedProjectIds: [] }} ${types.SET_DATE_RANGE} | ${{ startDate, endDate }} | ${{ startDate, endDate }}
${types.SET_SELECTED_PROJECTS} | ${[606, 707, 808, 909]} | ${{ selectedProjectIds: [606, 707, 808, 909] }} ${types.SET_SELECTED_STAGE_ID} | ${'first-stage'} | ${{ selectedStageId: 'first-stage' }}
${types.SET_DATE_RANGE} | ${{ startDate, endDate }} | ${{ startDate, endDate }}
${types.SET_SELECTED_STAGE_ID} | ${'first-stage'} | ${{ selectedStageId: 'first-stage' }}
`( `(
'$mutation with payload $payload will update state with $expectedState', '$mutation with payload $payload will update state with $expectedState',
({ mutation, payload, expectedState }) => { ({ mutation, payload, expectedState }) => {
......
...@@ -289,6 +289,17 @@ describe('Api', () => { ...@@ -289,6 +289,17 @@ describe('Api', () => {
const groupId = 'counting-54321'; const groupId = 'counting-54321';
const createdBefore = '2019-11-18'; const createdBefore = '2019-11-18';
const createdAfter = '2019-08-18'; const createdAfter = '2019-08-18';
const stageId = 'thursday';
const expectRequestWithCorrectParameters = (responseObj, { params, expectedUrl, response }) => {
const {
data,
config: { params: reqParams, url },
} = responseObj;
expect(data).toEqual(response);
expect(reqParams).toEqual(params);
expect(url).toEqual(expectedUrl);
};
describe('cycleAnalyticsTasksByType', () => { describe('cycleAnalyticsTasksByType', () => {
it('fetches tasks by type data', done => { it('fetches tasks by type data', done => {
...@@ -330,5 +341,101 @@ describe('Api', () => { ...@@ -330,5 +341,101 @@ describe('Api', () => {
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe('cycleAnalyticsSummaryData', () => {
it('fetches cycle analytics summary, stage stats and permissions data', done => {
const response = { summary: [], stats: [], permissions: {} };
const params = {
'cycle_analytics[created_after]': createdAfter,
'cycle_analytics[created_before]': createdBefore,
};
const expectedUrl = `${dummyUrlRoot}/groups/${groupId}/-/cycle_analytics`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsSummaryData(groupId, params)
.then(responseObj =>
expectRequestWithCorrectParameters(responseObj, {
response,
params,
expectedUrl,
}),
)
.then(done)
.catch(done.fail);
});
});
describe('cycleAnalyticsGroupStagesAndEvents', () => {
it('fetches custom stage events and all stages', done => {
const response = { events: [], stages: [] };
const params = {
group_id: groupId,
'cycle_analytics[created_after]': createdAfter,
'cycle_analytics[created_before]': createdBefore,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsGroupStagesAndEvents(groupId, params)
.then(responseObj =>
expectRequestWithCorrectParameters(responseObj, {
response,
params,
expectedUrl,
}),
)
.then(done)
.catch(done.fail);
});
});
describe('cycleAnalyticsStageEvents', () => {
it('fetches stage events', done => {
const response = { events: [] };
const params = {
'cycle_analytics[group_id]': groupId,
'cycle_analytics[created_after]': createdAfter,
'cycle_analytics[created_before]': createdBefore,
};
const expectedUrl = `${dummyUrlRoot}/groups/${groupId}/-/cycle_analytics/events/${stageId}.json`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsStageEvents(groupId, stageId, params)
.then(responseObj =>
expectRequestWithCorrectParameters(responseObj, {
response,
params,
expectedUrl,
}),
)
.then(done)
.catch(done.fail);
});
});
describe('cycleAnalyticsCreateStage', () => {
it('submit the custom stage data', done => {
const response = {};
const customStage = {
name: 'cool-stage',
start_event_identifier: 'issue_created',
start_event_label_id: null,
end_event_identifier: 'issue_closed',
end_event_label_id: null,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`;
mock.onPost(expectedUrl).reply(200, response);
Api.cycleAnalyticsCreateStage(groupId, customStage)
.then(({ data, config: { params: reqParams, data: reqData, url } }) => {
expect(data).toEqual(response);
expect(reqParams).toEqual({ group_id: groupId });
expect(JSON.parse(reqData)).toMatchObject(customStage);
expect(url).toEqual(expectedUrl);
})
.then(done)
.catch(done.fail);
});
});
}); });
}); });
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