diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index d8f775618..86588fc6f 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -738,6 +738,15 @@ Memory.prototype.destroyAll = function destroyAll(model, where, options, callbac var filter = null; var count = 0; if (where) { + for (var key in where) { + var p = this._models[model].properties[key]; + if (key !== 'and' && key !== 'or' && p == null) { + callback(new Error( + `Unknown property ${key} used in a "where" condition for model ${model}.` + )); + } + } + filter = applyFilter({where: where}); Object.keys(cache).forEach(function(id) { if (!filter || filter(this.fromDb(model, cache[id]))) { diff --git a/lib/utils.js b/lib/utils.js index dcd9760b1..a10030137 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -302,7 +302,7 @@ function selectFields(fields) { } /** - * Remove undefined values from the queury object + * Remove undefined values from the query object * @param query * @param handleUndefined {String} either "nullify", "throw" or "ignore" (default: "ignore") * @returns {exports.map|*} diff --git a/test/manipulation.test.js b/test/manipulation.test.js index 395c3b698..ca3ba273c 100644 --- a/test/manipulation.test.js +++ b/test/manipulation.test.js @@ -1622,6 +1622,10 @@ describe('manipulation', function() { }); describe('destroy', function() { + beforeEach(function resetFixtures(done) { + Person.destroyAll(done); + }); + it('should destroy record', function(done) { Person.create(function(err, p) { if (err) return done(err); @@ -1685,8 +1689,58 @@ describe('manipulation', function() { .catch(done); }); - // TODO: implement destroy with filtered set - it('should destroy filtered set of records'); + it('should destroy filtered set of records', function() { + return givenNamedPeople(['John', 'Jane', 'Mary']) + .then(() => + Person.destroyAll({name: 'Jane'})) + .then(() => Person.find({fields: {name: true}}) + .then(users => { + let userData = []; + users.forEach(user => userData.push(user.__data)); + userData.should.deepEqual([ + {name: 'John'}, + {name: 'Mary'}, + ]); + })); + }); + + it('should reject unknown properties', function() { + return givenNamedPeople(['John', 'Jane', 'Mary']) + .then(() => + Person.destroyAll({names: 'John'}).should.be.rejectedWith(/Unknown property/)) + .then(() => Person.find({fields: {name: true}, order: 'name ASC'}) + .then(users => { + let userData = []; + users.forEach(user => userData.push(user.__data)); + userData.should.deepEqual([ + {name: 'Jane'}, + {name: 'John'}, + {name: 'Mary'}, + ]); + })); + }); + + it('should reject where object inside a filter object', function() { + return givenNamedPeople(['John', 'Jane', 'Mary']) + .then(() => + Person.destroyAll({where: {name: 'John'}}).should.be.rejectedWith(/Unknown property/)) + .then(() => Person.find({fields: {name: true}}) + .then(users => { + let userData = []; + users.forEach(user => userData.push(user.__data)); + userData.should.deepEqual([ + {name: 'John'}, + {name: 'Jane'}, + {name: 'Mary'}, + ]); + })); + }); + + function givenNamedPeople(namesList) { + return Promise.all( + namesList.map(name => Person.create({name})) + ); + } }); bdd.describeIf(connectorCapabilities.reportDeletedCount !== false &&