debian-mirror-gitlab/spec/frontend/monitoring/components/dashboard_spec.js

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

795 lines
25 KiB
JavaScript
Raw Normal View History

2020-03-13 15:44:24 +05:30
import MockAdapter from 'axios-mock-adapter';
2021-03-11 19:13:27 +05:30
import VueDraggable from 'vuedraggable';
2022-04-04 11:22:00 +05:30
import { nextTick } from 'vue';
2021-10-27 15:23:28 +05:30
import setWindowLocation from 'helpers/set_window_location_helper';
2020-10-24 23:57:45 +05:30
import { TEST_HOST } from 'helpers/test_constants';
2021-09-04 01:27:46 +05:30
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createFlash from '~/flash';
2021-03-11 19:13:27 +05:30
import axios from '~/lib/utils/axios_utils';
2020-10-24 23:57:45 +05:30
import { ESC_KEY } from '~/lib/utils/keys';
import { objectToQuery } from '~/lib/utils/url_utility';
2020-03-13 15:44:24 +05:30
import Dashboard from '~/monitoring/components/dashboard.vue';
2020-06-23 00:09:42 +05:30
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
2020-05-24 23:13:21 +05:30
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
2021-03-11 19:13:27 +05:30
import EmptyState from '~/monitoring/components/empty_state.vue';
2020-07-28 23:09:34 +05:30
import GraphGroup from '~/monitoring/components/graph_group.vue';
2021-03-11 19:13:27 +05:30
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
2020-06-23 00:09:42 +05:30
import LinksSection from '~/monitoring/components/links_section.vue';
2021-03-11 19:13:27 +05:30
import { dashboardEmptyStates, metricStates } from '~/monitoring/constants';
2020-03-13 15:44:24 +05:30
import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
2021-03-11 19:13:27 +05:30
import {
metricsDashboardViewModel,
metricsDashboardPanelCount,
dashboardProps,
} from '../fixture_data';
import { dashboardGitResponse, storeVariables } from '../mock_data';
2020-05-24 23:13:21 +05:30
import {
setupAllDashboards,
setupStoreWithDashboard,
setMetricResult,
setupStoreWithData,
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount,
2020-06-23 00:09:42 +05:30
setupStoreWithLinks,
2020-05-24 23:13:21 +05:30
} from '../store_utils';
jest.mock('~/flash');
2020-03-13 15:44:24 +05:30
describe('Dashboard', () => {
let store;
let wrapper;
let mock;
const createShallowWrapper = (props = {}, options = {}) => {
2021-09-04 01:27:46 +05:30
wrapper = shallowMountExtended(Dashboard, {
2020-07-28 23:09:34 +05:30
propsData: { ...dashboardProps, ...props },
2020-03-13 15:44:24 +05:30
store,
2020-06-23 00:09:42 +05:30
stubs: {
DashboardHeader,
},
2020-03-13 15:44:24 +05:30
...options,
});
};
const createMountedWrapper = (props = {}, options = {}) => {
2021-09-04 01:27:46 +05:30
wrapper = mountExtended(Dashboard, {
2020-07-28 23:09:34 +05:30
propsData: { ...dashboardProps, ...props },
2020-03-13 15:44:24 +05:30
store,
2020-06-23 00:09:42 +05:30
stubs: {
'graph-group': true,
'dashboard-panel': true,
'dashboard-header': DashboardHeader,
},
2020-03-13 15:44:24 +05:30
...options,
});
};
beforeEach(() => {
store = createStore();
mock = new MockAdapter(axios);
2020-05-24 23:13:21 +05:30
jest.spyOn(store, 'dispatch').mockResolvedValue();
2020-03-13 15:44:24 +05:30
});
afterEach(() => {
mock.restore();
2020-05-24 23:13:21 +05:30
if (store.dispatch.mockReset) {
store.dispatch.mockReset();
}
2022-08-13 15:12:31 +05:30
wrapper.destroy();
2020-03-13 15:44:24 +05:30
});
describe('request information to the server', () => {
2022-04-04 11:22:00 +05:30
it('calls to set time range and fetch data', async () => {
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true });
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
await nextTick();
expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange',
expect.any(Object),
);
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('shows up a loading state', async () => {
2020-07-28 23:09:34 +05:30
store.state.monitoringDashboard.emptyState = dashboardEmptyStates.LOADING;
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true });
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
await nextTick();
expect(wrapper.find(EmptyState).exists()).toBe(true);
expect(wrapper.find(EmptyState).props('selectedState')).toBe(dashboardEmptyStates.LOADING);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('hides the group panels when showPanels is false', async () => {
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true, showPanels: false });
2020-03-13 15:44:24 +05:30
2020-05-24 23:13:21 +05:30
setupStoreWithData(store);
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
await nextTick();
expect(wrapper.vm.emptyState).toBeNull();
expect(wrapper.findAll('.prometheus-panel')).toHaveLength(0);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('fetches the metrics data with proper time window', async () => {
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
await nextTick();
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange',
expect.objectContaining({ duration: { seconds: 28800 } }),
);
2020-03-13 15:44:24 +05:30
});
});
2020-07-28 23:09:34 +05:30
describe('panel containers layout', () => {
2021-03-08 18:12:59 +05:30
const findPanelLayoutWrapperAt = (index) => {
2020-07-28 23:09:34 +05:30
return wrapper
.find(GraphGroup)
.findAll('[data-testid="dashboard-panel-layout-wrapper"]')
.at(index);
};
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-07-28 23:09:34 +05:30
createMountedWrapper({ hasMetrics: true });
2022-04-04 11:22:00 +05:30
await nextTick();
2020-07-28 23:09:34 +05:30
});
describe('when the graph group has an even number of panels', () => {
2022-04-04 11:22:00 +05:30
it('2 panels - all panel wrappers take half width of their parent', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount(store, 2);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
2020-07-28 23:09:34 +05:30
});
2022-04-04 11:22:00 +05:30
it('4 panels - all panel wrappers take half width of their parent', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount(store, 4);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
2020-07-28 23:09:34 +05:30
});
});
describe('when the graph group has an odd number of panels', () => {
2022-04-04 11:22:00 +05:30
it('1 panel - panel wrapper does not take half width of its parent', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount(store, 1);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(false);
2020-07-28 23:09:34 +05:30
});
2022-04-04 11:22:00 +05:30
it('3 panels - all panels but last take half width of their parents', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount(store, 3);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(false);
2020-07-28 23:09:34 +05:30
});
2022-04-04 11:22:00 +05:30
it('5 panels - all panels but last take half width of their parents', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDataForPanelCount(store, 5);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
expect(findPanelLayoutWrapperAt(4).classes('col-lg-6')).toBe(false);
2020-07-28 23:09:34 +05:30
});
});
});
describe('dashboard validation warning', () => {
2022-04-04 11:22:00 +05:30
it('displays a warning if there are validation warnings', async () => {
2020-07-28 23:09:34 +05:30
createMountedWrapper({ hasMetrics: true });
store.commit(
`monitoringDashboard/${types.RECEIVE_DASHBOARD_VALIDATION_WARNINGS_SUCCESS}`,
true,
);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(createFlash).toHaveBeenCalled();
2020-07-28 23:09:34 +05:30
});
2022-04-04 11:22:00 +05:30
it('does not display a warning if there are no validation warnings', async () => {
2020-07-28 23:09:34 +05:30
createMountedWrapper({ hasMetrics: true });
store.commit(
`monitoringDashboard/${types.RECEIVE_DASHBOARD_VALIDATION_WARNINGS_SUCCESS}`,
false,
);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(createFlash).not.toHaveBeenCalled();
2020-07-28 23:09:34 +05:30
});
});
2020-05-24 23:13:21 +05:30
describe('when the URL contains a reference to a panel', () => {
2021-10-27 15:23:28 +05:30
const location = window.location.href;
2020-05-24 23:13:21 +05:30
2021-10-27 15:23:28 +05:30
const setSearch = (searchParams) => {
setWindowLocation(`?${objectToQuery(searchParams)}`);
2020-05-24 23:13:21 +05:30
};
afterEach(() => {
2021-10-27 15:23:28 +05:30
setWindowLocation(location);
2020-05-24 23:13:21 +05:30
});
2022-04-04 11:22:00 +05:30
it('when the URL points to a panel it expands', async () => {
2020-05-24 23:13:21 +05:30
const panelGroup = metricsDashboardViewModel.panelGroups[0];
const panel = panelGroup.panels[0];
2021-10-27 15:23:28 +05:30
setSearch({
group: panelGroup.group,
title: panel.title,
y_label: panel.y_label,
});
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setExpandedPanel', {
group: panelGroup.group,
panel: expect.objectContaining({
title: panel.title,
y_label: panel.y_label,
}),
2020-05-24 23:13:21 +05:30
});
});
2022-04-04 11:22:00 +05:30
it('when the URL does not link to any panel, no panel is expanded', async () => {
2021-10-27 15:23:28 +05:30
setSearch();
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(store.dispatch).not.toHaveBeenCalledWith(
'monitoringDashboard/setExpandedPanel',
expect.anything(),
);
2020-05-24 23:13:21 +05:30
});
2022-04-04 11:22:00 +05:30
it('when the URL points to an incorrect panel it shows an error', async () => {
2020-05-24 23:13:21 +05:30
const panelGroup = metricsDashboardViewModel.panelGroups[0];
const panel = panelGroup.panels[0];
2021-10-27 15:23:28 +05:30
setSearch({
group: panelGroup.group,
title: 'incorrect',
y_label: panel.y_label,
});
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(createFlash).toHaveBeenCalled();
expect(store.dispatch).not.toHaveBeenCalledWith(
'monitoringDashboard/setExpandedPanel',
expect.anything(),
);
2020-05-24 23:13:21 +05:30
});
});
describe('when the panel is expanded', () => {
let group;
let panel;
const expandPanel = (mockGroup, mockPanel) => {
store.commit(`monitoringDashboard/${types.SET_EXPANDED_PANEL}`, {
group: mockGroup,
panel: mockPanel,
});
};
beforeEach(() => {
setupStoreWithData(store);
const { panelGroups } = store.state.monitoringDashboard.dashboard;
group = panelGroups[0].group;
[panel] = panelGroups[0].panels;
jest.spyOn(window.history, 'pushState').mockImplementation();
});
afterEach(() => {
window.history.pushState.mockRestore();
});
2022-04-04 11:22:00 +05:30
it('URL is updated with panel parameters', async () => {
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
expandPanel(group, panel);
const expectedSearch = objectToQuery({
group,
title: panel.title,
y_label: panel.y_label,
});
2022-04-04 11:22:00 +05:30
await nextTick();
expect(window.history.pushState).toHaveBeenCalledTimes(1);
expect(window.history.pushState).toHaveBeenCalledWith(
expect.anything(), // state
expect.any(String), // document title
expect.stringContaining(`${expectedSearch}`),
);
2020-05-24 23:13:21 +05:30
});
2022-04-04 11:22:00 +05:30
it('URL is updated with panel parameters and custom dashboard', async () => {
2020-05-24 23:13:21 +05:30
const dashboard = 'dashboard.yml';
2020-06-23 00:09:42 +05:30
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard: dashboard,
});
createMountedWrapper({ hasMetrics: true });
2020-05-24 23:13:21 +05:30
expandPanel(group, panel);
const expectedSearch = objectToQuery({
dashboard,
group,
title: panel.title,
y_label: panel.y_label,
});
2022-04-04 11:22:00 +05:30
await nextTick();
expect(window.history.pushState).toHaveBeenCalledTimes(1);
expect(window.history.pushState).toHaveBeenCalledWith(
expect.anything(), // state
expect.any(String), // document title
expect.stringContaining(`${expectedSearch}`),
);
2020-05-24 23:13:21 +05:30
});
2022-04-04 11:22:00 +05:30
it('URL is updated with no parameters', async () => {
2020-05-24 23:13:21 +05:30
expandPanel(group, panel);
createMountedWrapper({ hasMetrics: true });
expandPanel(null, null);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(window.history.pushState).toHaveBeenCalledTimes(1);
expect(window.history.pushState).toHaveBeenCalledWith(
expect.anything(), // state
expect.any(String), // document title
expect.not.stringMatching(/group|title|y_label/), // no panel params
);
2020-05-24 23:13:21 +05:30
});
2020-07-28 23:09:34 +05:30
});
describe('when all panels in the first group are loading', () => {
2021-03-08 18:12:59 +05:30
const findGroupAt = (i) => wrapper.findAll(GraphGroup).at(i);
2020-07-28 23:09:34 +05:30
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithDashboard(store);
const { panels } = store.state.monitoringDashboard.dashboard.panelGroups[0];
panels.forEach(({ metrics }) => {
store.commit(`monitoringDashboard/${types.REQUEST_METRIC_RESULT}`, {
metricId: metrics[0].metricId,
});
});
createShallowWrapper();
2022-04-04 11:22:00 +05:30
await nextTick();
2020-07-28 23:09:34 +05:30
});
it('a loading icon appears in the first group', () => {
expect(findGroupAt(0).props('isLoading')).toBe(true);
});
it('a loading icon does not appear in the second group', () => {
expect(findGroupAt(1).props('isLoading')).toBe(false);
});
2020-05-24 23:13:21 +05:30
});
2021-12-11 22:18:48 +05:30
describe('when all requests have been committed by the store', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-06-23 00:09:42 +05:30
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentEnvironmentName: 'production',
2020-07-28 23:09:34 +05:30
currentDashboard: dashboardGitResponse[0].path,
projectPath: TEST_HOST,
2020-06-23 00:09:42 +05:30
});
2020-05-24 23:13:21 +05:30
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('it does not show loading icons in any group', async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
wrapper.findAll(GraphGroup).wrappers.forEach((groupWrapper) => {
expect(groupWrapper.props('isLoading')).toBe(false);
2020-07-28 23:09:34 +05:30
});
});
2020-04-08 14:13:33 +05:30
});
2020-05-24 23:13:21 +05:30
describe('variables section', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-03-13 15:44:24 +05:30
createShallowWrapper({ hasMetrics: true });
2020-05-24 23:13:21 +05:30
setupStoreWithData(store);
2020-07-28 23:09:34 +05:30
store.state.monitoringDashboard.variables = storeVariables;
2022-04-04 11:22:00 +05:30
await nextTick();
2020-05-24 23:13:21 +05:30
});
it('shows the variables section', () => {
expect(wrapper.vm.shouldShowVariablesSection).toBe(true);
});
});
2020-06-23 00:09:42 +05:30
describe('links section', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-06-23 00:09:42 +05:30
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
setupStoreWithLinks(store);
2022-04-04 11:22:00 +05:30
await nextTick();
2020-06-23 00:09:42 +05:30
});
it('shows the links section', () => {
expect(wrapper.vm.shouldShowLinksSection).toBe(true);
2021-12-11 22:18:48 +05:30
expect(wrapper.findComponent(LinksSection).exists()).toBe(true);
2020-06-23 00:09:42 +05:30
});
});
2020-05-24 23:13:21 +05:30
describe('single panel expands to "full screen" mode', () => {
const findExpandedPanel = () => wrapper.find({ ref: 'expandedPanel' });
2020-04-22 19:07:51 +05:30
2020-05-24 23:13:21 +05:30
describe('when the panel is not expanded', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
2020-05-24 23:13:21 +05:30
});
it('expanded panel is not visible', () => {
expect(findExpandedPanel().isVisible()).toBe(false);
});
it('can set a panel as expanded', () => {
const panel = wrapper.findAll(DashboardPanel).at(1);
jest.spyOn(store, 'dispatch');
panel.vm.$emit('expand');
const groupData = metricsDashboardViewModel.panelGroups[0];
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setExpandedPanel', {
group: groupData.group,
panel: expect.objectContaining({
id: groupData.panels[0].id,
}),
});
});
});
describe('when the panel is expanded', () => {
let group;
let panel;
2021-03-08 18:12:59 +05:30
const mockKeyup = (key) => window.dispatchEvent(new KeyboardEvent('keyup', { key }));
2020-05-24 23:13:21 +05:30
const MockPanel = {
2021-01-29 00:20:46 +05:30
template: `<div><slot name="top-left"/></div>`,
2020-05-24 23:13:21 +05:30
};
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true }, { stubs: { DashboardPanel: MockPanel } });
setupStoreWithData(store);
const { panelGroups } = store.state.monitoringDashboard.dashboard;
group = panelGroups[0].group;
[panel] = panelGroups[0].panels;
store.commit(`monitoringDashboard/${types.SET_EXPANDED_PANEL}`, {
group,
panel,
});
jest.spyOn(store, 'dispatch');
2022-04-04 11:22:00 +05:30
await nextTick();
2020-05-24 23:13:21 +05:30
});
2020-04-22 19:07:51 +05:30
2020-05-24 23:13:21 +05:30
it('displays a single panel and others are hidden', () => {
const panels = wrapper.findAll(MockPanel);
2021-03-08 18:12:59 +05:30
const visiblePanels = panels.filter((w) => w.isVisible());
2020-05-24 23:13:21 +05:30
expect(findExpandedPanel().isVisible()).toBe(true);
// v-show for hiding panels is more performant than v-if
// check for panels to be hidden.
expect(panels.length).toBe(metricsDashboardPanelCount + 1);
expect(visiblePanels.length).toBe(1);
});
it('sets a link to the expanded panel', () => {
const searchQuery =
'?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=System%20metrics%20(Kubernetes)&title=Memory%20Usage%20(Total)&y_label=Total%20Memory%20Used%20(GB)';
expect(findExpandedPanel().attributes('clipboard-text')).toEqual(
expect.stringContaining(searchQuery),
);
});
it('restores full dashboard by clicking `back`', () => {
wrapper.find({ ref: 'goBackBtn' }).vm.$emit('click');
expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/clearExpandedPanel',
undefined,
);
});
it('restores dashboard from full screen by typing the Escape key', () => {
mockKeyup(ESC_KEY);
expect(store.dispatch).toHaveBeenCalledWith(
`monitoringDashboard/clearExpandedPanel`,
undefined,
);
});
});
});
describe('when one of the metrics is missing', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true });
setupStoreWithDashboard(store);
setMetricResult({ store, result: [], panel: 2 });
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
});
it('shows a group empty area', () => {
const emptyGroup = wrapper.findAll({ ref: 'empty-group' });
expect(emptyGroup).toHaveLength(1);
expect(emptyGroup.is(GroupEmptyState)).toBe(true);
});
it('group empty area displays a NO_DATA state', () => {
2021-03-08 18:12:59 +05:30
expect(wrapper.findAll({ ref: 'empty-group' }).at(0).props('selectedState')).toEqual(
metricStates.NO_DATA,
);
2020-03-13 15:44:24 +05:30
});
});
describe('drag and drop function', () => {
const findDraggables = () => wrapper.findAll(VueDraggable);
2021-03-08 18:12:59 +05:30
const findEnabledDraggables = () => findDraggables().filter((f) => !f.attributes('disabled'));
2020-03-13 15:44:24 +05:30
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
2022-08-13 15:12:31 +05:30
const setup = async () => {
2020-05-24 23:13:21 +05:30
// call original dispatch
store.dispatch.mockRestore();
2020-03-13 15:44:24 +05:30
2020-05-24 23:13:21 +05:30
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
2022-08-13 15:12:31 +05:30
};
it('wraps vuedraggable', async () => {
await setup();
2020-03-13 15:44:24 +05:30
expect(findDraggablePanels().exists()).toBe(true);
2020-04-22 19:07:51 +05:30
expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
2020-03-13 15:44:24 +05:30
});
2022-08-13 15:12:31 +05:30
it('is disabled by default', async () => {
await setup();
2020-03-13 15:44:24 +05:30
expect(findRearrangeButton().exists()).toBe(false);
expect(findEnabledDraggables().length).toBe(0);
});
describe('when rearrange is enabled', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2022-08-13 15:12:31 +05:30
// call original dispatch
store.dispatch.mockRestore();
createShallowWrapper({ hasMetrics: true, rearrangePanelsAvailable: true });
setupStoreWithData(store);
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
});
it('displays rearrange button', () => {
expect(findRearrangeButton().exists()).toBe(true);
});
describe('when rearrange button is clicked', () => {
const findFirstDraggableRemoveButton = () =>
2021-03-08 18:12:59 +05:30
findDraggablePanels().at(0).find('.js-draggable-remove');
2020-03-13 15:44:24 +05:30
2022-08-13 15:12:31 +05:30
it('it enables draggables', async () => {
2020-03-13 15:44:24 +05:30
findRearrangeButton().vm.$emit('click');
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
expect(findRearrangeButton().attributes('pressed')).toBeTruthy();
2020-11-24 15:15:51 +05:30
expect(findEnabledDraggables().wrappers).toEqual(findDraggables().wrappers);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('metrics can be swapped', async () => {
2022-08-13 15:12:31 +05:30
findRearrangeButton().vm.$emit('click');
await nextTick();
2020-03-13 15:44:24 +05:30
const firstDraggable = findDraggables().at(0);
2020-04-08 14:13:33 +05:30
const mockMetrics = [...metricsDashboardViewModel.panelGroups[0].panels];
2020-03-13 15:44:24 +05:30
const firstTitle = mockMetrics[0].title;
const secondTitle = mockMetrics[1].title;
// swap two elements and `input` them
[mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
firstDraggable.vm.$emit('input', mockMetrics);
2022-04-04 11:22:00 +05:30
await nextTick();
2022-08-13 15:12:31 +05:30
2022-04-04 11:22:00 +05:30
const { panels } = wrapper.vm.dashboard.panelGroups[0];
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
expect(panels[1].title).toEqual(firstTitle);
expect(panels[0].title).toEqual(secondTitle);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('shows a remove button, which removes a panel', async () => {
2022-08-13 15:12:31 +05:30
findRearrangeButton().vm.$emit('click');
await nextTick();
2021-03-08 18:12:59 +05:30
expect(findFirstDraggableRemoveButton().find('a').exists()).toBe(true);
2020-03-13 15:44:24 +05:30
2020-04-22 19:07:51 +05:30
expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
2022-08-13 15:12:31 +05:30
await findFirstDraggableRemoveButton().trigger('click');
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount - 1);
2020-03-13 15:44:24 +05:30
});
2022-04-04 11:22:00 +05:30
it('it disables draggables when clicked again', async () => {
2022-08-13 15:12:31 +05:30
findRearrangeButton().vm.$emit('click');
await nextTick();
2020-03-13 15:44:24 +05:30
findRearrangeButton().vm.$emit('click');
2022-04-04 11:22:00 +05:30
await nextTick();
expect(findRearrangeButton().attributes('pressed')).toBeFalsy();
expect(findEnabledDraggables().length).toBe(0);
2020-03-13 15:44:24 +05:30
});
});
});
});
describe('cluster health', () => {
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-03-13 15:44:24 +05:30
createShallowWrapper({ hasMetrics: true, showHeader: false });
// all_dashboards is not defined in health dashboards
2020-05-24 23:13:21 +05:30
store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined);
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
});
it('hides dashboard header by default', () => {
expect(wrapper.find({ ref: 'prometheusGraphsHeader' }).exists()).toEqual(false);
});
it('renders correctly', () => {
2020-11-24 15:15:51 +05:30
expect(wrapper.html()).not.toBe('');
2020-03-13 15:44:24 +05:30
});
});
2020-06-23 00:09:42 +05:30
describe('document title', () => {
const originalTitle = 'Original Title';
2020-10-24 23:57:45 +05:30
const overviewDashboardName = dashboardGitResponse[0].display_name;
2020-06-23 00:09:42 +05:30
beforeEach(() => {
document.title = originalTitle;
createShallowWrapper({ hasMetrics: true });
});
afterAll(() => {
document.title = '';
});
2022-04-04 11:22:00 +05:30
it('is prepended with the overview dashboard name by default', async () => {
2020-06-23 00:09:42 +05:30
setupAllDashboards(store);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
2020-06-23 00:09:42 +05:30
});
2022-04-04 11:22:00 +05:30
it('is prepended with dashboard name if path is known', async () => {
2020-06-23 00:09:42 +05:30
const dashboard = dashboardGitResponse[1];
const currentDashboard = dashboard.path;
setupAllDashboards(store, currentDashboard);
2022-04-04 11:22:00 +05:30
await nextTick();
expect(document.title.startsWith(`${dashboard.display_name} · `)).toBe(true);
2020-06-23 00:09:42 +05:30
});
2022-04-04 11:22:00 +05:30
it('is prepended with the overview dashboard name if path is not known', async () => {
2020-06-23 00:09:42 +05:30
setupAllDashboards(store, 'unknown/path');
2022-04-04 11:22:00 +05:30
await nextTick();
expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
2020-06-23 00:09:42 +05:30
});
2022-04-04 11:22:00 +05:30
it('is not modified when dashboard name is not provided', async () => {
2020-06-23 00:09:42 +05:30
const dashboard = { ...dashboardGitResponse[1], display_name: null };
const currentDashboard = dashboard.path;
store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, [dashboard]);
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard,
});
2022-04-04 11:22:00 +05:30
await nextTick();
expect(document.title).toBe(originalTitle);
2020-06-23 00:09:42 +05:30
});
});
2020-03-13 15:44:24 +05:30
describe('Clipboard text in panels', () => {
2020-05-24 23:13:21 +05:30
const currentDashboard = dashboardGitResponse[1].path;
const panelIndex = 1; // skip expanded panel
2020-03-13 15:44:24 +05:30
2020-05-24 23:13:21 +05:30
const getClipboardTextFirstPanel = () =>
2021-03-08 18:12:59 +05:30
wrapper.findAll(DashboardPanel).at(panelIndex).props('clipboardText');
2020-03-13 15:44:24 +05:30
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-05-24 23:13:21 +05:30
setupStoreWithData(store);
2020-06-23 00:09:42 +05:30
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard,
});
createShallowWrapper({ hasMetrics: true });
2022-04-04 11:22:00 +05:30
await nextTick();
2020-03-13 15:44:24 +05:30
});
it('contains a link to the dashboard', () => {
2020-05-24 23:13:21 +05:30
const dashboardParam = `dashboard=${encodeURIComponent(currentDashboard)}`;
2020-03-13 15:44:24 +05:30
2020-05-24 23:13:21 +05:30
expect(getClipboardTextFirstPanel()).toContain(dashboardParam);
expect(getClipboardTextFirstPanel()).toContain(`group=`);
expect(getClipboardTextFirstPanel()).toContain(`title=`);
expect(getClipboardTextFirstPanel()).toContain(`y_label=`);
2020-03-13 15:44:24 +05:30
});
});
2020-04-22 19:07:51 +05:30
2020-07-28 23:09:34 +05:30
describe('keyboard shortcuts', () => {
const currentDashboard = dashboardGitResponse[1].path;
const panelRef = 'dashboard-panel-response-metrics-aws-elb-4-1'; // skip expanded panel
// While the recommendation in the documentation is to test
// with a data-testid attribute, I want to make sure that
// the dashboard panels have a ref attribute set.
const getDashboardPanel = () => wrapper.find({ ref: panelRef });
2022-04-04 11:22:00 +05:30
beforeEach(async () => {
2020-07-28 23:09:34 +05:30
setupStoreWithData(store);
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard,
});
createShallowWrapper({ hasMetrics: true });
2022-03-02 08:16:31 +05:30
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2020-07-28 23:09:34 +05:30
wrapper.setData({ hoveredPanel: panelRef });
2022-04-04 11:22:00 +05:30
await nextTick();
2020-07-28 23:09:34 +05:30
});
it('contains a ref attribute inside a DashboardPanel component', () => {
const dashboardPanel = getDashboardPanel();
expect(dashboardPanel.exists()).toBe(true);
});
});
2020-03-13 15:44:24 +05:30
});