From 291c1516d97c9c4f6bb766dbe1e87d383b08d4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20B=C3=A9guin?= Date: Fri, 29 Oct 2021 14:12:56 +0200 Subject: [PATCH] ResourceFilter: add support for "exists" ResourceFilter now supports the "exists" comparison operator to be able to test if a field exists or not. --- CHANGELOG.md | 1 + lib/storages/ResourceFilter.js | 20 ++++++++++++++++ .../databases/mongodb/MongoDatabase.js | 4 ++++ tests/server/storages/MongoDatabase.js | 12 ++++++++++ tests/server/storages/ResourceFilter.js | 24 +++++++++++++++++++ 5 files changed, 61 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b10dc96..905f5a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - require('@openveo/api').fileSystem.getFileType has been added to be able to get the type of a file (only for supported files) - require('@openveo/api').fileSystem.extract is now capable of extracting zip files - require('@openveo/api').fileSystem now supports zip files +- require('@openveo/api').storages.ResourceFilter now supports `exists` comparison operator to test if a field exists or not ## BUG FIXES diff --git a/lib/storages/ResourceFilter.js b/lib/storages/ResourceFilter.js index 8832e0f..5862726 100644 --- a/lib/storages/ResourceFilter.js +++ b/lib/storages/ResourceFilter.js @@ -13,6 +13,7 @@ * @example * var filter = new ResourceFilter() * .equal('field1', 42) + * .exists('field1', true) * .notEqual('field2', 42) * .greaterThan('field3', 42) * .greaterThanEqual('field4', 42) @@ -75,6 +76,7 @@ ResourceFilter.OPERATORS = { NOR: 'nor', AND: 'and', EQUAL: 'equal', + EXISTS: 'exists', NOT_EQUAL: 'notEqual', IN: 'in', NOT_IN: 'notIn', @@ -191,6 +193,24 @@ ResourceFilter.prototype.equal = function(field, value) { ); }; +/** + * Adds an exists operation to the filter. + * + * @param {String} field The name of the field + * @param {Boolean} value true if the field should exist, false otherwise + * @return {module:storages/ResourceFilter~ResourceFilter} The actual filter + * @throws {TypeError} An error if field and / or value is not valid + */ +ResourceFilter.prototype.exists = function(field, value) { + return addComparisonOperation.call( + this, + field, + value, + ResourceFilter.OPERATORS.EXISTS, + ['Boolean'] + ); +}; + /** * Adds a "not equal" operation to the filter. * diff --git a/lib/storages/databases/mongodb/MongoDatabase.js b/lib/storages/databases/mongodb/MongoDatabase.js index bc6f09f..3ab39c5 100644 --- a/lib/storages/databases/mongodb/MongoDatabase.js +++ b/lib/storages/databases/mongodb/MongoDatabase.js @@ -118,6 +118,10 @@ MongoDatabase.buildFilter = function(resourceFilter) { if (!filter[operation.field]) filter[operation.field] = {}; filter[operation.field]['$eq'] = operation.value; break; + case ResourceFilter.OPERATORS.EXISTS: + if (!filter[operation.field]) filter[operation.field] = {}; + filter[operation.field]['$exists'] = operation.value; + break; case ResourceFilter.OPERATORS.NOT_EQUAL: if (!filter[operation.field]) filter[operation.field] = {}; filter[operation.field]['$ne'] = operation.value; diff --git a/tests/server/storages/MongoDatabase.js b/tests/server/storages/MongoDatabase.js index 4c97f99..fbe2282 100644 --- a/tests/server/storages/MongoDatabase.js +++ b/tests/server/storages/MongoDatabase.js @@ -290,6 +290,12 @@ describe('MongoDatabase', function() { type: ResourceFilter.OPERATORS.EQUAL, mongoOperator: '$eq' }, + { + field: 'field1', + value: true, + type: ResourceFilter.OPERATORS.EXISTS, + mongoOperator: '$exists' + }, { field: 'field2', value: 'value2', @@ -354,6 +360,12 @@ describe('MongoDatabase', function() { type: ResourceFilter.OPERATORS.EQUAL, mongoOperator: '$eq' }, + { + field: 'field', + value: true, + type: ResourceFilter.OPERATORS.EXISTS, + mongoOperator: '$exists' + }, { field: 'field', value: '43', diff --git a/tests/server/storages/ResourceFilter.js b/tests/server/storages/ResourceFilter.js index 8c00ba1..e558b6c 100644 --- a/tests/server/storages/ResourceFilter.js +++ b/tests/server/storages/ResourceFilter.js @@ -227,6 +227,30 @@ describe('ResourceFilter', function() { }); + describe(ResourceFilter.OPERATORS.EXISTS, function() { + + it('should add a "' + ResourceFilter.OPERATORS.EXISTS + '" operation', function() { + var expectedValue = true; + var expectedField = 'field'; + filter[ResourceFilter.OPERATORS.EXISTS](expectedField, expectedValue); + + assert.equal(filter.operations[0].type, ResourceFilter.OPERATORS.EXISTS, 'Wrong operation type'); + assert.equal(filter.operations[0].field, expectedField, 'Wrong operation field'); + assert.equal(filter.operations[0].value, expectedValue, 'Wrong operation value'); + }); + + it('should throw a TypeError if value is not a boolean', function() { + var wrongValues = [[], 42, /regexp/, {}, 'String']; + + wrongValues.forEach(function(wrongValue) { + assert.throws(function() { + filter[ResourceFilter.OPERATORS.EXISTS]('field', wrongValue); + }); + }); + }); + + }); + describe('hasOperation', function() { it('should return true if an operation type is already present in the list of operations', function() {