diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-20 09:24:38 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-20 09:24:38 +0000 |
commit | 898e2cc1dfa88b4ac39cb4b35011f61b37f57b51 (patch) | |
tree | c6524edb6c9a43cccf93be05c36883fde1a53ee4 /spec/frontend | |
parent | b5571e6e22cdacc81f78eff5943d68c8ba220fbb (diff) | |
download | gitlab-ce-898e2cc1dfa88b4ac39cb4b35011f61b37f57b51.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
6 files changed, 904 insertions, 0 deletions
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js new file mode 100644 index 00000000000..8a10857d0ff --- /dev/null +++ b/spec/frontend/monitoring/components/dashboard_spec.js @@ -0,0 +1,573 @@ +import { shallowMount, createLocalVue, mount } from '@vue/test-utils'; +import { GlDropdownItem, GlButton, GlToast } from '@gitlab/ui'; +import VueDraggable from 'vuedraggable'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import statusCodes from '~/lib/utils/http_status'; +import { metricStates } from '~/monitoring/constants'; +import Dashboard from '~/monitoring/components/dashboard.vue'; +import DateTimePicker from '~/monitoring/components/date_time_picker/date_time_picker.vue'; +import GroupEmptyState from '~/monitoring/components/group_empty_state.vue'; +import { createStore } from '~/monitoring/stores'; +import * as types from '~/monitoring/stores/mutation_types'; +import * as monitoringUtils from '~/monitoring/utils'; +import { setupComponentStore, propsData } from '../init_utils'; +import { + metricsGroupsAPIResponse, + mockedQueryResultPayload, + mockApiEndpoint, + environmentData, + dashboardGitResponse, +} from '../mock_data'; + +const localVue = createLocalVue(); +const expectedPanelCount = 2; + +describe('Dashboard', () => { + let DashboardComponent; + let store; + let wrapper; + let mock; + + const createShallowWrapper = (props = {}, options = {}) => { + wrapper = shallowMount(localVue.extend(DashboardComponent), { + localVue, + sync: false, + propsData: { ...propsData, ...props }, + store, + ...options, + }); + }; + + const createMountedWrapper = (props = {}, options = {}) => { + wrapper = mount(localVue.extend(DashboardComponent), { + localVue, + sync: false, + propsData: { ...propsData, ...props }, + store, + ...options, + }); + }; + + beforeEach(() => { + store = createStore(); + DashboardComponent = localVue.extend(Dashboard); + mock = new MockAdapter(axios); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + mock.restore(); + }); + + describe('no metrics are available yet', () => { + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + + createShallowWrapper({}, { attachToDocument: true }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('shows the environment selector', () => { + expect(wrapper.vm.$el.querySelector('.js-environments-dropdown')).toBeTruthy(); + }); + }); + + describe('no data found', () => { + beforeEach(done => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + + createShallowWrapper({}, { attachToDocument: true }); + + wrapper.vm.$nextTick(done); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('shows the environment selector dropdown', () => { + expect(wrapper.vm.$el.querySelector('.js-environments-dropdown')).toBeTruthy(); + }); + }); + + describe('request information to the server', () => { + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + }); + + it('shows up a loading state', done => { + createShallowWrapper({ hasMetrics: true }, { attachToDocument: true }); + + wrapper.vm + .$nextTick() + .then(() => { + expect(wrapper.vm.emptyState).toEqual('loading'); + + done(); + }) + .catch(done.fail); + }); + + it('hides the group panels when showPanels is false', done => { + createMountedWrapper( + { hasMetrics: true, showPanels: false }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + setupComponentStore(wrapper); + + wrapper.vm + .$nextTick() + .then(() => { + expect(wrapper.vm.showEmptyState).toEqual(false); + expect(wrapper.vm.$el.querySelector('.prometheus-panel')).toEqual(null); + // TODO: The last expectation doesn't belong here, it belongs in a `group_group_spec.js` file + // Issue: https://gitlab.com/gitlab-org/gitlab/issues/118780 + // expect(wrapper.vm.$el.querySelector('.prometheus-graph-group')).toBeTruthy(); + + done(); + }) + .catch(done.fail); + }); + + it('fetches the metrics data with proper time window', done => { + const getTimeDiffSpy = jest.spyOn(monitoringUtils, 'getTimeDiff'); + jest.spyOn(store, 'dispatch'); + + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, + environmentData, + ); + + wrapper.vm + .$nextTick() + .then(() => { + expect(store.dispatch).toHaveBeenCalled(); + expect(getTimeDiffSpy).toHaveBeenCalled(); + + done(); + }) + .catch(done.fail); + }); + }); + + describe('when all requests have been commited by the store', () => { + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + setupComponentStore(wrapper); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders the environments dropdown with a number of environments', done => { + wrapper.vm + .$nextTick() + .then(() => { + const environmentDropdownItems = wrapper + .find('.js-environments-dropdown') + .findAll(GlDropdownItem); + + expect(wrapper.vm.environments.length).toEqual(environmentData.length); + expect(environmentDropdownItems.length).toEqual(wrapper.vm.environments.length); + + environmentDropdownItems.wrappers.forEach((itemWrapper, index) => { + const anchorEl = itemWrapper.find('a'); + if (anchorEl.exists() && environmentData[index].metrics_path) { + const href = anchorEl.attributes('href'); + expect(href).toBe(environmentData[index].metrics_path); + } + }); + + done(); + }) + .catch(done.fail); + }); + + it('renders the environments dropdown with a single active element', done => { + wrapper.vm + .$nextTick() + .then(() => { + const environmentDropdownItems = wrapper + .find('.js-environments-dropdown') + .findAll(GlDropdownItem); + const activeItem = environmentDropdownItems.wrappers.filter(itemWrapper => + itemWrapper.find('.active').exists(), + ); + + expect(activeItem.length).toBe(1); + done(); + }) + .catch(done.fail); + }); + }); + + it('hides the environments dropdown list when there is no environments', done => { + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, + metricsGroupsAPIResponse, + ); + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, + mockedQueryResultPayload, + ); + + wrapper.vm + .$nextTick() + .then(() => { + const environmentDropdownItems = wrapper + .find('.js-environments-dropdown') + .findAll(GlDropdownItem); + + expect(environmentDropdownItems.length).toEqual(0); + done(); + }) + .catch(done.fail); + }); + + it('renders the datetimepicker dropdown', done => { + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + setupComponentStore(wrapper); + + wrapper.vm + .$nextTick() + .then(() => { + expect(wrapper.find(DateTimePicker).exists()).toBe(true); + done(); + }) + .catch(done.fail); + }); + + describe('when one of the metrics is missing', () => { + beforeEach(done => { + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + + createShallowWrapper({ hasMetrics: true }, { attachToDocument: true }); + setupComponentStore(wrapper); + + wrapper.vm.$nextTick(done); + }); + + 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', () => { + expect( + wrapper + .findAll({ ref: 'empty-group' }) + .at(0) + .props('selectedState'), + ).toEqual(metricStates.NO_DATA); + }); + }); + + describe('drag and drop function', () => { + const findDraggables = () => wrapper.findAll(VueDraggable); + const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled')); + const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel'); + const findRearrangeButton = () => wrapper.find('.js-rearrange-button'); + + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + }); + + beforeEach(done => { + createShallowWrapper({ hasMetrics: true }, { attachToDocument: true }); + + setupComponentStore(wrapper); + + wrapper.vm.$nextTick(done); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('wraps vuedraggable', () => { + expect(findDraggablePanels().exists()).toBe(true); + expect(findDraggablePanels().length).toEqual(expectedPanelCount); + }); + + it('is disabled by default', () => { + expect(findRearrangeButton().exists()).toBe(false); + expect(findEnabledDraggables().length).toBe(0); + }); + + describe('when rearrange is enabled', () => { + beforeEach(done => { + wrapper.setProps({ rearrangePanelsAvailable: true }); + wrapper.vm.$nextTick(done); + }); + + it('displays rearrange button', () => { + expect(findRearrangeButton().exists()).toBe(true); + }); + + describe('when rearrange button is clicked', () => { + const findFirstDraggableRemoveButton = () => + findDraggablePanels() + .at(0) + .find('.js-draggable-remove'); + + beforeEach(done => { + findRearrangeButton().vm.$emit('click'); + wrapper.vm.$nextTick(done); + }); + + it('it enables draggables', () => { + expect(findRearrangeButton().attributes('pressed')).toBeTruthy(); + expect(findEnabledDraggables()).toEqual(findDraggables()); + }); + + it('metrics can be swapped', done => { + const firstDraggable = findDraggables().at(0); + const mockMetrics = [...metricsGroupsAPIResponse[1].panels]; + + 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); + + wrapper.vm.$nextTick(() => { + const { panels } = wrapper.vm.dashboard.panel_groups[1]; + + expect(panels[1].title).toEqual(firstTitle); + expect(panels[0].title).toEqual(secondTitle); + done(); + }); + }); + + it('shows a remove button, which removes a panel', done => { + expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false); + + expect(findDraggablePanels().length).toEqual(expectedPanelCount); + findFirstDraggableRemoveButton().trigger('click'); + + wrapper.vm.$nextTick(() => { + expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1); + done(); + }); + }); + + it('it disables draggables when clicked again', done => { + findRearrangeButton().vm.$emit('click'); + wrapper.vm.$nextTick(() => { + expect(findRearrangeButton().attributes('pressed')).toBeFalsy(); + expect(findEnabledDraggables().length).toBe(0); + done(); + }); + }); + }); + }); + }); + + describe('cluster health', () => { + beforeEach(done => { + mock.onGet(propsData.metricsEndpoint).reply(statusCodes.OK, JSON.stringify({})); + createShallowWrapper({ hasMetrics: true }); + + // all_dashboards is not defined in health dashboards + wrapper.vm.$store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined); + wrapper.vm.$nextTick(done); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders correctly', () => { + expect(wrapper.isVueInstance()).toBe(true); + expect(wrapper.exists()).toBe(true); + }); + }); + + describe('dashboard edit link', () => { + const findEditLink = () => wrapper.find('.js-edit-link'); + + beforeEach(done => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + + createShallowWrapper({ hasMetrics: true }, { attachToDocument: true }); + + wrapper.vm.$store.commit( + `monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, + dashboardGitResponse, + ); + wrapper.vm.$nextTick(done); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('is not present for the default dashboard', () => { + expect(findEditLink().exists()).toBe(false); + }); + + it('is present for a custom dashboard, and links to its edit_path', done => { + const dashboard = dashboardGitResponse[1]; // non-default dashboard + const currentDashboard = dashboard.path; + + wrapper.setProps({ currentDashboard }); + wrapper.vm + .$nextTick() + .then(() => { + expect(findEditLink().exists()).toBe(true); + expect(findEditLink().attributes('href')).toBe(dashboard.project_blob_path); + done(); + }) + .catch(done.fail); + }); + }); + + describe('Dashboard dropdown', () => { + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + wrapper.vm.$store.commit( + `monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, + dashboardGitResponse, + ); + }); + + it('shows the dashboard dropdown', done => { + wrapper.vm + .$nextTick() + .then(() => { + const dashboardDropdown = wrapper.find('.js-dashboards-dropdown'); + + expect(dashboardDropdown.exists()).toBe(true); + done(); + }) + .catch(done.fail); + }); + }); + + describe('external dashboard link', () => { + beforeEach(() => { + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + + createMountedWrapper( + { + hasMetrics: true, + showPanels: false, + showTimeWindowDropdown: false, + externalDashboardUrl: '/mockUrl', + }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + }); + + it('shows the link', done => { + wrapper.vm + .$nextTick() + .then(() => { + const externalDashboardButton = wrapper.find('.js-external-dashboard-link'); + + expect(externalDashboardButton.exists()).toBe(true); + expect(externalDashboardButton.is(GlButton)).toBe(true); + expect(externalDashboardButton.text()).toContain('View full dashboard'); + done(); + }) + .catch(done.fail); + }); + }); + + // https://gitlab.com/gitlab-org/gitlab-ce/issues/66922 + // eslint-disable-next-line jest/no-disabled-tests + describe.skip('link to chart', () => { + const currentDashboard = 'TEST_DASHBOARD'; + localVue.use(GlToast); + const link = () => wrapper.find('.js-chart-link'); + const clipboardText = () => link().element.dataset.clipboardText; + + beforeEach(done => { + mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse); + + createShallowWrapper({ hasMetrics: true, currentDashboard }, { attachToDocument: true }); + + setTimeout(done); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('adds a copy button to the dropdown', () => { + expect(link().text()).toContain('Generate link to chart'); + }); + + it('contains a link to the dashboard', () => { + expect(clipboardText()).toContain(`dashboard=${currentDashboard}`); + expect(clipboardText()).toContain(`group=`); + expect(clipboardText()).toContain(`title=`); + expect(clipboardText()).toContain(`y_label=`); + }); + + it('undefined parameter is stripped', done => { + wrapper.setProps({ currentDashboard: undefined }); + + wrapper.vm.$nextTick(() => { + expect(clipboardText()).not.toContain(`dashboard=`); + expect(clipboardText()).toContain(`y_label=`); + done(); + }); + }); + + it('null parameter is stripped', done => { + wrapper.setProps({ currentDashboard: null }); + + wrapper.vm.$nextTick(() => { + expect(clipboardText()).not.toContain(`dashboard=`); + expect(clipboardText()).toContain(`y_label=`); + done(); + }); + }); + + it('creates a toast when clicked', () => { + jest.spyOn(wrapper.vm.$toast, 'show').and.stub(); + + link().vm.$emit('click'); + + expect(wrapper.vm.$toast.show).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/frontend/monitoring/components/dashboard_time_url_spec.js b/spec/frontend/monitoring/components/dashboard_time_url_spec.js new file mode 100644 index 00000000000..8dc450cf131 --- /dev/null +++ b/spec/frontend/monitoring/components/dashboard_time_url_spec.js @@ -0,0 +1,54 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import createFlash from '~/flash'; +import Dashboard from '~/monitoring/components/dashboard.vue'; +import { createStore } from '~/monitoring/stores'; +import { propsData } from '../init_utils'; + +const localVue = createLocalVue(); + +jest.mock('~/flash'); + +jest.mock('~/lib/utils/url_utility', () => ({ + getParameterValues: jest.fn().mockReturnValue('<script>alert("XSS")</script>'), +})); + +describe('dashboard invalid url parameters', () => { + let store; + let wrapper; + + const createMountedWrapper = (props = {}, options = {}) => { + wrapper = mount(localVue.extend(Dashboard), { + localVue, + sync: false, + propsData: { ...propsData, ...props }, + store, + ...options, + }); + }; + + beforeEach(() => { + store = createStore(); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + it('shows an error message if invalid url parameters are passed', done => { + createMountedWrapper( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + wrapper.vm + .$nextTick() + .then(() => { + expect(createFlash).toHaveBeenCalled(); + + done(); + }) + .catch(done.fail); + }); +}); diff --git a/spec/frontend/monitoring/components/dashboard_time_window_spec.js b/spec/frontend/monitoring/components/dashboard_time_window_spec.js new file mode 100644 index 00000000000..d49af6f84cb --- /dev/null +++ b/spec/frontend/monitoring/components/dashboard_time_window_spec.js @@ -0,0 +1,75 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import { GlDropdownItem } from '@gitlab/ui'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import statusCodes from '~/lib/utils/http_status'; +import Dashboard from '~/monitoring/components/dashboard.vue'; +import { createStore } from '~/monitoring/stores'; +import { propsData, setupComponentStore } from '../init_utils'; +import { metricsGroupsAPIResponse, mockApiEndpoint } from '../mock_data'; + +const localVue = createLocalVue(); + +jest.mock('~/lib/utils/url_utility', () => ({ + getParameterValues: jest.fn().mockImplementation(param => { + if (param === 'start') return ['2019-10-01T18:27:47.000Z']; + if (param === 'end') return ['2019-10-01T18:57:47.000Z']; + return []; + }), + mergeUrlParams: jest.fn().mockReturnValue('#'), +})); + +describe('dashboard time window', () => { + let store; + let wrapper; + let mock; + + const createComponentWrapperMounted = (props = {}, options = {}) => { + wrapper = mount(localVue.extend(Dashboard), { + localVue, + sync: false, + propsData: { ...propsData, ...props }, + store, + ...options, + }); + }; + + beforeEach(() => { + store = createStore(); + mock = new MockAdapter(axios); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + mock.restore(); + }); + + it('shows an error message if invalid url parameters are passed', done => { + mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse); + + createComponentWrapperMounted( + { hasMetrics: true }, + { attachToDocument: true, stubs: ['graph-group', 'panel-type'] }, + ); + + setupComponentStore(wrapper); + + wrapper.vm + .$nextTick() + .then(() => { + const timeWindowDropdownItems = wrapper + .find('.js-time-window-dropdown') + .findAll(GlDropdownItem); + const activeItem = timeWindowDropdownItems.wrappers.filter(itemWrapper => + itemWrapper.find('.active').exists(), + ); + + expect(activeItem.length).toBe(1); + + done(); + }) + .catch(done.fail); + }); +}); diff --git a/spec/frontend/monitoring/components/graph_group_spec.js b/spec/frontend/monitoring/components/graph_group_spec.js new file mode 100644 index 00000000000..43ca17c3cbc --- /dev/null +++ b/spec/frontend/monitoring/components/graph_group_spec.js @@ -0,0 +1,120 @@ +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import GraphGroup from '~/monitoring/components/graph_group.vue'; +import Icon from '~/vue_shared/components/icon.vue'; + +const localVue = createLocalVue(); + +describe('Graph group component', () => { + let wrapper; + + const findGroup = () => wrapper.find({ ref: 'graph-group' }); + const findContent = () => wrapper.find({ ref: 'graph-group-content' }); + const findCaretIcon = () => wrapper.find(Icon); + + const createComponent = propsData => { + wrapper = shallowMount(localVue.extend(GraphGroup), { + propsData, + sync: false, + localVue, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('When group is not collapsed', () => { + beforeEach(() => { + createComponent({ + name: 'panel', + collapseGroup: false, + }); + }); + + it('should show the angle-down caret icon', () => { + expect(findContent().isVisible()).toBe(true); + expect(findCaretIcon().props('name')).toBe('angle-down'); + }); + + it('should show the angle-right caret icon when the user collapses the group', done => { + wrapper.vm.collapse(); + + wrapper.vm.$nextTick(() => { + expect(findContent().isVisible()).toBe(false); + expect(findCaretIcon().props('name')).toBe('angle-right'); + done(); + }); + }); + + it('should show the open the group when collapseGroup is set to true', done => { + wrapper.setProps({ + collapseGroup: true, + }); + + wrapper.vm.$nextTick(() => { + expect(findContent().isVisible()).toBe(true); + expect(findCaretIcon().props('name')).toBe('angle-down'); + done(); + }); + }); + + describe('When group is collapsed', () => { + beforeEach(() => { + createComponent({ + name: 'panel', + collapseGroup: true, + }); + }); + + it('should show the angle-down caret icon when collapseGroup is true', () => { + expect(wrapper.vm.caretIcon).toBe('angle-right'); + }); + + it('should show the angle-right caret icon when collapseGroup is false', () => { + wrapper.vm.collapse(); + + expect(wrapper.vm.caretIcon).toBe('angle-down'); + }); + }); + + describe('When groups can not be collapsed', () => { + beforeEach(() => { + createComponent({ + name: 'panel', + showPanels: false, + collapseGroup: false, + }); + }); + + it('should not have a container when showPanels is false', () => { + expect(findGroup().exists()).toBe(false); + expect(findContent().exists()).toBe(true); + }); + }); + + describe('When group does not show a panel heading', () => { + beforeEach(() => { + createComponent({ + name: 'panel', + showPanels: false, + collapseGroup: false, + }); + }); + + it('should collapse the panel content', () => { + expect(findContent().isVisible()).toBe(true); + expect(findCaretIcon().exists()).toBe(false); + }); + + it('should show the panel content when clicked', done => { + wrapper.vm.collapse(); + + wrapper.vm.$nextTick(() => { + expect(findContent().isVisible()).toBe(true); + expect(findCaretIcon().exists()).toBe(false); + done(); + }); + }); + }); + }); +}); diff --git a/spec/frontend/monitoring/init_utils.js b/spec/frontend/monitoring/init_utils.js new file mode 100644 index 00000000000..10db8b902b5 --- /dev/null +++ b/spec/frontend/monitoring/init_utils.js @@ -0,0 +1,56 @@ +import * as types from '~/monitoring/stores/mutation_types'; +import { + metricsGroupsAPIResponse, + mockedEmptyResult, + mockedQueryResultPayload, + mockedQueryResultPayloadCoresTotal, + mockApiEndpoint, + environmentData, +} from './mock_data'; + +export const propsData = { + hasMetrics: false, + documentationPath: '/path/to/docs', + settingsPath: '/path/to/settings', + clustersPath: '/path/to/clusters', + tagsPath: '/path/to/tags', + projectPath: '/path/to/project', + metricsEndpoint: mockApiEndpoint, + deploymentsEndpoint: null, + emptyGettingStartedSvgPath: '/path/to/getting-started.svg', + emptyLoadingSvgPath: '/path/to/loading.svg', + emptyNoDataSvgPath: '/path/to/no-data.svg', + emptyNoDataSmallSvgPath: '/path/to/no-data-small.svg', + emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg', + environmentsEndpoint: '/root/hello-prometheus/environments/35', + currentEnvironmentName: 'production', + customMetricsAvailable: false, + customMetricsPath: '', + validateQueryPath: '', +}; + +export const setupComponentStore = wrapper => { + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, + metricsGroupsAPIResponse, + ); + + // Load 3 panels to the dashboard, one with an empty result + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, + mockedEmptyResult, + ); + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, + mockedQueryResultPayload, + ); + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, + mockedQueryResultPayloadCoresTotal, + ); + + wrapper.vm.$store.commit( + `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, + environmentData, + ); +}; diff --git a/spec/frontend/monitoring/shared/prometheus_header_spec.js b/spec/frontend/monitoring/shared/prometheus_header_spec.js new file mode 100644 index 00000000000..b216bfb72d8 --- /dev/null +++ b/spec/frontend/monitoring/shared/prometheus_header_spec.js @@ -0,0 +1,26 @@ +import { shallowMount } from '@vue/test-utils'; +import PrometheusHeader from '~/monitoring/components/shared/prometheus_header.vue'; + +describe('Prometheus Header component', () => { + let prometheusHeader; + + beforeEach(() => { + prometheusHeader = shallowMount(PrometheusHeader, { + propsData: { + graphTitle: 'graph header', + }, + }); + }); + + afterEach(() => { + prometheusHeader.destroy(); + }); + + describe('Prometheus header component', () => { + it('should show a title', () => { + const title = prometheusHeader.find({ ref: 'title' }).text(); + + expect(title).toBe('graph header'); + }); + }); +}); |