diff --git a/package.json b/package.json index 8599ef04f5..f9394c3576 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "less-loader": "^2.2.3", "lodash": "^3.10.1", "lodash.setwith": "^4.2.0", + "lodash.pickby": "^4.2.0", "merge-stream": "^1.0.0", "method-override": "^2.3.5", "moment": "^2.13.0", diff --git a/test/common/libs/shops.js b/test/common/libs/shops.js index 2c7c5d49d5..396e394169 100644 --- a/test/common/libs/shops.js +++ b/test/common/libs/shops.js @@ -22,7 +22,9 @@ describe('shops', () => { it('items contain required fields', () => { _.each(shopCategories, (category) => { _.each(category.items, (item) => { - expect(item).to.have.all.keys(['key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'class']); + _.each(['key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'class'], (key) => { + expect(_.has(item, key)).to.eql(true); + }); }); }); }); @@ -46,7 +48,9 @@ describe('shops', () => { it('items contain required fields', () => { _.each(shopCategories, (category) => { _.each(category.items, (item) => { - expect(item).to.have.all.keys('key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'boss', 'class', 'collect', 'drop', 'unlockCondition', 'lvl'); + _.each(['key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'boss', 'class', 'collect', 'drop', 'unlockCondition', 'lvl'], (key) => { + expect(_.has(item, key)).to.eql(true); + }); }); }); }); @@ -70,7 +74,9 @@ describe('shops', () => { it('items contain required fields', () => { _.each(shopCategories, (category) => { _.each(category.items, (item) => { - expect(item).to.have.all.keys('key', 'text', 'value', 'currency', 'locked', 'purchaseType', 'class', 'notes', 'class'); + _.each(['key', 'text', 'value', 'currency', 'locked', 'purchaseType', 'class', 'notes', 'class'], (key) => { + expect(_.has(item, key)).to.eql(true); + }); }); }); }); @@ -94,7 +100,9 @@ describe('shops', () => { it('items contain required fields', () => { _.each(shopCategories, (category) => { _.each(category.items, (item) => { - expect(item).to.have.all.keys('key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'specialClass', 'type'); + _.each(['key', 'text', 'notes', 'value', 'currency', 'locked', 'purchaseType', 'type'], (key) => { + expect(_.has(item, key)).to.eql(true); + }); }); }); }); diff --git a/website/common/script/libs/shops.js b/website/common/script/libs/shops.js index c7efe6a2a3..ee9a9be97f 100644 --- a/website/common/script/libs/shops.js +++ b/website/common/script/libs/shops.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import pickBy from 'lodash.pickby'; // Not available in lodash 3 import content from '../content/index'; import i18n from '../i18n'; @@ -208,12 +209,12 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la return categories; }; -// To switch seasons/available inventory, edit the availableSets object to whatever should be sold. -// let availableSets = { +// To switch seasons/available inventory, edit the AVAILABLE_SETS object to whatever should be sold. +// let AVAILABLE_SETS = { // setKey: i18n.t('setTranslationString', language), // }; shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, language) { - let availableSets = { + const AVAILABLE_SETS = { fallHealer: i18n.t('mummyMedicSet', language), fall2015Healer: i18n.t('potionerSet', language), fallMage: i18n.t('witchyWizardSet', language), @@ -224,15 +225,45 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang fall2015Warrior: i18n.t('scarecrowWarriorSet', language), }; + const AVAILABLE_SPELLS = [ + 'spookySparkles', + ]; + let categories = []; let flatGearArray = _.toArray(content.gear.flat); - for (let key in availableSets) { - if (availableSets.hasOwnProperty(key)) { + let spells = pickBy(content.spells.special, (spell, key) => { + return _.indexOf(AVAILABLE_SPELLS, key) !== -1; + }); + + if (_.keys(spells).length > 0) { + let category = { + identifier: 'spells', + text: i18n.t('seasonalItems', language), + }; + + category.items = _.map(spells, (spell, key) => { + return { + key, + text: spell.text(language), + notes: spell.notes(language), + value: spell.value, + type: 'special', + currency: 'gold', + locked: false, + purchaseType: 'spells', + }; + }); + + categories.push(category); + } + + for (let key in AVAILABLE_SETS) { + if (AVAILABLE_SETS.hasOwnProperty(key)) { let category = { identifier: key, - text: availableSets[key], + text: AVAILABLE_SETS[key], }; category.items = _(flatGearArray).filter((gear) => { diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js index 94ff959a37..44576bc8d0 100644 --- a/website/server/controllers/api-v3/user.js +++ b/website/server/controllers/api-v3/user.js @@ -832,7 +832,7 @@ api.purchase = { url: '/user/purchase/:type/:key', async handler (req, res) { let user = res.locals.user; - let purchaseRes = common.ops.purchase(user, req, res.analytics); + let purchaseRes = req.params.type === 'spells' ? common.ops.buySpecialSpell(user, req) : common.ops.purchase(user, req, res.analytics); await user.save(); res.respond(200, ...purchaseRes); }, diff --git a/website/views/options/inventory/seasonal-shop.jade b/website/views/options/inventory/seasonal-shop.jade index d5575e62e8..0e954497ac 100644 --- a/website/views/options/inventory/seasonal-shop.jade +++ b/website/views/options/inventory/seasonal-shop.jade @@ -11,16 +11,6 @@ // .well=env.t('seasonalShopRebirth') li.customize-menu.inventory-gear - menu.pets-menu(label=env.t('seasonalItems')) - div - button.customize-option(class='inventory_special_spookySparkles', - popover='{{::Content.spells.special.spookySparkles.notes()}}', - popover-title='{{::Content.spells.special.spookySparkles.text()}}', - popover-trigger='mouseenter', popover-placement='right', - popover-append-to-body='true', - ng-click='purchase("special", Content.spells.special.spookySparkles)') - p {{::Content.spells.special.spookySparkles.value}} - span(class='shop_gold') menu.pets-menu(label='{{category.text}}', ng-repeat='category in seasonalShopCategories') div(ng-repeat='item in category.items', ng-if='!user.items.gear.owned[item.key]') button.customize-option(class='shop_{{item.key}}', @@ -29,5 +19,5 @@ popover-append-to-body='true', ng-click='purchase(item.type,item)') div - | {{((item.specialClass == "wizard") && (item.type == "weapon")) + 1}}  - span.Pet_Currency_Gem1x.inline-gems + | {{item.value}} + span(ng-class="{ 'shop_gold': item.currency === 'gold', 'Pet_Currency_Gem1x inline-gems': item.currency === 'gems'}")