Commit 7a02b40c authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Added additional test to the base_spec

Checks the various rendering states for the base
vue component for project VSA
parent 555068a0
......@@ -64,18 +64,13 @@ export default {
return selectedStageEvents.length && !isLoadingStage && !isEmptyStage;
},
displayNotEnoughData() {
const { selectedStage, isEmptyStage, isLoadingStage } = this;
return selectedStage && isEmptyStage && !isLoadingStage;
return this.selectedStageReady && this.isEmptyStage;
},
displayNoAccess() {
const { selectedStage } = this;
return selectedStage && !selectedStage.isUserAllowed;
return this.selectedStageReady && !this.selectedStage.isUserAllowed;
},
selectedStageReady() {
return !this.hasNoAccessError && this.selectedStage;
},
shouldDisplayPathNavigation() {
return this.selectedStage;
return !this.isLoadingStage && this.selectedStage;
},
},
methods: {
......@@ -116,7 +111,7 @@ export default {
<template>
<div class="cycle-analytics">
<path-navigation
v-if="shouldDisplayPathNavigation"
v-if="selectedStageReady"
class="js-path-navigation gl-w-full gl-pb-2"
:loading="isLoading"
:stages="pathNavigationData"
......@@ -198,29 +193,29 @@ export default {
</div>
<div class="stage-panel-body">
<section class="stage-events gl-overflow-auto gl-w-full">
<gl-loading-icon v-show="isLoadingStage" size="lg" />
<template v-if="displayNoAccess">
<gl-loading-icon v-if="isLoadingStage" size="lg" />
<template v-else>
<gl-empty-state
v-if="displayNoAccess"
class="js-empty-state"
:title="__('You need permission.')"
:svg-path="noAccessSvgPath"
:description="__('Want to see the data? Please ask an administrator for access.')"
/>
</template>
<template v-else>
<template v-if="displayNotEnoughData">
<template v-else>
<gl-empty-state
v-if="displayNotEnoughData"
class="js-empty-state"
:description="selectedStage.emptyStageText"
:svg-path="noDataSvgPath"
:title="__('We don\'t have enough data to show this stage.')"
/>
</template>
<template v-if="displayStageEvents">
<component
:is="selectedStage.component"
v-if="displayStageEvents"
:stage="selectedStage"
:items="selectedStageEvents"
data-testid="stage-table-events"
/>
</template>
</template>
......
......@@ -10,13 +10,13 @@ import Metrics from 'ee/analytics/cycle_analytics/components/metrics.vue';
import StageTable from 'ee/analytics/cycle_analytics/components/stage_table.vue';
import TypeOfWorkCharts from 'ee/analytics/cycle_analytics/components/type_of_work_charts.vue';
import ValueStreamSelect from 'ee/analytics/cycle_analytics/components/value_stream_select.vue';
import { OVERVIEW_STAGE_ID } from 'ee/analytics/cycle_analytics/constants';
import createStore from 'ee/analytics/cycle_analytics/store';
import Daterange from 'ee/analytics/shared/components/daterange.vue';
import ProjectsDropdownFilter from 'ee/analytics/shared/components/projects_dropdown_filter.vue';
import { toYmd } from 'ee/analytics/shared/utils';
import waitForPromises from 'helpers/wait_for_promises';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import { OVERVIEW_STAGE_ID } from '~/cycle_analytics/constants';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import * as commonUtils from '~/lib/utils/common_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
......
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';
import Component from '~/cycle_analytics/components/base.vue';
import BaseComponent from '~/cycle_analytics/components/base.vue';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import createStore from '~/cycle_analytics/store';
import initState from '~/cycle_analytics/store/state';
import { selectedStage, convertedEvents as selectedStageEvents } from './mock_data';
const noDataSvgPath = 'path/to/no/data';
const noAccessSvgPath = 'path/to/no/access';
......@@ -13,11 +15,22 @@ Vue.use(Vuex);
let wrapper;
function createComponent() {
const store = createStore();
function createStore({ initialState = {} }) {
return new Vuex.Store({
state: {
...initState(),
...initialState,
},
getters: {
pathNavigationData: () => [],
},
});
}
function createComponent({ initialState } = {}) {
return extendedWrapper(
shallowMount(Component, {
store,
shallowMount(BaseComponent, {
store: createStore({ initialState }),
propsData: {
noDataSvgPath,
noAccessSvgPath,
......@@ -26,13 +39,24 @@ function createComponent() {
);
}
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findPathNavigation = () => wrapper.findComponent(PathNavigation);
const findOverviewMetrics = () => wrapper.findByTestId('vsa-stage-overview-metrics');
const findStageTable = () => wrapper.findByTestId('vsa-stage-table');
const findEmptyStage = () => wrapper.findComponent(GlEmptyState);
const findStageEvents = () => wrapper.findByTestId('stage-table-events');
describe('Value stream analytics component', () => {
beforeEach(() => {
wrapper = createComponent();
wrapper = createComponent({
initialState: {
isLoading: false,
isLoadingStage: false,
isEmptyStage: false,
selectedStageEvents,
selectedStage,
},
});
});
afterEach(() => {
......@@ -51,4 +75,104 @@ describe('Value stream analytics component', () => {
it('renders the stage table', () => {
expect(findStageTable().exists()).toBe(true);
});
it('renders the stage table events', () => {
expect(findEmptyStage().exists()).toBe(false);
expect(findStageEvents().exists()).toBe(true);
});
it('does not render the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
describe('isLoading = true', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { isLoading: true },
});
});
it('renders the path navigation component with prop `loading` set to true', () => {
expect(findPathNavigation().exists()).toBe(true);
expect(findPathNavigation().props('loading')).toBe(true);
});
it('does not render the overview metrics', () => {
expect(findOverviewMetrics().exists()).toBe(false);
});
it('does not render the stage table', () => {
expect(findStageTable().exists()).toBe(false);
});
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);
expect(tableWrapper.find(GlLoadingIcon).exists()).toBe(true);
});
});
describe('isEmptyStage = true', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { selectedStage, isEmptyStage: true },
});
});
it('renders the empty stage with not enough data', () => {
const es = findEmptyStage();
expect(es.exists()).toBe(true);
expect(es.props('title')).toBe("We don't have enough data to show this stage.");
});
});
describe('without enough permissions', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { selectedStage: { ...selectedStage, isUserAllowed: false } },
});
});
it('renders the empty stage', () => {
const es = findEmptyStage();
expect(es.exists()).toBe(true);
expect(es.props('title')).toBe('You need permission.');
});
});
describe('without a selected stage', () => {
beforeEach(() => {
wrapper = createComponent({
initialState: { selectedStage: null, isEmptyStage: true },
});
});
it('renders the stage table', () => {
expect(findStageTable().exists()).toBe(true);
});
it('does not render the path navigation component', () => {
expect(findPathNavigation().exists()).toBe(false);
});
it('does not render the stage table events', () => {
expect(findStageEvents().exists()).toBe(false);
});
it('does not render the loading icon', () => {
expect(findLoadingIcon().exists()).toBe(false);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment