diff --git a/index.js b/index.js index 65ecec5..cae440e 100644 --- a/index.js +++ b/index.js @@ -36,7 +36,6 @@ module.exports = function autopopulatePlugin(schema, options) { } const depth = options._depth != null ? options._depth : 0; - if (options.maxDepth > 0 && depth >= options.maxDepth) { return; } @@ -48,11 +47,9 @@ module.exports = function autopopulatePlugin(schema, options) { continue; } pathsToPopulate[i].options.options = pathsToPopulate[i].options.options || {}; - const newOptions = { _depth: depth + 1 }; if (options.maxDepth) newOptions.maxDepth = options.maxDepth; Object.assign(pathsToPopulate[i].options.options, newOptions); - const optionsToUse = processOption.call(this, pathsToPopulate[i].autopopulate, pathsToPopulate[i].options); if (optionsToUse) { @@ -65,7 +62,6 @@ module.exports = function autopopulatePlugin(schema, options) { } } } - return finalPaths; }; @@ -178,7 +174,6 @@ function getPathsToPopulate(schema) { }); } }, null, schemaStack); - return pathsToPopulate; } diff --git a/test/bugs.test.js b/test/bugs.test.js index eea4434..bdb92fc 100644 --- a/test/bugs.test.js +++ b/test/bugs.test.js @@ -16,6 +16,10 @@ describe('bug fixes', function() { await db.close(); }); + afterEach(function() { + db.deleteModel(/.+/); + }); + beforeEach(function() { const promises = []; for (const modelName of Object.keys(db.models)) { @@ -360,4 +364,237 @@ describe('bug fixes', function() { section = await Section.findById(section); assert.equal(section.subdoc.subSection.name, 'foo'); }); + it('supports the `refPath` option (gh-96)', async function() { + const AddressSchema = new Schema( + { + name: { + type: String + }, + status: { + type: String, + enum: ['active', 'inactive'], + default: 'active' + } + }, + { + timestamps: true, + toJSON: { virtuals: true }, + toObject: { virtuals: true } + } + ); + + AddressSchema.virtual('residentials', { + ref: 'Citizen', + localField: '_id', + foreignField: 'permanentAddress.address', + justOne: false, + autopopulate: true, + match: { + status: 'active' + }, + options: { + select: + 'name nId' + } + }); + + AddressSchema.plugin(autopopulate); + + + const CitizenSchema = new Schema( + { + nId: { + type: String, + required: [true, 'Please add national ID card'] + }, + name: { + type: String, + required: [true, 'Please add a name'], + trim: true + }, + permanentAddress: { + name: { + type: String, + trim: true + }, + address: { + type: mongoose.Schema.ObjectId, + ref: 'Address' + } + }, + father: { + type: mongoose.Schema.ObjectId, + refPath: 'fatherType', + autopopulate: true + }, + fatherType: { + type: String, + enum: ['Citizen', 'Guest'], + required: true + }, + status: { + type: String, + enum: ['active', 'inactive'], + default: 'active' + } + }, + { + timestamps: true, + toJSON: { virtuals: true }, + toObject: { virtuals: true } + } + ); + + CitizenSchema.plugin(autopopulate); + + + const Address = db.model('Address', AddressSchema); + + const Citizen = db.model('Citizen', CitizenSchema); + await Address.deleteMany({}); + await Citizen.deleteMany({}); + const entry = await Address.create({ + name: 'Another name for The Address', + status: 'active' + }); + + const doc = await Citizen.create({ + nId: 'Hello', + name: 'There', + permanentAddress: { + name: 'The Address', + address: entry._id + }, + fatherType: 'Guest' + }); + await Citizen.create({ + nId: 'Yo', + name: 'Test', + permanentAddress: { + name: 'The Address', + address: entry._id + }, + father: doc._id, + fatherType: 'Citizen', + status: 'active' + }); + const citizen = await Citizen.find(); + const testDoc = citizen.find(x => x.father != null); + assert.equal(testDoc.father.fatherType, 'Guest'); + }); + it('`refPath` works without autopopulate on the virtual (gh-96)', async function() { + const AddressSchema = new Schema( + { + name: { + type: String + }, + status: { + type: String, + enum: ['active', 'inactive'], + default: 'active' + } + }, + { + timestamps: true, + toJSON: { virtuals: true }, + toObject: { virtuals: true } + } + ); + + AddressSchema.virtual('residentials', { + ref: 'Citizen', + localField: '_id', + foreignField: 'permanentAddress.address', + justOne: false, + match: { + status: 'active' + }, + options: { + select: + 'name nId' + } + }); + + AddressSchema.plugin(autopopulate); + + + const CitizenSchema = new Schema( + { + nId: { + type: String, + required: [true, 'Please add national ID card'] + }, + name: { + type: String, + required: [true, 'Please add a name'], + trim: true + }, + permanentAddress: { + name: { + type: String, + trim: true + }, + address: { + type: mongoose.Schema.ObjectId, + ref: 'Address' + } + }, + father: { + type: mongoose.Schema.ObjectId, + refPath: 'fatherType' + }, + fatherType: { + type: String, + enum: ['Citizen', 'Guest'], + required: true + }, + status: { + type: String, + enum: ['active', 'inactive'], + default: 'active' + } + }, + { + timestamps: true, + toJSON: { virtuals: true }, + toObject: { virtuals: true } + } + ); + + CitizenSchema.plugin(autopopulate); + + + const Address = db.model('Address', AddressSchema); + + const Citizen = db.model('Citizen', CitizenSchema); + await Address.deleteMany({}); + await Citizen.deleteMany({}); + const entry = await Address.create({ + name: 'Another name for The Address', + status: 'active' + }); + + const doc = await Citizen.create({ + nId: 'Hello', + name: 'There', + permanentAddress: { + name: 'The Address', + address: entry._id + }, + fatherType: 'Guest' + }); + await Citizen.create({ + nId: 'Yo', + name: 'Test', + permanentAddress: { + name: 'The Address', + address: entry._id + }, + father: doc._id, + fatherType: 'Citizen', + status: 'active' + }); + const addr = await Address.findOne().populate({ path: 'residentials', populate: { path: 'permanentAddress.address' } }); + assert.notEqual(addr.residentials[0].permanentAddress.address.name, undefined); + }); });