mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-07-20 02:34:12 +00:00
fix(api): Only award participating members the quest rewards (#7706)
This commit is contained in:
parent
b27b18b323
commit
d5a354b499
2 changed files with 225 additions and 8 deletions
|
|
@ -385,18 +385,55 @@ describe('Group Model', () => {
|
|||
let quest = questScrolls[party.quest.key];
|
||||
let finishQuest = sandbox.spy(Group.prototype, 'finishQuest');
|
||||
|
||||
progress.collectedItems = 999; // TODO should this be collectedItems? What is this testing?
|
||||
progress.collectedItems = 999;
|
||||
|
||||
await Group.processQuestProgress(participatingMember, progress);
|
||||
|
||||
expect(finishQuest).to.be.calledOnce;
|
||||
expect(finishQuest).to.be.calledWith(quest);
|
||||
});
|
||||
|
||||
it('gives out rewards when quest finishes', async () => {
|
||||
progress.collectedItems = 999;
|
||||
|
||||
await Group.processQuestProgress(participatingMember, progress);
|
||||
|
||||
let [
|
||||
updatedLeader,
|
||||
updatedParticipatingMember,
|
||||
] = await Promise.all([
|
||||
User.findById(questLeader._id),
|
||||
User.findById(participatingMember._id),
|
||||
]);
|
||||
|
||||
expect(updatedLeader.achievements.quests[party.quest.key]).to.eql(1);
|
||||
expect(updatedLeader.stats.exp).to.be.greaterThan(0);
|
||||
expect(updatedLeader.stats.gp).to.be.greaterThan(0);
|
||||
expect(updatedParticipatingMember.achievements.quests[party.quest.key]).to.eql(1);
|
||||
expect(updatedParticipatingMember.stats.exp).to.be.greaterThan(0);
|
||||
expect(updatedParticipatingMember.stats.gp).to.be.greaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('Instance Methods', () => {
|
||||
describe('#getParticipatingQuestMembers', () => {
|
||||
it('returns an array of members whose quest status set to true', () => {
|
||||
party.quest.members = {
|
||||
[participatingMember._id]: true,
|
||||
[questLeader._id]: true,
|
||||
[nonParticipatingMember._id]: false,
|
||||
[undecidedMember._id]: null,
|
||||
};
|
||||
|
||||
expect(party.getParticipatingQuestMembers()).to.eql([
|
||||
participatingMember._id,
|
||||
questLeader._id,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#sendChat', () => {
|
||||
beforeEach(() => {
|
||||
sandbox.spy(User, 'update');
|
||||
|
|
@ -795,5 +832,178 @@ describe('Group Model', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#finishQuest', () => {
|
||||
let quest;
|
||||
|
||||
beforeEach(() => {
|
||||
quest = questScrolls.whale;
|
||||
party.quest.key = quest.key;
|
||||
party.quest.active = false;
|
||||
party.quest.leader = questLeader._id;
|
||||
party.quest.members = {
|
||||
[questLeader._id]: true,
|
||||
[participatingMember._id]: true,
|
||||
[nonParticipatingMember._id]: false,
|
||||
[undecidedMember._id]: null,
|
||||
};
|
||||
|
||||
sandbox.spy(User, 'update');
|
||||
});
|
||||
|
||||
it('gives out achievements', async () => {
|
||||
await party.finishQuest(quest);
|
||||
|
||||
let [
|
||||
updatedLeader,
|
||||
updatedParticipatingMember,
|
||||
] = await Promise.all([
|
||||
User.findById(questLeader._id),
|
||||
User.findById(participatingMember._id),
|
||||
]);
|
||||
|
||||
expect(updatedLeader.achievements.quests[quest.key]).to.eql(1);
|
||||
expect(updatedParticipatingMember.achievements.quests[quest.key]).to.eql(1);
|
||||
});
|
||||
|
||||
it('gives xp and gold', async () => {
|
||||
await party.finishQuest(quest);
|
||||
|
||||
let [
|
||||
updatedLeader,
|
||||
updatedParticipatingMember,
|
||||
] = await Promise.all([
|
||||
User.findById(questLeader._id),
|
||||
User.findById(participatingMember._id),
|
||||
]);
|
||||
|
||||
expect(updatedLeader.stats.exp).to.eql(quest.drop.exp);
|
||||
expect(updatedLeader.stats.gp).to.eql(quest.drop.gp);
|
||||
expect(updatedParticipatingMember.stats.exp).to.eql(quest.drop.exp);
|
||||
expect(updatedParticipatingMember.stats.gp).to.eql(quest.drop.gp);
|
||||
});
|
||||
|
||||
context('drops', () => {
|
||||
it('awards gear', async () => {
|
||||
let gearQuest = questScrolls.vice3;
|
||||
|
||||
await party.finishQuest(gearQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.gear.owned.weapon_special_2).to.eql(true);
|
||||
});
|
||||
|
||||
it('awards eggs', async () => {
|
||||
let eggQuest = questScrolls.vice3;
|
||||
|
||||
await party.finishQuest(eggQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.eggs.Dragon).to.eql(2);
|
||||
});
|
||||
|
||||
it('awards food', async () => {
|
||||
let foodQuest = questScrolls.moonstone3;
|
||||
|
||||
await party.finishQuest(foodQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.food.RottenMeat).to.eql(5);
|
||||
});
|
||||
|
||||
it('awards hatching potions', async () => {
|
||||
let hatchingPotionQuest = questScrolls.vice3;
|
||||
|
||||
await party.finishQuest(hatchingPotionQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.hatchingPotions.Shade).to.eql(2);
|
||||
});
|
||||
|
||||
it('awards quests', async () => {
|
||||
let questAwardQuest = questScrolls.vice2;
|
||||
|
||||
await party.finishQuest(questAwardQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.quests.vice3).to.eql(1);
|
||||
});
|
||||
|
||||
it('awards pets', async () => {
|
||||
let petQuest = questScrolls.evilsanta2;
|
||||
|
||||
await party.finishQuest(petQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.pets['BearCub-Polar']).to.eql(5);
|
||||
});
|
||||
|
||||
it('awards mounts', async () => {
|
||||
let mountQuest = questScrolls.evilsanta;
|
||||
|
||||
await party.finishQuest(mountQuest);
|
||||
|
||||
let updatedParticipatingMember = await User.findById(participatingMember._id);
|
||||
|
||||
expect(updatedParticipatingMember.items.mounts['BearCub-Polar']).to.eql(true);
|
||||
});
|
||||
});
|
||||
|
||||
context('Party quests', () => {
|
||||
it('updates participating members with rewards', async () => {
|
||||
await party.finishQuest(quest);
|
||||
|
||||
expect(User.update).to.be.calledOnce;
|
||||
expect(User.update).to.be.calledWithMatch({
|
||||
_id: {
|
||||
$in: [questLeader._id, participatingMember._id],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('sets user quest object to a clean state', async () => {
|
||||
await party.finishQuest(quest);
|
||||
|
||||
let updatedLeader = await User.findById(questLeader._id);
|
||||
|
||||
expect(updatedLeader.party.quest.completed).to.eql('whale');
|
||||
expect(updatedLeader.party.quest.progress.up).to.eql(0);
|
||||
expect(updatedLeader.party.quest.progress.down).to.eql(0);
|
||||
expect(updatedLeader.party.quest.progress.collectedItems).to.eql(0);
|
||||
expect(updatedLeader.party.quest.RSVPNeeded).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
context('World quests in Tavern', () => {
|
||||
let tavernQuest;
|
||||
|
||||
beforeEach(() => {
|
||||
party._id = TAVERN_ID;
|
||||
party.quest.key = 'stressbeast';
|
||||
tavernQuest = questScrolls.stressbeast;
|
||||
});
|
||||
|
||||
it('updates all users with rewards', async () => {
|
||||
await party.finishQuest(tavernQuest);
|
||||
|
||||
expect(User.update).to.be.calledOnce;
|
||||
expect(User.update).to.be.calledWithMatch({});
|
||||
});
|
||||
|
||||
it('sets quest completed to the world quest key', async () => {
|
||||
await party.finishQuest(tavernQuest);
|
||||
|
||||
let updatedLeader = await User.findById(questLeader._id);
|
||||
|
||||
expect(updatedLeader.party.quest.completed).to.eql(tavernQuest.key);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -248,6 +248,10 @@ schema.statics.toJSONCleanChat = function groupToJSONCleanChat (group, user) {
|
|||
return toJSON;
|
||||
};
|
||||
|
||||
schema.methods.getParticipatingQuestMembers = function getParticipatingQuestMembers () {
|
||||
return Object.keys(this.quest.members).filter(member => this.quest.members[member]);
|
||||
};
|
||||
|
||||
schema.methods.removeGroupInvitations = async function removeGroupInvitations () {
|
||||
let group = this;
|
||||
|
||||
|
|
@ -450,11 +454,14 @@ schema.statics.cleanGroupQuest = function cleanGroupQuest () {
|
|||
// Changes the group object update members
|
||||
schema.methods.finishQuest = async function finishQuest (quest) {
|
||||
let questK = quest.key;
|
||||
let updates = {$inc: {}, $set: {}};
|
||||
|
||||
updates.$inc[`achievements.quests.${questK}`] = 1;
|
||||
updates.$inc['stats.gp'] = Number(quest.drop.gp);
|
||||
updates.$inc['stats.exp'] = Number(quest.drop.exp);
|
||||
let updates = {
|
||||
$inc: {
|
||||
[`achievements.quests.${questK}`]: 1,
|
||||
'stats.gp': Number(quest.drop.gp),
|
||||
'stats.exp': Number(quest.drop.exp),
|
||||
},
|
||||
$set: {},
|
||||
};
|
||||
|
||||
if (this._id === TAVERN_ID) {
|
||||
updates.$set['party.quest.completed'] = questK; // Just show the notif
|
||||
|
|
@ -489,7 +496,7 @@ schema.methods.finishQuest = async function finishQuest (quest) {
|
|||
}
|
||||
});
|
||||
|
||||
let q = this._id === TAVERN_ID ? {} : {_id: {$in: _.keys(this.quest.members)}};
|
||||
let q = this._id === TAVERN_ID ? {} : {_id: {$in: this.getParticipatingQuestMembers()}};
|
||||
this.quest = {};
|
||||
this.markModified('quest');
|
||||
|
||||
|
|
@ -532,7 +539,7 @@ schema.methods._processBossQuest = async function processBossQuest (options) {
|
|||
|
||||
// Everyone takes damage
|
||||
await User.update({
|
||||
_id: {$in: _.keys(_.pick(group.quest.members, _.identity))},
|
||||
_id: {$in: this.getParticipatingQuestMembers()},
|
||||
}, {
|
||||
$inc: {'stats.hp': down},
|
||||
}, {multi: true}).exec();
|
||||
|
|
|
|||
Loading…
Reference in a new issue