Commit 3257efbd authored by Samantha Ming's avatar Samantha Ming

Add validation to delete blob modal

Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/335743
parent 858320c2
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import { GlModal, GlFormGroup, GlFormInput, GlFormTextarea, GlToggle, GlForm } from '@gitlab/ui'; import { GlModal, GlFormGroup, GlFormInput, GlFormTextarea, GlToggle, GlForm } from '@gitlab/ui';
import csrf from '~/lib/utils/csrf'; import csrf from '~/lib/utils/csrf';
import { __ } from '~/locale'; import { __ } from '~/locale';
import validation from '~/vue_shared/directives/validation';
import { import {
SECONDARY_OPTIONS_TEXT, SECONDARY_OPTIONS_TEXT,
COMMIT_LABEL, COMMIT_LABEL,
...@@ -9,6 +10,13 @@ import { ...@@ -9,6 +10,13 @@ import {
TOGGLE_CREATE_MR_LABEL, TOGGLE_CREATE_MR_LABEL,
} from '../constants'; } from '../constants';
const initFormField = ({ value, required = true, skipValidation = false }) => ({
value,
required,
state: skipValidation ? true : null,
feedback: null,
});
export default { export default {
csrf, csrf,
components: { components: {
...@@ -26,6 +34,9 @@ export default { ...@@ -26,6 +34,9 @@ export default {
TARGET_BRANCH_LABEL, TARGET_BRANCH_LABEL,
TOGGLE_CREATE_MR_LABEL, TOGGLE_CREATE_MR_LABEL,
}, },
directives: {
validation: validation(),
},
props: { props: {
modalId: { modalId: {
type: String, type: String,
...@@ -61,12 +72,20 @@ export default { ...@@ -61,12 +72,20 @@ export default {
}, },
}, },
data() { data() {
const form = {
state: false,
showValidation: false,
fields: {
// fields key must match case of form name for validation directive to work
commit_message: initFormField({ value: this.commitMessage }),
branch_name: initFormField({ value: this.targetBranch }),
},
};
return { return {
loading: false, loading: false,
commit: this.commitMessage,
target: this.targetBranch,
createNewMr: true, createNewMr: true,
error: '', error: '',
form,
}; };
}, },
computed: { computed: {
...@@ -77,7 +96,7 @@ export default { ...@@ -77,7 +96,7 @@ export default {
{ {
variant: 'danger', variant: 'danger',
loading: this.loading, loading: this.loading,
disabled: !this.formCompleted || this.loading, disabled: this.loading || !this.form.state,
}, },
], ],
}; };
...@@ -92,17 +111,26 @@ export default { ...@@ -92,17 +111,26 @@ export default {
], ],
}; };
}, },
/* eslint-disable dot-notation */
showCreateNewMrToggle() { showCreateNewMrToggle() {
return this.canPushCode && this.target !== this.originalBranch; return this.canPushCode && this.form.fields['branch_name'].value !== this.originalBranch;
}, },
formCompleted() { formCompleted() {
return this.commit && this.target; return this.form.fields['commit_message'].value && this.form.fields['branch_name'].value;
}, },
/* eslint-enable dot-notation */
}, },
methods: { methods: {
submitForm(e) { submitForm(e) {
e.preventDefault(); // Prevent modal from closing e.preventDefault(); // Prevent modal from closing
this.form.showValidation = true;
if (!this.form.state) {
return;
}
this.loading = true; this.loading = true;
this.form.showValidation = false;
this.$refs.form.$el.submit(); this.$refs.form.$el.submit();
}, },
}, },
...@@ -119,7 +147,7 @@ export default { ...@@ -119,7 +147,7 @@ export default {
:action-cancel="cancelOptions" :action-cancel="cancelOptions"
@primary="submitForm" @primary="submitForm"
> >
<gl-form ref="form" :action="deletePath" method="post"> <gl-form ref="form" novalidate :action="deletePath" method="post">
<input type="hidden" name="_method" value="delete" /> <input type="hidden" name="_method" value="delete" />
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" /> <input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<template v-if="emptyRepo"> <template v-if="emptyRepo">
...@@ -132,15 +160,34 @@ export default { ...@@ -132,15 +160,34 @@ export default {
<!-- Once "push to branch" permission is made available, will need to add to conditional <!-- Once "push to branch" permission is made available, will need to add to conditional
Follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/335462 --> Follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/335462 -->
<input v-if="createNewMr" type="hidden" name="create_merge_request" value="1" /> <input v-if="createNewMr" type="hidden" name="create_merge_request" value="1" />
<gl-form-group :label="$options.i18n.COMMIT_LABEL" label-for="commit_message"> <gl-form-group
<gl-form-textarea v-model="commit" name="commit_message" :disabled="loading" /> :label="$options.i18n.COMMIT_LABEL"
label-for="commit_message"
:invalid-feedback="form.fields['commit_message'].feedback"
>
<gl-form-textarea
v-model="form.fields['commit_message'].value"
v-validation:[form.showValidation]
name="commit_message"
:state="form.fields['commit_message'].state"
:disabled="loading"
required
/>
</gl-form-group> </gl-form-group>
<gl-form-group <gl-form-group
v-if="canPushCode" v-if="canPushCode"
:label="$options.i18n.TARGET_BRANCH_LABEL" :label="$options.i18n.TARGET_BRANCH_LABEL"
label-for="branch_name" label-for="branch_name"
:invalid-feedback="form.fields['branch_name'].feedback"
> >
<gl-form-input v-model="target" :disabled="loading" name="branch_name" /> <gl-form-input
v-model="form.fields['branch_name'].value"
v-validation:[form.showValidation]
:state="form.fields['branch_name'].state"
:disabled="loading"
name="branch_name"
required
/>
</gl-form-group> </gl-form-group>
<gl-toggle <gl-toggle
v-if="showCreateNewMrToggle" v-if="showCreateNewMrToggle"
......
...@@ -37,6 +37,8 @@ describe('DeleteBlobModal', () => { ...@@ -37,6 +37,8 @@ describe('DeleteBlobModal', () => {
const findModal = () => wrapper.findComponent(GlModal); const findModal = () => wrapper.findComponent(GlModal);
const findForm = () => findModal().findComponent(GlForm); const findForm = () => findModal().findComponent(GlForm);
const findCommitTextarea = () => findForm().findComponent(GlFormTextarea);
const findTargetInput = () => findForm().findComponent(GlFormInput);
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -65,18 +67,6 @@ describe('DeleteBlobModal', () => { ...@@ -65,18 +67,6 @@ describe('DeleteBlobModal', () => {
expect(findForm().attributes('action')).toBe(initialProps.deletePath); expect(findForm().attributes('action')).toBe(initialProps.deletePath);
}); });
it('submits the form', async () => {
createFullComponent();
await nextTick();
const submitSpy = jest.spyOn(findForm().element, 'submit');
findModal().vm.$emit('primary', { preventDefault: () => {} });
await nextTick();
expect(submitSpy).toHaveBeenCalled();
submitSpy.mockRestore();
});
it.each` it.each`
component | defaultValue | canPushCode | targetBranch | originalBranch | exist component | defaultValue | canPushCode | targetBranch | originalBranch | exist
${GlFormTextarea} | ${initialProps.commitMessage} | ${true} | ${initialProps.targetBranch} | ${initialProps.originalBranch} | ${true} ${GlFormTextarea} | ${initialProps.commitMessage} | ${true} | ${initialProps.targetBranch} | ${initialProps.originalBranch} | ${true}
...@@ -135,4 +125,62 @@ describe('DeleteBlobModal', () => { ...@@ -135,4 +125,62 @@ describe('DeleteBlobModal', () => {
}, },
); );
}); });
describe('form submission', () => {
let submitSpy;
beforeEach(async () => {
createFullComponent();
await nextTick();
submitSpy = jest.spyOn(findForm().element, 'submit');
});
afterEach(() => {
submitSpy.mockRestore();
});
const fillForm = async (inputValue = {}) => {
const { targetText, commitText } = inputValue;
await findTargetInput().vm.$emit('input', targetText);
await findCommitTextarea().vm.$emit('input', commitText);
};
describe('invalid form', () => {
beforeEach(async () => {
await fillForm({ targetText: '', commitText: '' });
});
it('disables submit button', async () => {
expect(findModal().props('actionPrimary').attributes[0]).toEqual(
expect.objectContaining({ disabled: true }),
);
});
it('does not submit form', async () => {
findModal().vm.$emit('primary', { preventDefault: () => {} });
expect(submitSpy).not.toHaveBeenCalled();
});
});
describe('valid form', () => {
beforeEach(async () => {
await fillForm({
targetText: 'some valid target branch',
commitText: 'some valid commit message',
});
});
it('enables submit button', async () => {
expect(findModal().props('actionPrimary').attributes[0]).toEqual(
expect.objectContaining({ disabled: false }),
);
});
it('submits form', async () => {
findModal().vm.$emit('primary', { preventDefault: () => {} });
expect(submitSpy).toHaveBeenCalled();
});
});
});
}); });
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