diff --git a/integration/test/ParseObjectTest.js b/integration/test/ParseObjectTest.js index 24285663c..e04c0ffdb 100644 --- a/integration/test/ParseObjectTest.js +++ b/integration/test/ParseObjectTest.js @@ -1774,4 +1774,55 @@ describe('Parse Object', () => { const fetched = await query.get(user.id); assert.equal(fetched.isDataAvailable(), true); }); + + it('retrieve subclass objects', async (done) => { + try { + class MySubclass extends Parse.Object { + constructor(attr) { + super('MySubclass', attr); + this.defaultProp = attr && attr.defaultProp || 'default'; + } + get defaultProp() { return this.get('defaultProp'); } + set defaultProp(val) { this.set('defaultProp', val); } + } + Parse.Object.registerSubclass('MySubclass', MySubclass); + + await new MySubclass({defaultProp: 'foo'}).save(); + const result = await new Parse.Query(MySubclass).first(); + expect(result.defaultProp).toBe('foo'); + + done(); + } catch(e) { + done.fail(e); + } + }); + + it('conver from JSON', async (done) => { + try { + + // Object without constructor + const o = Parse.Object.fromJSON({ + className: 'FooObject', + name: 'foo' + }, true); + + await o.save(); + let result = await new Parse.Query('FooObject').first(); + expect(result.get('name')).toBe('foo'); + + // Object with constructor `TestObject` + const to = Parse.Object.fromJSON({ + className: 'TestObject', + name: 'foo' + }, true); + + await to.save(); + result = await new Parse.Query('TestObject').first(); + expect(result.get('name')).toBe('foo'); + + done(); + } catch(e) { + done.fail(e); + } + }); }); diff --git a/integration/test/helper.js b/integration/test/helper.js index df4355669..6cadddf7d 100644 --- a/integration/test/helper.js +++ b/integration/test/helper.js @@ -1,6 +1,6 @@ const ParseServer = require('parse-server').ParseServer; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; beforeAll((done) => { const { app } = require('../server'); const httpServer = require('http').createServer(app); diff --git a/src/ParseObject.js b/src/ParseObject.js index 3ae07cc78..eac833bef 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -1741,8 +1741,23 @@ class ParseObject { if (!json.className) { throw new Error('Cannot create an object without a className'); } + const constructor = classMap[json.className]; - const o = constructor ? new constructor() : new ParseObject(json.className); + + // Remove reserved fields + const attributes = {} + Object.assign({}, json); + if(constructor && constructor.readOnlyAttributes) { + constructor.readOnlyAttributes().forEach(attr => { + try { delete attributes[attr]; } + catch { 0; } + }); + } + if(attributes && attributes.__type) delete attributes.__type; + if(attributes && attributes.className) delete attributes.className; + + const o = constructor ? new constructor(attributes) : new ParseObject(json.className, attributes); + const otherAttributes = {}; for (const attr in json) { if (attr !== 'className' && attr !== '__type') {