From baddfe76f4e69b627fdf323b1e8d5932c170966f Mon Sep 17 00:00:00 2001 From: "[NUTES] Lucas Barbosa Oliveira" Date: Mon, 13 Jun 2022 14:55:11 -0300 Subject: [PATCH 1/3] Admitting multiple $or in querystring. --- lib/mapper/filters.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/mapper/filters.js b/lib/mapper/filters.js index 5bf155c..47c6be2 100644 --- a/lib/mapper/filters.js +++ b/lib/mapper/filters.js @@ -14,6 +14,7 @@ function filters(query, options) { delete query.start_at delete query.end_at delete query.period + let or_count = 0 for (const elem in query) { if (query[elem] instanceof Array) { query[elem].forEach(function (param) { @@ -22,7 +23,18 @@ function filters(query, options) { } else { if (query[elem] instanceof Object) { } else if (query[elem].includes(',')) { - result['$or'] = result['$or'].concat(splitByCommas(elem, query[elem])) + if (or_count === 0){ + result['$or'] = result['$or'].concat(splitByCommas(elem, query[elem])) + } + else if (or_count === 1) { + result['$and'].push({'$or': result['$or']}) + result['$and'].push({'$or': splitByCommas(elem, query[elem])}) + result['$or'] = [] + } + else{ + result['$and'].push({'$or': splitByCommas(elem, query[elem])}) + } + or_count++ } else { Object.assign(result, processQuery(elem, query[elem])) } From fcfc5a5c5f0e5be25ec5535609d10b1f037bdecd Mon Sep 17 00:00:00 2001 From: jeffsampaio Date: Mon, 13 Jun 2022 22:23:10 -0300 Subject: [PATCH 2/3] Adding tests for multiple feature --- test/unit/filters.spec.js | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/unit/filters.spec.js b/test/unit/filters.spec.js index e5e0695..4fae706 100644 --- a/test/unit/filters.spec.js +++ b/test/unit/filters.spec.js @@ -35,6 +35,69 @@ describe('QueryString: Filters', function () { }) }) + context('when query filters have multiple values for multiple fields (status and sourcehealthentity_id)', function () { + it('should return a JSON with filter parameters containing a $AND filter with multiple $OR filters', function (done) { + const bedId = generateObjectId() + const requestStatusList = 'regulated,' + const sourceHealthEntityIds = `${generateObjectId()},${generateObjectId()}` + const result = filter.filters({ + bed_id: bedId, status: requestStatusList, sourcehealthentity_id: sourceHealthEntityIds + }, default_options) + + expect(result).to.have.property('$and') + expect(result['$and']).to.eql([ + { '$or': [{ status: requestStatusList.split(',')[0] }, { status: requestStatusList.split(',')[1] }] }, + { + '$or': [ + { sourcehealthentity_id: sourceHealthEntityIds.split(',')[0] }, + { sourcehealthentity_id: sourceHealthEntityIds.split(',')[1] } + ] + }]) + expect(result.bed_id).to.eql(bedId) + + done() + }) + }) + + context('when query filters have multiple values for one field (status)', function () { + it('should return a JSON with filter parameters containing a $OR filter with multiple values', function (done) { + const bedId = generateObjectId() + const requestStatusList = 'regulated,' + const sourceHealthEntityId = generateObjectId() + const result = filter.filters({ + bed_id: bedId, status: requestStatusList, sourcehealthentity_id: sourceHealthEntityId + }, default_options) + expect(result).to.not.have.property('$and') + expect(result).to.have.property('$or') + expect(result['$or']).to.eql([{ status: requestStatusList.split(',')[0] }, { status: requestStatusList.split(',')[1] }]) + expect(result.bed_id).to.eql(bedId) + expect(result.sourcehealthentity_id).to.eql(sourceHealthEntityId) + + done() + }) + }) + + context('when query filters have multiple values for one field (sourcehealthentity_id)', function () { + it('should return a JSON with filter parameters containing a $OR filter with multiple values', function (done) { + const bedId = generateObjectId() + const requestStatus = 'regulated' + const sourceHealthEntityIds = `${generateObjectId()},${generateObjectId()}` + const result = filter.filters({ + bed_id: bedId, status: requestStatus, sourcehealthentity_id: sourceHealthEntityIds + }, default_options) + expect(result).to.not.have.property('$and') + expect(result).to.have.property('$or') + expect(result['$or']).to.eql([ + { sourcehealthentity_id: sourceHealthEntityIds.split(',')[0] }, + { sourcehealthentity_id: sourceHealthEntityIds.split(',')[1] } + ]) + expect(result.bed_id).to.eql(bedId) + expect(result.status).to.eql(requestStatus) + + done() + }) + }) + context('when query filters key contains blank space', function () { it('should return a JSON with filters params, ignoring blank spaces', function (done) { verify(filter.filters({ ' na me ': 'lucas', age: '30' }, default_options)) @@ -76,3 +139,17 @@ function verify(result) { expect(result.name).to.eql('lucas') expect(result.age).to.eql(30) } + +/** + * Randomly generates a valid 24-byte hex ID. + * + * @returns {string} + */ +function generateObjectId() { + const chars = 'abcdef0123456789' + let randS = '' + for (let i = 0; i < 24; i++) { + randS += chars.charAt(Math.floor(Math.random() * chars.length)) + } + return randS +} \ No newline at end of file From b15267e8b69b2a8dc9ef0e2a7701861f6850d62f Mon Sep 17 00:00:00 2001 From: jeffsampaio Date: Mon, 13 Jun 2022 22:26:02 -0300 Subject: [PATCH 3/3] Updating package.json --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 59c0673..a57a26b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "query-strings-parser", - "version": "2.1.10", + "version": "2.1.11", "description": "Middleware to transform query strings in a format that is recognized by the MongoDB, MySQL and other databases...", "license": "MIT", "main": "index.js", @@ -45,10 +45,10 @@ }, "dependencies": {}, "devDependencies": { - "chai": "^4.3.4", - "express": "^4.17.1", - "mocha": "^9.1.3", + "chai": "^4.3.6", + "express": "^4.18.1", + "mocha": "^10.0.0", "nyc": "^15.1.0", - "supertest": "^6.1.6" + "supertest": "^6.2.3" } }