Commit 37805a8d authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '217758-add-empty-state-tests' into 'master'

Add constants for empty dashboard states

Closes #217758

See merge request gitlab-org/gitlab!36405
parents edc2761f 2125551c
<script>
import { GlEmptyState } from '@gitlab/ui';
import { __ } from '~/locale';
import { dashboardEmptyStates } from '../constants';
export default {
components: {
......@@ -54,7 +55,7 @@ export default {
data() {
return {
states: {
gettingStarted: {
[dashboardEmptyStates.GETTING_STARTED]: {
svgUrl: this.emptyGettingStartedSvgPath,
title: __('Get started with performance monitoring'),
description: __(`Stay updated about the performance and health
......@@ -64,7 +65,7 @@ export default {
secondaryButtonText: __('Configure existing installation'),
secondaryButtonPath: this.settingsPath,
},
loading: {
[dashboardEmptyStates.LOADING]: {
svgUrl: this.emptyLoadingSvgPath,
title: __('Waiting for performance data'),
description: __(`Creating graphs uses the data from the Prometheus server.
......@@ -74,7 +75,7 @@ export default {
secondaryButtonText: '',
secondaryButtonPath: '',
},
noData: {
[dashboardEmptyStates.NO_DATA]: {
svgUrl: this.emptyNoDataSvgPath,
title: __('No data found'),
description: __(`You are connected to the Prometheus server, but there is currently
......@@ -84,7 +85,7 @@ export default {
secondaryButtonText: '',
secondaryButtonPath: '',
},
unableToConnect: {
[dashboardEmptyStates.UNABLE_TO_CONNECT]: {
svgUrl: this.emptyUnableToConnectSvgPath,
title: __('Unable to connect to Prometheus server'),
description: __(
......
export const PROMETHEUS_TIMEOUT = 120000; // TWO_MINUTES
export const dashboardEmptyStates = {
GETTING_STARTED: 'gettingStarted',
LOADING: 'loading',
NO_DATA: 'noData',
UNABLE_TO_CONNECT: 'unableToConnect',
};
/**
* States and error states in Prometheus Queries (PromQL) for metrics
*/
......
......@@ -4,7 +4,7 @@ import * as types from './mutation_types';
import { mapToDashboardViewModel, normalizeQueryResponseData } from './utils';
import httpStatusCodes from '~/lib/utils/http_status';
import { BACKOFF_TIMEOUT } from '../../lib/utils/common_utils';
import { endpointKeys, initialStateKeys, metricStates } from '../constants';
import { dashboardEmptyStates, endpointKeys, initialStateKeys, metricStates } from '../constants';
import { optionsFromSeriesData } from './variable_mapping';
/**
......@@ -58,7 +58,7 @@ export default {
* Dashboard panels structure and global state
*/
[types.REQUEST_METRICS_DASHBOARD](state) {
state.emptyState = 'loading';
state.emptyState = dashboardEmptyStates.LOADING;
state.showEmptyState = true;
},
[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, dashboardYML) {
......@@ -71,11 +71,13 @@ export default {
state.links = links;
if (!state.dashboard.panelGroups.length) {
state.emptyState = 'noData';
state.emptyState = dashboardEmptyStates.NO_DATA;
}
},
[types.RECEIVE_METRICS_DASHBOARD_FAILURE](state, error) {
state.emptyState = error ? 'unableToConnect' : 'noData';
state.emptyState = error
? dashboardEmptyStates.UNABLE_TO_CONNECT
: dashboardEmptyStates.NO_DATA;
state.showEmptyState = true;
},
......@@ -151,6 +153,8 @@ export default {
metric.loading = false;
state.showEmptyState = false;
state.emptyState = null;
if (!data.result || data.result.length === 0) {
metric.state = metricStates.NO_DATA;
metric.result = null;
......@@ -180,11 +184,12 @@ export default {
state.timeRange = timeRange;
},
[types.SET_GETTING_STARTED_EMPTY_STATE](state) {
state.emptyState = 'gettingStarted';
state.showEmptyState = true;
state.emptyState = dashboardEmptyStates.GETTING_STARTED;
},
[types.SET_NO_DATA_EMPTY_STATE](state) {
state.showEmptyState = true;
state.emptyState = 'noData';
state.emptyState = dashboardEmptyStates.NO_DATA;
},
[types.SET_ALL_DASHBOARDS](state, dashboards) {
state.allDashboards = dashboards || [];
......
import invalidUrl from '~/lib/utils/invalid_url';
import { timezones } from '../format_date';
import { dashboardEmptyStates } from '../constants';
export default () => ({
// API endpoints
......@@ -20,7 +21,7 @@ export default () => ({
// Dashboard data
hasDashboardValidationWarnings: false,
emptyState: 'gettingStarted',
emptyState: dashboardEmptyStates.GETTING_STARTED,
showEmptyState: true,
showErrorBanner: true,
isUpdatingStarredValue: false,
......
......@@ -24,6 +24,18 @@ exports[`EmptyState shows loading state 1`] = `
/>
`;
exports[`EmptyState shows noData state 1`] = `
<gl-empty-state-stub
description="You are connected to the Prometheus server, but there is currently no data to display."
primarybuttonlink="/settingsPath"
primarybuttontext="Configure Prometheus"
secondarybuttonlink=""
secondarybuttontext=""
svgpath="/path/to/no-data.svg"
title="No data found"
/>
`;
exports[`EmptyState shows unableToConnect state 1`] = `
<gl-empty-state-stub
description="Ensure connectivity is available from the GitLab server to the Prometheus server"
......
......@@ -6,7 +6,7 @@ import { objectToQuery } from '~/lib/utils/url_utility';
import VueDraggable from 'vuedraggable';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { metricStates } from '~/monitoring/constants';
import { dashboardEmptyStates, metricStates } from '~/monitoring/constants';
import Dashboard from '~/monitoring/components/dashboard.vue';
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
......@@ -126,13 +126,13 @@ describe('Dashboard', () => {
});
it('shows up a loading state', () => {
store.state.monitoringDashboard.emptyState = 'loading';
store.state.monitoringDashboard.emptyState = dashboardEmptyStates.LOADING;
createShallowWrapper({ hasMetrics: true });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(EmptyState).exists()).toBe(true);
expect(wrapper.find(EmptyState).props('selectedState')).toBe('loading');
expect(wrapper.find(EmptyState).props('selectedState')).toBe(dashboardEmptyStates.LOADING);
});
});
......
import { shallowMount } from '@vue/test-utils';
import { dashboardEmptyStates } from '~/monitoring/constants';
import EmptyState from '~/monitoring/components/empty_state.vue';
function createComponent(props) {
......@@ -20,7 +21,7 @@ function createComponent(props) {
describe('EmptyState', () => {
it('shows gettingStarted state', () => {
const wrapper = createComponent({
selectedState: 'gettingStarted',
selectedState: dashboardEmptyStates.GETTING_STARTED,
});
expect(wrapper.element).toMatchSnapshot();
......@@ -28,7 +29,7 @@ describe('EmptyState', () => {
it('shows loading state', () => {
const wrapper = createComponent({
selectedState: 'loading',
selectedState: dashboardEmptyStates.LOADING,
});
expect(wrapper.element).toMatchSnapshot();
......@@ -36,7 +37,15 @@ describe('EmptyState', () => {
it('shows unableToConnect state', () => {
const wrapper = createComponent({
selectedState: 'unableToConnect',
selectedState: dashboardEmptyStates.UNABLE_TO_CONNECT,
});
expect(wrapper.element).toMatchSnapshot();
});
it('shows noData state', () => {
const wrapper = createComponent({
selectedState: dashboardEmptyStates.NO_DATA,
});
expect(wrapper.element).toMatchSnapshot();
......
......@@ -3,7 +3,7 @@ import httpStatusCodes from '~/lib/utils/http_status';
import mutations from '~/monitoring/stores/mutations';
import * as types from '~/monitoring/stores/mutation_types';
import state from '~/monitoring/stores/state';
import { metricStates } from '~/monitoring/constants';
import { dashboardEmptyStates, metricStates } from '~/monitoring/constants';
import { deploymentData, dashboardGitResponse, storeTextVariables } from '../mock_data';
import { metricsDashboardPayload } from '../fixture_data';
......@@ -15,6 +15,15 @@ describe('Monitoring mutations', () => {
stateCopy = state();
});
describe('REQUEST_METRICS_DASHBOARD', () => {
it('sets an empty loading state', () => {
mutations[types.REQUEST_METRICS_DASHBOARD](stateCopy);
expect(stateCopy.emptyState).toBe(dashboardEmptyStates.LOADING);
expect(stateCopy.showEmptyState).toBe(true);
});
});
describe('RECEIVE_METRICS_DASHBOARD_SUCCESS', () => {
let payload;
const getGroups = () => stateCopy.dashboard.panelGroups;
......@@ -23,6 +32,18 @@ describe('Monitoring mutations', () => {
stateCopy.dashboard.panelGroups = [];
payload = metricsDashboardPayload;
});
it('sets an empty noData state when the dashboard is empty', () => {
const emptyDashboardPayload = {
...payload,
panel_groups: [],
};
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](stateCopy, emptyDashboardPayload);
const groups = getGroups();
expect(groups).toEqual([]);
expect(stateCopy.emptyState).toBe(dashboardEmptyStates.NO_DATA);
});
it('adds a key to the group', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](stateCopy, payload);
const groups = getGroups();
......@@ -72,6 +93,22 @@ describe('Monitoring mutations', () => {
});
});
describe('RECEIVE_METRICS_DASHBOARD_FAILURE', () => {
it('sets an empty noData state when an empty error occurs', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_FAILURE](stateCopy);
expect(stateCopy.emptyState).toBe(dashboardEmptyStates.NO_DATA);
expect(stateCopy.showEmptyState).toBe(true);
});
it('sets an empty unableToConnect state when an error occurs', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_FAILURE](stateCopy, 'myerror');
expect(stateCopy.emptyState).toBe(dashboardEmptyStates.UNABLE_TO_CONNECT);
expect(stateCopy.showEmptyState).toBe(true);
});
});
describe('Dashboard starring mutations', () => {
it('REQUEST_DASHBOARD_STARRING', () => {
stateCopy = { isUpdatingStarredValue: false };
......@@ -283,6 +320,7 @@ describe('Monitoring mutations', () => {
});
expect(stateCopy.showEmptyState).toBe(false);
expect(stateCopy.emptyState).toBe(null);
});
it('adds results to the store', () => {
......
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