From fb0539aa6dca2d1bbf1bc730215c7a8fb7bd13b6 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sat, 10 Jun 2023 21:32:08 -0400 Subject: [PATCH] fix(query): handle non-string discriminator key values in query Fix #13492 --- lib/cast.js | 14 +++++++++++--- test/cast.test.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/cast.js b/lib/cast.js index 1637c2794de..278cc1f00cf 100644 --- a/lib/cast.js +++ b/lib/cast.js @@ -118,9 +118,17 @@ module.exports = function cast(schema, obj, options, context) { discriminatorKey != null && pathLastHalf !== discriminatorKey) { const discriminatorVal = get(obj, pathFirstHalf + '.' + discriminatorKey); - if (discriminatorVal != null) { - schematype = _schematype.schema.discriminators[discriminatorVal]. - path(pathLastHalf); + const discriminators = _schematype.schema.discriminators; + if (typeof discriminatorVal === 'string' && discriminators[discriminatorVal] != null) { + + schematype = discriminators[discriminatorVal].path(pathLastHalf); + } else if (discriminatorVal != null && + Object.keys(discriminatorVal).length === 1 && + Array.isArray(discriminatorVal.$in) && + discriminatorVal.$in.length === 1 && + typeof discriminatorVal.$in[0] === 'string' && + discriminators[discriminatorVal.$in[0]] != null) { + schematype = discriminators[discriminatorVal.$in[0]].path(pathLastHalf); } } } diff --git a/test/cast.test.js b/test/cast.test.js index 51b97518ff3..8557a97eec4 100644 --- a/test/cast.test.js +++ b/test/cast.test.js @@ -193,4 +193,34 @@ describe('cast: ', function() { name: 'foo' }); }); + + it('handles $in with discriminators if $in has exactly 1 element (gh-13492)', function() { + const itemStateFooSchema = new Schema({ + fieldFoo: String + }); + + const itemSchema = new Schema({ + state: new Schema( + { + field: String + }, + { + discriminatorKey: 'type' + } + ) + }); + + itemSchema.path('state').discriminator('FOO', itemStateFooSchema); + + const res = cast(itemSchema, { + 'state.type': { + $in: ['FOO'] + }, + 'state.fieldFoo': 44 + }); + assert.deepStrictEqual(res, { + 'state.type': { $in: ['FOO'] }, + 'state.fieldFoo': '44' + }); + }); });