From 6a67cbba6565769ca28b87ae7f8f76e9b566f6f2 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Mon, 12 Feb 2018 09:17:15 -0700 Subject: [PATCH] Refactored spell code to functions (#9908) * Refactored spell code to functions * Fixed party member returns --- website/server/controllers/api-v3/user.js | 187 ++++++++++++---------- 1 file changed, 106 insertions(+), 81 deletions(-) diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js index 4d3815dcaf..70721cfa54 100644 --- a/website/server/controllers/api-v3/user.js +++ b/website/server/controllers/api-v3/user.js @@ -526,6 +526,105 @@ api.getUserAnonymized = { const partyMembersFields = 'profile.name stats achievements items.special'; +async function castTaskSpell (res, req, targetId, user, spell) { + if (!targetId) throw new BadRequest(res.t('targetIdUUID')); + + const task = await Tasks.Task.findOne({ + _id: targetId, + userId: user._id, + }).exec(); + if (!task) throw new NotFound(res.t('taskNotFound')); + if (task.challenge.id) throw new BadRequest(res.t('challengeTasksNoCast')); + if (task.group.id) throw new BadRequest(res.t('groupTasksNoCast')); + + spell.cast(user, task, req); + + const results = await Bluebird.all([ + user.save(), + task.save(), + ]); + + return results; +} + +async function castMultiTaskSpell (req, user, spell) { + const tasks = await Tasks.Task.find({ + userId: user._id, + ...Tasks.taskIsGroupOrChallengeQuery, + }).exec(); + + spell.cast(user, tasks, req); + + const toSave = tasks + .filter(t => t.isModified()) + .map(t => t.save()); + toSave.unshift(user.save()); + const saved = await Bluebird.all(toSave); + + const response = { + tasks: saved, + user, + }; + + return response; +} + +async function castSelfSpell (req, user, spell) { + spell.cast(user, null, req); + await user.save(); +} + +async function castPartySpell (req, party, partyMembers, user, spell) { + if (!party) { + partyMembers = [user]; // Act as solo party + } else { + partyMembers = await User + .find({ + 'party._id': party._id, + _id: { $ne: user._id }, // add separately + }) + // .select(partyMembersFields) Selecting the entire user because otherwise when saving it'll save + // default values for non-selected fields and pre('save') will mess up thinking some values are missing + .exec(); + + partyMembers.unshift(user); + } + + spell.cast(user, partyMembers, req); + await Bluebird.all(partyMembers.map(m => m.save())); + + return partyMembers; +} + +async function castUserSpell (res, req, party, partyMembers, targetId, user, spell) { + if (!party && (!targetId || user._id === targetId)) { + partyMembers = user; + } else { + if (!targetId) throw new BadRequest(res.t('targetIdUUID')); + if (!party) throw new NotFound(res.t('partyNotFound')); + partyMembers = await User + .findOne({_id: targetId, 'party._id': party._id}) + // .select(partyMembersFields) Selecting the entire user because otherwise when saving it'll save + // default values for non-selected fields and pre('save') will mess up thinking some values are missing + .exec(); + } + + if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId})); + + spell.cast(user, partyMembers, req); + + if (partyMembers !== user) { + await Bluebird.all([ + user.save(), + partyMembers.save(), + ]); + } else { + await partyMembers.save(); // partyMembers is user + } + + return partyMembers; +} + /** * @api {post} /api/v3/user/class/cast/:spellId Cast a skill (spell) on a target * @apiName UserCast @@ -599,104 +698,30 @@ api.castSpell = { let targetType = spell.target; if (targetType === 'task') { - if (!targetId) throw new BadRequest(res.t('targetIdUUID')); - - let task = await Tasks.Task.findOne({ - _id: targetId, - userId: user._id, - }).exec(); - if (!task) throw new NotFound(res.t('taskNotFound')); - if (task.challenge.id) throw new BadRequest(res.t('challengeTasksNoCast')); - if (task.group.id) throw new BadRequest(res.t('groupTasksNoCast')); - - spell.cast(user, task, req); - - let results = await Bluebird.all([ - user.save(), - task.save(), - ]); - + const results = await castTaskSpell(res, req, targetId, user, spell); res.respond(200, { user: results[0], task: results[1], }); } else if (targetType === 'self') { - spell.cast(user, null, req); - await user.save(); + await castSelfSpell(req, user, spell); res.respond(200, { user }); } else if (targetType === 'tasks') { // new target type in v3: when all the user's tasks are necessary - let tasks = await Tasks.Task.find({ - userId: user._id, - ...Tasks.taskIsGroupOrChallengeQuery, - }).exec(); - - spell.cast(user, tasks, req); - - let toSave = tasks - .filter(t => t.isModified()) - .map(t => t.save()); - - toSave.unshift(user.save()); - let saved = await Bluebird.all(toSave); - - let response = { - tasks: saved, - user, - }; - + const response = await castMultiTaskSpell(req, user, spell); res.respond(200, response); } else if (targetType === 'party' || targetType === 'user') { - let party = await Group.getGroup({groupId: 'party', user}); + const party = await Group.getGroup({groupId: 'party', user}); // arrays of users when targetType is 'party' otherwise single users let partyMembers; if (targetType === 'party') { - if (!party) { - partyMembers = [user]; // Act as solo party - } else { - partyMembers = await User - .find({ - 'party._id': party._id, - _id: { $ne: user._id }, // add separately - }) - // .select(partyMembersFields) Selecting the entire user because otherwise when saving it'll save - // default values for non-selected fields and pre('save') will mess up thinking some values are missing - // and we need target.notifications to add the notification for the received card - .exec(); - - partyMembers.unshift(user); - } - - spell.cast(user, partyMembers, req); - await Bluebird.all(partyMembers.map(m => m.save())); + partyMembers = await castPartySpell(req, party, partyMembers, user, spell); } else { - if (!party && (!targetId || user._id === targetId)) { - partyMembers = user; - } else { - if (!targetId) throw new BadRequest(res.t('targetIdUUID')); - if (!party) throw new NotFound(res.t('partyNotFound')); - partyMembers = await User - .findOne({_id: targetId, 'party._id': party._id}) - // .select(partyMembersFields) Selecting the entire user because otherwise when saving it'll save - // default values for non-selected fields and pre('save') will mess up thinking some values are missing - .exec(); - } - - if (!partyMembers) throw new NotFound(res.t('userWithIDNotFound', {userId: targetId})); - - spell.cast(user, partyMembers, req); - - if (partyMembers !== user) { - await Bluebird.all([ - user.save(), - partyMembers.save(), - ]); - } else { - await partyMembers.save(); // partyMembers is user - } + partyMembers = await castUserSpell(res, req, party, partyMembers, targetId, user, spell); } let partyMembersRes = Array.isArray(partyMembers) ? partyMembers : [partyMembers]; + // Only return some fields. // See comment above on why we can't just select the necessary fields when querying partyMembersRes = partyMembersRes.map(partyMember => {