diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 9d27f302ca..b238e24e63 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -1891,6 +1891,41 @@ describe('Parse.Query testing', () => { }); }); + it("equalTo on same column as $dontSelect should not break $dontSelect functionality (#3678)", function(done) { + var AuthorObject = Parse.Object.extend("Author"); + var BlockedObject = Parse.Object.extend("Blocked"); + var PostObject = Parse.Object.extend("Post"); + + var postAuthor = null; + var requestUser = null; + + return new AuthorObject({ name: "Julius"}).save().then((user) => { + postAuthor = user; + return new AuthorObject({ name: "Bob"}).save(); + }).then((user) => { + requestUser = user; + var objects = [ + new PostObject({ author: postAuthor, title: "Lorem ipsum" }), + new PostObject({ author: requestUser, title: "Kafka" }), + new PostObject({ author: requestUser, title: "Brown fox" }), + new BlockedObject({ blockedBy: postAuthor, blockedUser: requestUser}) + ]; + return Parse.Object.saveAll(objects); + }).then(() => { + var banListQuery = new Parse.Query(BlockedObject); + banListQuery.equalTo("blockedUser", requestUser); + + return new Parse.Query(PostObject) + .equalTo("author", postAuthor) + .doesNotMatchKeyInQuery("author", "blockedBy", banListQuery) + .find() + .then((r) => { + expect(r.length).toEqual(0); + done(); + }, done.fail); + }) + }); + it("object with length", function(done) { var TestObject = Parse.Object.extend("TestObject"); var obj = new TestObject(); diff --git a/src/RestQuery.js b/src/RestQuery.js index 974e3e8912..37cbd518d6 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -169,6 +169,8 @@ RestQuery.prototype.buildRestWhere = function() { return this.replaceInQuery(); }).then(() => { return this.replaceNotInQuery(); + }).then(() => { + return this.replaceEquality(); }); } @@ -438,6 +440,39 @@ const cleanResultAuthData = function (result) { } }; +const replaceEqualityConstraint = (constraint) => { + if (typeof constraint !== 'object') { + return constraint; + } + const equalToObject = {}; + let hasDirectConstraint = false; + let hasOperatorConstraint = false; + for (const key in constraint) { + if (key.indexOf('$') !== 0) { + hasDirectConstraint = true; + equalToObject[key] = constraint[key]; + } else { + hasOperatorConstraint = true; + } + } + if (hasDirectConstraint && hasOperatorConstraint) { + constraint['$eq'] = equalToObject; + Object.keys(equalToObject).forEach((key) => { + delete constraint[key]; + }); + } + return constraint; +} + +RestQuery.prototype.replaceEquality = function() { + if (typeof this.restWhere !== 'object') { + return; + } + for (const key in this.restWhere) { + this.restWhere[key] = replaceEqualityConstraint(this.restWhere[key]); + } +} + // Returns a promise for whether it was successful. // Populates this.response with an object that only has 'results'. RestQuery.prototype.runFind = function(options = {}) {