diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index e60b6db491..0a672db17e 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1480,17 +1480,41 @@ describe('Cloud Code', () => { }); it('beforeSave should not sanitize database', async done => { + const { adapter } = Config.get(Parse.applicationId).database; + const spy = spyOn(adapter, 'findOneAndUpdate').and.callThrough(); + spy.calls.saveArgumentsByValue(); + let count = 0; - Parse.Cloud.beforeSave('CloudIncrementNested', () => { + Parse.Cloud.beforeSave('CloudIncrementNested', req => { count += 1; + req.object.set('foo', 'baz'); + expect(typeof req.object.get('objectField').number).toBe('number'); + }); + + Parse.Cloud.afterSave('CloudIncrementNested', req => { + expect(typeof req.object.get('objectField').number).toBe('number'); }); const obj = new Parse.Object('CloudIncrementNested'); obj.set('objectField', { number: 5 }); + obj.set('foo', 'bar'); await obj.save(); obj.increment('objectField.number', 10); await obj.save(); + + const [ + , + , + , + /* className */ /* schema */ /* query */ update, + ] = adapter.findOneAndUpdate.calls.first().args; + expect(update).toEqual({ + 'objectField.number': { __op: 'Increment', amount: 10 }, + foo: 'baz', + updatedAt: obj.updatedAt.toISOString(), + }); + count === 2 ? done() : fail(); }); diff --git a/src/RestWrite.js b/src/RestWrite.js index 9467c6a2d1..38b318100c 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -1558,15 +1558,19 @@ RestWrite.prototype.buildUpdatedObject = function (extraData) { const updatedObject = triggers.inflate(extraData, this.originalData); Object.keys(this.data).reduce(function (data, key) { if (key.indexOf('.') > 0) { - // subdocument key with dot notation ('x.y':v => 'x':{'y':v}) - const splittedKey = key.split('.'); - const parentProp = splittedKey[0]; - let parentVal = updatedObject.get(parentProp); - if (typeof parentVal !== 'object') { - parentVal = {}; + if (typeof data[key].__op === 'string') { + updatedObject.set(key, data[key]); + } else { + // subdocument key with dot notation { 'x.y': v } => { 'x': { 'y' : v } }) + const splittedKey = key.split('.'); + const parentProp = splittedKey[0]; + let parentVal = updatedObject.get(parentProp); + if (typeof parentVal !== 'object') { + parentVal = {}; + } + parentVal[splittedKey[1]] = data[key]; + updatedObject.set(parentProp, parentVal); } - parentVal[splittedKey[1]] = data[key]; - updatedObject.set(parentProp, parentVal); delete data[key]; } return data;