diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 12:26:25 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 12:26:25 +0000 |
commit | a09983ae35713f5a2bbb100981116d31ce99826e (patch) | |
tree | 2ee2af7bd104d57086db360a7e6d8c9d5d43667a /spec/frontend/incidents_settings/components | |
parent | 18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff) | |
download | gitlab-ce-a09983ae35713f5a2bbb100981116d31ce99826e.tar.gz |
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'spec/frontend/incidents_settings/components')
7 files changed, 477 insertions, 0 deletions
diff --git a/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap new file mode 100644 index 00000000000..dd3589e2951 --- /dev/null +++ b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Alert integration settings form default state should match the default snapshot 1`] = ` +<div> + <p> + <gl-sprintf-stub + message="Action to take when receiving an alert. %{docsLink}" + /> + </p> + + <form> + <gl-form-group-stub + class="gl-pl-0" + > + <gl-form-checkbox-stub + checked="true" + data-qa-selector="create_issue_checkbox" + > + <span> + Create an issue. Issues are created for each alert triggered. + </span> + </gl-form-checkbox-stub> + </gl-form-group-stub> + + <gl-form-group-stub + class="col-8 col-md-9 gl-px-6" + label-for="alert-integration-settings-issue-template" + label-size="sm" + > + <label + class="gl-display-inline-flex" + for="alert-integration-settings-issue-template" + > + + Issue template (optional) + + <gl-link-stub + href="/help/user/project/description_templates#creating-issue-templates" + target="_blank" + > + <gl-icon-stub + name="question" + size="12" + /> + </gl-link-stub> + </label> + + <gl-new-dropdown-stub + block="true" + category="tertiary" + data-qa-selector="incident_templates_dropdown" + headertext="" + id="alert-integration-settings-issue-template" + size="medium" + text="selecte_tmpl" + variant="default" + > + <gl-new-dropdown-item-stub + avatarurl="" + data-qa-selector="incident_templates_item" + iconcolor="" + iconname="" + iconrightname="" + ischeckitem="true" + secondarytext="" + > + + No template selected + + </gl-new-dropdown-item-stub> + </gl-new-dropdown-stub> + </gl-form-group-stub> + + <gl-form-group-stub + class="gl-pl-0 gl-mb-5" + > + <gl-form-checkbox-stub> + <span> + Send a separate email notification to Developers. + </span> + </gl-form-checkbox-stub> + </gl-form-group-stub> + + <gl-button-stub + category="tertiary" + class="js-no-auto-disable" + data-qa-selector="save_changes_button" + icon="" + size="medium" + type="submit" + variant="success" + > + + Save changes + + </gl-button-stub> + </form> +</div> +`; diff --git a/spec/frontend/incidents_settings/components/__snapshots__/incidents_settings_tabs_spec.js.snap b/spec/frontend/incidents_settings/components/__snapshots__/incidents_settings_tabs_spec.js.snap new file mode 100644 index 00000000000..5f355ee8261 --- /dev/null +++ b/spec/frontend/incidents_settings/components/__snapshots__/incidents_settings_tabs_spec.js.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`IncidentsSettingTabs should render the component 1`] = ` +<section + class="settings no-animate qa-incident-management-settings" + data-qa-selector="incidents_settings_content" + id="incident-management-settings" +> + <div + class="settings-header" + > + <h3 + class="h4" + > + + Incidents + + </h3> + + <gl-button-stub + category="tertiary" + class="js-settings-toggle" + icon="" + size="medium" + variant="default" + > + Expand + </gl-button-stub> + + <p> + + Set up integrations with external tools to help better manage incidents. + + </p> + </div> + + <div + class="settings-content" + > + <gl-tabs-stub + theme="indigo" + > + <gl-tab-stub + title="Alert integration" + > + <alertssettingsform-stub + class="gl-pt-3" + data-testid="AlertsSettingsForm-tab" + /> + </gl-tab-stub> + <gl-tab-stub + title="PagerDuty integration" + > + <pagerdutysettingsform-stub + class="gl-pt-3" + data-testid="PagerDutySettingsForm-tab" + /> + </gl-tab-stub> + <!----> + </gl-tabs-stub> + </div> +</section> +`; diff --git a/spec/frontend/incidents_settings/components/__snapshots__/pagerduty_form_spec.js.snap b/spec/frontend/incidents_settings/components/__snapshots__/pagerduty_form_spec.js.snap new file mode 100644 index 00000000000..17ada722034 --- /dev/null +++ b/spec/frontend/incidents_settings/components/__snapshots__/pagerduty_form_spec.js.snap @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Alert integration settings form should match the default snapshot 1`] = ` +<div> + <!----> + + <p> + Setting up a webhook with PagerDuty will automatically create a GitLab issue for each PagerDuty incident. + </p> + + <form> + <gl-form-group-stub + class="col-8 col-md-9 gl-p-0" + > + <gl-toggle-stub + id="active" + label="Active" + labelposition="top" + value="true" + /> + </gl-form-group-stub> + + <gl-form-group-stub + class="col-8 col-md-9 gl-p-0" + label="Webhook URL" + label-class="label-bold" + label-for="url" + > + <gl-form-input-group-stub + data-testid="webhook-url" + id="url" + predefinedoptions="[object Object]" + readonly="" + value="pagerduty.webhook.com" + /> + + <div + class="gl-text-gray-400 gl-pt-2" + > + <gl-sprintf-stub + message="Create a GitLab issue for each PagerDuty incident by %{docsLink}" + /> + </div> + + <gl-button-stub + category="tertiary" + class="gl-mt-3" + data-testid="webhook-reset-btn" + icon="" + role="button" + size="medium" + tabindex="0" + variant="default" + > + + Reset webhook URL + + </gl-button-stub> + + <gl-modal-stub + modalclass="" + modalid="resetWebhookModal" + ok-title="Reset webhook URL" + ok-variant="danger" + size="md" + title="Reset webhook URL" + titletag="h4" + > + + Resetting the webhook URL for this project will require updating this integration's settings in PagerDuty. + + </gl-modal-stub> + </gl-form-group-stub> + + <gl-button-stub + category="tertiary" + class="js-no-auto-disable" + icon="" + size="medium" + type="submit" + variant="success" + > + + Save changes + + </gl-button-stub> + </form> +</div> +`; diff --git a/spec/frontend/incidents_settings/components/alerts_form_spec.js b/spec/frontend/incidents_settings/components/alerts_form_spec.js new file mode 100644 index 00000000000..04832f31e58 --- /dev/null +++ b/spec/frontend/incidents_settings/components/alerts_form_spec.js @@ -0,0 +1,49 @@ +import { shallowMount } from '@vue/test-utils'; +import AlertsSettingsForm from '~/incidents_settings/components/alerts_form.vue'; + +describe('Alert integration settings form', () => { + let wrapper; + const service = { updateSettings: jest.fn().mockResolvedValue() }; + + const findForm = () => wrapper.find({ ref: 'settingsForm' }); + + beforeEach(() => { + wrapper = shallowMount(AlertsSettingsForm, { + provide: { + service, + alertSettings: { + issueTemplateKey: 'selecte_tmpl', + createIssue: true, + sendEmail: false, + templates: [], + }, + }, + }); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } + }); + + describe('default state', () => { + it('should match the default snapshot', () => { + expect(wrapper.element).toMatchSnapshot(); + }); + }); + + describe('form', () => { + it('should call service `updateSettings` on submit', () => { + findForm().trigger('submit'); + expect(service.updateSettings).toHaveBeenCalledWith( + expect.objectContaining({ + create_issue: wrapper.vm.createIssueEnabled, + issue_template_key: wrapper.vm.issueTemplate, + send_email: wrapper.vm.sendEmailEnabled, + }), + ); + }); + }); +}); diff --git a/spec/frontend/incidents_settings/components/incidents_settings_service_spec.js b/spec/frontend/incidents_settings/components/incidents_settings_service_spec.js new file mode 100644 index 00000000000..58f9a318808 --- /dev/null +++ b/spec/frontend/incidents_settings/components/incidents_settings_service_spec.js @@ -0,0 +1,55 @@ +import axios from '~/lib/utils/axios_utils'; +import AxiosMockAdapter from 'axios-mock-adapter'; +import httpStatusCodes from '~/lib/utils/http_status'; +import IncidentsSettingsService from '~/incidents_settings/incidents_settings_service'; +import { ERROR_MSG } from '~/incidents_settings/constants'; +import createFlash from '~/flash'; +import { refreshCurrentPage } from '~/lib/utils/url_utility'; + +jest.mock('~/flash'); +jest.mock('~/lib/utils/url_utility'); + +describe('IncidentsSettingsService', () => { + const settingsEndpoint = 'operations/settings'; + const webhookUpdateEndpoint = 'webhook/update'; + let mock; + let service; + + beforeEach(() => { + mock = new AxiosMockAdapter(axios); + service = new IncidentsSettingsService(settingsEndpoint, webhookUpdateEndpoint); + }); + + afterEach(() => { + mock.restore(); + }); + + describe('updateSettings', () => { + it('should refresh the page on successful update', () => { + mock.onPatch().reply(httpStatusCodes.OK); + + return service.updateSettings({}).then(() => { + expect(refreshCurrentPage).toHaveBeenCalled(); + }); + }); + + it('should display a flash message on update error', () => { + mock.onPatch().reply(httpStatusCodes.BAD_REQUEST); + + return service.updateSettings({}).then(() => { + expect(createFlash).toHaveBeenCalledWith(expect.stringContaining(ERROR_MSG), 'alert'); + }); + }); + }); + + describe('resetWebhookUrl', () => { + it('should make a call for webhook update', () => { + jest.spyOn(axios, 'post'); + mock.onPost().reply(httpStatusCodes.OK); + + return service.resetWebhookUrl().then(() => { + expect(axios.post).toHaveBeenCalledWith(webhookUpdateEndpoint); + }); + }); + }); +}); diff --git a/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js b/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js new file mode 100644 index 00000000000..47e2aecc108 --- /dev/null +++ b/spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js @@ -0,0 +1,55 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlTab } from '@gitlab/ui'; +import IncidentsSettingTabs from '~/incidents_settings/components/incidents_settings_tabs.vue'; + +describe('IncidentsSettingTabs', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallowMount(IncidentsSettingTabs, { + provide: { glFeatures: { pagerdutyWebhook: true } }, + }); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + const findToggleButton = () => wrapper.find({ ref: 'toggleBtn' }); + const findSectionHeader = () => wrapper.find({ ref: 'sectionHeader' }); + + const findIntegrationTabs = () => wrapper.findAll(GlTab); + it('renders header text', () => { + expect(findSectionHeader().text()).toBe('Incidents'); + }); + + describe('expand/collapse button', () => { + it('renders as an expand button by default', () => { + expect(findToggleButton().text()).toBe('Expand'); + }); + }); + + it('should render the component', () => { + expect(wrapper.element).toMatchSnapshot(); + }); + + it('should render the tab for each active integration', () => { + const activeTabs = wrapper.vm.$options.tabs.filter(tab => tab.active); + expect(findIntegrationTabs().length).toBe(activeTabs.length); + activeTabs.forEach((tab, index) => { + expect( + findIntegrationTabs() + .at(index) + .attributes('title'), + ).toBe(tab.title); + expect( + findIntegrationTabs() + .at(index) + .find(`[data-testid="${tab.component}-tab"]`) + .exists(), + ).toBe(true); + }); + }); +}); diff --git a/spec/frontend/incidents_settings/components/pagerduty_form_spec.js b/spec/frontend/incidents_settings/components/pagerduty_form_spec.js new file mode 100644 index 00000000000..521094ad54c --- /dev/null +++ b/spec/frontend/incidents_settings/components/pagerduty_form_spec.js @@ -0,0 +1,67 @@ +import { shallowMount } from '@vue/test-utils'; +import waitForPromises from 'helpers/wait_for_promises'; +import PagerDutySettingsForm from '~/incidents_settings/components/pagerduty_form.vue'; +import { GlAlert, GlModal } from '@gitlab/ui'; + +describe('Alert integration settings form', () => { + let wrapper; + const resetWebhookUrl = jest.fn(); + const service = { updateSettings: jest.fn().mockResolvedValue(), resetWebhookUrl }; + + const findForm = () => wrapper.find({ ref: 'settingsForm' }); + const findWebhookInput = () => wrapper.find('[data-testid="webhook-url"]'); + const findModal = () => wrapper.find(GlModal); + const findAlert = () => wrapper.find(GlAlert); + + beforeEach(() => { + wrapper = shallowMount(PagerDutySettingsForm, { + provide: { + service, + pagerDutySettings: { + active: true, + webhookUrl: 'pagerduty.webhook.com', + webhookUpdateEndpoint: 'webhook/update', + }, + }, + }); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } + }); + + it('should match the default snapshot', () => { + expect(wrapper.element).toMatchSnapshot(); + }); + + it('should call service `updateSettings` on form submit', () => { + findForm().trigger('submit'); + expect(service.updateSettings).toHaveBeenCalledWith( + expect.objectContaining({ pagerduty_active: wrapper.vm.active }), + ); + }); + + describe('Webhook reset', () => { + it('should make a call for webhook reset and reset form values', async () => { + const newWebhookUrl = 'new.webhook.url?token=token'; + resetWebhookUrl.mockResolvedValueOnce({ + data: { pagerduty_webhook_url: newWebhookUrl }, + }); + findModal().vm.$emit('ok'); + await waitForPromises(); + expect(resetWebhookUrl).toHaveBeenCalled(); + expect(findWebhookInput().attributes('value')).toBe(newWebhookUrl); + expect(findAlert().attributes('variant')).toBe('success'); + }); + + it('should show error message and NOT reset webhook url', async () => { + resetWebhookUrl.mockRejectedValueOnce(); + findModal().vm.$emit('ok'); + await waitForPromises(); + expect(findAlert().attributes('variant')).toBe('danger'); + }); + }); +}); |