it('ignores _RevocableSession "header" send by JS SDK', (done) => { const object = new Parse.Object('AnObject'); object.set('a', 'b'); object.save().then(() => { request.post({ headers: {'Content-Type': 'application/json'}, url: 'http://localhost:8378/1/classes/AnObject', body: { _method: 'GET', _ApplicationId: 'test', _JavaScriptKey: 'test', _ClientVersion: 'js1.8.3', _InstallationId: 'iid', _RevocableSession: "1", }, json: true }, (err, res, body) => { expect(body.error).toBeUndefined(); expect(body.results).not.toBeUndefined(); expect(body.results.length).toBe(1); const result = body.results[0]; expect(result.a).toBe('b'); done(); }) }); });
it('can handle object delete command which matches some subscriptions', function(done) { const parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {}); // Make deletedParseObject const parseObject = new Parse.Object(testClassName); parseObject._finishFetch({ key: 'value', className: testClassName }); // Make mock message const message = { currentParseObject: parseObject }; // Add mock client const clientId = 1; addMockClient(parseLiveQueryServer, clientId); // Add mock subscription const requestId = 2; addMockSubscription(parseLiveQueryServer, clientId, requestId); const client = parseLiveQueryServer.clients.get(clientId); // Mock _matchesSubscription to return matching parseLiveQueryServer._matchesSubscription = function() { return true; }; parseLiveQueryServer._matchesACL = function() { return Parse.Promise.as(true); }; parseLiveQueryServer._onAfterDelete(message); // Make sure we send command to client, since _matchesACL is async, we have to // wait and check setTimeout(function() { expect(client.pushDelete).toHaveBeenCalled(); done(); }, jasmine.ASYNC_TEST_WAIT_TIME); });
it('test beforeSave set object acl success', function(done) { const acl = new Parse.ACL({ '*': { read: true, write: false } }); Parse.Cloud.beforeSave('BeforeSaveAddACL', function(req, res) { req.object.setACL(acl); res.success(); }); const obj = new Parse.Object('BeforeSaveAddACL'); obj.set('lol', true); obj.save().then(function() { const query = new Parse.Query('BeforeSaveAddACL'); query.get(obj.id).then(function(objAgain) { expect(objAgain.get('lol')).toBeTruthy(); expect(objAgain.getACL().equals(acl)); done(); }, function(error) { fail(error); done(); }); }, error => { fail(JSON.stringify(error)); done(); }); });
it('pointer reassign is working properly (#1288)', (done) => { Parse.Cloud.beforeSave('GameScore', (req, res) => { const obj = req.object; if (obj.get('point')) { return res.success(); } const TestObject1 = Parse.Object.extend('TestObject1'); const newObj = new TestObject1({'key1': 1}); return newObj.save().then((newObj) => { obj.set('point' , newObj); res.success(); }); }); let pointId; const obj = new Parse.Object('GameScore'); obj.set('foo', 'bar'); obj.save().then(() => { expect(obj.get('point')).not.toBeUndefined(); pointId = obj.get('point').id; expect(pointId).not.toBeUndefined(); obj.set('foo', 'baz'); return obj.save(); }).then((obj) => { expect(obj.get('point').id).toEqual(pointId); done(); }) });
it_exclude_dbs(['postgres'])('should fully delete objects when using `unset` with beforeSave (regression test for #1840)', done => { var TestObject = Parse.Object.extend('TestObject'); var BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); Parse.Cloud.beforeSave('BeforeSaveChanged', (req, res) => { var object = req.object; object.set('before', 'save'); object.unset('remove'); res.success(); }); let object; let testObject = new TestObject({key: 'value'}); testObject.save().then(() => { object = new BeforeSaveObject(); return object.save().then(() => { object.set({remove:testObject}) return object.save(); }); }).then((objectAgain) => { expect(objectAgain.get('remove')).toBeUndefined(); expect(object.get('remove')).toBeUndefined(); done(); }).fail((err) => { console.error(err); done(); }) });
it('gets relation fields', (done) => { const object = new Parse.Object('AnObject'); const relatedObject = new Parse.Object('RelatedObject'); Parse.Object.saveAll([object, relatedObject]).then(() => { object.relation('related').add(relatedObject); return object.save(); }).then(() => { const headers = { 'Content-Type': 'application/json', 'X-Parse-Application-Id': 'test', 'X-Parse-REST-API-Key': 'rest' }; const requestOptions = { headers: headers, url: 'http://localhost:8378/1/classes/AnObject', json: true }; request.get(requestOptions, (err, res, body) => { expect(body.results.length).toBe(1); const result = body.results[0]; expect(result.related).toEqual({ __type: "Relation", className: 'RelatedObject' }) done(); }); }).catch((err) => { jfail(err); done(); }) });
it('should not update schema beforeSave #2672', (done) => { Parse.Cloud.beforeSave('MyObject', (request, response) => { if (request.object.get('secret')) { response.error('cannot set secret here'); return; } response.success(); }); const object = new Parse.Object('MyObject'); object.set('key', 'value'); object.save().then(() => { return object.save({'secret': 'should not update schema'}); }).then(() => { fail(); done(); }, () => { return rp({ method: 'GET', headers: { 'X-Parse-Application-Id': 'test', 'X-Parse-Master-Key': 'test' }, uri: 'http://localhost:8378/1/schemas/MyObject', json: true }); }).then((res) => { const fields = res.fields; expect(fields.secret).toBeUndefined(); done(); }, (err) => { jfail(err); done(); }); });
obj.save().then(() => { expect(obj.get('point')).not.toBeUndefined(); pointId = obj.get('point').id; expect(pointId).not.toBeUndefined(); obj.set('foo', 'baz'); return obj.save(); }).then((obj) => {
}, (error) => { expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED); expect(error.message).toEqual('Nope'); var objAgain = new Parse.Object('BeforeDeleteFail', {objectId: id}); return objAgain.fetch(); }).then((objAgain) => {
it('can handle object delete command which does not match any subscription', function() { const parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {}); // Make deletedParseObject const parseObject = new Parse.Object(testClassName); parseObject._finishFetch({ key: 'value', className: testClassName }); // Make mock message const message = { currentParseObject: parseObject }; // Add mock client const clientId = 1; addMockClient(parseLiveQueryServer, clientId); // Add mock subscription const requestId = 2; addMockSubscription(parseLiveQueryServer, clientId, requestId); const client = parseLiveQueryServer.clients.get(clientId); // Mock _matchesSubscription to return not matching parseLiveQueryServer._matchesSubscription = function() { return false; }; parseLiveQueryServer._matchesACL = function() { return true; }; parseLiveQueryServer._onAfterDelete(message); // Make sure we do not send command to client expect(client.pushDelete).not.toHaveBeenCalled(); });
it('test beforeDelete failure', function(done) { Parse.Cloud.beforeDelete('BeforeDeleteFail', function(req, res) { res.error('Nope'); }); var obj = new Parse.Object('BeforeDeleteFail'); var id; obj.set('foo', 'bar'); obj.save().then(() => { id = obj.id; return obj.destroy(); }).then(() => { fail('obj.destroy() should have failed, but it succeeded'); done(); }, (error) => { expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED); expect(error.message).toEqual('Nope'); var objAgain = new Parse.Object('BeforeDeleteFail', {objectId: id}); return objAgain.fetch(); }).then((objAgain) => { if (objAgain) { expect(objAgain.get('foo')).toEqual('bar'); } else { fail("unable to fetch the object ", id); } done(); }, (error) => { // We should have been able to fetch the object again fail(error); }); });
it('pointer reassign is working properly (#1288)', (done) => { Parse.Cloud.beforeSave('GameScore', (req, res) => { var obj = req.object; if (obj.get('point')) { return res.success(); } var TestObject1 = Parse.Object.extend('TestObject1'); var newObj = new TestObject1({'key1': 1}); return newObj.save().then((newObj) => { obj.set('point' , newObj); res.success(); }); }); var pointId; var obj = new Parse.Object('GameScore'); obj.set('foo', 'bar'); obj.save().then(() => { expect(obj.get('point')).not.toBeUndefined(); pointId = obj.get('point').id; expect(pointId).not.toBeUndefined(); obj.set('foo', 'baz'); return obj.save(); }).then((obj) => { expect(obj.get('point').id).toEqual(pointId); Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore"); done(); }) });
it('purge all objects in class', (done) => { const object = new Parse.Object('TestObject'); object.set('foo', 'bar'); const object2 = new Parse.Object('TestObject'); object2.set('alice', 'wonderland'); Parse.Object.saveAll([object, object2]) .then(() => { const query = new Parse.Query(TestObject); return query.count() }).then((count) => { expect(count).toBe(2); const headers = { 'Content-Type': 'application/json', 'X-Parse-Application-Id': 'test', 'X-Parse-Master-Key': 'test' }; request.del({ headers: headers, url: 'http://localhost:8378/1/purge/TestObject', json: true }, (err) => { expect(err).toBe(null); const query = new Parse.Query(TestObject); return query.count().then((count) => { expect(count).toBe(0); done(); }); }); }); });
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(); }); });
obj.save().then(() => { expect(obj.get('foo')).toEqual('baz'); obj.set('foo', 'bar'); return obj.save().then(() => { expect(obj.get('foo')).toEqual('baz'); done(); }) })
success: function() { var obj = new Parse.Object('SaveTriggerUser'); obj.save().then(function() { done(); }, function(error) { fail(error); done(); }); }
it('create a GameScore object', function(done) { var obj = new Parse.Object('GameScore'); obj.set('score', 1337); obj.save().then(function(obj) { expect(typeof obj.id).toBe('string'); expect(typeof obj.createdAt.toGMTString()).toBe('string'); done(); }, function(err) { console.log(err); }); });
Parse._request('POST', 'rest_create_app').then((res) => { expect(typeof res.application_id).toEqual('string'); expect(res.master_key).toEqual('master'); appId = res.application_id; Parse.initialize(appId, 'unused'); const obj = new Parse.Object('TestObject'); obj.set('foo', 'bar'); return obj.save(); }).then(() => {
it('import relations object from file', (done) => { const headers = { 'Content-Type': 'multipart/form-data', 'X-Parse-Application-Id': 'test', 'X-Parse-Master-Key': 'test' }; const object = new Parse.Object('TestObjectDad'); const relatedObject = new Parse.Object('TestObjectChild'); const ids = {}; Parse.Object.saveAll([object, relatedObject]).then(() => { object.relation('RelationObject').add(relatedObject); return object.save(); }) .then(() => { object.set('Name', 'namea'); return object.save(); }) .then((savedObj) => { ids.a = savedObj.id; relatedObject.set('Name', 'nameb'); return relatedObject.save(); }) .then((savedObj) => { ids.b = savedObj.id; request.post( { headers: headers, url: 'http://localhost:8378/1/import_relation_data/TestObjectDad/RelationObject', formData: { importFile: { value: Buffer.from(JSON.stringify({ results: [ { 'owningId': ids.a, 'relatedId': ids.b } ] })), options: { filename: 'TestObject:RelationObject.json' } } } }, (err) => { expect(err).toBe(null); object.relation('RelationObject').query().find().then((results) => { expect(results.length).toEqual(1); expect(results[0].id).toEqual(ids.b); done(); }); } ) }); });
it('basic beforeSave rejection', function(done) { var obj = new Parse.Object('BeforeSaveFail'); obj.set('foo', 'bar'); obj.save().then(() => { fail('Should not have been able to save BeforeSaveFailure class.'); done(); }, () => { done(); }) });
.then(f => { const obj = new Parse.Object('O'); obj.set('fileField', f); obj.set('geoField', new Parse.GeoPoint(0, 0)); obj.set('innerObj', { fileField: "data", geoField: [1,2], }); return obj.save(); })
it('test beforeSave unchanged success', function(done) { var obj = new Parse.Object('BeforeSaveUnchanged'); obj.set('foo', 'bar'); obj.save().then(function() { done(); }, function(error) { fail(error); done(); }); });
it_exclude_dbs(['postgres'])('should fully delete objects when using `unset` with beforeSave (regression test for #1840)', done => { var TestObject = Parse.Object.extend('TestObject'); var NoBeforeSaveObject = Parse.Object.extend('NoBeforeSave'); var BeforeSaveObject = Parse.Object.extend('BeforeSaveChanged'); Parse.Cloud.beforeSave('BeforeSaveChanged', (req, res) => { var object = req.object; object.set('before', 'save'); res.success(); }); Parse.Cloud.define('removeme', (req, res) => { var testObject = new TestObject(); testObject.save() .then(testObject => { var object = new NoBeforeSaveObject({remove: testObject}); return object.save(); }) .then(object => { object.unset('remove'); return object.save(); }) .then(object => { res.success(object); }); }); Parse.Cloud.define('removeme2', (req, res) => { var testObject = new TestObject(); testObject.save() .then(testObject => { var object = new BeforeSaveObject({remove: testObject}); return object.save(); }) .then(object => { object.unset('remove'); return object.save(); }) .then(object => { res.success(object); }); }); Parse.Cloud.run('removeme') .then(aNoBeforeSaveObj => { expect(aNoBeforeSaveObj.get('remove')).toEqual(undefined); return Parse.Cloud.run('removeme2'); }) .then(aBeforeSaveObj => { expect(aBeforeSaveObj.get('before')).toEqual('save'); expect(aBeforeSaveObj.get('remove')).toEqual(undefined); done(); }); });
it('doesnt convert interior keys of objects that use special names', done => { const obj = new Parse.Object('Obj'); obj.set('val', { createdAt: 'a', updatedAt: 1 }); obj.save() .then(obj => new Parse.Query('Obj').get(obj.id)) .then(obj => { expect(obj.get('val').createdAt).toEqual('a'); expect(obj.get('val').updatedAt).toEqual(1); done(); }); });
}).then((x) => { expect(x.id).toEqual(user.id); object = new Parse.Object('TestObject'); const acl = new Parse.ACL(); acl.setPublicReadAccess(false); acl.setPublicWriteAccess(false); acl.setRoleReadAccess('TestRole', true); acl.setRoleWriteAccess('TestRole', true); object.setACL(acl); return object.save(); }).then(() => {
it('test afterSave get original object on update', function(done) { var triggerTime = 0; // Register a mock beforeSave hook Parse.Cloud.afterSave('GameScore', function(req, res) { var object = req.object; expect(object instanceof Parse.Object).toBeTruthy(); expect(object.get('fooAgain')).toEqual('barAgain'); expect(object.id).not.toBeUndefined(); expect(object.createdAt).not.toBeUndefined(); expect(object.updatedAt).not.toBeUndefined(); var originalObject = req.original; if (triggerTime == 0) { // Create expect(object.get('foo')).toEqual('bar'); // Check the originalObject is undefined expect(originalObject).toBeUndefined(); } else if (triggerTime == 1) { // Update expect(object.get('foo')).toEqual('baz'); // Check the originalObject expect(originalObject instanceof Parse.Object).toBeTruthy(); expect(originalObject.get('fooAgain')).toEqual('barAgain'); expect(originalObject.id).not.toBeUndefined(); expect(originalObject.createdAt).not.toBeUndefined(); expect(originalObject.updatedAt).not.toBeUndefined(); expect(originalObject.get('foo')).toEqual('bar'); } else { res.error(); } triggerTime++; res.success(); }); var obj = new Parse.Object('GameScore'); obj.set('foo', 'bar'); obj.set('fooAgain', 'barAgain'); obj.save().then(function() { // We only update foo obj.set('foo', 'baz'); return obj.save(); }).then(function() { // Make sure the checking has been triggered expect(triggerTime).toBe(2); // Clear mock afterSave Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore"); done(); }, function(error) { console.error(error); fail(error); done(); }); });
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('original object is set on update', done => { let triggerTime = 0; // Register a mock beforeSave hook Parse.Cloud.beforeSave('GameScore', (req, res) => { const object = req.object; expect(object instanceof Parse.Object).toBeTruthy(); expect(object.get('fooAgain')).toEqual('barAgain'); const originalObject = req.original; if (triggerTime == 0) { // No id/createdAt/updatedAt expect(object.id).toBeUndefined(); expect(object.createdAt).toBeUndefined(); expect(object.updatedAt).toBeUndefined(); // Create expect(object.get('foo')).toEqual('bar'); // Check the originalObject is undefined expect(originalObject).toBeUndefined(); } else if (triggerTime == 1) { // Update expect(object.id).not.toBeUndefined(); expect(object.createdAt).not.toBeUndefined(); expect(object.updatedAt).not.toBeUndefined(); expect(object.get('foo')).toEqual('baz'); // Check the originalObject expect(originalObject instanceof Parse.Object).toBeTruthy(); expect(originalObject.get('fooAgain')).toEqual('barAgain'); expect(originalObject.id).not.toBeUndefined(); expect(originalObject.createdAt).not.toBeUndefined(); expect(originalObject.updatedAt).not.toBeUndefined(); expect(originalObject.get('foo')).toEqual('bar'); } else { res.error(); } triggerTime++; res.success(); }); const obj = new Parse.Object('GameScore'); obj.set('foo', 'bar'); obj.set('fooAgain', 'barAgain'); obj.save().then(() => { // We only update foo obj.set('foo', 'baz'); return obj.save(); }).then(() => { // Make sure the checking has been triggered expect(triggerTime).toBe(2); done(); }, error => { fail(error); done(); }); });
it('create a GameScore object', function(done) { const obj = new Parse.Object('GameScore'); obj.set('score', 1337); obj.save().then(function(obj) { expect(typeof obj.id).toBe('string'); expect(typeof obj.createdAt.toGMTString()).toBe('string'); done(); }, error => { fail(JSON.stringify(error)); done(); }); });
createTestUser().then((x) => { user = x; const acl = new Parse.ACL(); acl.setPublicReadAccess(true); acl.setPublicWriteAccess(false); const role = new Parse.Object('_Role'); role.set('name', 'TestRole'); role.setACL(acl); const users = role.relation('users'); users.add(user); return role.save({}, { useMasterKey: true }); }).then(() => {