summaryrefslogtreecommitdiff
path: root/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/monitoring/components/dashboard_panel_builder_spec.js')
-rw-r--r--spec/frontend/monitoring/components/dashboard_panel_builder_spec.js234
1 files changed, 234 insertions, 0 deletions
diff --git a/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js b/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
new file mode 100644
index 00000000000..587ddd23d3f
--- /dev/null
+++ b/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
@@ -0,0 +1,234 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlCard, GlForm, GlFormTextarea, GlAlert } from '@gitlab/ui';
+import { createStore } from '~/monitoring/stores';
+import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
+import * as types from '~/monitoring/stores/mutation_types';
+import { metricsDashboardResponse } from '../fixture_data';
+import { mockTimeRange } from '../mock_data';
+
+import DashboardPanelBuilder from '~/monitoring/components/dashboard_panel_builder.vue';
+import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
+
+const mockPanel = metricsDashboardResponse.dashboard.panel_groups[0].panels[0];
+
+describe('dashboard invalid url parameters', () => {
+ let store;
+ let wrapper;
+ let mockShowToast;
+
+ const createComponent = (props = {}, options = {}) => {
+ wrapper = shallowMount(DashboardPanelBuilder, {
+ propsData: { ...props },
+ store,
+ stubs: {
+ GlCard,
+ },
+ mocks: {
+ $toast: {
+ show: mockShowToast,
+ },
+ },
+ options,
+ });
+ };
+
+ const findForm = () => wrapper.find(GlForm);
+ const findTxtArea = () => findForm().find(GlFormTextarea);
+ const findSubmitBtn = () => findForm().find('[type="submit"]');
+ const findClipboardCopyBtn = () => wrapper.find({ ref: 'clipboardCopyBtn' });
+ const findViewDocumentationBtn = () => wrapper.find({ ref: 'viewDocumentationBtn' });
+ const findOpenRepositoryBtn = () => wrapper.find({ ref: 'openRepositoryBtn' });
+ const findPanel = () => wrapper.find(DashboardPanel);
+ const findTimeRangePicker = () => wrapper.find(DateTimePicker);
+ const findRefreshButton = () => wrapper.find('[data-testid="previewRefreshButton"]');
+
+ beforeEach(() => {
+ mockShowToast = jest.fn();
+ store = createStore();
+ createComponent();
+ jest.spyOn(store, 'dispatch').mockResolvedValue();
+ });
+
+ afterEach(() => {});
+
+ it('is mounted', () => {
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ it('displays an empty dashboard panel', () => {
+ expect(findPanel().exists()).toBe(true);
+ expect(findPanel().props('graphData')).toBe(null);
+ });
+
+ it('does not fetch initial data by default', () => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+
+ describe('yml form', () => {
+ it('form exists and can be submitted', () => {
+ expect(findForm().exists()).toBe(true);
+ expect(findSubmitBtn().exists()).toBe(true);
+ expect(findSubmitBtn().is('[disabled]')).toBe(false);
+ });
+
+ it('form has a text area with a default value', () => {
+ expect(findTxtArea().exists()).toBe(true);
+
+ const value = findTxtArea().attributes('value');
+
+ // Panel definition should contain a title and a type
+ expect(value).toContain('title:');
+ expect(value).toContain('type:');
+ });
+
+ it('"copy to clipboard" button works', () => {
+ findClipboardCopyBtn().vm.$emit('click');
+ const clipboardText = findClipboardCopyBtn().attributes('data-clipboard-text');
+
+ expect(clipboardText).toContain('title:');
+ expect(clipboardText).toContain('type:');
+
+ expect(mockShowToast).toHaveBeenCalledTimes(1);
+ });
+
+ it('on submit fetches a panel preview', () => {
+ findForm().vm.$emit('submit', new Event('submit'));
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/fetchPanelPreview',
+ expect.stringContaining('title:'),
+ );
+ });
+ });
+
+ describe('when form is submitted', () => {
+ beforeEach(() => {
+ store.commit(`monitoringDashboard/${types.REQUEST_PANEL_PREVIEW}`, 'mock yml content');
+ return wrapper.vm.$nextTick();
+ });
+
+ it('submit button is disabled', () => {
+ expect(findSubmitBtn().is('[disabled]')).toBe(true);
+ });
+ });
+ });
+
+ describe('time range picker', () => {
+ it('is visible by default', () => {
+ expect(findTimeRangePicker().exists()).toBe(true);
+ });
+
+ it('when changed does not trigger data fetch unless preview panel button is clicked', () => {
+ // mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
+ store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+
+ it('when changed triggers data fetch if preview panel button is clicked', () => {
+ findForm().vm.$emit('submit', new Event('submit'));
+
+ store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(store.dispatch).toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('refresh', () => {
+ it('is visible by default', () => {
+ expect(findRefreshButton().exists()).toBe(true);
+ });
+
+ it('when clicked does not trigger data fetch unless preview panel button is clicked', () => {
+ // mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
+ store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+
+ it('when clicked triggers data fetch if preview panel button is clicked', () => {
+ // mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true
+ store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, true);
+
+ findRefreshButton().vm.$emit('click');
+
+ return wrapper.vm.$nextTick(() => {
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/fetchPanelPreviewMetrics',
+ undefined,
+ );
+ });
+ });
+ });
+
+ describe('instructions card', () => {
+ const mockDocsPath = '/docs-path';
+ const mockProjectPath = '/project-path';
+
+ beforeEach(() => {
+ store.state.monitoringDashboard.addDashboardDocumentationPath = mockDocsPath;
+ store.state.monitoringDashboard.projectPath = mockProjectPath;
+
+ createComponent();
+ });
+
+ it('displays next actions for the user', () => {
+ expect(findViewDocumentationBtn().exists()).toBe(true);
+ expect(findViewDocumentationBtn().attributes('href')).toBe(mockDocsPath);
+
+ expect(findOpenRepositoryBtn().exists()).toBe(true);
+ expect(findOpenRepositoryBtn().attributes('href')).toBe(mockProjectPath);
+ });
+ });
+
+ describe('when there is an error', () => {
+ const mockError = 'an error ocurred!';
+
+ beforeEach(() => {
+ store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_FAILURE}`, mockError);
+ return wrapper.vm.$nextTick();
+ });
+
+ it('displays an alert', () => {
+ expect(wrapper.find(GlAlert).exists()).toBe(true);
+ expect(wrapper.find(GlAlert).text()).toBe(mockError);
+ });
+
+ it('displays an empty dashboard panel', () => {
+ expect(findPanel().props('graphData')).toBe(null);
+ });
+
+ it('changing time range should not refetch data', () => {
+ store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when panel data is available', () => {
+ beforeEach(() => {
+ store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_SUCCESS}`, mockPanel);
+ return wrapper.vm.$nextTick();
+ });
+
+ it('displays no alert', () => {
+ expect(wrapper.find(GlAlert).exists()).toBe(false);
+ });
+
+ it('displays panel with data', () => {
+ const { title, type } = wrapper.find(DashboardPanel).props('graphData');
+
+ expect(title).toBe(mockPanel.title);
+ expect(type).toBe(mockPanel.type);
+ });
+ });
+});