Fix issue with pointers getting un-hydrated when there is a beforeSave (#1884)
* Add failing test and simplify RestWrite * simplify and add test stubs * Fix issue
This commit is contained in:
@@ -557,4 +557,36 @@ describe('Cloud Code', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('trivial beforeSave should not affect fetched pointers (regression test for #1238)', done => {
|
||||
Parse.Cloud.beforeSave('BeforeSaveUnchanged', (req, res) => {
|
||||
res.success();
|
||||
});
|
||||
|
||||
var TestObject = Parse.Object.extend("TestObject");
|
||||
var NoBeforeSaveObject = Parse.Object.extend("NoBeforeSave");
|
||||
var BeforeSaveObject = Parse.Object.extend("BeforeSaveUnchanged");
|
||||
|
||||
var aTestObject = new TestObject();
|
||||
aTestObject.set("foo", "bar");
|
||||
aTestObject.save()
|
||||
.then(aTestObject => {
|
||||
var aNoBeforeSaveObj = new NoBeforeSaveObject();
|
||||
aNoBeforeSaveObj.set("aTestObject", aTestObject);
|
||||
expect(aNoBeforeSaveObj.get("aTestObject").get("foo")).toEqual("bar");
|
||||
return aNoBeforeSaveObj.save();
|
||||
})
|
||||
.then(aNoBeforeSaveObj => {
|
||||
expect(aNoBeforeSaveObj.get("aTestObject").get("foo")).toEqual("bar");
|
||||
|
||||
var aBeforeSaveObj = new BeforeSaveObject();
|
||||
aBeforeSaveObj.set("aTestObject", aTestObject);
|
||||
expect(aBeforeSaveObj.get("aTestObject").get("foo")).toEqual("bar");
|
||||
return aBeforeSaveObj.save();
|
||||
})
|
||||
.then(aBeforeSaveObj => {
|
||||
expect(aBeforeSaveObj.get("aTestObject").get("foo")).toEqual("bar");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ var passwordCrypto = require('./password');
|
||||
var Parse = require('parse/node');
|
||||
var triggers = require('./triggers');
|
||||
import RestQuery from './RestQuery';
|
||||
import _ from 'lodash';
|
||||
|
||||
// query and data are both provided in REST API format. So data
|
||||
// types are encoded by plain old objects.
|
||||
@@ -165,8 +166,10 @@ RestWrite.prototype.runBeforeTrigger = function() {
|
||||
return triggers.maybeRunTrigger(triggers.Types.beforeSave, this.auth, updatedObject, originalObject, this.config);
|
||||
}).then((response) => {
|
||||
if (response && response.object) {
|
||||
if (!_.isEqual(this.data, response.object)) {
|
||||
this.storage.changedByTrigger = true;
|
||||
}
|
||||
this.data = response.object;
|
||||
this.storage['changedByTrigger'] = true;
|
||||
// We should delete the objectId for an update write
|
||||
if (this.query && this.query.objectId) {
|
||||
delete this.data.objectId
|
||||
@@ -733,19 +736,16 @@ RestWrite.prototype.runDatabaseOperation = function() {
|
||||
this.data.ACL[this.query.objectId] = { read: true, write: true };
|
||||
}
|
||||
// Run an update
|
||||
return this.config.database.update(
|
||||
this.className, this.query, this.data, this.runOptions).then((resp) => {
|
||||
resp.updatedAt = this.updatedAt;
|
||||
if (this.storage['changedByTrigger']) {
|
||||
resp = Object.keys(this.data).reduce((memo, key) => {
|
||||
memo[key] = resp[key] || this.data[key];
|
||||
return memo;
|
||||
}, resp);
|
||||
}
|
||||
this.response = {
|
||||
response: resp
|
||||
};
|
||||
});
|
||||
return this.config.database.update(this.className, this.query, this.data, this.runOptions)
|
||||
.then(response => {
|
||||
response.updatedAt = this.updatedAt;
|
||||
if (this.storage.changedByTrigger) {
|
||||
Object.keys(this.data).forEach(fieldName => {
|
||||
response[fieldName] = response[fieldName] || this.data[fieldName];
|
||||
});
|
||||
}
|
||||
this.response = { response };
|
||||
});
|
||||
} else {
|
||||
// Set the default ACL for the new _User
|
||||
if (this.className === '_User') {
|
||||
@@ -762,23 +762,20 @@ RestWrite.prototype.runDatabaseOperation = function() {
|
||||
|
||||
// Run a create
|
||||
return this.config.database.create(this.className, this.data, this.runOptions)
|
||||
.then((resp) => {
|
||||
Object.assign(resp, {
|
||||
objectId: this.data.objectId,
|
||||
createdAt: this.data.createdAt
|
||||
.then(response => {
|
||||
response.objectId = this.data.objectId;
|
||||
response.createdAt = this.data.createdAt;
|
||||
if (this.storage.changedByTrigger) {
|
||||
Object.keys(this.data).forEach(fieldName => {
|
||||
response[fieldName] = response[fieldName] || this.data[fieldName];
|
||||
});
|
||||
if (this.storage['changedByTrigger']) {
|
||||
resp = Object.keys(this.data).reduce((memo, key) => {
|
||||
memo[key] = resp[key] || this.data[key];
|
||||
return memo;
|
||||
}, resp);
|
||||
}
|
||||
this.response = {
|
||||
status: 201,
|
||||
response: resp,
|
||||
location: this.location()
|
||||
};
|
||||
});
|
||||
}
|
||||
this.response = {
|
||||
status: 201,
|
||||
response,
|
||||
location: this.location()
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user