Skip to content

Commit

Permalink
fix(model): avoid deleting shared schema methods in fix for Automatti…
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Sep 21, 2022
1 parent 66ed34d commit 4495cf3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
5 changes: 4 additions & 1 deletion lib/helpers/model/applyMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const utils = require('../../utils');
*/

module.exports = function applyMethods(model, schema) {
const Model = require('../../model');

function apply(method, schema) {
Object.defineProperty(model.prototype, method, {
get: function() {
Expand All @@ -34,7 +36,8 @@ module.exports = function applyMethods(model, schema) {
// Avoid making custom methods if user sets a method to itself, e.g.
// `schema.method(save, Document.prototype.save)`. Can happen when
// calling `loadClass()` with a class that `extends Document`. See gh-12254
if (typeof fn === 'function' && model.prototype[method] === fn) {
if (typeof fn === 'function' &&
Model.prototype[method] === fn) {
delete schema.methods[method];
continue;
}
Expand Down
65 changes: 63 additions & 2 deletions test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8830,17 +8830,78 @@ describe('Model', function() {

class B extends mongoose.Document {
get foo() { return 'bar'; }

bar() { return 'baz'; }
}

DownloadJobSchema.loadClass(B);

const Test = db.model('Test', DownloadJobSchema);
let Test = db.model('Test', DownloadJobSchema);

const { _id } = await Test.create({ test: 'value' });
const doc = await Test.findById(_id);
let doc = await Test.findById(_id);
assert.ok(doc);
assert.equal(doc.foo, 'bar');
assert.equal(doc.test, 'value');
assert.equal(doc.bar(), 'baz');

db.deleteModel(/Test/);
Test = db.model('Test', { job: DownloadJobSchema });

await Test.deleteMany({});
await Test.create({ _id, job: { test: 'value' } });
doc = await Test.findById(_id);
assert.ok(doc);
assert.equal(doc.job.foo, 'bar');
assert.equal(doc.job.test, 'value');
assert.equal(doc.job.bar(), 'baz');
});

it('handles shared schema methods (gh-12423)', async function() {
const sharedSubSchema = new mongoose.Schema({
name: {
type: String
}
});

sharedSubSchema.methods.sharedSubSchemaMethod = function() {
return 'test';
};

const mainDocumentSchema = new mongoose.Schema({
subdocuments: {
type: [sharedSubSchema],
required: true
}
});
const Test1 = db.model('Test1', mainDocumentSchema);

const secondaryDocumentSchema = new mongoose.Schema({
subdocuments: {
type: [sharedSubSchema],
required: true
}
});
const Test2 = db.model('Test2', secondaryDocumentSchema);

const mainDoc = await Test1.create({
subdocuments: [
{
name: 'one'
}
]
});

const secondaryDoc = await Test2.create({
subdocuments: [
{
name: 'secondary'
}
]
});

assert.strictEqual(mainDoc.subdocuments[0].sharedSubSchemaMethod(), 'test');
assert.strictEqual(secondaryDoc.subdocuments[0].sharedSubSchemaMethod(), 'test');
});

describe('Check if static function that is supplied in schema option is available', function() {
Expand Down

0 comments on commit 4495cf3

Please sign in to comment.