From 908d46b33a66aa9982af625d3f9be0b34ff2b794 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Jun 2020 10:30:56 +0200 Subject: [PATCH 1/2] fix(castArrayFilters): handle casting on all fields of array filter --- lib/helpers/update/castArrayFilters.js | 57 ++++++++++---------- test/helpers/update.castArrayFilters.test.js | 25 +++++++++ 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/lib/helpers/update/castArrayFilters.js b/lib/helpers/update/castArrayFilters.js index 471fda35a38..57018d9fb10 100644 --- a/lib/helpers/update/castArrayFilters.js +++ b/lib/helpers/update/castArrayFilters.js @@ -38,40 +38,41 @@ module.exports = function castArrayFilters(query) { if (filter == null) { throw new Error(`Got null array filter in ${arrayFilters}`); } - const firstKey = Object.keys(filter)[0]; + for (const key in filter) { - if (filter[firstKey] == null) { - continue; - } + if (filter[key] == null) { + continue; + } - const dot = firstKey.indexOf('.'); - let filterPath = dot === -1 ? - updatedPathsByFilter[firstKey] + '.0' : - updatedPathsByFilter[firstKey.substr(0, dot)] + '.0' + firstKey.substr(dot); + const dot = key.indexOf('.'); + let filterPath = dot === -1 ? + updatedPathsByFilter[key] + '.0' : + updatedPathsByFilter[key.substr(0, dot)] + '.0' + key.substr(dot); - if (filterPath == null) { - throw new Error(`Filter path not found for ${firstKey}`); - } + if (filterPath == null) { + throw new Error(`Filter path not found for ${key}`); + } - // If there are multiple array filters in the path being updated, make sure - // to replace them so we can get the schema path. - filterPath = cleanPositionalOperators(filterPath); + // If there are multiple array filters in the path being updated, make sure + // to replace them so we can get the schema path. + filterPath = cleanPositionalOperators(filterPath); - const schematype = getPath(schema, filterPath); - if (schematype == null) { - if (!strictQuery) { - return; + const schematype = getPath(schema, filterPath); + if (schematype == null) { + if (!strictQuery) { + return; + } + // For now, treat `strictQuery = true` and `strictQuery = 'throw'` as + // equivalent for casting array filters. `strictQuery = true` doesn't + // quite work in this context because we never want to silently strip out + // array filters, even if the path isn't in the schema. + throw new Error(`Could not find path "${filterPath}" in schema`); + } + if (typeof filter[key] === 'object') { + filter[key] = castFilterPath(query, schematype, filter[key]); + } else { + filter[key] = schematype.castForQuery(filter[key]); } - // For now, treat `strictQuery = true` and `strictQuery = 'throw'` as - // equivalent for casting array filters. `strictQuery = true` doesn't - // quite work in this context because we never want to silently strip out - // array filters, even if the path isn't in the schema. - throw new Error(`Could not find path "${filterPath}" in schema`); - } - if (typeof filter[firstKey] === 'object') { - filter[firstKey] = castFilterPath(query, schematype, filter[firstKey]); - } else { - filter[firstKey] = schematype.castForQuery(filter[firstKey]); } } }; \ No newline at end of file diff --git a/test/helpers/update.castArrayFilters.test.js b/test/helpers/update.castArrayFilters.test.js index 17e64de2991..e78e9d8dffc 100644 --- a/test/helpers/update.castArrayFilters.test.js +++ b/test/helpers/update.castArrayFilters.test.js @@ -42,6 +42,31 @@ describe('castArrayFilters', function() { done(); }); + it('casts on multiple fields', function (done) { + const schema = new Schema({ + comments: [{ + text: String, + replies: [{ + beginAt: Date, + endAt: Date + }] + }] + }); + const q = new Query(); + q.schema = schema; + + q.updateOne({}, { $set: { 'comments.$[x].replies.$[y].endAt': '2019-01-01' } }, { + arrayFilters: [{ 'x.text': 123 }, { 'y.beginAt': { $gte: '2018-01-01' }, 'y.endAt': { $lt: '2020-01-01' } }] + }); + castArrayFilters(q); + + assert.strictEqual(q.options.arrayFilters[0]['x.text'], '123'); + assert.ok(q.options.arrayFilters[1]['y.beginAt'].$gte instanceof Date); + assert.ok(q.options.arrayFilters[1]['y.endAt'].$lt instanceof Date); + + done(); + }); + it('sane error on same filter twice', function(done) { const schema = new Schema({ comments: [{ From afc50c3fd3d550814a9271a8b9e9dd00b58585cf Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 12 Jun 2020 10:58:22 +0200 Subject: [PATCH 2/2] fix linter on cast array filters test --- test/helpers/update.castArrayFilters.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/helpers/update.castArrayFilters.test.js b/test/helpers/update.castArrayFilters.test.js index e78e9d8dffc..fac39ca9fc1 100644 --- a/test/helpers/update.castArrayFilters.test.js +++ b/test/helpers/update.castArrayFilters.test.js @@ -42,12 +42,12 @@ describe('castArrayFilters', function() { done(); }); - it('casts on multiple fields', function (done) { + it('casts on multiple fields', function(done) { const schema = new Schema({ comments: [{ text: String, - replies: [{ - beginAt: Date, + replies: [{ + beginAt: Date, endAt: Date }] }]