Merge pull request #1066 from ParsePlatform/flovilmart.returnsFullModificationsForREST
Improvements in REST calls
This commit is contained in:
@@ -224,6 +224,19 @@ describe('miscellaneous', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('test beforeSave returns value on create and update', (done) => {
|
||||
var obj = new Parse.Object('BeforeSaveChanged');
|
||||
obj.set('foo', 'bing');
|
||||
obj.save().then(() => {
|
||||
expect(obj.get('foo')).toEqual('baz');
|
||||
obj.set('foo', 'bar');
|
||||
return obj.save().then(() => {
|
||||
expect(obj.get('foo')).toEqual('baz');
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it('test afterSave ran and created an object', function(done) {
|
||||
var obj = new Parse.Object('AfterSaveTest');
|
||||
obj.save();
|
||||
@@ -383,6 +396,13 @@ describe('miscellaneous', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly create an object in before save', (done) => {
|
||||
Parse.Cloud.run('createBeforeSaveChangedObject').then((res) => {
|
||||
expect(res.get('foo')).toEqual('baz');
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('test rest_create_app', function(done) {
|
||||
var appId;
|
||||
Parse._request('POST', 'rest_create_app').then((res) => {
|
||||
@@ -868,6 +888,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) => {
|
||||
|
||||
@@ -108,3 +108,10 @@ Parse.Cloud.define('echoKeys', function(req, res){
|
||||
javascriptKey: Parse.javascriptKey
|
||||
})
|
||||
});
|
||||
|
||||
Parse.Cloud.define('createBeforeSaveChangedObject', function(req, res){
|
||||
var obj = new Parse.Object('BeforeSaveChanged');
|
||||
obj.save().then(() => {
|
||||
res.success(obj);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -177,18 +179,27 @@ DatabaseController.prototype.update = function(className, query, update, options
|
||||
return Promise.reject(new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
|
||||
'Object not found.'));
|
||||
}
|
||||
|
||||
let response = {};
|
||||
let inc = mongoUpdate['$inc'];
|
||||
if (inc) {
|
||||
Object.keys(inc).forEach(key => {
|
||||
response[key] = result[key];
|
||||
});
|
||||
}
|
||||
return response;
|
||||
return sanitizeDatabaseResult(originalUpdate, result);
|
||||
});
|
||||
};
|
||||
|
||||
function sanitizeDatabaseResult(originalObject, result) {
|
||||
let response = {};
|
||||
if (!result) {
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
Object.keys(originalObject).forEach(key => {
|
||||
let keyUpdate = originalObject[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 Promise.resolve(response);
|
||||
}
|
||||
|
||||
// Processes relation-updating operations from a REST-format update.
|
||||
// Returns a promise that resolves successfully when these are
|
||||
// processed.
|
||||
@@ -313,6 +324,7 @@ DatabaseController.prototype.destroy = function(className, query, options = {})
|
||||
// Returns a promise that resolves successfully iff the object saved.
|
||||
DatabaseController.prototype.create = function(className, object, options) {
|
||||
// Make a copy of the object, so we don't mutate the incoming data.
|
||||
let originalObject = object;
|
||||
object = deepcopy(object);
|
||||
|
||||
var schema;
|
||||
@@ -333,6 +345,9 @@ DatabaseController.prototype.create = function(className, object, options) {
|
||||
.then(coll => {
|
||||
var mongoObject = transform.transformCreate(schema, className, object);
|
||||
return coll.insertOne(mongoObject);
|
||||
})
|
||||
.then(result => {
|
||||
return sanitizeDatabaseResult(originalObject, result.ops[0]);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -474,7 +489,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};
|
||||
}
|
||||
|
||||
@@ -712,6 +712,12 @@ RestWrite.prototype.runDatabaseOperation = function() {
|
||||
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
|
||||
};
|
||||
@@ -726,13 +732,16 @@ RestWrite.prototype.runDatabaseOperation = function() {
|
||||
}
|
||||
// Run a create
|
||||
return this.config.database.create(this.className, this.data, this.runOptions)
|
||||
.then(() => {
|
||||
var resp = {
|
||||
.then((resp) => {
|
||||
Object.assign(resp, {
|
||||
objectId: this.data.objectId,
|
||||
createdAt: this.data.createdAt
|
||||
};
|
||||
});
|
||||
if (this.storage['changedByTrigger']) {
|
||||
Object.assign(resp, this.data);
|
||||
resp = Object.keys(this.data).reduce((memo, key) => {
|
||||
memo[key] = resp[key] || this.data[key];
|
||||
return memo;
|
||||
}, resp);
|
||||
}
|
||||
if (this.storage['token']) {
|
||||
resp.sessionToken = this.storage['token'];
|
||||
|
||||
Reference in New Issue
Block a user