diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-13 06:09:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-13 06:09:49 +0300 |
commit | b662e7d21db991d6f998ce5268ee843f85d2c631 (patch) | |
tree | 8433cc83290e7bcddb68bad4478216fd245781e4 /spec/frontend/cycle_analytics | |
parent | a125ac8a014fc86f8c716229835ed0a0403a6e91 (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.js | 2 | ||||
-rw-r--r-- | spec/frontend/cycle_analytics/store/actions_spec.js | 144 | ||||
-rw-r--r-- | spec/frontend/cycle_analytics/store/mutations_spec.js | 1 | ||||
-rw-r--r-- | spec/frontend/cycle_analytics/utils_spec.js | 94 |
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); + }); + }); + }); }); |