From 1f3a6912349e34318dfb33efac3bd36926ae104d Mon Sep 17 00:00:00 2001 From: Christian Jacobsen Date: Tue, 4 Apr 2017 08:48:15 +0200 Subject: [PATCH] fix: convert object ids deep --- src/mongoose-cleaner.js | 23 ++++++----------- test/unit/mongoose-cleaner-test.js | 40 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/mongoose-cleaner.js b/src/mongoose-cleaner.js index acde707..9ff875d 100644 --- a/src/mongoose-cleaner.js +++ b/src/mongoose-cleaner.js @@ -1,26 +1,18 @@ -import mapValues from 'lodash.mapvalues'; - function isLookingLikeMongooseDocument(obj) { return typeof obj.toObject === 'function'; } -function convertObjectIds(obj) { - return mapValues(obj, value => { - if (value && value.constructor && value.constructor.name === 'ObjectID') { - return value.toString(); - } - return value; - }); -} - -function removeIds(obj) { +function transformIds(obj) { for (const prop in obj) { if (obj.hasOwnProperty(prop)) { - if (prop === 'id') { + if (obj[prop] && obj[prop].constructor && obj[prop].constructor.name === 'ObjectID') { + obj[prop] = obj[prop].toString(); + } + else if (prop === 'id') { delete obj[prop]; } else if (typeof obj[prop] === 'object') { - removeIds(obj[prop]); + transformIds(obj[prop]); } } } @@ -43,8 +35,7 @@ const api = { } delete lean.__v; - lean = convertObjectIds(lean); - removeIds(lean); + transformIds(lean); return lean; }, diff --git a/test/unit/mongoose-cleaner-test.js b/test/unit/mongoose-cleaner-test.js index ab7a85a..5453eea 100644 --- a/test/unit/mongoose-cleaner-test.js +++ b/test/unit/mongoose-cleaner-test.js @@ -12,6 +12,12 @@ const MockSchema = new mongoose.Schema({ nested_foo: { type: String, required: false }, }, ], + nested_object_ids_level_1: { + nested_object_id_level_1: { type: ObjectId, required: false }, + nested_object_ids_level_2: { + nested_object_id_level_2: { type: ObjectId, required: false }, + }, + }, }); MockSchema.path('foo').get(value => { @@ -35,6 +41,19 @@ function assertNoIdProperties(obj) { } } +function assertNoObjectIdProperties(obj) { + for (const prop in obj) { + if (obj.hasOwnProperty(prop)) { + if (obj[prop] && obj[prop].constructor) { + obj[prop].constructor.name.should.not.equal('ObjectID'); + } + if (typeof obj[prop] === 'object') { + assertNoObjectIdProperties(obj[prop]); + } + } + } +} + describe('test/unit/mongoose-cleaner-test.js', () => { const sinon_sandbox = autorestoredSandbox(); @@ -111,6 +130,27 @@ describe('test/unit/mongoose-cleaner-test.js', () => { }); + describe('with a DB document having a nested ObjectID:s', () => { + let document; + + beforeEach(() => { + document = createMongooseDocument({ + nested_object_ids_level_1: { + nested_object_id_level_1: '537f844b2883b0d8c825270d', + nested_object_ids_level_2: { + nested_object_id_level_2: '337e844b2883b1d1c89527ad', + }, + }, + }); + }); + + it('should not have `id` anywhere on the document', () => { + const cleaned = cleaner.cleanMongooseDocument(document); + assertNoObjectIdProperties(cleaned); + }); + + }); + describe('when DB document omitted', () => { it('should return null, but not fail', () => {