Initial release, parse-server, 2.0.0
This commit is contained in:
615
spec/ParseAPI.spec.js
Normal file
615
spec/ParseAPI.spec.js
Normal file
@@ -0,0 +1,615 @@
|
||||
// A bunch of different tests are in here - it isn't very thematic.
|
||||
// It would probably be better to refactor them into different files.
|
||||
|
||||
var DatabaseAdapter = require('../DatabaseAdapter');
|
||||
var request = require('request');
|
||||
|
||||
describe('miscellaneous', function() {
|
||||
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); });
|
||||
});
|
||||
|
||||
it('get a TestObject', function(done) {
|
||||
create({ 'bloop' : 'blarg' }, function(obj) {
|
||||
var t2 = new TestObject({ objectId: obj.id });
|
||||
t2.fetch({
|
||||
success: function(obj2) {
|
||||
expect(obj2.get('bloop')).toEqual('blarg');
|
||||
expect(obj2.id).toBeTruthy();
|
||||
expect(obj2.id).toEqual(obj.id);
|
||||
done();
|
||||
},
|
||||
error: fail
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('create a valid parse user', function(done) {
|
||||
createTestUser(function(data) {
|
||||
expect(data.id).not.toBeUndefined();
|
||||
expect(data.getSessionToken()).not.toBeUndefined();
|
||||
expect(data.get('password')).toBeUndefined();
|
||||
done();
|
||||
}, function(err) {
|
||||
console.log(err);
|
||||
fail(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create a duplicate username', function(done) {
|
||||
createTestUser(function(data) {
|
||||
createTestUser(function(data) {
|
||||
fail('Should not have been able to save duplicate username.');
|
||||
}, function(error) {
|
||||
expect(error.code).toEqual(Parse.Error.USERNAME_TAKEN);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('succeed in logging in', function(done) {
|
||||
createTestUser(function(u) {
|
||||
expect(typeof u.id).toEqual('string');
|
||||
|
||||
Parse.User.logIn('test', 'moon-y', {
|
||||
success: function(user) {
|
||||
expect(typeof user.id).toEqual('string');
|
||||
expect(user.get('password')).toBeUndefined();
|
||||
expect(user.getSessionToken()).not.toBeUndefined();
|
||||
Parse.User.logOut();
|
||||
done();
|
||||
}, error: function(error) {
|
||||
fail(error);
|
||||
}
|
||||
});
|
||||
}, fail);
|
||||
});
|
||||
|
||||
it('increment with a user object', function(done) {
|
||||
createTestUser().then((user) => {
|
||||
user.increment('foo');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('test', 'moon-y');
|
||||
}).then((user) => {
|
||||
expect(user.get('foo')).toEqual(1);
|
||||
user.increment('foo');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
Parse.User.logOut();
|
||||
return Parse.User.logIn('test', 'moon-y');
|
||||
}).then((user) => {
|
||||
expect(user.get('foo')).toEqual(2);
|
||||
Parse.User.logOut();
|
||||
done();
|
||||
}, (error) => {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('save various data types', function(done) {
|
||||
var obj = new TestObject();
|
||||
obj.set('date', new Date());
|
||||
obj.set('array', [1, 2, 3]);
|
||||
obj.set('object', {one: 1, two: 2});
|
||||
obj.save().then(() => {
|
||||
var obj2 = new TestObject({objectId: obj.id});
|
||||
return obj2.fetch();
|
||||
}).then((obj2) => {
|
||||
expect(obj2.get('date') instanceof Date).toBe(true);
|
||||
expect(obj2.get('array') instanceof Array).toBe(true);
|
||||
expect(obj2.get('object') instanceof Array).toBe(false);
|
||||
expect(obj2.get('object') instanceof Object).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('query with limit', function(done) {
|
||||
var baz = new TestObject({ foo: 'baz' });
|
||||
var qux = new TestObject({ foo: 'qux' });
|
||||
baz.save().then(() => {
|
||||
return qux.save();
|
||||
}).then(() => {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.limit(1);
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toEqual(1);
|
||||
done();
|
||||
}, (error) => {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('basic saveAll', function(done) {
|
||||
var alpha = new TestObject({ letter: 'alpha' });
|
||||
var beta = new TestObject({ letter: 'beta' });
|
||||
Parse.Object.saveAll([alpha, beta]).then(() => {
|
||||
expect(alpha.id).toBeTruthy();
|
||||
expect(beta.id).toBeTruthy();
|
||||
return new Parse.Query(TestObject).find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toEqual(2);
|
||||
done();
|
||||
}, (error) => {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
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('BeforeSaveFailure');
|
||||
obj.set('foo', 'bar');
|
||||
obj.save().then(function() {
|
||||
fail('Should not have been able to save BeforeSaveFailure class.');
|
||||
done();
|
||||
}, function(error) {
|
||||
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 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) => {
|
||||
expect(objAgain.get('foo')).toEqual('bar');
|
||||
done();
|
||||
}, (error) => {
|
||||
// We should have been able to fetch the object again
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
|
||||
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();
|
||||
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 rest_create_app', function(done) {
|
||||
var appId;
|
||||
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');
|
||||
var obj = new Parse.Object('TestObject');
|
||||
obj.set('foo', 'bar');
|
||||
return obj.save();
|
||||
}).then(() => {
|
||||
var db = DatabaseAdapter.getDatabaseConnection(appId);
|
||||
return db.mongoFind('TestObject', {}, {});
|
||||
}).then((results) => {
|
||||
expect(results.length).toEqual(1);
|
||||
expect(results[0]['foo']).toEqual('bar');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('test beforeSave get full object on create and update', function(done) {
|
||||
var triggerTime = 0;
|
||||
// Register a mock beforeSave hook
|
||||
Parse.Cloud.beforeSave('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();
|
||||
if (triggerTime == 0) {
|
||||
// Create
|
||||
expect(object.get('foo')).toEqual('bar');
|
||||
} else if (triggerTime == 1) {
|
||||
// Update
|
||||
expect(object.get('foo')).toEqual('baz');
|
||||
} 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 beforeSave
|
||||
delete Parse.Cloud.Triggers.beforeSave.GameScore;
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('test afterSave get full object on create and 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();
|
||||
if (triggerTime == 0) {
|
||||
// Create
|
||||
expect(object.get('foo')).toEqual('bar');
|
||||
} else if (triggerTime == 1) {
|
||||
// Update
|
||||
expect(object.get('foo')).toEqual('baz');
|
||||
} 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
|
||||
delete Parse.Cloud.Triggers.afterSave.GameScore;
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('test beforeSave get original object on update', function(done) {
|
||||
var triggerTime = 0;
|
||||
// Register a mock beforeSave hook
|
||||
Parse.Cloud.beforeSave('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 beforeSave
|
||||
delete Parse.Cloud.Triggers.beforeSave.GameScore;
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
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
|
||||
delete Parse.Cloud.Triggers.afterSave.GameScore;
|
||||
done();
|
||||
}, function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('test cloud function error handling', (done) => {
|
||||
// Register a function which will fail
|
||||
Parse.Cloud.define('willFail', (req, res) => {
|
||||
res.error('noway');
|
||||
});
|
||||
Parse.Cloud.run('willFail').then((s) => {
|
||||
fail('Should not have succeeded.');
|
||||
delete Parse.Cloud.Functions['willFail'];
|
||||
done();
|
||||
}, (e) => {
|
||||
expect(e.code).toEqual(141);
|
||||
expect(e.message).toEqual('noway');
|
||||
delete Parse.Cloud.Functions['willFail'];
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on invalid client key', done => {
|
||||
var headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-Client-Key': 'notclient'
|
||||
};
|
||||
request.get({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestObject'
|
||||
}, (error, response, body) => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
expect(b.error).toEqual('unauthorized');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on invalid windows key', done => {
|
||||
var headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-Windows-Key': 'notwindows'
|
||||
};
|
||||
request.get({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestObject'
|
||||
}, (error, response, body) => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
expect(b.error).toEqual('unauthorized');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on invalid javascript key', done => {
|
||||
var headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-Javascript-Key': 'notjavascript'
|
||||
};
|
||||
request.get({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestObject'
|
||||
}, (error, response, body) => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
expect(b.error).toEqual('unauthorized');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on invalid rest api key', done => {
|
||||
var headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'notrest'
|
||||
};
|
||||
request.get({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestObject'
|
||||
}, (error, response, body) => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
expect(b.error).toEqual('unauthorized');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user