summaryrefslogtreecommitdiff
path: root/spec/frontend/incidents_settings/components
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/incidents_settings/components')
-rw-r--r--spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap99
-rw-r--r--spec/frontend/incidents_settings/components/__snapshots__/incidents_settings_tabs_spec.js.snap63
-rw-r--r--spec/frontend/incidents_settings/components/__snapshots__/pagerduty_form_spec.js.snap89
-rw-r--r--spec/frontend/incidents_settings/components/alerts_form_spec.js49
-rw-r--r--spec/frontend/incidents_settings/components/incidents_settings_service_spec.js55
-rw-r--r--spec/frontend/incidents_settings/components/incidents_settings_tabs_spec.js55
-rw-r--r--spec/frontend/incidents_settings/components/pagerduty_form_spec.js67
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');
+ });
+ });
+});