debian-mirror-gitlab/spec/frontend/vue_shared/alert_details/alert_details_spec.js

367 lines
12 KiB
JavaScript
Raw Normal View History

2020-11-24 15:15:51 +05:30
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
2021-01-03 14:25:43 +05:30
import { mount, shallowMount } from '@vue/test-utils';
2020-06-23 00:09:42 +05:30
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
2021-01-03 14:25:43 +05:30
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
2021-03-08 18:12:59 +05:30
import waitForPromises from 'helpers/wait_for_promises';
2021-01-03 14:25:43 +05:30
import { joinPaths } from '~/lib/utils/url_utility';
2020-06-23 00:09:42 +05:30
import Tracking from '~/tracking';
2021-03-11 19:13:27 +05:30
import AlertDetails from '~/vue_shared/alert_details/components/alert_details.vue';
import AlertSummaryRow from '~/vue_shared/alert_details/components/alert_summary_row.vue';
import { SEVERITY_LEVELS } from '~/vue_shared/alert_details/constants';
import createIssueMutation from '~/vue_shared/alert_details/graphql/mutations/alert_issue_create.mutation.graphql';
2021-01-03 14:25:43 +05:30
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
2021-03-11 19:13:27 +05:30
import mockAlerts from './mocks/alerts.json';
2020-05-24 23:13:21 +05:30
const mockAlert = mockAlerts[0];
2021-01-03 14:25:43 +05:30
const environmentName = 'Production';
const environmentPath = '/fake/path';
2020-05-24 23:13:21 +05:30
describe('AlertDetails', () => {
2021-01-29 00:20:46 +05:30
let environmentData = { name: environmentName, path: environmentPath };
2020-06-23 00:09:42 +05:30
let mock;
2021-01-03 14:25:43 +05:30
let wrapper;
2020-06-23 00:09:42 +05:30
const projectPath = 'root/alerts';
const projectIssuesPath = 'root/alerts/-/issues';
2020-07-28 23:09:34 +05:30
const projectId = '1';
2020-10-24 23:57:45 +05:30
const $router = { replace: jest.fn() };
2020-06-23 00:09:42 +05:30
2021-03-11 19:13:27 +05:30
function mountComponent({
data,
loading = false,
mountMethod = shallowMount,
provide = {},
stubs = {},
} = {}) {
2021-01-03 14:25:43 +05:30
wrapper = extendedWrapper(
mountMethod(AlertDetails, {
provide: {
alertId: 'alertId',
projectPath,
projectIssuesPath,
projectId,
2021-03-11 19:13:27 +05:30
...provide,
2021-01-03 14:25:43 +05:30
},
data() {
return {
2020-05-24 23:13:21 +05:30
alert: {
2021-01-03 14:25:43 +05:30
...mockAlert,
environment: environmentData,
},
sidebarStatus: false,
...data,
};
},
mocks: {
$apollo: {
mutate: jest.fn(),
queries: {
alert: {
loading,
},
sidebarStatus: {},
2020-05-24 23:13:21 +05:30
},
},
2021-01-03 14:25:43 +05:30
$router,
$route: { params: {} },
2020-05-24 23:13:21 +05:30
},
2021-01-03 14:25:43 +05:30
stubs: {
...stubs,
AlertSummaryRow,
},
}),
);
2020-05-24 23:13:21 +05:30
}
2020-06-23 00:09:42 +05:30
beforeEach(() => {
mock = new MockAdapter(axios);
});
2020-05-24 23:13:21 +05:30
afterEach(() => {
if (wrapper) {
2020-07-28 23:09:34 +05:30
wrapper.destroy();
2020-05-24 23:13:21 +05:30
}
2020-06-23 00:09:42 +05:30
mock.restore();
2020-05-24 23:13:21 +05:30
});
2021-01-03 14:25:43 +05:30
const findCreateIncidentBtn = () => wrapper.findByTestId('createIncidentBtn');
const findViewIncidentBtn = () => wrapper.findByTestId('viewIncidentBtn');
const findIncidentCreationAlert = () => wrapper.findByTestId('incidentCreationError');
const findEnvironmentName = () => wrapper.findByTestId('environmentName');
const findEnvironmentPath = () => wrapper.findByTestId('environmentPath');
2020-11-24 15:15:51 +05:30
const findDetailsTable = () => wrapper.find(AlertDetailsTable);
2021-03-11 19:13:27 +05:30
const findMetricsTab = () => wrapper.findByTestId('metrics');
2020-05-24 23:13:21 +05:30
describe('Alert details', () => {
describe('when alert is null', () => {
beforeEach(() => {
mountComponent({ data: { alert: null } });
});
it('shows an empty state', () => {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('alertDetailsTabs').exists()).toBe(false);
2020-05-24 23:13:21 +05:30
});
});
describe('when alert is present', () => {
beforeEach(() => {
mountComponent({ data: { alert: mockAlert } });
});
it('renders a tab with overview information', () => {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('overview').exists()).toBe(true);
2020-05-24 23:13:21 +05:30
});
2020-11-24 15:15:51 +05:30
it('renders a tab with an activity feed', () => {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('activity').exists()).toBe(true);
2020-05-24 23:13:21 +05:30
});
2020-06-23 00:09:42 +05:30
it('renders severity', () => {
2021-03-11 19:13:27 +05:30
expect(wrapper.findByTestId('severity').text()).toBe(SEVERITY_LEVELS[mockAlert.severity]);
2020-06-23 00:09:42 +05:30
});
2020-05-24 23:13:21 +05:30
it('renders a title', () => {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('title').text()).toBe(mockAlert.title);
2020-05-24 23:13:21 +05:30
});
it('renders a start time', () => {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('startTimeItem').exists()).toBe(true);
expect(wrapper.findByTestId('startTimeItem').props('time')).toBe(mockAlert.startedAt);
2020-05-24 23:13:21 +05:30
});
2021-03-11 19:13:27 +05:30
it('renders the metrics tab', () => {
expect(findMetricsTab().exists()).toBe(true);
});
2020-05-24 23:13:21 +05:30
});
describe('individual alert fields', () => {
describe.each`
field | data | isShown
${'eventCount'} | ${1} | ${true}
${'eventCount'} | ${undefined} | ${false}
${'monitoringTool'} | ${'New Relic'} | ${true}
${'monitoringTool'} | ${undefined} | ${false}
${'service'} | ${'Prometheus'} | ${true}
${'service'} | ${undefined} | ${false}
2020-10-24 23:57:45 +05:30
${'runbook'} | ${undefined} | ${false}
${'runbook'} | ${'run.com'} | ${true}
2020-05-24 23:13:21 +05:30
`(`$desc`, ({ field, data, isShown }) => {
beforeEach(() => {
mountComponent({ data: { alert: { ...mockAlert, [field]: data } } });
});
it(`${field} is ${isShown ? 'displayed' : 'hidden'} correctly`, () => {
2021-01-03 14:25:43 +05:30
const element = wrapper.findByTestId(field);
2020-05-24 23:13:21 +05:30
if (isShown) {
2021-01-03 14:25:43 +05:30
expect(element.text()).toContain(data.toString());
2020-05-24 23:13:21 +05:30
} else {
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId(field).exists()).toBe(false);
2020-05-24 23:13:21 +05:30
}
});
});
});
2021-01-03 14:25:43 +05:30
describe('environment fields', () => {
2021-01-29 00:20:46 +05:30
it('should show the environment name with a link to the path', () => {
mountComponent();
const path = findEnvironmentPath();
2021-01-03 14:25:43 +05:30
2021-01-29 00:20:46 +05:30
expect(findEnvironmentName().exists()).toBe(false);
expect(path.text()).toBe(environmentName);
expect(path.attributes('href')).toBe(environmentPath);
2021-01-03 14:25:43 +05:30
});
2021-01-29 00:20:46 +05:30
it('should only show the environment name if the path is not provided', () => {
environmentData = { name: environmentName, path: null };
mountComponent();
2021-01-03 14:25:43 +05:30
2021-01-29 00:20:46 +05:30
expect(findEnvironmentPath().exists()).toBe(false);
expect(findEnvironmentName().text()).toBe(environmentName);
2021-01-03 14:25:43 +05:30
});
});
2021-03-11 19:13:27 +05:30
describe('Threat Monitoring details', () => {
it('should not render the metrics tab', () => {
mountComponent({
data: { alert: mockAlert },
provide: { isThreatMonitoringPage: true },
});
expect(findMetricsTab().exists()).toBe(false);
});
});
2020-10-24 23:57:45 +05:30
describe('Create incident from alert', () => {
it('should display "View incident" button that links the incident page when incident exists', () => {
2020-06-23 00:09:42 +05:30
const issueIid = '3';
mountComponent({
2020-07-28 23:09:34 +05:30
data: { alert: { ...mockAlert, issueIid }, sidebarStatus: false },
2020-05-24 23:13:21 +05:30
});
2021-01-29 00:20:46 +05:30
2020-10-24 23:57:45 +05:30
expect(findViewIncidentBtn().exists()).toBe(true);
expect(findViewIncidentBtn().attributes('href')).toBe(
joinPaths(projectIssuesPath, issueIid),
);
expect(findCreateIncidentBtn().exists()).toBe(false);
2020-05-24 23:13:21 +05:30
});
2020-10-24 23:57:45 +05:30
it('should display "Create incident" button when incident doesn\'t exist yet', () => {
2020-06-23 00:09:42 +05:30
const issueIid = null;
mountComponent({
mountMethod: mount,
data: { alert: { ...mockAlert, issueIid } },
});
2020-07-28 23:09:34 +05:30
return wrapper.vm.$nextTick().then(() => {
2020-10-24 23:57:45 +05:30
expect(findViewIncidentBtn().exists()).toBe(false);
expect(findCreateIncidentBtn().exists()).toBe(true);
2020-07-28 23:09:34 +05:30
});
2020-06-23 00:09:42 +05:30
});
it('calls `$apollo.mutate` with `createIssueQuery`', () => {
const issueIid = '10';
2021-03-08 18:12:59 +05:30
mountComponent({
mountMethod: mount,
data: { alert: { ...mockAlert } },
});
2020-06-23 00:09:42 +05:30
jest
.spyOn(wrapper.vm.$apollo, 'mutate')
.mockResolvedValue({ data: { createAlertIssue: { issue: { iid: issueIid } } } });
2020-10-24 23:57:45 +05:30
findCreateIncidentBtn().trigger('click');
2021-01-29 00:20:46 +05:30
2020-06-23 00:09:42 +05:30
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
2020-07-28 23:09:34 +05:30
mutation: createIssueMutation,
2020-06-23 00:09:42 +05:30
variables: {
iid: mockAlert.iid,
projectPath,
},
});
});
2021-03-08 18:12:59 +05:30
it('shows error alert when incident creation fails ', async () => {
2020-06-23 00:09:42 +05:30
const errorMsg = 'Something went wrong';
mountComponent({
mountMethod: mount,
data: { alert: { ...mockAlert, alertIid: 1 } },
});
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg);
2020-10-24 23:57:45 +05:30
findCreateIncidentBtn().trigger('click');
2020-06-23 00:09:42 +05:30
2021-03-08 18:12:59 +05:30
await waitForPromises();
expect(findIncidentCreationAlert().text()).toBe(errorMsg);
2020-05-24 23:13:21 +05:30
});
});
describe('View full alert details', () => {
beforeEach(() => {
mountComponent({ data: { alert: mockAlert } });
});
2021-01-29 00:20:46 +05:30
2020-05-24 23:13:21 +05:30
it('should display a table of raw alert details data', () => {
expect(findDetailsTable().exists()).toBe(true);
});
});
describe('loading state', () => {
beforeEach(() => {
mountComponent({ loading: true });
});
it('displays a loading state when loading', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
});
describe('error state', () => {
it('displays a error state correctly', () => {
mountComponent({ data: { errored: true } });
expect(wrapper.find(GlAlert).exists()).toBe(true);
});
2020-07-28 23:09:34 +05:30
it('renders html-errors correctly', () => {
mountComponent({
data: { errored: true, sidebarErrorMessage: '<span data-testid="htmlError" />' },
});
2021-01-03 14:25:43 +05:30
expect(wrapper.findByTestId('htmlError').exists()).toBe(true);
2020-07-28 23:09:34 +05:30
});
2020-05-24 23:13:21 +05:30
it('does not display an error when dismissed', () => {
mountComponent({ data: { errored: true, isErrorDismissed: true } });
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
});
describe('header', () => {
2021-01-03 14:25:43 +05:30
const findHeader = () => wrapper.findByTestId('alert-header');
2020-11-24 15:15:51 +05:30
const stubs = { TimeAgoTooltip: { template: '<span>now</span>' } };
2020-05-24 23:13:21 +05:30
describe('individual header fields', () => {
describe.each`
2020-06-23 00:09:42 +05:30
createdAt | monitoringTool | result
${'2020-04-17T23:18:14.996Z'} | ${null} | ${'Alert Reported now'}
${'2020-04-17T23:18:14.996Z'} | ${'Datadog'} | ${'Alert Reported now by Datadog'}
2020-05-24 23:13:21 +05:30
`(
2020-06-23 00:09:42 +05:30
`When createdAt=$createdAt, monitoringTool=$monitoringTool`,
({ createdAt, monitoringTool, result }) => {
2020-05-24 23:13:21 +05:30
beforeEach(() => {
mountComponent({
2020-06-23 00:09:42 +05:30
data: { alert: { ...mockAlert, createdAt, monitoringTool } },
2020-05-24 23:13:21 +05:30
mountMethod: mount,
stubs,
});
});
it('header text is shown correctly', () => {
expect(findHeader().text()).toBe(result);
});
},
);
});
});
2020-10-24 23:57:45 +05:30
describe('tab navigation', () => {
beforeEach(() => {
mountComponent({ data: { alert: mockAlert } });
});
it.each`
index | tabId
${0} | ${'overview'}
2020-11-24 15:15:51 +05:30
${1} | ${'metrics'}
${2} | ${'activity'}
2020-10-24 23:57:45 +05:30
`('will navigate to the correct tab via $tabId', ({ index, tabId }) => {
wrapper.setData({ currentTabIndex: index });
expect($router.replace).toHaveBeenCalledWith({ name: 'tab', params: { tabId } });
});
});
2020-05-24 23:13:21 +05:30
});
2020-06-23 00:09:42 +05:30
describe('Snowplow tracking', () => {
2021-03-11 19:13:27 +05:30
const mountOptions = {
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alert: mockAlert },
loading: false,
};
2020-05-24 23:13:21 +05:30
beforeEach(() => {
2020-06-23 00:09:42 +05:30
jest.spyOn(Tracking, 'event');
2020-05-24 23:13:21 +05:30
});
2021-03-11 19:13:27 +05:30
it('should not track alert details page views when the tracking options do not exist', () => {
mountComponent(mountOptions);
expect(Tracking.event).not.toHaveBeenCalled();
});
it('should track alert details page views when the tracking options exist', () => {
const trackAlertsDetailsViewsOptions = {
category: 'Alert Management',
action: 'view_alert_details',
};
mountComponent({ ...mountOptions, provide: { trackAlertsDetailsViewsOptions } });
2020-06-23 00:09:42 +05:30
const { category, action } = trackAlertsDetailsViewsOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action);
2020-05-24 23:13:21 +05:30
});
});
});