Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-13 06:09:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-13 06:09:49 +0300
commitb662e7d21db991d6f998ce5268ee843f85d2c631 (patch)
tree8433cc83290e7bcddb68bad4478216fd245781e4 /spec/frontend/cycle_analytics
parenta125ac8a014fc86f8c716229835ed0a0403a6e91 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/cycle_analytics')
-rw-r--r--spec/frontend/cycle_analytics/mock_data.js2
-rw-r--r--spec/frontend/cycle_analytics/store/actions_spec.js144
-rw-r--r--spec/frontend/cycle_analytics/store/mutations_spec.js1
-rw-r--r--spec/frontend/cycle_analytics/utils_spec.js94
4 files changed, 188 insertions, 53 deletions
diff --git a/spec/frontend/cycle_analytics/mock_data.js b/spec/frontend/cycle_analytics/mock_data.js
index 077df3d52fe..c482bd4e910 100644
--- a/spec/frontend/cycle_analytics/mock_data.js
+++ b/spec/frontend/cycle_analytics/mock_data.js
@@ -9,7 +9,6 @@ import stagingStageFixtures from 'test_fixtures/projects/analytics/value_stream_
import { TEST_HOST } from 'helpers/test_constants';
import {
DEFAULT_VALUE_STREAM,
- DEFAULT_DAYS_IN_PAST,
PAGINATION_TYPE,
PAGINATION_SORT_DIRECTION_DESC,
PAGINATION_SORT_FIELD_END_EVENT,
@@ -17,6 +16,7 @@ import {
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { getDateInPast } from '~/lib/utils/datetime_utility';
+const DEFAULT_DAYS_IN_PAST = 30;
export const createdBefore = new Date(2019, 0, 14);
export const createdAfter = getDateInPast(createdBefore, DEFAULT_DAYS_IN_PAST);
diff --git a/spec/frontend/cycle_analytics/store/actions_spec.js b/spec/frontend/cycle_analytics/store/actions_spec.js
index 993e6b6b73a..e775e941b4c 100644
--- a/spec/frontend/cycle_analytics/store/actions_spec.js
+++ b/spec/frontend/cycle_analytics/store/actions_spec.js
@@ -57,22 +57,12 @@ describe('Project Value Stream Analytics actions', () => {
const mutationTypes = (arr) => arr.map(({ type }) => type);
- const mockFetchStageDataActions = [
- { type: 'setLoading', payload: true },
- { type: 'fetchCycleAnalyticsData' },
- { type: 'fetchStageData' },
- { type: 'fetchStageMedians' },
- { type: 'fetchStageCountValues' },
- { type: 'setLoading', payload: false },
- ];
-
describe.each`
- action | payload | expectedActions | expectedMutations
- ${'setLoading'} | ${true} | ${[]} | ${[{ type: 'SET_LOADING', payload: true }]}
- ${'setDateRange'} | ${{ createdAfter, createdBefore }} | ${mockFetchStageDataActions} | ${[mockSetDateActionCommit]}
- ${'setFilters'} | ${[]} | ${mockFetchStageDataActions} | ${[]}
- ${'setSelectedStage'} | ${{ selectedStage }} | ${[{ type: 'fetchStageData' }]} | ${[{ type: 'SET_SELECTED_STAGE', payload: { selectedStage } }]}
- ${'setSelectedValueStream'} | ${{ selectedValueStream }} | ${[{ type: 'fetchValueStreamStages' }, { type: 'fetchCycleAnalyticsData' }]} | ${[{ type: 'SET_SELECTED_VALUE_STREAM', payload: { selectedValueStream } }]}
+ action | payload | expectedActions | expectedMutations
+ ${'setDateRange'} | ${{ createdAfter, createdBefore }} | ${[{ type: 'refetchStageData' }]} | ${[mockSetDateActionCommit]}
+ ${'setFilters'} | ${[]} | ${[{ type: 'refetchStageData' }]} | ${[]}
+ ${'setSelectedStage'} | ${{ selectedStage }} | ${[{ type: 'refetchStageData' }]} | ${[{ type: 'SET_SELECTED_STAGE', payload: { selectedStage } }]}
+ ${'setSelectedValueStream'} | ${{ selectedValueStream }} | ${[{ type: 'fetchValueStreamStages' }]} | ${[{ type: 'SET_SELECTED_VALUE_STREAM', payload: { selectedValueStream } }]}
`('$action', ({ action, payload, expectedActions, expectedMutations }) => {
const types = mutationTypes(expectedMutations);
it(`will dispatch ${expectedActions} and commit ${types}`, () =>
@@ -86,9 +76,18 @@ describe('Project Value Stream Analytics actions', () => {
});
describe('initializeVsa', () => {
- let mockDispatch;
- let mockCommit;
- const payload = { endpoints: mockEndpoints };
+ const selectedAuthor = 'Author';
+ const selectedMilestone = 'Milestone 1';
+ const selectedAssigneeList = ['Assignee 1', 'Assignee 2'];
+ const selectedLabelList = ['Label 1', 'Label 2'];
+ const payload = {
+ endpoints: mockEndpoints,
+ selectedAuthor,
+ selectedMilestone,
+ selectedAssigneeList,
+ selectedLabelList,
+ selectedStage,
+ };
const mockFilterEndpoints = {
groupEndpoint: 'foo',
labelsEndpoint: mockLabelsPath,
@@ -96,27 +95,63 @@ describe('Project Value Stream Analytics actions', () => {
projectEndpoint: '/namespace/-/analytics/value_stream_analytics/value_streams',
};
+ it('will dispatch fetchValueStreams actions and commit SET_LOADING and INITIALIZE_VSA', () => {
+ return testAction({
+ action: actions.initializeVsa,
+ state: {},
+ payload,
+ expectedMutations: [
+ { type: 'INITIALIZE_VSA', payload },
+ { type: 'SET_LOADING', payload: true },
+ { type: 'SET_LOADING', payload: false },
+ ],
+ expectedActions: [
+ { type: 'filters/setEndpoints', payload: mockFilterEndpoints },
+ {
+ type: 'filters/initialize',
+ payload: { selectedAuthor, selectedMilestone, selectedAssigneeList, selectedLabelList },
+ },
+ { type: 'fetchValueStreams' },
+ { type: 'setInitialStage', payload: selectedStage },
+ ],
+ });
+ });
+ });
+
+ describe('setInitialStage', () => {
beforeEach(() => {
- mockDispatch = jest.fn(() => Promise.resolve());
- mockCommit = jest.fn();
+ state = { ...state, stages: allowedStages };
});
- it('will dispatch the setLoading and fetchValueStreams actions and commit INITIALIZE_VSA', async () => {
- await actions.initializeVsa(
- {
- ...state,
- dispatch: mockDispatch,
- commit: mockCommit,
- },
- payload,
- );
- expect(mockCommit).toHaveBeenCalledWith('INITIALIZE_VSA', { endpoints: mockEndpoints });
-
- expect(mockDispatch).toHaveBeenCalledTimes(4);
- expect(mockDispatch).toHaveBeenCalledWith('filters/setEndpoints', mockFilterEndpoints);
- expect(mockDispatch).toHaveBeenCalledWith('setLoading', true);
- expect(mockDispatch).toHaveBeenCalledWith('fetchValueStreams');
- expect(mockDispatch).toHaveBeenCalledWith('setLoading', false);
+ describe('with a selected stage', () => {
+ it('will commit `SET_SELECTED_STAGE` and fetchValueStreamStageData actions', () => {
+ const fakeStage = { ...selectedStage, id: 'fake', name: 'fake-stae' };
+ return testAction({
+ action: actions.setInitialStage,
+ state,
+ payload: fakeStage,
+ expectedMutations: [
+ {
+ type: 'SET_SELECTED_STAGE',
+ payload: fakeStage,
+ },
+ ],
+ expectedActions: [{ type: 'fetchValueStreamStageData' }],
+ });
+ });
+ });
+
+ describe('without a selected stage', () => {
+ it('will select the first stage from the value stream', () => {
+ const [firstStage] = allowedStages;
+ testAction({
+ action: actions.setInitialStage,
+ state,
+ payload: null,
+ expectedMutations: [{ type: 'SET_SELECTED_STAGE', payload: firstStage }],
+ expectedActions: [{ type: 'fetchValueStreamStageData' }],
+ });
+ });
});
});
@@ -270,12 +305,7 @@ describe('Project Value Stream Analytics actions', () => {
state,
payload: {},
expectedMutations: [{ type: 'REQUEST_VALUE_STREAMS' }],
- expectedActions: [
- { type: 'receiveValueStreamsSuccess' },
- { type: 'setSelectedStage' },
- { type: 'fetchStageMedians' },
- { type: 'fetchStageCountValues' },
- ],
+ expectedActions: [{ type: 'receiveValueStreamsSuccess' }],
}));
describe('with a failing request', () => {
@@ -483,4 +513,34 @@ describe('Project Value Stream Analytics actions', () => {
}));
});
});
+
+ describe('refetchStageData', () => {
+ it('will commit SET_LOADING and dispatch fetchValueStreamStageData actions', () =>
+ testAction({
+ action: actions.refetchStageData,
+ state,
+ payload: {},
+ expectedMutations: [
+ { type: 'SET_LOADING', payload: true },
+ { type: 'SET_LOADING', payload: false },
+ ],
+ expectedActions: [{ type: 'fetchValueStreamStageData' }],
+ }));
+ });
+
+ describe('fetchValueStreamStageData', () => {
+ it('will dispatch the fetchCycleAnalyticsData, fetchStageData, fetchStageMedians and fetchStageCountValues actions', () =>
+ testAction({
+ action: actions.fetchValueStreamStageData,
+ state,
+ payload: {},
+ expectedMutations: [],
+ expectedActions: [
+ { type: 'fetchCycleAnalyticsData' },
+ { type: 'fetchStageData' },
+ { type: 'fetchStageMedians' },
+ { type: 'fetchStageCountValues' },
+ ],
+ }));
+ });
});
diff --git a/spec/frontend/cycle_analytics/store/mutations_spec.js b/spec/frontend/cycle_analytics/store/mutations_spec.js
index 4860225c995..2670a390e9c 100644
--- a/spec/frontend/cycle_analytics/store/mutations_spec.js
+++ b/spec/frontend/cycle_analytics/store/mutations_spec.js
@@ -101,6 +101,7 @@ describe('Project Value Stream Analytics mutations', () => {
${types.SET_SELECTED_VALUE_STREAM} | ${selectedValueStream} | ${'selectedValueStream'} | ${selectedValueStream}
${types.SET_PAGINATION} | ${pagination} | ${'pagination'} | ${{ ...pagination, sort: PAGINATION_SORT_FIELD_END_EVENT, direction: PAGINATION_SORT_DIRECTION_DESC }}
${types.SET_PAGINATION} | ${{ ...pagination, sort: 'duration', direction: 'asc' }} | ${'pagination'} | ${{ ...pagination, sort: 'duration', direction: 'asc' }}
+ ${types.SET_SELECTED_STAGE} | ${selectedStage} | ${'selectedStage'} | ${selectedStage}
${types.RECEIVE_VALUE_STREAMS_SUCCESS} | ${[selectedValueStream]} | ${'valueStreams'} | ${[selectedValueStream]}
${types.RECEIVE_VALUE_STREAM_STAGES_SUCCESS} | ${{ stages: rawValueStreamStages }} | ${'stages'} | ${valueStreamStages}
${types.RECEIVE_STAGE_MEDIANS_SUCCESS} | ${rawStageMedians} | ${'medians'} | ${formattedStageMedians}
diff --git a/spec/frontend/cycle_analytics/utils_spec.js b/spec/frontend/cycle_analytics/utils_spec.js
index 370fe52299c..a6d6d022781 100644
--- a/spec/frontend/cycle_analytics/utils_spec.js
+++ b/spec/frontend/cycle_analytics/utils_spec.js
@@ -1,12 +1,11 @@
import metricsData from 'test_fixtures/projects/analytics/value_stream_analytics/summary.json';
-import { useFakeDate } from 'helpers/fake_date';
import {
transformStagesForPathNavigation,
medianTimeToParsedSeconds,
formatMedianValues,
filterStagesByHiddenStatus,
- calculateFormattedDayInPast,
prepareTimeMetricsData,
+ buildCycleAnalyticsInitialData,
} from '~/cycle_analytics/utils';
import { slugify } from '~/lib/utils/text_utility';
import {
@@ -90,14 +89,6 @@ describe('Value stream analytics utils', () => {
});
});
- describe('calculateFormattedDayInPast', () => {
- useFakeDate(1815, 11, 10);
-
- it('will return 2 dates, now and past', () => {
- expect(calculateFormattedDayInPast(5)).toEqual({ now: '1815-12-10', past: '1815-12-05' });
- });
- });
-
describe('prepareTimeMetricsData', () => {
let prepared;
const [first, second] = metricsData;
@@ -125,4 +116,87 @@ describe('Value stream analytics utils', () => {
]);
});
});
+
+ describe('buildCycleAnalyticsInitialData', () => {
+ let res = null;
+ const projectId = '5';
+ const createdAfter = '2021-09-01';
+ const createdBefore = '2021-11-06';
+ const groupId = '146';
+ const groupPath = 'fake-group';
+ const fullPath = 'fake-group/fake-project';
+ const labelsPath = '/fake-group/fake-project/-/labels.json';
+ const milestonesPath = '/fake-group/fake-project/-/milestones.json';
+ const requestPath = '/fake-group/fake-project/-/value_stream_analytics';
+
+ const rawData = {
+ projectId,
+ createdBefore,
+ createdAfter,
+ fullPath,
+ requestPath,
+ labelsPath,
+ milestonesPath,
+ groupId,
+ groupPath,
+ };
+
+ describe('with minimal data', () => {
+ beforeEach(() => {
+ res = buildCycleAnalyticsInitialData(rawData);
+ });
+
+ it('sets the projectId', () => {
+ expect(res.projectId).toBe(parseInt(projectId, 10));
+ });
+
+ it('sets the date range', () => {
+ expect(res.createdBefore).toEqual(new Date(createdBefore));
+ expect(res.createdAfter).toEqual(new Date(createdAfter));
+ });
+
+ it('sets the endpoints', () => {
+ const { endpoints } = res;
+ expect(endpoints.fullPath).toBe(fullPath);
+ expect(endpoints.requestPath).toBe(requestPath);
+ expect(endpoints.labelsPath).toBe(labelsPath);
+ expect(endpoints.milestonesPath).toBe(milestonesPath);
+ expect(endpoints.groupId).toBe(parseInt(groupId, 10));
+ expect(endpoints.groupPath).toBe(groupPath);
+ });
+
+ it('returns null when there is no stage', () => {
+ expect(res.selectedStage).toBeNull();
+ });
+
+ it('returns false for missing features', () => {
+ expect(res.features.cycleAnalyticsForGroups).toBe(false);
+ });
+ });
+
+ describe('with a stage set', () => {
+ const jsonStage = '{"id":"fakeStage","title":"fakeStage"}';
+
+ it('parses the selectedStage data', () => {
+ res = buildCycleAnalyticsInitialData({ ...rawData, stage: jsonStage });
+
+ const { selectedStage: stage } = res;
+
+ expect(stage.id).toBe('fakeStage');
+ expect(stage.title).toBe('fakeStage');
+ });
+ });
+
+ describe('with features set', () => {
+ const fakeFeatures = { cycleAnalyticsForGroups: true };
+
+ it('sets the feature flags', () => {
+ res = buildCycleAnalyticsInitialData({
+ ...rawData,
+ gon: { licensed_features: fakeFeatures },
+ });
+ expect(res.features).toEqual(fakeFeatures);
+ });
+ });
+ });
});