summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-09-12 16:46:09 +0100
committerPhil Hughes <me@iamphill.com>2018-09-12 16:46:09 +0100
commit8287f3477f4aaaa50f900ec06bef6e86f489a16d (patch)
tree8bfecb843a540fe4a7d0721abab0ae9c3914e5da
parentf87809f78de9da04f38134ba5ce0cf9ddebf2f63 (diff)
downloadgitlab-ce-8287f3477f4aaaa50f900ec06bef6e86f489a16d.tar.gz
Fixed MR widget unresolved discussions state
After resolving a discussion on a merge request page the merge request widget state would not get updated meaning users would need to refresh the page to merge (if that option is enabled in the projects settings) https://gitlab.com/gitlab-org/gitlab-ce/issues/42882
-rw-r--r--app/assets/javascripts/notes/stores/actions.js16
-rw-r--r--changelogs/unreleased/mr-widget-discussion-state-fix.yml5
-rw-r--r--spec/javascripts/notes/stores/actions_spec.js193
3 files changed, 211 insertions, 3 deletions
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 9a2ec15debd..17ff0a63833 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -61,9 +61,11 @@ export const refetchDiscussionById = ({ commit, state }, { path, discussionId })
.catch(() => {});
});
-export const deleteNote = ({ commit }, note) =>
+export const deleteNote = ({ commit, dispatch }, note) =>
service.deleteNote(note.path).then(() => {
commit(types.DELETE_NOTE, note);
+
+ dispatch('updateMergeRequestWidget');
});
export const updateNote = ({ commit }, { endpoint, note }) =>
@@ -84,20 +86,22 @@ export const replyToDiscussion = ({ commit }, { endpoint, data }) =>
return res;
});
-export const createNewNote = ({ commit }, { endpoint, data }) =>
+export const createNewNote = ({ commit, dispatch }, { endpoint, data }) =>
service
.createNewNote(endpoint, data)
.then(res => res.json())
.then(res => {
if (!res.errors) {
commit(types.ADD_NEW_NOTE, res);
+
+ dispatch('updateMergeRequestWidget');
}
return res;
});
export const removePlaceholderNotes = ({ commit }) => commit(types.REMOVE_PLACEHOLDER_NOTES);
-export const toggleResolveNote = ({ commit }, { endpoint, isResolved, discussion }) =>
+export const toggleResolveNote = ({ commit, dispatch }, { endpoint, isResolved, discussion }) =>
service
.toggleResolveNote(endpoint, isResolved)
.then(res => res.json())
@@ -105,6 +109,8 @@ export const toggleResolveNote = ({ commit }, { endpoint, isResolved, discussion
const mutationType = discussion ? types.UPDATE_DISCUSSION : types.UPDATE_NOTE;
commit(mutationType, res);
+
+ dispatch('updateMergeRequestWidget');
});
export const closeIssue = ({ commit, dispatch, state }) => {
@@ -333,5 +339,9 @@ export const fetchDiscussionDiffLines = ({ commit }, discussion) =>
});
});
+export const updateMergeRequestWidget = () => {
+ if (gl.mrWidget) gl.mrWidget.checkStatus();
+};
+
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
diff --git a/changelogs/unreleased/mr-widget-discussion-state-fix.yml b/changelogs/unreleased/mr-widget-discussion-state-fix.yml
new file mode 100644
index 00000000000..562d78a7aa7
--- /dev/null
+++ b/changelogs/unreleased/mr-widget-discussion-state-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed merge request widget discussion state not updating after resolving discussions
+merge_request: 21705
+author:
+type: fixed
diff --git a/spec/javascripts/notes/stores/actions_spec.js b/spec/javascripts/notes/stores/actions_spec.js
index b66e8e1ceb3..350162d5bb6 100644
--- a/spec/javascripts/notes/stores/actions_spec.js
+++ b/spec/javascripts/notes/stores/actions_spec.js
@@ -317,4 +317,197 @@ describe('Actions Notes Store', () => {
);
});
});
+
+ describe('deleteNote', () => {
+ const interceptor = (request, next) => {
+ next(
+ request.respondWith(JSON.stringify({}), {
+ status: 200,
+ }),
+ );
+ };
+
+ beforeEach(() => {
+ Vue.http.interceptors.push(interceptor);
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
+ });
+
+ it('commits DELETE_NOTE and dispatches updateMergeRequestWidget', done => {
+ const note = { path: `${gl.TEST_HOST}`, id: 1 };
+
+ testAction(
+ actions.deleteNote,
+ note,
+ store.state,
+ [
+ {
+ type: 'DELETE_NOTE',
+ payload: note,
+ },
+ ],
+ [
+ {
+ type: 'updateMergeRequestWidget',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('createNewNote', () => {
+ describe('success', () => {
+ const res = {
+ id: 1,
+ valid: true,
+ };
+ const interceptor = (request, next) => {
+ next(
+ request.respondWith(JSON.stringify(res), {
+ status: 200,
+ }),
+ );
+ };
+
+ beforeEach(() => {
+ Vue.http.interceptors.push(interceptor);
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
+ });
+
+ it('commits ADD_NEW_NOTE and dispatches updateMergeRequestWidget', done => {
+ testAction(
+ actions.createNewNote,
+ { endpoint: `${gl.TEST_HOST}`, data: {} },
+ store.state,
+ [
+ {
+ type: 'ADD_NEW_NOTE',
+ payload: res,
+ },
+ ],
+ [
+ {
+ type: 'updateMergeRequestWidget',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ const res = {
+ errors: ['error'],
+ };
+ const interceptor = (request, next) => {
+ next(
+ request.respondWith(JSON.stringify(res), {
+ status: 200,
+ }),
+ );
+ };
+
+ beforeEach(() => {
+ Vue.http.interceptors.push(interceptor);
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
+ });
+
+ it('does not commit ADD_NEW_NOTE or dispatch updateMergeRequestWidget', done => {
+ testAction(
+ actions.createNewNote,
+ { endpoint: `${gl.TEST_HOST}`, data: {} },
+ store.state,
+ [],
+ [],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('toggleResolveNote', () => {
+ const res = {
+ resolved: true,
+ };
+ const interceptor = (request, next) => {
+ next(
+ request.respondWith(JSON.stringify(res), {
+ status: 200,
+ }),
+ );
+ };
+
+ beforeEach(() => {
+ Vue.http.interceptors.push(interceptor);
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
+ });
+
+ describe('as note', () => {
+ it('commits UPDATE_NOTE and dispatches updateMergeRequestWidget', done => {
+ testAction(
+ actions.toggleResolveNote,
+ { endpoint: `${gl.TEST_HOST}`, isResolved: true, discussion: false },
+ store.state,
+ [
+ {
+ type: 'UPDATE_NOTE',
+ payload: res,
+ },
+ ],
+ [
+ {
+ type: 'updateMergeRequestWidget',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('as discussion', () => {
+ it('commits UPDATE_DISCUSSION and dispatches updateMergeRequestWidget', done => {
+ testAction(
+ actions.toggleResolveNote,
+ { endpoint: `${gl.TEST_HOST}`, isResolved: true, discussion: true },
+ store.state,
+ [
+ {
+ type: 'UPDATE_DISCUSSION',
+ payload: res,
+ },
+ ],
+ [
+ {
+ type: 'updateMergeRequestWidget',
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('updateMergeRequestWidget', () => {
+ it('calls mrWidget checkStatus', () => {
+ gl.mrWidget = {
+ checkStatus: jasmine.createSpy('checkStatus'),
+ };
+
+ actions.updateMergeRequestWidget();
+
+ expect(gl.mrWidget.checkStatus).toHaveBeenCalled();
+ });
+ });
});