From 71f304786c170f0886c953fd08ace5b8afab2109 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Sun, 20 Mar 2016 13:07:14 +0100 Subject: [PATCH] add pickDeep utility function to pick nested properties from objects --- common/script/libs/pickDeep.js | 13 ++++++++++ common/script/ops/buyMysterySet.js | 3 ++- common/script/ops/hourglassPurchase.js | 3 ++- test/common/libs/pickDeep.js | 34 ++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 common/script/libs/pickDeep.js create mode 100644 test/common/libs/pickDeep.js diff --git a/common/script/libs/pickDeep.js b/common/script/libs/pickDeep.js new file mode 100644 index 0000000000..919d926854 --- /dev/null +++ b/common/script/libs/pickDeep.js @@ -0,0 +1,13 @@ +// An utility to pick deep properties from an object. +// Works like _.pick but supports nested props (ie pickDeep(obj, ['deep.property'])) + +import _ from 'lodash'; + +module.exports = function pickDeep (obj, properties) { + if (!_.isArray(properties)) throw new Error('"properties" must be an array'); + + let result = {}; + _.each(properties, (prop) => _.set(result, prop, _.get(obj, prop))); + + return result; +}; diff --git a/common/script/ops/buyMysterySet.js b/common/script/ops/buyMysterySet.js index 91c5b3f5d9..8efb32c117 100644 --- a/common/script/ops/buyMysterySet.js +++ b/common/script/ops/buyMysterySet.js @@ -2,6 +2,7 @@ import i18n from '../i18n'; import content from '../content/index'; import _ from 'lodash'; import splitWhitespace from '../libs/splitWhitespace'; +import pickDeep from '../libs/pickDeep'; import { BadRequest, NotAuthorized, @@ -43,7 +44,7 @@ module.exports = function buyMysterySet (user, req = {}, analytics) { user.purchased.plan.consecutive.trinkets--; return { - data: _.pick(user, splitWhitespace('items purchased.plan.consecutive')), + data: pickDeep(user, splitWhitespace('items purchased.plan.consecutive')), // TODO this is broken, _.pick doesn't support nested keys message: i18n.t('hourglassPurchaseSet', req.language), }; }; diff --git a/common/script/ops/hourglassPurchase.js b/common/script/ops/hourglassPurchase.js index 4955898f0b..b97f581bb6 100644 --- a/common/script/ops/hourglassPurchase.js +++ b/common/script/ops/hourglassPurchase.js @@ -2,6 +2,7 @@ import content from '../content/index'; import i18n from '../i18n'; import _ from 'lodash'; import splitWhitespace from '../libs/splitWhitespace'; +import pickDeep from '../libs/pickDeep'; module.exports = function(user, req, cb, analytics) { var analyticsData, key, ref, type; @@ -50,5 +51,5 @@ module.exports = function(user, req, cb, analytics) { return typeof cb === "function" ? cb({ code: 200, message: i18n.t('hourglassPurchase', req.language) - }, _.pick(user, splitWhitespace('items purchased.plan.consecutive'))) : void 0; + }, pickDeep(user, splitWhitespace('items purchased.plan.consecutive'))) : void 0; }; diff --git a/test/common/libs/pickDeep.js b/test/common/libs/pickDeep.js new file mode 100644 index 0000000000..4a8741269d --- /dev/null +++ b/test/common/libs/pickDeep.js @@ -0,0 +1,34 @@ +import pickDeep from '../../../common/script/libs/pickDeep'; + +describe('pickDeep', () => { + it('throws an error if "properties" is not an array', () => { + expect(pickDeep).to.throw(Error); + }); + + it('returns an object of properties taken from the input object', () => { + let obj = { + a: true, + b: [1, 2, 3], + c: { + nested: { + two: { + times: true, + }, + }, + }, + d: false, + }; + + let res = pickDeep(obj, ['a', 'b[0]', 'c.nested.two.times']); + expect(res.a).to.be.true; + expect(res.b).to.eql([1]); + expect(res.c).to.eql({ + nested: { + two: { + times: true, + }, + }, + }); + expect(res).to.not.have.property('d'); + }); +});