diff --git a/integration/test/ParseACLTest.js b/integration/test/ParseACLTest.js index 669f191c7..96b2ade21 100644 --- a/integration/test/ParseACLTest.js +++ b/integration/test/ParseACLTest.js @@ -8,11 +8,10 @@ describe('Parse.ACL', () => { Parse.User.enableUnsafeCurrentUser(); }); - it('can handle invalid acl', () => { + it('acl must be valid', () => { const user = new Parse.User(); - user.setACL(`Ceci n'est pas un ACL.`) - assert.equal(user.getACL(), null); - assert.equal(user.get('ACL'), null); + assert.equal(user.setACL(`Ceci n'est pas un ACL.`), false); + console.log(user.getACL()); }); it('can refresh object with acl', async () => { diff --git a/src/ParseObject.js b/src/ParseObject.js index 047e24be6..ca2c433a6 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -603,10 +603,6 @@ class ParseObject { * @returns {*} */ get(attr: string): mixed { - if (attr === 'ACL') { - const acl = this.attributes[attr]; - return acl instanceof ParseACL ? acl : null; - } return this.attributes[attr]; } @@ -1047,6 +1043,9 @@ class ParseObject { * @see Parse.Object#set */ validate(attrs: AttributeMap): ParseError | boolean { + if (attrs.hasOwnProperty('ACL') && !(attrs.ACL instanceof ParseACL)) { + return new ParseError(ParseError.OTHER_CAUSE, 'ACL must be a Parse ACL.'); + } for (const key in attrs) { if (!/^[A-Za-z][0-9A-Za-z_.]*$/.test(key)) { return new ParseError(ParseError.INVALID_KEY_NAME); @@ -1309,15 +1308,18 @@ class ParseObject { options = arg3; } + options = options || {}; if (attrs) { - const validation = this.validate(attrs); - if (validation) { - return Promise.reject(validation); + let validationError; + options.error = (_, validation) => { + validationError = validation; + }; + const success = this.set(attrs, options); + if (!success) { + return Promise.reject(validationError); } - this.set(attrs, options); } - options = options || {}; const saveOptions = {}; if (options.hasOwnProperty('useMasterKey')) { saveOptions.useMasterKey = !!options.useMasterKey; diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 7f529daa8..2066a8979 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -876,6 +876,12 @@ describe('ParseObject', () => { it('can validate attributes', () => { const o = new ParseObject('Listing'); + expect( + o.validate({ + ACL: 'not an acl', + }) + ).toEqual(new ParseError(ParseError.OTHER_CAUSE, 'ACL must be a Parse ACL.')); + expect( o.validate({ 'invalid!key': 12, @@ -897,6 +903,8 @@ describe('ParseObject', () => { it('validates attributes on set()', () => { const o = new ParseObject('Listing'); + expect(o.set('ACL', 'not an acl')).toBe(false); + expect(o.set('ACL', { '*': { read: true, write: false } })).toBe(o); expect(o.set('$$$', 'o_O')).toBe(false); o.set('$$$', 'o_O', { @@ -907,13 +915,6 @@ describe('ParseObject', () => { }); }); - it('validates attributes on save()', async () => { - const o = new ParseObject('Listing'); - await expect(o.save({ '$$$': 'o_O' })).rejects.toEqual( - new ParseError(ParseError.INVALID_KEY_NAME) - ); - }); - it('ignores validation if ignoreValidation option is passed to set()', () => { const o = new ParseObject('Listing'); expect(o.set('$$$', 'o_O', { ignoreValidation: true })).toBe(o); @@ -1622,21 +1623,27 @@ describe('ParseObject', () => { }); }); - it('accepts attribute changes on save', async () => { + it('accepts attribute changes on save', done => { CoreManager.getRESTController()._setXHR( mockXHR([ - { status: 200, response: { objectId: 'newattributes' } }, - { status: 200, response: { objectId: 'newattributes' } }, + { + status: 200, + response: { objectId: 'newattributes' }, + }, ]) ); let o = new ParseObject('Item'); - await o.save({ key: 'value' }) - expect(o.get('key')).toBe('value'); + o.save({ key: 'value' }) + .then(() => { + expect(o.get('key')).toBe('value'); - o = new ParseObject('Item'); - await o.save({ ACL: 'not an acl' }); - expect(o.getACL()).toBe(null); - expect(o.get('ACL')).toBe(null); + o = new ParseObject('Item'); + return o.save({ ACL: 'not an acl' }); + }) + .then(null, error => { + expect(error.code).toBe(-1); + done(); + }); }); it('accepts context on save', async () => {