async function setup(options) { await reconfigureServer({ appId: Parse.applicationId, masterKey: Parse.masterKey, serverURL: Parse.serverURL, idempotencyOptions: options, }); }
it('should use default configuration when none is set', async () => { await setup({}); expect(Config.get(Parse.applicationId).idempotencyOptions.ttl).toBe(Definitions.IdempotencyOptions.ttl.default); expect(Config.get(Parse.applicationId).idempotencyOptions.paths).toBe(Definitions.IdempotencyOptions.paths.default); });
beforeEach(() => { Config.get(Parse.applicationId).database.schemaCache.clear(); });
it('should not use transactions when using SDK insert', async () => { const databaseAdapter = Config.get(Parse.applicationId).database .adapter; spyOn( databaseAdapter.database.serverConfig, 'insert' ).and.callThrough(); const myObject = new Parse.Object('MyObject'); await myObject.save(); const calls = databaseAdapter.database.serverConfig.insert.calls.all(); expect(calls.length).toBeGreaterThan(0); calls.forEach(call => { expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION'); }); });
it('should fail with invalid pointer perms (not array)', async done => { const config = Config.get(Parse.applicationId); const schema = await config.database.loadSchema(); try { // Lock the delete, and let only owners write await schema.addClassIfNotExists( 'AnObject', { owners: { type: 'Array' } }, { delete: {}, writeUserFields: 'owners' } ); } catch (err) { expect(err.code).toBe(Parse.Error.INVALID_JSON); done(); } });
// Helpers async function deleteRequestEntry(reqId) { const config = Config.get(Parse.applicationId); const res = await rest.find( config, auth.master(config), '_Idempotency', { reqId: reqId }, { limit: 1 } ); await rest.del( config, auth.master(config), '_Idempotency', res.results[0].objectId); }
it('should delete field without index', async () => { const database = Config.get(Parse.applicationId).database; const obj = new Parse.Object('MyObject'); obj.set("test", 1); await obj.save(); const schemaBeforeDeletion = await new Parse.Schema('MyObject').get(); await database.adapter.deleteFields( "MyObject", schemaBeforeDeletion, ["test"] ); const schemaAfterDeletion = await new Parse.Schema('MyObject').get(); expect(schemaBeforeDeletion.fields.test).toBeDefined(); expect(schemaAfterDeletion.fields.test).toBeUndefined(); });
const verifyPassword = function(login, password, isEmail = false) { const body = !isEmail ? { username: login, password } : { email: login, password }; return request({ url: Parse.serverURL + '/verifyPassword', headers: { 'X-Parse-Application-Id': Parse.applicationId, 'X-Parse-REST-API-Key': 'rest', }, qs: body, }) .then(res => res) .catch(err => err); }
it('should re-throw any other error unchanged when writing request entry fails for any other reason', async () => { spyOn(rest, 'create').and.rejectWith(new Parse.Error(0, "some other error")); Parse.Cloud.define('myFunction', () => {}); const params = { method: 'POST', url: 'http://localhost:8378/1/functions/myFunction', headers: { 'X-Parse-Application-Id': Parse.applicationId, 'X-Parse-Master-Key': Parse.masterKey, 'X-Parse-Request-Id': 'abc-123' } }; await request(params).then(fail, e => { expect(e.status).toEqual(400); expect(e.data.error).toEqual("some other error"); }); });
it('should fail with invalid pointer perms (not array)', done => { const config = Config.get(Parse.applicationId); config.database .loadSchema() .then(schema => { // Lock the update, and let only owner write return schema.addClassIfNotExists( 'AnObject', { owner: { type: 'Pointer', targetClass: '_User' } }, { delete: {}, writeUserFields: 'owner' } ); }) .catch(err => { expect(err.code).toBe(Parse.Error.INVALID_JSON); done(); }); });
async function updateCLP(clp) { const config = Config.get(Parse.applicationId); const schemaController = await config.database.loadSchema(); await schemaController.updateClass(className, {}, clp); }
it('should not use transactions when using SDK delete', async () => { const databaseAdapter = Config.get(Parse.applicationId).database .adapter; spyOn( databaseAdapter.database.serverConfig, 'remove' ).and.callThrough(); const myObject = new Parse.Object('MyObject'); await myObject.save(); await myObject.destroy(); const calls = databaseAdapter.database.serverConfig.remove.calls.all(); expect(calls.length).toBeGreaterThan(0); calls.forEach(call => { expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION'); }); });
it('should fail trying to create a malformed function (REST)', done => { request({ method: 'POST', url: Parse.serverURL + '/hooks/functions', headers: { 'X-Parse-Application-Id': Parse.applicationId, 'X-Parse-Master-Key': Parse.masterKey, }, body: JSON.stringify({ functionName: 'SomeFunction' }), }).then(fail, response => { const body = response.data; expect(body.error).toBe('invalid hook declaration'); expect(body.code).toBe(143); done(); }); });
it('should fail with invalid pointer perms (non-existing field)', async done => { const config = Config.get(Parse.applicationId); const schema = await config.database.loadSchema(); try { // Lock the delete, and let only owners write await schema.addClassIfNotExists( 'AnObject', { owners: { type: 'Array' } }, { delete: {}, writeUserFields: ['owners', 'invalid'] } ); } catch (err) { expect(err.code).toBe(Parse.Error.INVALID_JSON); done(); } });
it('should fail with invalid pointer perms (non-existing field)', done => { const config = Config.get(Parse.applicationId); config.database .loadSchema() .then(schema => { // Lock the update, and let only owner write return schema.addClassIfNotExists( 'AnObject', { owner: { type: 'Pointer', targetClass: '_User' } }, { delete: {}, writeUserFields: ['owner', 'invalid'] } ); }) .catch(err => { expect(err.code).toBe(Parse.Error.INVALID_JSON); done(); }); });