diff --git a/test/api/v3/unit/models/user.test.js b/test/api/v3/unit/models/user.test.js index 0192fe42ee..0f128cd296 100644 --- a/test/api/v3/unit/models/user.test.js +++ b/test/api/v3/unit/models/user.test.js @@ -210,4 +210,47 @@ describe('User Model', () => { expect(user.hasNotCancelled()).to.be.false; }); }); + + context('pre-save hook', () => { + it('does not try to award achievements when achievements or items not selected in query', async () => { + let user = new User(); + user = await user.save(); // necessary for user.isSelected to work correctly + + // Create conditions for the Beast Master achievement to be awarded + user.achievements.beastMasterCount = 3; + expect(user.achievements.beastMaster).to.not.equal(true); // verify that it was not awarded initially + + user = await user.save(); + // verify that it's been awarded + expect(user.achievements.beastMaster).to.equal(true); + + // reset the user + user.achievements.beastMasterCount = 0; + user.achievements.beastMaster = false; + + user = await user.save(); + // verify it's been removed + expect(user.achievements.beastMaster).to.equal(false); + + // fetch the user without selecting the 'items' field + user = await User.findById(user._id).select('-items').exec(); + expect(user.isSelected('items')).to.equal(false); + + // create the conditions for the beast master achievement but this time it should not be awarded + user.achievements.beastMasterCount = 3; + user = await user.save(); + expect(user.achievements.beastMaster).to.equal(false); + + // reset + user.achievements.beastMasterCount = 0; + user = await user.save(); + + // this time with achievements not selected + user = await User.findById(user._id).select('-achievements').exec(); + expect(user.isSelected('achievements')).to.equal(false); + user.achievements.beastMasterCount = 3; + user = await user.save(); + expect(user.achievements.beastMaster).to.not.equal(true); + }); + }); }); diff --git a/website/server/models/user/hooks.js b/website/server/models/user/hooks.js index f2a4389446..7d1685581f 100644 --- a/website/server/models/user/hooks.js +++ b/website/server/models/user/hooks.js @@ -171,7 +171,7 @@ schema.pre('save', true, function preSaveUser (next, done) { // since it'll break as soon as a new field is added to the schema but not here. // do not calculate achievements if items or achievements are not selected - if (!this.isSelected('items') || !this.isSelected('achievements')) { + if (this.isSelected('items') && this.isSelected('achievements')) { // Determines if Beast Master should be awarded let beastMasterProgress = shared.count.beastMasterProgress(this.items.pets);