From e6eda1bdaa018a3568cfd023a51ac9d30a2dcfbc Mon Sep 17 00:00:00 2001 From: Fiz <34069775+Hafizzle@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:20:36 -0500 Subject: [PATCH] fix(tasks): correct move route for challenge task reordering (#15660) route challenge task moves to the user endpoint, not group-tasks --- .../client/src/components/tasks/column.vue | 4 +- .../unit/components/tasks/column.spec.js | 79 +++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/website/client/src/components/tasks/column.vue b/website/client/src/components/tasks/column.vue index a39b738d0f..c6dd08dd40 100644 --- a/website/client/src/components/tasks/column.vue +++ b/website/client/src/components/tasks/column.vue @@ -582,7 +582,7 @@ export default { const newPosition = where === 'top' ? 0 : list.length; list.splice(newPosition, 0, moved[0]); - if (!this.isUser) { + if (task.group.id && !this.isUser) { await this.$store.dispatch('tasks:moveGroupTask', { taskId: taskIdToMove, position: newPosition, @@ -592,7 +592,7 @@ export default { taskId: taskIdToMove, position: newPosition, }); - this.user.tasksOrder[`${this.type}s`] = newOrder; + if (!this.taskListOverride) this.user.tasksOrder[`${this.type}s`] = newOrder; } }, async rewardSorted (data) { diff --git a/website/client/tests/unit/components/tasks/column.spec.js b/website/client/tests/unit/components/tasks/column.spec.js index e6cba6eb9e..5232ebf0ba 100644 --- a/website/client/tests/unit/components/tasks/column.spec.js +++ b/website/client/tests/unit/components/tasks/column.spec.js @@ -237,5 +237,84 @@ describe('Task Column', () => { }); }); }); + + // each board type should hit the right move route + describe('moveTo (task ordering route)', () => { + function makeStore (userData = {}, extraGetters = {}) { + return new Store({ + getters: { + 'tasks:getFilteredTaskList': () => () => [], + 'tasks:getUnfilteredTaskList': () => () => [], + ...extraGetters, + }, + state: { + user: { + data: { + preferences: { tasks: { activeFilter: {} } }, + tasksOrder: { habits: [] }, + ...userData, + }, + }, + }, + }); + } + + function stubDispatch (vm) { + const calls = []; + vm.$store.dispatch = (action, payload) => { + calls.push({ action, payload }); + return Promise.resolve(['b', 'a']); + }; + return calls; + } + + test('challenge tasks (no group.id) use tasks:move and keep the user order untouched', async () => { + wrapper = makeWrapper({ store: makeStore() }); + wrapper.setProps({ + isUser: false, + challenge: { _id: 'c1' }, + taskListOverride: [{ _id: 'a', group: {} }, { _id: 'b', group: {} }], + }); + const calls = stubDispatch(wrapper.vm); + + await wrapper.vm.moveTo({ _id: 'a', group: {} }, 'bottom'); + + expect(calls).to.have.lengthOf(1); + expect(calls[0].action).to.eq('tasks:move'); + // an overridden list must never overwrite the user's personal order + expect(wrapper.vm.user.tasksOrder.habits.join(',')).to.eq(''); + }); + + test('group-plan tasks (with group.id) use tasks:moveGroupTask', async () => { + wrapper = makeWrapper({ store: makeStore() }); + wrapper.setProps({ + isUser: false, + group: { _id: 'g1' }, + taskListOverride: [{ _id: 'a', group: { id: 'g1' } }, { _id: 'b', group: { id: 'g1' } }], + }); + const calls = stubDispatch(wrapper.vm); + + await wrapper.vm.moveTo({ _id: 'a', group: { id: 'g1' } }, 'bottom'); + + expect(calls).to.have.lengthOf(1); + expect(calls[0].action).to.eq('tasks:moveGroupTask'); + }); + + test('user tasks use tasks:move and update the user order', async () => { + const store = makeStore( + { tasksOrder: { habits: ['a', 'b'] } }, + { 'tasks:getUnfilteredTaskList': () => () => [{ _id: 'a', group: {} }, { _id: 'b', group: {} }] }, + ); + wrapper = makeWrapper({ store }); + wrapper.setProps({ isUser: true }); + const calls = stubDispatch(wrapper.vm); + + await wrapper.vm.moveTo({ _id: 'a', group: {} }, 'bottom'); + + expect(calls).to.have.lengthOf(1); + expect(calls[0].action).to.eq('tasks:move'); + expect(wrapper.vm.user.tasksOrder.habits.join(',')).to.eq('b,a'); + }); + }); }); });