debian-mirror-gitlab/spec/frontend/cycle_analytics/base_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

266 lines
7.8 KiB
JavaScript
Raw Normal View History

2021-09-04 01:27:46 +05:30
import { GlLoadingIcon, GlEmptyState } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
2022-04-04 11:22:00 +05:30
import ValueStreamMetrics from '~/analytics/shared/components/value_stream_metrics.vue';
2021-09-04 01:27:46 +05:30
import BaseComponent from '~/cycle_analytics/components/base.vue';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
2021-10-27 15:23:28 +05:30
import StageTable from '~/cycle_analytics/components/stage_table.vue';
2021-11-11 11:23:49 +05:30
import ValueStreamFilters from '~/cycle_analytics/components/value_stream_filters.vue';
2021-10-27 15:23:28 +05:30
import { NOT_ENOUGH_DATA_ERROR } from '~/cycle_analytics/constants';
2021-09-04 01:27:46 +05:30
import initState from '~/cycle_analytics/store/state';
2021-10-27 15:23:28 +05:30
import {
transformedProjectStagePathData,
selectedStage,
issueEvents,
createdBefore,
createdAfter,
currentGroup,
stageCounts,
2021-11-18 22:05:49 +05:30
initialPaginationState as pagination,
2021-10-27 15:23:28 +05:30
} from './mock_data';
const selectedStageEvents = issueEvents.events;
2021-09-04 01:27:46 +05:30
const noDataSvgPath = 'path/to/no/data';
const noAccessSvgPath = 'path/to/no/access';
2021-10-27 15:23:28 +05:30
const selectedStageCount = stageCounts[selectedStage.id];
const fullPath = 'full/path/to/foo';
2021-09-04 01:27:46 +05:30
Vue.use(Vuex);
let wrapper;
2021-11-11 11:23:49 +05:30
const { id: groupId, path: groupPath } = currentGroup;
2021-10-27 15:23:28 +05:30
const defaultState = {
currentGroup,
createdBefore,
createdAfter,
stageCounts,
2021-11-11 11:23:49 +05:30
endpoints: { fullPath, groupId, groupPath },
2021-10-27 15:23:28 +05:30
};
function createStore({ initialState = {}, initialGetters = {} }) {
2021-09-04 01:27:46 +05:30
return new Vuex.Store({
state: {
...initState(),
2021-10-27 15:23:28 +05:30
...defaultState,
2021-09-04 01:27:46 +05:30
...initialState,
},
getters: {
2021-10-27 15:23:28 +05:30
pathNavigationData: () => transformedProjectStagePathData,
filterParams: () => ({
created_after: createdAfter,
created_before: createdBefore,
}),
...initialGetters,
2021-09-04 01:27:46 +05:30
},
});
}
2021-10-27 15:23:28 +05:30
function createComponent({ initialState, initialGetters } = {}) {
2021-09-04 01:27:46 +05:30
return extendedWrapper(
shallowMount(BaseComponent, {
2021-10-27 15:23:28 +05:30
store: createStore({ initialState, initialGetters }),
2021-09-04 01:27:46 +05:30
propsData: {
noDataSvgPath,
noAccessSvgPath,
},
2021-10-27 15:23:28 +05:30
stubs: {
StageTable,
},
2021-09-04 01:27:46 +05:30
}),
);
}
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findPathNavigation = () => wrapper.findComponent(PathNavigation);
2021-11-11 11:23:49 +05:30
const findFilters = () => wrapper.findComponent(ValueStreamFilters);
2021-10-27 15:23:28 +05:30
const findOverviewMetrics = () => wrapper.findComponent(ValueStreamMetrics);
const findStageTable = () => wrapper.findComponent(StageTable);
const findStageEvents = () => findStageTable().props('stageEvents');
const findEmptyStageTitle = () => wrapper.findComponent(GlEmptyState).props('title');
2021-11-18 22:05:49 +05:30
const findPagination = () => wrapper.findByTestId('vsa-stage-pagination');
2021-10-27 15:23:28 +05:30
const hasMetricsRequests = (reqs) => {
const foundReqs = findOverviewMetrics().props('requests');
expect(foundReqs.length).toEqual(reqs.length);
expect(foundReqs.map(({ name }) => name)).toEqual(reqs);
};
2021-09-04 01:27:46 +05:30
describe('Value stream analytics component', () => {
beforeEach(() => {
2021-11-18 22:05:49 +05:30
wrapper = createComponent({ initialState: { selectedStage, selectedStageEvents, pagination } });
2021-09-04 01:27:46 +05:30
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders the path navigation component', () => {
expect(findPathNavigation().exists()).toBe(true);
});
2021-10-27 15:23:28 +05:30
it('receives the stages formatted for the path navigation', () => {
expect(findPathNavigation().props('stages')).toBe(transformedProjectStagePathData);
});
2021-09-04 01:27:46 +05:30
it('renders the overview metrics', () => {
expect(findOverviewMetrics().exists()).toBe(true);
});
2021-10-27 15:23:28 +05:30
it('passes requests prop to the metrics component', () => {
hasMetricsRequests(['recent activity']);
});
2021-09-04 01:27:46 +05:30
it('renders the stage table', () => {
expect(findStageTable().exists()).toBe(true);
});
2021-10-27 15:23:28 +05:30
it('passes the selected stage count to the stage table', () => {
expect(findStageTable().props('stageCount')).toBe(selectedStageCount);
});
2021-09-04 01:27:46 +05:30
it('renders the stage table events', () => {
2021-10-27 15:23:28 +05:30
expect(findStageEvents()).toEqual(selectedStageEvents);
2021-09-04 01:27:46 +05:30
});
2021-11-11 11:23:49 +05:30
it('renders the filters', () => {
expect(findFilters().exists()).toBe(true);
});
it('displays the date range selector and hides the project selector', () => {
expect(findFilters().props()).toMatchObject({
hasProjectFilter: false,
hasDateRangeFilter: true,
});
});
it('passes the paths to the filter bar', () => {
expect(findFilters().props()).toEqual({
groupId,
groupPath,
endDate: createdBefore,
hasDateRangeFilter: true,
hasProjectFilter: false,
selectedProjects: [],
startDate: createdAfter,
});
});
2021-09-04 01:27:46 +05:30
it('does not render the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
2021-11-18 22:05:49 +05:30
it('renders pagination', () => {
expect(findPagination().exists()).toBe(true);
});
2021-10-27 15:23:28 +05:30
describe('with `cycleAnalyticsForGroups=true` license', () => {
beforeEach(() => {
wrapper = createComponent({ initialState: { features: { cycleAnalyticsForGroups: true } } });
});
it('passes requests prop to the metrics component', () => {
hasMetricsRequests(['time summary', 'recent activity']);
});
});
2021-09-04 01:27:46 +05:30
describe('isLoading = true', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { isLoading: true },
});
});
it('renders the path navigation component with prop `loading` set to true', () => {
2021-10-27 15:23:28 +05:30
expect(findPathNavigation().props('loading')).toBe(true);
2021-09-04 01:27:46 +05:30
});
it('does not render the stage table', () => {
expect(findStageTable().exists()).toBe(false);
});
2021-10-27 15:23:28 +05:30
it('renders the overview metrics', () => {
expect(findOverviewMetrics().exists()).toBe(true);
});
2021-09-04 01:27:46 +05:30
it('renders the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
});
describe('isLoadingStage = true', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { isLoadingStage: true },
});
});
it('renders the stage table with a loading icon', () => {
const tableWrapper = findStageTable();
expect(tableWrapper.exists()).toBe(true);
2022-10-11 01:57:18 +05:30
expect(tableWrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
2021-09-04 01:27:46 +05:30
});
2021-10-27 15:23:28 +05:30
it('renders the path navigation loading state', () => {
expect(findPathNavigation().props('loading')).toBe(true);
});
2021-09-04 01:27:46 +05:30
});
describe('isEmptyStage = true', () => {
2021-10-27 15:23:28 +05:30
const emptyStageParams = {
isEmptyStage: true,
selectedStage: { ...selectedStage, emptyStageText: 'This stage is empty' },
};
2021-09-04 01:27:46 +05:30
beforeEach(() => {
2021-10-27 15:23:28 +05:30
wrapper = createComponent({ initialState: emptyStageParams });
2021-09-04 01:27:46 +05:30
});
it('renders the empty stage with `Not enough data` message', () => {
2021-10-27 15:23:28 +05:30
expect(findEmptyStageTitle()).toBe(NOT_ENOUGH_DATA_ERROR);
2021-09-04 01:27:46 +05:30
});
describe('with a selectedStageError', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: {
2021-10-27 15:23:28 +05:30
...emptyStageParams,
2021-09-04 01:27:46 +05:30
selectedStageError: 'There is too much data to calculate',
},
});
});
it('renders the empty stage with `There is too much data to calculate` message', () => {
2021-10-27 15:23:28 +05:30
expect(findEmptyStageTitle()).toBe('There is too much data to calculate');
2021-09-04 01:27:46 +05:30
});
});
});
describe('without a selected stage', () => {
beforeEach(() => {
wrapper = createComponent({
2021-10-27 15:23:28 +05:30
initialGetters: { pathNavigationData: () => [] },
2021-09-04 01:27:46 +05:30
initialState: { selectedStage: null, isEmptyStage: true },
});
});
it('renders the stage table', () => {
expect(findStageTable().exists()).toBe(true);
});
2021-10-27 15:23:28 +05:30
it('does not render the path navigation', () => {
2021-09-04 01:27:46 +05:30
expect(findPathNavigation().exists()).toBe(false);
});
it('does not render the stage table events', () => {
2021-10-27 15:23:28 +05:30
expect(findStageEvents()).toHaveLength(0);
2021-09-04 01:27:46 +05:30
});
it('does not render the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
});
});