diff options
Diffstat (limited to 'spec/frontend/vue_shared/alert_details/alert_status_spec.js')
-rw-r--r-- | spec/frontend/vue_shared/alert_details/alert_status_spec.js | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/alert_details/alert_status_spec.js b/spec/frontend/vue_shared/alert_details/alert_status_spec.js new file mode 100644 index 00000000000..a866fc13539 --- /dev/null +++ b/spec/frontend/vue_shared/alert_details/alert_status_spec.js @@ -0,0 +1,166 @@ +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import waitForPromises from 'helpers/wait_for_promises'; +import updateAlertStatusMutation from '~/graphql_shared//mutations/alert_status_update.mutation.graphql'; +import Tracking from '~/tracking'; +import AlertManagementStatus from '~/vue_shared/alert_details/components/alert_status.vue'; +import mockAlerts from './mocks/alerts.json'; + +const mockAlert = mockAlerts[0]; + +describe('AlertManagementStatus', () => { + let wrapper; + const findStatusDropdown = () => wrapper.find(GlDropdown); + const findFirstStatusOption = () => findStatusDropdown().find(GlDropdownItem); + + const selectFirstStatusOption = () => { + findFirstStatusOption().vm.$emit('click'); + + return waitForPromises(); + }; + + function mountComponent({ props = {}, provide = {}, loading = false, stubs = {} } = {}) { + wrapper = shallowMount(AlertManagementStatus, { + propsData: { + alert: { ...mockAlert }, + projectPath: 'gitlab-org/gitlab', + isSidebar: false, + ...props, + }, + provide, + mocks: { + $apollo: { + mutate: jest.fn(), + queries: { + alert: { + loading, + }, + }, + }, + }, + stubs, + }); + } + + beforeEach(() => { + mountComponent(); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } + }); + + 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.', + ]); + }); + + 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" />', + ]); + }); + }); + + describe('Snowplow tracking', () => { + beforeEach(() => { + jest.spyOn(Tracking, 'event'); + }); + + it('should not track alert status updates when the tracking options do not exist', () => { + mountComponent({}); + Tracking.event.mockClear(); + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({}); + findFirstStatusOption().vm.$emit('click'); + setImmediate(() => { + expect(Tracking.event).not.toHaveBeenCalled(); + }); + }); + + 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 } }); + 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 }); + }); + }); + }); +}); |