Commit ff91161d authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '268373-test-payload-opsgenie-1' into 'master'

Support test payloads through the UI for Alert intergrations

See merge request gitlab-org/gitlab!47079
parents ea48c52f 156cf30b
......@@ -17,6 +17,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import AlertSettingsFormHelpBlock from './alert_settings_form_help_block.vue';
import service from '../services';
import {
integrationTypesNew,
JSON_VALIDATE_DELAY,
......@@ -89,7 +90,7 @@ export default {
MappingBuilder,
},
directives: {
'gl-modal': GlModalDirective,
GlModal: GlModalDirective,
},
inject: {
generic: {
......@@ -150,6 +151,13 @@ export default {
apiUrl: this.currentIntegration?.apiUrl || '',
};
},
testAlertPayload() {
return {
data: this.integrationTestPayload.json,
endpoint: this.integrationForm.url,
token: this.integrationForm.token,
};
},
},
watch: {
currentIntegration(val) {
......@@ -170,8 +178,14 @@ export default {
}
},
submitWithTestPayload() {
// TODO: Test payload before saving via GraphQL
return service
.updateTestAlert(this.testAlertPayload)
.then(() => {
this.submit();
})
.catch(() => {
this.$emit('test-payload-failure');
});
},
submit() {
const { name, apiUrl } = this.integrationForm;
......@@ -359,7 +373,6 @@ export default {
</div>
</gl-form-group>
<gl-form-group
id="test-integration"
:label="$options.i18n.integrationFormSteps.step4.label"
label-for="test-integration"
:invalid-feedback="integrationTestPayload.error"
......@@ -395,6 +408,8 @@ export default {
<div class="gl-display-flex gl-justify-content-end">
<gl-button type="reset" class="gl-mr-3 js-no-auto-disable">{{ __('Cancel') }}</gl-button>
<gl-button
data-testid="integration-test-and-submit"
:disabled="Boolean(integrationTestPayload.error)"
category="secondary"
variant="success"
class="gl-mr-1 js-no-auto-disable"
......
......@@ -24,6 +24,7 @@ import {
ADD_INTEGRATION_ERROR,
RESET_INTEGRATION_TOKEN_ERROR,
UPDATE_INTEGRATION_ERROR,
INTEGRATION_PAYLOAD_TEST_ERROR,
} from '../utils/error_messages';
export default {
......@@ -244,6 +245,9 @@ export default {
clearCurrentIntegration() {
this.currentIntegration = null;
},
testPayloadFailure() {
createFlash({ message: INTEGRATION_PAYLOAD_TEST_ERROR });
},
},
};
</script>
......@@ -266,6 +270,7 @@ export default {
@update-integration="updateIntegration"
@reset-token="resetToken"
@clear-current-integration="clearCurrentIntegration"
@test-payload-failure="testPayloadFailure"
/>
<settings-form-old v-else />
</div>
......
......@@ -2,6 +2,7 @@
import axios from '~/lib/utils/axios_utils';
export default {
// TODO: All this code save updateTestAlert will be deleted as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/255501
updateGenericKey({ endpoint, params }) {
return axios.put(endpoint, params);
},
......@@ -25,11 +26,11 @@ export default {
},
});
},
updateTestAlert({ endpoint, data, authKey }) {
updateTestAlert({ endpoint, data, token }) {
return axios.post(endpoint, data, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${authKey}`,
Authorization: `Bearer ${token}`,
},
});
},
......
......@@ -15,3 +15,7 @@ export const UPDATE_INTEGRATION_ERROR = s__(
export const RESET_INTEGRATION_TOKEN_ERROR = s__(
'AlertsIntegrations|The integration token could not be reset. Please try again.',
);
export const INTEGRATION_PAYLOAD_TEST_ERROR = s__(
'AlertsIntegrations|Integration payload is invalid. You can still save your changes.',
);
......@@ -2668,6 +2668,9 @@ msgstr ""
msgid "AlertsIntegrations|Integration Name"
msgstr ""
msgid "AlertsIntegrations|Integration payload is invalid. You can still save your changes."
msgstr ""
msgid "AlertsIntegrations|No integrations have been added yet"
msgstr ""
......
......@@ -72,7 +72,7 @@ exports[`AlertsSettingsFormNew with default values renders the initial template
<!---->
</div>
</div>
<div id=\\"test-integration\\" role=\\"group\\" class=\\"form-group gl-form-group\\"><label id=\\"test-integration__BV_label_\\" for=\\"test-integration\\" class=\\"d-block col-form-label\\">4. Test integration(optional)</label>
<div role=\\"group\\" class=\\"form-group gl-form-group\\" id=\\"__BVID__40\\"><label for=\\"test-integration\\" class=\\"d-block col-form-label\\" id=\\"__BVID__40__BV_label_\\">4. Test integration(optional)</label>
<div class=\\"bv-no-focus-ring\\"><span class=\\"gl-text-gray-500\\">Provide an example payload from the monitoring tool you intend to integrate with to send a test alert to the <a rel=\\"noopener noreferrer\\" target=\\"_blank\\" href=\\"http://invalid\\" class=\\"gl-link gl-display-inline-block\\">alerts page</a>. This payload can be used to test the integration using the \\"save and test payload\\" button.</span> <textarea id=\\"test-integration\\" disabled=\\"disabled\\" placeholder=\\"Enter test alert JSON....\\" wrap=\\"soft\\" class=\\"gl-form-input gl-form-textarea gl-my-4 form-control is-valid\\" style=\\"resize: none; overflow-y: scroll;\\"></textarea>
<!---->
<!---->
......@@ -82,7 +82,7 @@ exports[`AlertsSettingsFormNew with default values renders the initial template
<!---->
<div class=\\"gl-display-flex gl-justify-content-end\\"><button type=\\"reset\\" class=\\"btn gl-mr-3 js-no-auto-disable btn-default btn-md gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">Cancel</span></button> <button type=\\"button\\" class=\\"btn gl-mr-1 js-no-auto-disable btn-success btn-md gl-button btn-success-secondary\\">
<!----> <span class=\\"gl-button-text\\">Cancel</span></button> <button data-testid=\\"integration-test-and-submit\\" type=\\"button\\" class=\\"btn gl-mr-1 js-no-auto-disable btn-success btn-md gl-button btn-success-secondary\\">
<!---->
<!----> <span class=\\"gl-button-text\\">Save and test payload</span></button> <button data-testid=\\"integration-form-submit\\" type=\\"submit\\" class=\\"btn js-no-auto-disable btn-success btn-md gl-button\\">
<!---->
......
......@@ -37,6 +37,8 @@ describe('AlertsSettingsFormNew', () => {
const findSubmitButton = () => wrapper.find(`[type = "submit"]`);
const findMultiSupportText = () =>
wrapper.find(`[data-testid="multi-integrations-not-supported"]`);
const findJsonTestSubmit = () => wrapper.find(`[data-testid="integration-test-and-submit"]`);
const findJsonTextArea = () => wrapper.find(`[id = "test-integration"]`);
afterEach(() => {
if (wrapper) {
......@@ -203,6 +205,42 @@ describe('AlertsSettingsFormNew', () => {
});
});
describe('submitting the integration with a JSON test payload', () => {
beforeEach(() => {
createComponent({
data: {
selectedIntegration: typeSet.http,
active: true,
},
props: {
currentIntegration: { id: '1', name: 'Test' },
loading: false,
},
});
});
it('should not allow a user to test invalid JSON', async () => {
jest.useFakeTimers();
await findJsonTextArea().setValue('Invalid JSON');
jest.runAllTimers();
await wrapper.vm.$nextTick();
expect(findJsonTestSubmit().exists()).toBe(true);
expect(findJsonTestSubmit().text()).toBe('Save and test payload');
expect(findJsonTestSubmit().props('disabled')).toBe(true);
});
it('should allow for the form to be automatically saved if the test payload is successfully submitted', async () => {
jest.useFakeTimers();
await findJsonTextArea().setValue('{ "value": "value" }');
jest.runAllTimers();
await wrapper.vm.$nextTick();
expect(findJsonTestSubmit().props('disabled')).toBe(false);
});
});
describe('Mapping builder section', () => {
beforeEach(() => {
createComponent({});
......
......@@ -20,6 +20,7 @@ import {
ADD_INTEGRATION_ERROR,
RESET_INTEGRATION_TOKEN_ERROR,
UPDATE_INTEGRATION_ERROR,
INTEGRATION_PAYLOAD_TEST_ERROR,
} from '~/alerts_settings/utils/error_messages';
import createFlash from '~/flash';
import { defaultAlertSettingsConfig } from './util';
......@@ -327,6 +328,20 @@ describe('AlertsSettingsWrapper', () => {
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({ message: UPDATE_INTEGRATION_ERROR });
});
it('shows an error alert when integration test payload fails ', async () => {
createComponent({
data: { integrations: { list: mockIntegrations }, currentIntegration: mockIntegrations[0] },
provide: { glFeatures: { httpIntegrationsList: true } },
loading: false,
});
wrapper.find(AlertsSettingsFormNew).vm.$emit('test-payload-failure');
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({ message: INTEGRATION_PAYLOAD_TEST_ERROR });
expect(createFlash).toHaveBeenCalledTimes(1);
});
});
describe('with mocked Apollo client', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment