Commit 94e59dae authored by Kev's avatar Kev Committed by Miguel Rincon

Prevent creating duplicate pipelines manually

parent 9536023b
...@@ -116,6 +116,7 @@ export default { ...@@ -116,6 +116,7 @@ export default {
totalWarnings: 0, totalWarnings: 0,
isWarningDismissed: false, isWarningDismissed: false,
isLoading: false, isLoading: false,
submitted: false,
}; };
}, },
computed: { computed: {
...@@ -294,6 +295,7 @@ export default { ...@@ -294,6 +295,7 @@ export default {
}); });
}, },
createPipeline() { createPipeline() {
this.submitted = true;
const filteredVariables = this.variables const filteredVariables = this.variables
.filter(({ key, value }) => key !== '' && value !== '') .filter(({ key, value }) => key !== '' && value !== '')
.map(({ variable_type, key, value }) => ({ .map(({ variable_type, key, value }) => ({
...@@ -313,8 +315,16 @@ export default { ...@@ -313,8 +315,16 @@ export default {
redirectTo(`${this.pipelinesPath}/${data.id}`); redirectTo(`${this.pipelinesPath}/${data.id}`);
}) })
.catch((err) => { .catch((err) => {
const { errors, warnings, total_warnings: totalWarnings } = err.response.data; // always re-enable submit button
this.submitted = false;
const {
errors = [],
warnings = [],
total_warnings: totalWarnings = 0,
} = err?.response?.data;
const [error] = errors; const [error] = errors;
this.error = error; this.error = error;
this.warnings = warnings; this.warnings = warnings;
this.totalWarnings = totalWarnings; this.totalWarnings = totalWarnings;
...@@ -464,6 +474,8 @@ export default { ...@@ -464,6 +474,8 @@ export default {
variant="success" variant="success"
class="js-no-auto-disable" class="js-no-auto-disable"
data-qa-selector="run_pipeline_button" data-qa-selector="run_pipeline_button"
data-testid="run_pipeline_button"
:disabled="submitted"
>{{ s__('Pipeline|Run Pipeline') }}</gl-button >{{ s__('Pipeline|Run Pipeline') }}</gl-button
> >
<gl-button :href="pipelinesPath">{{ __('Cancel') }}</gl-button> <gl-button :href="pipelinesPath">{{ __('Cancel') }}</gl-button>
......
---
title: Prevent creating duplicate pipelines manually
merge_request: 51076
author: Kev @KevSlashNull
type: changed
...@@ -34,6 +34,7 @@ describe('Pipeline New Form', () => { ...@@ -34,6 +34,7 @@ describe('Pipeline New Form', () => {
const findForm = () => wrapper.find(GlForm); const findForm = () => wrapper.find(GlForm);
const findDropdown = () => wrapper.find(GlDropdown); const findDropdown = () => wrapper.find(GlDropdown);
const findDropdownItems = () => wrapper.findAll(GlDropdownItem); const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
const findSubmitButton = () => wrapper.find('[data-testid="run_pipeline_button"]');
const findVariableRows = () => wrapper.findAll('[data-testid="ci-variable-row"]'); const findVariableRows = () => wrapper.findAll('[data-testid="ci-variable-row"]');
const findRemoveIcons = () => wrapper.findAll('[data-testid="remove-ci-variable-row"]'); const findRemoveIcons = () => wrapper.findAll('[data-testid="remove-ci-variable-row"]');
const findKeyInputs = () => wrapper.findAll('[data-testid="pipeline-form-ci-variable-key"]'); const findKeyInputs = () => wrapper.findAll('[data-testid="pipeline-form-ci-variable-key"]');
...@@ -155,6 +156,18 @@ describe('Pipeline New Form', () => { ...@@ -155,6 +156,18 @@ describe('Pipeline New Form', () => {
await waitForPromises(); await waitForPromises();
}); });
it('disables the submit button immediately after submitting', async () => {
createComponent();
expect(findSubmitButton().props('disabled')).toBe(false);
findForm().vm.$emit('submit', dummySubmitEvent);
await waitForPromises();
expect(findSubmitButton().props('disabled')).toBe(true);
});
it('creates pipeline with full ref and variables', async () => { it('creates pipeline with full ref and variables', async () => {
createComponent(); createComponent();
...@@ -167,6 +180,7 @@ describe('Pipeline New Form', () => { ...@@ -167,6 +180,7 @@ describe('Pipeline New Form', () => {
expect(getExpectedPostParams().ref).toEqual(wrapper.vm.$data.refValue.fullName); expect(getExpectedPostParams().ref).toEqual(wrapper.vm.$data.refValue.fullName);
expect(redirectTo).toHaveBeenCalledWith(`${pipelinesPath}/${postResponse.id}`); expect(redirectTo).toHaveBeenCalledWith(`${pipelinesPath}/${postResponse.id}`);
}); });
it('creates a pipeline with short ref and variables', async () => { it('creates a pipeline with short ref and variables', async () => {
// query params are used // query params are used
createComponent('', mockParams); createComponent('', mockParams);
...@@ -312,12 +326,15 @@ describe('Pipeline New Form', () => { ...@@ -312,12 +326,15 @@ describe('Pipeline New Form', () => {
describe('Form errors and warnings', () => { describe('Form errors and warnings', () => {
beforeEach(() => { beforeEach(() => {
createComponent(); createComponent();
});
describe('when the error response can be handled', () => {
beforeEach(async () => {
mock.onPost(pipelinesPath).reply(httpStatusCodes.BAD_REQUEST, mockError); mock.onPost(pipelinesPath).reply(httpStatusCodes.BAD_REQUEST, mockError);
findForm().vm.$emit('submit', dummySubmitEvent); findForm().vm.$emit('submit', dummySubmitEvent);
return waitForPromises(); await waitForPromises();
}); });
it('shows both error and warning', () => { it('shows both error and warning', () => {
...@@ -338,5 +355,26 @@ describe('Pipeline New Form', () => { ...@@ -338,5 +355,26 @@ describe('Pipeline New Form', () => {
it('shows the correct amount of warnings', () => { it('shows the correct amount of warnings', () => {
expect(findWarnings()).toHaveLength(mockError.warnings.length); expect(findWarnings()).toHaveLength(mockError.warnings.length);
}); });
it('re-enables the submit button', () => {
expect(findSubmitButton().props('disabled')).toBe(false);
});
});
describe('when the error response cannot be handled', () => {
beforeEach(async () => {
mock
.onPost(pipelinesPath)
.reply(httpStatusCodes.INTERNAL_SERVER_ERROR, 'something went wrong');
findForm().vm.$emit('submit', dummySubmitEvent);
await waitForPromises();
});
it('re-enables the submit button', () => {
expect(findSubmitButton().props('disabled')).toBe(false);
});
});
}); });
}); });
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