Skip to content

Commit

Permalink
Merge pull request #13958 from Automattic/vkarpov15/gh-13898
Browse files Browse the repository at this point in the history
fix(schema): handle embedded discriminators defined using `Schema.prototype.discriminator()`
  • Loading branch information
vkarpov15 committed Oct 10, 2023
2 parents 03c6967 + 914b4b4 commit 3042ac1
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 13 deletions.
13 changes: 0 additions & 13 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -723,19 +723,6 @@ Schema.prototype.add = function add(obj, prefix) {
for (const key in val[0].discriminators) {
schemaType.discriminator(key, val[0].discriminators[key]);
}
} else if (val[0] != null && val[0].instanceOfSchema && val[0]._applyDiscriminators instanceof Map) {
const applyDiscriminators = val[0]._applyDiscriminators;
const schemaType = this.path(prefix + key);
for (const disc of applyDiscriminators.keys()) {
schemaType.discriminator(disc, applyDiscriminators.get(disc));
}
}
else if (val != null && val.instanceOfSchema && val._applyDiscriminators instanceof Map) {
const applyDiscriminators = val._applyDiscriminators;
const schemaType = this.path(prefix + key);
for (const disc of applyDiscriminators.keys()) {
schemaType.discriminator(disc, applyDiscriminators.get(disc));
}
}
} else if (Object.keys(val).length < 1) {
// Special-case: {} always interpreted as Mixed path so leaf at this node
Expand Down
6 changes: 6 additions & 0 deletions lib/schema/SubdocumentPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ function SubdocumentPath(schema, path, options) {
this.$isSingleNested = true;
this.base = schema.base;
SchemaType.call(this, path, options, 'Embedded');

if (schema._applyDiscriminators != null) {
for (const disc of schema._applyDiscriminators.keys()) {
this.discriminator(disc, schema._applyDiscriminators.get(disc));
}
}
}

/*!
Expand Down
6 changes: 6 additions & 0 deletions lib/schema/documentarray.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ function DocumentArrayPath(key, schema, options, schemaOptions) {

this.$embeddedSchemaType.caster = this.Constructor;
this.$embeddedSchemaType.schema = this.schema;

if (schema._applyDiscriminators != null) {
for (const disc of schema._applyDiscriminators.keys()) {
this.discriminator(disc, schema._applyDiscriminators.get(disc));
}
}
}

/**
Expand Down
50 changes: 50 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12520,6 +12520,56 @@ describe('document', function() {
await doc.save();
assert.strictEqual(attachmentSchemaPreValidateCalls, 1);
});

it('handles embedded discriminators defined using Schema.prototype.discriminator (gh-13898)', async function() {
const baseNestedDiscriminated = new Schema({
type: { type: Number, required: true }
}, { discriminatorKey: 'type' });

class BaseClass {
whoAmI() {
return 'I am baseNestedDiscriminated';
}
}
BaseClass.type = 1;

baseNestedDiscriminated.loadClass(BaseClass);

class NumberTyped extends BaseClass {
whoAmI() {
return 'I am NumberTyped';
}
}
NumberTyped.type = 3;

class StringTyped extends BaseClass {
whoAmI() {
return 'I am StringTyped';
}
}
StringTyped.type = 4;

baseNestedDiscriminated.discriminator(1, new Schema({}).loadClass(NumberTyped));
baseNestedDiscriminated.discriminator('3', new Schema({}).loadClass(StringTyped));

const containsNestedSchema = new Schema({
nestedDiscriminatedTypes: { type: [baseNestedDiscriminated], required: true }
});

class ContainsNested {
whoAmI() {
return 'I am ContainsNested';
}
}
containsNestedSchema.loadClass(ContainsNested);

const Test = db.model('Test', containsNestedSchema);
const instance = await Test.create({ type: 1, nestedDiscriminatedTypes: [{ type: 1 }, { type: '3' }] });
assert.deepStrictEqual(
instance.nestedDiscriminatedTypes.map(i => i.whoAmI()),
['I am NumberTyped', 'I am StringTyped']
);
});
});

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

0 comments on commit 3042ac1

Please sign in to comment.