Merge pull request #614 from ParsePlatform/nlutsenko.beforeSave.dirty
Fix dirtyKeys() and dirty(key:) on beforeSave when updating objects.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
// A bunch of different tests are in here - it isn't very thematic.
|
// A bunch of different tests are in here - it isn't very thematic.
|
||||||
// It would probably be better to refactor them into different files.
|
// It would probably be better to refactor them into different files.
|
||||||
|
'use strict';
|
||||||
|
|
||||||
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
||||||
var request = require('request');
|
var request = require('request');
|
||||||
@@ -138,7 +139,7 @@ describe('miscellaneous', function() {
|
|||||||
return new Parse.Query(TestObject).find();
|
return new Parse.Query(TestObject).find();
|
||||||
}).then((results) => {
|
}).then((results) => {
|
||||||
expect(results.length).toEqual(100);
|
expect(results.length).toEqual(100);
|
||||||
done();
|
done();
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
fail(error);
|
fail(error);
|
||||||
done();
|
done();
|
||||||
@@ -280,7 +281,7 @@ describe('miscellaneous', function() {
|
|||||||
// We should have been able to fetch the object again
|
// We should have been able to fetch the object again
|
||||||
fail(error);
|
fail(error);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
it('basic beforeDelete rejection via promise', function(done) {
|
it('basic beforeDelete rejection via promise', function(done) {
|
||||||
var obj = new Parse.Object('BeforeDeleteFailWithPromise');
|
var obj = new Parse.Object('BeforeDeleteFailWithPromise');
|
||||||
@@ -383,50 +384,155 @@ describe('miscellaneous', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test beforeSave get full object on create and update', function(done) {
|
describe('beforeSave', () => {
|
||||||
var triggerTime = 0;
|
beforeEach(done => {
|
||||||
// Register a mock beforeSave hook
|
// Make sure the required mock for all tests is unset.
|
||||||
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');
|
|
||||||
// No objectId/createdAt/updatedAt
|
|
||||||
expect(object.id).toBeUndefined();
|
|
||||||
expect(object.createdAt).toBeUndefined();
|
|
||||||
expect(object.updatedAt).toBeUndefined();
|
|
||||||
} else if (triggerTime == 1) {
|
|
||||||
// Update
|
|
||||||
expect(object.get('foo')).toEqual('baz');
|
|
||||||
expect(object.id).not.toBeUndefined();
|
|
||||||
expect(object.createdAt).not.toBeUndefined();
|
|
||||||
expect(object.updatedAt).not.toBeUndefined();
|
|
||||||
} 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;
|
delete Parse.Cloud.Triggers.beforeSave.GameScore;
|
||||||
done();
|
done();
|
||||||
}, function(error) {
|
});
|
||||||
fail(error);
|
|
||||||
|
afterEach(done => {
|
||||||
|
// Make sure the required mock for all tests is unset.
|
||||||
|
delete Parse.Cloud.Triggers.beforeSave.GameScore;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('object is set on create and update', done => {
|
||||||
|
let triggerTime = 0;
|
||||||
|
// Register a mock beforeSave hook
|
||||||
|
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||||||
|
let 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');
|
||||||
|
// No objectId/createdAt/updatedAt
|
||||||
|
expect(object.id).toBeUndefined();
|
||||||
|
expect(object.createdAt).toBeUndefined();
|
||||||
|
expect(object.updatedAt).toBeUndefined();
|
||||||
|
} else if (triggerTime == 1) {
|
||||||
|
// Update
|
||||||
|
expect(object.get('foo')).toEqual('baz');
|
||||||
|
expect(object.id).not.toBeUndefined();
|
||||||
|
expect(object.createdAt).not.toBeUndefined();
|
||||||
|
expect(object.updatedAt).not.toBeUndefined();
|
||||||
|
} else {
|
||||||
|
res.error();
|
||||||
|
}
|
||||||
|
triggerTime++;
|
||||||
|
res.success();
|
||||||
|
});
|
||||||
|
|
||||||
|
let obj = new Parse.Object('GameScore');
|
||||||
|
obj.set('foo', 'bar');
|
||||||
|
obj.set('fooAgain', 'barAgain');
|
||||||
|
obj.save().then(() => {
|
||||||
|
// We only update foo
|
||||||
|
obj.set('foo', 'baz');
|
||||||
|
return obj.save();
|
||||||
|
}).then(() => {
|
||||||
|
// Make sure the checking has been triggered
|
||||||
|
expect(triggerTime).toBe(2);
|
||||||
|
done();
|
||||||
|
}, error => {
|
||||||
|
fail(error);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('dirtyKeys are set on update', done => {
|
||||||
|
let triggerTime = 0;
|
||||||
|
// Register a mock beforeSave hook
|
||||||
|
Parse.Cloud.beforeSave('GameScore', (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();
|
||||||
|
});
|
||||||
|
|
||||||
|
let obj = new Parse.Object('GameScore');
|
||||||
|
obj.set('foo', 'bar');
|
||||||
|
obj.set('fooAgain', 'barAgain');
|
||||||
|
obj.save().then(() => {
|
||||||
|
// We only update foo
|
||||||
|
obj.set('foo', 'baz');
|
||||||
|
return obj.save();
|
||||||
|
}).then(() => {
|
||||||
|
// Make sure the checking has been triggered
|
||||||
|
expect(triggerTime).toBe(2);
|
||||||
|
done();
|
||||||
|
}, function(error) {
|
||||||
|
fail(error);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('original object is set on update', done => {
|
||||||
|
let triggerTime = 0;
|
||||||
|
// Register a mock beforeSave hook
|
||||||
|
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||||||
|
let object = req.object;
|
||||||
|
expect(object instanceof Parse.Object).toBeTruthy();
|
||||||
|
expect(object.get('fooAgain')).toEqual('barAgain');
|
||||||
|
let originalObject = req.original;
|
||||||
|
if (triggerTime == 0) {
|
||||||
|
// No id/createdAt/updatedAt
|
||||||
|
expect(object.id).toBeUndefined();
|
||||||
|
expect(object.createdAt).toBeUndefined();
|
||||||
|
expect(object.updatedAt).toBeUndefined();
|
||||||
|
// Create
|
||||||
|
expect(object.get('foo')).toEqual('bar');
|
||||||
|
// Check the originalObject is undefined
|
||||||
|
expect(originalObject).toBeUndefined();
|
||||||
|
} else if (triggerTime == 1) {
|
||||||
|
// Update
|
||||||
|
expect(object.id).not.toBeUndefined();
|
||||||
|
expect(object.createdAt).not.toBeUndefined();
|
||||||
|
expect(object.updatedAt).not.toBeUndefined();
|
||||||
|
expect(object.get('foo')).toEqual('baz');
|
||||||
|
// Check the originalObject
|
||||||
|
expect(originalObject instanceof Parse.Object).toBeTruthy();
|
||||||
|
expect(originalObject.get('fooAgain')).toEqual('barAgain');
|
||||||
|
expect(originalObject.id).not.toBeUndefined();
|
||||||
|
expect(originalObject.createdAt).not.toBeUndefined();
|
||||||
|
expect(originalObject.updatedAt).not.toBeUndefined();
|
||||||
|
expect(originalObject.get('foo')).toEqual('bar');
|
||||||
|
} else {
|
||||||
|
res.error();
|
||||||
|
}
|
||||||
|
triggerTime++;
|
||||||
|
res.success();
|
||||||
|
});
|
||||||
|
|
||||||
|
let obj = new Parse.Object('GameScore');
|
||||||
|
obj.set('foo', 'bar');
|
||||||
|
obj.set('fooAgain', 'barAgain');
|
||||||
|
obj.save().then(() => {
|
||||||
|
// We only update foo
|
||||||
|
obj.set('foo', 'baz');
|
||||||
|
return obj.save();
|
||||||
|
}).then(() => {
|
||||||
|
// Make sure the checking has been triggered
|
||||||
|
expect(triggerTime).toBe(2);
|
||||||
|
done();
|
||||||
|
}, error => {
|
||||||
|
fail(error);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test afterSave get full object on create and update', function(done) {
|
it('test afterSave get full object on create and update', function(done) {
|
||||||
@@ -471,62 +577,6 @@ describe('miscellaneous', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test beforeSave get original object 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');
|
|
||||||
var originalObject = req.original;
|
|
||||||
if (triggerTime == 0) {
|
|
||||||
// No id/createdAt/updatedAt
|
|
||||||
expect(object.id).toBeUndefined();
|
|
||||||
expect(object.createdAt).toBeUndefined();
|
|
||||||
expect(object.updatedAt).toBeUndefined();
|
|
||||||
// Create
|
|
||||||
expect(object.get('foo')).toEqual('bar');
|
|
||||||
// Check the originalObject is undefined
|
|
||||||
expect(originalObject).toBeUndefined();
|
|
||||||
} else if (triggerTime == 1) {
|
|
||||||
// Update
|
|
||||||
expect(object.id).not.toBeUndefined();
|
|
||||||
expect(object.createdAt).not.toBeUndefined();
|
|
||||||
expect(object.updatedAt).not.toBeUndefined();
|
|
||||||
expect(object.get('foo')).toEqual('baz');
|
|
||||||
// Check the originalObject
|
|
||||||
expect(originalObject instanceof Parse.Object).toBeTruthy();
|
|
||||||
expect(originalObject.get('fooAgain')).toEqual('barAgain');
|
|
||||||
expect(originalObject.id).not.toBeUndefined();
|
|
||||||
expect(originalObject.createdAt).not.toBeUndefined();
|
|
||||||
expect(originalObject.updatedAt).not.toBeUndefined();
|
|
||||||
expect(originalObject.get('foo')).toEqual('bar');
|
|
||||||
} 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 original object on update', function(done) {
|
it('test afterSave get original object on update', function(done) {
|
||||||
var triggerTime = 0;
|
var triggerTime = 0;
|
||||||
// Register a mock beforeSave hook
|
// Register a mock beforeSave hook
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ var DatabaseAdapter = require('../src/DatabaseAdapter');
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var facebook = require('../src/oauth/facebook');
|
var facebook = require('../src/oauth/facebook');
|
||||||
var ParseServer = require('../src/index').ParseServer;
|
var ParseServer = require('../src/index').ParseServer;
|
||||||
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
|
||||||
|
|
||||||
var databaseURI = process.env.DATABASE_URI;
|
var databaseURI = process.env.DATABASE_URI;
|
||||||
var cloudMain = process.env.CLOUD_CODE_MAIN || '../spec/cloud/main.js';
|
var cloudMain = process.env.CLOUD_CODE_MAIN || '../spec/cloud/main.js';
|
||||||
|
|||||||
@@ -116,18 +116,23 @@ RestWrite.prototype.runBeforeTrigger = function() {
|
|||||||
if (this.query && this.query.objectId) {
|
if (this.query && this.query.objectId) {
|
||||||
extraData.objectId = 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);;
|
let originalObject = null;
|
||||||
inflatedObject._finishFetch(this.data);
|
let updatedObject = null;
|
||||||
// Build the original object, we only do this for a update write
|
|
||||||
var originalObject;
|
|
||||||
if (this.query && this.query.objectId) {
|
if (this.query && this.query.objectId) {
|
||||||
|
// This is an update for existing object.
|
||||||
originalObject = triggers.inflate(extraData, this.originalData);
|
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 Promise.resolve().then(() => {
|
||||||
return triggers.maybeRunTrigger(
|
return triggers.maybeRunTrigger(
|
||||||
'beforeSave', this.auth, inflatedObject, originalObject);
|
'beforeSave', this.auth, updatedObject, originalObject);
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
if (response && response.object) {
|
if (response && response.object) {
|
||||||
this.data = response.object;
|
this.data = response.object;
|
||||||
|
|||||||
Reference in New Issue
Block a user