Refactor cloud code tests (#1837)

* Move cloud code tests

* Remove _removeHook calls that are no longer necessary

* Use Strict
This commit is contained in:
Drew
2016-05-19 13:38:16 -07:00
committed by Tyler Brock
parent fece2a4b47
commit b2183680be
13 changed files with 496 additions and 514 deletions

470
spec/CloudCode.spec.js Normal file
View File

@@ -0,0 +1,470 @@
"use strict"
const Parse = require("parse/node");
describe('Cloud Code', () => {
it('can load absolute cloud code file', done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
masterKey: 'test',
cloud: __dirname + '/cloud/cloudCodeRelativeFile.js'
});
Parse.Cloud.run('cloudCodeInFile', {}, result => {
expect(result).toEqual('It is possible to define cloud code in a file.');
done();
});
});
it('can load relative cloud code file', done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
masterKey: 'test',
cloud: './spec/cloud/cloudCodeAbsoluteFile.js'
});
Parse.Cloud.run('cloudCodeInFile', {}, result => {
expect(result).toEqual('It is possible to define cloud code in a file.');
done();
});
});
it('can create functions', done => {
Parse.Cloud.define('hello', (req, res) => {
res.success('Hello world!');
});
Parse.Cloud.run('hello', {}, result => {
expect(result).toEqual('Hello world!');
done();
});
});
it('is cleared cleared after the previous test', done => {
Parse.Cloud.run('hello', {})
.catch(error => {
expect(error.code).toEqual(141);
done();
});
});
it('basic beforeSave rejection', function(done) {
Parse.Cloud.beforeSave('BeforeSaveFail', function(req, res) {
res.error('You shall not pass!');
});
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();
})
});
it('basic beforeSave rejection via promise', function(done) {
Parse.Cloud.beforeSave('BeforeSaveFailWithPromise', function (req, res) {
var query = new Parse.Query('Yolo');
query.find().then(() => {
res.error('Nope');
}, () => {
res.success();
});
});
var obj = new Parse.Object('BeforeSaveFailWithPromise');
obj.set('foo', 'bar');
obj.save().then(function() {
fail('Should not have been able to save BeforeSaveFailure class.');
done();
}, function(error) {
expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED);
expect(error.message).toEqual('Nope');
done();
})
});
it('test beforeSave changed object success', function(done) {
Parse.Cloud.beforeSave('BeforeSaveChanged', function(req, res) {
req.object.set('foo', 'baz');
res.success();
});
var obj = new Parse.Object('BeforeSaveChanged');
obj.set('foo', 'bar');
obj.save().then(function() {
var query = new Parse.Query('BeforeSaveChanged');
query.get(obj.id).then(function(objAgain) {
expect(objAgain.get('foo')).toEqual('baz');
done();
}, function(error) {
fail(error);
done();
});
}, function(error) {
fail(error);
done();
});
});
it('test beforeSave returns value on create and update', (done) => {
Parse.Cloud.beforeSave('BeforeSaveChanged', function(req, res) {
req.object.set('foo', 'baz');
res.success();
});
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('test afterSave ran and created an object', function(done) {
Parse.Cloud.afterSave('AfterSaveTest', function(req) {
var obj = new Parse.Object('AfterSaveProof');
obj.set('proof', req.object.id);
obj.save();
});
var obj = new Parse.Object('AfterSaveTest');
obj.save();
setTimeout(function() {
var query = new Parse.Query('AfterSaveProof');
query.equalTo('proof', obj.id);
query.find().then(function(results) {
expect(results.length).toEqual(1);
done();
}, function(error) {
fail(error);
done();
});
}, 500);
});
it('test beforeSave happens on update', function(done) {
Parse.Cloud.beforeSave('BeforeSaveChanged', function(req, res) {
req.object.set('foo', 'baz');
res.success();
});
var obj = new Parse.Object('BeforeSaveChanged');
obj.set('foo', 'bar');
obj.save().then(function() {
obj.set('foo', 'bar');
return obj.save();
}).then(function() {
var query = new Parse.Query('BeforeSaveChanged');
return query.get(obj.id).then(function(objAgain) {
expect(objAgain.get('foo')).toEqual('baz');
done();
});
}, function(error) {
fail(error);
done();
});
});
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('basic beforeDelete rejection via promise', function(done) {
Parse.Cloud.beforeSave('BeforeDeleteFailWithPromise', function (req, res) {
var query = new Parse.Query('Yolo');
query.find().then(() => {
res.error('Nope');
}, () => {
res.success();
});
});
var obj = new Parse.Object('BeforeDeleteFailWithPromise');
obj.set('foo', 'bar');
obj.save().then(function() {
fail('Should not have been able to save BeforeSaveFailure class.');
done();
}, function(error) {
expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED);
expect(error.message).toEqual('Nope');
done();
})
});
it('test afterDelete ran and created an object', function(done) {
Parse.Cloud.afterDelete('AfterDeleteTest', function(req) {
var obj = new Parse.Object('AfterDeleteProof');
obj.set('proof', req.object.id);
obj.save();
});
var obj = new Parse.Object('AfterDeleteTest');
obj.save().then(function() {
obj.destroy();
});
setTimeout(function() {
var query = new Parse.Query('AfterDeleteProof');
query.equalTo('proof', obj.id);
query.find().then(function(results) {
expect(results.length).toEqual(1);
done();
}, function(error) {
fail(error);
done();
});
}, 500);
});
it('test cloud function return types', function(done) {
Parse.Cloud.define('foo', function(req, res) {
res.success({
object: {
__type: 'Object',
className: 'Foo',
objectId: '123',
x: 2,
relation: {
__type: 'Object',
className: 'Bar',
objectId: '234',
x: 3
}
},
array: [{
__type: 'Object',
className: 'Bar',
objectId: '345',
x: 2
}],
a: 2
});
});
Parse.Cloud.run('foo').then((result) => {
expect(result.object instanceof Parse.Object).toBeTruthy();
if (!result.object) {
fail("Unable to run foo");
done();
return;
}
expect(result.object.className).toEqual('Foo');
expect(result.object.get('x')).toEqual(2);
var bar = result.object.get('relation');
expect(bar instanceof Parse.Object).toBeTruthy();
expect(bar.className).toEqual('Bar');
expect(bar.get('x')).toEqual(3);
expect(Array.isArray(result.array)).toEqual(true);
expect(result.array[0] instanceof Parse.Object).toBeTruthy();
expect(result.array[0].get('x')).toEqual(2);
done();
});
});
it('test cloud function should echo keys', function(done) {
Parse.Cloud.define('echoKeys', function(req, res){
return res.success({
applicationId: Parse.applicationId,
masterKey: Parse.masterKey,
javascriptKey: Parse.javascriptKey
})
});
Parse.Cloud.run('echoKeys').then((result) => {
expect(result.applicationId).toEqual(Parse.applicationId);
expect(result.masterKey).toEqual(Parse.masterKey);
expect(result.javascriptKey).toEqual(Parse.javascriptKey);
done();
});
});
it('should properly create an object in before save', done => {
Parse.Cloud.beforeSave('BeforeSaveChanged', function(req, res) {
req.object.set('foo', 'baz');
res.success();
});
Parse.Cloud.define('createBeforeSaveChangedObject', function(req, res){
var obj = new Parse.Object('BeforeSaveChanged');
obj.save().then(() => {
res.success(obj);
})
})
Parse.Cloud.run('createBeforeSaveChangedObject').then((res) => {
expect(res.get('foo')).toEqual('baz');
done();
});
});
it('dirtyKeys are set on update', done => {
let triggerTime = 0;
// Register a mock beforeSave hook
Parse.Cloud.beforeSave('GameScore', (req, res) => {
var object = req.object;
expect(object instanceof Parse.Object).toBeTruthy();
expect(object.get('fooAgain')).toEqual('barAgain');
if (triggerTime == 0) {
// Create
expect(object.get('foo')).toEqual('bar');
} else if (triggerTime == 1) {
// Update
expect(object.dirtyKeys()).toEqual(['foo']);
expect(object.dirty('foo')).toBeTruthy();
expect(object.get('foo')).toEqual('baz');
} else {
res.error();
}
triggerTime++;
res.success();
});
let 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();
}, function(error) {
fail(error);
done();
});
});
it('test beforeSave unchanged success', function(done) {
Parse.Cloud.beforeSave('BeforeSaveUnchanged', function(req, res) {
res.success();
});
var obj = new Parse.Object('BeforeSaveUnchanged');
obj.set('foo', 'bar');
obj.save().then(function() {
done();
}, function(error) {
fail(error);
done();
});
});
it('test beforeDelete success', function(done) {
Parse.Cloud.beforeDelete('BeforeDeleteTest', function(req, res) {
res.success();
});
var obj = new Parse.Object('BeforeDeleteTest');
obj.set('foo', 'bar');
obj.save().then(function() {
return obj.destroy();
}).then(function() {
var objAgain = new Parse.Object('BeforeDeleteTest', obj.id);
return objAgain.fetch().then(fail, done);
}, function(error) {
fail(error);
done();
});
});
it('test save triggers get user', function(done) {
Parse.Cloud.beforeSave('SaveTriggerUser', function(req, res) {
if (req.user && req.user.id) {
res.success();
} else {
res.error('No user present on request object for beforeSave.');
}
});
Parse.Cloud.afterSave('SaveTriggerUser', function(req) {
if (!req.user || !req.user.id) {
console.log('No user present on request object for afterSave.');
}
});
var user = new Parse.User();
user.set("password", "asdf");
user.set("email", "asdf@example.com");
user.set("username", "zxcv");
user.signUp(null, {
success: function() {
var obj = new Parse.Object('SaveTriggerUser');
obj.save().then(function() {
done();
}, function(error) {
fail(error);
done();
});
}
});
});
it('beforeSave change propagates through the save response', (done) => {
Parse.Cloud.beforeSave('ChangingObject', function(request, response) {
request.object.set('foo', 'baz');
response.success();
});
let obj = new Parse.Object('ChangingObject');
obj.save({ foo: 'bar' }).then((objAgain) => {
expect(objAgain.get('foo')).toEqual('baz');
done();
}, (e) => {
fail('Should not have failed to save.');
done();
});
});
it('test cloud function parameter validation success', (done) => {
// Register a function with validation
Parse.Cloud.define('functionWithParameterValidation', (req, res) => {
res.success('works');
}, (request) => {
return request.params.success === 100;
});
Parse.Cloud.run('functionWithParameterValidation', {"success":100}).then((s) => {
done();
}, (e) => {
fail('Validation should not have failed.');
done();
});
});
});

View File

@@ -14,7 +14,6 @@ describe("Cloud Code Logger", () => {
}); });
Parse.Cloud.run('loggerTest').then(() => { Parse.Cloud.run('loggerTest').then(() => {
Parse.Cloud._removeHook('Functions', 'logTest');
return logController.getLogs({from: Date.now() - 500, size: 1000}); return logController.getLogs({from: Date.now() - 500, size: 1000});
}).then((res) => { }).then((res) => {
expect(res.length).not.toBe(0); expect(res.length).not.toBe(0);
@@ -42,7 +41,6 @@ describe("Cloud Code Logger", () => {
let obj = new Parse.Object('MyObject'); let obj = new Parse.Object('MyObject');
obj.save().then(() => { obj.save().then(() => {
Parse.Cloud._removeHook('Triggers', 'beforeSave', 'MyObject');
return logController.getLogs({from: Date.now() - 500, size: 1000}) return logController.getLogs({from: Date.now() - 500, size: 1000})
}).then((res) => { }).then((res) => {
expect(res.length).not.toBe(0); expect(res.length).not.toBe(0);

View File

@@ -1182,7 +1182,6 @@ describe('Parse.ACL', () => {
done(); done();
}, error => { }, error => {
expect(error.code).toEqual(Parse.Error.OBJECT_NOT_FOUND); expect(error.code).toEqual(Parse.Error.OBJECT_NOT_FOUND);
Parse.Cloud._removeHook('Triggers', 'afterSave', Parse.User.className);
done(); done();
}); });
}); });

View File

@@ -164,67 +164,6 @@ describe('miscellaneous', function() {
}); });
}); });
it('test cloud function', function(done) {
Parse.Cloud.run('hello', {}, function(result) {
expect(result).toEqual('Hello world!');
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();
})
});
it('basic beforeSave rejection via promise', function(done) {
var obj = new Parse.Object('BeforeSaveFailWithPromise');
obj.set('foo', 'bar');
obj.save().then(function() {
fail('Should not have been able to save BeforeSaveFailure class.');
done();
}, function(error) {
expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED);
expect(error.message).toEqual('Nope');
done();
})
});
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('test beforeSave changed object success', function(done) {
var obj = new Parse.Object('BeforeSaveChanged');
obj.set('foo', 'bar');
obj.save().then(function() {
var query = new Parse.Query('BeforeSaveChanged');
query.get(obj.id).then(function(objAgain) {
expect(objAgain.get('foo')).toEqual('baz');
done();
}, function(error) {
fail(error);
done();
});
}, function(error) {
fail(error);
done();
});
});
it('test beforeSave set object acl success', function(done) { it('test beforeSave set object acl success', function(done) {
var acl = new Parse.ACL({ var acl = new Parse.ACL({
'*': { read: true, write: false } '*': { read: true, write: false }
@@ -237,7 +176,6 @@ describe('miscellaneous', function() {
var obj = new Parse.Object('BeforeSaveAddACL'); var obj = new Parse.Object('BeforeSaveAddACL');
obj.set('lol', true); obj.set('lol', true);
obj.save().then(function() { obj.save().then(function() {
Parse.Cloud._removeHook('Triggers', 'beforeSave', 'BeforeSaveAddACL');
var query = new Parse.Query('BeforeSaveAddACL'); var query = new Parse.Query('BeforeSaveAddACL');
query.get(obj.id).then(function(objAgain) { query.get(obj.id).then(function(objAgain) {
expect(objAgain.get('lol')).toBeTruthy(); expect(objAgain.get('lol')).toBeTruthy();
@@ -253,185 +191,6 @@ describe('miscellaneous', function() {
}); });
}); });
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('test afterSave ran and created an object', function(done) {
var obj = new Parse.Object('AfterSaveTest');
obj.save();
setTimeout(function() {
var query = new Parse.Query('AfterSaveProof');
query.equalTo('proof', obj.id);
query.find().then(function(results) {
expect(results.length).toEqual(1);
done();
}, function(error) {
fail(error);
done();
});
}, 500);
});
it('test beforeSave happens on update', function(done) {
var obj = new Parse.Object('BeforeSaveChanged');
obj.set('foo', 'bar');
obj.save().then(function() {
obj.set('foo', 'bar');
return obj.save();
}).then(function() {
var query = new Parse.Query('BeforeSaveChanged');
return query.get(obj.id).then(function(objAgain) {
expect(objAgain.get('foo')).toEqual('baz');
done();
});
}, function(error) {
fail(error);
done();
});
});
it('test beforeDelete failure', function(done) {
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('basic beforeDelete rejection via promise', function(done) {
var obj = new Parse.Object('BeforeDeleteFailWithPromise');
obj.set('foo', 'bar');
obj.save().then(function() {
fail('Should not have been able to save BeforeSaveFailure class.');
done();
}, function(error) {
expect(error.code).toEqual(Parse.Error.SCRIPT_FAILED);
expect(error.message).toEqual('Nope');
done();
})
});
it('test beforeDelete success', function(done) {
var obj = new Parse.Object('BeforeDeleteTest');
obj.set('foo', 'bar');
obj.save().then(function() {
return obj.destroy();
}).then(function() {
var objAgain = new Parse.Object('BeforeDeleteTest', obj.id);
return objAgain.fetch().then(fail, done);
}, function(error) {
fail(error);
done();
});
});
it('test afterDelete ran and created an object', function(done) {
var obj = new Parse.Object('AfterDeleteTest');
obj.save().then(function() {
obj.destroy();
});
setTimeout(function() {
var query = new Parse.Query('AfterDeleteProof');
query.equalTo('proof', obj.id);
query.find().then(function(results) {
expect(results.length).toEqual(1);
done();
}, function(error) {
fail(error);
done();
});
}, 500);
});
it('test save triggers get user', function(done) {
var user = new Parse.User();
user.set("password", "asdf");
user.set("email", "asdf@example.com");
user.set("username", "zxcv");
user.signUp(null, {
success: function() {
var obj = new Parse.Object('SaveTriggerUser');
obj.save().then(function() {
done();
}, function(error) {
fail(error);
done();
});
}
});
});
it('test cloud function return types', function(done) {
Parse.Cloud.run('foo').then((result) => {
expect(result.object instanceof Parse.Object).toBeTruthy();
if (!result.object) {
fail("Unable to run foo");
done();
return;
}
expect(result.object.className).toEqual('Foo');
expect(result.object.get('x')).toEqual(2);
var bar = result.object.get('relation');
expect(bar instanceof Parse.Object).toBeTruthy();
expect(bar.className).toEqual('Bar');
expect(bar.get('x')).toEqual(3);
expect(Array.isArray(result.array)).toEqual(true);
expect(result.array[0] instanceof Parse.Object).toBeTruthy();
expect(result.array[0].get('x')).toEqual(2);
done();
});
});
it('test cloud function should echo keys', function(done) {
Parse.Cloud.run('echoKeys').then((result) => {
expect(result.applicationId).toEqual(Parse.applicationId);
expect(result.masterKey).toEqual(Parse.masterKey);
expect(result.javascriptKey).toEqual(Parse.javascriptKey);
done();
});
});
it('should properly create an object in before save', (done) => {
Parse.Cloud.run('createBeforeSaveChangedObject').then((res) => {
expect(res.get('foo')).toEqual('baz');
done();
});
})
it('test rest_create_app', function(done) { it('test rest_create_app', function(done) {
var appId; var appId;
Parse._request('POST', 'rest_create_app').then((res) => { Parse._request('POST', 'rest_create_app').then((res) => {
@@ -456,17 +215,6 @@ describe('miscellaneous', function() {
}); });
describe('beforeSave', () => { describe('beforeSave', () => {
beforeEach(done => {
// Make sure the required mock for all tests is unset.
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
done();
});
afterEach(done => {
// Make sure the required mock for all tests is unset.
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
done();
});
it('object is set on create and update', done => { it('object is set on create and update', done => {
let triggerTime = 0; let triggerTime = 0;
// Register a mock beforeSave hook // Register a mock beforeSave hook
@@ -511,45 +259,6 @@ describe('miscellaneous', function() {
}); });
}); });
it('dirtyKeys are set on update', done => {
let triggerTime = 0;
// Register a mock beforeSave hook
Parse.Cloud.beforeSave('GameScore', (req, res) => {
var object = req.object;
expect(object instanceof Parse.Object).toBeTruthy();
expect(object.get('fooAgain')).toEqual('barAgain');
if (triggerTime == 0) {
// Create
expect(object.get('foo')).toEqual('bar');
} else if (triggerTime == 1) {
// Update
expect(object.dirtyKeys()).toEqual(['foo']);
expect(object.dirty('foo')).toBeTruthy();
expect(object.get('foo')).toEqual('baz');
} else {
res.error();
}
triggerTime++;
res.success();
});
let 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();
}, function(error) {
fail(error);
done();
});
});
it('original object is set on update', done => { it('original object is set on update', done => {
let triggerTime = 0; let triggerTime = 0;
// Register a mock beforeSave hook // Register a mock beforeSave hook
@@ -673,7 +382,6 @@ describe('miscellaneous', function() {
return obj.save(); return obj.save();
}).then((obj) => { }).then((obj) => {
expect(obj.get('point').id).toEqual(pointId); expect(obj.get('point').id).toEqual(pointId);
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
done(); done();
}) })
}); });
@@ -711,8 +419,6 @@ describe('miscellaneous', function() {
}).then(function() { }).then(function() {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock beforeSave
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
done(); done();
}, function(error) { }, function(error) {
fail(error); fail(error);
@@ -764,8 +470,6 @@ describe('miscellaneous', function() {
}).then(function() { }).then(function() {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock afterSave
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
done(); done();
}, function(error) { }, function(error) {
console.error(error); console.error(error);
@@ -814,8 +518,6 @@ describe('miscellaneous', function() {
}).then(function() { }).then(function() {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock afterSave
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
done(); done();
}, function(error) { }, function(error) {
console.error(error); console.error(error);
@@ -854,8 +556,6 @@ describe('miscellaneous', function() {
}).then(() => { }).then(() => {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock afterSave
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
done(); done();
}, error => { }, error => {
console.error(error); console.error(error);
@@ -896,8 +596,6 @@ describe('miscellaneous', function() {
}).then(() => { }).then(() => {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock afterSave
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
done(); done();
}, error => { }, error => {
console.error(error); console.error(error);
@@ -938,8 +636,6 @@ describe('miscellaneous', function() {
}).then(() => { }).then(() => {
// Make sure the checking has been triggered // Make sure the checking has been triggered
expect(triggerTime).toBe(2); expect(triggerTime).toBe(2);
// Clear mock afterSave
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
done(); done();
}, error => { }, error => {
console.error(error); console.error(error);
@@ -999,12 +695,10 @@ describe('miscellaneous', function() {
}); });
Parse.Cloud.run('willFail').then((s) => { Parse.Cloud.run('willFail').then((s) => {
fail('Should not have succeeded.'); fail('Should not have succeeded.');
Parse.Cloud._removeHook("Functions", "willFail");
done(); done();
}, (e) => { }, (e) => {
expect(e.code).toEqual(141); expect(e.code).toEqual(141);
expect(e.message).toEqual('noway'); expect(e.message).toEqual('noway');
Parse.Cloud._removeHook("Functions", "willFail");
done(); done();
}); });
}); });
@@ -1036,9 +730,6 @@ describe('miscellaneous', function() {
}, (error, response, body) => { }, (error, response, body) => {
expect(error).toBe(null); expect(error).toBe(null);
expect(triggerTime).toEqual(2); expect(triggerTime).toEqual(2);
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
done(); done();
}); });
}); });
@@ -1075,9 +766,6 @@ describe('miscellaneous', function() {
}, (error, response, body) => { }, (error, response, body) => {
expect(error).toBe(null); expect(error).toBe(null);
expect(triggerTime).toEqual(2); expect(triggerTime).toEqual(2);
Parse.Cloud._removeHook("Triggers", "beforeDelete", "GameScore");
Parse.Cloud._removeHook("Triggers", "afterDelete", "GameScore");
done(); done();
}); });
}); });
@@ -1107,24 +795,6 @@ describe('miscellaneous', function() {
// Make sure query string params override body params // Make sure query string params override body params
expect(res.other).toEqual('2'); expect(res.other).toEqual('2');
expect(res.foo).toEqual("bar"); expect(res.foo).toEqual("bar");
Parse.Cloud._removeHook("Functions",'echoParams');
done();
});
});
it('test cloud function parameter validation success', (done) => {
// Register a function with validation
Parse.Cloud.define('functionWithParameterValidation', (req, res) => {
res.success('works');
}, (request) => {
return request.params.success === 100;
});
Parse.Cloud.run('functionWithParameterValidation', {"success":100}).then((s) => {
Parse.Cloud._removeHook("Functions", "functionWithParameterValidation");
done();
}, (e) => {
fail('Validation should not have failed.');
done(); done();
}); });
}); });
@@ -1139,7 +809,6 @@ describe('miscellaneous', function() {
Parse.Cloud.run('functionWithParameterValidationFailure', {"success":500}).then((s) => { Parse.Cloud.run('functionWithParameterValidationFailure', {"success":500}).then((s) => {
fail('Validation should not have succeeded'); fail('Validation should not have succeeded');
Parse.Cloud._removeHook("Functions", "functionWithParameterValidationFailure");
done(); done();
}, (e) => { }, (e) => {
expect(e.code).toEqual(141); expect(e.code).toEqual(141);
@@ -1156,7 +825,6 @@ describe('miscellaneous', function() {
Parse.Cloud.run('func', {nullParam: null}) Parse.Cloud.run('func', {nullParam: null})
.then(() => { .then(() => {
Parse.Cloud._removeHook('Functions', 'func');
done() done()
}, e => { }, e => {
fail('cloud code call failed'); fail('cloud code call failed');
@@ -1243,23 +911,6 @@ describe('miscellaneous', function() {
}); });
}); });
it('beforeSave change propagates through the save response', (done) => {
Parse.Cloud.beforeSave('ChangingObject', function(request, response) {
request.object.set('foo', 'baz');
response.success();
});
let obj = new Parse.Object('ChangingObject');
obj.save({ foo: 'bar' }).then((objAgain) => {
expect(objAgain.get('foo')).toEqual('baz');
Parse.Cloud._removeHook("Triggers", "beforeSave", "ChangingObject");
done();
}, (e) => {
Parse.Cloud._removeHook("Triggers", "beforeSave", "ChangingObject");
fail('Should not have failed to save.');
done();
});
});
it('dedupes an installation properly and returns updatedAt', (done) => { it('dedupes an installation properly and returns updatedAt', (done) => {
let headers = { let headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -696,20 +696,16 @@ describe('Parse.Relation testing', () => {
admins.first({ useMasterKey: true }) admins.first({ useMasterKey: true })
.then(user => { .then(user => {
if (user) { if (user) {
Parse.Cloud._removeHook('Functions', 'isAdmin');
done(); done();
} else { } else {
Parse.Cloud._removeHook('Functions', 'isAdmin');
fail('Should have found admin user, found nothing instead'); fail('Should have found admin user, found nothing instead');
done(); done();
} }
}, error => { }, error => {
Parse.Cloud._removeHook('Functions', 'isAdmin');
fail('User not admin'); fail('User not admin');
done(); done();
}) })
}, error => { }, error => {
Parse.Cloud._removeHook('Functions', 'isAdmin');
fail('Should have found admin user, errored instead'); fail('Should have found admin user, errored instead');
fail(error); fail(error);
done(); done();

View File

@@ -1156,12 +1156,10 @@ describe('Parse.User testing', () => {
Parse.User._logInWith("facebook", { Parse.User._logInWith("facebook", {
success: function(innerModel) { success: function(innerModel) {
Parse.Cloud._removeHook('Triggers', 'beforeSave', Parse.User.className);
done(); done();
}, },
error: function(model, error) { error: function(model, error) {
ok(undefined, error); ok(undefined, error);
Parse.Cloud._removeHook('Triggers', 'beforeSave', Parse.User.className);
done(); done();
} }
}); });
@@ -1584,8 +1582,6 @@ describe('Parse.User testing', () => {
Parse.User._registerAuthenticationProvider(provider); Parse.User._registerAuthenticationProvider(provider);
Parse.User._logInWith("facebook", { Parse.User._logInWith("facebook", {
success: function(model) { success: function(model) {
Parse.Cloud._removeHook('Triggers', 'beforeSave', Parse.User.className);
Parse.Cloud._removeHook('Triggers', 'afterSave', Parse.User.className);
done(); done();
} }
}); });
@@ -2213,11 +2209,9 @@ describe('Parse.User testing', () => {
}).then((user) => { }).then((user) => {
expect(typeof user).toEqual('object'); expect(typeof user).toEqual('object');
expect(user.authData).toBeUndefined(); expect(user.authData).toBeUndefined();
Parse.Cloud._removeHook('Triggers', 'beforeSave', '_User');
done(); done();
}).catch((err) => { }).catch((err) => {
fail('no request should fail: ' + JSON.stringify(err)); fail('no request should fail: ' + JSON.stringify(err));
Parse.Cloud._removeHook('Triggers', 'beforeSave', '_User');
done(); done();
}); });
}); });
@@ -2237,7 +2231,6 @@ describe('Parse.User testing', () => {
user.set('hello', 'world'); user.set('hello', 'world');
return user.save(); return user.save();
}).then(() => { }).then(() => {
Parse.Cloud._removeHook('Triggers', 'afterSave', '_User');
done(); done();
}); });
}); });
@@ -2395,7 +2388,6 @@ describe('Parse.User testing', () => {
serverURL: 'http://localhost:8378/1', serverURL: 'http://localhost:8378/1',
appId: 'test', appId: 'test',
masterKey: 'test', masterKey: 'test',
cloud: './spec/cloud/main.js',
revokeSessionOnPasswordReset: false, revokeSessionOnPasswordReset: false,
}) })
request.post({ request.post({

View File

@@ -0,0 +1,3 @@
Parse.Cloud.define('cloudCodeInFile', (req, res) => {
res.success('It is possible to define cloud code in a file.');
});

View File

@@ -0,0 +1,3 @@
Parse.Cloud.define('cloudCodeInFile', (req, res) => {
res.success('It is possible to define cloud code in a file.');
});

View File

@@ -1,117 +0,0 @@
Parse.Cloud.define('hello', function(req, res) {
res.success('Hello world!');
});
Parse.Cloud.beforeSave('BeforeSaveFail', function(req, res) {
res.error('You shall not pass!');
});
Parse.Cloud.beforeSave('BeforeSaveFailWithPromise', function (req, res) {
var query = new Parse.Query('Yolo');
query.find().then(() => {
res.error('Nope');
}, () => {
res.success();
});
});
Parse.Cloud.beforeSave('BeforeSaveUnchanged', function(req, res) {
res.success();
});
Parse.Cloud.beforeSave('BeforeSaveChanged', function(req, res) {
req.object.set('foo', 'baz');
res.success();
});
Parse.Cloud.afterSave('AfterSaveTest', function(req) {
var obj = new Parse.Object('AfterSaveProof');
obj.set('proof', req.object.id);
obj.save();
});
Parse.Cloud.beforeDelete('BeforeDeleteFail', function(req, res) {
res.error('Nope');
});
Parse.Cloud.beforeSave('BeforeDeleteFailWithPromise', function (req, res) {
var query = new Parse.Query('Yolo');
query.find().then(() => {
res.error('Nope');
}, () => {
res.success();
});
});
Parse.Cloud.beforeDelete('BeforeDeleteTest', function(req, res) {
res.success();
});
Parse.Cloud.afterDelete('AfterDeleteTest', function(req) {
var obj = new Parse.Object('AfterDeleteProof');
obj.set('proof', req.object.id);
obj.save();
});
Parse.Cloud.beforeSave('SaveTriggerUser', function(req, res) {
if (req.user && req.user.id) {
res.success();
} else {
res.error('No user present on request object for beforeSave.');
}
});
Parse.Cloud.afterSave('SaveTriggerUser', function(req) {
if (!req.user || !req.user.id) {
console.log('No user present on request object for afterSave.');
}
});
Parse.Cloud.define('foo', function(req, res) {
res.success({
object: {
__type: 'Object',
className: 'Foo',
objectId: '123',
x: 2,
relation: {
__type: 'Object',
className: 'Bar',
objectId: '234',
x: 3
}
},
array: [{
__type: 'Object',
className: 'Bar',
objectId: '345',
x: 2
}],
a: 2
});
});
Parse.Cloud.define('bar', function(req, res) {
res.error('baz');
});
Parse.Cloud.define('requiredParameterCheck', function(req, res) {
res.success();
}, function(params) {
return params.name;
});
Parse.Cloud.define('echoKeys', function(req, res){
return res.success({
applicationId: Parse.applicationId,
masterKey: Parse.masterKey,
javascriptKey: Parse.javascriptKey
})
});
Parse.Cloud.define('createBeforeSaveChangedObject', function(req, res){
var obj = new Parse.Object('BeforeSaveChanged');
obj.save().then(() => {
res.success(obj);
})
})

View File

@@ -12,13 +12,11 @@ var TestUtils = require('../src/index').TestUtils;
var MongoStorageAdapter = require('../src/Adapters/Storage/Mongo/MongoStorageAdapter'); var MongoStorageAdapter = require('../src/Adapters/Storage/Mongo/MongoStorageAdapter');
var databaseURI = process.env.DATABASE_URI; var databaseURI = process.env.DATABASE_URI;
var cloudMain = process.env.CLOUD_CODE_MAIN || './spec/cloud/main.js';
var port = 8378; var port = 8378;
// Default server configuration for tests. // Default server configuration for tests.
var defaultConfiguration = { var defaultConfiguration = {
databaseURI: databaseURI, databaseURI: databaseURI,
cloud: cloudMain,
serverURL: 'http://localhost:' + port + '/1', serverURL: 'http://localhost:' + port + '/1',
appId: 'test', appId: 'test',
javascriptKey: 'test', javascriptKey: 'test',
@@ -94,6 +92,7 @@ var mongoAdapter = new MongoStorageAdapter({
}) })
afterEach(function(done) { afterEach(function(done) {
Parse.Cloud._removeAllHooks();
mongoAdapter.getAllSchemas() mongoAdapter.getAllSchemas()
.then(allSchemas => { .then(allSchemas => {
allSchemas.forEach((schema) => { allSchemas.forEach((schema) => {

View File

@@ -12,7 +12,7 @@ describe('server', () => {
expect(setServerConfiguration.bind(undefined, { appId: 'myId', masterKey: 'mk' })).toThrow('You must provide a serverURL!'); expect(setServerConfiguration.bind(undefined, { appId: 'myId', masterKey: 'mk' })).toThrow('You must provide a serverURL!');
done(); done();
}); });
it('support http basic authentication with masterkey', done => { it('support http basic authentication with masterkey', done => {
request.get({ request.get({
url: 'http://localhost:8378/1/classes/TestObject', url: 'http://localhost:8378/1/classes/TestObject',
@@ -24,7 +24,7 @@ describe('server', () => {
done(); done();
}); });
}); });
it('support http basic authentication with javascriptKey', done => { it('support http basic authentication with javascriptKey', done => {
request.get({ request.get({
url: 'http://localhost:8378/1/classes/TestObject', url: 'http://localhost:8378/1/classes/TestObject',
@@ -199,26 +199,6 @@ describe('server', () => {
}) })
}); });
it('can load absolute cloud code file', done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
masterKey: 'test',
cloud: __dirname + '/cloud/main.js'
});
done();
});
it('can load relative cloud code file', done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
masterKey: 'test',
cloud: './spec/cloud/main.js'
});
done();
});
it('can create a parse-server', done => { it('can create a parse-server', done => {
var parseServer = new ParseServer.default({ var parseServer = new ParseServer.default({
appId: "aTestApp", appId: "aTestApp",

View File

@@ -1,4 +1,4 @@
import { Parse } from 'parse/node'; import { Parse } from 'parse/node';
import * as triggers from '../triggers'; import * as triggers from '../triggers';
function validateClassNameForTriggers(className) { function validateClassNameForTriggers(className) {
@@ -40,12 +40,16 @@ ParseCloud.afterDelete = function(parseClass, handler) {
var className = getClassName(parseClass); var className = getClassName(parseClass);
triggers.addTrigger(triggers.Types.afterDelete, className, handler, Parse.applicationId); triggers.addTrigger(triggers.Types.afterDelete, className, handler, Parse.applicationId);
}; };
ParseCloud._removeHook = function(category, name, type, applicationId) { ParseCloud._removeHook = function(category, name, type, applicationId) {
applicationId = applicationId || Parse.applicationId; applicationId = applicationId || Parse.applicationId;
triggers._unregister(applicationId, category, name, type); triggers._unregister(applicationId, category, name, type);
}; };
ParseCloud._removeAllHooks = () => {
triggers._unregisterAll();
}
ParseCloud.httpRequest = require("./httpRequest"); ParseCloud.httpRequest = require("./httpRequest");
module.exports = ParseCloud; module.exports = ParseCloud;

View File

@@ -1,6 +1,6 @@
// triggers.js // triggers.js
import Parse from 'parse/node'; import Parse from 'parse/node';
import AppCache from './cache'; import AppCache from './cache';
export const Types = { export const Types = {
beforeSave: 'beforeSave', beforeSave: 'beforeSave',
@@ -49,15 +49,19 @@ export function removeTrigger(type, className, applicationId) {
delete _triggerStore[applicationId].Triggers[type][className] delete _triggerStore[applicationId].Triggers[type][className]
} }
export function _unregister(a,b,c,d) { export function _unregister(appId,category,className,type) {
if (d) { if (type) {
removeTrigger(c,d,a); removeTrigger(className,type,appId);
delete _triggerStore[a][b][c][d]; delete _triggerStore[appId][category][className][type];
} else { } else {
delete _triggerStore[a][b][c]; delete _triggerStore[appId][category][className];
} }
} }
export function _unregisterAll() {
Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]);
}
export function getTrigger(className, triggerType, applicationId) { export function getTrigger(className, triggerType, applicationId) {
if (!applicationId) { if (!applicationId) {
throw "Missing ApplicationID"; throw "Missing ApplicationID";