diff --git a/test/common/ops/buyArmoire.js b/test/common/ops/buyArmoire.js index 81f794dc48..13a5907f70 100644 --- a/test/common/ops/buyArmoire.js +++ b/test/common/ops/buyArmoire.js @@ -1,24 +1,17 @@ /* eslint-disable camelcase */ -import sinon from 'sinon'; // eslint-disable-line no-shadow import { generateUser, } from '../../helpers/common.helper'; import count from '../../../website/common/script/count'; import buyArmoire from '../../../website/common/script/ops/buyArmoire'; -import shared from '../../../website/common/script'; import content from '../../../website/common/script/content/index'; import { NotAuthorized, } from '../../../website/common/script/libs/errors'; import i18n from '../../../website/common/script/i18n'; -describe('shared.ops.buyArmoire', () => { - let user; - let YIELD_EQUIPMENT = 0.5; - let YIELD_FOOD = 0.7; - let YIELD_EXP = 0.9; - +function getFullArmoire () { let fullArmoire = {}; _(content.gearTypes).each((type) => { @@ -29,39 +22,36 @@ describe('shared.ops.buyArmoire', () => { }).value(); }).value(); + return fullArmoire; +} + +describe('shared.ops.buyArmoire', () => { + let user; + let YIELD_EQUIPMENT = 0.5; + let YIELD_FOOD = 0.7; + let YIELD_EXP = 0.9; beforeEach(() => { user = generateUser({ - items: { - gear: { - owned: { - weapon_warrior_0: true, - }, - equipped: { - weapon_warrior_0: true, - }, - }, - }, stats: { gp: 200 }, }); - + user.items.gear.owned = { + weapon_warrior_0: true, + }; user.achievements.ultimateGearSets = { rogue: true }; user.flags.armoireOpened = true; user.stats.exp = 0; user.items.food = {}; - sinon.stub(shared.fns, 'randomVal'); - sinon.stub(shared.fns, 'predictableRandom'); + sandbox.stub(Math, 'random'); }); afterEach(() => { - shared.fns.randomVal.restore(); - shared.fns.predictableRandom.restore(); + Math.random.restore(); }); context('failure conditions', () => { it('does not open if user does not have enough gold', (done) => { - shared.fns.predictableRandom.returns(YIELD_EQUIPMENT); user.stats.gp = 50; try { @@ -71,13 +61,6 @@ describe('shared.ops.buyArmoire', () => { expect(err.message).to.equal(i18n.t('messageNotEnoughGold')); expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, - eyewear_special_blackTopFrame: true, - eyewear_special_blueTopFrame: true, - eyewear_special_greenTopFrame: true, - eyewear_special_pinkTopFrame: true, - eyewear_special_redTopFrame: true, - eyewear_special_whiteTopFrame: true, - eyewear_special_yellowTopFrame: true, }); expect(user.items.food).to.be.empty; expect(user.stats.exp).to.eql(0); @@ -86,7 +69,6 @@ describe('shared.ops.buyArmoire', () => { }); it('does not open without Ultimate Gear achievement', (done) => { - shared.fns.predictableRandom.returns(YIELD_EQUIPMENT); user.achievements.ultimateGearSets = {healer: false, wizard: false, rogue: false, warrior: false}; try { @@ -96,13 +78,6 @@ describe('shared.ops.buyArmoire', () => { expect(err.message).to.equal(i18n.t('cannotBuyItem')); expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, - eyewear_special_blackTopFrame: true, - eyewear_special_blueTopFrame: true, - eyewear_special_greenTopFrame: true, - eyewear_special_pinkTopFrame: true, - eyewear_special_redTopFrame: true, - eyewear_special_whiteTopFrame: true, - eyewear_special_yellowTopFrame: true, }); expect(user.items.food).to.be.empty; expect(user.stats.exp).to.eql(0); @@ -112,93 +87,83 @@ describe('shared.ops.buyArmoire', () => { }); context('non-gear awards', () => { - // Skipped because can't stub predictableRandom correctly - xit('gives Experience', () => { - shared.fns.predictableRandom.returns(YIELD_EXP); + it('gives Experience', () => { + let previousExp = user.stats.exp; + Math.random.returns(YIELD_EXP); buyArmoire(user); expect(user.items.gear.owned).to.eql({weapon_warrior_0: true}); expect(user.items.food).to.be.empty; - expect(user.stats.exp).to.eql(46); - expect(user.stats.gp).to.eql(100); + expect(user.stats.exp).to.be.greaterThan(previousExp); + expect(user.stats.gp).to.equal(100); }); - // Skipped because can't stub predictableRandom correctly - xit('gives food', () => { - let honey = content.food.Honey; + it('gives food', () => { + let previousExp = user.stats.exp; - shared.fns.randomVal.returns(honey); - shared.fns.predictableRandom.returns(YIELD_FOOD); + Math.random.returns(YIELD_FOOD); buyArmoire(user); expect(user.items.gear.owned).to.eql({weapon_warrior_0: true}); - expect(user.items.food).to.eql({Honey: 1}); - expect(user.stats.exp).to.eql(0); - expect(user.stats.gp).to.eql(100); + expect(user.items.food).to.not.be.empty; + expect(user.stats.exp).to.equal(previousExp); + expect(user.stats.gp).to.equal(100); }); - // Skipped because can't stub predictableRandom correctly - xit('does not give equipment if all equipment has been found', () => { - shared.fns.predictableRandom.returns(YIELD_EQUIPMENT); - user.items.gear.owned = fullArmoire; + it('does not give equipment if all equipment has been found', () => { + Math.random.returns(YIELD_EQUIPMENT); + user.items.gear.owned = getFullArmoire(); user.stats.gp = 150; buyArmoire(user); - expect(user.items.gear.owned).to.eql(fullArmoire); + expect(user.items.gear.owned).to.eql(getFullArmoire()); let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire'); expect(armoireCount).to.eql(0); - expect(user.stats.exp).to.eql(30); - expect(user.stats.gp).to.eql(50); + expect(user.stats.gp).to.equal(50); }); }); context('gear awards', () => { - beforeEach(() => { - let shield = content.gear.tree.shield.armoire.gladiatorShield; - - shared.fns.randomVal.returns(shield); - }); - - // Skipped because can't stub predictableRandom correctly - xit('always drops equipment the first time', () => { + it('always drops equipment the first time', () => { delete user.flags.armoireOpened; - shared.fns.predictableRandom.returns(YIELD_EXP); + Math.random.returns(YIELD_EXP); + + expect(_.size(user.items.gear.owned)).to.equal(1); buyArmoire(user); - expect(user.items.gear.owned).to.eql({ - weapon_warrior_0: true, - shield_armoire_gladiatorShield: true, - }); + expect(_.size(user.items.gear.owned)).to.equal(2); let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire'); - expect(armoireCount).to.eql(_.size(fullArmoire) - 1); + expect(armoireCount).to.eql(_.size(getFullArmoire()) - 1); expect(user.items.food).to.be.empty; - expect(user.stats.exp).to.eql(0); - expect(user.stats.gp).to.eql(100); + expect(user.stats.exp).to.equal(0); + expect(user.stats.gp).to.equal(100); }); - // Skipped because can't stub predictableRandom correctly - xit('gives more equipment', () => { - shared.fns.predictableRandom.returns(YIELD_EQUIPMENT); + it('gives more equipment', () => { + Math.random.returns(YIELD_EQUIPMENT); user.items.gear.owned = { weapon_warrior_0: true, head_armoire_hornedIronHelm: true, }; user.stats.gp = 200; + expect(_.size(user.items.gear.owned)).to.equal(2); + buyArmoire(user); - expect(user.items.gear.owned).to.eql({weapon_warrior_0: true, shield_armoire_gladiatorShield: true, head_armoire_hornedIronHelm: true}); + expect(_.size(user.items.gear.owned)).to.equal(3); + let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire'); - expect(armoireCount).to.eql(_.size(fullArmoire) - 2); + expect(armoireCount).to.eql(_.size(getFullArmoire()) - 2); expect(user.stats.gp).to.eql(100); }); }); diff --git a/website/common/script/ops/buyArmoire.js b/website/common/script/ops/buyArmoire.js index a07f7e8d79..5b40d6da04 100644 --- a/website/common/script/ops/buyArmoire.js +++ b/website/common/script/ops/buyArmoire.js @@ -6,9 +6,11 @@ import splitWhitespace from '../libs/splitWhitespace'; import { NotAuthorized, } from '../libs/errors'; -import predictableRandom from '../fns/predictableRandom'; import randomVal from '../fns/randomVal'; +const YIELD_EQUIPMENT_THRESHOLD = 0.6; +const YIELD_FOOD_THRESHOLD = 0.8; + module.exports = function buyArmoire (user, req = {}, analytics) { let item = content.armoire; @@ -21,17 +23,16 @@ module.exports = function buyArmoire (user, req = {}, analytics) { } let armoireResp; - let armoireResult; - let eligibleEquipment; let drop; let message; - armoireResult = predictableRandom(user, user.stats.gp); - eligibleEquipment = _.filter(content.gear.flat, (eligible) => { + let armoireResult = Math.random(); + let eligibleEquipment = _.filter(content.gear.flat, (eligible) => { return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key]; }); + let armoireHasEquipment = !_.isEmpty(eligibleEquipment); - if (!_.isEmpty(eligibleEquipment) && (armoireResult < 0.6 || !user.flags.armoireOpened)) { + if (armoireHasEquipment && (armoireResult < YIELD_EQUIPMENT_THRESHOLD || !user.flags.armoireOpened)) { eligibleEquipment.sort(); drop = randomVal(user, eligibleEquipment); @@ -55,10 +56,11 @@ module.exports = function buyArmoire (user, req = {}, analytics) { dropKey: drop.key, dropText: drop.text(req.language), }; - } else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens + } else if ((armoireHasEquipment && armoireResult < YIELD_FOOD_THRESHOLD) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens drop = randomVal(user, _.where(content.food, { canDrop: true, })); + user.items.food[drop.key] = user.items.food[drop.key] || 0; user.items.food[drop.key] += 1; @@ -74,7 +76,7 @@ module.exports = function buyArmoire (user, req = {}, analytics) { dropText: drop.text(req.language), }; } else { - let armoireExp = Math.floor(predictableRandom(user, user.stats.exp) * 40 + 10); + let armoireExp = Math.floor(Math.random() * 40 + 10); user.stats.exp += armoireExp; message = i18n.t('armoireExp', req.language); armoireResp = {