gitlab-ce/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js

242 lines
7.5 KiB
JavaScript

import merge from 'lodash/merge';
import { nextTick } from 'vue';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import DescriptionComponent from '~/issues/show/components/description.vue';
import HighlightBar from '~/issues/show/components/incidents/highlight_bar.vue';
import IncidentTabs, {
incidentTabsI18n,
} from '~/issues/show/components/incidents/incident_tabs.vue';
import INVALID_URL from '~/lib/utils/invalid_url';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
import { descriptionProps } from '../../mock_data/mock_data';
const push = jest.fn();
const $router = {
push,
};
const mockAlert = {
__typename: 'AlertManagementAlert',
detailsUrl: INVALID_URL,
iid: '1',
};
const defaultMocks = {
$apollo: {
queries: {
alert: {
loading: true,
},
timelineEvents: {
loading: false,
},
},
},
$route: { params: {} },
$router,
};
beforeEach(() => {
gon.features = { hideIncidentManagementFeatures: false };
});
afterEach(() => {
window.gon.features = {};
});
describe('Incident Tabs component', () => {
let wrapper;
const mountComponent = ({
data = {},
options = {},
mount = shallowMountExtended,
hasLinkedAlerts = false,
mocks = {},
} = {}) => {
wrapper = mount(
IncidentTabs,
merge(
{
propsData: {
...descriptionProps,
},
stubs: {
DescriptionComponent: true,
IncidentMetricTab: true,
},
provide: {
fullPath: '',
iid: '',
projectId: '',
issuableId: '',
uploadMetricsFeatureAvailable: true,
slaFeatureAvailable: true,
canUpdate: true,
canUpdateTimelineEvent: true,
hasLinkedAlerts,
},
data() {
return { alert: mockAlert, ...data };
},
mocks: { ...defaultMocks, ...mocks },
},
options,
),
);
};
const findSummaryTab = () => wrapper.findByTestId('summary-tab');
const findTimelineTab = () => wrapper.findByTestId('timeline-tab');
const findAlertDetailsTab = () => wrapper.findByTestId('alert-details-tab');
const findMetricsTab = () => wrapper.findByTestId('metrics-tab');
const findAlertDetailsComponent = () => wrapper.findComponent(AlertDetailsTable);
const findDescriptionComponent = () => wrapper.findComponent(DescriptionComponent);
const findHighlightBarComponent = () => wrapper.findComponent(HighlightBar);
const findTabButtonByFilter = (filter) => wrapper.findAllByRole('tab').filter(filter);
const findTimelineTabButton = () =>
findTabButtonByFilter((inner) => inner.text() === incidentTabsI18n.timelineTitle).at(0);
const findActiveTabs = () => findTabButtonByFilter((inner) => inner.classes('active'));
describe('with no alerts', () => {
beforeEach(() => {
mountComponent({ data: { alert: null } });
});
it('does not show the alert details tab option', () => {
expect(findAlertDetailsComponent().exists()).toBe(false);
});
});
describe('with an alert present', () => {
beforeEach(() => {
mountComponent();
});
it('renders the summary tab', () => {
expect(findSummaryTab().exists()).toBe(true);
expect(findSummaryTab().attributes('title')).toBe(incidentTabsI18n.summaryTitle);
});
it('renders the timeline tab', () => {
expect(findTimelineTab().exists()).toBe(true);
expect(findTimelineTab().attributes('title')).toBe(incidentTabsI18n.timelineTitle);
});
it('renders the alert details tab', () => {
mountComponent({ hasLinkedAlerts: true });
expect(findAlertDetailsTab().exists()).toBe(true);
expect(findAlertDetailsTab().attributes('title')).toBe('Alert details');
});
it('renders the alert details table with the correct props', () => {
mountComponent({ hasLinkedAlerts: true });
const alert = { iid: mockAlert.iid };
expect(findAlertDetailsComponent().props('alert')).toMatchObject(alert);
expect(findAlertDetailsComponent().props('loading')).toBe(true);
});
it('renders the description component with highlight bar', () => {
expect(findDescriptionComponent().exists()).toBe(true);
expect(findHighlightBarComponent().exists()).toBe(true);
});
it('renders the highlight bar component with the correct props', () => {
const alert = { detailsUrl: mockAlert.detailsUrl };
expect(findHighlightBarComponent().props('alert')).toMatchObject(alert);
});
it('passes all props to the description component', () => {
expect(findDescriptionComponent().props()).toMatchObject(descriptionProps);
});
});
describe('Snowplow tracking', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event');
mountComponent();
});
it('should track incident details views', () => {
const { category, action } = trackIncidentDetailsViewsOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
describe('tab changing', () => {
beforeEach(() => {
mountComponent({ mount: mountExtended });
});
it('shows only the summary tab by default', () => {
expect(findActiveTabs()).toHaveLength(1);
expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.summaryTitle);
});
it("shows the timeline tab after it's clicked", async () => {
await findTimelineTabButton().trigger('click');
expect(findActiveTabs()).toHaveLength(1);
expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle);
expect(push).toHaveBeenCalledWith('/timeline');
});
});
describe('loading page with tab', () => {
it('shows the timeline tab when timeline path is passed', async () => {
mountComponent({
mount: mountExtended,
mocks: { $route: { params: { tabId: 'timeline' } } },
});
await nextTick();
expect(findActiveTabs()).toHaveLength(1);
expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle);
});
it('shows the alerts tab when timeline path is passed', async () => {
mountComponent({
mount: mountExtended,
mocks: { $route: { params: { tabId: 'alerts' } } },
hasLinkedAlerts: true,
});
await nextTick();
expect(findActiveTabs()).toHaveLength(1);
expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.alertsTitle);
});
it('shows the metrics tab when metrics path is passed', async () => {
mountComponent({
mount: mountExtended,
mocks: { $route: { params: { tabId: 'metrics' } } },
});
await nextTick();
expect(findActiveTabs()).toHaveLength(1);
expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.metricsTitle);
});
});
describe('when hideIncidentManagementFeatures feature flag is enabled', () => {
beforeEach(() => {
gon.features = { hideIncidentManagementFeatures: true };
mountComponent();
});
it('does not render the timeline tab', () => {
expect(findTimelineTab().exists()).toBe(false);
});
it('does not render the alert details tab', () => {
mountComponent({ hasLinkedAlerts: true });
expect(findAlertDetailsTab().exists()).toBe(false);
});
it('does not render the metrics tab', () => {
expect(findMetricsTab().exists()).toBe(false);
});
});
});