diff options
Diffstat (limited to 'spec/frontend/cycle_analytics/store')
-rw-r--r-- | spec/frontend/cycle_analytics/store/actions_spec.js | 191 | ||||
-rw-r--r-- | spec/frontend/cycle_analytics/store/getters_spec.js | 16 | ||||
-rw-r--r-- | spec/frontend/cycle_analytics/store/mutations_spec.js | 34 |
3 files changed, 211 insertions, 30 deletions
diff --git a/spec/frontend/cycle_analytics/store/actions_spec.js b/spec/frontend/cycle_analytics/store/actions_spec.js index 630c5100754..4f37e1266fb 100644 --- a/spec/frontend/cycle_analytics/store/actions_spec.js +++ b/spec/frontend/cycle_analytics/store/actions_spec.js @@ -3,10 +3,27 @@ import MockAdapter from 'axios-mock-adapter'; import testAction from 'helpers/vuex_action_helper'; import * as actions from '~/cycle_analytics/store/actions'; import httpStatusCodes from '~/lib/utils/http_status'; -import { selectedStage } from '../mock_data'; +import { selectedStage, selectedValueStream } from '../mock_data'; const mockRequestPath = 'some/cool/path'; +const mockFullPath = '/namespace/-/analytics/value_stream_analytics/value_streams'; const mockStartDate = 30; +const mockRequestedDataActions = ['fetchValueStreams', 'fetchCycleAnalyticsData']; +const mockInitializeActionCommit = { + payload: { requestPath: mockRequestPath }, + type: 'INITIALIZE_VSA', +}; +const mockSetDateActionCommit = { payload: { startDate: mockStartDate }, type: 'SET_DATE_RANGE' }; +const mockRequestedDataMutations = [ + { + payload: true, + type: 'SET_LOADING', + }, + { + payload: false, + type: 'SET_LOADING', + }, +]; describe('Project Value Stream Analytics actions', () => { let state; @@ -22,27 +39,26 @@ describe('Project Value Stream Analytics actions', () => { state = {}; }); - it.each` - action | type | payload | expectedActions - ${'initializeVsa'} | ${'INITIALIZE_VSA'} | ${{ requestPath: mockRequestPath }} | ${['fetchCycleAnalyticsData']} - ${'setDateRange'} | ${'SET_DATE_RANGE'} | ${{ startDate: 30 }} | ${[]} - ${'setSelectedStage'} | ${'SET_SELECTED_STAGE'} | ${{ selectedStage }} | ${[]} - `( - '$action should dispatch $expectedActions and commit $type', - ({ action, type, payload, expectedActions }) => + const mutationTypes = (arr) => arr.map(({ type }) => type); + + describe.each` + action | payload | expectedActions | expectedMutations + ${'initializeVsa'} | ${{ requestPath: mockRequestPath }} | ${mockRequestedDataActions} | ${[mockInitializeActionCommit, ...mockRequestedDataMutations]} + ${'setDateRange'} | ${{ startDate: mockStartDate }} | ${mockRequestedDataActions} | ${[mockSetDateActionCommit, ...mockRequestedDataMutations]} + ${'setSelectedStage'} | ${{ selectedStage }} | ${['fetchStageData']} | ${[{ type: 'SET_SELECTED_STAGE', payload: { selectedStage } }]} + ${'setSelectedValueStream'} | ${{ selectedValueStream }} | ${['fetchValueStreamStages']} | ${[{ type: 'SET_SELECTED_VALUE_STREAM', payload: { selectedValueStream } }]} + `('$action', ({ action, payload, expectedActions, expectedMutations }) => { + const types = mutationTypes(expectedMutations); + + it(`will dispatch ${expectedActions} and commit ${types}`, () => testAction({ action: actions[action], state, payload, - expectedMutations: [ - { - type, - payload, - }, - ], + expectedMutations, expectedActions: expectedActions.map((a) => ({ type: a })), - }), - ); + })); + }); describe('fetchCycleAnalyticsData', () => { beforeEach(() => { @@ -60,7 +76,7 @@ describe('Project Value Stream Analytics actions', () => { { type: 'REQUEST_CYCLE_ANALYTICS_DATA' }, { type: 'RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS' }, ], - expectedActions: [{ type: 'setSelectedStage' }, { type: 'fetchStageData' }], + expectedActions: [], })); describe('with a failing request', () => { @@ -85,7 +101,7 @@ describe('Project Value Stream Analytics actions', () => { }); describe('fetchStageData', () => { - const mockStagePath = `${mockRequestPath}/events/${selectedStage.name}.json`; + const mockStagePath = `${mockRequestPath}/events/${selectedStage.name}`; beforeEach(() => { state = { @@ -106,6 +122,32 @@ describe('Project Value Stream Analytics actions', () => { expectedActions: [], })); + describe('with a successful request, but an error in the payload', () => { + const tooMuchDataError = 'Too much data'; + + beforeEach(() => { + state = { + requestPath: mockRequestPath, + startDate: mockStartDate, + selectedStage, + }; + mock = new MockAdapter(axios); + mock.onGet(mockStagePath).reply(httpStatusCodes.OK, { error: tooMuchDataError }); + }); + + it(`commits the 'RECEIVE_STAGE_DATA_ERROR' mutation`, () => + testAction({ + action: actions.fetchStageData, + state, + payload: { error: tooMuchDataError }, + expectedMutations: [ + { type: 'REQUEST_STAGE_DATA' }, + { type: 'RECEIVE_STAGE_DATA_ERROR', payload: tooMuchDataError }, + ], + expectedActions: [], + })); + }); + describe('with a failing request', () => { beforeEach(() => { state = { @@ -127,4 +169,115 @@ describe('Project Value Stream Analytics actions', () => { })); }); }); + + describe('fetchValueStreams', () => { + const mockValueStreamPath = /\/analytics\/value_stream_analytics\/value_streams/; + + beforeEach(() => { + state = { + fullPath: mockFullPath, + }; + mock = new MockAdapter(axios); + mock.onGet(mockValueStreamPath).reply(httpStatusCodes.OK); + }); + + it(`commits the 'REQUEST_VALUE_STREAMS' mutation`, () => + testAction({ + action: actions.fetchValueStreams, + state, + payload: {}, + expectedMutations: [{ type: 'REQUEST_VALUE_STREAMS' }], + expectedActions: [{ type: 'receiveValueStreamsSuccess' }, { type: 'setSelectedStage' }], + })); + + describe('with a failing request', () => { + beforeEach(() => { + mock = new MockAdapter(axios); + mock.onGet(mockValueStreamPath).reply(httpStatusCodes.BAD_REQUEST); + }); + + it(`commits the 'RECEIVE_VALUE_STREAMS_ERROR' mutation`, () => + testAction({ + action: actions.fetchValueStreams, + state, + payload: {}, + expectedMutations: [ + { type: 'REQUEST_VALUE_STREAMS' }, + { type: 'RECEIVE_VALUE_STREAMS_ERROR', payload: httpStatusCodes.BAD_REQUEST }, + ], + expectedActions: [], + })); + }); + }); + + describe('receiveValueStreamsSuccess', () => { + const mockValueStream = { + id: 'mockDefault', + name: 'mock default', + }; + const mockValueStreams = [mockValueStream, selectedValueStream]; + it('with data, will set the first value stream', () => { + testAction({ + action: actions.receiveValueStreamsSuccess, + state, + payload: mockValueStreams, + expectedMutations: [{ type: 'RECEIVE_VALUE_STREAMS_SUCCESS', payload: mockValueStreams }], + expectedActions: [{ type: 'setSelectedValueStream', payload: mockValueStream }], + }); + }); + + it('without data, will set the default value stream', () => { + testAction({ + action: actions.receiveValueStreamsSuccess, + state, + payload: [], + expectedMutations: [{ type: 'RECEIVE_VALUE_STREAMS_SUCCESS', payload: [] }], + expectedActions: [{ type: 'setSelectedValueStream', payload: selectedValueStream }], + }); + }); + }); + + describe('fetchValueStreamStages', () => { + const mockValueStreamPath = /\/analytics\/value_stream_analytics\/value_streams/; + + beforeEach(() => { + state = { + fullPath: mockFullPath, + selectedValueStream, + }; + mock = new MockAdapter(axios); + mock.onGet(mockValueStreamPath).reply(httpStatusCodes.OK); + }); + + it(`commits the 'REQUEST_VALUE_STREAM_STAGES' and 'RECEIVE_VALUE_STREAM_STAGES_SUCCESS' mutations`, () => + testAction({ + action: actions.fetchValueStreamStages, + state, + payload: {}, + expectedMutations: [ + { type: 'REQUEST_VALUE_STREAM_STAGES' }, + { type: 'RECEIVE_VALUE_STREAM_STAGES_SUCCESS' }, + ], + expectedActions: [], + })); + + describe('with a failing request', () => { + beforeEach(() => { + mock = new MockAdapter(axios); + mock.onGet(mockValueStreamPath).reply(httpStatusCodes.BAD_REQUEST); + }); + + it(`commits the 'RECEIVE_VALUE_STREAM_STAGES_ERROR' mutation`, () => + testAction({ + action: actions.fetchValueStreamStages, + state, + payload: {}, + expectedMutations: [ + { type: 'REQUEST_VALUE_STREAM_STAGES' }, + { type: 'RECEIVE_VALUE_STREAM_STAGES_ERROR', payload: httpStatusCodes.BAD_REQUEST }, + ], + expectedActions: [], + })); + }); + }); }); diff --git a/spec/frontend/cycle_analytics/store/getters_spec.js b/spec/frontend/cycle_analytics/store/getters_spec.js new file mode 100644 index 00000000000..5745e9d7902 --- /dev/null +++ b/spec/frontend/cycle_analytics/store/getters_spec.js @@ -0,0 +1,16 @@ +import * as getters from '~/cycle_analytics/store/getters'; +import { + allowedStages, + stageMedians, + transformedProjectStagePathData, + selectedStage, +} from '../mock_data'; + +describe('Value stream analytics getters', () => { + describe('pathNavigationData', () => { + it('returns the transformed data', () => { + const state = { stages: allowedStages, medians: stageMedians, selectedStage }; + expect(getters.pathNavigationData(state)).toEqual(transformedProjectStagePathData); + }); + }); +}); diff --git a/spec/frontend/cycle_analytics/store/mutations_spec.js b/spec/frontend/cycle_analytics/store/mutations_spec.js index 08c70af6ef6..88e1a13f506 100644 --- a/spec/frontend/cycle_analytics/store/mutations_spec.js +++ b/spec/frontend/cycle_analytics/store/mutations_spec.js @@ -1,6 +1,15 @@ import * as types from '~/cycle_analytics/store/mutation_types'; import mutations from '~/cycle_analytics/store/mutations'; -import { selectedStage, rawEvents, convertedEvents, rawData, convertedData } from '../mock_data'; +import { + selectedStage, + rawEvents, + convertedEvents, + rawData, + convertedData, + selectedValueStream, + rawValueStreamStages, + valueStreamStages, +} from '../mock_data'; let state; const mockRequestPath = 'fake/request/path'; @@ -17,15 +26,15 @@ describe('Project Value Stream Analytics mutations', () => { it.each` mutation | stateKey | value - ${types.SET_SELECTED_STAGE} | ${'isLoadingStage'} | ${false} + ${types.REQUEST_VALUE_STREAMS} | ${'valueStreams'} | ${[]} + ${types.RECEIVE_VALUE_STREAMS_ERROR} | ${'valueStreams'} | ${[]} + ${types.REQUEST_VALUE_STREAM_STAGES} | ${'stages'} | ${[]} + ${types.RECEIVE_VALUE_STREAM_STAGES_ERROR} | ${'stages'} | ${[]} ${types.REQUEST_CYCLE_ANALYTICS_DATA} | ${'isLoading'} | ${true} - ${types.REQUEST_CYCLE_ANALYTICS_DATA} | ${'stages'} | ${[]} ${types.REQUEST_CYCLE_ANALYTICS_DATA} | ${'hasError'} | ${false} - ${types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS} | ${'isLoading'} | ${false} ${types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS} | ${'hasError'} | ${false} ${types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR} | ${'isLoading'} | ${false} ${types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR} | ${'hasError'} | ${true} - ${types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR} | ${'stages'} | ${[]} ${types.REQUEST_STAGE_DATA} | ${'isLoadingStage'} | ${true} ${types.REQUEST_STAGE_DATA} | ${'isEmptyStage'} | ${false} ${types.REQUEST_STAGE_DATA} | ${'hasError'} | ${false} @@ -44,12 +53,15 @@ describe('Project Value Stream Analytics mutations', () => { }); it.each` - mutation | payload | stateKey | value - ${types.INITIALIZE_VSA} | ${{ requestPath: mockRequestPath }} | ${'requestPath'} | ${mockRequestPath} - ${types.SET_SELECTED_STAGE} | ${selectedStage} | ${'selectedStage'} | ${selectedStage} - ${types.SET_DATE_RANGE} | ${{ startDate: mockStartData }} | ${'startDate'} | ${mockStartData} - ${types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS} | ${rawData} | ${'stages'} | ${convertedData.stages} - ${types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS} | ${rawData} | ${'summary'} | ${convertedData.summary} + mutation | payload | stateKey | value + ${types.INITIALIZE_VSA} | ${{ requestPath: mockRequestPath }} | ${'requestPath'} | ${mockRequestPath} + ${types.SET_DATE_RANGE} | ${{ startDate: mockStartData }} | ${'startDate'} | ${mockStartData} + ${types.SET_LOADING} | ${true} | ${'isLoading'} | ${true} + ${types.SET_LOADING} | ${false} | ${'isLoading'} | ${false} + ${types.SET_SELECTED_VALUE_STREAM} | ${selectedValueStream} | ${'selectedValueStream'} | ${selectedValueStream} + ${types.RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS} | ${rawData} | ${'summary'} | ${convertedData.summary} + ${types.RECEIVE_VALUE_STREAMS_SUCCESS} | ${[selectedValueStream]} | ${'valueStreams'} | ${[selectedValueStream]} + ${types.RECEIVE_VALUE_STREAM_STAGES_SUCCESS} | ${{ stages: rawValueStreamStages }} | ${'stages'} | ${valueStreamStages} `( '$mutation with $payload will set $stateKey to $value', ({ mutation, payload, stateKey, value }) => { |