diff --git a/app/assets/javascripts/repository/components/delete_blob_modal.vue b/app/assets/javascripts/repository/components/delete_blob_modal.vue index 394f1e7995abe477ca2b7af01152e477a773ce05..c13bde6b41a16b8e9a427382ebdc01f20511f952 100644 --- a/app/assets/javascripts/repository/components/delete_blob_modal.vue +++ b/app/assets/javascripts/repository/components/delete_blob_modal.vue @@ -33,6 +33,9 @@ export default { COMMIT_LABEL, TARGET_BRANCH_LABEL, TOGGLE_CREATE_MR_LABEL, + COMMIT_MESSAGE_HINT: __( + 'Try to keep the first line under 52 characters and the others under 72.', + ), }, directives: { validation: validation(), @@ -118,6 +121,26 @@ export default { formCompleted() { return this.form.fields['commit_message'].value && this.form.fields['branch_name'].value; }, + showHint() { + const commitMessageSubjectMaxLength = 52; + const commitMessageBodyMaxLength = 72; + + const splitCommitMessageByLineBreak = this.form.fields['commit_message'].value + .trim() + .split('\n'); + const [firstLine, ...otherLines] = splitCommitMessageByLineBreak; + + const hasFirstLineExceedMaxLength = firstLine.length > commitMessageSubjectMaxLength; + + const hasOtherLineExceedMaxLength = + Boolean(otherLines.length) && + otherLines.some((text) => text.length > commitMessageBodyMaxLength); + + return ( + !this.form.fields['commit_message'].feedback && + (hasFirstLineExceedMaxLength || hasOtherLineExceedMaxLength) + ); + }, /* eslint-enable dot-notation */ }, methods: { @@ -173,6 +196,9 @@ export default { :disabled="loading" required /> +

+ {{ $options.i18n.COMMIT_MESSAGE_HINT }} +

{ const findForm = () => findModal().findComponent(GlForm); const findCommitTextarea = () => findForm().findComponent(GlFormTextarea); const findTargetInput = () => findForm().findComponent(GlFormInput); + const findCommitHint = () => wrapper.find('[data-testid="hint"]'); + + const fillForm = async (inputValue = {}) => { + const { targetText, commitText } = inputValue; + + await findTargetInput().vm.$emit('input', targetText); + await findCommitTextarea().vm.$emit('input', commitText); + }; afterEach(() => { wrapper.destroy(); @@ -126,6 +134,36 @@ describe('DeleteBlobModal', () => { ); }); + describe('hint', () => { + const targetText = 'some target branch'; + const hintText = 'Try to keep the first line under 52 characters and the others under 72.'; + const charsGenerator = (length) => 'lorem'.repeat(length); + + beforeEach(async () => { + createFullComponent(); + await nextTick(); + }); + + it.each` + commitText | exist | desc + ${charsGenerator(53)} | ${true} | ${'first line length > 52'} + ${`lorem\n${charsGenerator(73)}`} | ${true} | ${'other line length > 72'} + ${charsGenerator(52)} | ${true} | ${'other line length = 52'} + ${`lorem\n${charsGenerator(72)}`} | ${true} | ${'other line length = 72'} + ${`lorem`} | ${false} | ${'first line length < 53'} + ${`lorem\nlorem`} | ${false} | ${'other line length < 53'} + `('displays hint $exist for $desc', async ({ commitText, exist }) => { + await fillForm({ targetText, commitText }); + + if (!exist) { + expect(findCommitHint().exists()).toBe(false); + return; + } + + expect(findCommitHint().text()).toBe(hintText); + }); + }); + describe('form submission', () => { let submitSpy; @@ -139,13 +177,6 @@ describe('DeleteBlobModal', () => { 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: '' });