diff options
Diffstat (limited to 'spec/frontend/alert_management/components')
12 files changed, 6 insertions, 1116 deletions
diff --git a/spec/frontend/alert_management/components/alert_details_spec.js b/spec/frontend/alert_management/components/alert_details_spec.js deleted file mode 100644 index 976e50625a6..00000000000 --- a/spec/frontend/alert_management/components/alert_details_spec.js +++ /dev/null @@ -1,338 +0,0 @@ -import { GlAlert, GlLoadingIcon } from '@gitlab/ui'; -import { mount, shallowMount } from '@vue/test-utils'; -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import waitForPromises from 'helpers/wait_for_promises'; -import AlertDetails from '~/alert_management/components/alert_details.vue'; -import AlertSummaryRow from '~/alert_management/components/alert_summary_row.vue'; -import { - ALERTS_SEVERITY_LABELS, - trackAlertsDetailsViewsOptions, -} from '~/alert_management/constants'; -import createIssueMutation from '~/alert_management/graphql/mutations/create_issue_from_alert.mutation.graphql'; -import { joinPaths } from '~/lib/utils/url_utility'; -import Tracking from '~/tracking'; -import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue'; -import mockAlerts from '../mocks/alerts.json'; - -const mockAlert = mockAlerts[0]; -const environmentName = 'Production'; -const environmentPath = '/fake/path'; - -describe('AlertDetails', () => { - let environmentData = { name: environmentName, path: environmentPath }; - let mock; - let wrapper; - const projectPath = 'root/alerts'; - const projectIssuesPath = 'root/alerts/-/issues'; - const projectId = '1'; - const $router = { replace: jest.fn() }; - - function mountComponent({ data, loading = false, mountMethod = shallowMount, stubs = {} } = {}) { - wrapper = extendedWrapper( - mountMethod(AlertDetails, { - provide: { - alertId: 'alertId', - projectPath, - projectIssuesPath, - projectId, - }, - data() { - return { - alert: { - ...mockAlert, - environment: environmentData, - }, - sidebarStatus: false, - ...data, - }; - }, - mocks: { - $apollo: { - mutate: jest.fn(), - queries: { - alert: { - loading, - }, - sidebarStatus: {}, - }, - }, - $router, - $route: { params: {} }, - }, - stubs: { - ...stubs, - AlertSummaryRow, - }, - }), - ); - } - - beforeEach(() => { - mock = new MockAdapter(axios); - }); - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - } - mock.restore(); - }); - - 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'); - const findDetailsTable = () => wrapper.find(AlertDetailsTable); - - describe('Alert details', () => { - describe('when alert is null', () => { - beforeEach(() => { - mountComponent({ data: { alert: null } }); - }); - - it('shows an empty state', () => { - expect(wrapper.findByTestId('alertDetailsTabs').exists()).toBe(false); - }); - }); - - describe('when alert is present', () => { - beforeEach(() => { - mountComponent({ data: { alert: mockAlert } }); - }); - - it('renders a tab with overview information', () => { - expect(wrapper.findByTestId('overview').exists()).toBe(true); - }); - - it('renders a tab with an activity feed', () => { - expect(wrapper.findByTestId('activity').exists()).toBe(true); - }); - - it('renders severity', () => { - expect(wrapper.findByTestId('severity').text()).toBe( - ALERTS_SEVERITY_LABELS[mockAlert.severity], - ); - }); - - it('renders a title', () => { - expect(wrapper.findByTestId('title').text()).toBe(mockAlert.title); - }); - - it('renders a start time', () => { - expect(wrapper.findByTestId('startTimeItem').exists()).toBe(true); - expect(wrapper.findByTestId('startTimeItem').props('time')).toBe(mockAlert.startedAt); - }); - }); - - 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} - ${'runbook'} | ${undefined} | ${false} - ${'runbook'} | ${'run.com'} | ${true} - `(`$desc`, ({ field, data, isShown }) => { - beforeEach(() => { - mountComponent({ data: { alert: { ...mockAlert, [field]: data } } }); - }); - - it(`${field} is ${isShown ? 'displayed' : 'hidden'} correctly`, () => { - const element = wrapper.findByTestId(field); - if (isShown) { - expect(element.text()).toContain(data.toString()); - } else { - expect(wrapper.findByTestId(field).exists()).toBe(false); - } - }); - }); - }); - - describe('environment fields', () => { - it('should show the environment name with a link to the path', () => { - mountComponent(); - const path = findEnvironmentPath(); - - expect(findEnvironmentName().exists()).toBe(false); - expect(path.text()).toBe(environmentName); - expect(path.attributes('href')).toBe(environmentPath); - }); - - it('should only show the environment name if the path is not provided', () => { - environmentData = { name: environmentName, path: null }; - mountComponent(); - - expect(findEnvironmentPath().exists()).toBe(false); - expect(findEnvironmentName().text()).toBe(environmentName); - }); - }); - - describe('Create incident from alert', () => { - it('should display "View incident" button that links the incident page when incident exists', () => { - const issueIid = '3'; - mountComponent({ - data: { alert: { ...mockAlert, issueIid }, sidebarStatus: false }, - }); - - expect(findViewIncidentBtn().exists()).toBe(true); - expect(findViewIncidentBtn().attributes('href')).toBe( - joinPaths(projectIssuesPath, issueIid), - ); - expect(findCreateIncidentBtn().exists()).toBe(false); - }); - - it('should display "Create incident" button when incident doesn\'t exist yet', () => { - const issueIid = null; - mountComponent({ - mountMethod: mount, - data: { alert: { ...mockAlert, issueIid } }, - }); - - return wrapper.vm.$nextTick().then(() => { - expect(findViewIncidentBtn().exists()).toBe(false); - expect(findCreateIncidentBtn().exists()).toBe(true); - }); - }); - - it('calls `$apollo.mutate` with `createIssueQuery`', () => { - const issueIid = '10'; - mountComponent({ - mountMethod: mount, - data: { alert: { ...mockAlert } }, - }); - - jest - .spyOn(wrapper.vm.$apollo, 'mutate') - .mockResolvedValue({ data: { createAlertIssue: { issue: { iid: issueIid } } } }); - findCreateIncidentBtn().trigger('click'); - - expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ - mutation: createIssueMutation, - variables: { - iid: mockAlert.iid, - projectPath, - }, - }); - }); - - it('shows error alert when incident creation fails ', async () => { - const errorMsg = 'Something went wrong'; - mountComponent({ - mountMethod: mount, - data: { alert: { ...mockAlert, alertIid: 1 } }, - }); - - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg); - findCreateIncidentBtn().trigger('click'); - - await waitForPromises(); - expect(findIncidentCreationAlert().text()).toBe(errorMsg); - }); - }); - - describe('View full alert details', () => { - beforeEach(() => { - mountComponent({ data: { alert: mockAlert } }); - }); - - 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); - }); - - it('renders html-errors correctly', () => { - mountComponent({ - data: { errored: true, sidebarErrorMessage: '<span data-testid="htmlError" />' }, - }); - expect(wrapper.findByTestId('htmlError').exists()).toBe(true); - }); - - it('does not display an error when dismissed', () => { - mountComponent({ data: { errored: true, isErrorDismissed: true } }); - expect(wrapper.find(GlAlert).exists()).toBe(false); - }); - }); - - describe('header', () => { - const findHeader = () => wrapper.findByTestId('alert-header'); - const stubs = { TimeAgoTooltip: { template: '<span>now</span>' } }; - - describe('individual header fields', () => { - describe.each` - 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'} - `( - `When createdAt=$createdAt, monitoringTool=$monitoringTool`, - ({ createdAt, monitoringTool, result }) => { - beforeEach(() => { - mountComponent({ - data: { alert: { ...mockAlert, createdAt, monitoringTool } }, - mountMethod: mount, - stubs, - }); - }); - - it('header text is shown correctly', () => { - expect(findHeader().text()).toBe(result); - }); - }, - ); - }); - }); - - describe('tab navigation', () => { - beforeEach(() => { - mountComponent({ data: { alert: mockAlert } }); - }); - - it.each` - index | tabId - ${0} | ${'overview'} - ${1} | ${'metrics'} - ${2} | ${'activity'} - `('will navigate to the correct tab via $tabId', ({ index, tabId }) => { - wrapper.setData({ currentTabIndex: index }); - expect($router.replace).toHaveBeenCalledWith({ name: 'tab', params: { tabId } }); - }); - }); - }); - - describe('Snowplow tracking', () => { - beforeEach(() => { - jest.spyOn(Tracking, 'event'); - mountComponent({ - props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, - data: { alert: mockAlert }, - loading: false, - }); - }); - - it('should track alert details page views', () => { - const { category, action } = trackAlertsDetailsViewsOptions; - expect(Tracking.event).toHaveBeenCalledWith(category, action); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/alert_management_empty_state_spec.js b/spec/frontend/alert_management/components/alert_management_empty_state_spec.js index 509c67743c1..c2bf90e7635 100644 --- a/spec/frontend/alert_management/components/alert_management_empty_state_spec.js +++ b/spec/frontend/alert_management/components/alert_management_empty_state_spec.js @@ -1,5 +1,5 @@ -import { shallowMount } from '@vue/test-utils'; import { GlEmptyState } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; import AlertManagementEmptyState from '~/alert_management/components/alert_management_empty_state.vue'; import defaultProvideValues from '../mocks/alerts_provide_config.json'; diff --git a/spec/frontend/alert_management/components/alert_management_list_wrapper_spec.js b/spec/frontend/alert_management/components/alert_management_list_wrapper_spec.js index 1d79b10a796..bba5fcbbf08 100644 --- a/spec/frontend/alert_management/components/alert_management_list_wrapper_spec.js +++ b/spec/frontend/alert_management/components/alert_management_list_wrapper_spec.js @@ -1,6 +1,6 @@ import { shallowMount } from '@vue/test-utils'; -import AlertManagementList from '~/alert_management/components/alert_management_list_wrapper.vue'; import AlertManagementEmptyState from '~/alert_management/components/alert_management_empty_state.vue'; +import AlertManagementList from '~/alert_management/components/alert_management_list_wrapper.vue'; import AlertManagementTable from '~/alert_management/components/alert_management_table.vue'; import defaultProvideValues from '../mocks/alerts_provide_config.json'; diff --git a/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js b/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js deleted file mode 100644 index ea7b4584a63..00000000000 --- a/spec/frontend/alert_management/components/alert_management_sidebar_todo_spec.js +++ /dev/null @@ -1,112 +0,0 @@ -import { mount } from '@vue/test-utils'; -import SidebarTodo from '~/alert_management/components/sidebar/sidebar_todo.vue'; -import createAlertTodoMutation from '~/alert_management/graphql/mutations/alert_todo_create.mutation.graphql'; -import todoMarkDoneMutation from '~/graphql_shared/mutations/todo_mark_done.mutation.graphql'; -import mockAlerts from '../mocks/alerts.json'; - -const mockAlert = mockAlerts[0]; - -describe('Alert Details Sidebar To Do', () => { - let wrapper; - - function mountComponent({ data, sidebarCollapsed = true, loading = false, stubs = {} } = {}) { - wrapper = mount(SidebarTodo, { - propsData: { - alert: { ...mockAlert }, - ...data, - sidebarCollapsed, - projectPath: 'projectPath', - }, - mocks: { - $apollo: { - mutate: jest.fn(), - queries: { - alert: { - loading, - }, - }, - }, - }, - stubs, - }); - } - - afterEach(() => { - wrapper.destroy(); - }); - - const findToDoButton = () => wrapper.find('[data-testid="alert-todo-button"]'); - - describe('updating the alert to do', () => { - const mockUpdatedMutationResult = { - data: { - updateAlertTodo: { - errors: [], - alert: {}, - }, - }, - }; - - describe('adding a todo', () => { - beforeEach(() => { - mountComponent({ - data: { alert: mockAlert }, - sidebarCollapsed: false, - loading: false, - }); - }); - - it('renders a button for adding a To-Do', async () => { - await wrapper.vm.$nextTick(); - - expect(findToDoButton().text()).toBe('Add a To-Do'); - }); - - it('calls `$apollo.mutate` with `createAlertTodoMutation` mutation and variables containing `iid`, `todoEvent`, & `projectPath`', async () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); - - findToDoButton().trigger('click'); - await wrapper.vm.$nextTick(); - - expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ - mutation: createAlertTodoMutation, - variables: { - iid: '1527542', - projectPath: 'projectPath', - }, - }); - }); - }); - - describe('removing a todo', () => { - beforeEach(() => { - mountComponent({ - data: { alert: { ...mockAlert, todos: { nodes: [{ id: '1234' }] } } }, - sidebarCollapsed: false, - loading: false, - }); - }); - - it('renders a Mark As Done button when todo is present', async () => { - await wrapper.vm.$nextTick(); - - expect(findToDoButton().text()).toBe('Mark as done'); - }); - - it('calls `$apollo.mutate` with `todoMarkDoneMutation` mutation and variables containing `id`', async () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); - - findToDoButton().trigger('click'); - await wrapper.vm.$nextTick(); - - expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ - mutation: todoMarkDoneMutation, - update: expect.anything(), - variables: { - id: '1234', - }, - }); - }); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/alert_management_table_spec.js b/spec/frontend/alert_management/components/alert_management_table_spec.js index 0cc3d565e10..cea665aa50d 100644 --- a/spec/frontend/alert_management/components/alert_management_table_spec.js +++ b/spec/frontend/alert_management/components/alert_management_table_spec.js @@ -1,12 +1,12 @@ -import { mount } from '@vue/test-utils'; import { GlTable, GlAlert, GlLoadingIcon, GlDropdown, GlIcon, GlAvatar } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import { visitUrl } from '~/lib/utils/url_utility'; -import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; +import mockAlerts from 'jest/vue_shared/alert_details/mocks/alerts.json'; import AlertManagementTable from '~/alert_management/components/alert_management_table.vue'; +import { visitUrl } from '~/lib/utils/url_utility'; import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue'; -import mockAlerts from '../mocks/alerts.json'; +import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import defaultProvideValues from '../mocks/alerts_provide_config.json'; jest.mock('~/lib/utils/url_utility', () => ({ diff --git a/spec/frontend/alert_management/components/alert_metrics_spec.js b/spec/frontend/alert_management/components/alert_metrics_spec.js deleted file mode 100644 index 42da8c3768b..00000000000 --- a/spec/frontend/alert_management/components/alert_metrics_spec.js +++ /dev/null @@ -1,62 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import waitForPromises from 'helpers/wait_for_promises'; -import MockAdapter from 'axios-mock-adapter'; -import axios from 'axios'; -import AlertMetrics from '~/alert_management/components/alert_metrics.vue'; -import MetricEmbed from '~/monitoring/components/embeds/metric_embed.vue'; - -jest.mock('~/monitoring/stores', () => ({ - monitoringDashboard: {}, -})); - -jest.mock('~/monitoring/components/embeds/metric_embed.vue', () => ({ - render(h) { - return h('div'); - }, -})); - -describe('Alert Metrics', () => { - let wrapper; - const mock = new MockAdapter(axios); - - function mountComponent({ props } = {}) { - wrapper = shallowMount(AlertMetrics, { - propsData: { - ...props, - }, - }); - } - - const findChart = () => wrapper.find(MetricEmbed); - const findEmptyState = () => wrapper.find({ ref: 'emptyState' }); - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - } - }); - - afterAll(() => { - mock.restore(); - }); - - describe('Empty state', () => { - it('should display a message when metrics dashboard url is not provided ', () => { - mountComponent(); - expect(findChart().exists()).toBe(false); - expect(findEmptyState().text()).toBe("Metrics weren't available in the alerts payload."); - }); - }); - - describe('Chart', () => { - it('should be rendered when dashboard url is provided', async () => { - mountComponent({ props: { dashboardUrl: 'metrics.url' } }); - - await waitForPromises(); - await wrapper.vm.$nextTick(); - - expect(findEmptyState().exists()).toBe(false); - expect(findChart().exists()).toBe(true); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/alert_status_spec.js b/spec/frontend/alert_management/components/alert_status_spec.js deleted file mode 100644 index 6f2ddb86020..00000000000 --- a/spec/frontend/alert_management/components/alert_status_spec.js +++ /dev/null @@ -1,151 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; -import waitForPromises from 'helpers/wait_for_promises'; -import { trackAlertStatusUpdateOptions } from '~/alert_management/constants'; -import AlertManagementStatus from '~/alert_management/components/alert_status.vue'; -import updateAlertStatusMutation from '~/graphql_shared/mutations/update_alert_status.mutation.graphql'; -import Tracking from '~/tracking'; -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 = {}, loading = false, stubs = {} } = {}) { - wrapper = shallowMount(AlertManagementStatus, { - propsData: { - alert: { ...mockAlert }, - projectPath: 'gitlab-org/gitlab', - isSidebar: false, - ...props, - }, - 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'); - mountComponent({}); - }); - - it('should track alert status updates', () => { - 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 }); - }); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/alert_summary_row_spec.js b/spec/frontend/alert_management/components/alert_summary_row_spec.js deleted file mode 100644 index 47c715c089a..00000000000 --- a/spec/frontend/alert_management/components/alert_summary_row_spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import AlertSummaryRow from '~/alert_management/components/alert_summary_row.vue'; - -const label = 'a label'; -const value = 'a value'; - -describe('AlertSummaryRow', () => { - let wrapper; - - function mountComponent({ mountMethod = shallowMount, props, defaultSlot } = {}) { - wrapper = mountMethod(AlertSummaryRow, { - propsData: props, - scopedSlots: { - default: defaultSlot, - }, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - wrapper = null; - } - }); - - describe('Alert Summary Row', () => { - beforeEach(() => { - mountComponent({ - props: { - label, - }, - defaultSlot: `<span class="value">${value}</span>`, - }); - }); - - it('should display a label and a value', () => { - expect(wrapper.text()).toBe(`${label} ${value}`); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/sidebar/alert_managment_sidebar_assignees_spec.js b/spec/frontend/alert_management/components/sidebar/alert_managment_sidebar_assignees_spec.js deleted file mode 100644 index 00c479071fe..00000000000 --- a/spec/frontend/alert_management/components/sidebar/alert_managment_sidebar_assignees_spec.js +++ /dev/null @@ -1,173 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; -import { GlDropdownItem } from '@gitlab/ui'; -import SidebarAssignee from '~/alert_management/components/sidebar/sidebar_assignee.vue'; -import SidebarAssignees from '~/alert_management/components/sidebar/sidebar_assignees.vue'; -import AlertSetAssignees from '~/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql'; -import mockAlerts from '../../mocks/alerts.json'; - -const mockAlert = mockAlerts[0]; - -describe('Alert Details Sidebar Assignees', () => { - let wrapper; - let mock; - - function mountComponent({ - data, - users = [], - isDropdownSearching = false, - sidebarCollapsed = true, - loading = false, - stubs = {}, - } = {}) { - wrapper = shallowMount(SidebarAssignees, { - data() { - return { - users, - isDropdownSearching, - }; - }, - propsData: { - alert: { ...mockAlert }, - ...data, - sidebarCollapsed, - projectPath: 'projectPath', - projectId: '1', - }, - mocks: { - $apollo: { - mutate: jest.fn(), - queries: { - alert: { - loading, - }, - }, - }, - }, - stubs, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - } - mock.restore(); - }); - - const findAssigned = () => wrapper.find('[data-testid="assigned-users"]'); - const findUnassigned = () => wrapper.find('[data-testid="unassigned-users"]'); - - describe('updating the alert status', () => { - const mockUpdatedMutationResult = { - data: { - alertSetAssignees: { - errors: [], - alert: { - assigneeUsernames: ['root'], - }, - }, - }, - }; - - beforeEach(() => { - mock = new MockAdapter(axios); - const path = '/-/autocomplete/users.json'; - const users = [ - { - avatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - id: 1, - name: 'User 1', - username: 'root', - }, - { - avatar_url: - 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', - id: 2, - name: 'User 2', - username: 'not-root', - }, - ]; - - mock.onGet(path).replyOnce(200, users); - mountComponent({ - data: { alert: mockAlert }, - sidebarCollapsed: false, - loading: false, - users, - stubs: { - SidebarAssignee, - }, - }); - }); - - it('renders a unassigned option', async () => { - wrapper.setData({ isDropdownSearching: false }); - await wrapper.vm.$nextTick(); - expect(wrapper.find(GlDropdownItem).text()).toBe('Unassigned'); - }); - - it('calls `$apollo.mutate` with `AlertSetAssignees` mutation and variables containing `iid`, `assigneeUsernames`, & `projectPath`', async () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); - wrapper.setData({ isDropdownSearching: false }); - - await wrapper.vm.$nextTick(); - wrapper.find(SidebarAssignee).vm.$emit('update-alert-assignees', 'root'); - - expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ - mutation: AlertSetAssignees, - variables: { - iid: '1527542', - assigneeUsernames: ['root'], - projectPath: 'projectPath', - }, - }); - }); - - it('emits an error when request contains error messages', () => { - wrapper.setData({ isDropdownSearching: false }); - const errorMutationResult = { - data: { - alertSetAssignees: { - errors: ['There was a problem for sure.'], - alert: {}, - }, - }, - }; - - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(errorMutationResult); - return wrapper.vm - .$nextTick() - .then(() => { - const SideBarAssigneeItem = wrapper.findAll(SidebarAssignee).at(0); - SideBarAssigneeItem.vm.$emit('update-alert-assignees'); - }) - .then(() => { - expect(wrapper.emitted('alert-error')).toBeDefined(); - }); - }); - - it('stops updating and cancels loading when the request fails', () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); - wrapper.vm.updateAlertAssignees('root'); - expect(findUnassigned().text()).toBe('assign yourself'); - }); - - it('shows a user avatar, username and full name when a user is set', () => { - mountComponent({ - data: { alert: mockAlerts[1] }, - sidebarCollapsed: false, - loading: false, - stubs: { - SidebarAssignee, - }, - }); - - expect(findAssigned().find('img').attributes('src')).toBe('/url'); - expect(findAssigned().find('.dropdown-menu-user-full-name').text()).toBe('root'); - expect(findAssigned().find('.dropdown-menu-user-username').text()).toBe('@root'); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/sidebar/alert_sidebar_spec.js b/spec/frontend/alert_management/components/sidebar/alert_sidebar_spec.js deleted file mode 100644 index 5235ae63fee..00000000000 --- a/spec/frontend/alert_management/components/sidebar/alert_sidebar_spec.js +++ /dev/null @@ -1,64 +0,0 @@ -import { shallowMount, mount } from '@vue/test-utils'; -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; -import AlertSidebar from '~/alert_management/components/alert_sidebar.vue'; -import SidebarAssignees from '~/alert_management/components/sidebar/sidebar_assignees.vue'; -import mockAlerts from '../../mocks/alerts.json'; - -const mockAlert = mockAlerts[0]; - -describe('Alert Details Sidebar', () => { - let wrapper; - let mock; - - function mountComponent({ mountMethod = shallowMount, stubs = {}, alert = {} } = {}) { - wrapper = mountMethod(AlertSidebar, { - data() { - return { - sidebarStatus: false, - }; - }, - propsData: { - alert, - }, - provide: { - projectPath: 'projectPath', - projectId: '1', - }, - stubs, - mocks: { - $apollo: { - queries: { - sidebarStatus: {}, - }, - }, - }, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - } - mock.restore(); - }); - - describe('the sidebar renders', () => { - beforeEach(() => { - mock = new MockAdapter(axios); - mountComponent(); - }); - - it('open as default', () => { - expect(wrapper.classes('right-sidebar-expanded')).toBe(true); - }); - - it('should render side bar assignee dropdown', () => { - mountComponent({ - mountMethod: mount, - alert: mockAlert, - }); - expect(wrapper.find(SidebarAssignees).exists()).toBe(true); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js b/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js deleted file mode 100644 index 0b60a36cf54..00000000000 --- a/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js +++ /dev/null @@ -1,130 +0,0 @@ -import { mount } from '@vue/test-utils'; -import { GlDropdown, GlDropdownItem, GlLoadingIcon } from '@gitlab/ui'; -import { trackAlertStatusUpdateOptions } from '~/alert_management/constants'; -import AlertSidebarStatus from '~/alert_management/components/sidebar/sidebar_status.vue'; -import updateAlertStatusMutation from '~/graphql_shared/mutations/update_alert_status.mutation.graphql'; -import Tracking from '~/tracking'; -import mockAlerts from '../../mocks/alerts.json'; - -const mockAlert = mockAlerts[0]; - -describe('Alert Details Sidebar Status', () => { - let wrapper; - const findStatusDropdown = () => wrapper.find(GlDropdown); - const findStatusDropdownItem = () => wrapper.find(GlDropdownItem); - const findStatusLoadingIcon = () => wrapper.find(GlLoadingIcon); - const findStatusDropdownHeader = () => wrapper.find('[data-testid="dropdown-header"]'); - - function mountComponent({ data, sidebarCollapsed = true, loading = false, stubs = {} } = {}) { - wrapper = mount(AlertSidebarStatus, { - propsData: { - alert: { ...mockAlert }, - ...data, - sidebarCollapsed, - projectPath: 'projectPath', - }, - mocks: { - $apollo: { - mutate: jest.fn(), - queries: { - alert: { - loading, - }, - }, - }, - }, - stubs, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - } - }); - - describe('Alert Sidebar Dropdown Status', () => { - beforeEach(() => { - mountComponent({ - data: { alert: mockAlert }, - sidebarCollapsed: false, - loading: false, - }); - }); - - it('displays status dropdown', () => { - expect(findStatusDropdown().exists()).toBe(true); - }); - - it('displays the dropdown status header', () => { - expect(findStatusDropdownHeader().exists()).toBe(true); - }); - - describe('updating the alert status', () => { - const mockUpdatedMutationResult = { - data: { - updateAlertStatus: { - errors: [], - alert: { - status: 'acknowledged', - }, - }, - }, - }; - - beforeEach(() => { - mountComponent({ - data: { alert: mockAlert }, - sidebarCollapsed: false, - loading: false, - }); - }); - - it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); - findStatusDropdownItem().vm.$emit('click'); - - expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ - mutation: updateAlertStatusMutation, - variables: { - iid: '1527542', - status: 'TRIGGERED', - projectPath: 'projectPath', - }, - }); - }); - - it('stops updating when the request fails', () => { - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); - findStatusDropdownItem().vm.$emit('click'); - expect(findStatusLoadingIcon().exists()).toBe(false); - expect(wrapper.find('[data-testid="status"]').text()).toBe('Triggered'); - }); - }); - - describe('Snowplow tracking', () => { - beforeEach(() => { - jest.spyOn(Tracking, 'event'); - mountComponent({ - props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, - data: { alert: mockAlert }, - loading: false, - }); - }); - - it('should track alert status updates', () => { - Tracking.event.mockClear(); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({}); - findStatusDropdownItem().vm.$emit('click'); - const status = findStatusDropdownItem().text(); - setImmediate(() => { - const { category, action, label } = trackAlertStatusUpdateOptions; - expect(Tracking.event).toHaveBeenCalledWith(category, action, { - label, - property: status, - }); - }); - }); - }); - }); -}); diff --git a/spec/frontend/alert_management/components/system_notes/alert_management_system_note_spec.js b/spec/frontend/alert_management/components/system_notes/alert_management_system_note_spec.js deleted file mode 100644 index 65cfc600d76..00000000000 --- a/spec/frontend/alert_management/components/system_notes/alert_management_system_note_spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlIcon } from '@gitlab/ui'; -import SystemNote from '~/alert_management/components/system_notes/system_note.vue'; -import mockAlerts from '../../mocks/alerts.json'; - -const mockAlert = mockAlerts[1]; - -describe('Alert Details System Note', () => { - let wrapper; - - function mountComponent({ stubs = {} } = {}) { - wrapper = shallowMount(SystemNote, { - propsData: { - note: { ...mockAlert.notes.nodes[0] }, - }, - stubs, - }); - } - - afterEach(() => { - if (wrapper) { - wrapper.destroy(); - wrapper = null; - } - }); - - describe('System notes', () => { - beforeEach(() => { - mountComponent({}); - }); - - it('renders the correct system note', () => { - const noteId = wrapper.find('.note-wrapper').attributes('id'); - const iconName = wrapper.find(GlIcon).attributes('name'); - - expect(noteId).toBe('note_1628'); - expect(iconName).toBe(mockAlert.notes.nodes[0].systemNoteIconName); - }); - }); -}); |