2021-01-03 14:25:43 +05:30
|
|
|
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
|
2021-09-04 01:27:46 +05:30
|
|
|
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
2021-01-03 14:25:43 +05:30
|
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
2021-03-11 19:13:27 +05:30
|
|
|
import updateAlertStatusMutation from '~/graphql_shared//mutations/alert_status_update.mutation.graphql';
|
2021-01-03 14:25:43 +05:30
|
|
|
import Tracking from '~/tracking';
|
2021-03-11 19:13:27 +05:30
|
|
|
import AlertManagementStatus from '~/vue_shared/alert_details/components/alert_status.vue';
|
|
|
|
import mockAlerts from './mocks/alerts.json';
|
2021-01-03 14:25:43 +05:30
|
|
|
|
|
|
|
const mockAlert = mockAlerts[0];
|
|
|
|
|
|
|
|
describe('AlertManagementStatus', () => {
|
|
|
|
let wrapper;
|
2021-09-04 01:27:46 +05:30
|
|
|
const findStatusDropdown = () => wrapper.findComponent(GlDropdown);
|
|
|
|
const findFirstStatusOption = () => findStatusDropdown().findComponent(GlDropdownItem);
|
2021-04-29 21:17:54 +05:30
|
|
|
const findAllStatusOptions = () => findStatusDropdown().findAll(GlDropdownItem);
|
2021-09-04 01:27:46 +05:30
|
|
|
const findStatusDropdownHeader = () => wrapper.findByTestId('dropdown-header');
|
2021-01-03 14:25:43 +05:30
|
|
|
|
|
|
|
const selectFirstStatusOption = () => {
|
|
|
|
findFirstStatusOption().vm.$emit('click');
|
|
|
|
|
|
|
|
return waitForPromises();
|
|
|
|
};
|
|
|
|
|
2021-03-11 19:13:27 +05:30
|
|
|
function mountComponent({ props = {}, provide = {}, loading = false, stubs = {} } = {}) {
|
2021-09-04 01:27:46 +05:30
|
|
|
wrapper = shallowMountExtended(AlertManagementStatus, {
|
2021-01-03 14:25:43 +05:30
|
|
|
propsData: {
|
|
|
|
alert: { ...mockAlert },
|
|
|
|
projectPath: 'gitlab-org/gitlab',
|
|
|
|
isSidebar: false,
|
|
|
|
...props,
|
|
|
|
},
|
2021-03-11 19:13:27 +05:30
|
|
|
provide,
|
2021-01-03 14:25:43 +05:30
|
|
|
mocks: {
|
|
|
|
$apollo: {
|
|
|
|
mutate: jest.fn(),
|
|
|
|
queries: {
|
|
|
|
alert: {
|
|
|
|
loading,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
stubs,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
if (wrapper) {
|
|
|
|
wrapper.destroy();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
describe('sidebar', () => {
|
|
|
|
it('displays the dropdown status header', () => {
|
|
|
|
mountComponent({ props: { isSidebar: true } });
|
|
|
|
expect(findStatusDropdownHeader().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('hides the dropdown by default', () => {
|
|
|
|
mountComponent({ props: { isSidebar: true } });
|
|
|
|
expect(wrapper.classes()).toContain('gl-display-none');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows the dropdown', () => {
|
|
|
|
mountComponent({ props: { isSidebar: true, isDropdownShowing: true } });
|
|
|
|
expect(wrapper.classes()).toContain('show');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
describe('updating the alert status', () => {
|
|
|
|
const iid = '1527542';
|
|
|
|
const mockUpdatedMutationResult = {
|
|
|
|
data: {
|
|
|
|
updateAlertStatus: {
|
|
|
|
errors: [],
|
|
|
|
alert: {
|
|
|
|
iid,
|
|
|
|
status: 'acknowledged',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
mountComponent({});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => {
|
|
|
|
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult);
|
|
|
|
findFirstStatusOption().vm.$emit('click');
|
|
|
|
|
|
|
|
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
|
|
|
|
mutation: updateAlertStatusMutation,
|
|
|
|
variables: {
|
|
|
|
iid,
|
|
|
|
status: 'TRIGGERED',
|
|
|
|
projectPath: 'gitlab-org/gitlab',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when a request fails', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error()));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits an error', async () => {
|
|
|
|
await selectFirstStatusOption();
|
|
|
|
|
|
|
|
expect(wrapper.emitted('alert-error')[0]).toEqual([
|
|
|
|
'There was an error while updating the status of the alert. Please try again.',
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
it('emits an update event at the start and ending of the updating', async () => {
|
|
|
|
await selectFirstStatusOption();
|
|
|
|
expect(wrapper.emitted('handle-updating').length > 1).toBe(true);
|
|
|
|
expect(wrapper.emitted('handle-updating')[0]).toEqual([true]);
|
|
|
|
expect(wrapper.emitted('handle-updating')[1]).toEqual([false]);
|
|
|
|
});
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it('emits an error when triggered a second time', async () => {
|
|
|
|
await selectFirstStatusOption();
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
await selectFirstStatusOption();
|
|
|
|
// Should emit two errors [0,1]
|
|
|
|
expect(wrapper.emitted('alert-error').length > 1).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows an error when response includes HTML errors', async () => {
|
|
|
|
const mockUpdatedMutationErrorResult = {
|
|
|
|
data: {
|
|
|
|
updateAlertStatus: {
|
|
|
|
errors: ['<span data-testid="htmlError" />'],
|
|
|
|
alert: {
|
|
|
|
iid,
|
|
|
|
status: 'acknowledged',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationErrorResult);
|
|
|
|
|
|
|
|
await selectFirstStatusOption();
|
|
|
|
|
|
|
|
expect(wrapper.emitted('alert-error').length > 0).toBe(true);
|
|
|
|
expect(wrapper.emitted('alert-error')[0]).toEqual([
|
|
|
|
'There was an error while updating the status of the alert. <span data-testid="htmlError" />',
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
describe('Statuses', () => {
|
|
|
|
it('renders default translated statuses', () => {
|
|
|
|
mountComponent({});
|
|
|
|
expect(findAllStatusOptions().length).toBe(3);
|
|
|
|
expect(findFirstStatusOption().text()).toBe('Triggered');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders translated statuses', () => {
|
|
|
|
const status = 'TEST';
|
|
|
|
const translatedStatus = 'Test';
|
|
|
|
mountComponent({
|
|
|
|
props: { alert: { ...mockAlert, status }, statuses: { [status]: translatedStatus } },
|
|
|
|
});
|
|
|
|
expect(findAllStatusOptions().length).toBe(1);
|
|
|
|
expect(findFirstStatusOption().text()).toBe(translatedStatus);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
describe('Snowplow tracking', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
jest.spyOn(Tracking, 'event');
|
2021-03-11 19:13:27 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('should not track alert status updates when the tracking options do not exist', () => {
|
2021-01-03 14:25:43 +05:30
|
|
|
mountComponent({});
|
2021-03-11 19:13:27 +05:30
|
|
|
Tracking.event.mockClear();
|
|
|
|
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
|
|
|
|
findFirstStatusOption().vm.$emit('click');
|
|
|
|
setImmediate(() => {
|
|
|
|
expect(Tracking.event).not.toHaveBeenCalled();
|
|
|
|
});
|
2021-01-03 14:25:43 +05:30
|
|
|
});
|
|
|
|
|
2021-03-11 19:13:27 +05:30
|
|
|
it('should track alert status updates when the tracking options exist', () => {
|
|
|
|
const trackAlertStatusUpdateOptions = {
|
|
|
|
category: 'Alert Management',
|
|
|
|
action: 'update_alert_status',
|
|
|
|
label: 'Status',
|
|
|
|
};
|
|
|
|
mountComponent({ provide: { trackAlertStatusUpdateOptions } });
|
2021-01-03 14:25:43 +05:30
|
|
|
Tracking.event.mockClear();
|
|
|
|
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({});
|
|
|
|
findFirstStatusOption().vm.$emit('click');
|
|
|
|
const status = findFirstStatusOption().text();
|
|
|
|
setImmediate(() => {
|
|
|
|
const { category, action, label } = trackAlertStatusUpdateOptions;
|
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(category, action, { label, property: status });
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|