Commit 6fdd8b52 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch 'cleanup-dashboard-data' into 'master'

Use of dashboard fixtures to remove mock data

See merge request gitlab-org/gitlab!29399
parents b46bfa0c e41cc561
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import { GlModal, GlDeprecatedButton } from '@gitlab/ui'; import { GlModal, GlDeprecatedButton } from '@gitlab/ui';
import Dashboard from 'ee/monitoring/components/dashboard.vue'; import Dashboard from 'ee/monitoring/components/dashboard.vue';
import { import { mockApiEndpoint, propsData } from 'jest/monitoring/mock_data';
mockApiEndpoint, import { metricsDashboardResponse } from 'jest/monitoring/fixture_data';
mockedQueryResultFixture, import { setupStoreWithData } from 'jest/monitoring/store_utils';
environmentData,
} from '../../../../../spec/frontend/monitoring/mock_data';
import { getJSONFixture } from '../../../../../spec/frontend/helpers/fixtures';
import { propsData } from '../../../../../spec/frontend/monitoring/init_utils';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue'; import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import * as types from '~/monitoring/stores/mutation_types';
const localVue = createLocalVue();
const metricsDashboardFixture = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
const metricsDashboardPayload = metricsDashboardFixture.dashboard;
describe('Dashboard', () => { describe('Dashboard', () => {
let Component;
let mock; let mock;
let store; let store;
let wrapper; let wrapper;
...@@ -31,13 +18,12 @@ describe('Dashboard', () => { ...@@ -31,13 +18,12 @@ describe('Dashboard', () => {
const findAddMetricButton = () => wrapper.vm.$refs.addMetricBtn; const findAddMetricButton = () => wrapper.vm.$refs.addMetricBtn;
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
wrapper = shallowMount(localVue.extend(Component), { wrapper = shallowMount(Dashboard, {
propsData: { ...propsData, ...props }, propsData: { ...propsData, ...props },
stubs: { stubs: {
GlDeprecatedButton, GlDeprecatedButton,
}, },
store, store,
localVue,
}); });
}; };
...@@ -49,29 +35,13 @@ describe('Dashboard', () => { ...@@ -49,29 +35,13 @@ describe('Dashboard', () => {
window.gon = { ...window.gon, ee: true }; window.gon = { ...window.gon, ee: true };
store = createStore(); store = createStore();
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
mock.onGet(mockApiEndpoint).reply(200, metricsDashboardPayload); mock.onGet(mockApiEndpoint).reply(200, metricsDashboardResponse);
Component = localVue.extend(Dashboard);
}); });
afterEach(() => { afterEach(() => {
mock.restore(); mock.restore();
}); });
function setupComponentStore(component) {
component.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
component.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedQueryResultFixture,
);
component.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
}
describe('add custom metrics', () => { describe('add custom metrics', () => {
describe('when not available', () => { describe('when not available', () => {
beforeEach(() => { beforeEach(() => {
...@@ -93,7 +63,7 @@ describe('Dashboard', () => { ...@@ -93,7 +63,7 @@ describe('Dashboard', () => {
customMetricsPath: '/endpoint', customMetricsPath: '/endpoint',
customMetricsAvailable: true, customMetricsAvailable: true,
}); });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
origPage = document.body.dataset.page; origPage = document.body.dataset.page;
document.body.dataset.page = 'projects:environments:metrics'; document.body.dataset.page = 'projects:environments:metrics';
...@@ -133,6 +103,7 @@ describe('Dashboard', () => { ...@@ -133,6 +103,7 @@ describe('Dashboard', () => {
}); });
}); });
}); });
it('renders custom metrics form fields', () => { it('renders custom metrics form fields', () => {
expect(wrapper.find(CustomMetricsFormFields).exists()).toBe(true); expect(wrapper.find(CustomMetricsFormFields).exists()).toBe(true);
}); });
......
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { setTestTimeout } from 'helpers/timeout'; import { setTestTimeout } from 'helpers/timeout';
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { TEST_HOST } from 'jest/helpers/test_constants';
import { import {
GlAreaChart, GlAreaChart,
GlLineChart, GlLineChart,
...@@ -12,23 +13,16 @@ import { shallowWrapperContainsSlotText } from 'helpers/vue_test_utils_helper'; ...@@ -12,23 +13,16 @@ import { shallowWrapperContainsSlotText } from 'helpers/vue_test_utils_helper';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import TimeSeries from '~/monitoring/components/charts/time_series.vue'; import TimeSeries from '~/monitoring/components/charts/time_series.vue';
import * as types from '~/monitoring/stores/mutation_types'; import * as types from '~/monitoring/stores/mutation_types';
import { deploymentData, mockProjectDir } from '../../mock_data';
import { import {
deploymentData, metricsDashboardPayload,
mockedQueryResultFixture,
metricsDashboardViewModel, metricsDashboardViewModel,
mockProjectDir, metricResultStatus,
mockHost, } from '../../fixture_data';
} from '../../mock_data';
import * as iconUtils from '~/lib/utils/icon_utils'; import * as iconUtils from '~/lib/utils/icon_utils';
import { getJSONFixture } from '../../../helpers/fixtures';
const mockSvgPathContent = 'mockSvgPathContent'; const mockSvgPathContent = 'mockSvgPathContent';
const metricsDashboardFixture = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
const metricsDashboardPayload = metricsDashboardFixture.dashboard;
jest.mock('lodash/throttle', () => jest.mock('lodash/throttle', () =>
// this throttle mock executes immediately // this throttle mock executes immediately
jest.fn(func => { jest.fn(func => {
...@@ -51,7 +45,7 @@ describe('Time series component', () => { ...@@ -51,7 +45,7 @@ describe('Time series component', () => {
graphData: { ...graphData, type }, graphData: { ...graphData, type },
deploymentData: store.state.monitoringDashboard.deploymentData, deploymentData: store.state.monitoringDashboard.deploymentData,
annotations: store.state.monitoringDashboard.annotations, annotations: store.state.monitoringDashboard.annotations,
projectPath: `${mockHost}${mockProjectDir}`, projectPath: `${TEST_HOST}${mockProjectDir}`,
}, },
store, store,
stubs: { stubs: {
...@@ -74,7 +68,7 @@ describe('Time series component', () => { ...@@ -74,7 +68,7 @@ describe('Time series component', () => {
store.commit( store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, `monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedQueryResultFixture, metricResultStatus,
); );
// dashboard is a dynamically generated fixture and stored at environment_metrics_dashboard.json // dashboard is a dynamically generated fixture and stored at environment_metrics_dashboard.json
[mockGraphData] = store.state.monitoringDashboard.dashboard.panelGroups[1].panels; [mockGraphData] = store.state.monitoringDashboard.dashboard.panelGroups[1].panels;
...@@ -606,7 +600,7 @@ describe('Time series component', () => { ...@@ -606,7 +600,7 @@ describe('Time series component', () => {
store = createStore(); store = createStore();
const graphData = cloneDeep(metricsDashboardViewModel.panelGroups[0].panels[3]); const graphData = cloneDeep(metricsDashboardViewModel.panelGroups[0].panels[3]);
graphData.metrics.forEach(metric => graphData.metrics.forEach(metric =>
Object.assign(metric, { result: mockedQueryResultFixture.result }), Object.assign(metric, { result: metricResultStatus.result }),
); );
timeSeriesChart = makeTimeSeriesChart(graphData, 'area-chart'); timeSeriesChart = makeTimeSeriesChart(graphData, 'area-chart');
......
import { shallowMount, createLocalVue, mount } from '@vue/test-utils'; import { shallowMount, mount } from '@vue/test-utils';
import { GlDropdownItem, GlDeprecatedButton } from '@gitlab/ui'; import { GlDropdownItem, GlDeprecatedButton } from '@gitlab/ui';
import VueDraggable from 'vuedraggable'; import VueDraggable from 'vuedraggable';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
...@@ -6,7 +6,6 @@ import axios from '~/lib/utils/axios_utils'; ...@@ -6,7 +6,6 @@ import axios from '~/lib/utils/axios_utils';
import statusCodes from '~/lib/utils/http_status'; import statusCodes from '~/lib/utils/http_status';
import { metricStates } from '~/monitoring/constants'; import { metricStates } from '~/monitoring/constants';
import Dashboard from '~/monitoring/components/dashboard.vue'; import Dashboard from '~/monitoring/components/dashboard.vue';
import { getJSONFixture } from '../../../../spec/frontend/helpers/fixtures';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue'; import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue'; import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue';
...@@ -14,21 +13,9 @@ import GroupEmptyState from '~/monitoring/components/group_empty_state.vue'; ...@@ -14,21 +13,9 @@ import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue'; import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types'; import * as types from '~/monitoring/stores/mutation_types';
import { setupComponentStore, propsData } from '../init_utils'; import { setupStoreWithDashboard, setMetricResult, setupStoreWithData } from '../store_utils';
import { import { environmentData, dashboardGitResponse, propsData } from '../mock_data';
metricsDashboardViewModel, import { metricsDashboardViewModel, metricsDashboardPanelCount } from '../fixture_data';
environmentData,
dashboardGitResponse,
mockedQueryResultFixture,
} from '../mock_data';
const localVue = createLocalVue();
const expectedPanelCount = 4;
const metricsDashboardFixture = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
const metricsDashboardPayload = metricsDashboardFixture.dashboard;
describe('Dashboard', () => { describe('Dashboard', () => {
let store; let store;
...@@ -43,7 +30,6 @@ describe('Dashboard', () => { ...@@ -43,7 +30,6 @@ describe('Dashboard', () => {
const createShallowWrapper = (props = {}, options = {}) => { const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(Dashboard, { wrapper = shallowMount(Dashboard, {
localVue,
propsData: { ...propsData, ...props }, propsData: { ...propsData, ...props },
methods: { methods: {
fetchData: jest.fn(), fetchData: jest.fn(),
...@@ -55,7 +41,6 @@ describe('Dashboard', () => { ...@@ -55,7 +41,6 @@ describe('Dashboard', () => {
const createMountedWrapper = (props = {}, options = {}) => { const createMountedWrapper = (props = {}, options = {}) => {
wrapper = mount(Dashboard, { wrapper = mount(Dashboard, {
localVue,
propsData: { ...propsData, ...props }, propsData: { ...propsData, ...props },
methods: { methods: {
fetchData: jest.fn(), fetchData: jest.fn(),
...@@ -144,7 +129,7 @@ describe('Dashboard', () => { ...@@ -144,7 +129,7 @@ describe('Dashboard', () => {
{ stubs: ['graph-group', 'panel-type'] }, { stubs: ['graph-group', 'panel-type'] },
); );
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.showEmptyState).toEqual(false); expect(wrapper.vm.showEmptyState).toEqual(false);
...@@ -172,7 +157,7 @@ describe('Dashboard', () => { ...@@ -172,7 +157,7 @@ describe('Dashboard', () => {
beforeEach(() => { beforeEach(() => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] }); createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
...@@ -201,14 +186,7 @@ describe('Dashboard', () => { ...@@ -201,14 +186,7 @@ describe('Dashboard', () => {
it('hides the environments dropdown list when there is no environments', () => { it('hides the environments dropdown list when there is no environments', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] }); createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm.$store.commit( setupStoreWithDashboard(wrapper.vm.$store);
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
wrapper.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedQueryResultFixture,
);
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(findAllEnvironmentsDropdownItems()).toHaveLength(0); expect(findAllEnvironmentsDropdownItems()).toHaveLength(0);
...@@ -218,7 +196,7 @@ describe('Dashboard', () => { ...@@ -218,7 +196,7 @@ describe('Dashboard', () => {
it('renders the datetimepicker dropdown', () => { it('renders the datetimepicker dropdown', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] }); createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(DateTimePicker).exists()).toBe(true); expect(wrapper.find(DateTimePicker).exists()).toBe(true);
...@@ -228,7 +206,7 @@ describe('Dashboard', () => { ...@@ -228,7 +206,7 @@ describe('Dashboard', () => {
it('renders the refresh dashboard button', () => { it('renders the refresh dashboard button', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] }); createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
const refreshBtn = wrapper.findAll({ ref: 'refreshDashboardBtn' }); const refreshBtn = wrapper.findAll({ ref: 'refreshDashboardBtn' });
...@@ -241,7 +219,11 @@ describe('Dashboard', () => { ...@@ -241,7 +219,11 @@ describe('Dashboard', () => {
describe('when one of the metrics is missing', () => { describe('when one of the metrics is missing', () => {
beforeEach(() => { beforeEach(() => {
createShallowWrapper({ hasMetrics: true }); createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper);
const { $store } = wrapper.vm;
setupStoreWithDashboard($store);
setMetricResult({ $store, result: [], panel: 2 });
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
...@@ -273,7 +255,7 @@ describe('Dashboard', () => { ...@@ -273,7 +255,7 @@ describe('Dashboard', () => {
}, },
); );
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
...@@ -348,14 +330,14 @@ describe('Dashboard', () => { ...@@ -348,14 +330,14 @@ describe('Dashboard', () => {
beforeEach(() => { beforeEach(() => {
createShallowWrapper({ hasMetrics: true }); createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
it('wraps vuedraggable', () => { it('wraps vuedraggable', () => {
expect(findDraggablePanels().exists()).toBe(true); expect(findDraggablePanels().exists()).toBe(true);
expect(findDraggablePanels().length).toEqual(expectedPanelCount); expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
}); });
it('is disabled by default', () => { it('is disabled by default', () => {
...@@ -411,11 +393,11 @@ describe('Dashboard', () => { ...@@ -411,11 +393,11 @@ describe('Dashboard', () => {
it('shows a remove button, which removes a panel', () => { it('shows a remove button, which removes a panel', () => {
expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false); expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
expect(findDraggablePanels().length).toEqual(expectedPanelCount); expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
findFirstDraggableRemoveButton().trigger('click'); findFirstDraggableRemoveButton().trigger('click');
return wrapper.vm.$nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1); expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount - 1);
}); });
}); });
...@@ -534,7 +516,7 @@ describe('Dashboard', () => { ...@@ -534,7 +516,7 @@ describe('Dashboard', () => {
beforeEach(() => { beforeEach(() => {
createShallowWrapper({ hasMetrics: true, currentDashboard }); createShallowWrapper({ hasMetrics: true, currentDashboard });
setupComponentStore(wrapper); setupStoreWithData(wrapper.vm.$store);
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
......
...@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter'; ...@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import Dashboard from '~/monitoring/components/dashboard.vue'; import Dashboard from '~/monitoring/components/dashboard.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import { propsData } from '../init_utils'; import { propsData } from '../mock_data';
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
......
...@@ -9,12 +9,11 @@ import { ...@@ -9,12 +9,11 @@ import {
updateHistory, updateHistory,
} from '~/lib/utils/url_utility'; } from '~/lib/utils/url_utility';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { mockProjectDir } from '../mock_data'; import { mockProjectDir, propsData } from '../mock_data';
import Dashboard from '~/monitoring/components/dashboard.vue'; import Dashboard from '~/monitoring/components/dashboard.vue';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import { defaultTimeRange } from '~/vue_shared/constants'; import { defaultTimeRange } from '~/vue_shared/constants';
import { propsData } from '../init_utils';
jest.mock('~/flash'); jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
......
import { mapToDashboardViewModel } from '~/monitoring/stores/utils';
import { metricsResult } from './mock_data';
// Use globally available `getJSONFixture` so this file can be imported by both karma and jest specs
export const metricsDashboardResponse = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
export const metricsDashboardPayload = metricsDashboardResponse.dashboard;
export const metricsDashboardViewModel = mapToDashboardViewModel(metricsDashboardPayload);
export const metricsDashboardPanelCount = 22;
export const metricResultStatus = {
// First metric in fixture `metrics_dashboard/environment_metrics_dashboard.json`
metricId: 'NO_DB_response_metrics_nginx_ingress_throughput_status_code',
result: metricsResult,
};
export const metricResultPods = {
// Second metric in fixture `metrics_dashboard/environment_metrics_dashboard.json`
metricId: 'NO_DB_response_metrics_nginx_ingress_latency_pod_average',
result: metricsResult,
};
export const metricResultEmpty = {
metricId: 'NO_DB_response_metrics_nginx_ingress_16_throughput_status_code',
result: [],
};
import * as types from '~/monitoring/stores/mutation_types';
import {
metricsDashboardPayload,
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',
logsPath: '/path/to/logs',
defaultBranch: 'master',
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',
currentEnvironmentName: 'production',
customMetricsAvailable: false,
customMetricsPath: '',
validateQueryPath: '',
};
export const setupComponentStore = wrapper => {
wrapper.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
// 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,
);
};
This diff is collapsed.
...@@ -31,11 +31,14 @@ import { ...@@ -31,11 +31,14 @@ import {
deploymentData, deploymentData,
environmentData, environmentData,
annotationsData, annotationsData,
metricsDashboardResponse,
metricsDashboardViewModel,
dashboardGitResponse, dashboardGitResponse,
mockDashboardsErrorResponse, mockDashboardsErrorResponse,
} from '../mock_data'; } from '../mock_data';
import {
metricsDashboardResponse,
metricsDashboardViewModel,
metricsDashboardPanelCount,
} from '../fixture_data';
jest.mock('~/flash'); jest.mock('~/flash');
...@@ -553,7 +556,7 @@ describe('Monitoring store actions', () => { ...@@ -553,7 +556,7 @@ describe('Monitoring store actions', () => {
fetchDashboardData({ state, commit, dispatch }) fetchDashboardData({ state, commit, dispatch })
.then(() => { .then(() => {
expect(dispatch).toHaveBeenCalledTimes(10); // one per metric plus 1 for deployments expect(dispatch).toHaveBeenCalledTimes(metricsDashboardPanelCount + 1); // plus 1 for deployments
expect(dispatch).toHaveBeenCalledWith('fetchDeploymentsData'); expect(dispatch).toHaveBeenCalledWith('fetchDeploymentsData');
expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetric', { expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetric', {
metric, metric,
...@@ -581,11 +584,13 @@ describe('Monitoring store actions', () => { ...@@ -581,11 +584,13 @@ describe('Monitoring store actions', () => {
let metric; let metric;
let state; let state;
let data; let data;
let prometheusEndpointPath;
beforeEach(() => { beforeEach(() => {
state = storeState(); state = storeState();
[metric] = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics; [metric] = metricsDashboardViewModel.panelGroups[0].panels[0].metrics;
metric = convertObjectPropsToCamelCase(metric, { deep: true });
prometheusEndpointPath = metric.prometheusEndpointPath;
data = { data = {
metricId: metric.metricId, metricId: metric.metricId,
...@@ -594,7 +599,7 @@ describe('Monitoring store actions', () => { ...@@ -594,7 +599,7 @@ describe('Monitoring store actions', () => {
}); });
it('commits result', done => { it('commits result', done => {
mock.onGet('http://test').reply(200, { data }); // One attempt mock.onGet(prometheusEndpointPath).reply(200, { data }); // One attempt
testAction( testAction(
fetchPrometheusMetric, fetchPrometheusMetric,
...@@ -631,7 +636,7 @@ describe('Monitoring store actions', () => { ...@@ -631,7 +636,7 @@ describe('Monitoring store actions', () => {
}; };
it('uses calculated step', done => { it('uses calculated step', done => {
mock.onGet('http://test').reply(200, { data }); // One attempt mock.onGet(prometheusEndpointPath).reply(200, { data }); // One attempt
testAction( testAction(
fetchPrometheusMetric, fetchPrometheusMetric,
...@@ -673,7 +678,7 @@ describe('Monitoring store actions', () => { ...@@ -673,7 +678,7 @@ describe('Monitoring store actions', () => {
}; };
it('uses metric step', done => { it('uses metric step', done => {
mock.onGet('http://test').reply(200, { data }); // One attempt mock.onGet(prometheusEndpointPath).reply(200, { data }); // One attempt
testAction( testAction(
fetchPrometheusMetric, fetchPrometheusMetric,
...@@ -705,10 +710,10 @@ describe('Monitoring store actions', () => { ...@@ -705,10 +710,10 @@ describe('Monitoring store actions', () => {
it('commits result, when waiting for results', done => { it('commits result, when waiting for results', done => {
// Mock multiple attempts while the cache is filling up // Mock multiple attempts while the cache is filling up
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').reply(200, { data }); // 4th attempt mock.onGet(prometheusEndpointPath).reply(200, { data }); // 4th attempt
testAction( testAction(
fetchPrometheusMetric, fetchPrometheusMetric,
...@@ -739,10 +744,10 @@ describe('Monitoring store actions', () => { ...@@ -739,10 +744,10 @@ describe('Monitoring store actions', () => {
it('commits failure, when waiting for results and getting a server error', done => { it('commits failure, when waiting for results and getting a server error', done => {
// Mock multiple attempts while the cache is filling up and fails // Mock multiple attempts while the cache is filling up and fails
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').replyOnce(statusCodes.NO_CONTENT); mock.onGet(prometheusEndpointPath).replyOnce(statusCodes.NO_CONTENT);
mock.onGet('http://test').reply(500); // 4th attempt mock.onGet(prometheusEndpointPath).reply(500); // 4th attempt
const error = new Error('Request failed with status code 500'); const error = new Error('Request failed with status code 500');
......
...@@ -3,18 +3,13 @@ import * as getters from '~/monitoring/stores/getters'; ...@@ -3,18 +3,13 @@ import * as getters from '~/monitoring/stores/getters';
import mutations from '~/monitoring/stores/mutations'; import mutations from '~/monitoring/stores/mutations';
import * as types from '~/monitoring/stores/mutation_types'; import * as types from '~/monitoring/stores/mutation_types';
import { metricStates } from '~/monitoring/constants'; import { metricStates } from '~/monitoring/constants';
import { environmentData, metricsResult } from '../mock_data';
import { import {
environmentData, metricsDashboardPayload,
mockedEmptyThroughputResult, metricResultStatus,
mockedQueryResultFixture, metricResultPods,
mockedQueryResultFixtureStatusCode, metricResultEmpty,
} from '../mock_data'; } from '../fixture_data';
import { getJSONFixture } from '../../helpers/fixtures';
const metricsDashboardFixture = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
const metricsDashboardPayload = metricsDashboardFixture.dashboard;
describe('Monitoring store Getters', () => { describe('Monitoring store Getters', () => {
describe('getMetricStates', () => { describe('getMetricStates', () => {
...@@ -22,6 +17,21 @@ describe('Monitoring store Getters', () => { ...@@ -22,6 +17,21 @@ describe('Monitoring store Getters', () => {
let state; let state;
let getMetricStates; let getMetricStates;
const setMetricSuccess = ({ result = metricsResult, group = 0, panel = 0, metric = 0 }) => {
const { metricId } = state.dashboard.panelGroups[group].panels[panel].metrics[metric];
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, {
metricId,
result,
});
};
const setMetricFailure = ({ group = 0, panel = 0, metric = 0 }) => {
const { metricId } = state.dashboard.panelGroups[group].panels[panel].metrics[metric];
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, {
metricId,
});
};
beforeEach(() => { beforeEach(() => {
setupState = (initState = {}) => { setupState = (initState = {}) => {
state = initState; state = initState;
...@@ -61,31 +71,30 @@ describe('Monitoring store Getters', () => { ...@@ -61,31 +71,30 @@ describe('Monitoring store Getters', () => {
it('on an empty metric with no result, returns NO_DATA', () => { it('on an empty metric with no result, returns NO_DATA', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedEmptyThroughputResult); setMetricSuccess({ result: [], group: 2 });
expect(getMetricStates()).toEqual([metricStates.NO_DATA]); expect(getMetricStates()).toEqual([metricStates.NO_DATA]);
}); });
it('on a metric with a result, returns OK', () => { it('on a metric with a result, returns OK', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture); setMetricSuccess({ group: 1 });
expect(getMetricStates()).toEqual([metricStates.OK]); expect(getMetricStates()).toEqual([metricStates.OK]);
}); });
it('on a metric with an error, returns an error', () => { it('on a metric with an error, returns an error', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, { setMetricFailure({});
metricId: groups[0].panels[0].metrics[0].metricId,
});
expect(getMetricStates()).toEqual([metricStates.UNKNOWN_ERROR]); expect(getMetricStates()).toEqual([metricStates.UNKNOWN_ERROR]);
}); });
it('on multiple metrics with results, returns OK', () => { it('on multiple metrics with results, returns OK', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixtureStatusCode); setMetricSuccess({ group: 1 });
setMetricSuccess({ group: 1, panel: 1 });
expect(getMetricStates()).toEqual([metricStates.OK]); expect(getMetricStates()).toEqual([metricStates.OK]);
...@@ -96,15 +105,8 @@ describe('Monitoring store Getters', () => { ...@@ -96,15 +105,8 @@ describe('Monitoring store Getters', () => {
it('on multiple metrics errors', () => { it('on multiple metrics errors', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, { setMetricFailure({});
metricId: groups[0].panels[0].metrics[0].metricId, setMetricFailure({ group: 1 });
});
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, {
metricId: groups[0].panels[0].metrics[0].metricId,
});
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, {
metricId: groups[1].panels[0].metrics[0].metricId,
});
// Entire dashboard fails // Entire dashboard fails
expect(getMetricStates()).toEqual([metricStates.UNKNOWN_ERROR]); expect(getMetricStates()).toEqual([metricStates.UNKNOWN_ERROR]);
...@@ -116,14 +118,11 @@ describe('Monitoring store Getters', () => { ...@@ -116,14 +118,11 @@ describe('Monitoring store Getters', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
// An success in 1 group // An success in 1 group
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture); setMetricSuccess({ group: 1 });
// An error in 2 groups // An error in 2 groups
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, { setMetricFailure({ group: 1, panel: 1 });
metricId: groups[1].panels[1].metrics[0].metricId, setMetricFailure({ group: 2, panel: 0 });
});
mutations[types.RECEIVE_METRIC_RESULT_FAILURE](state, {
metricId: groups[2].panels[0].metrics[0].metricId,
});
expect(getMetricStates()).toEqual([metricStates.OK, metricStates.UNKNOWN_ERROR]); expect(getMetricStates()).toEqual([metricStates.OK, metricStates.UNKNOWN_ERROR]);
expect(getMetricStates(groups[1].key)).toEqual([ expect(getMetricStates(groups[1].key)).toEqual([
...@@ -182,38 +181,35 @@ describe('Monitoring store Getters', () => { ...@@ -182,38 +181,35 @@ describe('Monitoring store Getters', () => {
it('an empty metric, returns empty', () => { it('an empty metric, returns empty', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedEmptyThroughputResult); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultEmpty);
expect(metricsWithData()).toEqual([]); expect(metricsWithData()).toEqual([]);
}); });
it('a metric with results, it returns a metric', () => { it('a metric with results, it returns a metric', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultStatus);
expect(metricsWithData()).toEqual([mockedQueryResultFixture.metricId]); expect(metricsWithData()).toEqual([metricResultStatus.metricId]);
}); });
it('multiple metrics with results, it return multiple metrics', () => { it('multiple metrics with results, it return multiple metrics', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultStatus);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixtureStatusCode); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultPods);
expect(metricsWithData()).toEqual([ expect(metricsWithData()).toEqual([metricResultStatus.metricId, metricResultPods.metricId]);
mockedQueryResultFixture.metricId,
mockedQueryResultFixtureStatusCode.metricId,
]);
}); });
it('multiple metrics with results, it returns metrics filtered by group', () => { it('multiple metrics with results, it returns metrics filtered by group', () => {
mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload); mutations[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, metricsDashboardPayload);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixture); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultStatus);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, mockedQueryResultFixtureStatusCode); mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](state, metricResultPods);
// First group has metrics // First group has metrics
expect(metricsWithData(state.dashboard.panelGroups[1].key)).toEqual([ expect(metricsWithData(state.dashboard.panelGroups[1].key)).toEqual([
mockedQueryResultFixture.metricId, metricResultStatus.metricId,
mockedQueryResultFixtureStatusCode.metricId, metricResultPods.metricId,
]); ]);
// Second group has no metrics // Second group has no metrics
......
...@@ -6,12 +6,7 @@ import state from '~/monitoring/stores/state'; ...@@ -6,12 +6,7 @@ import state from '~/monitoring/stores/state';
import { metricStates } from '~/monitoring/constants'; import { metricStates } from '~/monitoring/constants';
import { deploymentData, dashboardGitResponse } from '../mock_data'; import { deploymentData, dashboardGitResponse } from '../mock_data';
import { getJSONFixture } from '../../helpers/fixtures'; import { metricsDashboardPayload } from '../fixture_data';
const metricsDashboardFixture = getJSONFixture(
'metrics_dashboard/environment_metrics_dashboard.json',
);
const metricsDashboardPayload = metricsDashboardFixture.dashboard;
describe('Monitoring mutations', () => { describe('Monitoring mutations', () => {
let stateCopy; let stateCopy;
......
import * as types from '~/monitoring/stores/mutation_types';
import { metricsResult, environmentData } from './mock_data';
import { metricsDashboardPayload } from './fixture_data';
export const setMetricResult = ({ $store, result, group = 0, panel = 0, metric = 0 }) => {
const { dashboard } = $store.state.monitoringDashboard;
const { metricId } = dashboard.panelGroups[group].panels[panel].metrics[metric];
$store.commit(`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`, {
metricId,
result,
});
};
const setEnvironmentData = $store => {
$store.commit(`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, environmentData);
};
export const setupStoreWithDashboard = $store => {
$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
};
export const setupStoreWithData = $store => {
setupStoreWithDashboard($store);
setMetricResult({ $store, result: [], panel: 0 });
setMetricResult({ $store, result: metricsResult, panel: 1 });
setMetricResult({ $store, result: metricsResult, panel: 2 });
setEnvironmentData($store);
};
import * as monitoringUtils from '~/monitoring/utils'; import * as monitoringUtils from '~/monitoring/utils';
import { queryToObject, mergeUrlParams, removeParams } from '~/lib/utils/url_utility'; import { queryToObject, mergeUrlParams, removeParams } from '~/lib/utils/url_utility';
import { TEST_HOST } from 'jest/helpers/test_constants';
import { import {
mockHost,
mockProjectDir, mockProjectDir,
graphDataPrometheusQuery, graphDataPrometheusQuery,
graphDataPrometheusQueryRange, graphDataPrometheusQueryRange,
...@@ -11,7 +11,7 @@ import { ...@@ -11,7 +11,7 @@ import {
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
const mockPath = `${mockHost}${mockProjectDir}/-/environments/29/metrics`; const mockPath = `${TEST_HOST}${mockProjectDir}/-/environments/29/metrics`;
const generatedLink = 'http://chart.link.com'; const generatedLink = 'http://chart.link.com';
......
...@@ -2,66 +2,13 @@ import Vue from 'vue'; ...@@ -2,66 +2,13 @@ import Vue from 'vue';
import { createLocalVue } from '@vue/test-utils'; import { createLocalVue } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import Dashboard from '~/monitoring/components/dashboard.vue'; import Dashboard from '~/monitoring/components/dashboard.vue';
import * as types from '~/monitoring/stores/mutation_types';
import { createStore } from '~/monitoring/stores'; import { createStore } from '~/monitoring/stores';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { import { mockApiEndpoint, propsData } from '../mock_data';
metricsDashboardPayload, import { metricsDashboardPayload } from '../fixture_data';
mockedEmptyResult, import { setupStoreWithData } from '../store_utils';
mockedQueryResultPayload,
mockedQueryResultPayloadCoresTotal,
mockApiEndpoint,
environmentData,
} from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
const propsData = {
hasMetrics: false,
documentationPath: '/path/to/docs',
settingsPath: '/path/to/settings',
clustersPath: '/path/to/clusters',
tagsPath: '/path/to/tags',
projectPath: '/path/to/project',
defaultBranch: 'master',
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',
currentEnvironmentName: 'production',
customMetricsAvailable: false,
customMetricsPath: '',
validateQueryPath: '',
};
function setupComponentStore(component) {
// Load 2 panel groups
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`,
metricsDashboardPayload,
);
// Load 3 panels to the dashboard, one with an empty result
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedEmptyResult,
);
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedQueryResultPayload,
);
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRIC_RESULT_SUCCESS}`,
mockedQueryResultPayloadCoresTotal,
);
component.$store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
}
describe('Dashboard', () => { describe('Dashboard', () => {
let DashboardComponent; let DashboardComponent;
...@@ -109,7 +56,7 @@ describe('Dashboard', () => { ...@@ -109,7 +56,7 @@ describe('Dashboard', () => {
store, store,
}); });
setupComponentStore(component); setupStoreWithData(component.$store);
return Vue.nextTick().then(() => { return Vue.nextTick().then(() => {
[promPanel] = component.$el.querySelectorAll('.prometheus-panel'); [promPanel] = component.$el.querySelectorAll('.prometheus-panel');
......
export * from '../../frontend/monitoring/fixture_data';
export * from '../../frontend/monitoring/store_utils';
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