Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize objectId $in management, fix $select bug from iOS #809

Merged
merged 2 commits into from
Mar 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions spec/ParseQuery.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2088,4 +2088,60 @@ describe('Parse.Query testing', () => {
console.log(error);
});
});

// #371
it('should properly interpret a query', (done) => {
var query = new Parse.Query("C1");
var auxQuery = new Parse.Query("C1");
query.matchesKeyInQuery("A1", "A2", auxQuery);
query.include("A3");
query.include("A2");
query.find().then((result) => {
done();
}, (err) => {
console.error(err);
fail("should not failt");
done();
})
});

it('should properly interpret a query', (done) => {
var user = new Parse.User();
user.set("username", "foo");
user.set("password", "bar");
return user.save().then( (user) => {
var objIdQuery = new Parse.Query("_User").equalTo("objectId", user.id);
var blockedUserQuery = user.relation("blockedUsers").query();

var aResponseQuery = new Parse.Query("MatchRelationshipActivityResponse");
aResponseQuery.equalTo("userA", user);
aResponseQuery.equalTo("userAResponse", 1);

var bResponseQuery = new Parse.Query("MatchRelationshipActivityResponse");
bResponseQuery.equalTo("userB", user);
bResponseQuery.equalTo("userBResponse", 1);

var matchOr = Parse.Query.or(aResponseQuery, bResponseQuery);
var matchRelationshipA = new Parse.Query("_User");
matchRelationshipA.matchesKeyInQuery("objectId", "userAObjectId", matchOr);
var matchRelationshipB = new Parse.Query("_User");
matchRelationshipB.matchesKeyInQuery("objectId", "userBObjectId", matchOr);


var orQuery = Parse.Query.or(objIdQuery, blockedUserQuery, matchRelationshipA, matchRelationshipB);
var query = new Parse.Query("_User");
query.doesNotMatchQuery("objectId", orQuery);
return query.find();
}).then((res) => {
done();
done();
}, (err) => {
console.error(err);
fail("should not fail");
done();
});


});

});
39 changes: 39 additions & 0 deletions spec/ParseRelation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,44 @@ describe('Parse.Relation testing', () => {
});
});

it("query on pointer and relation fields with equal", (done) => {
var ChildObject = Parse.Object.extend("ChildObject");
var childObjects = [];
for (var i = 0; i < 10; i++) {
childObjects.push(new ChildObject({x: i}));
}

Parse.Object.saveAll(childObjects).then(() => {
var ParentObject = Parse.Object.extend("ParentObject");
var parent = new ParentObject();
parent.set("x", 4);
var relation = parent.relation("toChilds");
relation.add(childObjects[0]);
relation.add(childObjects[1]);
relation.add(childObjects[2]);

var parent2 = new ParentObject();
parent2.set("x", 3);
parent2.set("toChild", childObjects[2]);

var parents = [];
parents.push(parent);
parents.push(parent2);
parents.push(new ParentObject());

return Parse.Object.saveAll(parents).then(() => {
var query = new Parse.Query(ParentObject);
query.equalTo("objectId", parent.id);
query.equalTo("toChilds", childObjects[2]);

return query.find().then((list) => {
equal(list.length, 1, "There should be 1 result");
done();
});
});
});
});

it("or queries on pointer and relation fields", (done) => {
var ChildObject = Parse.Object.extend("ChildObject");
var childObjects = [];
Expand Down Expand Up @@ -335,6 +373,7 @@ describe('Parse.Relation testing', () => {
});
});


it("Get query on relation using un-fetched parent object", (done) => {
// Setup data model
var Wheel = Parse.Object.extend('Wheel');
Expand Down
21 changes: 14 additions & 7 deletions src/Controllers/DatabaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,8 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
relatedIds = [query[key].objectId];
}
return this.owningIds(className, key, relatedIds).then((ids) => {
delete query[key];
query.objectId = Object.assign({'$in': []}, query.objectId);
query.objectId['$in'] = query.objectId['$in'].concat(ids);
delete query[key];
this.addInObjectIdsIds(ids, query);
return Promise.resolve(query);
});
}
Expand Down Expand Up @@ -448,15 +447,23 @@ DatabaseController.prototype.reduceRelationKeys = function(className, query) {
relatedTo.key,
relatedTo.object.objectId).then((ids) => {
delete query['$relatedTo'];
query.objectId = query.objectId || {};
let queryIn = query.objectId['$in'] || [];
queryIn = queryIn.concat(ids);
query['objectId'] = {'$in': queryIn};
this.addInObjectIdsIds(ids, query);
return this.reduceRelationKeys(className, query);
});
}
};

DatabaseController.prototype.addInObjectIdsIds = function(ids, query) {
if (typeof query.objectId == 'string') {
query.objectId = {'$in': [query.objectId]};
}
query.objectId = query.objectId || {};
let queryIn = [].concat(query.objectId['$in'] || [], ids || []);
// make a set and spread to remove duplicates
query.objectId = {'$in': [...new Set(queryIn)]};
return query;
}

// Runs a query on the database.
// Returns a promise that resolves to a list of items.
// Options:
Expand Down
2 changes: 1 addition & 1 deletion src/RestQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,11 @@ RestQuery.prototype.replaceSelect = function() {

// The select value must have precisely two keys - query and key
var selectValue = selectObject['$select'];
// iOS SDK don't send where if not set, let it pass
if (!selectValue.query ||
!selectValue.key ||
typeof selectValue.query !== 'object' ||
!selectValue.query.className ||
!selectValue.query.where ||
Object.keys(selectValue).length !== 2) {
throw new Parse.Error(Parse.Error.INVALID_QUERY,
'improper usage of $select');
Expand Down