From 14cc82a057830b2d012a4120a6c6cf1e8456d80e Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Tue, 23 Feb 2016 18:01:54 -0800 Subject: [PATCH] Fix dirtyKeys() and dirty(key:) on beforeSave when updating objects. --- spec/ParseAPI.spec.js | 41 +++++++++++++++++++++++++++++++++++++++++ src/RestWrite.js | 17 +++++++++++------ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/spec/ParseAPI.spec.js b/spec/ParseAPI.spec.js index 99e4e917..f1fd09ef 100644 --- a/spec/ParseAPI.spec.js +++ b/spec/ParseAPI.spec.js @@ -429,6 +429,47 @@ describe('miscellaneous', function() { }); }); + it('test beforeSave get dirtyKeys on update', function(done) { + var triggerTime = 0; + // Register a mock beforeSave hook + Parse.Cloud.beforeSave('GameScore', function(req, res) { + var object = req.object; + expect(object instanceof Parse.Object).toBeTruthy(); + expect(object.get('fooAgain')).toEqual('barAgain'); + if (triggerTime == 0) { + // Create + expect(object.get('foo')).toEqual('bar'); + } else if (triggerTime == 1) { + // Update + expect(object.dirtyKeys()).toEqual(['foo']); + expect(object.dirty('foo')).toBeTruthy(); + expect(object.get('foo')).toEqual('baz'); + } else { + res.error(); + } + triggerTime++; + res.success(); + }); + + var obj = new Parse.Object('GameScore'); + obj.set('foo', 'bar'); + obj.set('fooAgain', 'barAgain'); + obj.save().then(function() { + // We only update foo + obj.set('foo', 'baz'); + return obj.save(); + }).then(function() { + // Make sure the checking has been triggered + expect(triggerTime).toBe(2); + // Clear mock beforeSave + delete Parse.Cloud.Triggers.beforeSave.GameScore; + done(); + }, function(error) { + fail(error); + done(); + }); + }); + it('test afterSave get full object on create and update', function(done) { var triggerTime = 0; // Register a mock beforeSave hook diff --git a/src/RestWrite.js b/src/RestWrite.js index 2728a9a6..bc2b91ba 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -116,18 +116,23 @@ RestWrite.prototype.runBeforeTrigger = function() { if (this.query && this.query.objectId) { extraData.objectId = this.query.objectId; } - // Build the inflated object, for a create write, originalData is empty - var inflatedObject = triggers.inflate(extraData, this.originalData);; - inflatedObject._finishFetch(this.data); - // Build the original object, we only do this for a update write - var originalObject; + + let originalObject = null; + let updatedObject = null; if (this.query && this.query.objectId) { + // This is an update for existing object. originalObject = triggers.inflate(extraData, this.originalData); + updatedObject = triggers.inflate(extraData, this.originalData); + updatedObject.set(Parse._decode(undefined, this.data)); + } else { + // This is create of an object, so no original object exists. + // TODO: (nlutsenko) Use the same flow as for creation, when _Session triggers support is removed. + updatedObject = triggers.inflate(extraData, this.data); } return Promise.resolve().then(() => { return triggers.maybeRunTrigger( - 'beforeSave', this.auth, inflatedObject, originalObject); + 'beforeSave', this.auth, updatedObject, originalObject); }).then((response) => { if (response && response.object) { this.data = response.object;