From 2b3bf7c2b76ab16a77815305c3ad0b528691110c Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Thu, 31 Mar 2016 19:01:42 -0400 Subject: [PATCH 1/3] :zap: troubleshoot #1293 --- spec/ParseQuery.spec.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 334ac1b62c..50cbebae8e 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -1422,6 +1422,40 @@ describe('Parse.Query testing', () => { }); }); + it('properly includes array', (done) => { + let objects = []; + let total = 0; + while(objects.length != 5) { + let object = new Parse.Object('AnObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + Parse.Object.saveAll(objects).then(() => { + let object = new Parse.Object("AContainer"); + object.set('objects', objects); + return object.save(); + }).then(() => { + let query = new Parse.Query('AContainer'); + query.include('objects'); + return query.find() + }).then((results) => { + expect(results.length).toBe(1); + let res = results[0]; + let objects = res.get('objects'); + expect(objects.length).toBe(5); + objects.forEach((object) => { + total -= object.get('key'); + }); + expect(total).toBe(0); + done() + }, () => { + fail('should not fail'); + console.error(err); + done(); + }) + }) + it("result object creation uses current extension", function(done) { var ParentObject = Parse.Object.extend({ className: "ParentObject" }); // Add a foo() method to ChildObject. From 9c528c6fe886e1a27709221130ec21c64b2100d5 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Thu, 31 Mar 2016 19:10:59 -0400 Subject: [PATCH 2/3] :tada: regression test for #1298 --- spec/ParseQuery.spec.js | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 50cbebae8e..a2340e9eb6 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -1451,7 +1451,45 @@ describe('Parse.Query testing', () => { done() }, () => { fail('should not fail'); - console.error(err); + done(); + }) + }); + + it('properly includes array of mixed objects', (done) => { + let objects = []; + let total = 0; + while(objects.length != 5) { + let object = new Parse.Object('AnObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + while(objects.length != 10) { + let object = new Parse.Object('AnotherObject'); + object.set('key', objects.length); + total += objects.length; + objects.push(object); + } + Parse.Object.saveAll(objects).then(() => { + let object = new Parse.Object("AContainer"); + object.set('objects', objects); + return object.save(); + }).then(() => { + let query = new Parse.Query('AContainer'); + query.include('objects'); + return query.find() + }).then((results) => { + expect(results.length).toBe(1); + let res = results[0]; + let objects = res.get('objects'); + expect(objects.length).toBe(10); + objects.forEach((object) => { + total -= object.get('key'); + }); + expect(total).toBe(0); + done() + }, (err) => { + fail('should not fail'); done(); }) }) From ca7d8580e3b9d061f4b72d6c34f9fdbb6961127a Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Thu, 31 Mar 2016 19:32:24 -0400 Subject: [PATCH 3/3] :+1: fixes #1298 --- src/RestQuery.js | 51 +++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/RestQuery.js b/src/RestQuery.js index 8cfd26df86..f2636b54c1 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -449,39 +449,42 @@ function includePath(config, auth, response, path) { if (pointers.length == 0) { return response; } + let pointersHash = {}; var className = null; var objectIds = {}; for (var pointer of pointers) { - if (className === null) { - className = pointer.className; - } else { - if (className != pointer.className) { - throw new Parse.Error(Parse.Error.INVALID_JSON, - 'inconsistent type data for include'); - } + let className = pointer.className; + // only include the good pointers + if (className) { + pointersHash[className] = pointersHash[className] || []; + pointersHash[className].push(pointer.objectId); } - objectIds[pointer.objectId] = true; - } - if (!className) { - throw new Parse.Error(Parse.Error.INVALID_JSON, - 'bad pointers'); } + let queryPromises = Object.keys(pointersHash).map((className) => { + var where = {'objectId': {'$in': pointersHash[className]}}; + var query = new RestQuery(config, auth, className, where); + return query.execute().then((results) => { + results.className = className; + return Promise.resolve(results); + }) + }) + // Get the objects for all these object ids - var where = {'objectId': {'$in': Object.keys(objectIds)}}; - var query = new RestQuery(config, auth, className, where); - return query.execute().then((includeResponse) => { - var replace = {}; - for (var obj of includeResponse.results) { - obj.__type = 'Object'; - obj.className = className; - - if(className == "_User"){ - delete obj.sessionToken; + return Promise.all(queryPromises).then((responses) => { + var replace = responses.reduce((replace, includeResponse) => { + for (var obj of includeResponse.results) { + obj.__type = 'Object'; + obj.className = includeResponse.className; + + if(className == "_User"){ + delete obj.sessionToken; + } + replace[obj.objectId] = obj; } + return replace; + }, {}) - replace[obj.objectId] = obj; - } var resp = { results: replacePointers(response.results, path, replace) };