diff --git a/test/common/ops/buy/buySpecialSpell.js b/test/common/ops/buy/buySpell.js similarity index 90% rename from test/common/ops/buy/buySpecialSpell.js rename to test/common/ops/buy/buySpell.js index bd4b0cf22c..02d0bda6a4 100644 --- a/test/common/ops/buy/buySpecialSpell.js +++ b/test/common/ops/buy/buySpell.js @@ -1,4 +1,4 @@ -import buySpecialSpell from '../../../../website/common/script/ops/buy/buySpecialSpell'; +import {BuySpellOperation} from '../../../../website/common/script/ops/buy/buySpell'; import { BadRequest, NotFound, @@ -15,6 +15,11 @@ describe('shared.ops.buySpecialSpell', () => { let user; let analytics = {track () {}}; + function buySpecialSpell (_user, _req, _analytics) { + const buyOp = new BuySpellOperation(_user, _req, _analytics); + + return buyOp.purchase(); + } beforeEach(() => { user = generateUser(); sinon.stub(analytics, 'track'); diff --git a/website/client/store/actions/shops.js b/website/client/store/actions/shops.js index 56bbf4ac9b..1900533e1a 100644 --- a/website/client/store/actions/shops.js +++ b/website/client/store/actions/shops.js @@ -1,7 +1,6 @@ import axios from 'axios'; import buyOp from 'common/script/ops/buy/buy'; import content from 'common/script/content/index'; -import purchaseOp from 'common/script/ops/buy/purchaseWithSpell'; import hourglassPurchaseOp from 'common/script/ops/buy/hourglassPurchase'; import sellOp from 'common/script/ops/sell'; import unlockOp from 'common/script/ops/unlock'; @@ -91,7 +90,7 @@ async function buyArmoire (store, params) { export function purchase (store, params) { const quantity = params.quantity || 1; const user = store.state.user.data; - let opResult = purchaseOp(user, {params, quantity}); + let opResult = buyOp(user, {params, quantity}); return { result: opResult, diff --git a/website/common/script/ops/buy/buy.js b/website/common/script/ops/buy/buy.js index e3cb62bdca..9bcee0706e 100644 --- a/website/common/script/ops/buy/buy.js +++ b/website/common/script/ops/buy/buy.js @@ -7,7 +7,7 @@ import {BuyHealthPotionOperation} from './buyHealthPotion'; import {BuyMarketGearOperation} from './buyMarketGear'; import buyMysterySet from './buyMysterySet'; import {BuyQuestWithGoldOperation} from './buyQuest'; -import buySpecialSpell from './buySpecialSpell'; +import {BuySpellOperation} from './buySpell'; import purchaseOp from './purchase'; import hourglassPurchase from './hourglassPurchase'; import errorMessage from '../../libs/errorMessage'; @@ -70,9 +70,12 @@ module.exports = function buy (user, req = {}, analytics) { buyRes = buyOp.purchase(); break; } - case 'special': - buyRes = buySpecialSpell(user, req, analytics); + case 'special': { + const buyOp = new BuySpellOperation(user, req, analytics); + + buyRes = buyOp.purchase(); break; + } default: { const buyOp = new BuyMarketGearOperation(user, req, analytics); diff --git a/website/common/script/ops/buy/buyQuest.js b/website/common/script/ops/buy/buyQuest.js index b7e9f783b9..1fd60949fd 100644 --- a/website/common/script/ops/buy/buyQuest.js +++ b/website/common/script/ops/buy/buyQuest.js @@ -25,6 +25,10 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { user.achievements.quests.taskwoodsTerror3; } + getItemKey () { + return this.key; + } + getItemValue (item) { return item.goldValue; } @@ -61,13 +65,4 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { }), ]; } - - analyticsData () { - return { - itemKey: this.key, - itemType: 'Market', - acquireMethod: 'Gold', - goldCost: this.getItemValue(this.item.goldValue), - }; - } } diff --git a/website/common/script/ops/buy/buySpecialSpell.js b/website/common/script/ops/buy/buySpecialSpell.js deleted file mode 100644 index d63638acfd..0000000000 --- a/website/common/script/ops/buy/buySpecialSpell.js +++ /dev/null @@ -1,48 +0,0 @@ -import i18n from '../../i18n'; -import content from '../../content/index'; -import get from 'lodash/get'; -import pick from 'lodash/pick'; -import splitWhitespace from '../../libs/splitWhitespace'; -import { - BadRequest, - NotAuthorized, - NotFound, -} from '../../libs/errors'; -import errorMessage from '../../libs/errorMessage'; - -module.exports = function buySpecialSpell (user, req = {}, analytics) { - let key = get(req, 'params.key'); - let quantity = req.quantity || 1; - - if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - - let item = content.special[key]; - if (!item) throw new NotFound(errorMessage('spellNotFound', {spellId: key})); - - if (user.stats.gp < item.value * quantity) { - throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language)); - } - user.stats.gp -= item.value * quantity; - - user.items.special[key] += quantity; - - if (analytics) { - analytics.track('acquire item', { - uuid: user._id, - itemKey: item.key, - itemType: 'Market', - goldCost: item.goldValue, - quantityPurchased: quantity, - acquireMethod: 'Gold', - category: 'behavior', - headers: req.headers, - }); - } - - return [ - pick(user, splitWhitespace('items stats')), - i18n.t('messageBought', { - itemText: item.text(req.language), - }, req.language), - ]; -}; diff --git a/website/common/script/ops/buy/buySpell.js b/website/common/script/ops/buy/buySpell.js new file mode 100644 index 0000000000..2a26d0defb --- /dev/null +++ b/website/common/script/ops/buy/buySpell.js @@ -0,0 +1,47 @@ +import content from '../../content/index'; +import get from 'lodash/get'; +import pick from 'lodash/pick'; +import splitWhitespace from '../../libs/splitWhitespace'; +import { + BadRequest, + NotFound, +} from '../../libs/errors'; +import {AbstractGoldItemOperation} from './abstractBuyOperation'; +import errorMessage from '../../libs/errorMessage'; + +export class BuySpellOperation extends AbstractGoldItemOperation { + constructor (user, req, analytics) { + super(user, req, analytics); + } + + getItemKey () { + return this.key; + } + + multiplePurchaseAllowed () { + return true; + } + + extractAndValidateParams (user, req) { + let key = this.key = get(req, 'params.key'); + if (!key) throw new BadRequest(errorMessage('missingKeyParam')); + + let item = content.special[key]; + if (!item) throw new NotFound(errorMessage('spellNotFound', {spellId: key})); + + this.canUserPurchase(user, item); + } + + executeChanges (user, item, req) { + user.items.special[item.key] += this.quantity; + + this.subtractCurrency(user, item, this.quantity); + + return [ + pick(user, splitWhitespace('items stats')), + this.i18n('messageBought', { + itemText: item.text(req.language), + }), + ]; + } +} diff --git a/website/common/script/ops/buy/purchaseWithSpell.js b/website/common/script/ops/buy/purchaseWithSpell.js deleted file mode 100644 index 7f0a087190..0000000000 --- a/website/common/script/ops/buy/purchaseWithSpell.js +++ /dev/null @@ -1,12 +0,0 @@ -import buy from './buy'; -import get from 'lodash/get'; - -module.exports = function purchaseWithSpell (user, req = {}, analytics) { - const type = get(req.params, 'type'); - - if (type === 'spells') { - req.type = 'special'; - } - - return buy(user, req, analytics); -};