Commit d8552474 authored by Paul Gascou-Vaillancourt's avatar Paul Gascou-Vaillancourt Committed by Andrew Fontaine

Improve error handling in DAST site profile form

- Abort redirect when the backend returns errors as data
- Show error messages in the alert
parent 6f17d227
...@@ -75,21 +75,23 @@ export default { ...@@ -75,21 +75,23 @@ export default {
}, },
onSubmit() { onSubmit() {
this.loading = true; this.loading = true;
this.showAlert = false; this.hideErrors();
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: dastSiteProfileCreateMutation, mutation: dastSiteProfileCreateMutation,
variables: this.formData, variables: this.formData,
}) })
.then(data => { .then(({ data: { dastSiteProfileCreate: { errors } } }) => {
if (data.errors?.length > 0) { if (errors?.length > 0) {
throw new Error(data.errors); this.showErrors(errors);
this.loading = false;
} else {
redirectTo(this.profilesLibraryPath);
} }
redirectTo(this.profilesLibraryPath);
}) })
.catch(e => { .catch(e => {
Sentry.captureException(e); Sentry.captureException(e);
this.showAlert = true; this.showErrors();
this.loading = false; this.loading = false;
}); });
}, },
...@@ -103,6 +105,14 @@ export default { ...@@ -103,6 +105,14 @@ export default {
discard() { discard() {
redirectTo(this.profilesLibraryPath); redirectTo(this.profilesLibraryPath);
}, },
showErrors(errors = []) {
this.errors = errors;
this.showAlert = true;
},
hideErrors() {
this.errors = [];
this.showAlert = false;
},
}, },
modalId: 'deleteDastProfileModal', modalId: 'deleteDastProfileModal',
i18n: { i18n: {
...@@ -115,13 +125,17 @@ export default { ...@@ -115,13 +125,17 @@ export default {
<template> <template>
<gl-form @submit.prevent="onSubmit"> <gl-form @submit.prevent="onSubmit">
<gl-alert v-if="showAlert" variant="danger" @dismiss="showAlert = false">
{{ s__('DastProfiles|Could not create the site profile. Please try again.') }}
</gl-alert>
<h2 class="gl-mb-6"> <h2 class="gl-mb-6">
{{ s__('DastProfiles|New site profile') }} {{ s__('DastProfiles|New site profile') }}
</h2> </h2>
<gl-alert v-if="showAlert" variant="danger" class="gl-mb-5" @dismiss="hideErrors">
{{ s__('DastProfiles|Could not create the site profile. Please try again.') }}
<ul v-if="errors.length" class="gl-mt-3 gl-mb-0">
<li v-for="error in errors" :key="error" v-text="error"></li>
</ul>
</gl-alert>
<gl-form-group :label="s__('DastProfiles|Profile name')"> <gl-form-group :label="s__('DastProfiles|Profile name')">
<gl-form-input <gl-form-input
v-model="form.profileName.value" v-model="form.profileName.value"
......
...@@ -147,9 +147,13 @@ describe('OnDemandScansApp', () => { ...@@ -147,9 +147,13 @@ describe('OnDemandScansApp', () => {
it('redirects to the profiles library', () => { it('redirects to the profiles library', () => {
expect(redirectTo).toHaveBeenCalledWith(profilesLibraryPath); expect(redirectTo).toHaveBeenCalledWith(profilesLibraryPath);
}); });
it('does not show an alert', () => {
expect(findAlert().exists()).toBe(false);
});
}); });
describe('on error', () => { describe('on top-level error', () => {
beforeEach(() => { beforeEach(() => {
createComponent(); createComponent();
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue();
...@@ -166,6 +170,33 @@ describe('OnDemandScansApp', () => { ...@@ -166,6 +170,33 @@ describe('OnDemandScansApp', () => {
expect(findAlert().exists()).toBe(true); expect(findAlert().exists()).toBe(true);
}); });
}); });
describe('on errors as data', () => {
const errors = ['error#1', 'error#2', 'error#3'];
beforeEach(() => {
createComponent();
jest
.spyOn(wrapper.vm.$apollo, 'mutate')
.mockResolvedValue({ data: { dastSiteProfileCreate: { pipelineUrl: null, errors } } });
const input = findTargetUrlInput();
input.vm.$emit('input', targetUrl);
submitForm();
});
it('resets loading state', () => {
expect(findSubmitButton().props('loading')).toBe(false);
});
it('shows an alert with the returned errors', () => {
const alert = findAlert();
expect(alert.exists()).toBe(true);
errors.forEach(error => {
expect(alert.text()).toContain(error);
});
});
});
}); });
describe('cancellation', () => { describe('cancellation', () => {
......
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