diff --git a/test/api/v3/integration/quests/POST-groups_groupId_quests_force-start.test.js b/test/api/v3/integration/quests/POST-groups_groupId_quests_force-start.test.js index e569b14c33..bf295ee892 100644 --- a/test/api/v3/integration/quests/POST-groups_groupId_quests_force-start.test.js +++ b/test/api/v3/integration/quests/POST-groups_groupId_quests_force-start.test.js @@ -149,5 +149,87 @@ describe('POST /groups/:groupId/quests/force-start', () => { expect(partyMemberThatIgnores.party.quest.key).to.not.exist; expect(partyMemberThatIgnores.party.quest.completed).to.not.exist; }); + + it('removes users who have not accepted the quest from quest.members', async () => { + let partyMemberThatRejects = partyMembers[1]; + let partyMemberThatIgnores = partyMembers[2]; + let partyMemberThatAccepts = partyMembers[0]; + + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + await partyMemberThatAccepts.post(`/groups/${questingGroup._id}/quests/accept`); + await partyMemberThatRejects.post(`/groups/${questingGroup._id}/quests/reject`); + + await leader.post(`/groups/${questingGroup._id}/quests/force-start`); + + await Bluebird.delay(500); + + await questingGroup.sync(); + + expect(questingGroup.quest.members[partyMemberThatRejects._id]).to.not.exist; + expect(questingGroup.quest.members[partyMemberThatIgnores._id]).to.not.exist; + expect(questingGroup.quest.members[partyMemberThatAccepts._id]).to.exist; + expect(questingGroup.quest.members[leader._id]).to.exist; + }); + + it('removes users who are not in the party from quest.members', async () => { + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + let notInPartyUser = await generateUser(); + + await questingGroup.update({ + [`quest.members.${notInPartyUser._id}`]: true, + }); + await questingGroup.sync(); + + expect(questingGroup.quest.members[notInPartyUser._id]).to.eql(true); + + await leader.post(`/groups/${questingGroup._id}/quests/force-start`); + + await Bluebird.delay(500); + + await questingGroup.sync(); + + expect(questingGroup.quest.members[notInPartyUser._id]).to.not.exist; + }); + + it('removes users who have been deleted from quest.members', async () => { + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`); + + await partyMembers[0].del('/user', { + password: 'password', + }); + + await leader.post(`/groups/${questingGroup._id}/quests/force-start`); + + await Bluebird.delay(500); + + await questingGroup.sync(); + + expect(questingGroup.quest.members[partyMembers[0]._id]).to.not.exist; + }); + + it('removes users who don\'t have true value in quest.members from quest.members', async () => { + let partyMemberThatRejects = partyMembers[1]; + let partyMemberThatIgnores = partyMembers[2]; + + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`); + + await questingGroup.update({ + [`quest.members.${partyMemberThatRejects._id}`]: false, + [`quest.members.${partyMemberThatIgnores._id}`]: null, + }); + + await leader.post(`/groups/${questingGroup._id}/quests/force-start`); + + await Bluebird.delay(500); + + await questingGroup.sync(); + + expect(questingGroup.quest.members[partyMemberThatRejects._id]).to.not.exist; + expect(questingGroup.quest.members[partyMemberThatIgnores._id]).to.not.exist; + expect(questingGroup.quest.members[partyMembers[0]._id]).to.exist; + expect(questingGroup.quest.members[leader._id]).to.exist; + }); }); }); diff --git a/website/server/models/group.js b/website/server/models/group.js index 5eee28f5e9..d5aa3d4536 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -393,6 +393,17 @@ schema.methods.startQuest = async function startQuest (user) { let nonUserQuestMembers = _.keys(this.quest.members); removeFromArray(nonUserQuestMembers, user._id); + // remove any users from quest.members who aren't in the party + let partyId = this._id; + let questMembers = this.quest.members; + await Bluebird.map(Object.keys(this.quest.members), async (memberId) => { + let member = await User.findOne({_id: memberId, 'party._id': partyId}).select('_id').lean(); + + if (!member) { + delete questMembers[memberId]; + } + }); + if (userIsParticipating) { user.party.quest.key = this.quest.key; user.party.quest.progress.down = 0;