From bcc4d568df8b19796882d43fc91c93e1e62e9aff Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Fri, 4 Mar 2016 11:45:21 -0600 Subject: [PATCH] Moved unlinkChallengeTasks to challenge model and added tests --- test/api/v3/unit/models/challenge.test.js | 27 ++++++++++++++++ website/src/controllers/api-v3/challenges.js | 2 +- website/src/models/challenge.js | 34 ++++++++++++++++++++ website/src/models/group.js | 2 +- website/src/models/user.js | 33 ------------------- 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/test/api/v3/unit/models/challenge.test.js b/test/api/v3/unit/models/challenge.test.js index 9f6ca65eb7..d028933e33 100644 --- a/test/api/v3/unit/models/challenge.test.js +++ b/test/api/v3/unit/models/challenge.test.js @@ -122,6 +122,33 @@ describe('Challenge Model', () => { expect(updatedUserTask.challenge.broken).to.equal('TASK_DELETED'); }); + + it('unlinks and deletes challenge tasks for a user when remove-all is specified', async () => { + await challenge.addTasks([task]); + await challenge.unlinkTasks(leader, 'remove-all'); + + let updatedLeader = await User.findOne({_id: leader._id}); + let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}}); + let syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) { + return updatedLeadersTask.type === taskValue.type && updatedLeadersTask.text === taskValue.text; + }); + + expect(syncedTask).to.not.exist; + }); + + it('unlinks and keeps challenge tasks for a user when keep-all is specified', async () => { + await challenge.addTasks([task]); + await challenge.unlinkTasks(leader, 'keep-all'); + + let updatedLeader = await User.findOne({_id: leader._id}); + let updatedLeadersTasks = await Tasks.Task.find({_id: { $in: updatedLeader.tasksOrder[`${taskType}s`]}}); + let syncedTask = find(updatedLeadersTasks, function findNewTask (updatedLeadersTask) { + return updatedLeadersTask.type === taskValue.type && updatedLeadersTask.text === taskValue.text; + }); + + expect(syncedTask).to.exist; + expect(syncedTask.challenge._id).to.be.empty; + }); }); }); }); diff --git a/website/src/controllers/api-v3/challenges.js b/website/src/controllers/api-v3/challenges.js index 5102da8975..f98ceae36c 100644 --- a/website/src/controllers/api-v3/challenges.js +++ b/website/src/controllers/api-v3/challenges.js @@ -191,7 +191,7 @@ api.leaveChallenge = { challenge.memberCount -= 1; // Unlink challenge's tasks from user's tasks and save the challenge - await Q.all([user.unlinkChallengeTasks(challenge._id, keep), challenge.save()]); + await Q.all([challenge.unlinkTasks(user, keep), challenge.save()]); res.respond(200, {}); }, }; diff --git a/website/src/models/challenge.js b/website/src/models/challenge.js index 0e4606748f..e3c2f3ee97 100644 --- a/website/src/models/challenge.js +++ b/website/src/models/challenge.js @@ -5,6 +5,7 @@ import baseModel from '../libs/api-v3/baseModel'; import _ from 'lodash'; import * as Tasks from './task'; import { model as User } from './user'; +import { removeFromArray } from '../libs/api-v3/collectionManipulators'; let Schema = mongoose.Schema; @@ -214,4 +215,37 @@ schema.methods.removeTask = async function challengeRemoveTask (task) { }, {multi: true}).exec(); }; +// Unlink challenges tasks (and the challenge itself) from user +schema.methods.unlinkTasks = async function challengeUnlinkTasks (user, keep) { + let challengeId = this._id; + let findQuery = { + userId: user._id, + 'challenge.id': challengeId, + }; + + removeFromArray(user.challenges, challengeId); + + if (keep === 'keep-all') { + await Tasks.Task.update(findQuery, { + $set: {challenge: {}}, // TODO what about updatedAt? + }, {multi: true}).exec(); + + await user.save(); + } else { // keep = 'remove-all' + let tasks = await Tasks.Task.find(findQuery).select('_id type completed').exec(); + let taskPromises = tasks.map(task => { + // Remove task from user.tasksOrder and delete them + if (task.type !== 'todo' || !task.completed) { + removeFromArray(user.tasksOrder[`${task.type}s`], task._id); + } + + return task.remove(); + }); + user.markModified('tasksOrder'); + taskPromises.push(user.save()); + return Q.all(taskPromises); + } +}; + + export let model = mongoose.model('Challenge', schema); diff --git a/website/src/models/group.js b/website/src/models/group.js index 1620ed020c..7a57490405 100644 --- a/website/src/models/group.js +++ b/website/src/models/group.js @@ -587,7 +587,7 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all') { }); let challengesToRemoveUserFrom = challenges.map(chal => { - return user.unlinkChallengeTasks(chal._id, keep); + return chal.unlinkTasks(user, keep); }); await Q.all(challengesToRemoveUserFrom); diff --git a/website/src/models/user.js b/website/src/models/user.js index 71138aebe6..e8ba70f857 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -6,7 +6,6 @@ import moment from 'moment'; import * as Tasks from './task'; import Q from 'q'; import { schema as TagSchema } from './tag'; -import { removeFromArray } from '../libs/api-v3/collectionManipulators'; import baseModel from '../libs/api-v3/baseModel'; // import {model as Challenge} from './challenge'; @@ -696,38 +695,6 @@ schema.methods.getGroups = function getUserGroups () { return userGroups; }; -// Unlink challenges tasks (and the challenge itself) from user -schema.methods.unlinkChallengeTasks = async function unlinkChallengeTasks (challengeId, keep) { - let user = this; - let findQuery = { - userId: user._id, - 'challenge.id': challengeId, - }; - - removeFromArray(user.challenges, challengeId); - - if (keep === 'keep-all') { - await Tasks.Task.update(findQuery, { - $set: {challenge: {}}, // TODO what about updatedAt? - }, {multi: true}).exec(); - - await user.save(); - } else { // keep = 'remove-all' - let tasks = await Tasks.Task.find(findQuery).select('_id type completed').exec(); - let taskPromises = tasks.map(task => { - // Remove task from user.tasksOrder and delete them - if (task.type !== 'todo' || !task.completed) { - removeFromArray(user.tasksOrder[`${task.type}s`], task._id); - } - - return task.remove(); - }); - - taskPromises.push(user.save()); - return Q.all(taskPromises); - } -}; - export let model = mongoose.model('User', schema); // Initially export an empty object so external requires will get