Collection quests: make sure users cannot earn "excess" items (#12098)

* fix(collection quests): make sure users cannot earn "excess" collection items

* add test
This commit is contained in:
Matteo Pagliazzi
2020-04-20 23:12:05 +02:00
committed by GitHub
parent 2e97f9864e
commit 97209e40ad
2 changed files with 65 additions and 41 deletions

View File

@@ -538,52 +538,74 @@ describe('Group Model', () => {
}); });
}); });
it('sends a chat message if no progress is made on quest with multiple items', async () => { describe('collection quests with multiple items', () => {
progress.collectedItems = 0; it('sends a chat message if no progress is made on quest with multiple items', async () => {
party.quest.key = 'dilatoryDistress1'; progress.collectedItems = 0;
party.quest.active = false; party.quest.key = 'dilatoryDistress1';
party.quest.active = false;
await party.startQuest(questLeader); await party.startQuest(questLeader);
Group.prototype.sendChat.resetHistory(); Group.prototype.sendChat.resetHistory();
await party.save(); await party.save();
await Group.processQuestProgress(participatingMember, progress); await Group.processQuestProgress(participatingMember, progress);
party = await Group.findOne({ _id: party._id }); party = await Group.findOne({ _id: party._id });
expect(Group.prototype.sendChat).to.be.calledOnce; expect(Group.prototype.sendChat).to.be.calledOnce;
expect(Group.prototype.sendChat).to.be.calledWith({ expect(Group.prototype.sendChat).to.be.calledWith({
message: '`Participating Member found 0 Fire Coral, 0 Blue Fins.`', message: '`Participating Member found 0 Fire Coral, 0 Blue Fins.`',
info: { info: {
items: { blueFins: 0, fireCoral: 0 }, items: { blueFins: 0, fireCoral: 0 },
quest: 'dilatoryDistress1', quest: 'dilatoryDistress1',
type: 'user_found_items', type: 'user_found_items',
user: 'Participating Member', user: 'Participating Member',
}, },
});
}); });
});
it('handles collection quests with multiple items', async () => { it('handles correctly', async () => {
progress.collectedItems = 10; progress.collectedItems = 10;
party.quest.key = 'evilsanta2'; party.quest.key = 'evilsanta2';
party.quest.active = false; party.quest.active = false;
await party.startQuest(questLeader); await party.startQuest(questLeader);
Group.prototype.sendChat.resetHistory(); Group.prototype.sendChat.resetHistory();
await party.save(); await party.save();
await Group.processQuestProgress(participatingMember, progress); await Group.processQuestProgress(participatingMember, progress);
party = await Group.findOne({ _id: party._id }); party = await Group.findOne({ _id: party._id });
expect(Group.prototype.sendChat).to.be.calledOnce; expect(Group.prototype.sendChat).to.be.calledOnce;
expect(Group.prototype.sendChat).to.be.calledWithMatch({ expect(Group.prototype.sendChat).to.be.calledWithMatch({
message: sinon.match(/`Participating Member found/).and(sinon.match(/\d* (Tracks|Broken Twigs)/)), message: sinon.match(/`Participating Member found/).and(sinon.match(/\d* (Tracks|Broken Twigs)/)),
info: { info: {
quest: 'evilsanta2', quest: 'evilsanta2',
type: 'user_found_items', type: 'user_found_items',
user: 'Participating Member', user: 'Participating Member',
}, },
});
});
it('cannot collect excess items', async () => {
// Make sure the quest progress isn't erased
sandbox.stub(Group.prototype, 'finishQuest').returns(Promise.resolve());
progress.collectedItems = 500;
party.quest.key = 'evilsanta2';
party.quest.active = false;
await party.startQuest(questLeader);
await party.save();
await Group.processQuestProgress(participatingMember, progress);
party = await Group.findOne({ _id: party._id });
expect(party.quest.progress.collect.tracks)
.to.eql(questScrolls.evilsanta2.collect.tracks.count);
expect(party.quest.progress.collect.branches)
.to.eql(questScrolls.evilsanta2.collect.branches.count);
}); });
}); });

View File

@@ -1141,7 +1141,7 @@ schema.methods._processCollectionQuest = async function processCollectionQuest (
const itemsFound = {}; const itemsFound = {};
const possibleItemKeys = Object.keys(quest.collect) const possibleItemKeys = Object.keys(quest.collect)
.filter(key => group.quest.progress.collect[key] !== quest.collect[key].count); .filter(key => group.quest.progress.collect[key] < quest.collect[key].count);
const possibleItemsToCollect = possibleItemKeys.reduce((accumulator, current, index) => { const possibleItemsToCollect = possibleItemKeys.reduce((accumulator, current, index) => {
accumulator[possibleItemKeys[index]] = quest.collect[current]; accumulator[possibleItemKeys[index]] = quest.collect[current];
@@ -1151,11 +1151,13 @@ schema.methods._processCollectionQuest = async function processCollectionQuest (
_.times(progress.collectedItems, () => { _.times(progress.collectedItems, () => {
const item = shared.randomVal(possibleItemsToCollect, { key: true }); const item = shared.randomVal(possibleItemsToCollect, { key: true });
if (!itemsFound[item]) { if (group.quest.progress.collect[item] < quest.collect[item].count) {
itemsFound[item] = 0; if (!itemsFound[item]) {
itemsFound[item] = 0;
}
itemsFound[item] += 1;
group.quest.progress.collect[item] += 1;
} }
itemsFound[item] += 1;
group.quest.progress.collect[item] += 1;
}); });
// Add 0 for all items not found // Add 0 for all items not found