diff --git a/spec/ParseAPI.spec.js b/spec/ParseAPI.spec.js index 92e30732..4cf3f7a5 100644 --- a/spec/ParseAPI.spec.js +++ b/spec/ParseAPI.spec.js @@ -868,6 +868,50 @@ describe('miscellaneous', function() { }); }); + it('should return the updated fields on PUT', (done) => { + let obj = new Parse.Object('GameScore'); + obj.save({a:'hello', c: 1, d: ['1'], e:['1'], f:['1','2']}).then(( ) => { + var headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + 'X-Parse-Installation-Id': 'yolo' + }; + request.put({ + headers: headers, + url: 'http://localhost:8378/1/classes/GameScore/'+obj.id, + body: JSON.stringify({ + a: 'b', + c: {"__op":"Increment","amount":2}, + d: {"__op":"Add", objects: ['2']}, + e: {"__op":"AddUnique", objects: ['1', '2']}, + f: {"__op":"Remove", objects: ['2']}, + selfThing: {"__type":"Pointer","className":"GameScore","objectId":obj.id}, + }) + }, (error, response, body) => { + body = JSON.parse(body); + expect(body.a).toBeUndefined(); + expect(body.c).toEqual(3); // 2+1 + expect(body.d.length).toBe(2); + expect(body.d.indexOf('1') > -1).toBe(true); + expect(body.d.indexOf('2') > -1).toBe(true); + expect(body.e.length).toBe(2); + expect(body.e.indexOf('1') > -1).toBe(true); + expect(body.e.indexOf('2') > -1).toBe(true); + expect(body.f.length).toBe(1); + expect(body.f.indexOf('1') > -1).toBe(true); + // return nothing on other self + expect(body.selfThing).toBeUndefined(); + // updatedAt is always set + expect(body.updatedAt).not.toBeUndefined(); + done(); + }); + }).fail((err) => { + fail('Should not fail'); + done(); + }) + }) + it('test cloud function error handling', (done) => { // Register a function which will fail Parse.Cloud.define('willFail', (req, res) => { diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 3e85eca0..51f18811 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -139,6 +139,8 @@ DatabaseController.prototype.untransformObject = function( // one of the provided strings must provide the caller with // write permissions. DatabaseController.prototype.update = function(className, query, update, options) { + + const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. update = deepcopy(update); @@ -179,12 +181,15 @@ DatabaseController.prototype.update = function(className, query, update, options } let response = {}; - let inc = mongoUpdate['$inc']; - if (inc) { - Object.keys(inc).forEach(key => { + Object.keys(originalUpdate).forEach(key => { + let keyUpdate = originalUpdate[key]; + // determine if that was an op + if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op + && ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) { + // only valid ops that produce an actionable result response[key] = result[key]; - }); - } + } + }); return response; }); }; @@ -474,7 +479,7 @@ DatabaseController.prototype.reduceRelationKeys = function(className, query) { DatabaseController.prototype.addInObjectIdsIds = function(ids, query) { if (typeof query.objectId == 'string') { - // Add equality op as we are sure + // Add equality op as we are sure // we had a constraint on that one query.objectId = {'$eq': query.objectId}; }