Skip to content

Commit 41de90c

Browse files
authored
Merge pull request #13716 from Hajjiri/discriminator-update-fix
fix: accessing discriminator schema with null
2 parents 8df3699 + 63a7fc8 commit 41de90c

File tree

3 files changed

+130
-1
lines changed

3 files changed

+130
-1
lines changed

lib/helpers/query/getEmbeddedDiscriminatorPath.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, p
7575
continue;
7676
}
7777

78-
const discriminatorSchema = getDiscriminatorByValue(schematype.caster.discriminators, discriminatorKey).schema;
78+
const discriminator = getDiscriminatorByValue(schematype.caster.discriminators, discriminatorKey);
79+
const discriminatorSchema = discriminator && discriminator.schema;
80+
if (discriminatorSchema == null) {
81+
continue;
82+
}
7983

8084
const rest = parts.slice(i + 1).join('.');
8185
schematype = discriminatorSchema.path(rest);

test/helpers/query.castUpdate.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,30 @@ describe('castUpdate', function() {
1212
const res = castUpdate(schema, obj);
1313
assert.deepEqual(res, { $addToSet: { test: [1, 2, 3] } });
1414
});
15+
16+
it('casts the update correctly when target discriminator type is missing', function() {
17+
const shapeSchema = Schema({ name: String }, { discriminatorKey: 'kind' });
18+
const schema = Schema({ shape: shapeSchema });
19+
20+
schema
21+
.path('shape')
22+
.discriminator(
23+
'gh8378_Circle',
24+
Schema({ radius: String, color: String })
25+
);
26+
27+
// schema
28+
// .path('shape')
29+
// .discriminator('gh8378_Square', Schema({ side: Number, color: String }));
30+
31+
const toBeUpdated = {
32+
'shape.name': 'aName',
33+
'shape.kind': 'gh8378_Square',
34+
'shape.side': 4,
35+
'shape.color': 'white'
36+
};
37+
38+
const res = castUpdate(schema, { $set: toBeUpdated });
39+
assert.deepEqual(res, { $set: toBeUpdated });
40+
});
1541
});

test/model.findByIdAndUpdate.test.js

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
'use strict';
2+
3+
/**
4+
* Test dependencies.
5+
*/
6+
7+
const start = require('./common');
8+
9+
const assert = require('assert');
10+
const mongoose = start.mongoose;
11+
const Schema = mongoose.Schema;
12+
const util = require('./util');
13+
14+
describe('model: findByIdAndUpdate:', function() {
15+
let db;
16+
17+
before(function() {
18+
db = start();
19+
});
20+
21+
after(async function() {
22+
await db.close();
23+
});
24+
25+
beforeEach(() => db.deleteModel(/.*/));
26+
afterEach(() => util.clearTestData(db));
27+
afterEach(() => require('./util').stopRemainingOps(db));
28+
29+
it('returns the edited document with previous and target discriminators types defined', async function() {
30+
const shapeSchema = Schema({ name: String }, { discriminatorKey: 'kind' });
31+
const schema = Schema({ shape: shapeSchema });
32+
33+
schema.path('shape').discriminator('gh8378_Circle',
34+
Schema({ radius: String, color: String }));
35+
schema.path('shape').discriminator('gh8378_Square',
36+
Schema({ side: Number, color: String }));
37+
38+
const MyModel = db.model('Test', schema);
39+
40+
41+
let doc = await MyModel.create({
42+
shape: {
43+
kind: 'gh8378_Circle',
44+
name: 'before',
45+
radius: 5,
46+
color: 'red'
47+
}
48+
});
49+
50+
doc = await MyModel.findByIdAndUpdate(doc._id, {
51+
'shape.kind': 'gh8378_Square',
52+
'shape.name': 'after',
53+
'shape.side': 4,
54+
'shape.color': 'white'
55+
}, { new: true });
56+
console.log('doc');
57+
console.log(doc);
58+
console.log('doc');
59+
60+
assert.equal(doc.shape.kind, 'gh8378_Square');
61+
assert.equal(doc.shape.name, 'after');
62+
assert.equal(doc.shape.side, 4);
63+
assert.equal(doc.shape.color, 'white');
64+
});
65+
66+
it('returns the edited document with only previous discriminator type defined', async function() {
67+
const shapeSchema = Schema({ name: String }, { discriminatorKey: 'kind' });
68+
const schema = Schema({ shape: shapeSchema });
69+
70+
schema.path('shape').discriminator('gh8378_Circle',
71+
Schema({ radius: String, color: String }));
72+
schema.path('shape').discriminator('gh8378_Square',
73+
Schema({ side: Number, color: String }));
74+
75+
const MyModel = db.model('Test', schema);
76+
77+
78+
let doc = await MyModel.create({
79+
shape: {
80+
kind: 'gh8378_Circle',
81+
name: 'before',
82+
radius: 5,
83+
color: 'red'
84+
}
85+
});
86+
87+
doc = await MyModel.findByIdAndUpdate(doc._id, {
88+
'shape.kind': 'gh8378_Square',
89+
'shape.name': 'after',
90+
'shape.side': 4,
91+
'shape.color': 'white'
92+
}, { new: true, overwriteDiscriminatorKey: true });
93+
94+
assert.equal(doc.shape.kind, 'gh8378_Square');
95+
assert.equal(doc.shape.name, 'after');
96+
assert.equal(doc.shape.side, 4);
97+
assert.equal(doc.shape.color, 'white');
98+
});
99+
});

0 commit comments

Comments
 (0)