From 315779f9a59fd069e3bf0f98cb8eedb0b4b01752 Mon Sep 17 00:00:00 2001 From: Nicolas Polizzo Date: Tue, 27 Aug 2024 16:38:08 +0200 Subject: [PATCH] use sanitized params instead of original ones --- .../src/index.js | 8 ++-- .../test/integration/virtuals.spec.js | 42 +++++++++++++++++++ packages/moleculer-db/src/index.js | 2 +- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/packages/moleculer-db-adapter-mongoose/src/index.js b/packages/moleculer-db-adapter-mongoose/src/index.js index 02aed43d..488a0322 100644 --- a/packages/moleculer-db-adapter-mongoose/src/index.js +++ b/packages/moleculer-db-adapter-mongoose/src/index.js @@ -308,8 +308,8 @@ class MongooseDbAdapter { * @returns {Object[]} * @memberof MongooseDbAdapter */ - getNativeVirtualPopulateQuery(ctx) { - const fieldsToPopulate = ctx.params?.populate || []; + getNativeVirtualPopulateQuery(ctx, params) { + const fieldsToPopulate = params?.populate || []; if (fieldsToPopulate.length === 0) return []; @@ -366,8 +366,8 @@ class MongooseDbAdapter { * @returns {Object} * @memberof MongooseDbAdapter */ - entityToObject(entity, ctx) { - const populate = this.useNativeMongooseVirtuals ? this.getNativeVirtualPopulateQuery(ctx) : []; + entityToObject(entity, ctx, params) { + const populate = this.useNativeMongooseVirtuals ? this.getNativeVirtualPopulateQuery(ctx, params) : []; return Promise.resolve(populate.length > 0 ? entity.populate(populate) : entity) .then(entity => { diff --git a/packages/moleculer-db-adapter-mongoose/test/integration/virtuals.spec.js b/packages/moleculer-db-adapter-mongoose/test/integration/virtuals.spec.js index d1a435c7..2c318e57 100644 --- a/packages/moleculer-db-adapter-mongoose/test/integration/virtuals.spec.js +++ b/packages/moleculer-db-adapter-mongoose/test/integration/virtuals.spec.js @@ -103,6 +103,48 @@ if (process.versions.node.split(".")[0] < 14) { expect(user).toHaveProperty("lastPostWithVotes"); expect(user.lastPostWithVotes).toHaveProperty("_id", _post2.id); }); + + it("Should populate virtuals using populate string param", async () => { + const _user = await User.Model.create({ + firstName: "John", + lastName: "Doe", + }); + + const _post1 = await Post.Model.create({ + title: "post_1", + content: "content 1", + author: _user._id, + }); + + const _post2 = await Post.Model.create({ + title: "post_2", + content: "content 2", + author: _user._id, + votes: 2, + }); + + const user = await broker.call("users.get", { + id: _user.id, + populate: "posts, postCount, lastPost, lastPostWithVotes", + }); + + expect(user).toHaveProperty("firstName", "John"); + expect(user).toHaveProperty("lastName", "Doe"); + // virtual function without populate + expect(user).toHaveProperty("fullName", "John Doe"); + // virtual populate with refPath and count option + expect(user).toHaveProperty("postCount", 2); + // virtual populate with ref + expect(user).toHaveProperty("posts"); + expect(user.posts).toHaveLength(2); + expect(user.posts.map((p) => p._id)).toEqual([_post2.id, _post1.id]); + // virtual populate with justOne option set to "true" + expect(user).toHaveProperty("lastPost"); + expect(user.lastPost).toHaveProperty("_id", _post2.id); + // virtual populate with match clause + expect(user).toHaveProperty("lastPostWithVotes"); + expect(user.lastPostWithVotes).toHaveProperty("_id", _post2.id); + }); }); describe("Test moleculer basic virtual population", () => { diff --git a/packages/moleculer-db/src/index.js b/packages/moleculer-db/src/index.js index 1835b4cb..67058e15 100644 --- a/packages/moleculer-db/src/index.js +++ b/packages/moleculer-db/src/index.js @@ -532,7 +532,7 @@ module.exports = { return Promise.resolve(docs) // Convert entity to JS object - .then(docs => Promise.all(docs.map(doc => this.adapter.entityToObject(doc, ctx)))) + .then(docs => Promise.all(docs.map(doc => this.adapter.entityToObject(doc, ctx, params)))) // Apply idField .then(docs => docs.map(doc => this.adapter.afterRetrieveTransformID(doc, this.settings.idField)))