Commit 18dd29c0 authored by Fatih Acet's avatar Fatih Acet

Merge branch 'winh-notes-error-handling' into 'master'

Handle errors in successful notes reply

Closes #61377

See merge request gitlab-org/gitlab-ce!28082
parents 4f447e0f 4f1d2bf5
...@@ -268,11 +268,20 @@ export const saveNote = ({ commit, dispatch }, noteData) => { ...@@ -268,11 +268,20 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
const { errors } = res; const { errors } = res;
const commandsChanges = res.commands_changes; const commandsChanges = res.commands_changes;
if (hasQuickActions && errors && Object.keys(errors).length) { if (errors && Object.keys(errors).length) {
/*
The following reply means that quick actions have been successfully applied:
{"commands_changes":{},"valid":false,"errors":{"commands_only":["Commands applied"]}}
*/
if (hasQuickActions) {
eTagPoll.makeRequest(); eTagPoll.makeRequest();
$('.js-gfm-input').trigger('clear-commands-cache.atwho'); $('.js-gfm-input').trigger('clear-commands-cache.atwho');
Flash(__('Commands applied'), 'notice', noteData.flashContainer); Flash(__('Commands applied'), 'notice', noteData.flashContainer);
} else {
throw new Error(__('Failed to save comment!'));
}
} }
if (commandsChanges) { if (commandsChanges) {
......
...@@ -2,7 +2,8 @@ import AjaxCache from '~/lib/utils/ajax_cache'; ...@@ -2,7 +2,8 @@ import AjaxCache from '~/lib/utils/ajax_cache';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils'; import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
import { sprintf, __ } from '~/locale'; import { sprintf, __ } from '~/locale';
const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm; // factory function because global flag makes RegExp stateful
const createQuickActionsRegex = () => /^\/\w+.*$/gm;
export const findNoteObjectById = (notes, id) => notes.filter(n => n.id === id)[0]; export const findNoteObjectById = (notes, id) => notes.filter(n => n.id === id)[0];
...@@ -27,9 +28,9 @@ export const getQuickActionText = note => { ...@@ -27,9 +28,9 @@ export const getQuickActionText = note => {
return text; return text;
}; };
export const hasQuickActions = note => REGEX_QUICK_ACTIONS.test(note); export const hasQuickActions = note => createQuickActionsRegex().test(note);
export const stripQuickActions = note => note.replace(REGEX_QUICK_ACTIONS, '').trim(); export const stripQuickActions = note => note.replace(createQuickActionsRegex(), '').trim();
export const prepareDiffLines = diffLines => export const prepareDiffLines = diffLines =>
diffLines.map(line => ({ ...trimFirstCharOfLineContent(line) })); diffLines.map(line => ({ ...trimFirstCharOfLineContent(line) }));
---
title: Handle errors in successful notes reply
merge_request: 28082
author:
type: fixed
...@@ -4196,6 +4196,9 @@ msgstr "" ...@@ -4196,6 +4196,9 @@ msgstr ""
msgid "Failed to remove user key." msgid "Failed to remove user key."
msgstr "" msgstr ""
msgid "Failed to save comment!"
msgstr ""
msgid "Failed to save merge conflicts resolutions. Please try again!" msgid "Failed to save merge conflicts resolutions. Please try again!"
msgstr "" msgstr ""
......
import { hasQuickActions } from '~/notes/stores/utils';
describe('hasQuickActions', () => {
it.each`
input | expected
${'some comment'} | ${false}
${'/quickaction'} | ${true}
${'some comment with\n/quickaction'} | ${true}
`('returns $expected for $input', ({ input, expected }) => {
expect(hasQuickActions(input)).toBe(expected);
});
it('is stateless', () => {
expect(hasQuickActions('some comment')).toBe(hasQuickActions('some comment'));
expect(hasQuickActions('/quickaction')).toBe(hasQuickActions('/quickaction'));
});
});
...@@ -794,6 +794,51 @@ describe('Actions Notes Store', () => { ...@@ -794,6 +794,51 @@ describe('Actions Notes Store', () => {
}); });
}); });
describe('saveNote', () => {
const payload = { endpoint: TEST_HOST, data: { 'note[note]': 'some text' } };
describe('if response contains errors', () => {
const res = { errors: { something: ['went wrong'] } };
it('throws an error', done => {
actions
.saveNote(
{
commit() {},
dispatch: () => Promise.resolve(res),
},
payload,
)
.then(() => done.fail('Expected error to be thrown!'))
.catch(error => {
expect(error.message).toBe('Failed to save comment!');
})
.then(done)
.catch(done.fail);
});
});
describe('if response contains no errors', () => {
const res = { valid: true };
it('returns the response', done => {
actions
.saveNote(
{
commit() {},
dispatch: () => Promise.resolve(res),
},
payload,
)
.then(data => {
expect(data).toBe(res);
})
.then(done)
.catch(done.fail);
});
});
});
describe('submitSuggestion', () => { describe('submitSuggestion', () => {
const discussionId = 'discussion-id'; const discussionId = 'discussion-id';
const noteId = 'note-id'; const noteId = 'note-id';
......
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