diff --git a/test/api/v3/integration/quests/POST-groups_groupId_quests_accept.test.js b/test/api/v3/integration/quests/POST-groups_groupId_quests_accept.test.js index ed57d4250a..ea5f32d23f 100644 --- a/test/api/v3/integration/quests/POST-groups_groupId_quests_accept.test.js +++ b/test/api/v3/integration/quests/POST-groups_groupId_quests_accept.test.js @@ -148,5 +148,16 @@ describe('POST /groups/:groupId/quests/accept', () => { expect(rejectingMember.party.quest.key).to.not.exist; expect(rejectingMember.party.quest.completed).to.not.exist; }); + + it('begins the quest if accepting the last pending invite and verifies chat', async () => { + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`); + // quest will start after everyone has accepted + await partyMembers[1].post(`/groups/${questingGroup._id}/quests/accept`); + + await questingGroup.sync(); + expect(questingGroup.chat[0].text).to.exist; + expect(questingGroup.chat[0]._meta).to.exist; + }); }); }); 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 bf295ee892..d07ba9e31a 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 @@ -231,5 +231,18 @@ describe('POST /groups/:groupId/quests/force-start', () => { expect(questingGroup.quest.members[partyMembers[0]._id]).to.exist; expect(questingGroup.quest.members[leader._id]).to.exist; }); + + it('allows group leader to force start quest and verifies chat', async () => { + let questLeader = partyMembers[0]; + await questLeader.update({[`items.quests.${PET_QUEST}`]: 1}); + await questLeader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + + await leader.post(`/groups/${questingGroup._id}/quests/force-start`); + + await questingGroup.sync(); + + expect(questingGroup.chat[0].text).to.exist; + expect(questingGroup.chat[0]._meta).to.exist; + }); }); }); diff --git a/test/api/v3/integration/quests/POST-groups_groupId_quests_invite.test.js b/test/api/v3/integration/quests/POST-groups_groupId_quests_invite.test.js index 6ae491fc8a..b2e0b832aa 100644 --- a/test/api/v3/integration/quests/POST-groups_groupId_quests_invite.test.js +++ b/test/api/v3/integration/quests/POST-groups_groupId_quests_invite.test.js @@ -188,5 +188,21 @@ describe('POST /groups/:groupId/quests/invite/:questKey', () => { expect(group.quest.active).to.eql(true); }); + + it('starts quest automatically if user is in a solo party and verifies chat', async () => { + let leaderDetails = { balance: 10 }; + leaderDetails[`items.quests.${PET_QUEST}`] = 1; + let { group, groupLeader } = await createAndPopulateGroup({ + groupDetails: { type: 'party', privacy: 'private' }, + leaderDetails, + }); + + await groupLeader.post(`/groups/${group._id}/quests/invite/${PET_QUEST}`); + + await group.sync(); + + expect(group.chat[0].text).to.exist; + expect(group.chat[0]._meta).to.exist; + }); }); }); diff --git a/test/api/v3/integration/quests/POST-groups_groupid_quests_reject.test.js b/test/api/v3/integration/quests/POST-groups_groupid_quests_reject.test.js index 8bdb3b7ba7..d3b0806089 100644 --- a/test/api/v3/integration/quests/POST-groups_groupid_quests_reject.test.js +++ b/test/api/v3/integration/quests/POST-groups_groupid_quests_reject.test.js @@ -180,5 +180,15 @@ describe('POST /groups/:groupId/quests/reject', () => { expect(rejectingMember.party.quest.key).to.not.exist; expect(rejectingMember.party.quest.completed).to.not.exist; }); + + it('starts the quest when the last user reject and verifies chat', async () => { + await leader.post(`/groups/${questingGroup._id}/quests/invite/${PET_QUEST}`); + await partyMembers[0].post(`/groups/${questingGroup._id}/quests/accept`); + await partyMembers[1].post(`/groups/${questingGroup._id}/quests/reject`); + await questingGroup.sync(); + + expect(questingGroup.chat[0].text).to.exist; + expect(questingGroup.chat[0]._meta).to.exist; + }); }); }); diff --git a/test/api/v3/unit/models/group.test.js b/test/api/v3/unit/models/group.test.js index 38695730db..e439b36e9d 100644 --- a/test/api/v3/unit/models/group.test.js +++ b/test/api/v3/unit/models/group.test.js @@ -365,6 +365,7 @@ describe('Group Model', () => { party.quest.active = false; await party.startQuest(questLeader); + Group.prototype.sendChat.reset(); await party.save(); await Group.processQuestProgress(participatingMember, progress); @@ -383,6 +384,7 @@ describe('Group Model', () => { party.quest.active = false; await party.startQuest(questLeader); + Group.prototype.sendChat.reset(); await party.save(); await Group.processQuestProgress(participatingMember, progress); diff --git a/website/server/controllers/api-v3/quests.js b/website/server/controllers/api-v3/quests.js index edb3bf2f74..1d17e114a4 100644 --- a/website/server/controllers/api-v3/quests.js +++ b/website/server/controllers/api-v3/quests.js @@ -65,7 +65,7 @@ api.inviteToQuest = { let validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'}); + let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest chat'}); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -180,7 +180,7 @@ api.acceptQuest = { user.party.quest.RSVPNeeded = false; await user.save(); - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'}); + let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest chat'}); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -240,7 +240,7 @@ api.rejectQuest = { user.markModified('party.quest'); await user.save(); - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest'}); + let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest chat'}); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); if (!group.quest.key) throw new NotFound(res.t('questInvitationDoesNotExist')); @@ -299,7 +299,7 @@ api.forceStart = { let validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest leader'}); + let group = await Group.getGroup({user, groupId: req.params.groupId, fields: 'type quest leader chat'}); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); diff --git a/website/server/models/group.js b/website/server/models/group.js index 7f345b6da9..ae8a3f594f 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -389,8 +389,11 @@ export function chatDefaults (msg, user) { return message; } -schema.methods.sendChat = function sendChat (message, user) { +schema.methods.sendChat = function sendChat (message, user, metaData) { let newMessage = chatDefaults(message, user); + if (metaData) { + newMessage._meta = metaData; + } this.chat.unshift(newMessage); @@ -546,6 +549,9 @@ schema.methods.startQuest = async function startQuest (user) { }); }); }); + this.sendChat(`Your quest, ${quest.text('en')}, has started.`, null, { + participatingMembers: this.getParticipatingQuestMembers().join(', '), + }); }; schema.methods.sendGroupChatReceivedWebhooks = function sendGroupChatReceivedWebhooks (chat) {