gitlab-org--gitlab-foss/spec/frontend/cycle_analytics/store/actions_spec.js

283 lines
9.2 KiB
JavaScript

import axios from 'axios';
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, 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;
let mock;
beforeEach(() => {
state = {};
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
state = {};
});
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,
expectedActions: expectedActions.map((a) => ({ type: a })),
}));
});
describe('fetchCycleAnalyticsData', () => {
beforeEach(() => {
state = { requestPath: mockRequestPath };
mock = new MockAdapter(axios);
mock.onGet(mockRequestPath).reply(httpStatusCodes.OK);
});
it(`dispatches the 'setSelectedStage' and 'fetchStageData' actions`, () =>
testAction({
action: actions.fetchCycleAnalyticsData,
state,
payload: {},
expectedMutations: [
{ type: 'REQUEST_CYCLE_ANALYTICS_DATA' },
{ type: 'RECEIVE_CYCLE_ANALYTICS_DATA_SUCCESS' },
],
expectedActions: [],
}));
describe('with a failing request', () => {
beforeEach(() => {
state = { requestPath: mockRequestPath };
mock = new MockAdapter(axios);
mock.onGet(mockRequestPath).reply(httpStatusCodes.BAD_REQUEST);
});
it(`commits the 'RECEIVE_CYCLE_ANALYTICS_DATA_ERROR' mutation`, () =>
testAction({
action: actions.fetchCycleAnalyticsData,
state,
payload: {},
expectedMutations: [
{ type: 'REQUEST_CYCLE_ANALYTICS_DATA' },
{ type: 'RECEIVE_CYCLE_ANALYTICS_DATA_ERROR' },
],
expectedActions: [],
}));
});
});
describe('fetchStageData', () => {
const mockStagePath = `${mockRequestPath}/events/${selectedStage.name}`;
beforeEach(() => {
state = {
requestPath: mockRequestPath,
startDate: mockStartDate,
selectedStage,
};
mock = new MockAdapter(axios);
mock.onGet(mockStagePath).reply(httpStatusCodes.OK);
});
it(`commits the 'RECEIVE_STAGE_DATA_SUCCESS' mutation`, () =>
testAction({
action: actions.fetchStageData,
state,
payload: {},
expectedMutations: [{ type: 'REQUEST_STAGE_DATA' }, { type: 'RECEIVE_STAGE_DATA_SUCCESS' }],
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 = {
requestPath: mockRequestPath,
startDate: mockStartDate,
selectedStage,
};
mock = new MockAdapter(axios);
mock.onGet(mockStagePath).reply(httpStatusCodes.BAD_REQUEST);
});
it(`commits the 'RECEIVE_STAGE_DATA_ERROR' mutation`, () =>
testAction({
action: actions.fetchStageData,
state,
payload: {},
expectedMutations: [{ type: 'REQUEST_STAGE_DATA' }, { type: 'RECEIVE_STAGE_DATA_ERROR' }],
expectedActions: [],
}));
});
});
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: [],
}));
});
});
});