diff options
Diffstat (limited to 'spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js')
-rw-r--r-- | spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js | 231 |
1 files changed, 155 insertions, 76 deletions
diff --git a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js index 80293597ab6..77fac6dd022 100644 --- a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js +++ b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js @@ -2,21 +2,26 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { mount, createLocalVue } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; import VueApollo from 'vue-apollo'; +import createHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql'; +import updateHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql'; import createMockApollo from 'helpers/mock_apollo_helper'; import { useMockIntersectionObserver } from 'helpers/mock_dom_observer'; import waitForPromises from 'helpers/wait_for_promises'; import IntegrationsList from '~/alerts_settings/components/alerts_integrations_list.vue'; import AlertsSettingsForm from '~/alerts_settings/components/alerts_settings_form.vue'; -import AlertsSettingsWrapper from '~/alerts_settings/components/alerts_settings_wrapper.vue'; +import AlertsSettingsWrapper, { + i18n, +} from '~/alerts_settings/components/alerts_settings_wrapper.vue'; import { typeSet } from '~/alerts_settings/constants'; -import createHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql'; import createPrometheusIntegrationMutation from '~/alerts_settings/graphql/mutations/create_prometheus_integration.mutation.graphql'; import destroyHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/destroy_http_integration.mutation.graphql'; import resetHttpTokenMutation from '~/alerts_settings/graphql/mutations/reset_http_token.mutation.graphql'; import resetPrometheusTokenMutation from '~/alerts_settings/graphql/mutations/reset_prometheus_token.mutation.graphql'; -import updateHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql'; +import updateCurrentHttpIntegrationMutation from '~/alerts_settings/graphql/mutations/update_current_http_integration.mutation.graphql'; +import updateCurrentPrometheusIntegrationMutation from '~/alerts_settings/graphql/mutations/update_current_prometheus_integration.mutation.graphql'; import updatePrometheusIntegrationMutation from '~/alerts_settings/graphql/mutations/update_prometheus_integration.mutation.graphql'; import getIntegrationsQuery from '~/alerts_settings/graphql/queries/get_integrations.query.graphql'; +import alertsUpdateService from '~/alerts_settings/services'; import { ADD_INTEGRATION_ERROR, RESET_INTEGRATION_TOKEN_ERROR, @@ -24,14 +29,15 @@ import { INTEGRATION_PAYLOAD_TEST_ERROR, DELETE_INTEGRATION_ERROR, } from '~/alerts_settings/utils/error_messages'; -import createFlash from '~/flash'; +import createFlash, { FLASH_TYPES } from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { createHttpVariables, updateHttpVariables, createPrometheusVariables, updatePrometheusVariables, - ID, + HTTP_ID, + PROMETHEUS_ID, errorMsg, getIntegrationsQueryResponse, destroyIntegrationResponse, @@ -50,9 +56,33 @@ describe('AlertsSettingsWrapper', () => { let fakeApollo; let destroyIntegrationHandler; useMockIntersectionObserver(); + const httpMappingData = { + payloadExample: '{"test: : "field"}', + payloadAttributeMappings: [], + payloadAlertFields: [], + }; + const httpIntegrations = { + list: [ + { + id: mockIntegrations[0].id, + ...httpMappingData, + }, + { + id: mockIntegrations[1].id, + ...httpMappingData, + }, + { + id: mockIntegrations[2].id, + httpMappingData, + }, + ], + }; - const findLoader = () => wrapper.find(IntegrationsList).find(GlLoadingIcon); + const findLoader = () => wrapper.findComponent(IntegrationsList).findComponent(GlLoadingIcon); + const findIntegrationsList = () => wrapper.findComponent(IntegrationsList); const findIntegrations = () => wrapper.find(IntegrationsList).findAll('table tbody tr'); + const findAddIntegrationBtn = () => wrapper.find('[data-testid="add-integration-btn"]'); + const findAlertsSettingsForm = () => wrapper.findComponent(AlertsSettingsForm); async function destroyHttpIntegration(localWrapper) { await jest.runOnlyPendingTimers(); @@ -119,14 +149,37 @@ describe('AlertsSettingsWrapper', () => { wrapper = null; }); - describe('rendered via default permissions', () => { - it('renders the GraphQL alerts integrations list and new form', () => { - createComponent(); - expect(wrapper.find(IntegrationsList).exists()).toBe(true); - expect(wrapper.find(AlertsSettingsForm).exists()).toBe(true); + describe('template', () => { + beforeEach(() => { + createComponent({ + data: { + integrations: { list: mockIntegrations }, + httpIntegrations: { list: [] }, + currentIntegration: mockIntegrations[0], + }, + loading: false, + }); }); - it('uses a loading state inside the IntegrationsList table', () => { + it('renders alerts integrations list and add new integration button by default', () => { + expect(findLoader().exists()).toBe(false); + expect(findIntegrations()).toHaveLength(mockIntegrations.length); + expect(findAddIntegrationBtn().exists()).toBe(true); + }); + + it('does NOT render settings form by default', () => { + expect(findAlertsSettingsForm().exists()).toBe(false); + }); + + it('hides `add new integration` button and displays setting form on btn click', async () => { + const addNewIntegrationBtn = findAddIntegrationBtn(); + expect(addNewIntegrationBtn.exists()).toBe(true); + await addNewIntegrationBtn.trigger('click'); + expect(findAlertsSettingsForm().exists()).toBe(true); + expect(addNewIntegrationBtn.exists()).toBe(false); + }); + + it('shows loading indicator inside the IntegrationsList table', () => { createComponent({ data: { integrations: {} }, loading: true, @@ -134,26 +187,24 @@ describe('AlertsSettingsWrapper', () => { expect(wrapper.find(IntegrationsList).exists()).toBe(true); expect(findLoader().exists()).toBe(true); }); + }); - it('renders the IntegrationsList table using the API data', () => { + describe('Integration updates', () => { + beforeEach(() => { createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + data: { + integrations: { list: mockIntegrations }, + currentIntegration: mockIntegrations[0], + formVisible: true, + }, loading: false, }); - expect(findLoader().exists()).toBe(false); - expect(findIntegrations()).toHaveLength(mockIntegrations.length); }); - it('calls `$apollo.mutate` with `createHttpIntegrationMutation`', () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { createHttpIntegrationMutation: { integration: { id: '1' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('create-new-integration', { + findAlertsSettingsForm().vm.$emit('create-new-integration', { type: typeSet.http, variables: createHttpVariables, }); @@ -167,15 +218,10 @@ describe('AlertsSettingsWrapper', () => { }); it('calls `$apollo.mutate` with `updateHttpIntegrationMutation`', () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { updateHttpIntegrationMutation: { integration: { id: '1' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('update-integration', { + findAlertsSettingsForm().vm.$emit('update-integration', { type: typeSet.http, variables: updateHttpVariables, }); @@ -187,37 +233,27 @@ describe('AlertsSettingsWrapper', () => { }); it('calls `$apollo.mutate` with `resetHttpTokenMutation`', () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { resetHttpTokenMutation: { integration: { id: '1' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('reset-token', { + findAlertsSettingsForm().vm.$emit('reset-token', { type: typeSet.http, - variables: { id: ID }, + variables: { id: HTTP_ID }, }); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: resetHttpTokenMutation, variables: { - id: ID, + id: HTTP_ID, }, }); }); it('calls `$apollo.mutate` with `createPrometheusIntegrationMutation`', () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { createPrometheusIntegrationMutation: { integration: { id: '2' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('create-new-integration', { + findAlertsSettingsForm().vm.$emit('create-new-integration', { type: typeSet.prometheus, variables: createPrometheusVariables, }); @@ -232,14 +268,18 @@ describe('AlertsSettingsWrapper', () => { it('calls `$apollo.mutate` with `updatePrometheusIntegrationMutation`', () => { createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + data: { + integrations: { list: mockIntegrations }, + currentIntegration: mockIntegrations[3], + formVisible: true, + }, loading: false, }); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { updatePrometheusIntegrationMutation: { integration: { id: '2' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('update-integration', { + findAlertsSettingsForm().vm.$emit('update-integration', { type: typeSet.prometheus, variables: updatePrometheusVariables, }); @@ -251,35 +291,25 @@ describe('AlertsSettingsWrapper', () => { }); it('calls `$apollo.mutate` with `resetPrometheusTokenMutation`', () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({ data: { resetPrometheusTokenMutation: { integration: { id: '1' } } }, }); - wrapper.find(AlertsSettingsForm).vm.$emit('reset-token', { + findAlertsSettingsForm().vm.$emit('reset-token', { type: typeSet.prometheus, - variables: { id: ID }, + variables: { id: PROMETHEUS_ID }, }); expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: resetPrometheusTokenMutation, variables: { - id: ID, + id: PROMETHEUS_ID, }, }); }); it('shows an error alert when integration creation fails ', async () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(ADD_INTEGRATION_ERROR); - wrapper.find(AlertsSettingsForm).vm.$emit('create-new-integration', {}); + findAlertsSettingsForm().vm.$emit('create-new-integration', {}); await waitForPromises(); @@ -287,28 +317,18 @@ describe('AlertsSettingsWrapper', () => { }); it('shows an error alert when integration token reset fails ', async () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(RESET_INTEGRATION_TOKEN_ERROR); - wrapper.find(AlertsSettingsForm).vm.$emit('reset-token', {}); + findAlertsSettingsForm().vm.$emit('reset-token', {}); await waitForPromises(); expect(createFlash).toHaveBeenCalledWith({ message: RESET_INTEGRATION_TOKEN_ERROR }); }); it('shows an error alert when integration update fails ', async () => { - createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, - loading: false, - }); - jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(errorMsg); - wrapper.find(AlertsSettingsForm).vm.$emit('update-integration', {}); + findAlertsSettingsForm().vm.$emit('update-integration', {}); await waitForPromises(); expect(createFlash).toHaveBeenCalledWith({ message: UPDATE_INTEGRATION_ERROR }); @@ -317,15 +337,74 @@ describe('AlertsSettingsWrapper', () => { it('shows an error alert when integration test payload fails ', async () => { const mock = new AxiosMockAdapter(axios); mock.onPost(/(.*)/).replyOnce(403); + return wrapper.vm.testAlertPayload({ endpoint: '', data: '', token: '' }).then(() => { + expect(createFlash).toHaveBeenCalledWith({ message: INTEGRATION_PAYLOAD_TEST_ERROR }); + expect(createFlash).toHaveBeenCalledTimes(1); + mock.restore(); + }); + }); + + it('calls `$apollo.mutate` with `updateCurrentHttpIntegrationMutation` on HTTP integration edit', () => { createComponent({ - data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] }, + data: { + integrations: { list: mockIntegrations }, + currentIntegration: mockIntegrations[0], + httpIntegrations, + }, loading: false, }); - return wrapper.vm.validateAlertPayload({ endpoint: '', data: '', token: '' }).then(() => { - expect(createFlash).toHaveBeenCalledWith({ message: INTEGRATION_PAYLOAD_TEST_ERROR }); - expect(createFlash).toHaveBeenCalledTimes(1); - mock.restore(); + jest.spyOn(wrapper.vm.$apollo, 'mutate'); + findIntegrationsList().vm.$emit('edit-integration', updateHttpVariables); + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateCurrentHttpIntegrationMutation, + variables: { ...mockIntegrations[0], ...httpMappingData }, + }); + }); + + it('calls `$apollo.mutate` with `updateCurrentPrometheusIntegrationMutation` on PROMETHEUS integration edit', () => { + createComponent({ + data: { + integrations: { list: mockIntegrations }, + currentIntegration: mockIntegrations[3], + httpIntegrations, + }, + loading: false, + }); + + jest.spyOn(wrapper.vm.$apollo, 'mutate'); + findIntegrationsList().vm.$emit('edit-integration', updatePrometheusVariables); + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateCurrentPrometheusIntegrationMutation, + variables: mockIntegrations[3], + }); + }); + + describe('Test alert', () => { + it('makes `updateTestAlert` service call', async () => { + jest.spyOn(alertsUpdateService, 'updateTestAlert').mockResolvedValueOnce(); + const testPayload = '{"title":"test"}'; + findAlertsSettingsForm().vm.$emit('test-alert-payload', testPayload); + expect(alertsUpdateService.updateTestAlert).toHaveBeenCalledWith(testPayload); + }); + + it('shows success message on successful test', async () => { + jest.spyOn(alertsUpdateService, 'updateTestAlert').mockResolvedValueOnce({}); + findAlertsSettingsForm().vm.$emit('test-alert-payload', ''); + await waitForPromises(); + expect(createFlash).toHaveBeenCalledWith({ + message: i18n.alertSent, + type: FLASH_TYPES.SUCCESS, + }); + }); + + it('shows error message when test alert fails', async () => { + jest.spyOn(alertsUpdateService, 'updateTestAlert').mockRejectedValueOnce({}); + findAlertsSettingsForm().vm.$emit('test-alert-payload', ''); + await waitForPromises(); + expect(createFlash).toHaveBeenCalledWith({ + message: INTEGRATION_PAYLOAD_TEST_ERROR, + }); }); }); }); |