1466 lines
45 KiB
JavaScript
1466 lines
45 KiB
JavaScript
// A bunch of different tests are in here - it isn't very thematic.
|
||
// It would probably be better to refactor them into different files.
|
||
'use strict';
|
||
|
||
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
||
const MongoStorageAdapter = require('../src/Adapters/Storage/Mongo/MongoStorageAdapter');
|
||
var request = require('request');
|
||
const rp = require('request-promise');
|
||
const Parse = require("parse/node");
|
||
let Config = require('../src/Config');
|
||
const SchemaController = require('../src/Controllers/SchemaController');
|
||
var TestUtils = require('../src/index').TestUtils;
|
||
const deepcopy = require('deepcopy');
|
||
|
||
const userSchema = SchemaController.convertSchemaToAdapterSchema({ className: '_User', fields: Object.assign({}, SchemaController.defaultColumns._Default, SchemaController.defaultColumns._User) });
|
||
|
||
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();
|
||
}, error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
});
|
||
});
|
||
|
||
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: error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
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();
|
||
}, error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('fail to create a duplicate username', done => {
|
||
let numCreated = 0;
|
||
let numFailed = 0;
|
||
let p1 = createTestUser();
|
||
p1.then(user => {
|
||
numCreated++;
|
||
expect(numCreated).toEqual(1);
|
||
})
|
||
.catch(error => {
|
||
numFailed++;
|
||
expect(numFailed).toEqual(1);
|
||
expect(error.code).toEqual(Parse.Error.USERNAME_TAKEN);
|
||
});
|
||
let p2 = createTestUser();
|
||
p2.then(user => {
|
||
numCreated++;
|
||
expect(numCreated).toEqual(1);
|
||
})
|
||
.catch(error => {
|
||
numFailed++;
|
||
expect(numFailed).toEqual(1);
|
||
expect(error.code).toEqual(Parse.Error.USERNAME_TAKEN);
|
||
});
|
||
Parse.Promise.when([p1, p2])
|
||
.then(() => {
|
||
fail('one of the users should not have been created');
|
||
done();
|
||
})
|
||
.catch(done);
|
||
});
|
||
|
||
it('ensure that email is uniquely indexed', done => {
|
||
let numFailed = 0;
|
||
let numCreated = 0;
|
||
let user1 = new Parse.User();
|
||
user1.setPassword('asdf');
|
||
user1.setUsername('u1');
|
||
user1.setEmail('dupe@dupe.dupe');
|
||
let p1 = user1.signUp();
|
||
p1.then(user => {
|
||
numCreated++;
|
||
expect(numCreated).toEqual(1);
|
||
}, error => {
|
||
numFailed++;
|
||
expect(numFailed).toEqual(1);
|
||
expect(error.code).toEqual(Parse.Error.EMAIL_TAKEN);
|
||
});
|
||
|
||
let user2 = new Parse.User();
|
||
user2.setPassword('asdf');
|
||
user2.setUsername('u2');
|
||
user2.setEmail('dupe@dupe.dupe');
|
||
let p2 = user2.signUp();
|
||
p2.then(user => {
|
||
numCreated++;
|
||
expect(numCreated).toEqual(1);
|
||
}, error => {
|
||
numFailed++;
|
||
expect(numFailed).toEqual(1);
|
||
expect(error.code).toEqual(Parse.Error.EMAIL_TAKEN);
|
||
});
|
||
|
||
Parse.Promise.when([p1, p2])
|
||
.then(() => {
|
||
fail('one of the users should not have been created');
|
||
done();
|
||
})
|
||
.catch(done);
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('ensure that if people already have duplicate users, they can still sign up new users', done => {
|
||
let config = new Config('test');
|
||
// Remove existing data to clear out unique index
|
||
TestUtils.destroyAllDataPermanently()
|
||
.then(() => config.database.adapter.createClass('_User', userSchema))
|
||
.then(() => config.database.adapter.createObject('_User', userSchema, { objectId: 'x', username: 'u' }).catch(fail))
|
||
.then(() => config.database.adapter.createObject('_User', userSchema, { objectId: 'y', username: 'u' }).catch(fail))
|
||
// Create a new server to try to recreate the unique indexes
|
||
.then(reconfigureServer)
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.DUPLICATE_VALUE);
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('zxcv');
|
||
return user.signUp().catch(fail);
|
||
})
|
||
.then(() => {
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('u');
|
||
return user.signUp()
|
||
})
|
||
.then(result => {
|
||
fail('should not have been able to sign up');
|
||
done();
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.USERNAME_TAKEN);
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('ensure that if people already have duplicate emails, they can still sign up new users', done => {
|
||
let config = new Config('test');
|
||
// Remove existing data to clear out unique index
|
||
TestUtils.destroyAllDataPermanently()
|
||
.then(() => config.database.adapter.createClass('_User', userSchema))
|
||
.then(() => config.database.adapter.createObject('_User', userSchema, { objectId: 'x', email: 'a@b.c' }))
|
||
.then(() => config.database.adapter.createObject('_User', userSchema, { objectId: 'y', email: 'a@b.c' }))
|
||
.then(reconfigureServer)
|
||
.catch(() => {
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('qqq');
|
||
user.setEmail('unique@unique.unique');
|
||
return user.signUp().catch(fail);
|
||
})
|
||
.then(() => {
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('www');
|
||
user.setEmail('a@b.c');
|
||
return user.signUp()
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.EMAIL_TAKEN);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('ensure that if you try to sign up a user with a unique username and email, but duplicates in some other field that has a uniqueness constraint, you get a regular duplicate value error', done => {
|
||
let config = new Config('test');
|
||
config.database.adapter.addFieldIfNotExists('_User', 'randomField', { type: 'String' })
|
||
.then(() => config.database.adapter.ensureUniqueness('_User', userSchema, ['randomField']))
|
||
.then(() => {
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('1');
|
||
user.setEmail('1@b.c');
|
||
user.set('randomField', 'a');
|
||
return user.signUp()
|
||
})
|
||
.then(() => {
|
||
let user = new Parse.User();
|
||
user.setPassword('asdf');
|
||
user.setUsername('2');
|
||
user.setEmail('2@b.c');
|
||
user.set('randomField', 'a');
|
||
return user.signUp()
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.DUPLICATE_VALUE);
|
||
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().then(done);
|
||
}, error: error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
}
|
||
});
|
||
}, 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())
|
||
.then(() => Parse.User.logIn('test', 'moon-y'))
|
||
.then((user) => {
|
||
expect(user.get('foo')).toEqual(2);
|
||
Parse.User.logOut()
|
||
.then(done);
|
||
}, (error) => {
|
||
fail(JSON.stringify(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(JSON.stringify(error));
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('query without limit get default 100 records', function(done) {
|
||
var objects = [];
|
||
for (var i = 0; i < 150; i++) {
|
||
objects.push(new TestObject({name: 'name' + i}));
|
||
}
|
||
Parse.Object.saveAll(objects).then(() => {
|
||
return new Parse.Query(TestObject).find();
|
||
}).then((results) => {
|
||
expect(results.length).toEqual(100);
|
||
done();
|
||
}, error => {
|
||
fail(JSON.stringify(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 beforeSave set object acl success', function(done) {
|
||
var acl = new Parse.ACL({
|
||
'*': { read: true, write: false }
|
||
});
|
||
Parse.Cloud.beforeSave('BeforeSaveAddACL', function(req, res) {
|
||
req.object.setACL(acl);
|
||
res.success();
|
||
});
|
||
|
||
var obj = new Parse.Object('BeforeSaveAddACL');
|
||
obj.set('lol', true);
|
||
obj.save().then(function() {
|
||
var 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('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(() => {
|
||
let config = new Config(appId);
|
||
return config.database.adapter.find('TestObject', { fields: {} }, {}, {});
|
||
}).then((results) => {
|
||
expect(results.length).toEqual(1);
|
||
expect(results[0]['foo']).toEqual('bar');
|
||
done();
|
||
}).fail(error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('object is set on create and update', done => {
|
||
let triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||
let 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');
|
||
// No objectId/createdAt/updatedAt
|
||
expect(object.id).toBeUndefined();
|
||
expect(object.createdAt).toBeUndefined();
|
||
expect(object.updatedAt).toBeUndefined();
|
||
} else if (triggerTime == 1) {
|
||
// Update
|
||
expect(object.get('foo')).toEqual('baz');
|
||
expect(object.id).not.toBeUndefined();
|
||
expect(object.createdAt).not.toBeUndefined();
|
||
expect(object.updatedAt).not.toBeUndefined();
|
||
} 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();
|
||
}, error => {
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
it('works when object is passed to success', done => {
|
||
let triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||
let object = req.object;
|
||
object.set('foo', 'bar');
|
||
triggerTime++;
|
||
res.success(object);
|
||
});
|
||
|
||
let obj = new Parse.Object('GameScore');
|
||
obj.set('foo', 'baz');
|
||
obj.save().then(() => {
|
||
expect(triggerTime).toBe(1);
|
||
expect(obj.get('foo')).toEqual('bar');
|
||
done();
|
||
}, error => {
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('original object is set on update', done => {
|
||
let triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||
let object = req.object;
|
||
expect(object instanceof Parse.Object).toBeTruthy();
|
||
expect(object.get('fooAgain')).toEqual('barAgain');
|
||
let 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();
|
||
});
|
||
|
||
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();
|
||
}, error => {
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('pointer mutation properly saves object', done => {
|
||
let className = 'GameScore';
|
||
|
||
Parse.Cloud.beforeSave(className, (req, res) => {
|
||
let object = req.object;
|
||
expect(object instanceof Parse.Object).toBeTruthy();
|
||
|
||
let child = object.get('child');
|
||
expect(child instanceof Parse.Object).toBeTruthy();
|
||
child.set('a', 'b');
|
||
child.save().then(() => {
|
||
res.success();
|
||
});
|
||
});
|
||
|
||
let obj = new Parse.Object(className);
|
||
obj.set('foo', 'bar');
|
||
|
||
let child = new Parse.Object('Child');
|
||
child.save().then(() => {
|
||
obj.set('child', child);
|
||
return obj.save();
|
||
}).then(() => {
|
||
let query = new Parse.Query(className);
|
||
query.include('child');
|
||
return query.get(obj.id).then(objAgain => {
|
||
expect(objAgain.get('foo')).toEqual('bar');
|
||
|
||
let childAgain = objAgain.get('child');
|
||
expect(childAgain instanceof Parse.Object).toBeTruthy();
|
||
expect(childAgain.get('a')).toEqual('b');
|
||
|
||
return Promise.resolve();
|
||
});
|
||
}).then(() => {
|
||
done();
|
||
}, error => {
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
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);
|
||
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.id).not.toBeUndefined();
|
||
expect(object.createdAt).not.toBeUndefined();
|
||
expect(object.updatedAt).not.toBeUndefined();
|
||
expect(object.get('fooAgain')).toEqual('barAgain');
|
||
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);
|
||
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);
|
||
done();
|
||
}, function(error) {
|
||
console.error(error);
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test afterSave get full original object even req auth can not query it', (done) => {
|
||
var triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.afterSave('GameScore', function(req, res) {
|
||
var object = req.object;
|
||
var originalObject = req.original;
|
||
if (triggerTime == 0) {
|
||
// Create
|
||
} else if (triggerTime == 1) {
|
||
// Update
|
||
expect(object.get('foo')).toEqual('baz');
|
||
// Make sure we get the full 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');
|
||
var acl = new Parse.ACL();
|
||
// Make sure our update request can not query the object
|
||
acl.setPublicReadAccess(false);
|
||
acl.setPublicWriteAccess(true);
|
||
obj.setACL(acl);
|
||
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);
|
||
done();
|
||
}, function(error) {
|
||
console.error(error);
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('afterSave flattens custom operations', done => {
|
||
var triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.afterSave('GameScore', function(req, res) {
|
||
let object = req.object;
|
||
expect(object instanceof Parse.Object).toBeTruthy();
|
||
let originalObject = req.original;
|
||
if (triggerTime == 0) {
|
||
// Create
|
||
expect(object.get('yolo')).toEqual(1);
|
||
} else if (triggerTime == 1) {
|
||
// Update
|
||
expect(object.get('yolo')).toEqual(2);
|
||
// Check the originalObject
|
||
expect(originalObject.get('yolo')).toEqual(1);
|
||
} else {
|
||
res.error();
|
||
}
|
||
triggerTime++;
|
||
res.success();
|
||
});
|
||
|
||
var obj = new Parse.Object('GameScore');
|
||
obj.increment('yolo', 1);
|
||
obj.save().then(() => {
|
||
obj.increment('yolo', 1);
|
||
return obj.save();
|
||
}).then(() => {
|
||
// Make sure the checking has been triggered
|
||
expect(triggerTime).toBe(2);
|
||
done();
|
||
}, error => {
|
||
console.error(error);
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('beforeSave receives ACL', done => {
|
||
let triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.beforeSave('GameScore', function(req, res) {
|
||
let object = req.object;
|
||
if (triggerTime == 0) {
|
||
let acl = object.getACL();
|
||
expect(acl.getPublicReadAccess()).toBeTruthy();
|
||
expect(acl.getPublicWriteAccess()).toBeTruthy();
|
||
} else if (triggerTime == 1) {
|
||
let acl = object.getACL();
|
||
expect(acl.getPublicReadAccess()).toBeFalsy();
|
||
expect(acl.getPublicWriteAccess()).toBeTruthy();
|
||
} else {
|
||
res.error();
|
||
}
|
||
triggerTime++;
|
||
res.success();
|
||
});
|
||
|
||
let obj = new Parse.Object('GameScore');
|
||
let acl = new Parse.ACL();
|
||
acl.setPublicReadAccess(true);
|
||
acl.setPublicWriteAccess(true);
|
||
obj.setACL(acl);
|
||
obj.save().then(() => {
|
||
acl.setPublicReadAccess(false);
|
||
obj.setACL(acl);
|
||
return obj.save();
|
||
}).then(() => {
|
||
// Make sure the checking has been triggered
|
||
expect(triggerTime).toBe(2);
|
||
done();
|
||
}, error => {
|
||
console.error(error);
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('afterSave receives ACL', done => {
|
||
let triggerTime = 0;
|
||
// Register a mock beforeSave hook
|
||
Parse.Cloud.afterSave('GameScore', function(req, res) {
|
||
let object = req.object;
|
||
if (triggerTime == 0) {
|
||
let acl = object.getACL();
|
||
expect(acl.getPublicReadAccess()).toBeTruthy();
|
||
expect(acl.getPublicWriteAccess()).toBeTruthy();
|
||
} else if (triggerTime == 1) {
|
||
let acl = object.getACL();
|
||
expect(acl.getPublicReadAccess()).toBeFalsy();
|
||
expect(acl.getPublicWriteAccess()).toBeTruthy();
|
||
} else {
|
||
res.error();
|
||
}
|
||
triggerTime++;
|
||
res.success();
|
||
});
|
||
|
||
let obj = new Parse.Object('GameScore');
|
||
let acl = new Parse.ACL();
|
||
acl.setPublicReadAccess(true);
|
||
acl.setPublicWriteAccess(true);
|
||
obj.setACL(acl);
|
||
obj.save().then(() => {
|
||
acl.setPublicReadAccess(false);
|
||
obj.setACL(acl);
|
||
return obj.save();
|
||
}).then(() => {
|
||
// Make sure the checking has been triggered
|
||
expect(triggerTime).toBe(2);
|
||
done();
|
||
}, error => {
|
||
console.error(error);
|
||
fail(error);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should return the updated fields on PUT', done => {
|
||
let obj = new Parse.Object('GameScore');
|
||
obj.save({a:'hello', c: 1, d: ['1'], e:['1'], f:['1','2']}).then(( ) => {
|
||
var headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest',
|
||
'X-Parse-Installation-Id': 'yolo'
|
||
};
|
||
request.put({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/GameScore/'+obj.id,
|
||
body: JSON.stringify({
|
||
a: 'b',
|
||
c: {"__op":"Increment","amount":2},
|
||
d: {"__op":"Add", objects: ['2']},
|
||
e: {"__op":"AddUnique", objects: ['1', '2']},
|
||
f: {"__op":"Remove", objects: ['2']},
|
||
selfThing: {"__type":"Pointer","className":"GameScore","objectId":obj.id},
|
||
})
|
||
}, (error, response, body) => {
|
||
body = JSON.parse(body);
|
||
expect(body.a).toBeUndefined();
|
||
expect(body.c).toEqual(3); // 2+1
|
||
expect(body.d.length).toBe(2);
|
||
expect(body.d.indexOf('1') > -1).toBe(true);
|
||
expect(body.d.indexOf('2') > -1).toBe(true);
|
||
expect(body.e.length).toBe(2);
|
||
expect(body.e.indexOf('1') > -1).toBe(true);
|
||
expect(body.e.indexOf('2') > -1).toBe(true);
|
||
expect(body.f.length).toBe(1);
|
||
expect(body.f.indexOf('1') > -1).toBe(true);
|
||
// return nothing on other self
|
||
expect(body.selfThing).toBeUndefined();
|
||
// updatedAt is always set
|
||
expect(body.updatedAt).not.toBeUndefined();
|
||
done();
|
||
});
|
||
}).fail((err) => {
|
||
fail('Should not fail');
|
||
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.');
|
||
done();
|
||
}, (e) => {
|
||
expect(e.code).toEqual(141);
|
||
expect(e.message).toEqual('noway');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test cloud function error handling with custom error code', (done) => {
|
||
// Register a function which will fail
|
||
Parse.Cloud.define('willFail', (req, res) => {
|
||
res.error(999, 'noway');
|
||
});
|
||
Parse.Cloud.run('willFail').then((s) => {
|
||
fail('Should not have succeeded.');
|
||
done();
|
||
}, (e) => {
|
||
expect(e.code).toEqual(999);
|
||
expect(e.message).toEqual('noway');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test cloud function error handling with standard error code', (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.');
|
||
done();
|
||
}, (e) => {
|
||
expect(e.code).toEqual(Parse.Error.SCRIPT_FAILED);
|
||
expect(e.message).toEqual('noway');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test beforeSave/afterSave get installationId', function(done) {
|
||
let triggerTime = 0;
|
||
Parse.Cloud.beforeSave('GameScore', function(req, res) {
|
||
triggerTime++;
|
||
expect(triggerTime).toEqual(1);
|
||
expect(req.installationId).toEqual('yolo');
|
||
res.success();
|
||
});
|
||
Parse.Cloud.afterSave('GameScore', function(req) {
|
||
triggerTime++;
|
||
expect(triggerTime).toEqual(2);
|
||
expect(req.installationId).toEqual('yolo');
|
||
});
|
||
|
||
var headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest',
|
||
'X-Parse-Installation-Id': 'yolo'
|
||
};
|
||
request.post({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/GameScore',
|
||
body: JSON.stringify({ a: 'b' })
|
||
}, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
expect(triggerTime).toEqual(2);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test beforeDelete/afterDelete get installationId', function(done) {
|
||
let triggerTime = 0;
|
||
Parse.Cloud.beforeDelete('GameScore', function(req, res) {
|
||
triggerTime++;
|
||
expect(triggerTime).toEqual(1);
|
||
expect(req.installationId).toEqual('yolo');
|
||
res.success();
|
||
});
|
||
Parse.Cloud.afterDelete('GameScore', function(req) {
|
||
triggerTime++;
|
||
expect(triggerTime).toEqual(2);
|
||
expect(req.installationId).toEqual('yolo');
|
||
});
|
||
|
||
var headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest',
|
||
'X-Parse-Installation-Id': 'yolo'
|
||
};
|
||
request.post({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/GameScore',
|
||
body: JSON.stringify({ a: 'b' })
|
||
}, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
request.del({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/GameScore/' + JSON.parse(body).objectId
|
||
}, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
expect(triggerTime).toEqual(2);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
it('test cloud function query parameters', (done) => {
|
||
Parse.Cloud.define('echoParams', (req, res) => {
|
||
res.success(req.params);
|
||
});
|
||
var headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-Javascript-Key': 'test'
|
||
};
|
||
request.post({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/functions/echoParams', //?option=1&other=2
|
||
qs: {
|
||
option: 1,
|
||
other: 2
|
||
},
|
||
body: '{"foo":"bar", "other": 1}'
|
||
}, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
var res = JSON.parse(body).result;
|
||
expect(res.option).toEqual('1');
|
||
// Make sure query string params override body params
|
||
expect(res.other).toEqual('2');
|
||
expect(res.foo).toEqual("bar");
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('test cloud function parameter validation', (done) => {
|
||
// Register a function with validation
|
||
Parse.Cloud.define('functionWithParameterValidationFailure', (req, res) => {
|
||
res.success('noway');
|
||
}, (request) => {
|
||
return request.params.success === 100;
|
||
});
|
||
|
||
Parse.Cloud.run('functionWithParameterValidationFailure', {"success":500}).then((s) => {
|
||
fail('Validation should not have succeeded');
|
||
done();
|
||
}, (e) => {
|
||
expect(e.code).toEqual(142);
|
||
expect(e.message).toEqual('Validation failed.');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('can handle null params in cloud functions (regression test for #1742)', done => {
|
||
Parse.Cloud.define('func', (request, response) => {
|
||
expect(request.params.nullParam).toEqual(null);
|
||
response.success('yay');
|
||
});
|
||
|
||
Parse.Cloud.run('func', {nullParam: null})
|
||
.then(() => {
|
||
done()
|
||
}, e => {
|
||
fail('cloud code call failed');
|
||
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();
|
||
});
|
||
});
|
||
|
||
it('fails on invalid function', done => {
|
||
Parse.Cloud.run('somethingThatDoesDefinitelyNotExist').then((s) => {
|
||
fail('This should have never suceeded');
|
||
done();
|
||
}, (e) => {
|
||
expect(e.code).toEqual(Parse.Error.SCRIPT_FAILED);
|
||
expect(e.message).toEqual('Invalid function.');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('dedupes an installation properly and returns updatedAt', (done) => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
let data = {
|
||
'installationId': 'lkjsahdfkjhsdfkjhsdfkjhsdf',
|
||
'deviceType': 'embedded'
|
||
};
|
||
let requestOptions = {
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/installations',
|
||
body: JSON.stringify(data)
|
||
};
|
||
request.post(requestOptions, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
let b = JSON.parse(body);
|
||
expect(typeof b.objectId).toEqual('string');
|
||
request.post(requestOptions, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
let b = JSON.parse(body);
|
||
expect(typeof b.updatedAt).toEqual('string');
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
it('android login providing empty authData block works', (done) => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
let data = {
|
||
username: 'pulse1989',
|
||
password: 'password1234',
|
||
authData: {}
|
||
};
|
||
let requestOptions = {
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/users',
|
||
body: JSON.stringify(data)
|
||
};
|
||
request.post(requestOptions, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
requestOptions.url = 'http://localhost:8378/1/login';
|
||
request.get(requestOptions, (error, response, body) => {
|
||
expect(error).toBe(null);
|
||
let b = JSON.parse(body);
|
||
expect(typeof b['sessionToken']).toEqual('string');
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('gets relation fields', (done) => {
|
||
let object = new Parse.Object('AnObject');
|
||
let relatedObject = new Parse.Object('RelatedObject');
|
||
Parse.Object.saveAll([object, relatedObject]).then(() => {
|
||
object.relation('related').add(relatedObject);
|
||
return object.save();
|
||
}).then(() => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
let requestOptions = {
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/AnObject',
|
||
json: true
|
||
};
|
||
request.get(requestOptions, (err, res, body) => {
|
||
expect(body.results.length).toBe(1);
|
||
let result = body.results[0];
|
||
expect(result.related).toEqual({
|
||
__type: "Relation",
|
||
className: 'RelatedObject'
|
||
})
|
||
done();
|
||
});
|
||
})
|
||
});
|
||
|
||
it('properly returns incremented values (#1554)', (done) => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
let requestOptions = {
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/AnObject',
|
||
json: true
|
||
};
|
||
let object = new Parse.Object('AnObject');;
|
||
|
||
function runIncrement(amount) {
|
||
let options = Object.assign({}, requestOptions, {
|
||
body: {
|
||
"key": {
|
||
__op: 'Increment',
|
||
amount: amount
|
||
}
|
||
},
|
||
url: 'http://localhost:8378/1/classes/AnObject/'+object.id
|
||
})
|
||
return new Promise((resolve, reject) => {
|
||
request.put(options, (err, res, body) => {
|
||
if (err) {
|
||
reject(err);
|
||
} else {
|
||
resolve(body);
|
||
}
|
||
});
|
||
})
|
||
}
|
||
|
||
object.save().then(() => {
|
||
return runIncrement(1);
|
||
}).then((res) => {
|
||
expect(res.key).toBe(1);
|
||
return runIncrement(-1);
|
||
}).then((res) => {
|
||
expect(res.key).toBe(0);
|
||
done();
|
||
})
|
||
})
|
||
|
||
it('ignores _RevocableSession "header" send by JS SDK', (done) => {
|
||
let 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);
|
||
let result = body.results[0];
|
||
expect(result.a).toBe('b');
|
||
done();
|
||
})
|
||
});
|
||
});
|
||
|
||
it('doesnt convert interior keys of objects that use special names', done => {
|
||
let 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();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('bans interior keys containing . or $', done => {
|
||
new Parse.Object('Obj').save({innerObj: {'key with a $': 'fails'}})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||
return new Parse.Object('Obj').save({innerObj: {'key with a .': 'fails'}});
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||
return new Parse.Object('Obj').save({innerObj: {innerInnerObj: {'key with $': 'fails'}}});
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||
return new Parse.Object('Obj').save({innerObj: {innerInnerObj: {'key with .': 'fails'}}});
|
||
})
|
||
.catch(error => {
|
||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('does not change inner object keys named _auth_data_something', done => {
|
||
new Parse.Object('O').save({ innerObj: {_auth_data_facebook: 7}})
|
||
.then(object => new Parse.Query('O').get(object.id))
|
||
.then(object => {
|
||
expect(object.get('innerObj')).toEqual({_auth_data_facebook: 7});
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('does not change inner object key names _p_somethign', done => {
|
||
new Parse.Object('O').save({ innerObj: {_p_data: 7}})
|
||
.then(object => new Parse.Query('O').get(object.id))
|
||
.then(object => {
|
||
expect(object.get('innerObj')).toEqual({_p_data: 7});
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('does not change inner object key names _rperm, _wperm', done => {
|
||
new Parse.Object('O').save({ innerObj: {_rperm: 7, _wperm: 8}})
|
||
.then(object => new Parse.Query('O').get(object.id))
|
||
.then(object => {
|
||
expect(object.get('innerObj')).toEqual({_rperm: 7, _wperm: 8});
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('does not change inner objects if the key has the same name as a geopoint field on the class, and the value is an array of length 2, or if the key has the same name as a file field on the class, and the value is a string', done => {
|
||
let file = new Parse.File('myfile.txt', { base64: 'eAo=' });
|
||
file.save()
|
||
.then(f => {
|
||
let 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();
|
||
})
|
||
.then(object => object.fetch())
|
||
.then(object => {
|
||
expect(object.get('innerObj')).toEqual({
|
||
fileField: "data",
|
||
geoField: [1,2],
|
||
});
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('purge all objects in class', (done) => {
|
||
let object = new Parse.Object('TestObject');
|
||
object.set('foo', 'bar');
|
||
let object2 = new Parse.Object('TestObject');
|
||
object2.set('alice', 'wonderland');
|
||
Parse.Object.saveAll([object, object2])
|
||
.then(() => {
|
||
let query = new Parse.Query(TestObject);
|
||
return query.count()
|
||
}).then((count) => {
|
||
expect(count).toBe(2);
|
||
let 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, res, body) => {
|
||
expect(err).toBe(null);
|
||
let query = new Parse.Query(TestObject);
|
||
return query.count().then((count) => {
|
||
expect(count).toBe(0);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
});
|
||
|
||
it('fail on purge all objects in class without master key', (done) => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
rp({
|
||
method: 'DELETE',
|
||
headers: headers,
|
||
uri: 'http://localhost:8378/1/purge/TestObject',
|
||
json: true
|
||
}).then(body => {
|
||
fail('Should not succeed');
|
||
}).catch(err => {
|
||
expect(err.error.error).toEqual('unauthorized: master key is required');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('purge all objects in _Role also purge cache', (done) => {
|
||
let headers = {
|
||
'Content-Type': 'application/json',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-Master-Key': 'test'
|
||
};
|
||
var user, object;
|
||
createTestUser().then((x) => {
|
||
user = x;
|
||
let acl = new Parse.ACL();
|
||
acl.setPublicReadAccess(true);
|
||
acl.setPublicWriteAccess(false);
|
||
let role = new Parse.Object('_Role');
|
||
role.set('name', 'TestRole');
|
||
role.setACL(acl);
|
||
let users = role.relation('users');
|
||
users.add(user);
|
||
return role.save({}, { useMasterKey: true });
|
||
}).then((x) => {
|
||
let query = new Parse.Query('_Role');
|
||
return query.find({ useMasterKey: true });
|
||
}).then((x) => {
|
||
expect(x.length).toEqual(1);
|
||
let relation = x[0].relation('users').query();
|
||
return relation.first({ useMasterKey: true });
|
||
}).then((x) => {
|
||
expect(x.id).toEqual(user.id);
|
||
object = new Parse.Object('TestObject');
|
||
let 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((x) => {
|
||
let query = new Parse.Query('TestObject');
|
||
return query.find({ sessionToken: user.getSessionToken() });
|
||
}).then((x) => {
|
||
expect(x.length).toEqual(1);
|
||
return rp({
|
||
method: 'DELETE',
|
||
headers: headers,
|
||
uri: 'http://localhost:8378/1/purge/_Role',
|
||
json: true
|
||
});
|
||
}).then((x) => {
|
||
let query = new Parse.Query('TestObject');
|
||
return query.get(object.id, { sessionToken: user.getSessionToken() });
|
||
}).then((x) => {
|
||
fail('Should not succeed');
|
||
}, (e) => {
|
||
expect(e.code).toEqual(Parse.Error.OBJECT_NOT_FOUND);
|
||
done();
|
||
});
|
||
});
|
||
});
|