Adds liniting into the workflow (#3082)
* initial linting of src * fix indent to 2 spaces * Removes unnecessary rules * ignore spec folder for now * Spec linting * Fix spec indent * nits * nits * no no-empty rule
This commit is contained in:
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
lib/*
|
||||
coverage/*
|
||||
20
.eslintrc.json
Normal file
20
.eslintrc.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"plugins": [
|
||||
"flowtype"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"indent": ["error", 2],
|
||||
"linebreak-style": ["error", "unix"]
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ before_script:
|
||||
- psql -c 'create database parse_server_postgres_adapter_test_database;' -U postgres
|
||||
- psql -c 'CREATE EXTENSION postgis;' -U postgres -d parse_server_postgres_adapter_test_database
|
||||
- psql -c 'CREATE EXTENSION postgis_topology;' -U postgres -d parse_server_postgres_adapter_test_database
|
||||
- npm run lint
|
||||
env:
|
||||
global:
|
||||
- COVERAGE_OPTION='./node_modules/.bin/istanbul cover'
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.18.0",
|
||||
"babel-core": "6.18.2",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-plugin-syntax-flow": "6.13.0",
|
||||
"babel-plugin-transform-flow-strip-types": "6.18.0",
|
||||
"babel-preset-es2015": "6.14.0",
|
||||
@@ -54,6 +55,8 @@
|
||||
"bcrypt-nodejs": "0.0.3",
|
||||
"cross-env": "3.1.3",
|
||||
"deep-diff": "0.3.4",
|
||||
"eslint": "^3.10.2",
|
||||
"eslint-plugin-flowtype": "^2.25.0",
|
||||
"gaze": "1.1.1",
|
||||
"istanbul": "1.0.0-alpha.1",
|
||||
"jasmine": "2.5.2",
|
||||
@@ -64,6 +67,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "npm run build && node bin/dev",
|
||||
"lint": "eslint ./",
|
||||
"build": "babel src/ -d lib/",
|
||||
"test": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=3.2.6} MONGODB_STORAGE_ENGINE=mmapv1 NODE_ENV=test TESTING=1 $COVERAGE_OPTION jasmine",
|
||||
"test:win": "npm run pretest && cross-env NODE_ENV=test TESTING=1 node ./node_modules/jasmine/bin/jasmine.js && npm run posttest",
|
||||
|
||||
35
spec/.eslintrc.json
Normal file
35
spec/.eslintrc.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true,
|
||||
"jasmine": true
|
||||
},
|
||||
"globals": {
|
||||
"Parse": true,
|
||||
"reconfigureServer": true,
|
||||
"createTestUser": true,
|
||||
"jfail": true,
|
||||
"ok": true,
|
||||
"strictEqual": true,
|
||||
"TestObject": true,
|
||||
"Item": true,
|
||||
"Container": true,
|
||||
"equal": true,
|
||||
"notEqual": true,
|
||||
"it_exclude_dbs": true,
|
||||
"describe_only_db": true,
|
||||
"on_db": true,
|
||||
"defaultConfiguration": true,
|
||||
"expectSuccess": true,
|
||||
"range": true,
|
||||
"expectError": true,
|
||||
"jequal": true,
|
||||
"create": true,
|
||||
"arrayContains": true
|
||||
},
|
||||
"rules": {
|
||||
"no-console": [0],
|
||||
"indent": ["error", 2]
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ const Config = require("../src/Config");
|
||||
var loginWithWrongCredentialsShouldFail = function(username, password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Parse.User.logIn(username, password)
|
||||
.then(user => reject('login should have failed'))
|
||||
.then(() => reject('login should have failed'))
|
||||
.catch(err => {
|
||||
if (err.message === 'Invalid username/password.') {
|
||||
resolve();
|
||||
@@ -20,7 +20,7 @@ var isAccountLockoutError = function(username, password, duration, waitTime) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
Parse.User.logIn(username, password)
|
||||
.then(user => reject('login should have failed'))
|
||||
.then(() => reject('login should have failed'))
|
||||
.catch(err => {
|
||||
if (err.message === 'Your account is locked due to multiple failed login attempts. Please try again after ' + duration + ' minute(s)') {
|
||||
resolve();
|
||||
@@ -45,7 +45,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
user.setPassword('password');
|
||||
return user.signUp(null);
|
||||
})
|
||||
.then(user => {
|
||||
.then(() => {
|
||||
return loginWithWrongCredentialsShouldFail('username1', 'incorrect password 1');
|
||||
})
|
||||
.then(() => {
|
||||
@@ -71,7 +71,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('set duration to an invalid number test failed');
|
||||
done();
|
||||
})
|
||||
@@ -95,7 +95,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('set threshold to an invalid number test failed');
|
||||
done();
|
||||
})
|
||||
@@ -119,7 +119,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('threshold value < 1 is invalid test failed');
|
||||
done();
|
||||
})
|
||||
@@ -143,7 +143,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('threshold value > 999 is invalid test failed');
|
||||
done();
|
||||
})
|
||||
@@ -167,7 +167,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('duration value < 1 is invalid test failed');
|
||||
done();
|
||||
})
|
||||
@@ -191,7 +191,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
publicServerURL: "https://my.public.server.com/1"
|
||||
})
|
||||
.then(() => {
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
fail('duration value > 99999 is invalid test failed');
|
||||
done();
|
||||
})
|
||||
@@ -230,7 +230,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
return isAccountLockoutError('username2', 'wrong password', 1, 1);
|
||||
})
|
||||
.then(() => {
|
||||
done();
|
||||
done();
|
||||
})
|
||||
.catch(err => {
|
||||
fail('lock account after failed login attempts test failed: ' + JSON.stringify(err));
|
||||
@@ -301,7 +301,7 @@ describe("Account Lockout Policy: ", () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
Parse.User.logIn('username4', 'correct password')
|
||||
.then(user => resolve())
|
||||
.then(() => resolve())
|
||||
.catch(err => reject(err));
|
||||
}, 3001);
|
||||
});
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("AdaptableController", ()=>{
|
||||
});
|
||||
|
||||
it("should fail setting the wrong adapter to the controller", (done) => {
|
||||
function WrongAdapter() {};
|
||||
function WrongAdapter() {}
|
||||
var adapter = new FilesAdapter();
|
||||
var controller = new FilesController(adapter);
|
||||
var otherAdapter = new WrongAdapter();
|
||||
@@ -42,7 +42,7 @@ describe("AdaptableController", ()=>{
|
||||
});
|
||||
|
||||
it("should fail to instantiate a controller with wrong adapter", (done) => {
|
||||
function WrongAdapter() {};
|
||||
function WrongAdapter() {}
|
||||
var adapter = new WrongAdapter();
|
||||
expect(() => {
|
||||
new FilesController(adapter);
|
||||
@@ -59,10 +59,10 @@ describe("AdaptableController", ()=>{
|
||||
|
||||
it("should accept an object adapter", (done) => {
|
||||
var adapter = {
|
||||
createFile: function(config, filename, data) { },
|
||||
deleteFile: function(config, filename) { },
|
||||
getFileData: function(config, filename) { },
|
||||
getFileLocation: function(config, filename) { },
|
||||
createFile: function() { },
|
||||
deleteFile: function() { },
|
||||
getFileData: function() { },
|
||||
getFileLocation: function() { },
|
||||
}
|
||||
expect(() => {
|
||||
new FilesController(adapter);
|
||||
@@ -71,11 +71,11 @@ describe("AdaptableController", ()=>{
|
||||
});
|
||||
|
||||
it("should accept an object adapter", (done) => {
|
||||
function AGoodAdapter() {};
|
||||
AGoodAdapter.prototype.createFile = function(config, filename, data) { };
|
||||
AGoodAdapter.prototype.deleteFile = function(config, filename) { };
|
||||
AGoodAdapter.prototype.getFileData = function(config, filename) { };
|
||||
AGoodAdapter.prototype.getFileLocation = function(config, filename) { };
|
||||
function AGoodAdapter() {}
|
||||
AGoodAdapter.prototype.createFile = function() { };
|
||||
AGoodAdapter.prototype.deleteFile = function() { };
|
||||
AGoodAdapter.prototype.getFileData = function() { };
|
||||
AGoodAdapter.prototype.getFileLocation = function() { };
|
||||
|
||||
var adapter = new AGoodAdapter();
|
||||
expect(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const analyticsAdapter = {
|
||||
appOpened: function(parameters, req) {},
|
||||
trackEvent: function(eventName, parameters, req) {}
|
||||
appOpened: function() {},
|
||||
trackEvent: function() {}
|
||||
}
|
||||
|
||||
describe('AnalyticsController', () => {
|
||||
@@ -9,7 +9,7 @@ describe('AnalyticsController', () => {
|
||||
spyOn(analyticsAdapter, 'trackEvent').and.callThrough();
|
||||
reconfigureServer({
|
||||
analyticsAdapter
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Analytics.track('MyEvent', {
|
||||
key: 'value',
|
||||
count: '0'
|
||||
@@ -26,7 +26,7 @@ describe('AnalyticsController', () => {
|
||||
}
|
||||
});
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
})
|
||||
@@ -37,7 +37,7 @@ describe('AnalyticsController', () => {
|
||||
spyOn(analyticsAdapter, 'appOpened').and.callThrough();
|
||||
reconfigureServer({
|
||||
analyticsAdapter
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Analytics.track('AppOpened', {
|
||||
key: 'value',
|
||||
count: '0'
|
||||
@@ -53,7 +53,7 @@ describe('AnalyticsController', () => {
|
||||
}
|
||||
});
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -4,7 +4,6 @@ describe('Auth', () => {
|
||||
describe('getUserRoles', () => {
|
||||
var auth;
|
||||
var config;
|
||||
var cacheController;
|
||||
var currentRoles = null;
|
||||
var currentUserId = 'userId';
|
||||
|
||||
@@ -51,8 +50,8 @@ describe('Auth', () => {
|
||||
expect(roles).toEqual(currentRoles);
|
||||
return auth.getUserRoles()
|
||||
})
|
||||
.then((roles) => auth.getUserRoles())
|
||||
.then((roles) => auth.getUserRoles())
|
||||
.then(() => auth.getUserRoles())
|
||||
.then(() => auth.getUserRoles())
|
||||
.then((roles) => {
|
||||
// Should only call the cache adapter once.
|
||||
expect(config.cacheController.role.get.calls.count()).toEqual(1);
|
||||
@@ -79,7 +78,7 @@ describe('Auth', () => {
|
||||
.then(() => done());
|
||||
});
|
||||
|
||||
it('should properly handle bcrypt upgrade', (done) => {
|
||||
it('should properly handle bcrypt upgrade', (done) => {
|
||||
var bcryptOriginal = require('bcrypt-nodejs');
|
||||
var bcryptNew = require('bcryptjs');
|
||||
bcryptOriginal.hash('my1Long:password', null, null, function(err, res) {
|
||||
|
||||
@@ -62,13 +62,13 @@ describe('CacheController', function() {
|
||||
|
||||
it('should handle cache rejections', (done) => {
|
||||
|
||||
FakeCacheAdapter.get = () => Promise.reject();
|
||||
FakeCacheAdapter.get = () => Promise.reject();
|
||||
|
||||
var cache = new CacheController(FakeCacheAdapter, FakeAppID);
|
||||
var cache = new CacheController(FakeCacheAdapter, FakeAppID);
|
||||
|
||||
cache.get('foo').then(done, () => {
|
||||
fail('Promise should not be rejected.');
|
||||
});
|
||||
cache.get('foo').then(done, () => {
|
||||
fail('Promise should not be rejected.');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
var ClientSDK = require('../src/ClientSDK');
|
||||
|
||||
describe('ClientSDK', () => {
|
||||
it('should properly parse the SDK versions', () => {
|
||||
let clientSDKFromVersion = ClientSDK.fromString;
|
||||
expect(clientSDKFromVersion('i1.1.1')).toEqual({
|
||||
sdk: 'i',
|
||||
version: '1.1.1'
|
||||
});
|
||||
expect(clientSDKFromVersion('i1')).toEqual({
|
||||
sdk: 'i',
|
||||
version: '1'
|
||||
});
|
||||
expect(clientSDKFromVersion('apple-tv1.13.0')).toEqual({
|
||||
sdk: 'apple-tv',
|
||||
version: '1.13.0'
|
||||
});
|
||||
expect(clientSDKFromVersion('js1.9.0')).toEqual({
|
||||
sdk: 'js',
|
||||
version: '1.9.0'
|
||||
});
|
||||
describe('ClientSDK', () => {
|
||||
it('should properly parse the SDK versions', () => {
|
||||
let clientSDKFromVersion = ClientSDK.fromString;
|
||||
expect(clientSDKFromVersion('i1.1.1')).toEqual({
|
||||
sdk: 'i',
|
||||
version: '1.1.1'
|
||||
});
|
||||
expect(clientSDKFromVersion('i1')).toEqual({
|
||||
sdk: 'i',
|
||||
version: '1'
|
||||
});
|
||||
expect(clientSDKFromVersion('apple-tv1.13.0')).toEqual({
|
||||
sdk: 'apple-tv',
|
||||
version: '1.13.0'
|
||||
});
|
||||
expect(clientSDKFromVersion('js1.9.0')).toEqual({
|
||||
sdk: 'js',
|
||||
version: '1.9.0'
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly sastisfy', () => {
|
||||
it('should properly sastisfy', () => {
|
||||
expect(ClientSDK.compatible({
|
||||
js: '>=1.9.0'
|
||||
})("js1.9.0")).toBe(true);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict"
|
||||
const Parse = require("parse/node");
|
||||
const request = require('request');
|
||||
const rp = require('request-promise');
|
||||
const InMemoryCacheAdapter = require('../src/Adapters/Cache/InMemoryCacheAdapter').InMemoryCacheAdapter;
|
||||
const triggers = require('../src/triggers');
|
||||
|
||||
describe('Cloud Code', () => {
|
||||
it('can load absolute cloud code file', done => {
|
||||
@@ -62,13 +60,15 @@ describe('Cloud Code', () => {
|
||||
|
||||
it('returns an error', (done) => {
|
||||
Parse.Cloud.define('cloudCodeWithError', (req, res) => {
|
||||
/* eslint-disable no-undef */
|
||||
foo.bar();
|
||||
/* eslint-enable no-undef */
|
||||
res.success('I better throw an error.');
|
||||
});
|
||||
|
||||
Parse.Cloud.run('cloudCodeWithError')
|
||||
.then(
|
||||
a => done.fail('should not succeed'),
|
||||
() => done.fail('should not succeed'),
|
||||
e => {
|
||||
expect(e).toEqual(new Parse.Error(1, undefined));
|
||||
done();
|
||||
@@ -96,7 +96,7 @@ describe('Cloud Code', () => {
|
||||
Parse.Cloud.beforeSave('BeforeSaveFailWithPromise', function (req, res) {
|
||||
var query = new Parse.Query('Yolo');
|
||||
query.find().then(() => {
|
||||
res.error('Nope');
|
||||
res.error('Nope');
|
||||
}, () => {
|
||||
res.success();
|
||||
});
|
||||
@@ -145,10 +145,10 @@ describe('Cloud Code', () => {
|
||||
|
||||
var obj = new Parse.Object('BeforeSaveChanged');
|
||||
obj.set('foo', 'bing');
|
||||
obj.save().then(() => {
|
||||
obj.save().then(() => {
|
||||
expect(obj.get('foo')).toEqual('baz');
|
||||
obj.set('foo', 'bar');
|
||||
return obj.save().then(() => {
|
||||
return obj.save().then(() => {
|
||||
expect(obj.get('foo')).toEqual('baz');
|
||||
done();
|
||||
})
|
||||
@@ -180,34 +180,34 @@ describe('Cloud Code', () => {
|
||||
|
||||
it('test afterSave ran on created object and returned a promise', function(done) {
|
||||
Parse.Cloud.afterSave('AfterSaveTest2', function(req) {
|
||||
let obj = req.object;
|
||||
if(!obj.existed())
|
||||
let obj = req.object;
|
||||
if(!obj.existed())
|
||||
{
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
obj.set('proof', obj.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
}, 1000);
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
obj.set('proof', obj.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return promise;
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
let obj = new Parse.Object('AfterSaveTest2');
|
||||
obj.save().then(function(){
|
||||
let query = new Parse.Query('AfterSaveTest2');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(1);
|
||||
let savedObject = results[0];
|
||||
expect(savedObject.get('proof')).toEqual(obj.id);
|
||||
done();
|
||||
},
|
||||
let query = new Parse.Query('AfterSaveTest2');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(1);
|
||||
let savedObject = results[0];
|
||||
expect(savedObject.get('proof')).toEqual(obj.id);
|
||||
done();
|
||||
},
|
||||
function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
fail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -215,124 +215,124 @@ describe('Cloud Code', () => {
|
||||
// TODO: Fails on CI randomly as racing
|
||||
xit('test afterSave ignoring promise, object not found', function(done) {
|
||||
Parse.Cloud.afterSave('AfterSaveTest2', function(req) {
|
||||
let obj = req.object;
|
||||
if(!obj.existed())
|
||||
let obj = req.object;
|
||||
if(!obj.existed())
|
||||
{
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
obj.set('proof', obj.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
}, 1000);
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
obj.set('proof', obj.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return promise;
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
let obj = new Parse.Object('AfterSaveTest2');
|
||||
obj.save().then(function(){
|
||||
done();
|
||||
done();
|
||||
})
|
||||
|
||||
let query = new Parse.Query('AfterSaveTest2');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(0);
|
||||
expect(results.length).toEqual(0);
|
||||
},
|
||||
function(error) {
|
||||
fail(error);
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
|
||||
it('test afterSave rejecting promise', function(done) {
|
||||
Parse.Cloud.afterSave('AfterSaveTest2', function(req) {
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
promise.reject("THIS SHOULD BE IGNORED");
|
||||
}, 1000);
|
||||
Parse.Cloud.afterSave('AfterSaveTest2', function() {
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
promise.reject("THIS SHOULD BE IGNORED");
|
||||
}, 1000);
|
||||
|
||||
return promise;
|
||||
});
|
||||
return promise;
|
||||
});
|
||||
|
||||
let obj = new Parse.Object('AfterSaveTest2');
|
||||
obj.save().then(function(){
|
||||
done();
|
||||
}, function(error){
|
||||
fail(error);
|
||||
done();
|
||||
})
|
||||
let obj = new Parse.Object('AfterSaveTest2');
|
||||
obj.save().then(function(){
|
||||
done();
|
||||
}, function(error){
|
||||
fail(error);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('test afterDelete returning promise, object is deleted when destroy resolves', function(done) {
|
||||
Parse.Cloud.afterDelete('AfterDeleteTest2', function(req) {
|
||||
let promise = new Parse.Promise();
|
||||
Parse.Cloud.afterDelete('AfterDeleteTest2', function(req) {
|
||||
let promise = new Parse.Promise();
|
||||
|
||||
setTimeout(function(){
|
||||
let obj = new Parse.Object('AfterDeleteTestProof');
|
||||
obj.set('proof', req.object.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
setTimeout(function(){
|
||||
let obj = new Parse.Object('AfterDeleteTestProof');
|
||||
obj.set('proof', req.object.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
|
||||
return promise;
|
||||
});
|
||||
return promise;
|
||||
});
|
||||
|
||||
let errorHandler = function(error) {
|
||||
fail(error);
|
||||
let errorHandler = function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
}
|
||||
|
||||
let obj = new Parse.Object('AfterDeleteTest2');
|
||||
obj.save().then(function(){
|
||||
obj.destroy().then(function(){
|
||||
let query = new Parse.Query('AfterDeleteTestProof');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(1);
|
||||
let deletedObject = results[0];
|
||||
expect(deletedObject.get('proof')).toEqual(obj.id);
|
||||
done();
|
||||
}
|
||||
|
||||
let obj = new Parse.Object('AfterDeleteTest2');
|
||||
obj.save().then(function(){
|
||||
obj.destroy().then(function(){
|
||||
let query = new Parse.Query('AfterDeleteTestProof');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(1);
|
||||
let deletedObject = results[0];
|
||||
expect(deletedObject.get('proof')).toEqual(obj.id);
|
||||
done();
|
||||
}, errorHandler);
|
||||
}, errorHandler)
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
}, errorHandler)
|
||||
}, errorHandler);
|
||||
});
|
||||
|
||||
it('test afterDelete ignoring promise, object is not yet deleted', function(done) {
|
||||
Parse.Cloud.afterDelete('AfterDeleteTest2', function(req) {
|
||||
let promise = new Parse.Promise();
|
||||
Parse.Cloud.afterDelete('AfterDeleteTest2', function(req) {
|
||||
let promise = new Parse.Promise();
|
||||
|
||||
setTimeout(function(){
|
||||
let obj = new Parse.Object('AfterDeleteTestProof');
|
||||
obj.set('proof', req.object.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
setTimeout(function(){
|
||||
let obj = new Parse.Object('AfterDeleteTestProof');
|
||||
obj.set('proof', req.object.id);
|
||||
obj.save().then(function(){
|
||||
promise.resolve();
|
||||
});
|
||||
|
||||
}, 1000);
|
||||
}, 1000);
|
||||
|
||||
return promise;
|
||||
});
|
||||
return promise;
|
||||
});
|
||||
|
||||
let errorHandler = function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
}
|
||||
let errorHandler = function(error) {
|
||||
fail(error);
|
||||
done();
|
||||
}
|
||||
|
||||
let obj = new Parse.Object('AfterDeleteTest2');
|
||||
obj.save().then(function(){
|
||||
obj.destroy().then(function(){
|
||||
done();
|
||||
})
|
||||
let obj = new Parse.Object('AfterDeleteTest2');
|
||||
obj.save().then(function(){
|
||||
obj.destroy().then(function(){
|
||||
done();
|
||||
})
|
||||
|
||||
let query = new Parse.Query('AfterDeleteTestProof');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(0);
|
||||
}, errorHandler);
|
||||
let query = new Parse.Query('AfterDeleteTestProof');
|
||||
query.equalTo('proof', obj.id);
|
||||
query.find().then(function(results) {
|
||||
expect(results.length).toEqual(0);
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
});
|
||||
|
||||
it('test beforeSave happens on update', function(done) {
|
||||
@@ -553,7 +553,7 @@ describe('Cloud Code', () => {
|
||||
'array': ['a', 'b', 'c'],
|
||||
'arrayOfArray': [['a', 'b', 'c'], ['d', 'e', 'f']]
|
||||
};
|
||||
Parse.Cloud.run('params', params).then((result) => {
|
||||
Parse.Cloud.run('params', params).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -583,7 +583,7 @@ describe('Cloud Code', () => {
|
||||
|
||||
Parse.Cloud.define('createBeforeSaveChangedObject', function(req, res){
|
||||
var obj = new Parse.Object('BeforeSaveChanged');
|
||||
obj.save().then(() => {
|
||||
obj.save().then(() => {
|
||||
res.success(obj);
|
||||
})
|
||||
})
|
||||
@@ -707,7 +707,7 @@ describe('Cloud Code', () => {
|
||||
obj.save({ foo: 'bar' }).then((objAgain) => {
|
||||
expect(objAgain.get('foo')).toEqual('baz');
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Should not have failed to save.');
|
||||
done();
|
||||
});
|
||||
@@ -720,8 +720,7 @@ describe('Cloud Code', () => {
|
||||
response.success();
|
||||
});
|
||||
|
||||
Parse.Cloud.afterSave('ChangingObject', function(request, response) {
|
||||
let json = request.object.toJSON();
|
||||
Parse.Cloud.afterSave('ChangingObject', function(request) {
|
||||
expect(request.object.has("file")).toBe(false);
|
||||
expect(request.object.has("date")).toBe(false);
|
||||
expect(request.object.get('file')).toBeUndefined();
|
||||
@@ -747,9 +746,9 @@ describe('Cloud Code', () => {
|
||||
return request.params.success === 100;
|
||||
});
|
||||
|
||||
Parse.Cloud.run('functionWithParameterValidation', {"success":100}).then((s) => {
|
||||
Parse.Cloud.run('functionWithParameterValidation', {"success":100}).then(() => {
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Validation should not have failed.');
|
||||
done();
|
||||
});
|
||||
@@ -883,7 +882,7 @@ describe('Cloud Code', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('beforeSave should not affect fetched pointers', done => {
|
||||
it('beforeSave should not affect fetched pointers', done => {
|
||||
Parse.Cloud.beforeSave('BeforeSaveUnchanged', (req, res) => {
|
||||
res.success();
|
||||
});
|
||||
@@ -974,7 +973,7 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
expect(aBeforeSaveObj.get('before')).toEqual('save');
|
||||
expect(aBeforeSaveObj.get('remove')).toEqual(undefined);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -998,15 +997,15 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
let object;
|
||||
let testObject = new TestObject({key: 'value'});
|
||||
testObject.save().then(() => {
|
||||
object = new BeforeSaveObject();
|
||||
return object.save().then(() => {
|
||||
object.set({remove:testObject})
|
||||
return object.save();
|
||||
});
|
||||
object = new BeforeSaveObject();
|
||||
return object.save().then(() => {
|
||||
object.set({remove:testObject})
|
||||
return object.save();
|
||||
});
|
||||
}).then((objectAgain) => {
|
||||
expect(objectAgain.get('remove')).toBeUndefined();
|
||||
expect(object.get('remove')).toBeUndefined();
|
||||
done();
|
||||
expect(objectAgain.get('remove')).toBeUndefined();
|
||||
expect(object.get('remove')).toBeUndefined();
|
||||
done();
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
@@ -1021,7 +1020,7 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
var object = req.object;
|
||||
object.set('before', 'save');
|
||||
testObj = new TestObject();
|
||||
testObj.save().then(() => {
|
||||
testObj.save().then(() => {
|
||||
object.relation('testsRelation').add(testObj);
|
||||
res.success();
|
||||
}, res.error);
|
||||
@@ -1038,10 +1037,10 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
})
|
||||
});
|
||||
|
||||
describe('cloud jobs', () => {
|
||||
it('should define a job', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
describe('cloud jobs', () => {
|
||||
it('should define a job', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
res.success();
|
||||
});
|
||||
}).not.toThrow();
|
||||
@@ -1052,17 +1051,17 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-Master-Key': Parse.masterKey,
|
||||
},
|
||||
}).then((result) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not run without master key', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
it('should not run without master key', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
res.success();
|
||||
});
|
||||
}).not.toThrow();
|
||||
@@ -1073,18 +1072,18 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
},
|
||||
}).then((result) => {
|
||||
}).then(() => {
|
||||
fail('Expected to be unauthorized');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.statusCode).toBe(403);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should run with master key', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
it('should run with master key', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
expect(req.functionName).toBeUndefined();
|
||||
expect(req.jobName).toBe('myJob');
|
||||
expect(typeof req.jobId).toBe('string');
|
||||
@@ -1102,16 +1101,16 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-Master-Key': Parse.masterKey,
|
||||
},
|
||||
}).then((response) => {
|
||||
}, (err) => {
|
||||
}).then(() => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should run with master key basic auth', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
it('should run with master key basic auth', (done) => {
|
||||
expect(() => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
expect(req.functionName).toBeUndefined();
|
||||
expect(req.jobName).toBe('myJob');
|
||||
expect(typeof req.jobId).toBe('string');
|
||||
@@ -1125,25 +1124,25 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
|
||||
rp.post({
|
||||
url: `http://${Parse.applicationId}:${Parse.masterKey}@localhost:8378/1/jobs/myJob`,
|
||||
}).then((response) => {
|
||||
}, (err) => {
|
||||
}).then(() => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should set the message / success on the job', (done) => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
it('should set the message / success on the job', (done) => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
res.message('hello');
|
||||
res.message().then(() => {
|
||||
res.message().then(() => {
|
||||
return getJobStatus(req.jobId);
|
||||
}).then((jobStatus) => {
|
||||
}).then((jobStatus) => {
|
||||
expect(jobStatus.get('message')).toEqual('hello');
|
||||
expect(jobStatus.get('status')).toEqual('running');
|
||||
return res.success().then(() => {
|
||||
return res.success().then(() => {
|
||||
return getJobStatus(req.jobId);
|
||||
});
|
||||
}).then((jobStatus) => {
|
||||
}).then((jobStatus) => {
|
||||
expect(jobStatus.get('message')).toEqual('hello');
|
||||
expect(jobStatus.get('status')).toEqual('succeeded');
|
||||
done();
|
||||
@@ -1160,18 +1159,18 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-Master-Key': Parse.masterKey,
|
||||
},
|
||||
}).then((response) => {
|
||||
}, (err) => {
|
||||
}).then(() => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should set the failure on the job', (done) => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
res.error('Something went wrong').then(() => {
|
||||
it('should set the failure on the job', (done) => {
|
||||
Parse.Cloud.job('myJob', (req, res) => {
|
||||
res.error('Something went wrong').then(() => {
|
||||
return getJobStatus(req.jobId);
|
||||
}).then((jobStatus) => {
|
||||
}).then((jobStatus) => {
|
||||
expect(jobStatus.get('message')).toEqual('Something went wrong');
|
||||
expect(jobStatus.get('status')).toEqual('failed');
|
||||
done();
|
||||
@@ -1187,8 +1186,8 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-Master-Key': Parse.masterKey,
|
||||
},
|
||||
}).then((response) => {
|
||||
}, (err) => {
|
||||
}).then(() => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
@@ -1202,8 +1201,8 @@ it('beforeSave should not affect fetched pointers', done => {
|
||||
});
|
||||
|
||||
describe('beforeFind hooks', () => {
|
||||
it('should add beforeFind trigger', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req, res) => {
|
||||
it('should add beforeFind trigger', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
let q = req.query;
|
||||
expect(q instanceof Parse.Query).toBe(true);
|
||||
let jsonQuery = q.toJSON();
|
||||
@@ -1219,13 +1218,13 @@ describe('beforeFind hooks', () => {
|
||||
query.greaterThan('some', 10);
|
||||
query.include('otherKey');
|
||||
query.include('otherValue');
|
||||
query.find().then(() => {
|
||||
query.find().then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should use modify', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
it('should use modify', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
let q = req.query;
|
||||
q.equalTo('forced', true);
|
||||
});
|
||||
@@ -1235,10 +1234,10 @@ describe('beforeFind hooks', () => {
|
||||
|
||||
let obj1 = new Parse.Object('MyObject');
|
||||
obj1.set('forced', true);
|
||||
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('forced', false);
|
||||
query.find().then((results) => {
|
||||
query.find().then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let firstResult = results[0];
|
||||
expect(firstResult.get('forced')).toBe(true);
|
||||
@@ -1247,8 +1246,8 @@ describe('beforeFind hooks', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the modified the query', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
it('should use the modified the query', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
let q = req.query;
|
||||
let otherQuery = new Parse.Query('MyObject');
|
||||
otherQuery.equalTo('forced', true);
|
||||
@@ -1260,34 +1259,34 @@ describe('beforeFind hooks', () => {
|
||||
|
||||
let obj1 = new Parse.Object('MyObject');
|
||||
obj1.set('forced', true);
|
||||
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('forced', false);
|
||||
query.find().then((results) => {
|
||||
query.find().then((results) => {
|
||||
expect(results.length).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject queries', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
it('should reject queries', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', () => {
|
||||
return Promise.reject('Do not run that query');
|
||||
});
|
||||
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.find().then(() => {
|
||||
query.find().then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(1);
|
||||
expect(err.message).toEqual('Do not run that query');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty where', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
it('should handle empty where', (done) => {
|
||||
Parse.Cloud.beforeFind('MyObject', (req) => {
|
||||
let otherQuery = new Parse.Query('MyObject');
|
||||
otherQuery.equalTo('some', true);
|
||||
return Parse.Query.or(req.query, otherQuery);
|
||||
@@ -1299,9 +1298,9 @@ describe('beforeFind hooks', () => {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
},
|
||||
}).then((result) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
});
|
||||
@@ -1397,19 +1396,19 @@ describe('afterFind hooks', () => {
|
||||
obj.save().then(function() {
|
||||
let query = new Parse.Query('MyObject');
|
||||
query.equalTo('objectId',obj.id);
|
||||
query.find().then(function(results) {
|
||||
query.find().then(function() {
|
||||
fail("AfterFind should handle response failure correctly");
|
||||
done();
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should also work with promise',(done) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req, res) => {
|
||||
Parse.Cloud.afterFind('MyObject', (req) => {
|
||||
let promise = new Parse.Promise();
|
||||
setTimeout(function(){
|
||||
for(let i = 0 ; i < req.objects.length ; i++){
|
||||
|
||||
@@ -6,215 +6,215 @@ const fs = require('fs');
|
||||
const loremFile = __dirname + '/support/lorem.txt';
|
||||
|
||||
describe("Cloud Code Logger", () => {
|
||||
let user;
|
||||
let user;
|
||||
|
||||
beforeEach(done => {
|
||||
Parse.User.enableUnsafeCurrentUser();
|
||||
return reconfigureServer({
|
||||
beforeEach(done => {
|
||||
Parse.User.enableUnsafeCurrentUser();
|
||||
return reconfigureServer({
|
||||
// useful to flip to false for fine tuning :).
|
||||
silent: true,
|
||||
}).then(() => {
|
||||
return Parse.User.signUp('tester', 'abc')
|
||||
silent: true,
|
||||
}).then(() => {
|
||||
return Parse.User.signUp('tester', 'abc')
|
||||
.then(loggedInUser => user = loggedInUser)
|
||||
.then(() => Parse.User.logIn(user.get('username'), 'abc'))
|
||||
.then(() => done())
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Note that helpers takes care of logout.
|
||||
// see helpers.js:afterEach
|
||||
|
||||
it("should expose log to functions", done => {
|
||||
var logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
it("should expose log to functions", done => {
|
||||
var logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.define("loggerTest", (req, res) => {
|
||||
req.log.info('logTest', 'info log', { info: 'some log' });
|
||||
req.log.error('logTest', 'error log', { error: 'there was an error' });
|
||||
res.success({});
|
||||
});
|
||||
|
||||
Parse.Cloud.run('loggerTest').then(() => {
|
||||
return logController.getLogs({ from: Date.now() - 500, size: 1000 });
|
||||
}).then((res) => {
|
||||
expect(res.length).not.toBe(0);
|
||||
let lastLogs = res.slice(0, 3);
|
||||
let cloudFunctionMessage = lastLogs[0];
|
||||
let errorMessage = lastLogs[1];
|
||||
let infoMessage = lastLogs[2];
|
||||
expect(cloudFunctionMessage.level).toBe('info');
|
||||
expect(cloudFunctionMessage.params).toEqual({});
|
||||
expect(cloudFunctionMessage.message).toMatch(/Ran cloud function loggerTest for user [^ ]* with:\n Input: {}\n Result: {}/);
|
||||
expect(cloudFunctionMessage.functionName).toEqual('loggerTest');
|
||||
expect(errorMessage.level).toBe('error');
|
||||
expect(errorMessage.error).toBe('there was an error');
|
||||
expect(errorMessage.message).toBe('logTest error log');
|
||||
expect(infoMessage.level).toBe('info');
|
||||
expect(infoMessage.info).toBe('some log');
|
||||
expect(infoMessage.message).toBe('logTest info log');
|
||||
done();
|
||||
});
|
||||
Parse.Cloud.define("loggerTest", (req, res) => {
|
||||
req.log.info('logTest', 'info log', { info: 'some log' });
|
||||
req.log.error('logTest', 'error log', { error: 'there was an error' });
|
||||
res.success({});
|
||||
});
|
||||
|
||||
it('trigger should obfuscate password', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
Parse.Cloud.run('loggerTest').then(() => {
|
||||
return logController.getLogs({ from: Date.now() - 500, size: 1000 });
|
||||
}).then((res) => {
|
||||
expect(res.length).not.toBe(0);
|
||||
let lastLogs = res.slice(0, 3);
|
||||
let cloudFunctionMessage = lastLogs[0];
|
||||
let errorMessage = lastLogs[1];
|
||||
let infoMessage = lastLogs[2];
|
||||
expect(cloudFunctionMessage.level).toBe('info');
|
||||
expect(cloudFunctionMessage.params).toEqual({});
|
||||
expect(cloudFunctionMessage.message).toMatch(/Ran cloud function loggerTest for user [^ ]* with:\n {2}Input: {}\n {2}Result: {}/);
|
||||
expect(cloudFunctionMessage.functionName).toEqual('loggerTest');
|
||||
expect(errorMessage.level).toBe('error');
|
||||
expect(errorMessage.error).toBe('there was an error');
|
||||
expect(errorMessage.message).toBe('logTest error log');
|
||||
expect(infoMessage.level).toBe('info');
|
||||
expect(infoMessage.info).toBe('some log');
|
||||
expect(infoMessage.message).toBe('logTest info log');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Parse.Cloud.beforeSave(Parse.User, (req, res) => {
|
||||
res.success(req.object);
|
||||
});
|
||||
it('trigger should obfuscate password', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.User.signUp('tester123', 'abc')
|
||||
Parse.Cloud.beforeSave(Parse.User, (req, res) => {
|
||||
res.success(req.object);
|
||||
});
|
||||
|
||||
Parse.User.signUp('tester123', 'abc')
|
||||
.then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then((res) => {
|
||||
const entry = res[0];
|
||||
expect(entry.message).not.toMatch(/password":"abc/);
|
||||
expect(entry.message).toMatch(/\*\*\*\*\*\*\*\*/);
|
||||
done();
|
||||
const entry = res[0];
|
||||
expect(entry.message).not.toMatch(/password":"abc/);
|
||||
expect(entry.message).toMatch(/\*\*\*\*\*\*\*\*/);
|
||||
done();
|
||||
})
|
||||
.then(null, e => done.fail(e));
|
||||
});
|
||||
|
||||
it("should expose log to trigger", (done) => {
|
||||
var logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
req.log.info('beforeSave MyObject', 'info log', { info: 'some log' });
|
||||
req.log.error('beforeSave MyObject', 'error log', { error: 'there was an error' });
|
||||
res.success({});
|
||||
});
|
||||
|
||||
it("should expose log to trigger", (done) => {
|
||||
var logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.save().then(() => {
|
||||
return logController.getLogs({ from: Date.now() - 500, size: 1000 })
|
||||
}).then((res) => {
|
||||
expect(res.length).not.toBe(0);
|
||||
let lastLogs = res.slice(0, 3);
|
||||
let cloudTriggerMessage = lastLogs[0];
|
||||
let errorMessage = lastLogs[1];
|
||||
let infoMessage = lastLogs[2];
|
||||
expect(cloudTriggerMessage.level).toBe('info');
|
||||
expect(cloudTriggerMessage.triggerType).toEqual('beforeSave');
|
||||
expect(cloudTriggerMessage.message).toMatch(/beforeSave triggered for MyObject for user [^ ]*\n {2}Input: {}\n {2}Result: {}/);
|
||||
expect(cloudTriggerMessage.user).toBe(user.id);
|
||||
expect(errorMessage.level).toBe('error');
|
||||
expect(errorMessage.error).toBe('there was an error');
|
||||
expect(errorMessage.message).toBe('beforeSave MyObject error log');
|
||||
expect(infoMessage.level).toBe('info');
|
||||
expect(infoMessage.info).toBe('some log');
|
||||
expect(infoMessage.message).toBe('beforeSave MyObject info log');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
req.log.info('beforeSave MyObject', 'info log', { info: 'some log' });
|
||||
req.log.error('beforeSave MyObject', 'error log', { error: 'there was an error' });
|
||||
res.success({});
|
||||
});
|
||||
it('should truncate really long lines when asked to', () => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
const longString = fs.readFileSync(loremFile, 'utf8');
|
||||
const truncatedString = logController.truncateLogMessage(longString);
|
||||
expect(truncatedString.length).toBe(1015); // truncate length + the string '... (truncated)'
|
||||
});
|
||||
|
||||
let obj = new Parse.Object('MyObject');
|
||||
obj.save().then(() => {
|
||||
return logController.getLogs({ from: Date.now() - 500, size: 1000 })
|
||||
}).then((res) => {
|
||||
expect(res.length).not.toBe(0);
|
||||
let lastLogs = res.slice(0, 3);
|
||||
let cloudTriggerMessage = lastLogs[0];
|
||||
let errorMessage = lastLogs[1];
|
||||
let infoMessage = lastLogs[2];
|
||||
expect(cloudTriggerMessage.level).toBe('info');
|
||||
expect(cloudTriggerMessage.triggerType).toEqual('beforeSave');
|
||||
expect(cloudTriggerMessage.message).toMatch(/beforeSave triggered for MyObject for user [^ ]*\n Input: {}\n Result: {}/);
|
||||
expect(cloudTriggerMessage.user).toBe(user.id);
|
||||
expect(errorMessage.level).toBe('error');
|
||||
expect(errorMessage.error).toBe('there was an error');
|
||||
expect(errorMessage.message).toBe('beforeSave MyObject error log');
|
||||
expect(infoMessage.level).toBe('info');
|
||||
expect(infoMessage.info).toBe('some log');
|
||||
expect(infoMessage.message).toBe('beforeSave MyObject info log');
|
||||
done();
|
||||
});
|
||||
it('should truncate input and result of long lines', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
const longString = fs.readFileSync(loremFile, 'utf8');
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.success(req.params);
|
||||
});
|
||||
|
||||
it('should truncate really long lines when asked to', () => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
const longString = fs.readFileSync(loremFile, 'utf8');
|
||||
const truncatedString = logController.truncateLogMessage(longString);
|
||||
expect(truncatedString.length).toBe(1015); // truncate length + the string '... (truncated)'
|
||||
});
|
||||
|
||||
it('should truncate input and result of long lines', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
const longString = fs.readFileSync(loremFile, 'utf8');
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.success(req.params);
|
||||
});
|
||||
|
||||
Parse.Cloud.run('aFunction', { longString })
|
||||
Parse.Cloud.run('aFunction', { longString })
|
||||
.then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then(logs => {
|
||||
const log = logs[0];
|
||||
expect(log.level).toEqual('info');
|
||||
expect(log.message).toMatch(
|
||||
/Ran cloud function aFunction for user [^ ]* with:\n Input: {.*?\(truncated\)$/m);
|
||||
done();
|
||||
const log = logs[0];
|
||||
expect(log.level).toEqual('info');
|
||||
expect(log.message).toMatch(
|
||||
/Ran cloud function aFunction for user [^ ]* with:\n {2}Input: {.*?\(truncated\)$/m);
|
||||
done();
|
||||
})
|
||||
.then(null, e => done.fail(e));
|
||||
});
|
||||
});
|
||||
|
||||
it('should log an afterSave', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
Parse.Cloud.afterSave("MyObject", (req) => { });
|
||||
new Parse.Object('MyObject')
|
||||
it('should log an afterSave', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
Parse.Cloud.afterSave("MyObject", () => { });
|
||||
new Parse.Object('MyObject')
|
||||
.save()
|
||||
.then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then((logs) => {
|
||||
const log = logs[0];
|
||||
expect(log.triggerType).toEqual('afterSave');
|
||||
done();
|
||||
const log = logs[0];
|
||||
expect(log.triggerType).toEqual('afterSave');
|
||||
done();
|
||||
})
|
||||
// catch errors - not that the error is actually useful :(
|
||||
.then(null, e => done.fail(e));
|
||||
});
|
||||
|
||||
it('should log a denied beforeSave', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
res.error('uh oh!');
|
||||
});
|
||||
|
||||
it('should log a denied beforeSave', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
res.error('uh oh!');
|
||||
});
|
||||
|
||||
new Parse.Object('MyObject')
|
||||
new Parse.Object('MyObject')
|
||||
.save()
|
||||
.then(
|
||||
() => done.fail('this is not supposed to succeed'),
|
||||
e => logController.getLogs({ from: Date.now() - 500, size: 1000 })
|
||||
() => logController.getLogs({ from: Date.now() - 500, size: 1000 })
|
||||
)
|
||||
.then(logs => {
|
||||
const log = logs[1]; // 0 is the 'uh oh!' from rejection...
|
||||
expect(log.level).toEqual('error');
|
||||
expect(log.error).toEqual({ code: 141, message: 'uh oh!' });
|
||||
done()
|
||||
const log = logs[1]; // 0 is the 'uh oh!' from rejection...
|
||||
expect(log.level).toEqual('error');
|
||||
expect(log.error).toEqual({ code: 141, message: 'uh oh!' });
|
||||
done()
|
||||
});
|
||||
});
|
||||
|
||||
it('should log cloud function success', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.success('it worked!');
|
||||
});
|
||||
|
||||
it('should log cloud function success', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.success('it worked!');
|
||||
});
|
||||
|
||||
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
||||
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
||||
.then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then(logs => {
|
||||
const log = logs[0];
|
||||
expect(log.level).toEqual('info');
|
||||
expect(log.message).toMatch(
|
||||
/Ran cloud function aFunction for user [^ ]* with:\n Input: {"foo":"bar"}\n Result: "it worked!/);
|
||||
done();
|
||||
const log = logs[0];
|
||||
expect(log.level).toEqual('info');
|
||||
expect(log.message).toMatch(
|
||||
/Ran cloud function aFunction for user [^ ]* with:\n {2}Input: {"foo":"bar"}\n {2}Result: "it worked!/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should log cloud function failure', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.error('it failed!');
|
||||
});
|
||||
|
||||
it('should log cloud function failure', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.define('aFunction', (req, res) => {
|
||||
res.error('it failed!');
|
||||
});
|
||||
|
||||
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
||||
Parse.Cloud.run('aFunction', { foo: 'bar' })
|
||||
.then(null, () => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then(logs => {
|
||||
const log = logs[1];
|
||||
expect(log.level).toEqual('error');
|
||||
expect(log.message).toMatch(
|
||||
/Failed running cloud function aFunction for user [^ ]* with:\n Input: {"foo":"bar"}\n Error: {"code":141,"message":"it failed!"}/);
|
||||
done();
|
||||
const log = logs[1];
|
||||
expect(log.level).toEqual('error');
|
||||
expect(log.message).toMatch(
|
||||
/Failed running cloud function aFunction for user [^ ]* with:\n {2}Input: {"foo":"bar"}\n {2}Error: {"code":141,"message":"it failed!"}/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
xit('should log a changed beforeSave indicating a change', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
const myObj = req.object;
|
||||
myObj.set('aChange', true);
|
||||
res.success(myObj);
|
||||
});
|
||||
|
||||
xit('should log a changed beforeSave indicating a change', done => {
|
||||
const logController = new LoggerController(new WinstonLoggerAdapter());
|
||||
|
||||
Parse.Cloud.beforeSave("MyObject", (req, res) => {
|
||||
const myObj = req.object;
|
||||
myObj.set('aChange', true);
|
||||
res.success(myObj);
|
||||
});
|
||||
|
||||
new Parse.Object('MyObject')
|
||||
new Parse.Object('MyObject')
|
||||
.save()
|
||||
.then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
|
||||
.then(logs => {
|
||||
.then(() => {
|
||||
// expect the log to indicate that it has changed
|
||||
/*
|
||||
Here's what it looks like on parse.com...
|
||||
@@ -222,8 +222,8 @@ describe("Cloud Code Logger", () => {
|
||||
Input: {"original":{"clientVersion":"1","createdAt":"2016-06-02T05:29:08.694Z","image":{"__type":"File","name":"tfss-xxxxxxxx.png","url":"http://files.parsetfss.com/xxxxxxxx.png"},"lastScanDate":{"__type":"Date","iso":"2016-06-02T05:28:58.135Z"},"localIdentifier":"XXXXX","objectId":"OFHMX7ZUcI","status":... (truncated)
|
||||
Result: Update changed to {"object":{"__type":"Pointer","className":"Emoticode","objectId":"ksrq7z3Ehc"},"imageThumb":{"__type":"File","name":"tfss-xxxxxxx.png","url":"http://files.parsetfss.com/xxxxx.png"},"status":"success"}
|
||||
*/
|
||||
done();
|
||||
done();
|
||||
})
|
||||
.then(null, e => done.fail(JSON.stringify(e)));
|
||||
}).pend('needs more work.....');
|
||||
}).pend('needs more work.....');
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const MockEmailAdapterWithOptions = require('./MockEmailAdapterWithOptions');
|
||||
const request = require('request');
|
||||
const Config = require('../src/Config');
|
||||
|
||||
@@ -34,8 +33,8 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
expect(sendEmailOptions).not.toBeUndefined();
|
||||
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done();
|
||||
@@ -75,21 +74,21 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
expect(sendEmailOptions).not.toBeUndefined();
|
||||
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
user.fetch()
|
||||
.then(() => {
|
||||
expect(user.get('emailVerified')).toEqual(false);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(() => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 1000);
|
||||
}).catch((err) => {
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -119,13 +118,13 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
return user.signUp();
|
||||
}).then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/verify_email_success.html?username=testEmailVerifyTokenValidity');
|
||||
done();
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -155,20 +154,20 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
return user.signUp();
|
||||
}).then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
user.fetch()
|
||||
.then(() => {
|
||||
expect(user.get('emailVerified')).toEqual(true);
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -198,8 +197,8 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
return user.signUp();
|
||||
}).then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
Parse.User.logIn("testEmailVerifyTokenValidity", "expiringToken")
|
||||
.then(user => {
|
||||
@@ -212,7 +211,7 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -252,6 +251,7 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
expect(user.emailVerified).toEqual(false);
|
||||
expect(typeof user._email_verify_token).toBe('string');
|
||||
expect(typeof user._email_verify_token_expires_at).toBe('object');
|
||||
expect(sendEmailOptions).toBeDefined();
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -285,11 +285,11 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
})
|
||||
.then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
let config = new Config('test');
|
||||
return config.database.find('_User', {username: 'unsets_email_verify_token_expires_at'}).then((results) => {
|
||||
return config.database.find('_User', {username: 'unsets_email_verify_token_expires_at'}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
return results[0];
|
||||
})
|
||||
@@ -355,14 +355,14 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
})
|
||||
.then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -405,14 +405,14 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
})
|
||||
.then(() => {
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -420,8 +420,6 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
|
||||
it('setting the email on the user should set a new email verification token and new expiration date for the token when expire email verify token flag is set', done => {
|
||||
|
||||
let db;
|
||||
|
||||
let user = new Parse.User();
|
||||
let userBeforeEmailReset;
|
||||
|
||||
@@ -450,7 +448,7 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
})
|
||||
.then(() => {
|
||||
let config = new Config('test');
|
||||
return config.database.find('_User', {username: 'newEmailVerifyTokenOnEmailReset'}).then((results) => {
|
||||
return config.database.find('_User', {username: 'newEmailVerifyTokenOnEmailReset'}).then((results) => {
|
||||
return results[0];
|
||||
});
|
||||
})
|
||||
@@ -460,14 +458,14 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
|
||||
// trigger another token generation by setting the email
|
||||
user.set('email', 'user@parse.com');
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
// wait for half a sec to get a new expiration time
|
||||
setTimeout( () => resolve(user.save()), 500 );
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
let config = new Config('test');
|
||||
return config.database.find('_User', {username: 'newEmailVerifyTokenOnEmailReset'}).then((results) => {
|
||||
return config.database.find('_User', {username: 'newEmailVerifyTokenOnEmailReset'}).then((results) => {
|
||||
return results[0];
|
||||
});
|
||||
})
|
||||
@@ -475,9 +473,10 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
expect(typeof userAfterEmailReset).toBe('object');
|
||||
expect(userBeforeEmailReset._email_verify_token).not.toEqual(userAfterEmailReset._email_verify_token);
|
||||
expect(userBeforeEmailReset._email_verify_token_expires_at).not.toEqual(userAfterEmailReset.__email_verify_token_expires_at);
|
||||
expect(sendEmailOptions).toBeDefined();
|
||||
done();
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
@@ -512,6 +511,7 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
.then(() => {
|
||||
expect(user.get('emailVerified')).toEqual(false);
|
||||
expect(typeof user.get('_email_verify_token_expires_at')).toBe('undefined');
|
||||
expect(sendEmailOptions).toBeDefined();
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -519,7 +519,7 @@ describe("Email Verification Token Expiration: ", () => {
|
||||
done();
|
||||
});
|
||||
|
||||
}).catch((err) => {
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('Enable single schema cache', () => {
|
||||
config = fakeRequestForConfig();
|
||||
nobody = auth.nobody(config);
|
||||
return rest.find(config, nobody, 'Bar', {type: 1});
|
||||
}).then((response) => {
|
||||
}).then(() => {
|
||||
fail('Should throw error');
|
||||
done();
|
||||
}, (error) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('EventEmitterPubSub', function() {
|
||||
subscriber.unsubscribe('testChannel');
|
||||
// Register mock checked for subscriber
|
||||
var isCalled = false;
|
||||
subscriber.on('message', function(channel, message) {
|
||||
subscriber.on('message', function() {
|
||||
isCalled = true;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var httpRequest = require("../src/cloud-code/httpRequest"),
|
||||
HTTPResponse = require('../src/cloud-code/HTTPResponse').default,
|
||||
bodyParser = require('body-parser'),
|
||||
express = require("express");
|
||||
HTTPResponse = require('../src/cloud-code/HTTPResponse').default,
|
||||
bodyParser = require('body-parser'),
|
||||
express = require("express");
|
||||
|
||||
var port = 13371;
|
||||
var httpRequestServer = "http://localhost:"+port;
|
||||
@@ -125,7 +125,7 @@ describe("httpRequest", () => {
|
||||
it("should fail on 404", (done) => {
|
||||
httpRequest({
|
||||
url: httpRequestServer+"/404",
|
||||
}).then(function(httpResponse){
|
||||
}).then(function(){
|
||||
fail("should not succeed");
|
||||
done();
|
||||
}, function(httpResponse){
|
||||
@@ -143,7 +143,7 @@ describe("httpRequest", () => {
|
||||
method: "POST",
|
||||
url: httpRequestServer+"/echo",
|
||||
body: {
|
||||
foo: "bar"
|
||||
foo: "bar"
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -155,7 +155,7 @@ describe("httpRequest", () => {
|
||||
expect(httpResponse.status).toBe(200);
|
||||
expect(httpResponse.data).toEqual({foo: "bar"});
|
||||
done();
|
||||
}, function(httpResponse){
|
||||
}, function(){
|
||||
fail("should not fail");
|
||||
done();
|
||||
})
|
||||
@@ -182,7 +182,7 @@ describe("httpRequest", () => {
|
||||
done();
|
||||
|
||||
})
|
||||
it("should encode a www-form body", (done) => {
|
||||
it("should encode a www-form body", (done) => {
|
||||
let options = {
|
||||
body: {"foo": "bar", "bar": "baz"},
|
||||
headers: {'cOntent-tYpe': 'application/x-www-form-urlencoded'}
|
||||
@@ -220,7 +220,7 @@ describe("httpRequest", () => {
|
||||
httpRequest({
|
||||
url: httpRequestServer+"/qs",
|
||||
params: {
|
||||
foo: "bar"
|
||||
foo: "bar"
|
||||
}
|
||||
}).then(function(httpResponse){
|
||||
expect(httpResponse.status).toBe(200);
|
||||
@@ -269,7 +269,7 @@ describe("httpRequest", () => {
|
||||
|
||||
it('serialized httpResponse correctly with body object', () => {
|
||||
let httpResponse = new HTTPResponse({}, {foo: "bar"});
|
||||
let encodedResponse = Parse._encode(httpResponse);
|
||||
Parse._encode(httpResponse);
|
||||
let serialized = JSON.stringify(httpResponse);
|
||||
let result = JSON.parse(serialized);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ describe('InMemoryCache', function() {
|
||||
|
||||
|
||||
function wait(sleep) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(resolve, sleep);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ describe('InMemoryCacheAdapter', function() {
|
||||
var VALUE = 'world';
|
||||
|
||||
function wait(sleep) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(resolve, sleep);
|
||||
})
|
||||
}
|
||||
@@ -15,8 +15,6 @@ describe('InMemoryCacheAdapter', function() {
|
||||
ttl: NaN
|
||||
});
|
||||
|
||||
var noop = () => {};
|
||||
|
||||
// Verify all methods return promises.
|
||||
Promise.all([
|
||||
cache.put(KEY, VALUE),
|
||||
|
||||
@@ -69,15 +69,15 @@ describe('InstallationsRouter', () => {
|
||||
.then(() => {
|
||||
return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest);
|
||||
}).then(() => {
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var results = res.response.results;
|
||||
expect(results.length).toEqual(1);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var results = res.response.results;
|
||||
expect(results.length).toEqual(1);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('query installations with limit = 0', (done) => {
|
||||
@@ -100,21 +100,21 @@ describe('InstallationsRouter', () => {
|
||||
info: {}
|
||||
};
|
||||
|
||||
var config = new Config('test');
|
||||
new Config('test');
|
||||
var router = new InstallationsRouter();
|
||||
rest.create(config, auth.nobody(config), '_Installation', androidDeviceRequest)
|
||||
.then(() => {
|
||||
return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest);
|
||||
}).then(() => {
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var response = res.response;
|
||||
expect(response.results.length).toEqual(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var response = res.response;
|
||||
expect(response.results.length).toEqual(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('query installations with count = 1', done => {
|
||||
@@ -179,15 +179,15 @@ describe('InstallationsRouter', () => {
|
||||
.then(() => {
|
||||
return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest);
|
||||
}).then(() => {
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var response = res.response;
|
||||
expect(response.results.length).toEqual(0);
|
||||
expect(response.count).toEqual(2);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
return router.handleFind(request);
|
||||
}).then((res) => {
|
||||
var response = res.response;
|
||||
expect(response.results.length).toEqual(0);
|
||||
expect(response.count).toEqual(2);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('Logger', () => {
|
||||
});
|
||||
|
||||
it('should have files transports', (done) => {
|
||||
reconfigureServer().then(() => {
|
||||
reconfigureServer().then(() => {
|
||||
let transports = logging.logger.transports;
|
||||
let transportKeys = Object.keys(transports);
|
||||
expect(transportKeys.length).toBe(3);
|
||||
@@ -33,7 +33,7 @@ describe('Logger', () => {
|
||||
it('should disable files logs', (done) => {
|
||||
reconfigureServer({
|
||||
logsFolder: null
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let transports = logging.logger.transports;
|
||||
let transportKeys = Object.keys(transports);
|
||||
expect(transportKeys.length).toBe(1);
|
||||
@@ -47,8 +47,8 @@ describe('Logger', () => {
|
||||
logsFolder: null,
|
||||
jsonLogs: true,
|
||||
silent: false
|
||||
}).then(() => {
|
||||
let spy = spyOn(process.stdout, 'write');
|
||||
}).then(() => {
|
||||
spyOn(process.stdout, 'write');
|
||||
logging.logger.info('hi', {key: 'value'});
|
||||
expect(process.stdout.write).toHaveBeenCalled();
|
||||
var firstLog = process.stdout.write.calls.first().args[0];
|
||||
@@ -56,7 +56,7 @@ describe('Logger', () => {
|
||||
return reconfigureServer({
|
||||
jsonLogs: false
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('LoggerController', () => {
|
||||
loggerController.getLogs(query).then(function(res) {
|
||||
expect(res.length).not.toBe(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -74,7 +74,7 @@ describe('LoggerController', () => {
|
||||
loggerController.getLogs(query).then(function(res) {
|
||||
expect(res.length).toBe(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
fail("should not fail");
|
||||
done();
|
||||
@@ -84,7 +84,7 @@ describe('LoggerController', () => {
|
||||
|
||||
it('should throw without an adapter', (done) => {
|
||||
expect(() => {
|
||||
var loggerController = new LoggerController();
|
||||
new LoggerController();
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -3,121 +3,121 @@ var AppCache = require('../src/cache').AppCache;
|
||||
|
||||
describe('middlewares', () => {
|
||||
|
||||
var fakeReq, fakeRes;
|
||||
var fakeReq, fakeRes;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeReq = {
|
||||
originalUrl: 'http://example.com/parse/',
|
||||
url: 'http://example.com/',
|
||||
body: {
|
||||
_ApplicationId: 'FakeAppId'
|
||||
},
|
||||
headers: {},
|
||||
get: (key) => {
|
||||
return fakeReq.headers[key.toLowerCase()]
|
||||
}
|
||||
};
|
||||
fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']);
|
||||
AppCache.put(fakeReq.body._ApplicationId, {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
AppCache.del(fakeReq.body._ApplicationId);
|
||||
});
|
||||
|
||||
it('should use _ContentType if provided', (done) => {
|
||||
expect(fakeReq.headers['content-type']).toEqual(undefined);
|
||||
var contentType = 'image/jpeg';
|
||||
fakeReq.body._ContentType = contentType;
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeReq.headers['content-type']).toEqual(contentType);
|
||||
expect(fakeReq.body._ContentType).toEqual(undefined);
|
||||
done()
|
||||
});
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but no key supplied', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but supplied key is incorrect', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but different key is supplied', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-client-key'] = 'clientKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
|
||||
it('should succeed when any one of the configured keys supplied', (done) => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
clientKey: 'clientKey',
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeRes.status).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed when no keys are configured and none supplied', (done) => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey'
|
||||
});
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeRes.status).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
const BodyParams = {
|
||||
clientVersion: '_ClientVersion',
|
||||
installationId: '_InstallationId',
|
||||
sessionToken: '_SessionToken',
|
||||
masterKey: '_MasterKey',
|
||||
javascriptKey: '_JavaScriptKey'
|
||||
beforeEach(() => {
|
||||
fakeReq = {
|
||||
originalUrl: 'http://example.com/parse/',
|
||||
url: 'http://example.com/',
|
||||
body: {
|
||||
_ApplicationId: 'FakeAppId'
|
||||
},
|
||||
headers: {},
|
||||
get: (key) => {
|
||||
return fakeReq.headers[key.toLowerCase()]
|
||||
}
|
||||
};
|
||||
fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']);
|
||||
AppCache.put(fakeReq.body._ApplicationId, {});
|
||||
});
|
||||
|
||||
const BodyKeys = Object.keys(BodyParams);
|
||||
afterEach(() => {
|
||||
AppCache.del(fakeReq.body._ApplicationId);
|
||||
});
|
||||
|
||||
BodyKeys.forEach((infoKey) => {
|
||||
const bodyKey = BodyParams[infoKey];
|
||||
const keyValue = 'Fake' + bodyKey;
|
||||
// javascriptKey is the only one that gets defaulted,
|
||||
const otherKeys = BodyKeys.filter((otherKey) => otherKey !== infoKey && otherKey !== 'javascriptKey');
|
||||
|
||||
it(`it should pull ${bodyKey} into req.info`, (done) => {
|
||||
fakeReq.body[bodyKey] = keyValue;
|
||||
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeReq.body[bodyKey]).toEqual(undefined);
|
||||
expect(fakeReq.info[infoKey]).toEqual(keyValue);
|
||||
|
||||
otherKeys.forEach((otherKey) => {
|
||||
expect(fakeReq.info[otherKey]).toEqual(undefined);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should use _ContentType if provided', (done) => {
|
||||
expect(fakeReq.headers['content-type']).toEqual(undefined);
|
||||
var contentType = 'image/jpeg';
|
||||
fakeReq.body._ContentType = contentType;
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeReq.headers['content-type']).toEqual(contentType);
|
||||
expect(fakeReq.body._ContentType).toEqual(undefined);
|
||||
done()
|
||||
});
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but no key supplied', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but supplied key is incorrect', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
it('should give invalid response when keys are configured but different key is supplied', () => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-client-key'] = 'clientKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes);
|
||||
expect(fakeRes.status).toHaveBeenCalledWith(403);
|
||||
});
|
||||
|
||||
|
||||
it('should succeed when any one of the configured keys supplied', (done) => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
clientKey: 'clientKey',
|
||||
masterKey: 'masterKey',
|
||||
restAPIKey: 'restAPIKey'
|
||||
});
|
||||
fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey';
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeRes.status).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed when no keys are configured and none supplied', (done) => {
|
||||
AppCache.put(fakeReq.body._ApplicationId, {
|
||||
masterKey: 'masterKey'
|
||||
});
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeRes.status).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
const BodyParams = {
|
||||
clientVersion: '_ClientVersion',
|
||||
installationId: '_InstallationId',
|
||||
sessionToken: '_SessionToken',
|
||||
masterKey: '_MasterKey',
|
||||
javascriptKey: '_JavaScriptKey'
|
||||
};
|
||||
|
||||
const BodyKeys = Object.keys(BodyParams);
|
||||
|
||||
BodyKeys.forEach((infoKey) => {
|
||||
const bodyKey = BodyParams[infoKey];
|
||||
const keyValue = 'Fake' + bodyKey;
|
||||
// javascriptKey is the only one that gets defaulted,
|
||||
const otherKeys = BodyKeys.filter((otherKey) => otherKey !== infoKey && otherKey !== 'javascriptKey');
|
||||
|
||||
it(`it should pull ${bodyKey} into req.info`, (done) => {
|
||||
fakeReq.body[bodyKey] = keyValue;
|
||||
|
||||
middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
|
||||
expect(fakeReq.body[bodyKey]).toEqual(undefined);
|
||||
expect(fakeReq.info[infoKey]).toEqual(keyValue);
|
||||
|
||||
otherKeys.forEach((otherKey) => {
|
||||
expect(fakeReq.info[otherKey]).toEqual(undefined);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,21 +1,21 @@
|
||||
module.exports = options => {
|
||||
if (!options) {
|
||||
throw "Options were not provided"
|
||||
}
|
||||
let adapter = {
|
||||
sendVerificationEmail: () => Promise.resolve(),
|
||||
if (!options) {
|
||||
throw "Options were not provided"
|
||||
}
|
||||
let adapter = {
|
||||
sendVerificationEmail: () => Promise.resolve(),
|
||||
sendPasswordResetEmail: () => Promise.resolve(),
|
||||
sendMail: () => Promise.resolve()
|
||||
};
|
||||
if (options.sendMail) {
|
||||
adapter.sendMail = options.sendMail
|
||||
}
|
||||
if (options.sendPasswordResetEmail) {
|
||||
adapter.sendPasswordResetEmail = options.sendPasswordResetEmail
|
||||
}
|
||||
if (options.sendVerificationEmail) {
|
||||
adapter.sendVerificationEmail = options.sendVerificationEmail;
|
||||
}
|
||||
};
|
||||
if (options.sendMail) {
|
||||
adapter.sendMail = options.sendMail
|
||||
}
|
||||
if (options.sendPasswordResetEmail) {
|
||||
adapter.sendPasswordResetEmail = options.sendPasswordResetEmail
|
||||
}
|
||||
if (options.sendVerificationEmail) {
|
||||
adapter.sendVerificationEmail = options.sendVerificationEmail;
|
||||
}
|
||||
|
||||
return adapter;
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ describe('parseObjectToMongoObjectForCreate', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
it('untransforms mongodb number types', (done) => {
|
||||
it('untransforms mongodb number types', (done) => {
|
||||
var input = {
|
||||
long: mongodb.Long.fromNumber(Number.MAX_SAFE_INTEGER),
|
||||
double: new mongodb.Double(Number.MAX_VALUE)
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('OAuth', function() {
|
||||
var path = "/";
|
||||
|
||||
var oauthClient = new OAuth(options);
|
||||
oauthClient.post(path, null, body).then(function(data){
|
||||
oauthClient.post(path, null, body).then(function(){
|
||||
jequal(false, true);
|
||||
done();
|
||||
}).catch(function(){
|
||||
@@ -192,7 +192,7 @@ describe('OAuth', function() {
|
||||
};
|
||||
};
|
||||
|
||||
var ExtendedUser = Parse.User.extend({
|
||||
Parse.User.extend({
|
||||
extended: function() {
|
||||
return true;
|
||||
}
|
||||
@@ -206,13 +206,13 @@ describe('OAuth', function() {
|
||||
};
|
||||
|
||||
var options = {
|
||||
headers: {'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
'X-Parse-Installation-Id': 'yolo',
|
||||
'Content-Type': 'application/json' },
|
||||
url: 'http://localhost:8378/1/users',
|
||||
body: JSON.stringify(jsonBody)
|
||||
};
|
||||
headers: {'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
'X-Parse-Installation-Id': 'yolo',
|
||||
'Content-Type': 'application/json' },
|
||||
url: 'http://localhost:8378/1/users',
|
||||
body: JSON.stringify(jsonBody)
|
||||
};
|
||||
|
||||
return request.post(options, callback);
|
||||
}
|
||||
@@ -227,15 +227,15 @@ describe('OAuth', function() {
|
||||
var sessionToken = b.sessionToken;
|
||||
var q = new Parse.Query("_Session");
|
||||
q.equalTo('sessionToken', sessionToken);
|
||||
q.first({useMasterKey: true}).then((res) => {
|
||||
q.first({useMasterKey: true}).then((res) => {
|
||||
if (!res) {
|
||||
fail('should not fail fetching the session');
|
||||
done();
|
||||
return;
|
||||
fail('should not fail fetching the session');
|
||||
done();
|
||||
return;
|
||||
}
|
||||
expect(res.get("installationId")).toEqual('yolo');
|
||||
done();
|
||||
}).fail((err) => {
|
||||
}).fail(() => {
|
||||
fail('should not fail fetching the session');
|
||||
done();
|
||||
})
|
||||
@@ -305,20 +305,20 @@ describe('OAuth', function() {
|
||||
"User should be linked to myoauth");
|
||||
done();
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking again should succeed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "unlinking should succeed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have worked");
|
||||
done();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('Parse.Push', () => {
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
var badge = body.data.badge;
|
||||
let promises = installations.map((installation) => {
|
||||
let promises = installations.map((installation) => {
|
||||
if (installation.deviceType == "ios") {
|
||||
expect(installation.badge).toEqual(badge);
|
||||
expect(installation.originalBadge+1).toEqual(installation.badge);
|
||||
@@ -47,45 +47,45 @@ describe('Parse.Push', () => {
|
||||
installations.push(installation);
|
||||
}
|
||||
return Parse.Object.saveAll(installations);
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
})
|
||||
}
|
||||
|
||||
it('should properly send push', (done) => {
|
||||
return setup().then(() => {
|
||||
return setup().then(() => {
|
||||
return Parse.Push.send({
|
||||
where: {
|
||||
deviceType: 'ios'
|
||||
},
|
||||
data: {
|
||||
badge: 'Increment',
|
||||
alert: 'Hello world!'
|
||||
}
|
||||
}, {useMasterKey: true})
|
||||
where: {
|
||||
deviceType: 'ios'
|
||||
},
|
||||
data: {
|
||||
badge: 'Increment',
|
||||
alert: 'Hello world!'
|
||||
}
|
||||
}, {useMasterKey: true})
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly send push with lowercaseIncrement', (done) => {
|
||||
return setup().then(() => {
|
||||
return setup().then(() => {
|
||||
return Parse.Push.send({
|
||||
where: {
|
||||
deviceType: 'ios'
|
||||
},
|
||||
data: {
|
||||
badge: 'increment',
|
||||
alert: 'Hello world!'
|
||||
}
|
||||
}, {useMasterKey: true})
|
||||
}).then(() => {
|
||||
where: {
|
||||
deviceType: 'ios'
|
||||
},
|
||||
data: {
|
||||
badge: 'increment',
|
||||
alert: 'Hello world!'
|
||||
}
|
||||
}, {useMasterKey: true})
|
||||
}).then(() => {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -113,7 +113,7 @@ describe('Parse.Push', () => {
|
||||
expect(body.error).toEqual('unauthorized');
|
||||
done();
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -148,7 +148,7 @@ describe('Parse.Push', () => {
|
||||
}
|
||||
done();
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -166,12 +166,12 @@ describe('Parse.Push', () => {
|
||||
alert: 'Hello world!'
|
||||
}
|
||||
}, {useMasterKey: true})
|
||||
}).then((response) => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
}, (err) => {
|
||||
expect(err.code).toEqual(Parse.Error.PUSH_MISCONFIGURED);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('Parse.ACL', () => {
|
||||
// Get
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.get(object.id, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
fail('Should not have retrieved the object.');
|
||||
done();
|
||||
},
|
||||
@@ -1139,7 +1139,7 @@ describe('Parse.ACL', () => {
|
||||
ACL: new Parse.ACL(),
|
||||
foo: "bar"
|
||||
}, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
Parse.User.logOut()
|
||||
.then(() => {
|
||||
Parse.User.logIn("tdurden", "mayhem", {
|
||||
@@ -1211,13 +1211,13 @@ describe('Parse.ACL', () => {
|
||||
}
|
||||
};
|
||||
|
||||
Parse.Cloud.afterSave(Parse.User, req => {
|
||||
Parse.Cloud.afterSave(Parse.User, req => {
|
||||
if (!req.object.existed()) {
|
||||
var user = req.object;
|
||||
var acl = new Parse.ACL(user);
|
||||
user.setACL(acl);
|
||||
user.save(null, {useMasterKey: true}).then(user => {
|
||||
new Parse.Query('_User').get(user.objectId).then(user => {
|
||||
new Parse.Query('_User').get(user.objectId).then(() => {
|
||||
fail('should not have fetched user without public read enabled');
|
||||
done();
|
||||
}, error => {
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
// It would probably be better to refactor them into different files.
|
||||
'use strict';
|
||||
|
||||
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/TestUtils');
|
||||
const deepcopy = require('deepcopy');
|
||||
|
||||
const userSchema = SchemaController.convertSchemaToAdapterSchema({ className: '_User', fields: Object.assign({}, SchemaController.defaultColumns._Default, SchemaController.defaultColumns._User) });
|
||||
|
||||
describe_only_db('mongo')('miscellaneous', () => {
|
||||
describe_only_db('mongo')('miscellaneous', () => {
|
||||
it('test rest_create_app', function(done) {
|
||||
var appId;
|
||||
Parse._request('POST', 'rest_create_app').then((res) => {
|
||||
@@ -86,7 +84,7 @@ describe('miscellaneous', function() {
|
||||
let numCreated = 0;
|
||||
let numFailed = 0;
|
||||
let p1 = createTestUser();
|
||||
p1.then(user => {
|
||||
p1.then(() => {
|
||||
numCreated++;
|
||||
expect(numCreated).toEqual(1);
|
||||
})
|
||||
@@ -96,7 +94,7 @@ describe('miscellaneous', function() {
|
||||
expect(error.code).toEqual(Parse.Error.USERNAME_TAKEN);
|
||||
});
|
||||
let p2 = createTestUser();
|
||||
p2.then(user => {
|
||||
p2.then(() => {
|
||||
numCreated++;
|
||||
expect(numCreated).toEqual(1);
|
||||
})
|
||||
@@ -121,7 +119,7 @@ describe('miscellaneous', function() {
|
||||
user1.setUsername('u1');
|
||||
user1.setEmail('dupe@dupe.dupe');
|
||||
let p1 = user1.signUp();
|
||||
p1.then(user => {
|
||||
p1.then(() => {
|
||||
numCreated++;
|
||||
expect(numCreated).toEqual(1);
|
||||
}, error => {
|
||||
@@ -135,7 +133,7 @@ describe('miscellaneous', function() {
|
||||
user2.setUsername('u2');
|
||||
user2.setEmail('dupe@dupe.dupe');
|
||||
let p2 = user2.signUp();
|
||||
p2.then(user => {
|
||||
p2.then(() => {
|
||||
numCreated++;
|
||||
expect(numCreated).toEqual(1);
|
||||
}, error => {
|
||||
@@ -174,7 +172,7 @@ describe('miscellaneous', function() {
|
||||
user.setUsername('u');
|
||||
return user.signUp()
|
||||
})
|
||||
.then(result => {
|
||||
.then(() => {
|
||||
fail('should not have been able to sign up');
|
||||
done();
|
||||
})
|
||||
@@ -212,7 +210,7 @@ describe('miscellaneous', function() {
|
||||
});
|
||||
});
|
||||
|
||||
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 => {
|
||||
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']))
|
||||
@@ -533,25 +531,25 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
});
|
||||
});
|
||||
|
||||
it('pointer reassign is working properly (#1288)', (done) => {
|
||||
Parse.Cloud.beforeSave('GameScore', (req, res) => {
|
||||
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});
|
||||
var TestObject1 = Parse.Object.extend('TestObject1');
|
||||
var newObj = new TestObject1({'key1': 1});
|
||||
|
||||
return newObj.save().then((newObj) => {
|
||||
obj.set('point' , newObj);
|
||||
res.success();
|
||||
});
|
||||
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(() => {
|
||||
obj.save().then(() => {
|
||||
expect(obj.get('point')).not.toBeUndefined();
|
||||
pointId = obj.get('point').id;
|
||||
expect(pointId).not.toBeUndefined();
|
||||
@@ -816,9 +814,9 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the updated fields on PUT', done => {
|
||||
it('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(( ) => {
|
||||
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',
|
||||
@@ -842,13 +840,13 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
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.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.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);
|
||||
expect(body.f.indexOf('1') > -1).toBe(true);
|
||||
// return nothing on other self
|
||||
expect(body.selfThing).toBeUndefined();
|
||||
// updatedAt is always set
|
||||
@@ -858,7 +856,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
}
|
||||
done();
|
||||
});
|
||||
}).fail((err) => {
|
||||
}).fail(() => {
|
||||
fail('Should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -869,7 +867,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
Parse.Cloud.define('willFail', (req, res) => {
|
||||
res.error('noway');
|
||||
});
|
||||
Parse.Cloud.run('willFail').then((s) => {
|
||||
Parse.Cloud.run('willFail').then(() => {
|
||||
fail('Should not have succeeded.');
|
||||
done();
|
||||
}, (e) => {
|
||||
@@ -884,7 +882,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
Parse.Cloud.define('willFail', (req, res) => {
|
||||
res.error(999, 'noway');
|
||||
});
|
||||
Parse.Cloud.run('willFail').then((s) => {
|
||||
Parse.Cloud.run('willFail').then(() => {
|
||||
fail('Should not have succeeded.');
|
||||
done();
|
||||
}, (e) => {
|
||||
@@ -899,7 +897,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
Parse.Cloud.define('willFail', (req, res) => {
|
||||
res.error('noway');
|
||||
});
|
||||
Parse.Cloud.run('willFail').then((s) => {
|
||||
Parse.Cloud.run('willFail').then(() => {
|
||||
fail('Should not have succeeded.');
|
||||
done();
|
||||
}, (e) => {
|
||||
@@ -933,7 +931,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/GameScore',
|
||||
body: JSON.stringify({ a: 'b' })
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toBe(null);
|
||||
expect(triggerTime).toEqual(2);
|
||||
done();
|
||||
@@ -969,7 +967,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
request.del({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/GameScore/' + JSON.parse(body).objectId
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toBe(null);
|
||||
expect(triggerTime).toEqual(2);
|
||||
done();
|
||||
@@ -1013,7 +1011,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
return request.params.success === 100;
|
||||
});
|
||||
|
||||
Parse.Cloud.run('functionWithParameterValidationFailure', {"success":500}).then((s) => {
|
||||
Parse.Cloud.run('functionWithParameterValidationFailure', {"success":500}).then(() => {
|
||||
fail('Validation should not have succeeded');
|
||||
done();
|
||||
}, (e) => {
|
||||
@@ -1032,7 +1030,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
Parse.Cloud.run('func', {nullParam: null})
|
||||
.then(() => {
|
||||
done()
|
||||
}, e => {
|
||||
}, () => {
|
||||
fail('cloud code call failed');
|
||||
done();
|
||||
});
|
||||
@@ -1049,7 +1047,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
Parse.Cloud.run('dateFunc', {date: date})
|
||||
.then(() => {
|
||||
done()
|
||||
}, e => {
|
||||
}, () => {
|
||||
fail('cloud code call failed');
|
||||
done();
|
||||
});
|
||||
@@ -1124,7 +1122,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
});
|
||||
|
||||
it('fails on invalid function', done => {
|
||||
Parse.Cloud.run('somethingThatDoesDefinitelyNotExist').then((s) => {
|
||||
Parse.Cloud.run('somethingThatDoesDefinitelyNotExist').then(() => {
|
||||
fail('This should have never suceeded');
|
||||
done();
|
||||
}, (e) => {
|
||||
@@ -1178,7 +1176,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
url: 'http://localhost:8378/1/users',
|
||||
body: JSON.stringify(data)
|
||||
};
|
||||
request.post(requestOptions, (error, response, body) => {
|
||||
request.post(requestOptions, (error) => {
|
||||
expect(error).toBe(null);
|
||||
requestOptions.url = 'http://localhost:8378/1/login';
|
||||
request.get(requestOptions, (error, response, body) => {
|
||||
@@ -1193,10 +1191,10 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
it('gets relation fields', (done) => {
|
||||
let object = new Parse.Object('AnObject');
|
||||
let relatedObject = new Parse.Object('RelatedObject');
|
||||
Parse.Object.saveAll([object, relatedObject]).then(() => {
|
||||
Parse.Object.saveAll([object, relatedObject]).then(() => {
|
||||
object.relation('related').add(relatedObject);
|
||||
return object.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
@@ -1216,55 +1214,55 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
})
|
||||
done();
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
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');;
|
||||
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": {
|
||||
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);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
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();
|
||||
})
|
||||
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) => {
|
||||
@@ -1308,25 +1306,25 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
|
||||
it('bans interior keys containing . or $', done => {
|
||||
new Parse.Object('Obj').save({innerObj: {'key with a $': 'fails'}})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
fail('should not succeed')
|
||||
}, error => {
|
||||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||||
return new Parse.Object('Obj').save({innerObj: {'key with a .': 'fails'}});
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
fail('should not succeed')
|
||||
}, error => {
|
||||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||||
return new Parse.Object('Obj').save({innerObj: {innerInnerObj: {'key with $': 'fails'}}});
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
fail('should not succeed')
|
||||
}, error => {
|
||||
expect(error.code).toEqual(Parse.Error.INVALID_NESTED_KEY);
|
||||
return new Parse.Object('Obj').save({innerObj: {innerInnerObj: {'key with .': 'fails'}}});
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
fail('should not succeed')
|
||||
done();
|
||||
}, error => {
|
||||
@@ -1382,7 +1380,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
geoField: [1,2],
|
||||
});
|
||||
done();
|
||||
}).catch((e) => {
|
||||
}).catch((e) => {
|
||||
jfail(e);
|
||||
done();
|
||||
});
|
||||
@@ -1408,7 +1406,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/purge/TestObject',
|
||||
json: true
|
||||
}, (err, res, body) => {
|
||||
}, (err) => {
|
||||
expect(err).toBe(null);
|
||||
let query = new Parse.Query(TestObject);
|
||||
return query.count().then((count) => {
|
||||
@@ -1430,7 +1428,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
headers: headers,
|
||||
uri: 'http://localhost:8378/1/purge/TestObject',
|
||||
json: true
|
||||
}).then(body => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed');
|
||||
}).catch(err => {
|
||||
expect(err.error.error).toEqual('unauthorized: master key is required');
|
||||
@@ -1456,7 +1454,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
let users = role.relation('users');
|
||||
users.add(user);
|
||||
return role.save({}, { useMasterKey: true });
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('_Role');
|
||||
return query.find({ useMasterKey: true });
|
||||
}).then((x) => {
|
||||
@@ -1473,7 +1471,7 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
acl.setRoleWriteAccess('TestRole', true);
|
||||
object.setACL(acl);
|
||||
return object.save();
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('TestObject');
|
||||
return query.find({ sessionToken: user.getSessionToken() });
|
||||
}).then((x) => {
|
||||
@@ -1484,10 +1482,10 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
uri: 'http://localhost:8378/1/purge/_Role',
|
||||
json: true
|
||||
});
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('TestObject');
|
||||
return query.get(object.id, { sessionToken: user.getSessionToken() });
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed');
|
||||
}, (e) => {
|
||||
expect(e.code).toEqual(Parse.Error.OBJECT_NOT_FOUND);
|
||||
@@ -1495,23 +1493,23 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
});
|
||||
});
|
||||
|
||||
it('should not update schema beforeSave #2672', (done) => {
|
||||
it('should not update schema beforeSave #2672', (done) => {
|
||||
Parse.Cloud.beforeSave('MyObject', (request, response) => {
|
||||
if (request.object.get('secret')) {
|
||||
response.error('cannot set secret here');
|
||||
return;
|
||||
response.error('cannot set secret here');
|
||||
return;
|
||||
}
|
||||
response.success();
|
||||
});
|
||||
|
||||
let object = new Parse.Object('MyObject');
|
||||
object.set('key', 'value');
|
||||
object.save().then(() => {
|
||||
object.save().then(() => {
|
||||
return object.save({'secret': 'should not update schema'});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail();
|
||||
done();
|
||||
}, () => {
|
||||
}, () => {
|
||||
return rp({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -1521,11 +1519,11 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
uri: 'http://localhost:8378/1/schemas/MyObject',
|
||||
json: true
|
||||
});
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
let fields = res.fields;
|
||||
expect(fields.secret).toBeUndefined();
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -1533,36 +1531,36 @@ it('ensure that if you try to sign up a user with a unique username and email, b
|
||||
});
|
||||
|
||||
describe_only_db('mongo')('legacy _acl', () => {
|
||||
it('should have _acl when locking down (regression for #2465)', (done) => {
|
||||
it('should have _acl when locking down (regression for #2465)', (done) => {
|
||||
let headers = {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'
|
||||
}
|
||||
rp({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
uri: 'http://localhost:8378/1/classes/Report',
|
||||
body: {
|
||||
ACL: {},
|
||||
name: 'My Report'
|
||||
},
|
||||
json: true
|
||||
}).then(() => {
|
||||
let config = new Config('test');
|
||||
let adapter = config.database.adapter;
|
||||
return adapter._adaptiveCollection("Report")
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
uri: 'http://localhost:8378/1/classes/Report',
|
||||
body: {
|
||||
ACL: {},
|
||||
name: 'My Report'
|
||||
},
|
||||
json: true
|
||||
}).then(() => {
|
||||
let config = new Config('test');
|
||||
let adapter = config.database.adapter;
|
||||
return adapter._adaptiveCollection("Report")
|
||||
.then(collection => collection.find({}))
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let result = results[0];
|
||||
expect(result.name).toEqual('My Report');
|
||||
expect(result._wperm).toEqual([]);
|
||||
expect(result._rperm).toEqual([]);
|
||||
expect(result._acl).toEqual({});
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let result = results[0];
|
||||
expect(result.name).toEqual('My Report');
|
||||
expect(result._wperm).toEqual([]);
|
||||
expect(result._rperm).toEqual([]);
|
||||
expect(result._acl).toEqual({});
|
||||
done();
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('ParseCloudCodePublisher', function() {
|
||||
|
||||
it('can initialize', function() {
|
||||
var config = {}
|
||||
var publisher = new ParseCloudCodePublisher(config);
|
||||
new ParseCloudCodePublisher(config);
|
||||
|
||||
var ParsePubSub = require('../src/LiveQuery/ParsePubSub').ParsePubSub;
|
||||
expect(ParsePubSub.createPublisher).toHaveBeenCalledWith(config);
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('Parse.File testing', () => {
|
||||
'X-Parse-Master-Key': 'test'
|
||||
},
|
||||
url: 'http://localhost:8378/1/files/' + b.name
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(error).toBe(null);
|
||||
expect(response.statusCode).toEqual(200);
|
||||
request.get({
|
||||
@@ -122,7 +122,7 @@ describe('Parse.File testing', () => {
|
||||
'X-Parse-REST-API-Key': 'rest'
|
||||
},
|
||||
url: b.url
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(error).toBe(null);
|
||||
try {
|
||||
expect(response.statusCode).toEqual(404);
|
||||
@@ -370,7 +370,7 @@ describe('Parse.File testing', () => {
|
||||
object.save({
|
||||
file: file
|
||||
}, expectSuccess({
|
||||
success: function(obj) {
|
||||
success: function() {
|
||||
ok(object.toJSON().file.url);
|
||||
done();
|
||||
}
|
||||
@@ -391,7 +391,7 @@ describe('Parse.File testing', () => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
expect(b.name).toMatch(/\.html$/);
|
||||
request.get(b.url, (error, response, body) => {
|
||||
request.get(b.url, (error, response) => {
|
||||
if (!response) {
|
||||
fail('response should be set');
|
||||
return done();
|
||||
@@ -572,10 +572,10 @@ describe('Parse.File testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('return with publicServerURL when provided', done => {
|
||||
it('return with publicServerURL when provided', done => {
|
||||
reconfigureServer({
|
||||
publicServerURL: 'https://mydomain/parse'
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
var file = {
|
||||
__type: 'File',
|
||||
name: '123.txt'
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
obj.set('index', i);
|
||||
objects.push(obj);
|
||||
});
|
||||
Parse.Object.saveAll(objects).then((list) => {
|
||||
Parse.Object.saveAll(objects).then(() => {
|
||||
var query = new Parse.Query(TestObject);
|
||||
var point = new Parse.GeoPoint(1.0, -1.0);
|
||||
query.withinRadians('location', point, 3.14);
|
||||
@@ -99,7 +99,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
obj.set('index', i);
|
||||
objects.push(obj);
|
||||
});
|
||||
Parse.Object.saveAll(objects, function(list) {
|
||||
Parse.Object.saveAll(objects, function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
var point = new Parse.GeoPoint(1.0, -1.0);
|
||||
query.withinRadians('location', point, 3.14 * 0.5);
|
||||
@@ -123,7 +123,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
obj.set('index', i);
|
||||
objects.push(obj);
|
||||
});
|
||||
Parse.Object.saveAll(objects, function(list) {
|
||||
Parse.Object.saveAll(objects, function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
var point = new Parse.GeoPoint(1.0, -1.0);
|
||||
query.withinRadians('location', point, 3.14 * 0.25);
|
||||
@@ -154,7 +154,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
};
|
||||
|
||||
it('geo max distance in km everywhere', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
// Honolulu is 4300 km away from SFO on a sphere ;)
|
||||
@@ -169,7 +169,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in km california', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinKilometers('location', sfo, 3700.0);
|
||||
@@ -185,7 +185,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in km bay area', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinKilometers('location', sfo, 100.0);
|
||||
@@ -200,7 +200,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in km mid peninsula', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinKilometers('location', sfo, 10.0);
|
||||
@@ -214,7 +214,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in miles everywhere', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinMiles('location', sfo, 2600.0);
|
||||
@@ -228,7 +228,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in miles california', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinMiles('location', sfo, 2200.0);
|
||||
@@ -244,7 +244,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in miles bay area', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
// 100km is 62 miles...
|
||||
@@ -260,7 +260,7 @@ describe('Parse.GeoPoint testing', () => {
|
||||
});
|
||||
|
||||
it('geo max distance in miles mid peninsula', (done) => {
|
||||
makeSomeGeoPoints(function(list) {
|
||||
makeSomeGeoPoints(function() {
|
||||
var sfo = new Parse.GeoPoint(37.6189722, -122.3748889);
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.withinMiles('location', sfo, 10.0);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var request = require('request');
|
||||
var Parse = require('parse/node').Parse;
|
||||
let Config = require('../src/Config');
|
||||
|
||||
describe('a GlobalConfig', () => {
|
||||
@@ -18,7 +17,7 @@ describe('a GlobalConfig', () => {
|
||||
{ fields: { objectId: { type: 'Number' }, params: {type: 'Object'}} },
|
||||
query,
|
||||
{ params: { companies: ['US', 'DK'] } }
|
||||
).then(done, (err) => {
|
||||
).then(done, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -123,7 +122,7 @@ describe('a GlobalConfig', () => {
|
||||
expect(body.params).toEqual({});
|
||||
done();
|
||||
});
|
||||
}).catch((e) => {
|
||||
}).catch((e) => {
|
||||
jfail(e);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -15,25 +15,25 @@ app.use(bodyParser.json({ 'type': '*/*' }))
|
||||
app.listen(12345);
|
||||
|
||||
describe('Hooks', () => {
|
||||
it("should have no hooks registered", (done) => {
|
||||
Parse.Hooks.getFunctions().then((res) => {
|
||||
expect(res.constructor).toBe(Array.prototype.constructor);
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should have no hooks registered", (done) => {
|
||||
Parse.Hooks.getFunctions().then((res) => {
|
||||
expect(res.constructor).toBe(Array.prototype.constructor);
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should have no triggers registered", (done) => {
|
||||
Parse.Hooks.getTriggers().then( (res) => {
|
||||
expect(res.constructor).toBe(Array.prototype.constructor);
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should have no triggers registered", (done) => {
|
||||
Parse.Hooks.getTriggers().then( (res) => {
|
||||
expect(res.constructor).toBe(Array.prototype.constructor);
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should CRUD a function registration", (done) => {
|
||||
// Create
|
||||
@@ -55,7 +55,7 @@ describe('Hooks', () => {
|
||||
// delete
|
||||
return Parse.Hooks.removeFunction("My-Test-Function")
|
||||
})
|
||||
.then((res) => {
|
||||
.then(() => {
|
||||
// Find again! but should be deleted
|
||||
return Parse.Hooks.getFunction("My-Test-Function")
|
||||
.then(res => {
|
||||
@@ -78,270 +78,270 @@ describe('Hooks', () => {
|
||||
|
||||
it("should CRUD a trigger registration", (done) => {
|
||||
// Create
|
||||
Parse.Hooks.createTrigger("MyClass","beforeDelete", "http://someurl").then((res) => {
|
||||
expect(res.className).toBe("MyClass");
|
||||
expect(res.triggerName).toBe("beforeDelete");
|
||||
expect(res.url).toBe("http://someurl")
|
||||
Parse.Hooks.createTrigger("MyClass","beforeDelete", "http://someurl").then((res) => {
|
||||
expect(res.className).toBe("MyClass");
|
||||
expect(res.triggerName).toBe("beforeDelete");
|
||||
expect(res.url).toBe("http://someurl")
|
||||
// Find
|
||||
return Parse.Hooks.getTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
}).then((res) => {
|
||||
expect(res).not.toBe(null);
|
||||
expect(res).not.toBe(undefined);
|
||||
expect(res.objectId).toBeUndefined();
|
||||
expect(res.url).toBe("http://someurl");
|
||||
return Parse.Hooks.getTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
fail(err);
|
||||
done();
|
||||
}).then((res) => {
|
||||
expect(res).not.toBe(null);
|
||||
expect(res).not.toBe(undefined);
|
||||
expect(res.objectId).toBeUndefined();
|
||||
expect(res.url).toBe("http://someurl");
|
||||
// delete
|
||||
return Parse.Hooks.updateTrigger("MyClass","beforeDelete", "http://anotherurl");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then((res) => {
|
||||
expect(res.className).toBe("MyClass");
|
||||
expect(res.url).toBe("http://anotherurl")
|
||||
expect(res.objectId).toBeUndefined();
|
||||
return Parse.Hooks.updateTrigger("MyClass","beforeDelete", "http://anotherurl");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then((res) => {
|
||||
expect(res.className).toBe("MyClass");
|
||||
expect(res.url).toBe("http://anotherurl")
|
||||
expect(res.objectId).toBeUndefined();
|
||||
|
||||
return Parse.Hooks.removeTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then((res) => {
|
||||
return Parse.Hooks.removeTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then(() => {
|
||||
// Find again! but should be deleted
|
||||
return Parse.Hooks.getTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then(function(){
|
||||
fail("should not succeed");
|
||||
done();
|
||||
}, (err) => {
|
||||
return Parse.Hooks.getTrigger("MyClass","beforeDelete");
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
}).then(function(){
|
||||
fail("should not succeed");
|
||||
done();
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
expect(err).not.toBe(null);
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe("class MyClass does not exist")
|
||||
} else {
|
||||
} else {
|
||||
fail('should have errored');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail to register hooks without Master Key", (done) => {
|
||||
request.post(Parse.serverURL+"/hooks/functions", {
|
||||
headers: {
|
||||
"X-Parse-Application-Id": Parse.applicationId,
|
||||
"X-Parse-REST-API-Key": Parse.restKey,
|
||||
},
|
||||
body: JSON.stringify({ url: "http://hello.word", functionName: "SomeFunction"})
|
||||
}, (err, res, body) => {
|
||||
body = JSON.parse(body);
|
||||
expect(body.error).toBe("unauthorized");
|
||||
done();
|
||||
})
|
||||
});
|
||||
it("should fail to register hooks without Master Key", (done) => {
|
||||
request.post(Parse.serverURL+"/hooks/functions", {
|
||||
headers: {
|
||||
"X-Parse-Application-Id": Parse.applicationId,
|
||||
"X-Parse-REST-API-Key": Parse.restKey,
|
||||
},
|
||||
body: JSON.stringify({ url: "http://hello.word", functionName: "SomeFunction"})
|
||||
}, (err, res, body) => {
|
||||
body = JSON.parse(body);
|
||||
expect(body.error).toBe("unauthorized");
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it("should fail trying to create two times the same function", (done) => {
|
||||
Parse.Hooks.createFunction("my_new_function", "http://url.com").then( () => {
|
||||
return Parse.Hooks.createFunction("my_new_function", "http://url.com")
|
||||
}, () => {
|
||||
fail("should create a new function");
|
||||
}).then( () => {
|
||||
fail("should not be able to create the same function");
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('function name: my_new_function already exits')
|
||||
}
|
||||
return Parse.Hooks.removeFunction("my_new_function");
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
it("should fail trying to create two times the same function", (done) => {
|
||||
Parse.Hooks.createFunction("my_new_function", "http://url.com").then( () => {
|
||||
return Parse.Hooks.createFunction("my_new_function", "http://url.com")
|
||||
}, () => {
|
||||
fail("should create a new function");
|
||||
}).then( () => {
|
||||
fail("should not be able to create the same function");
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('function name: my_new_function already exits')
|
||||
}
|
||||
return Parse.Hooks.removeFunction("my_new_function");
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it("should fail trying to create two times the same trigger", (done) => {
|
||||
Parse.Hooks.createTrigger("MyClass", "beforeSave", "http://url.com").then( () => {
|
||||
return Parse.Hooks.createTrigger("MyClass", "beforeSave", "http://url.com")
|
||||
}, () => {
|
||||
fail("should create a new trigger");
|
||||
}).then( () => {
|
||||
fail("should not be able to create the same trigger");
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class MyClass already has trigger beforeSave')
|
||||
}
|
||||
return Parse.Hooks.removeTrigger("MyClass", "beforeSave");
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
it("should fail trying to create two times the same trigger", (done) => {
|
||||
Parse.Hooks.createTrigger("MyClass", "beforeSave", "http://url.com").then( () => {
|
||||
return Parse.Hooks.createTrigger("MyClass", "beforeSave", "http://url.com")
|
||||
}, () => {
|
||||
fail("should create a new trigger");
|
||||
}).then( () => {
|
||||
fail("should not be able to create the same trigger");
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class MyClass already has trigger beforeSave')
|
||||
}
|
||||
return Parse.Hooks.removeTrigger("MyClass", "beforeSave");
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it("should fail trying to update a function that don't exist", (done) => {
|
||||
Parse.Hooks.updateFunction("A_COOL_FUNCTION", "http://url.com").then( () => {
|
||||
fail("Should not succeed")
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('no function named: A_COOL_FUNCTION is defined');
|
||||
}
|
||||
return Parse.Hooks.getFunction("A_COOL_FUNCTION")
|
||||
}).then( (res) => {
|
||||
fail("the function should not exist");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('no function named: A_COOL_FUNCTION is defined');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should fail trying to update a function that don't exist", (done) => {
|
||||
Parse.Hooks.updateFunction("A_COOL_FUNCTION", "http://url.com").then( () => {
|
||||
fail("Should not succeed")
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('no function named: A_COOL_FUNCTION is defined');
|
||||
}
|
||||
return Parse.Hooks.getFunction("A_COOL_FUNCTION")
|
||||
}).then(() => {
|
||||
fail("the function should not exist");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('no function named: A_COOL_FUNCTION is defined');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail trying to update a trigger that don't exist", (done) => {
|
||||
Parse.Hooks.updateTrigger("AClassName","beforeSave", "http://url.com").then( () => {
|
||||
fail("Should not succeed")
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class AClassName does not exist');
|
||||
}
|
||||
return Parse.Hooks.getTrigger("AClassName","beforeSave")
|
||||
}).then( (res) => {
|
||||
fail("the function should not exist");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class AClassName does not exist');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should fail trying to update a trigger that don't exist", (done) => {
|
||||
Parse.Hooks.updateTrigger("AClassName","beforeSave", "http://url.com").then( () => {
|
||||
fail("Should not succeed")
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class AClassName does not exist');
|
||||
}
|
||||
return Parse.Hooks.getTrigger("AClassName","beforeSave")
|
||||
}).then(() => {
|
||||
fail("the function should not exist");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.message).toBe('class AClassName does not exist');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should fail trying to create a malformed function", (done) => {
|
||||
Parse.Hooks.createFunction("MyFunction").then( (res) => {
|
||||
fail(res);
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.error).toBe("invalid hook declaration");
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should fail trying to create a malformed function", (done) => {
|
||||
Parse.Hooks.createFunction("MyFunction").then( (res) => {
|
||||
fail(res);
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(143);
|
||||
expect(err.error).toBe("invalid hook declaration");
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail trying to create a malformed function (REST)", (done) => {
|
||||
request.post(Parse.serverURL+"/hooks/functions", {
|
||||
headers: {
|
||||
"X-Parse-Application-Id": Parse.applicationId,
|
||||
"X-Parse-Master-Key": Parse.masterKey,
|
||||
},
|
||||
body: JSON.stringify({ functionName: "SomeFunction"})
|
||||
}, (err, res, body) => {
|
||||
body = JSON.parse(body);
|
||||
expect(body.error).toBe("invalid hook declaration");
|
||||
expect(body.code).toBe(143);
|
||||
done();
|
||||
})
|
||||
});
|
||||
it("should fail trying to create a malformed function (REST)", (done) => {
|
||||
request.post(Parse.serverURL+"/hooks/functions", {
|
||||
headers: {
|
||||
"X-Parse-Application-Id": Parse.applicationId,
|
||||
"X-Parse-Master-Key": Parse.masterKey,
|
||||
},
|
||||
body: JSON.stringify({ functionName: "SomeFunction"})
|
||||
}, (err, res, body) => {
|
||||
body = JSON.parse(body);
|
||||
expect(body.error).toBe("invalid hook declaration");
|
||||
expect(body.code).toBe(143);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
it("should create hooks and properly preload them", (done) => {
|
||||
it("should create hooks and properly preload them", (done) => {
|
||||
|
||||
var promises = [];
|
||||
for (var i = 0; i<5; i++) {
|
||||
promises.push(Parse.Hooks.createTrigger("MyClass"+i, "beforeSave", "http://url.com/beforeSave/"+i));
|
||||
promises.push(Parse.Hooks.createFunction("AFunction"+i, "http://url.com/function"+i));
|
||||
}
|
||||
var promises = [];
|
||||
for (var i = 0; i<5; i++) {
|
||||
promises.push(Parse.Hooks.createTrigger("MyClass"+i, "beforeSave", "http://url.com/beforeSave/"+i));
|
||||
promises.push(Parse.Hooks.createFunction("AFunction"+i, "http://url.com/function"+i));
|
||||
}
|
||||
|
||||
Parse.Promise.when(promises).then(function(results){
|
||||
for (var i=0; i<5; i++) {
|
||||
Parse.Promise.when(promises).then(function(){
|
||||
for (var i=0; i<5; i++) {
|
||||
// Delete everything from memory, as the server just started
|
||||
triggers.removeTrigger("beforeSave", "MyClass"+i, Parse.applicationId);
|
||||
triggers.removeFunction("AFunction"+i, Parse.applicationId);
|
||||
expect(triggers.getTrigger("MyClass"+i, "beforeSave", Parse.applicationId)).toBeUndefined();
|
||||
expect(triggers.getFunction("AFunction"+i, Parse.applicationId)).toBeUndefined();
|
||||
}
|
||||
const hooksController = new HooksController(Parse.applicationId, AppCache.get('test').databaseController);
|
||||
return hooksController.load()
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail('Should properly create all hooks');
|
||||
done();
|
||||
}).then(function() {
|
||||
for (var i=0; i<5; i++) {
|
||||
expect(triggers.getTrigger("MyClass"+i, "beforeSave", Parse.applicationId)).not.toBeUndefined();
|
||||
expect(triggers.getFunction("AFunction"+i, Parse.applicationId)).not.toBeUndefined();
|
||||
}
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail('should properly load all hooks');
|
||||
done();
|
||||
})
|
||||
});
|
||||
triggers.removeTrigger("beforeSave", "MyClass"+i, Parse.applicationId);
|
||||
triggers.removeFunction("AFunction"+i, Parse.applicationId);
|
||||
expect(triggers.getTrigger("MyClass"+i, "beforeSave", Parse.applicationId)).toBeUndefined();
|
||||
expect(triggers.getFunction("AFunction"+i, Parse.applicationId)).toBeUndefined();
|
||||
}
|
||||
const hooksController = new HooksController(Parse.applicationId, AppCache.get('test').databaseController);
|
||||
return hooksController.load()
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail('Should properly create all hooks');
|
||||
done();
|
||||
}).then(function() {
|
||||
for (var i=0; i<5; i++) {
|
||||
expect(triggers.getTrigger("MyClass"+i, "beforeSave", Parse.applicationId)).not.toBeUndefined();
|
||||
expect(triggers.getFunction("AFunction"+i, Parse.applicationId)).not.toBeUndefined();
|
||||
}
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail('should properly load all hooks');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it("should run the function on the test server", (done) => {
|
||||
it("should run the function on the test server", (done) => {
|
||||
|
||||
app.post("/SomeFunction", function(req, res) {
|
||||
res.json({success:"OK!"});
|
||||
});
|
||||
app.post("/SomeFunction", function(req, res) {
|
||||
res.json({success:"OK!"});
|
||||
});
|
||||
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/SomeFunction").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
expect(res).toBe("OK!");
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail calling a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/SomeFunction").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
expect(res).toBe("OK!");
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail calling a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should run the function on the test server", (done) => {
|
||||
it("should run the function on the test server", (done) => {
|
||||
|
||||
app.post("/SomeFunctionError", function(req, res) {
|
||||
res.json({error: {code: 1337, error: "hacking that one!"}});
|
||||
});
|
||||
app.post("/SomeFunctionError", function(req, res) {
|
||||
res.json({error: {code: 1337, error: "hacking that one!"}});
|
||||
});
|
||||
// The function is deleted as the DB is dropped between calls
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/SomeFunctionError").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
fail("Should not succeed calling that function");
|
||||
done();
|
||||
}, (err) => {
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/SomeFunctionError").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function() {
|
||||
fail("Should not succeed calling that function");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
@@ -350,36 +350,36 @@ describe('Hooks', () => {
|
||||
expect(err.message.error).toEqual("hacking that one!");
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should provide X-Parse-Webhook-Key when defined", (done) => {
|
||||
app.post("/ExpectingKey", function(req, res) {
|
||||
if (req.get('X-Parse-Webhook-Key') === 'hook') {
|
||||
res.json({success: "correct key provided"});
|
||||
} else {
|
||||
res.json({error: "incorrect key provided"});
|
||||
}
|
||||
});
|
||||
it("should provide X-Parse-Webhook-Key when defined", (done) => {
|
||||
app.post("/ExpectingKey", function(req, res) {
|
||||
if (req.get('X-Parse-Webhook-Key') === 'hook') {
|
||||
res.json({success: "correct key provided"});
|
||||
} else {
|
||||
res.json({error: "incorrect key provided"});
|
||||
}
|
||||
});
|
||||
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKey").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
expect(res).toBe("correct key provided");
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail calling a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
Parse.Hooks.createFunction("SOME_TEST_FUNCTION", hookServerURL+"/ExpectingKey").then(function(){
|
||||
return Parse.Cloud.run("SOME_TEST_FUNCTION")
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
expect(res).toBe("correct key provided");
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail calling a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should not pass X-Parse-Webhook-Key if not provided", (done) => {
|
||||
reconfigureServer({ webhookKey: undefined })
|
||||
it("should not pass X-Parse-Webhook-Key if not provided", (done) => {
|
||||
reconfigureServer({ webhookKey: undefined })
|
||||
.then(() => {
|
||||
app.post("/ExpectingKeyAlso", function(req, res) {
|
||||
if (req.get('X-Parse-Webhook-Key') === 'hook') {
|
||||
@@ -395,103 +395,103 @@ describe('Hooks', () => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
}).then(function(res){
|
||||
}).then(function(){
|
||||
fail("Should not succeed calling that function");
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(141);
|
||||
expect(err.message).toEqual("incorrect key provided");
|
||||
}
|
||||
done();
|
||||
expect(err).not.toBe(undefined);
|
||||
expect(err).not.toBe(null);
|
||||
if (err) {
|
||||
expect(err.code).toBe(141);
|
||||
expect(err.message).toEqual("incorrect key provided");
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should run the beforeSave hook on the test server", (done) => {
|
||||
var triggerCount = 0;
|
||||
app.post("/BeforeSaveSome", function(req, res) {
|
||||
triggerCount++;
|
||||
var object = req.body.object;
|
||||
object.hello = "world";
|
||||
it("should run the beforeSave hook on the test server", (done) => {
|
||||
var triggerCount = 0;
|
||||
app.post("/BeforeSaveSome", function(req, res) {
|
||||
triggerCount++;
|
||||
var object = req.body.object;
|
||||
object.hello = "world";
|
||||
// Would need parse cloud express to set much more
|
||||
// But this should override the key upon return
|
||||
res.json({success: object});
|
||||
});
|
||||
res.json({success: object});
|
||||
});
|
||||
// The function is delete as the DB is dropped between calls
|
||||
Parse.Hooks.createTrigger("SomeRandomObject", "beforeSave" ,hookServerURL+"/BeforeSaveSome").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject");
|
||||
return obj.save();
|
||||
}).then(function(res) {
|
||||
expect(triggerCount).toBe(1);
|
||||
return res.fetch();
|
||||
}).then(function(res) {
|
||||
expect(res.get("hello")).toEqual("world");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
Parse.Hooks.createTrigger("SomeRandomObject", "beforeSave" ,hookServerURL+"/BeforeSaveSome").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject");
|
||||
return obj.save();
|
||||
}).then(function(res) {
|
||||
expect(triggerCount).toBe(1);
|
||||
return res.fetch();
|
||||
}).then(function(res) {
|
||||
expect(res.get("hello")).toEqual("world");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("beforeSave hooks should correctly handle responses containing entire object", (done) => {
|
||||
app.post("/BeforeSaveSome2", function(req, res) {
|
||||
var object = Parse.Object.fromJSON(req.body.object);
|
||||
object.set('hello', "world");
|
||||
res.json({success: object});
|
||||
});
|
||||
Parse.Hooks.createTrigger("SomeRandomObject2", "beforeSave" ,hookServerURL+"/BeforeSaveSome2").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject2");
|
||||
return obj.save();
|
||||
}).then(function(res) {
|
||||
return res.save();
|
||||
}).then(function(res) {
|
||||
expect(res.get("hello")).toEqual("world");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
fail(`Should not fail: ${JSON.stringify(err)}`);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("beforeSave hooks should correctly handle responses containing entire object", (done) => {
|
||||
app.post("/BeforeSaveSome2", function(req, res) {
|
||||
var object = Parse.Object.fromJSON(req.body.object);
|
||||
object.set('hello', "world");
|
||||
res.json({success: object});
|
||||
});
|
||||
Parse.Hooks.createTrigger("SomeRandomObject2", "beforeSave" ,hookServerURL+"/BeforeSaveSome2").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject2");
|
||||
return obj.save();
|
||||
}).then(function(res) {
|
||||
return res.save();
|
||||
}).then(function(res) {
|
||||
expect(res.get("hello")).toEqual("world");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
fail(`Should not fail: ${JSON.stringify(err)}`);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should run the afterSave hook on the test server", (done) => {
|
||||
var triggerCount = 0;
|
||||
var newObjectId;
|
||||
app.post("/AfterSaveSome", function(req, res) {
|
||||
triggerCount++;
|
||||
var obj = new Parse.Object("AnotherObject");
|
||||
obj.set("foo", "bar");
|
||||
obj.save().then(function(obj){
|
||||
newObjectId = obj.id;
|
||||
res.json({success: {}});
|
||||
})
|
||||
});
|
||||
it("should run the afterSave hook on the test server", (done) => {
|
||||
var triggerCount = 0;
|
||||
var newObjectId;
|
||||
app.post("/AfterSaveSome", function(req, res) {
|
||||
triggerCount++;
|
||||
var obj = new Parse.Object("AnotherObject");
|
||||
obj.set("foo", "bar");
|
||||
obj.save().then(function(obj){
|
||||
newObjectId = obj.id;
|
||||
res.json({success: {}});
|
||||
})
|
||||
});
|
||||
// The function is delete as the DB is dropped between calls
|
||||
Parse.Hooks.createTrigger("SomeRandomObject", "afterSave" ,hookServerURL+"/AfterSaveSome").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject");
|
||||
return obj.save();
|
||||
}).then(function(res){
|
||||
var promise = new Parse.Promise();
|
||||
Parse.Hooks.createTrigger("SomeRandomObject", "afterSave" ,hookServerURL+"/AfterSaveSome").then(function(){
|
||||
const obj = new Parse.Object("SomeRandomObject");
|
||||
return obj.save();
|
||||
}).then(function() {
|
||||
var promise = new Parse.Promise();
|
||||
// Wait a bit here as it's an after save
|
||||
setTimeout(function(){
|
||||
setTimeout(function(){
|
||||
expect(triggerCount).toBe(1);
|
||||
var q = new Parse.Query("AnotherObject");
|
||||
q.get(newObjectId).then(function(r){
|
||||
promise.resolve(r);
|
||||
promise.resolve(r);
|
||||
});
|
||||
}, 300)
|
||||
return promise;
|
||||
}).then(function(res){
|
||||
expect(res.get("foo")).toEqual("bar");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 300)
|
||||
return promise;
|
||||
}).then(function(res){
|
||||
expect(res.get("foo")).toEqual("bar");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
fail("Should not fail creating a function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Ported from installation_collection_test.go
|
||||
|
||||
let auth = require('../src/Auth');
|
||||
let cache = require('../src/cache');
|
||||
let Config = require('../src/Config');
|
||||
let Parse = require('parse/node').Parse;
|
||||
let rest = require('../src/rest');
|
||||
@@ -17,7 +16,7 @@ const installationSchema = { fields: Object.assign({}, defaultColumns._Default,
|
||||
|
||||
describe('Installations', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(() => {
|
||||
config = new Config('test');
|
||||
database = config.database;
|
||||
});
|
||||
@@ -133,7 +132,7 @@ describe('Installations', () => {
|
||||
.then(() => {
|
||||
let query = new Parse.Query(Parse.Installation);
|
||||
return query.find()
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed!');
|
||||
done();
|
||||
}).catch((error) => {
|
||||
@@ -160,7 +159,7 @@ describe('Installations', () => {
|
||||
expect(obj.installationId).toEqual(installId);
|
||||
expect(obj.deviceType).toEqual(device);
|
||||
done();
|
||||
}).catch((error) => {
|
||||
}).catch(() => {
|
||||
fail('Should not fail');
|
||||
done();
|
||||
});
|
||||
@@ -205,7 +204,7 @@ describe('Installations', () => {
|
||||
'channels': ['foo', 'bar'],
|
||||
'custom': 'allowed'
|
||||
};
|
||||
rest.create(config, auth.nobody(config), '_Installation', input)
|
||||
rest.create(config, auth.nobody(config), '_Installation', input)
|
||||
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
||||
.then(results => {
|
||||
expect(results.length).toEqual(1);
|
||||
@@ -220,7 +219,6 @@ describe('Installations', () => {
|
||||
it('merging when installationId already exists', (done) => {
|
||||
var installId1 = '12345678-abcd-abcd-abcd-123456789abc';
|
||||
var t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
||||
var installId2 = '12345678-abcd-abcd-abcd-123456789abd';
|
||||
var input = {
|
||||
'deviceToken': t,
|
||||
'deviceType': 'ios',
|
||||
@@ -426,7 +424,7 @@ describe('Installations', () => {
|
||||
expect(results.length).toEqual(1);
|
||||
expect(results[0].deviceToken).toEqual(u);
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -880,7 +878,7 @@ describe('Installations', () => {
|
||||
'deviceType': device
|
||||
};
|
||||
rest.create(config, auth.nobody(config), '_Installation', input)
|
||||
.then(createResult => {
|
||||
.then(() => {
|
||||
let headers = {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
@@ -936,14 +934,14 @@ describe('Installations', () => {
|
||||
'installationId': installId,
|
||||
'deviceType': device
|
||||
};
|
||||
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
||||
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
||||
let query = new Parse.Query(Parse.Installation);
|
||||
query.equalTo('installationId', installId);
|
||||
query.first({useMasterKey: true}).then((installation) => {
|
||||
return installation.save({
|
||||
key: 'value'
|
||||
}, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err)
|
||||
@@ -959,7 +957,7 @@ describe('Installations', () => {
|
||||
'installationId': installId,
|
||||
'deviceType': device
|
||||
};
|
||||
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
||||
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
||||
let query = new Parse.Query(Parse.Installation);
|
||||
query.equalTo('installationId', installId);
|
||||
query.first({useMasterKey: true}).then((installation) => {
|
||||
@@ -967,7 +965,7 @@ describe('Installations', () => {
|
||||
key: 'value',
|
||||
installationId: '22222222-abcd-abcd-abcd-123456789abc'
|
||||
}, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}, (err) => {
|
||||
|
||||
@@ -159,7 +159,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {});
|
||||
// Add two mock clients
|
||||
var clientId = 1;
|
||||
var client = addMockClient(parseLiveQueryServer, clientId);
|
||||
addMockClient(parseLiveQueryServer, clientId);
|
||||
var clientIdAgain = 2;
|
||||
var clientAgain = addMockClient(parseLiveQueryServer, clientIdAgain);
|
||||
// Add subscription for mock client 1
|
||||
@@ -232,7 +232,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {});
|
||||
// Add mock client
|
||||
var clientId = 1;
|
||||
var client = addMockClient(parseLiveQueryServer, clientId);
|
||||
addMockClient(parseLiveQueryServer, clientId);
|
||||
// Handle unsubscribe command
|
||||
var parseWebSocket = {
|
||||
clientId: 1
|
||||
@@ -274,7 +274,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
expect(subscriptions.size).toBe(0);
|
||||
});
|
||||
|
||||
it('can set connect command message handler for a parseWebSocket', function() {
|
||||
it('can set connect command message handler for a parseWebSocket', function() {
|
||||
var parseLiveQueryServer = new ParseLiveQueryServer(10, 10, {});
|
||||
// Register mock connect/subscribe/unsubscribe handler for the server
|
||||
parseLiveQueryServer._handleConnect = jasmine.createSpy('_handleSubscribe');
|
||||
@@ -533,7 +533,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
// In order to mimic a enter, we need original match return false
|
||||
// and the current match return true
|
||||
var counter = 0;
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject, subscription){
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject){
|
||||
if (!parseObject) {
|
||||
return false;
|
||||
}
|
||||
@@ -567,7 +567,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
var requestId = 2;
|
||||
addMockSubscription(parseLiveQueryServer, clientId, requestId);
|
||||
// Mock _matchesSubscription to return matching
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject, subscription){
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject){
|
||||
if (!parseObject) {
|
||||
return false;
|
||||
}
|
||||
@@ -603,7 +603,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
// In order to mimic a leave, we need original match return true
|
||||
// and the current match return false
|
||||
var counter = 0;
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject, subscription){
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject){
|
||||
if (!parseObject) {
|
||||
return false;
|
||||
}
|
||||
@@ -637,7 +637,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
var requestId = 2;
|
||||
addMockSubscription(parseLiveQueryServer, clientId, requestId);
|
||||
// Mock _matchesSubscription to return matching
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject, subscription){
|
||||
parseLiveQueryServer._matchesSubscription = function(parseObject){
|
||||
if (!parseObject) {
|
||||
return false;
|
||||
}
|
||||
@@ -746,7 +746,6 @@ describe('ParseLiveQueryServer', function() {
|
||||
};
|
||||
var requestId = 0;
|
||||
|
||||
var isChecked = false;
|
||||
parseLiveQueryServer._matchesACL(acl, client, requestId).then(function(isMatched) {
|
||||
expect(isMatched).toBe(false);
|
||||
done();
|
||||
@@ -916,7 +915,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
|
||||
spyOn(Parse, "Query").and.callFake(function(){
|
||||
return {
|
||||
equalTo(relation, value) {
|
||||
equalTo() {
|
||||
// Nothing to do here
|
||||
},
|
||||
find() {
|
||||
@@ -952,7 +951,7 @@ describe('ParseLiveQueryServer', function() {
|
||||
|
||||
spyOn(Parse, "Query").and.callFake(function(){
|
||||
return {
|
||||
equalTo(relation, value) {
|
||||
equalTo() {
|
||||
// Nothing to do here
|
||||
},
|
||||
find() {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
describe('Parse.Object testing', () => {
|
||||
it("create", function(done) {
|
||||
create({ "test" : "test" }, function(model, response) {
|
||||
create({ "test" : "test" }, function(model) {
|
||||
ok(model.id, "Should have an objectId set");
|
||||
equal(model.get("test"), "test", "Should have the right attribute");
|
||||
done();
|
||||
@@ -22,11 +22,11 @@ describe('Parse.Object testing', () => {
|
||||
});
|
||||
|
||||
it("update", function(done) {
|
||||
create({ "test" : "test" }, function(model, response) {
|
||||
create({ "test" : "test" }, function(model) {
|
||||
var t2 = new TestObject({ objectId: model.id });
|
||||
t2.set("test", "changed");
|
||||
t2.save(null, {
|
||||
success: function(model, response) {
|
||||
success: function(model) {
|
||||
equal(model.get("test"), "changed", "Update should have succeeded");
|
||||
done();
|
||||
}
|
||||
@@ -72,10 +72,10 @@ describe('Parse.Object testing', () => {
|
||||
});
|
||||
|
||||
it("get", function(done) {
|
||||
create({ "test" : "test" }, function(model, response) {
|
||||
create({ "test" : "test" }, function(model) {
|
||||
var t2 = new TestObject({ objectId: model.id });
|
||||
t2.fetch({
|
||||
success: function(model2, response) {
|
||||
success: function(model2) {
|
||||
equal(model2.get("test"), "test", "Update should have succeeded");
|
||||
ok(model2.id);
|
||||
equal(model2.id, model.id, "Ids should match");
|
||||
@@ -269,20 +269,19 @@ describe('Parse.Object testing', () => {
|
||||
});
|
||||
|
||||
it_exclude_dbs(['postgres'])("can set null", function(done) {
|
||||
var errored = false;
|
||||
var obj = new Parse.Object("TestObject");
|
||||
obj.set("foo", null);
|
||||
obj.save(null, {
|
||||
success: function(obj) {
|
||||
on_db('mongo', () => {
|
||||
on_db('mongo', () => {
|
||||
equal(obj.get("foo"), null);
|
||||
});
|
||||
on_db('postgres', () => {
|
||||
on_db('postgres', () => {
|
||||
fail('should not succeed');
|
||||
});
|
||||
done();
|
||||
},
|
||||
error: function(obj, error) {
|
||||
error: function() {
|
||||
fail('should not fail');
|
||||
done();
|
||||
}
|
||||
@@ -323,11 +322,11 @@ describe('Parse.Object testing', () => {
|
||||
it("invalid class name", function(done) {
|
||||
var item = new Parse.Object("Foo^bar");
|
||||
item.save(null, {
|
||||
success: function(item) {
|
||||
success: function() {
|
||||
ok(false, "The name should have been invalid.");
|
||||
done();
|
||||
},
|
||||
error: function(item, error) {
|
||||
error: function() {
|
||||
// Because the class name is invalid, the router will not be able to route
|
||||
// it, so it will actually return a -1 error code.
|
||||
// equal(error.code, Parse.Error.INVALID_CLASS_NAME);
|
||||
@@ -346,7 +345,6 @@ describe('Parse.Object testing', () => {
|
||||
it("invalid __type", function(done) {
|
||||
var item = new Parse.Object("Item");
|
||||
var types = ['Pointer', 'File', 'Date', 'GeoPoint', 'Bytes'];
|
||||
var Error = Parse.Error;
|
||||
var tests = types.map(type => {
|
||||
var test = new Parse.Object("Item");
|
||||
test.set('foo', {
|
||||
@@ -368,7 +366,7 @@ describe('Parse.Object testing', () => {
|
||||
"foo": {
|
||||
__type: "IvalidName"
|
||||
}
|
||||
}).then(fail, err => next(0));
|
||||
}).then(fail, () => next(0));
|
||||
});
|
||||
|
||||
it("simple field deletion", function(done) {
|
||||
@@ -609,7 +607,7 @@ describe('Parse.Object testing', () => {
|
||||
on_db('mongo', () => {
|
||||
jfail(error);
|
||||
});
|
||||
on_db('postgres', () => {
|
||||
on_db('postgres', () => {
|
||||
expect(error.message).toEqual("Postgres does not support AddUnique operator.");
|
||||
});
|
||||
done();
|
||||
@@ -688,7 +686,7 @@ describe('Parse.Object testing', () => {
|
||||
|
||||
done();
|
||||
},
|
||||
error: function(object, error) {
|
||||
error: function() {
|
||||
ok(false, "This should have saved.");
|
||||
done();
|
||||
}
|
||||
@@ -1079,7 +1077,7 @@ describe('Parse.Object testing', () => {
|
||||
parent.set('children', [child1, child2]);
|
||||
|
||||
parent.save(null, {
|
||||
success: function(parent) {
|
||||
success: function() {
|
||||
var query = new Parse.Query(Child);
|
||||
query.ascending('name');
|
||||
query.find({
|
||||
@@ -1199,8 +1197,7 @@ describe('Parse.Object testing', () => {
|
||||
});
|
||||
|
||||
it("toJSON saved object", function(done) {
|
||||
var _ = Parse._;
|
||||
create({ "foo" : "bar" }, function(model, response) {
|
||||
create({ "foo" : "bar" }, function(model) {
|
||||
var objJSON = model.toJSON();
|
||||
ok(objJSON.foo, "expected json to contain key 'foo'");
|
||||
ok(objJSON.objectId, "expected json to contain key 'objectId'");
|
||||
@@ -1274,7 +1271,7 @@ describe('Parse.Object testing', () => {
|
||||
return bryan.save({
|
||||
meal: "tomatoes"
|
||||
});
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
ok(false, "Save should have succeeded.");
|
||||
}).then(function() {
|
||||
ok(false, "Save should have failed.");
|
||||
@@ -1474,7 +1471,7 @@ describe('Parse.Object testing', () => {
|
||||
});
|
||||
done();
|
||||
},
|
||||
error: function(error) {
|
||||
error: function() {
|
||||
ok(false, "Failed to fetchAll");
|
||||
done();
|
||||
}
|
||||
@@ -1507,8 +1504,6 @@ describe('Parse.Object testing', () => {
|
||||
|
||||
it("fetchAll error on deleted object", function(done) {
|
||||
var numItems = 11;
|
||||
var container = new Container();
|
||||
var subContainer = new Container();
|
||||
var items = [];
|
||||
for (var i = 0; i < numItems; i++) {
|
||||
var item = new Item();
|
||||
@@ -1639,7 +1634,7 @@ describe('Parse.Object testing', () => {
|
||||
done();
|
||||
},
|
||||
|
||||
error: function(error) {
|
||||
error: function() {
|
||||
ok(false, "Failed to fetchAll");
|
||||
done();
|
||||
}
|
||||
@@ -1763,7 +1758,7 @@ describe('Parse.Object testing', () => {
|
||||
var obj2 = new TestObject();
|
||||
obj2.increment('astring');
|
||||
return obj2.save();
|
||||
}).then((obj2) => {
|
||||
}).then(() => {
|
||||
fail('Should not have saved.');
|
||||
done();
|
||||
}, (error) => {
|
||||
@@ -1850,7 +1845,7 @@ describe('Parse.Object testing', () => {
|
||||
object.save().then( res => {
|
||||
ok(res);
|
||||
return res.fetch();
|
||||
}).then( res => {
|
||||
}).then( res => {
|
||||
const foo = res.get("foo");
|
||||
expect(foo["_bar"]).toEqual("_");
|
||||
expect(foo["baz_bar"]).toEqual(1);
|
||||
@@ -1869,7 +1864,7 @@ describe('Parse.Object testing', () => {
|
||||
let obj1 = new Parse.Object("AnObject");
|
||||
let obj2 = new Parse.Object("AnObject");
|
||||
|
||||
Parse.Object.saveAll([obj1, obj2]).then(() => {
|
||||
Parse.Object.saveAll([obj1, obj2]).then(() => {
|
||||
obj1.set("obj", obj2);
|
||||
// Save the pointer, delete the pointee
|
||||
return obj1.save().then(() => { return obj2.destroy() });
|
||||
@@ -1884,7 +1879,7 @@ describe('Parse.Object testing', () => {
|
||||
}
|
||||
let query = new Parse.Query("AnObject");
|
||||
return query.find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(1);
|
||||
if (res[0]) {
|
||||
expect(res[0].get("obj")).not.toBe(undefined);
|
||||
@@ -1904,7 +1899,7 @@ describe('Parse.Object testing', () => {
|
||||
let obj1 = new Parse.Object("AnObject");
|
||||
let obj2 = new Parse.Object("AnObject");
|
||||
let obj3 = new Parse.Object("AnObject");
|
||||
Parse.Object.saveAll([obj1, obj2, obj3]).then(() => {
|
||||
Parse.Object.saveAll([obj1, obj2, obj3]).then(() => {
|
||||
obj1.set("obj", obj2);
|
||||
obj2.set("obj", obj3);
|
||||
// Save the pointer, delete the pointee
|
||||
@@ -1934,7 +1929,7 @@ describe('Parse.Object testing', () => {
|
||||
"key": obj3
|
||||
})
|
||||
|
||||
Parse.Object.saveAll([obj1, obj2]).then(() => {
|
||||
Parse.Object.saveAll([obj1, obj2]).then(() => {
|
||||
obj1.set("objects", [null, null, obj2]);
|
||||
return obj1.save();
|
||||
}).then(() => {
|
||||
@@ -1963,7 +1958,7 @@ describe('Parse.Object testing', () => {
|
||||
"score": 1234
|
||||
});
|
||||
|
||||
score.save().then(() => {
|
||||
score.save().then(() => {
|
||||
player.set("gameScore", score);
|
||||
player.set("other", "value");
|
||||
return player.save();
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('ParsePubSub', function() {
|
||||
});
|
||||
|
||||
it('can create redis publisher', function() {
|
||||
var publisher = ParsePubSub.createPublisher({
|
||||
ParsePubSub.createPublisher({
|
||||
redisURL: 'redisURL'
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('ParsePubSub', function() {
|
||||
});
|
||||
|
||||
it('can create event emitter publisher', function() {
|
||||
var publisher = ParsePubSub.createPublisher({});
|
||||
ParsePubSub.createPublisher({});
|
||||
|
||||
var RedisPubSub = require('../src/Adapters/PubSub/RedisPubSub').RedisPubSub;
|
||||
var EventEmitterPubSub = require('../src/Adapters/PubSub/EventEmitterPubSub').EventEmitterPubSub;
|
||||
@@ -39,7 +39,7 @@ describe('ParsePubSub', function() {
|
||||
});
|
||||
|
||||
it('can create redis subscriber', function() {
|
||||
var subscriber = ParsePubSub.createSubscriber({
|
||||
ParsePubSub.createSubscriber({
|
||||
redisURL: 'redisURL'
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('ParsePubSub', function() {
|
||||
});
|
||||
|
||||
it('can create event emitter subscriber', function() {
|
||||
var subscriptionInfos = ParsePubSub.createSubscriber({});
|
||||
ParsePubSub.createSubscriber({});
|
||||
|
||||
var RedisPubSub = require('../src/Adapters/PubSub/RedisPubSub').RedisPubSub;
|
||||
var EventEmitterPubSub = require('../src/Adapters/PubSub/EventEmitterPubSub').EventEmitterPubSub;
|
||||
|
||||
@@ -145,7 +145,7 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
}).then(function(){
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -221,7 +221,7 @@ describe('Parse.Query testing', () => {
|
||||
done();
|
||||
},
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -243,7 +243,7 @@ describe('Parse.Query testing', () => {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -282,7 +282,7 @@ describe('Parse.Query testing', () => {
|
||||
var objectsList = [];
|
||||
objectsList.push(new DateSet({
|
||||
"dates" : makeDates(["2013-02-01", "2013-02-02", "2013-02-03",
|
||||
"2013-02-04"])
|
||||
"2013-02-04"])
|
||||
}));
|
||||
objectsList.push(new DateSet({
|
||||
"dates" : makeDates(["2013-02-01", "2013-02-03", "2013-02-04"])
|
||||
@@ -353,15 +353,15 @@ describe('Parse.Query testing', () => {
|
||||
};
|
||||
Parse.Object.saveAll([0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', 3);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', 3);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("equalTo undefined", function(done) {
|
||||
@@ -370,15 +370,15 @@ describe('Parse.Query testing', () => {
|
||||
};
|
||||
Parse.Object.saveAll([0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', undefined);
|
||||
query.find(expectSuccess({
|
||||
success: function(results) {
|
||||
equal(results.length, 0);
|
||||
done();
|
||||
}
|
||||
}));
|
||||
});
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', undefined);
|
||||
query.find(expectSuccess({
|
||||
success: function(results) {
|
||||
equal(results.length, 0);
|
||||
done();
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("lessThan queries", function(done) {
|
||||
@@ -387,15 +387,15 @@ describe('Parse.Query testing', () => {
|
||||
};
|
||||
Parse.Object.saveAll([0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThan('number', 7);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 7);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThan('number', 7);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 7);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("lessThanOrEqualTo queries", function(done) {
|
||||
@@ -459,16 +459,16 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThanOrEqualTo('number', 7);
|
||||
query.greaterThanOrEqualTo('number', 7);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 1);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThanOrEqualTo('number', 7);
|
||||
query.greaterThanOrEqualTo('number', 7);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("lessThan greaterThan queries", function(done) {
|
||||
@@ -478,16 +478,16 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThan('number', 9);
|
||||
query.greaterThan('number', 3);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 5);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.lessThan('number', 9);
|
||||
query.greaterThan('number', 3);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 5);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("notEqualTo queries", function(done) {
|
||||
@@ -497,15 +497,15 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.notEqualTo('number', 5);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 9);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.notEqualTo('number', 5);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 9);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("containedIn queries", function(done) {
|
||||
@@ -515,15 +515,15 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.containedIn('number', [3,5,7,9,11]);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 4);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.containedIn('number', [3,5,7,9,11]);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 4);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("notContainedIn queries", function(done) {
|
||||
@@ -533,15 +533,15 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.notContainedIn('number', [3,5,7,9,11]);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 6);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.notContainedIn('number', [3,5,7,9,11]);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 6);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -554,8 +554,8 @@ describe('Parse.Query testing', () => {
|
||||
function(list) {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.containedIn('objectId',
|
||||
[list[2].id, list[3].id, list[0].id,
|
||||
"NONSENSE"]);
|
||||
[list[2].id, list[3].id, list[0].id,
|
||||
"NONSENSE"]);
|
||||
query.ascending('number');
|
||||
query.find({
|
||||
success: function(results) {
|
||||
@@ -602,15 +602,15 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', 17);
|
||||
query.find(expectSuccess({
|
||||
success: function(results) {
|
||||
equal(results.length, 0);
|
||||
done();
|
||||
}
|
||||
}));
|
||||
});
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.equalTo('number', 17);
|
||||
query.find(expectSuccess({
|
||||
success: function(results) {
|
||||
equal(results.length, 0);
|
||||
done();
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
it("find with error", function(done) {
|
||||
@@ -651,10 +651,9 @@ describe('Parse.Query testing', () => {
|
||||
it("get error", function(done) {
|
||||
Parse.Object.saveAll([new TestObject({foo: 'bar'})], function(items) {
|
||||
ok(items[0]);
|
||||
var objectId = items[0].id;
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.get("InvalidObjectID", {
|
||||
success: function(result) {
|
||||
success: function() {
|
||||
ok(false, "The get should have failed.");
|
||||
done();
|
||||
},
|
||||
@@ -694,16 +693,16 @@ describe('Parse.Query testing', () => {
|
||||
|
||||
it("first with two results", function(done) {
|
||||
Parse.Object.saveAll([new TestObject({foo: 'bar'}),
|
||||
new TestObject({foo: 'bar'})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.equalTo('foo', 'bar');
|
||||
query.first({
|
||||
success: function(result) {
|
||||
equal(result.get('foo'), 'bar');
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
new TestObject({foo: 'bar'})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.equalTo('foo', 'bar');
|
||||
query.first({
|
||||
success: function(result) {
|
||||
equal(result.get('foo'), 'bar');
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("first with error", function(done) {
|
||||
@@ -783,22 +782,22 @@ describe('Parse.Query testing', () => {
|
||||
Parse.Object.saveAll(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(makeBoxedNumber),
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.greaterThan("number", 1);
|
||||
query.count({
|
||||
success: function(count) {
|
||||
equal(count, 8);
|
||||
done();
|
||||
}
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.greaterThan("number", 1);
|
||||
query.count({
|
||||
success: function(count) {
|
||||
equal(count, 8);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("order by ascending number", function(done) {
|
||||
var makeBoxedNumber = function(i) {
|
||||
return new BoxedNumber({ number: i });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber), function(list) {
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber), function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.ascending("number");
|
||||
query.find(expectSuccess({
|
||||
@@ -817,7 +816,7 @@ describe('Parse.Query testing', () => {
|
||||
var makeBoxedNumber = function(i) {
|
||||
return new BoxedNumber({ number: i });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber)).then( function(list) {
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber)).then( function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("number");
|
||||
query.find(expectSuccess({
|
||||
@@ -839,7 +838,7 @@ describe('Parse.Query testing', () => {
|
||||
};
|
||||
Parse.Object.saveAll(
|
||||
[3, 1, 3, 2].map(makeBoxedNumber)).then(
|
||||
function(list) {
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.ascending("number").addDescending("string");
|
||||
query.find(expectSuccess({
|
||||
@@ -867,11 +866,11 @@ describe('Parse.Query testing', () => {
|
||||
|
||||
let objects = [3, 1, 3, 2].map(makeBoxedNumber);
|
||||
Parse.Object.saveAll(objects)
|
||||
.then((list) => {
|
||||
.then(() => {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("number").addAscending("string");
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then((results) => {
|
||||
equal(results.length, 4);
|
||||
equal(results[0].get("number"), 3);
|
||||
equal(results[0].get("string"), "a");
|
||||
@@ -882,7 +881,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(results[3].get("number"), 1);
|
||||
equal(results[3].get("string"), "b");
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -894,7 +893,7 @@ describe('Parse.Query testing', () => {
|
||||
return new BoxedNumber({ number: num, string: strings[i] });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 3, 2].map(makeBoxedNumber)).then(
|
||||
function(list) {
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("number,string");
|
||||
query.find(expectSuccess({
|
||||
@@ -920,7 +919,7 @@ describe('Parse.Query testing', () => {
|
||||
return new BoxedNumber({ number: num, string: strings[i] });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 3, 2].map(makeBoxedNumber)).then(
|
||||
function(list) {
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("number, string");
|
||||
query.find(expectSuccess({
|
||||
@@ -937,10 +936,10 @@ describe('Parse.Query testing', () => {
|
||||
done();
|
||||
}
|
||||
}));
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("order by descending number and string, with array arg", function(done) {
|
||||
@@ -949,7 +948,7 @@ describe('Parse.Query testing', () => {
|
||||
return new BoxedNumber({ number: num, string: strings[i] });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 3, 2].map(makeBoxedNumber)).then(
|
||||
function(list) {
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending(["number", "string"]);
|
||||
query.find(expectSuccess({
|
||||
@@ -975,7 +974,7 @@ describe('Parse.Query testing', () => {
|
||||
return new BoxedNumber({ number: num, string: strings[i] });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 3, 2].map(makeBoxedNumber)).then(
|
||||
function(list) {
|
||||
function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("number", "string");
|
||||
query.find(expectSuccess({
|
||||
@@ -999,7 +998,7 @@ describe('Parse.Query testing', () => {
|
||||
var makeBoxedNumber = function(i) {
|
||||
return new BoxedNumber({ number: i });
|
||||
};
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber), function(list) {
|
||||
Parse.Object.saveAll([3, 1, 2].map(makeBoxedNumber), function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.ascending("_password");
|
||||
query.find(expectError(Parse.Error.INVALID_KEY_NAME, done));
|
||||
@@ -1070,7 +1069,7 @@ describe('Parse.Query testing', () => {
|
||||
}).then(function() {
|
||||
numbers[1].set("number", 4);
|
||||
numbers[1].save(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.ascending("_updated_at");
|
||||
query.find({
|
||||
@@ -1097,7 +1096,7 @@ describe('Parse.Query testing', () => {
|
||||
}).then(function() {
|
||||
numbers[1].set("number", 4);
|
||||
numbers[1].save(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
var query = new Parse.Query(BoxedNumber);
|
||||
query.descending("_updated_at");
|
||||
query.find({
|
||||
@@ -1220,7 +1219,7 @@ describe('Parse.Query testing', () => {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.matches("myString", "FootBall", "i");
|
||||
query.find({
|
||||
success: function(results) {
|
||||
success: function() {
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1277,50 +1276,50 @@ describe('Parse.Query testing', () => {
|
||||
|
||||
it("contains", function(done) {
|
||||
Parse.Object.saveAll([new TestObject({myString: "zax" + someAscii + "qub"}),
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.contains("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results, foo) {
|
||||
equal(results.length, 4);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.contains("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 4);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("startsWith", function(done) {
|
||||
Parse.Object.saveAll([new TestObject({myString: "zax" + someAscii + "qub"}),
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.startsWith("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results, foo) {
|
||||
equal(results.length, 2);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.startsWith("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 2);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("endsWith", function(done) {
|
||||
Parse.Object.saveAll([new TestObject({myString: "zax" + someAscii + "qub"}),
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.endsWith("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results, foo) {
|
||||
equal(results.length, 2);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
new TestObject({myString: "start" + someAscii}),
|
||||
new TestObject({myString: someAscii + "end"}),
|
||||
new TestObject({myString: someAscii})], function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.endsWith("myString", someAscii);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
equal(results.length, 2);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("exists", function(done) {
|
||||
@@ -1342,7 +1341,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(results.length, 5);
|
||||
for (var result of results) {
|
||||
ok(result.get("x"));
|
||||
};
|
||||
}
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1359,7 +1358,7 @@ describe('Parse.Query testing', () => {
|
||||
item.set('y', i + 1);
|
||||
}
|
||||
objects.push(item);
|
||||
};
|
||||
}
|
||||
Parse.Object.saveAll(objects, function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.doesNotExist("x");
|
||||
@@ -1388,7 +1387,7 @@ describe('Parse.Query testing', () => {
|
||||
container.set('y', i);
|
||||
}
|
||||
objects.push(container);
|
||||
};
|
||||
}
|
||||
Parse.Object.saveAll(objects).then(function() {
|
||||
var query = new Parse.Query(Container);
|
||||
query.exists("x");
|
||||
@@ -1397,7 +1396,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(results.length, 5);
|
||||
for (var result of results) {
|
||||
ok(result.get("x"));
|
||||
};
|
||||
}
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1426,7 +1425,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(results.length, 4);
|
||||
for (var result of results) {
|
||||
ok(result.get("y"));
|
||||
};
|
||||
}
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1579,7 +1578,7 @@ describe('Parse.Query testing', () => {
|
||||
let object = new Parse.Object("AContainer");
|
||||
object.set('objects', objects);
|
||||
return object.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AContainer');
|
||||
query.include('objects');
|
||||
return query.find()
|
||||
@@ -1593,7 +1592,7 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
expect(total).toBe(0);
|
||||
done()
|
||||
}, () => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -1618,7 +1617,7 @@ describe('Parse.Query testing', () => {
|
||||
let object = new Parse.Object("AContainer");
|
||||
object.set('objects', objects);
|
||||
return object.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AContainer');
|
||||
query.include('objects');
|
||||
return query.find()
|
||||
@@ -1632,7 +1631,7 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
expect(total).toBe(0);
|
||||
done()
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -1662,7 +1661,7 @@ describe('Parse.Query testing', () => {
|
||||
}
|
||||
object.set('objects', objects);
|
||||
return object.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AContainer');
|
||||
query.include('objects');
|
||||
return query.find()
|
||||
@@ -1676,37 +1675,37 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
expect(total).toBe(0);
|
||||
done()
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('properly fetches nested pointers', (done) => {
|
||||
it('properly fetches nested pointers', (done) => {
|
||||
let color = new Parse.Object('Color');
|
||||
color.set('hex','#133733');
|
||||
let circle = new Parse.Object('Circle');
|
||||
circle.set('radius', 1337);
|
||||
|
||||
Parse.Object.saveAll([color, circle]).then(() => {
|
||||
Parse.Object.saveAll([color, circle]).then(() => {
|
||||
circle.set('color', color);
|
||||
let badCircle = new Parse.Object('Circle');
|
||||
badCircle.id = 'badId';
|
||||
let complexFigure = new Parse.Object('ComplexFigure');
|
||||
complexFigure.set('consistsOf', [circle, badCircle]);
|
||||
return complexFigure.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('ComplexFigure');
|
||||
q.include('consistsOf.color');
|
||||
return q.find()
|
||||
}).then((results) => {
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let figure = results[0];
|
||||
expect(figure.get('consistsOf').length).toBe(1);
|
||||
expect(figure.get('consistsOf')[0].get('color').get('hex')).toBe('#133733');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -1897,7 +1896,7 @@ describe('Parse.Query testing', () => {
|
||||
obj.set("length", 5);
|
||||
equal(obj.get("length"), 5);
|
||||
obj.save(null, {
|
||||
success: function(obj) {
|
||||
success: function() {
|
||||
var query = new Parse.Query(TestObject);
|
||||
query.find({
|
||||
success: function(results) {
|
||||
@@ -2072,7 +2071,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(seen.length, COUNT);
|
||||
for (var i = 0; i < COUNT; i++) {
|
||||
equal(seen[i], 1, "Should have seen object number " + i);
|
||||
};
|
||||
}
|
||||
done();
|
||||
},
|
||||
error: function(error) {
|
||||
@@ -2115,7 +2114,7 @@ describe('Parse.Query testing', () => {
|
||||
equal(seen.length, COUNT);
|
||||
for (var i = 0; i < COUNT; i++) {
|
||||
equal(seen[i], 1, "Should have seen object number " + i);
|
||||
};
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2143,7 +2142,7 @@ describe('Parse.Query testing', () => {
|
||||
}).then(function() {
|
||||
ok(false, "This should have failed.");
|
||||
done();
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2171,7 +2170,7 @@ describe('Parse.Query testing', () => {
|
||||
}).then(function() {
|
||||
ok(false, "This should have failed.");
|
||||
done();
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2201,7 +2200,7 @@ describe('Parse.Query testing', () => {
|
||||
}).then(function() {
|
||||
ok(false, "This should have failed.");
|
||||
done();
|
||||
}, function(error) {
|
||||
}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2336,7 +2335,6 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
|
||||
it('query within dictionary', (done) => {
|
||||
var objs = [];
|
||||
var promises = [];
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var proc = (iter) => {
|
||||
@@ -2361,24 +2359,24 @@ describe('Parse.Query testing', () => {
|
||||
it('supports include on the wrong key type (#2262)', function(done) {
|
||||
let childObject = new Parse.Object('TestChildObject');
|
||||
childObject.set('hello', 'world');
|
||||
childObject.save().then(() => {
|
||||
childObject.save().then(() => {
|
||||
let obj = new Parse.Object('TestObject');
|
||||
obj.set('foo', 'bar');
|
||||
obj.set('child', childObject);
|
||||
return obj.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('TestObject');
|
||||
q.include('child');
|
||||
q.include('child.parent');
|
||||
q.include('createdAt');
|
||||
q.include('createdAt.createdAt');
|
||||
return q.find();
|
||||
}).then((objs) => {
|
||||
}).then((objs) => {
|
||||
expect(objs.length).toBe(1);
|
||||
expect(objs[0].get('child').get('hello')).toEqual('world');
|
||||
expect(objs[0].createdAt instanceof Date).toBe(true);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
});
|
||||
@@ -2424,7 +2422,7 @@ describe('Parse.Query testing', () => {
|
||||
query.matchesKeyInQuery("A1", "A2", auxQuery);
|
||||
query.include("A3");
|
||||
query.include("A2");
|
||||
query.find().then((result) => {
|
||||
query.find().then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
@@ -2437,7 +2435,7 @@ describe('Parse.Query testing', () => {
|
||||
var user = new Parse.User();
|
||||
user.set("username", "foo");
|
||||
user.set("password", "bar");
|
||||
return user.save().then( (user) => {
|
||||
return user.save().then( (user) => {
|
||||
var objIdQuery = new Parse.Query("_User").equalTo("objectId", user.id);
|
||||
var blockedUserQuery = user.relation("blockedUsers").query();
|
||||
|
||||
@@ -2460,7 +2458,7 @@ describe('Parse.Query testing', () => {
|
||||
var query = new Parse.Query("_User");
|
||||
query.doesNotMatchQuery("objectId", orQuery);
|
||||
return query.find();
|
||||
}).then((res) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
@@ -2477,13 +2475,13 @@ describe('Parse.Query testing', () => {
|
||||
objects.push(object);
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(objects).then((objects) => {
|
||||
Parse.Object.saveAll(objects).then((objects) => {
|
||||
var container = new Parse.Object('Container');
|
||||
var pointers = objects.map((obj) => {
|
||||
var pointers = objects.map((obj) => {
|
||||
return {
|
||||
__type: 'Pointer',
|
||||
className: 'ContainedObject',
|
||||
objectId: obj.id
|
||||
__type: 'Pointer',
|
||||
className: 'ContainedObject',
|
||||
objectId: obj.id
|
||||
}
|
||||
})
|
||||
container.set('objects', pointers);
|
||||
@@ -2496,12 +2494,12 @@ describe('Parse.Query testing', () => {
|
||||
let query = new Parse.Query('Container');
|
||||
query.matchesQuery('objects', inQuery);
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then((results) => {
|
||||
if (results) {
|
||||
expect(results.length).toBe(2);
|
||||
}
|
||||
done();
|
||||
}).fail((err) => {
|
||||
}).fail((err) => {
|
||||
jfail(err);
|
||||
fail('should not fail');
|
||||
done();
|
||||
@@ -2520,7 +2518,7 @@ describe('Parse.Query testing', () => {
|
||||
q1.doesNotExist('nonExistantKey1');
|
||||
let q2 = anObject.relation('relation').query();
|
||||
q2.doesNotExist('nonExistantKey2');
|
||||
let orQuery = Parse.Query.or(q1, q2).find().then(results => {
|
||||
Parse.Query.or(q1, q2).find().then(results => {
|
||||
expect(results.length).toEqual(1);
|
||||
if (results.length == 1) {
|
||||
expect(results[0].objectId).toEqual(q1.objectId);
|
||||
@@ -2592,7 +2590,7 @@ describe('Parse.Query testing', () => {
|
||||
var BarBaz = new Parse.Object('Barbaz');
|
||||
BarBaz.set('key', 'value');
|
||||
BarBaz.set('otherKey', 'value');
|
||||
BarBaz.save().then(() => {
|
||||
BarBaz.save().then(() => {
|
||||
Foobar.set('foo', 'bar');
|
||||
Foobar.set('fizz', 'buzz');
|
||||
Foobar.set('barBaz', BarBaz);
|
||||
@@ -2624,12 +2622,12 @@ describe('Parse.Query testing', () => {
|
||||
|
||||
Bazoo.set('some', 'thing');
|
||||
Bazoo.set('otherSome', 'value');
|
||||
Bazoo.save().then(() => {
|
||||
Bazoo.save().then(() => {
|
||||
BarBaz.set('key', 'value');
|
||||
BarBaz.set('otherKey', 'value');
|
||||
BarBaz.set('bazoo', Bazoo);
|
||||
return BarBaz.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
Foobar.set('foo', 'bar');
|
||||
Foobar.set('fizz', 'buzz');
|
||||
Foobar.set('barBaz', BarBaz);
|
||||
@@ -2673,10 +2671,10 @@ describe('Parse.Query testing', () => {
|
||||
q2.equalTo('x', 2);
|
||||
let or01 = Parse.Query.or(q0,q1);
|
||||
return Parse.Query.or(or01, q2).find();
|
||||
}).then((results) => {
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(3);
|
||||
done();
|
||||
}).catch((error) => {
|
||||
}).catch((error) => {
|
||||
fail('should not fail');
|
||||
jfail(error);
|
||||
done();
|
||||
|
||||
@@ -46,10 +46,10 @@ describe('Parse.Relation testing', () => {
|
||||
var childObjects = [];
|
||||
for (var i = 0; i < 10; i++) {
|
||||
childObjects.push(new ChildObject({x:i}));
|
||||
};
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(childObjects, expectSuccess({
|
||||
success: function(list) {
|
||||
success: function() {
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
@@ -84,7 +84,7 @@ describe('Parse.Relation testing', () => {
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(childObjects, {
|
||||
success: function(list) {
|
||||
success: function() {
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
@@ -106,7 +106,7 @@ describe('Parse.Relation testing', () => {
|
||||
"The relation should not be dirty");
|
||||
done();
|
||||
},
|
||||
error: function(list) {
|
||||
error: function() {
|
||||
ok(false, "This shouldn't have failed");
|
||||
done();
|
||||
}
|
||||
@@ -131,7 +131,7 @@ describe('Parse.Relation testing', () => {
|
||||
var parent;
|
||||
var relation;
|
||||
|
||||
Parse.Object.saveAll(childObjects).then(function(list) {
|
||||
Parse.Object.saveAll(childObjects).then(function() {
|
||||
var ParentObject = Parse.Object.extend('ParentObject');
|
||||
parent = new ParentObject();
|
||||
parent.set('x', 4);
|
||||
@@ -304,34 +304,34 @@ describe('Parse.Relation testing', () => {
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(childObjects).then(() => {
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.set("toChild", childObjects[2]);
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.set("toChild", childObjects[2]);
|
||||
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query = new Parse.Query(ParentObject);
|
||||
query.equalTo("objectId", parent.id);
|
||||
query.equalTo("toChilds", childObjects[2]);
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query = new Parse.Query(ParentObject);
|
||||
query.equalTo("objectId", parent.id);
|
||||
query.equalTo("toChilds", childObjects[2]);
|
||||
|
||||
return query.find().then((list) => {
|
||||
equal(list.length, 1, "There should be 1 result");
|
||||
done();
|
||||
});
|
||||
return query.find().then((list) => {
|
||||
equal(list.length, 1, "There should be 1 result");
|
||||
done();
|
||||
});
|
||||
}).catch(err => {
|
||||
});
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -345,35 +345,35 @@ describe('Parse.Relation testing', () => {
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(childObjects).then(() => {
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.relation("toChilds").add(childObjects[2]);
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.relation("toChilds").add(childObjects[2]);
|
||||
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query = new Parse.Query(ParentObject);
|
||||
query.equalTo("objectId", parent2.id);
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query = new Parse.Query(ParentObject);
|
||||
query.equalTo("objectId", parent2.id);
|
||||
// childObjects[2] is in 2 relations
|
||||
// before the fix, that woul yield 2 results
|
||||
query.equalTo("toChilds", childObjects[2]);
|
||||
query.equalTo("toChilds", childObjects[2]);
|
||||
|
||||
return query.find().then((list) => {
|
||||
equal(list.length, 1, "There should be 1 result");
|
||||
done();
|
||||
});
|
||||
return query.find().then((list) => {
|
||||
equal(list.length, 1, "There should be 1 result");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -385,39 +385,39 @@ describe('Parse.Relation testing', () => {
|
||||
}
|
||||
|
||||
Parse.Object.saveAll(childObjects).then(() => {
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
var ParentObject = Parse.Object.extend("ParentObject");
|
||||
var parent = new ParentObject();
|
||||
parent.set("x", 4);
|
||||
var relation = parent.relation("toChilds");
|
||||
relation.add(childObjects[0]);
|
||||
relation.add(childObjects[1]);
|
||||
relation.add(childObjects[2]);
|
||||
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.set("toChild", childObjects[2]);
|
||||
var parent2 = new ParentObject();
|
||||
parent2.set("x", 3);
|
||||
parent2.set("toChild", childObjects[2]);
|
||||
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
var parents = [];
|
||||
parents.push(parent);
|
||||
parents.push(parent2);
|
||||
parents.push(new ParentObject());
|
||||
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query1 = new Parse.Query(ParentObject);
|
||||
query1.containedIn("toChilds", [childObjects[2]]);
|
||||
var query2 = new Parse.Query(ParentObject);
|
||||
query2.equalTo("toChild", childObjects[2]);
|
||||
var query = Parse.Query.or(query1, query2);
|
||||
return query.find().then((list) => {
|
||||
var objectIds = list.map(function(item){
|
||||
return item.id;
|
||||
});
|
||||
expect(objectIds.indexOf(parent.id)).not.toBe(-1);
|
||||
expect(objectIds.indexOf(parent2.id)).not.toBe(-1);
|
||||
equal(list.length, 2, "There should be 2 results");
|
||||
done();
|
||||
return Parse.Object.saveAll(parents).then(() => {
|
||||
var query1 = new Parse.Query(ParentObject);
|
||||
query1.containedIn("toChilds", [childObjects[2]]);
|
||||
var query2 = new Parse.Query(ParentObject);
|
||||
query2.equalTo("toChild", childObjects[2]);
|
||||
var query = Parse.Query.or(query1, query2);
|
||||
return query.find().then((list) => {
|
||||
var objectIds = list.map(function(item){
|
||||
return item.id;
|
||||
});
|
||||
expect(objectIds.indexOf(parent.id)).not.toBe(-1);
|
||||
expect(objectIds.indexOf(parent2.id)).not.toBe(-1);
|
||||
equal(list.length, 2, "There should be 2 results");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -552,11 +552,11 @@ describe('Parse.Relation testing', () => {
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(5);
|
||||
results.forEach((result) => {
|
||||
results.forEach((result) => {
|
||||
expect(result.get('key').get('even')).toBe(true);
|
||||
});
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// Query on the relation of another owner
|
||||
let object = new Parse.Object('AnotherOwner');
|
||||
object.id = anotherOwner.id;
|
||||
@@ -571,7 +571,7 @@ describe('Parse.Relation testing', () => {
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(5);
|
||||
results.forEach((result) => {
|
||||
results.forEach((result) => {
|
||||
expect(result.get('key').get('even')).toBe(false);
|
||||
});
|
||||
done();
|
||||
@@ -592,11 +592,9 @@ describe('Parse.Relation testing', () => {
|
||||
new PersonObject({ name: "Billy", hometown: "Detroit" }),
|
||||
];
|
||||
let owner = new OwnerObject({name: 'Joe'});
|
||||
let ownerId;
|
||||
let allObjects = [owner].concat(restaurants).concat(persons);
|
||||
expect(allObjects.length).toEqual(6);
|
||||
Parse.Object.saveAll([owner].concat(restaurants).concat(persons)).then(function() {
|
||||
ownerId = owner.id;
|
||||
owner.relation('restaurants').add(restaurants);
|
||||
return owner.save()
|
||||
}).then(() => {
|
||||
@@ -632,11 +630,9 @@ describe('Parse.Relation testing', () => {
|
||||
new PersonObject({ name: "Billy", hometown: "Detroit" }),
|
||||
];
|
||||
let owner = new OwnerObject({name: 'Joe'});
|
||||
let ownerId;
|
||||
let allObjects = [owner].concat(restaurants).concat(persons);
|
||||
expect(allObjects.length).toEqual(6);
|
||||
Parse.Object.saveAll([owner].concat(restaurants).concat(persons)).then(function() {
|
||||
ownerId = owner.id;
|
||||
owner.relation('restaurants').add(restaurants);
|
||||
return owner.save()
|
||||
}).then(() => {
|
||||
@@ -705,7 +701,7 @@ describe('Parse.Relation testing', () => {
|
||||
fail('Should have found admin user, found nothing instead');
|
||||
done();
|
||||
}
|
||||
}, error => {
|
||||
}, () => {
|
||||
fail('User not admin');
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('Parse Role testing', () => {
|
||||
var users = role.relation('users');
|
||||
users.add(user);
|
||||
return role.save({}, { useMasterKey: true });
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
var query = new Parse.Query('_Role');
|
||||
return query.find({ useMasterKey: true });
|
||||
}).then((x) => {
|
||||
@@ -42,7 +42,7 @@ describe('Parse Role testing', () => {
|
||||
acl.setRoleWriteAccess('Foos', true);
|
||||
obj.setACL(acl);
|
||||
return obj.save();
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
var query = new Parse.Query('TestObject');
|
||||
return query.find({ sessionToken: user.getSessionToken() });
|
||||
}).then((x) => {
|
||||
@@ -55,7 +55,7 @@ describe('Parse Role testing', () => {
|
||||
x.set('foo', 'baz');
|
||||
// This should fail:
|
||||
return x.save({},{sessionToken: ""});
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
fail('Should not have been able to save.');
|
||||
}, (e) => {
|
||||
expect(e.code).toEqual(Parse.Error.OBJECT_NOT_FOUND);
|
||||
@@ -135,7 +135,7 @@ describe('Parse Role testing', () => {
|
||||
// 1 call for the 2nd layer
|
||||
expect(getAllRolesSpy.calls.count()).toEqual(2);
|
||||
done()
|
||||
}).catch( (err) => {
|
||||
}).catch( () => {
|
||||
fail("should succeed");
|
||||
done();
|
||||
});
|
||||
@@ -145,45 +145,45 @@ describe('Parse Role testing', () => {
|
||||
it("should recursively load roles", (done) => {
|
||||
var rolesNames = ["FooRole", "BarRole", "BazRole"];
|
||||
var roleIds = {};
|
||||
createTestUser().then( (user) => {
|
||||
createTestUser().then( (user) => {
|
||||
// Put the user on the 1st role
|
||||
return createRole(rolesNames[0], null, user).then( (aRole) => {
|
||||
roleIds[aRole.get("name")] = aRole.id;
|
||||
return createRole(rolesNames[0], null, user).then( (aRole) => {
|
||||
roleIds[aRole.get("name")] = aRole.id;
|
||||
// set the 1st role as a sibling of the second
|
||||
// user will should have 2 role now
|
||||
return createRole(rolesNames[1], aRole, null);
|
||||
}).then( (anotherRole) => {
|
||||
roleIds[anotherRole.get("name")] = anotherRole.id;
|
||||
return createRole(rolesNames[1], aRole, null);
|
||||
}).then( (anotherRole) => {
|
||||
roleIds[anotherRole.get("name")] = anotherRole.id;
|
||||
// set this role as a sibling of the last
|
||||
// the user should now have 3 roles
|
||||
return createRole(rolesNames[2], anotherRole, null);
|
||||
}).then( (lastRole) => {
|
||||
roleIds[lastRole.get("name")] = lastRole.id;
|
||||
var auth = new Auth({ config: new Config("test"), isMaster: true, user: user });
|
||||
return auth._loadRoles();
|
||||
})
|
||||
}).then( (roles) => {
|
||||
expect(roles.length).toEqual(3);
|
||||
rolesNames.forEach( (name) => {
|
||||
return createRole(rolesNames[2], anotherRole, null);
|
||||
}).then( (lastRole) => {
|
||||
roleIds[lastRole.get("name")] = lastRole.id;
|
||||
var auth = new Auth({ config: new Config("test"), isMaster: true, user: user });
|
||||
return auth._loadRoles();
|
||||
})
|
||||
}).then( (roles) => {
|
||||
expect(roles.length).toEqual(3);
|
||||
rolesNames.forEach( (name) => {
|
||||
expect(roles.indexOf('role:'+name)).not.toBe(-1);
|
||||
});
|
||||
done();
|
||||
}, function(err){
|
||||
fail("should succeed")
|
||||
done();
|
||||
});
|
||||
});
|
||||
done();
|
||||
}, function(){
|
||||
fail("should succeed")
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("_Role object should not save without name.", (done) => {
|
||||
var role = new Parse.Role();
|
||||
role.save(null,{useMasterKey:true})
|
||||
.then((r) => {
|
||||
.then(() => {
|
||||
fail("_Role object should not save without name.");
|
||||
}, (error) => {
|
||||
expect(error.code).toEqual(111);
|
||||
role.set('name','testRole');
|
||||
role.save(null,{useMasterKey:true})
|
||||
.then((r2)=>{
|
||||
.then(()=>{
|
||||
fail("_Role object should not save without ACL.");
|
||||
}, (error2) =>{
|
||||
expect(error2.code).toEqual(111);
|
||||
@@ -192,23 +192,23 @@ describe('Parse Role testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("Should properly resolve roles", (done) => {
|
||||
it("Should properly resolve roles", (done) => {
|
||||
let admin = new Parse.Role("Admin", new Parse.ACL());
|
||||
let moderator = new Parse.Role("Moderator", new Parse.ACL());
|
||||
let superModerator = new Parse.Role("SuperModerator", new Parse.ACL());
|
||||
let contentManager = new Parse.Role('ContentManager', new Parse.ACL());
|
||||
let superContentManager = new Parse.Role('SuperContentManager', new Parse.ACL());
|
||||
Parse.Object.saveAll([admin, moderator, contentManager, superModerator, superContentManager], {useMasterKey: true}).then(() => {
|
||||
Parse.Object.saveAll([admin, moderator, contentManager, superModerator, superContentManager], {useMasterKey: true}).then(() => {
|
||||
contentManager.getRoles().add([moderator, superContentManager]);
|
||||
moderator.getRoles().add([admin, superModerator]);
|
||||
superContentManager.getRoles().add(superModerator);
|
||||
return Parse.Object.saveAll([admin, moderator, contentManager, superModerator, superContentManager], {useMasterKey: true});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
var auth = new Auth({ config: new Config("test"), isMaster: true });
|
||||
// For each role, fetch their sibling, what they inherit
|
||||
// return with result and roleId for later comparison
|
||||
let promises = [admin, moderator, contentManager, superModerator].map((role) => {
|
||||
return auth._getAllRolesNamesForRoleIds([role.id]).then((result) => {
|
||||
let promises = [admin, moderator, contentManager, superModerator].map((role) => {
|
||||
return auth._getAllRolesNamesForRoleIds([role.id]).then((result) => {
|
||||
return Parse.Promise.as({
|
||||
id: role.id,
|
||||
name: role.get('name'),
|
||||
@@ -239,7 +239,7 @@ describe('Parse Role testing', () => {
|
||||
}
|
||||
});
|
||||
done();
|
||||
}).fail((err) => {
|
||||
}).fail(() => {
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -250,16 +250,16 @@ describe('Parse Role testing', () => {
|
||||
roleACL.setPublicReadAccess(true);
|
||||
var role = new Parse.Role('subscribers', roleACL);
|
||||
role.save({}, {useMasterKey : true})
|
||||
.then((x)=>{
|
||||
.then(()=>{
|
||||
var query = role.relation('users').query();
|
||||
query.find({useMasterKey : true})
|
||||
.then((users)=>{
|
||||
.then(()=>{
|
||||
done();
|
||||
}, (e)=>{
|
||||
}, ()=>{
|
||||
fail('should not have errors');
|
||||
done();
|
||||
});
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('should not have errored');
|
||||
});
|
||||
});
|
||||
@@ -278,10 +278,10 @@ describe('Parse Role testing', () => {
|
||||
user = x;
|
||||
user2 = new Parse.User();
|
||||
return user2.save({ username: 'user2', password: 'omgbbq' });
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
user3 = new Parse.User();
|
||||
return user3.save({ username: 'user3', password: 'omgbbq' });
|
||||
}).then((x) => {
|
||||
}).then(() => {
|
||||
role = new Parse.Role('Admin', prACL);
|
||||
role.getUsers().add(user);
|
||||
return role.save({}, { useMasterKey: true });
|
||||
@@ -327,7 +327,7 @@ describe('Parse Role testing', () => {
|
||||
obj2 = new Parse.Object('TestObjectRoles');
|
||||
obj2.set('ACL', adminACL);
|
||||
return obj2.save(null, { useMasterKey: true });
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Admin user should have been able to save.');
|
||||
done();
|
||||
}).then(() => {
|
||||
|
||||
@@ -2,34 +2,34 @@ const ParseServerRESTController = require('../src/ParseServerRESTController').Pa
|
||||
const ParseServer = require('../src/ParseServer').default;
|
||||
let RESTController;
|
||||
|
||||
describe('ParseServerRESTController', () => {
|
||||
describe('ParseServerRESTController', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(() => {
|
||||
RESTController = ParseServerRESTController(Parse.applicationId, ParseServer.promiseRouter({appId: Parse.applicationId}));
|
||||
})
|
||||
|
||||
it('should handle a get request', (done) => {
|
||||
RESTController.request("GET", "/classes/MyObject").then((res) => {
|
||||
it('should handle a get request', (done) => {
|
||||
RESTController.request("GET", "/classes/MyObject").then((res) => {
|
||||
expect(res.results.length).toBe(0);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a get request with full serverURL mount path', (done) => {
|
||||
RESTController.request("GET", "/1/classes/MyObject").then((res) => {
|
||||
it('should handle a get request with full serverURL mount path', (done) => {
|
||||
RESTController.request("GET", "/1/classes/MyObject").then((res) => {
|
||||
expect(res.results.length).toBe(0);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a POST batch', (done) => {
|
||||
it('should handle a POST batch', (done) => {
|
||||
RESTController.request("POST", "batch", {
|
||||
requests: [
|
||||
{
|
||||
@@ -46,72 +46,71 @@ describe('ParseServerRESTController', () => {
|
||||
path: '/classes/MyObject'
|
||||
}
|
||||
]
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(3);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a POST request', (done) => {
|
||||
RESTController.request("POST", "/classes/MyObject", {"key": "value"}).then((res) => {
|
||||
it('should handle a POST request', (done) => {
|
||||
RESTController.request("POST", "/classes/MyObject", {"key": "value"}).then(() => {
|
||||
return RESTController.request("GET", "/classes/MyObject");
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].key).toEqual("value");
|
||||
done();
|
||||
}).fail((err) => {
|
||||
}).fail((err) => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures sessionTokens are properly handled', (done) => {
|
||||
it('ensures sessionTokens are properly handled', (done) => {
|
||||
let userId;
|
||||
Parse.User.signUp('user', 'pass').then((user) => {
|
||||
Parse.User.signUp('user', 'pass').then((user) => {
|
||||
userId = user.id;
|
||||
let sessionToken = user.getSessionToken();
|
||||
return RESTController.request("GET", "/users/me", undefined, {sessionToken});
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
// Result is in JSON format
|
||||
expect(res.objectId).toEqual(userId);
|
||||
done();
|
||||
}).fail((err) => {
|
||||
}).fail((err) => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures masterKey is properly handled', (done) => {
|
||||
it('ensures masterKey is properly handled', (done) => {
|
||||
let userId;
|
||||
Parse.User.signUp('user', 'pass').then((user) => {
|
||||
Parse.User.signUp('user', 'pass').then((user) => {
|
||||
userId = user.id;
|
||||
let sessionToken = user.getSessionToken();
|
||||
return Parse.User.logOut().then(() => {
|
||||
return Parse.User.logOut().then(() => {
|
||||
return RESTController.request("GET", "/classes/_User", undefined, {useMasterKey: true});
|
||||
});
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].objectId).toEqual(userId);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures no session token is created on creating users', (done) => {
|
||||
RESTController.request("POST", "/classes/_User", {username: "hello", password: "world"}).then(() => {
|
||||
it('ensures no session token is created on creating users', (done) => {
|
||||
RESTController.request("POST", "/classes/_User", {username: "hello", password: "world"}).then(() => {
|
||||
let query = new Parse.Query('_Session');
|
||||
return query.find({useMasterKey: true});
|
||||
}).then(sessions => {
|
||||
}).then(sessions => {
|
||||
expect(sessions.length).toBe(0);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it("user login wrong username", (done) => {
|
||||
Parse.User.signUp("asdf", "zxcv", null, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
Parse.User.logIn("non_existent_user", "asdf3",
|
||||
expectError(Parse.Error.OBJECT_NOT_FOUND, done));
|
||||
},
|
||||
@@ -67,7 +67,7 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it("user login wrong password", (done) => {
|
||||
Parse.User.signUp("asdf", "zxcv", null, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
Parse.User.logIn("asdf", "asdfWrong",
|
||||
expectError(Parse.Error.OBJECT_NOT_FOUND, done));
|
||||
}
|
||||
@@ -128,7 +128,7 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it("user login", (done) => {
|
||||
Parse.User.signUp("asdf", "zxcv", null, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
Parse.User.logIn("asdf", "zxcv", {
|
||||
success: function(user) {
|
||||
equal(user.get("username"), "asdf");
|
||||
@@ -148,7 +148,7 @@ describe('Parse.User testing', () => {
|
||||
user.setUsername('asdf');
|
||||
user.setPassword('zxcv');
|
||||
user.setACL(ACL);
|
||||
user.signUp().then((user) => {
|
||||
user.signUp().then(() => {
|
||||
return Parse.User.logIn("asdf", "zxcv");
|
||||
}).then((user) => {
|
||||
equal(user.get("username"), "asdf");
|
||||
@@ -168,7 +168,7 @@ describe('Parse.User testing', () => {
|
||||
newACL.setWriteAccess(user.id, false);
|
||||
user.setACL(newACL);
|
||||
return user.save();
|
||||
}).then((user) => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn("asdf", "zxcv");
|
||||
}).then((user) => {
|
||||
equal(user.get("username"), "asdf");
|
||||
@@ -183,7 +183,7 @@ describe('Parse.User testing', () => {
|
||||
expect(perms[user.id].write).toBe(true);
|
||||
expect(perms['*']).toBeUndefined();
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
fail("Should not fail");
|
||||
done();
|
||||
})
|
||||
@@ -200,7 +200,7 @@ describe('Parse.User testing', () => {
|
||||
ok(fileAgain.name());
|
||||
ok(fileAgain.url());
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -374,7 +374,7 @@ describe('Parse.User testing', () => {
|
||||
object.save({
|
||||
user: userNotAuthedNotChanged
|
||||
}, {
|
||||
success: function(object) {
|
||||
success: function() {
|
||||
var item1 = new TestObject();
|
||||
item1.save({
|
||||
number: 0
|
||||
@@ -571,7 +571,7 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
|
||||
// Save all the messages.
|
||||
Parse.Object.saveAll(messageList, function(messages) {
|
||||
Parse.Object.saveAll(messageList, function() {
|
||||
|
||||
// Assemble an "in" list.
|
||||
var inList = [users[0], users[3], users[3]]; // Intentional dupe
|
||||
@@ -756,7 +756,7 @@ describe('Parse.User testing', () => {
|
||||
return Parse.User.logOut();
|
||||
}).then(() => {
|
||||
return Parse.User.logIn("alice", "password");
|
||||
}).then((user) => {
|
||||
}).then(() => {
|
||||
// Force the current user to read from disk
|
||||
delete Parse.User._currentUser;
|
||||
delete Parse.User._currentUserMatchesDisk;
|
||||
@@ -772,7 +772,6 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
|
||||
it("saving user after browser refresh", (done) => {
|
||||
var _ = Parse._;
|
||||
var id;
|
||||
|
||||
Parse.User.signUp("alice", "password", null).then(function(alice) {
|
||||
@@ -920,12 +919,11 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
|
||||
it("user on disk gets updated after save", (done) => {
|
||||
var SuperUser = Parse.User.extend({
|
||||
Parse.User.extend({
|
||||
isSuper: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Parse.User.signUp("bob", "welcome", null, {
|
||||
success: function(user) {
|
||||
// Modify the user and save.
|
||||
@@ -1061,7 +1059,7 @@ describe('Parse.User testing', () => {
|
||||
};
|
||||
};
|
||||
|
||||
var ExtendedUser = Parse.User.extend({
|
||||
Parse.User.extend({
|
||||
extended: function() {
|
||||
return true;
|
||||
}
|
||||
@@ -1122,17 +1120,17 @@ describe('Parse.User testing', () => {
|
||||
it("log in with provider and update token", (done) => {
|
||||
var provider = getMockFacebookProvider();
|
||||
var secondProvider = getMockFacebookProviderWithIdToken('8675309', 'jenny_valid_token');
|
||||
var errorHandler = function(err) {
|
||||
var errorHandler = function() {
|
||||
fail('should not fail');
|
||||
done();
|
||||
}
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: (model) => {
|
||||
success: () => {
|
||||
Parse.User._registerAuthenticationProvider(secondProvider);
|
||||
return Parse.User.logOut().then(() => {
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: (model) => {
|
||||
success: () => {
|
||||
expect(secondProvider.synchronizedAuthToken).toEqual('jenny_valid_token');
|
||||
// Make sure we can login with the new token again
|
||||
Parse.User.logOut().then(() => {
|
||||
@@ -1243,7 +1241,7 @@ describe('Parse.User testing', () => {
|
||||
provider.shouldError = true;
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
ok(false, "logIn should not have succeeded");
|
||||
},
|
||||
error: function(model, error) {
|
||||
@@ -1258,7 +1256,7 @@ describe('Parse.User testing', () => {
|
||||
provider.shouldCancel = true;
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
ok(false, "logIn should not have succeeded");
|
||||
},
|
||||
error: function(model, error) {
|
||||
@@ -1272,7 +1270,7 @@ describe('Parse.User testing', () => {
|
||||
var provider = getMockFacebookProvider();
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
Parse.User.logOut();
|
||||
|
||||
Parse.Cloud.beforeSave(Parse.User, function(req, res) {
|
||||
@@ -1280,7 +1278,7 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(innerModel) {
|
||||
success: function() {
|
||||
done();
|
||||
},
|
||||
error: function(model, error) {
|
||||
@@ -1299,7 +1297,7 @@ describe('Parse.User testing', () => {
|
||||
user.set("username", "testLinkWithProvider");
|
||||
user.set("password", "mypass");
|
||||
user.signUp(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
user._linkWith("facebook", {
|
||||
success: function(model) {
|
||||
ok(model instanceof Parse.User, "Model should be a Parse.User");
|
||||
@@ -1310,13 +1308,13 @@ describe('Parse.User testing', () => {
|
||||
ok(model._isLinked("facebook"), "User should be linked");
|
||||
done();
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have succeeded");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "signup should not have failed");
|
||||
done();
|
||||
}
|
||||
@@ -1332,7 +1330,7 @@ describe('Parse.User testing', () => {
|
||||
user.set("username", "testLinkWithProviderToAlreadyLinkedUser");
|
||||
user.set("password", "mypass");
|
||||
user.signUp(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
user._linkWith("facebook", {
|
||||
success: function(model) {
|
||||
ok(model instanceof Parse.User, "Model should be a Parse.User");
|
||||
@@ -1345,9 +1343,9 @@ describe('Parse.User testing', () => {
|
||||
user2.set("username", "testLinkWithProviderToAlreadyLinkedUser2");
|
||||
user2.set("password", "mypass");
|
||||
user2.signUp(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
user2._linkWith('facebook', {
|
||||
success: (err) => {
|
||||
success: (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
},
|
||||
@@ -1358,19 +1356,19 @@ describe('Parse.User testing', () => {
|
||||
},
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have failed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have succeeded");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "signup should not have failed");
|
||||
done();
|
||||
}
|
||||
@@ -1385,9 +1383,9 @@ describe('Parse.User testing', () => {
|
||||
user.set("username", "testLinkWithProvider");
|
||||
user.set("password", "mypass");
|
||||
user.signUp(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
user._linkWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
ok(false, "linking should fail");
|
||||
done();
|
||||
},
|
||||
@@ -1399,7 +1397,7 @@ describe('Parse.User testing', () => {
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "signup should not have failed");
|
||||
done();
|
||||
}
|
||||
@@ -1414,9 +1412,9 @@ describe('Parse.User testing', () => {
|
||||
user.set("username", "testLinkWithProvider");
|
||||
user.set("password", "mypass");
|
||||
user.signUp(null, {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
user._linkWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
ok(false, "linking should fail");
|
||||
done();
|
||||
},
|
||||
@@ -1428,7 +1426,7 @@ describe('Parse.User testing', () => {
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "signup should not have failed");
|
||||
done();
|
||||
}
|
||||
@@ -1458,13 +1456,13 @@ describe('Parse.User testing', () => {
|
||||
"Expiration should be cleared.");
|
||||
done();
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "unlinking should succeed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have worked");
|
||||
done();
|
||||
}
|
||||
@@ -1504,19 +1502,19 @@ describe('Parse.User testing', () => {
|
||||
"User should be linked to facebook");
|
||||
done();
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking again should succeed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "unlinking should succeed");
|
||||
done();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have worked");
|
||||
done();
|
||||
}
|
||||
@@ -1552,7 +1550,7 @@ describe('Parse.User testing', () => {
|
||||
}
|
||||
})
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have worked");
|
||||
done();
|
||||
}
|
||||
@@ -1575,14 +1573,14 @@ describe('Parse.User testing', () => {
|
||||
Parse.User._registerAuthenticationProvider(mockProvider);
|
||||
let objectId = model.id;
|
||||
model._linkWith("myoauth", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
Parse.User._registerAuthenticationProvider(secondProvider);
|
||||
Parse.User.logOut().then(() => {
|
||||
return Parse.User._logInWith("facebook", {
|
||||
success: () => {
|
||||
Parse.User.logOut().then(() => {
|
||||
success: () => {
|
||||
Parse.User.logOut().then(() => {
|
||||
return Parse.User._logInWith("myoauth", {
|
||||
success: (user) => {
|
||||
success: (user) => {
|
||||
expect(user.id).toBe(objectId);
|
||||
done();
|
||||
}
|
||||
@@ -1639,30 +1637,30 @@ describe('Parse.User testing', () => {
|
||||
}
|
||||
})
|
||||
},
|
||||
error: function(model, error) {
|
||||
error: function() {
|
||||
ok(false, "linking should have worked");
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail linking with existing', (done) => {
|
||||
it('should fail linking with existing', (done) => {
|
||||
var provider = getMockFacebookProvider();
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
Parse.User.logOut().then(() => {
|
||||
success: function() {
|
||||
Parse.User.logOut().then(() => {
|
||||
let user = new Parse.User();
|
||||
user.setUsername('user');
|
||||
user.setPassword('password');
|
||||
return user.signUp().then(() => {
|
||||
// try to link here
|
||||
user._linkWith('facebook', {
|
||||
success: () => {
|
||||
success: () => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
},
|
||||
error: (err) => {
|
||||
error: () => {
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1672,20 +1670,20 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail linking with existing', (done) => {
|
||||
it('should fail linking with existing', (done) => {
|
||||
var provider = getMockFacebookProvider();
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
let userId = model.id;
|
||||
Parse.User.logOut().then(() => {
|
||||
Parse.User.logOut().then(() => {
|
||||
request.post({
|
||||
url:Parse.serverURL+'/classes/_User',
|
||||
headers: {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest'
|
||||
},
|
||||
json: {authData: {facebook: provider.authData}}
|
||||
url:Parse.serverURL+'/classes/_User',
|
||||
headers: {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest'
|
||||
},
|
||||
json: {authData: {facebook: provider.authData}}
|
||||
}, (err,res, body) => {
|
||||
// make sure the location header is properly set
|
||||
expect(userId).not.toBeUndefined();
|
||||
@@ -1698,7 +1696,7 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly error when password is missing', (done) => {
|
||||
it('should properly error when password is missing', (done) => {
|
||||
var provider = getMockFacebookProvider();
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
@@ -1709,7 +1707,7 @@ describe('Parse.User testing', () => {
|
||||
return Parse.User.logOut();
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('myUser', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}, (err) => {
|
||||
@@ -1721,9 +1719,9 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should have authData in beforeSave and afterSave', (done) => {
|
||||
it('should have authData in beforeSave and afterSave', (done) => {
|
||||
|
||||
Parse.Cloud.beforeSave('_User', (request, response) => {
|
||||
Parse.Cloud.beforeSave('_User', (request, response) => {
|
||||
let authData = request.object.get('authData');
|
||||
expect(authData).not.toBeUndefined();
|
||||
if (authData) {
|
||||
@@ -1735,7 +1733,7 @@ describe('Parse.User testing', () => {
|
||||
response.success();
|
||||
});
|
||||
|
||||
Parse.Cloud.afterSave('_User', (request, response) => {
|
||||
Parse.Cloud.afterSave('_User', (request, response) => {
|
||||
let authData = request.object.get('authData');
|
||||
expect(authData).not.toBeUndefined();
|
||||
if (authData) {
|
||||
@@ -1750,7 +1748,7 @@ describe('Parse.User testing', () => {
|
||||
var provider = getMockFacebookProvider();
|
||||
Parse.User._registerAuthenticationProvider(provider);
|
||||
Parse.User._logInWith("facebook", {
|
||||
success: function(model) {
|
||||
success: function() {
|
||||
done();
|
||||
}
|
||||
});
|
||||
@@ -1777,7 +1775,7 @@ describe('Parse.User testing', () => {
|
||||
user.set("password", "onetwothreefour");
|
||||
ok(!user.authenticated());
|
||||
user.signUp(null, expectSuccess({
|
||||
success: function(result) {
|
||||
success: function() {
|
||||
ok(user.authenticated());
|
||||
done();
|
||||
}
|
||||
@@ -1932,13 +1930,13 @@ describe('Parse.User testing', () => {
|
||||
user.setUsername("zxcv");
|
||||
var currentSessionToken = "";
|
||||
Parse.Promise.as().then(function() {
|
||||
return user.signUp();
|
||||
return user.signUp();
|
||||
}).then(function(){
|
||||
currentSessionToken = user.getSessionToken();
|
||||
return user.fetch();
|
||||
currentSessionToken = user.getSessionToken();
|
||||
return user.fetch();
|
||||
}).then(function(u){
|
||||
expect(currentSessionToken).toEqual(u.getSessionToken());
|
||||
done();
|
||||
expect(currentSessionToken).toEqual(u.getSessionToken());
|
||||
done();
|
||||
}, function(error) {
|
||||
ok(false, error);
|
||||
done();
|
||||
@@ -1973,7 +1971,7 @@ describe('Parse.User testing', () => {
|
||||
}).then(() => {
|
||||
fail('Should not have been able to sign up.');
|
||||
done();
|
||||
}, (error) => {
|
||||
}, () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -1994,7 +1992,7 @@ describe('Parse.User testing', () => {
|
||||
}).then(() => {
|
||||
fail('Should not have been able to sign up.');
|
||||
done();
|
||||
}, (error) => {
|
||||
}, () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2066,7 +2064,7 @@ describe('Parse.User testing', () => {
|
||||
it('user get session from token on login', (done) => {
|
||||
Parse.Promise.as().then(() => {
|
||||
return Parse.User.signUp("finn", "human", { foo: "bar" });
|
||||
}).then((user) => {
|
||||
}).then(() => {
|
||||
return Parse.User.logOut().then(() => {
|
||||
return Parse.User.logIn("finn", "human");
|
||||
})
|
||||
@@ -2114,7 +2112,7 @@ describe('Parse.User testing', () => {
|
||||
body: JSON.stringify({ foo: 'bar' })
|
||||
}, (error, response, body) => {
|
||||
expect(error).toBe(null);
|
||||
var b = JSON.parse(body);
|
||||
JSON.parse(body);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2181,7 +2179,7 @@ describe('Parse.User testing', () => {
|
||||
'X-Parse-REST-API-Key': 'rest'
|
||||
},
|
||||
url: 'http://localhost:8378/1/sessions/' + objId
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toBe(null);
|
||||
request.get({
|
||||
headers: {
|
||||
@@ -2207,7 +2205,7 @@ describe('Parse.User testing', () => {
|
||||
.then((pass) => {
|
||||
expect(pass).toBe(true);
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Password format did not match.');
|
||||
done();
|
||||
});
|
||||
@@ -2226,7 +2224,7 @@ describe('Parse.User testing', () => {
|
||||
return newUser.save();
|
||||
}).then(function() {
|
||||
return Parse.User.become(sessionToken);
|
||||
}).then(function(newUser) {
|
||||
}).then(function() {
|
||||
fail('Session should have been invalidated');
|
||||
done();
|
||||
}, function(err) {
|
||||
@@ -2251,7 +2249,7 @@ describe('Parse.User testing', () => {
|
||||
}).then(function(newUser) {
|
||||
equal(newUser.get('foo'), 2);
|
||||
done();
|
||||
}, function(e) {
|
||||
}, function() {
|
||||
fail('The session should still be valid');
|
||||
done();
|
||||
});
|
||||
@@ -2281,9 +2279,9 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it('support user/password signup with empty authData block', (done) => {
|
||||
// The android SDK can send an empty authData object along with username and password.
|
||||
Parse.User.signUp('artof', 'thedeal', { authData: {} }).then((user) => {
|
||||
Parse.User.signUp('artof', 'thedeal', { authData: {} }).then(() => {
|
||||
done();
|
||||
}, (error) => {
|
||||
}, () => {
|
||||
fail('Signup should have succeeded.');
|
||||
done();
|
||||
});
|
||||
@@ -2291,7 +2289,7 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it("session expiresAt correct format", (done) => {
|
||||
Parse.User.signUp("asdf", "zxcv", null, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/classes/_Session',
|
||||
json: true,
|
||||
@@ -2309,7 +2307,7 @@ describe('Parse.User testing', () => {
|
||||
|
||||
it("invalid session tokens are rejected", (done) => {
|
||||
Parse.User.signUp("asdf", "zxcv", null, {
|
||||
success: function(user) {
|
||||
success: function() {
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/classes/AClass',
|
||||
json: true,
|
||||
@@ -2333,8 +2331,8 @@ describe('Parse.User testing', () => {
|
||||
username: 'user',
|
||||
_hashed_password: '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie',
|
||||
_auth_data_facebook: null
|
||||
}, {}).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
}, {}).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/login?username=user&password=test',
|
||||
headers: {
|
||||
@@ -2355,7 +2353,7 @@ describe('Parse.User testing', () => {
|
||||
expect(user.username).toEqual('user');
|
||||
expect(authData).toBeUndefined();
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
fail('this should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -2367,7 +2365,7 @@ describe('Parse.User testing', () => {
|
||||
username: 'user',
|
||||
_hashed_password: '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie',
|
||||
_auth_data_facebook: null
|
||||
}, {}).then(() => {
|
||||
}, {}).then(() => {
|
||||
return new Parse.Query(Parse.User)
|
||||
.equalTo('username', 'user')
|
||||
.first({useMasterKey: true});
|
||||
@@ -2376,7 +2374,7 @@ describe('Parse.User testing', () => {
|
||||
expect(user.get('username')).toEqual('user');
|
||||
expect(authData).toBeUndefined();
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
fail('this should not fail');
|
||||
done();
|
||||
})
|
||||
@@ -2484,12 +2482,12 @@ describe('Parse.User testing', () => {
|
||||
})
|
||||
// Simulate anonymous user save
|
||||
return rp.post({
|
||||
url: 'http://localhost:8378/1/classes/_User',
|
||||
headers: {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
},
|
||||
json: {authData: {anonymous: {id: '00000000-0000-0000-0000-000000000001'}}}
|
||||
url: 'http://localhost:8378/1/classes/_User',
|
||||
headers: {
|
||||
'X-Parse-Application-Id': Parse.applicationId,
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
},
|
||||
json: {authData: {anonymous: {id: '00000000-0000-0000-0000-000000000001'}}}
|
||||
}).then((user) => {
|
||||
return rp.put({
|
||||
url: 'http://localhost:8378/1/classes/_User/' + user.objectId,
|
||||
@@ -2554,6 +2552,8 @@ describe('Parse.User testing', () => {
|
||||
fail('no request should succeed: ' + JSON.stringify(res));
|
||||
done();
|
||||
}).catch((err) => {
|
||||
expect(emailCalled).toBeTruthy();
|
||||
expect(emailOptions).toBeDefined();
|
||||
expect(err.statusCode).toBe(400);
|
||||
expect(err.message).toMatch('{"code":125,"error":"you must provide a valid email string"}');
|
||||
done();
|
||||
@@ -2563,7 +2563,7 @@ describe('Parse.User testing', () => {
|
||||
});
|
||||
|
||||
|
||||
it('should aftersave with full object', (done) => {
|
||||
it('should aftersave with full object', (done) => {
|
||||
var hit = 0;
|
||||
Parse.Cloud.afterSave('_User', (req, res) => {
|
||||
hit++;
|
||||
@@ -2577,6 +2577,7 @@ describe('Parse.User testing', () => {
|
||||
user.set('hello', 'world');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
expect(hit).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -2596,7 +2597,7 @@ describe('Parse.User testing', () => {
|
||||
return Parse.Cloud.run('testUpdatedUser');
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Should not have failed.');
|
||||
done();
|
||||
});
|
||||
@@ -2606,7 +2607,7 @@ describe('Parse.User testing', () => {
|
||||
it('should fail to become user with expired token', (done) => {
|
||||
let token;
|
||||
Parse.User.signUp("auser", "somepass", null)
|
||||
.then(user => rp({
|
||||
.then(() => rp({
|
||||
method: 'GET',
|
||||
url: 'http://localhost:8378/1/classes/_Session',
|
||||
json: true,
|
||||
@@ -2643,26 +2644,26 @@ describe('Parse.User testing', () => {
|
||||
})
|
||||
});
|
||||
|
||||
it('should not create extraneous session tokens', (done) => {
|
||||
it('should not create extraneous session tokens', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
config.database.loadSchema().then((s) => {
|
||||
// Lock down the _User class for creation
|
||||
return s.addClassIfNotExists('_User', {}, {create: {}})
|
||||
}).then((res) => {
|
||||
}).then(() => {
|
||||
let user = new Parse.User();
|
||||
return user.save({'username': 'user', 'password': 'pass'});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not be able to save the user');
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('_Session');
|
||||
return q.find({useMasterKey: true})
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
// We should have no session created
|
||||
expect(res.length).toBe(0);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
});
|
||||
@@ -2721,15 +2722,15 @@ describe('Parse.User testing', () => {
|
||||
user.set('password', 'password');
|
||||
return user.save()
|
||||
})
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
// Session token should have been recycled
|
||||
expect(body.sessionToken).not.toEqual(user.getSessionToken());
|
||||
})
|
||||
.then(() => obj.fetch())
|
||||
.then((res) => {
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
.catch(() => {
|
||||
fail('should not fail')
|
||||
done();
|
||||
});
|
||||
@@ -2773,12 +2774,12 @@ describe('Parse.User testing', () => {
|
||||
username: 'hello',
|
||||
password: 'world'
|
||||
})
|
||||
user.signUp().then(() => {
|
||||
user.signUp().then(() => {
|
||||
return Parse.User.current().relation('relation').query().find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const requestp = require('request-promise');
|
||||
const Config = require('../src/Config');
|
||||
|
||||
describe("Password Policy: ", () => {
|
||||
|
||||
@@ -28,8 +27,8 @@ describe("Password Policy: ", () => {
|
||||
user.setPassword("original");
|
||||
user.set('email', 'user@parse.com');
|
||||
return user.signUp();
|
||||
}).then(user => {
|
||||
Parse.User.requestPasswordReset('user@parse.com').catch((err) => {
|
||||
}).then(() => {
|
||||
Parse.User.requestPasswordReset("user@parse.com").catch((err) => {
|
||||
jfail(err);
|
||||
fail("Reset password request should not fail");
|
||||
done();
|
||||
@@ -81,7 +80,7 @@ describe("Password Policy: ", () => {
|
||||
user.setPassword("original");
|
||||
user.set('email', 'user@parse.com');
|
||||
return user.signUp();
|
||||
}).then(user => {
|
||||
}).then(() => {
|
||||
Parse.User.requestPasswordReset('user@parse.com').catch((err) => {
|
||||
jfail(err);
|
||||
fail("Reset password request should not fail");
|
||||
@@ -212,7 +211,7 @@ describe("Password Policy: ", () => {
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
Parse.User.logOut().then(() => {
|
||||
Parse.User.logIn("user1", "1digit").then(function (user) {
|
||||
Parse.User.logIn("user1", "1digit").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -237,7 +236,7 @@ describe("Password Policy: ", () => {
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
validatorCallback: password => false // just fail
|
||||
validatorCallback: () => false // just fail
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
@@ -259,7 +258,7 @@ describe("Password Policy: ", () => {
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
validatorCallback: password => true // never fail
|
||||
validatorCallback: () => true // never fail
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
@@ -268,7 +267,7 @@ describe("Password Policy: ", () => {
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
Parse.User.logOut().then(() => {
|
||||
Parse.User.logIn("user1", "oneUpper").then(function (user) {
|
||||
Parse.User.logIn("user1", "oneUpper").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -294,7 +293,7 @@ describe("Password Policy: ", () => {
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
validatorPattern: /[A-Z]+/, // password should contain at least one UPPER case letter
|
||||
validatorCallback: value => true
|
||||
validatorCallback: () => true
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
@@ -317,7 +316,7 @@ describe("Password Policy: ", () => {
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
validatorPattern: /[A-Z]+/, // password should contain at least one UPPER case letter
|
||||
validatorCallback: value => false
|
||||
validatorCallback: () => false
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
@@ -340,7 +339,7 @@ describe("Password Policy: ", () => {
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
validatorPattern: /[A-Z]+/, // password should contain at least one digit
|
||||
validatorCallback: value => true
|
||||
validatorCallback: () => true
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
@@ -349,7 +348,7 @@ describe("Password Policy: ", () => {
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
Parse.User.logOut().then(() => {
|
||||
Parse.User.logIn("user1", "oneUpper").then(function (user) {
|
||||
Parse.User.logIn("user1", "oneUpper").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -403,7 +402,7 @@ describe("Password Policy: ", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/password_reset_success.html?username=user1');
|
||||
|
||||
Parse.User.logIn("user1", "has2init").then(function (user) {
|
||||
Parse.User.logIn("user1", "has2init").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -484,7 +483,7 @@ describe("Password Policy: ", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual(`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20does%20not%20meet%20the%20Password%20Policy%20requirements.&app=passwordPolicy`);
|
||||
|
||||
Parse.User.logIn("user1", "has 1 digit").then(function (user) {
|
||||
Parse.User.logIn("user1", "has 1 digit").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -584,7 +583,7 @@ describe("Password Policy: ", () => {
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
done();
|
||||
}).catch((error) => {
|
||||
}).catch(() => {
|
||||
fail('Should have succeeded as password does not contain username.');
|
||||
done();
|
||||
});
|
||||
@@ -605,7 +604,7 @@ describe("Password Policy: ", () => {
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
done();
|
||||
}).catch((error) => {
|
||||
}).catch(() => {
|
||||
fail('Should have succeeded as policy allows username in password.');
|
||||
done();
|
||||
});
|
||||
@@ -646,7 +645,7 @@ describe("Password Policy: ", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual(`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20does%20not%20meet%20the%20Password%20Policy%20requirements.&app=passwordPolicy`);
|
||||
|
||||
Parse.User.logIn("user1", "r@nd0m").then(function (user) {
|
||||
Parse.User.logIn("user1", "r@nd0m").then(function () {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
@@ -728,7 +727,7 @@ describe("Password Policy: ", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/password_reset_success.html?username=user1');
|
||||
|
||||
Parse.User.logIn("user1", "uuser11").then(function (user) {
|
||||
Parse.User.logIn("user1", "uuser11").then(function () {
|
||||
done();
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
@@ -819,8 +818,8 @@ describe("Password Policy: ", () => {
|
||||
user.setUsername("user1");
|
||||
user.setPassword("user1");
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then((u) => {
|
||||
Parse.User.logIn("user1", "user1").then((user) => {
|
||||
user.signUp().then(() => {
|
||||
Parse.User.logIn("user1", "user1").then(() => {
|
||||
done();
|
||||
}).catch((error) => {
|
||||
jfail(error);
|
||||
@@ -885,7 +884,7 @@ describe("Password Policy: ", () => {
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
Parse.User.logIn("user1", "user1").then((u) => {
|
||||
Parse.User.logIn("user1", "user1").then(() => {
|
||||
Parse.User.logOut().then(() => {
|
||||
// wait for a bit more than the validity duration set
|
||||
setTimeout(() => {
|
||||
@@ -957,7 +956,7 @@ describe("Password Policy: ", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/password_reset_success.html?username=user1');
|
||||
|
||||
Parse.User.logIn("user1", "uuser11").then(function (user) {
|
||||
Parse.User.logIn("user1", "uuser11").then(function () {
|
||||
done();
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
'use strict';
|
||||
var Schema = require('../src/Controllers/SchemaController');
|
||||
|
||||
var Config = require('../src/Config');
|
||||
|
||||
describe('Pointer Permissions', () => {
|
||||
describe('Pointer Permissions', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
new Config(Parse.applicationId).database.schemaCache.clear();
|
||||
});
|
||||
|
||||
it('should work with find', (done) => {
|
||||
it('should work with find', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let user2 = new Parse.User();
|
||||
@@ -28,27 +26,27 @@ describe('Pointer Permissions', () => {
|
||||
obj.set('owner', user);
|
||||
obj2.set('owner', user2);
|
||||
return Parse.Object.saveAll([obj, obj2]);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
return schema.updateClass('AnObject', {}, {readUserFields: ['owner']})
|
||||
});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find();
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].id).toBe(obj.id);
|
||||
done();
|
||||
}).catch(error => {
|
||||
}).catch(error => {
|
||||
fail(JSON.stringify(error));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should work with write', (done) => {
|
||||
it('should work with write', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let user2 = new Parse.User();
|
||||
@@ -69,16 +67,16 @@ describe('Pointer Permissions', () => {
|
||||
obj2.set('owner', user2);
|
||||
obj2.set('reader', user);
|
||||
return Parse.Object.saveAll([obj, obj2]);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
return schema.updateClass('AnObject', {}, {writeUserFields: ['owner'], readUserFields: ['reader', 'owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
obj2.set('hello', 'world');
|
||||
return obj2.save();
|
||||
}).then((res) => {
|
||||
}).then(() => {
|
||||
fail('User should not be able to update obj2');
|
||||
}, (err) => {
|
||||
// User 1 should not be able to update obj2
|
||||
@@ -87,19 +85,19 @@ describe('Pointer Permissions', () => {
|
||||
}).then(()=> {
|
||||
obj.set('hello', 'world');
|
||||
return obj.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('User should be able to update');
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should login with user 2');
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(2);
|
||||
res.forEach((result) => {
|
||||
res.forEach((result) => {
|
||||
if (result.id == obj.id) {
|
||||
expect(result.get('hello')).toBe('world');
|
||||
} else {
|
||||
@@ -107,7 +105,7 @@ describe('Pointer Permissions', () => {
|
||||
}
|
||||
})
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail("failed");
|
||||
done();
|
||||
})
|
||||
@@ -129,32 +127,32 @@ describe('Pointer Permissions', () => {
|
||||
let obj2 = new Parse.Object('AnObject');
|
||||
user.signUp().then(() => {
|
||||
return user2.signUp()
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
Parse.User.logOut();
|
||||
}).then(() => {
|
||||
obj.set('owner', user);
|
||||
return Parse.Object.saveAll([obj, obj2]);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
return schema.updateClass('AnObject', {}, {find: {}, get:{}, readUserFields: ['owner']})
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(0);
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(0);
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.get(obj.id);
|
||||
}).then(() => {
|
||||
fail('User 2 should not get the obj1 object');
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
expect(err.message).toBe('Object not found.');
|
||||
return Promise.resolve();
|
||||
@@ -163,17 +161,17 @@ describe('Pointer Permissions', () => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(1);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should not allow creating objects', (done) => {
|
||||
it('should not allow creating objects', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
user.set({
|
||||
@@ -181,25 +179,25 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
user.save().then(() => {
|
||||
user.save().then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type:'Pointer', targetClass: '_User'}}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
obj.set('owner', user);
|
||||
return obj.save();
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(119);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should handle multiple writeUserFields', done => {
|
||||
it('should handle multiple writeUserFields', done => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let user2 = new Parse.User();
|
||||
@@ -218,10 +216,10 @@ describe('Pointer Permissions', () => {
|
||||
obj.set('otherOwner', user2);
|
||||
return obj.save();
|
||||
})
|
||||
.then(() => config.database.loadSchema())
|
||||
.then(() => config.database.loadSchema())
|
||||
.then(schema => schema.updateClass('AnObject', {}, {find: {"*": true},writeUserFields: ['owner', 'otherOwner']}))
|
||||
.then(() => Parse.User.logIn('user1', 'password'))
|
||||
.then(() => obj.save({hello: 'fromUser1'}))
|
||||
.then(() => Parse.User.logIn('user1', 'password'))
|
||||
.then(() => obj.save({hello: 'fromUser1'}))
|
||||
.then(() => Parse.User.logIn('user2', 'password'))
|
||||
.then(() => obj.save({hello: 'fromUser2'}))
|
||||
.then(() => Parse.User.logOut())
|
||||
@@ -229,59 +227,59 @@ describe('Pointer Permissions', () => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.first();
|
||||
})
|
||||
.then(result => {
|
||||
.then(result => {
|
||||
expect(result.get('hello')).toBe('fromUser2');
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(() => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should prevent creating pointer permission on missing field', (done) => {
|
||||
it('should prevent creating pointer permission on missing field', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
config.database.loadSchema().then((schema) => {
|
||||
return schema.addClassIfNotExists('AnObject', {}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
expect(err.code).toBe(107);
|
||||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should prevent creating pointer permission on bad field', (done) => {
|
||||
it('should prevent creating pointer permission on bad field', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
config.database.loadSchema().then((schema) => {
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'String'}}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
expect(err.code).toBe(107);
|
||||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should prevent creating pointer permission on bad field', (done) => {
|
||||
it('should prevent creating pointer permission on bad field', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let object = new Parse.Object('AnObject');
|
||||
object.set('owner', 'value');
|
||||
object.save().then(() => {
|
||||
object.save().then(() => {
|
||||
return config.database.loadSchema();
|
||||
}).then((schema) => {
|
||||
return schema.updateClass('AnObject', {}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('should not succeed');
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
expect(err.code).toBe(107);
|
||||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL write (PP Locked)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL write (PP Locked)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: update closed ({})
|
||||
@@ -314,21 +312,21 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user1 has ACL read/write but should be blocked by PP
|
||||
return obj.save({key: 'value'});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed saving');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL write (ACL Locked)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL write (ACL Locked)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: update closed ({})
|
||||
@@ -347,7 +345,7 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
let ACL = new Parse.ACL();
|
||||
ACL.setReadAccess(user, true);
|
||||
ACL.setWriteAccess(user, true);
|
||||
@@ -359,21 +357,21 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user1 has ACL read/write but should be blocked by ACL
|
||||
return obj.save({key: 'value'});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed saving');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL write (ACL/PP OK)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL write (ACL/PP OK)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: update closed ({})
|
||||
@@ -392,7 +390,7 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
let ACL = new Parse.ACL();
|
||||
ACL.setWriteAccess(user, true);
|
||||
ACL.setWriteAccess(user2, true);
|
||||
@@ -404,21 +402,21 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user1 has ACL read/write but should be blocked by ACL
|
||||
return obj.save({key: 'value'});
|
||||
}).then((objAgain) => {
|
||||
}).then((objAgain) => {
|
||||
expect(objAgain.get('key')).toBe('value');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('Should not fail saving');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL read (PP locked)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL read (PP locked)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: find/get open ({})
|
||||
@@ -439,7 +437,7 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
let ACL = new Parse.ACL();
|
||||
ACL.setReadAccess(user, true);
|
||||
ACL.setWriteAccess(user, true);
|
||||
@@ -451,21 +449,21 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {find: {}, get: {}, readUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user1', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user1 has ACL read/write but should be block
|
||||
return obj.fetch();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed saving');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL read (PP/ACL OK)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL read (PP/ACL OK)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: find/get open ({"*": true})
|
||||
@@ -484,7 +482,7 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
let ACL = new Parse.ACL();
|
||||
ACL.setReadAccess(user, true);
|
||||
ACL.setWriteAccess(user, true);
|
||||
@@ -498,21 +496,21 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {find: {"*": true}, get: {"*": true}, readUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user1 has ACL read/write but should be block
|
||||
return obj.fetch();
|
||||
}).then((objAgain) => {
|
||||
}).then((objAgain) => {
|
||||
expect(objAgain.id).toBe(obj.id);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('Should not fail fetching');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tests CLP / Pointer Perms / ACL read (ACL locked)', (done) => {
|
||||
it('tests CLP / Pointer Perms / ACL read (ACL locked)', (done) => {
|
||||
/*
|
||||
tests:
|
||||
CLP: find/get open ({"*": true})
|
||||
@@ -531,7 +529,7 @@ describe('Pointer Permissions', () => {
|
||||
password: 'password'
|
||||
});
|
||||
let obj = new Parse.Object('AnObject');
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
Parse.Object.saveAll([user, user2]).then(() => {
|
||||
let ACL = new Parse.ACL();
|
||||
ACL.setReadAccess(user, true);
|
||||
ACL.setWriteAccess(user, true);
|
||||
@@ -543,15 +541,15 @@ describe('Pointer Permissions', () => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {}, {find: {"*": true}, get: {"*": true}, readUserFields: ['owner']});
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'password');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// user2 has ACL read/write but should be block by ACL
|
||||
return obj.fetch();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('Should not succeed saving');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
done();
|
||||
});
|
||||
@@ -559,10 +557,9 @@ describe('Pointer Permissions', () => {
|
||||
|
||||
it('should let master key find objects', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let object = new Parse.Object('AnObject');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {find: {}, get: {}, readUserFields: ['owner']});
|
||||
@@ -575,13 +572,13 @@ describe('Pointer Permissions', () => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let q = new Parse.Query('AnObject');
|
||||
return q.find({useMasterKey: true});
|
||||
}).then((objects) => {
|
||||
expect(objects.length).toBe(1);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('master key should find the object');
|
||||
done();
|
||||
})
|
||||
@@ -589,10 +586,9 @@ describe('Pointer Permissions', () => {
|
||||
|
||||
it('should let master key get objects', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let object = new Parse.Object('AnObject');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {find: {}, get: {}, readUserFields: ['owner']});
|
||||
@@ -612,7 +608,7 @@ describe('Pointer Permissions', () => {
|
||||
expect(objectAgain).not.toBeUndefined();
|
||||
expect(objectAgain.id).toBe(object.id);
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('master key should find the object');
|
||||
done();
|
||||
})
|
||||
@@ -621,10 +617,9 @@ describe('Pointer Permissions', () => {
|
||||
|
||||
it('should let master key update objects', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let object = new Parse.Object('AnObject');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {update: {}, writeUserFields: ['owner']});
|
||||
@@ -636,12 +631,12 @@ describe('Pointer Permissions', () => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return object.save({'hello': 'baz'}, {useMasterKey: true});
|
||||
}).then((objectAgain) => {
|
||||
expect(objectAgain.get('hello')).toBe('baz');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('master key should save the object');
|
||||
done();
|
||||
})
|
||||
@@ -649,10 +644,9 @@ describe('Pointer Permissions', () => {
|
||||
|
||||
it('should let master key delete objects', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
let user = new Parse.User();
|
||||
let object = new Parse.Object('AnObject');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
return config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: ['owner']});
|
||||
@@ -664,35 +658,35 @@ describe('Pointer Permissions', () => {
|
||||
}, (err) => {
|
||||
expect(err.code).toBe(101);
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return object.destroy({useMasterKey: true});
|
||||
}).then((objectAgain) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('master key should destroy the object');
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('should fail with invalid pointer perms', () => {
|
||||
it('should fail with invalid pointer perms', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: 'owner'});
|
||||
}).catch((err) => {
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: 'owner'});
|
||||
}).catch((err) => {
|
||||
expect(err.code).toBe(Parse.Error.INVALID_JSON);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail with invalid pointer perms', () => {
|
||||
it('should fail with invalid pointer perms', (done) => {
|
||||
let config = new Config(Parse.applicationId);
|
||||
config.database.loadSchema().then((schema) => {
|
||||
// Lock the update, and let only owner write
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: ['owner', 'invalid']});
|
||||
}).catch((err) => {
|
||||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: ['owner', 'invalid']});
|
||||
}).catch((err) => {
|
||||
expect(err.code).toBe(Parse.Error.INVALID_JSON);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
var PromiseRouter = require("../src/PromiseRouter").default;
|
||||
|
||||
describe("PromiseRouter", () => {
|
||||
it("should properly handle rejects", (done) => {
|
||||
describe("PromiseRouter", () => {
|
||||
it("should properly handle rejects", (done) => {
|
||||
var router = new PromiseRouter();
|
||||
router.route("GET", "/dummy", (req)=> {
|
||||
router.route("GET", "/dummy", ()=> {
|
||||
return Promise.reject({
|
||||
error: "an error",
|
||||
code: -1
|
||||
})
|
||||
}, (req) => {
|
||||
}, () => {
|
||||
fail("this should not be called");
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ var request = require('request');
|
||||
|
||||
describe("public API", () => {
|
||||
it("should get invalid_link.html", (done) => {
|
||||
request('http://localhost:8378/1/apps/invalid_link.html', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/invalid_link.html', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(200);
|
||||
done();
|
||||
});
|
||||
@@ -15,7 +15,7 @@ describe("public API", () => {
|
||||
publicServerURL: 'http://localhost:8378/1',
|
||||
})
|
||||
.then(() => {
|
||||
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(200);
|
||||
done();
|
||||
});
|
||||
@@ -23,14 +23,14 @@ describe("public API", () => {
|
||||
});
|
||||
|
||||
it("should get verify_email_success.html", (done) => {
|
||||
request('http://localhost:8378/1/apps/verify_email_success.html', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/verify_email_success.html', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should get password_reset_success.html", (done) => {
|
||||
request('http://localhost:8378/1/apps/password_reset_success.html', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/password_reset_success.html', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(200);
|
||||
done();
|
||||
});
|
||||
@@ -38,26 +38,26 @@ describe("public API", () => {
|
||||
});
|
||||
|
||||
describe("public API without publicServerURL", () => {
|
||||
beforeEach(done => {
|
||||
beforeEach(done => {
|
||||
reconfigureServer({ appName: 'unused' })
|
||||
.then(done, fail);
|
||||
});
|
||||
it("should get 404 on verify_email", (done) => {
|
||||
request('http://localhost:8378/1/apps/test/verify_email', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/test/verify_email', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should get 404 choose_password", (done) => {
|
||||
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should get 404 on request_password_reset", (done) => {
|
||||
request('http://localhost:8378/1/apps/test/request_password_reset', (err, httpResponse, body) => {
|
||||
request('http://localhost:8378/1/apps/test/request_password_reset', (err, httpResponse) => {
|
||||
expect(httpResponse.statusCode).toBe(404);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -21,14 +21,14 @@ function createProduct() {
|
||||
|
||||
describe("test validate_receipt endpoint", () => {
|
||||
beforeEach( done => {
|
||||
createProduct().then(done).fail(function(err){
|
||||
createProduct().then(done).fail(function(){
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it("should bypass appstore validation", (done) => {
|
||||
|
||||
request.post({
|
||||
request.post({
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'},
|
||||
@@ -45,7 +45,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
}, function(err, res, body){
|
||||
if (typeof body != "object") {
|
||||
fail("Body is not an object");
|
||||
done();
|
||||
done();
|
||||
} else {
|
||||
expect(body.__type).toEqual("File");
|
||||
const url = body.url;
|
||||
@@ -60,7 +60,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
});
|
||||
|
||||
it("should fail for missing receipt", (done) => {
|
||||
request.post({
|
||||
request.post({
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'},
|
||||
@@ -73,7 +73,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
}, function(err, res, body){
|
||||
if (typeof body != "object") {
|
||||
fail("Body is not an object");
|
||||
done();
|
||||
done();
|
||||
} else {
|
||||
expect(body.code).toEqual(Parse.Error.INVALID_JSON);
|
||||
done();
|
||||
@@ -82,7 +82,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
});
|
||||
|
||||
it("should fail for missing product identifier", (done) => {
|
||||
request.post({
|
||||
request.post({
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'},
|
||||
@@ -98,7 +98,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
}, function(err, res, body){
|
||||
if (typeof body != "object") {
|
||||
fail("Body is not an object");
|
||||
done();
|
||||
done();
|
||||
} else {
|
||||
expect(body.code).toEqual(Parse.Error.INVALID_JSON);
|
||||
done();
|
||||
@@ -108,7 +108,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
|
||||
it("should bypass appstore validation and not find product", (done) => {
|
||||
|
||||
request.post({
|
||||
request.post({
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'},
|
||||
@@ -135,7 +135,7 @@ describe("test validate_receipt endpoint", () => {
|
||||
});
|
||||
|
||||
it("should fail at appstore validation", done => {
|
||||
request.post({
|
||||
request.post({
|
||||
headers: {
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest'},
|
||||
@@ -160,49 +160,49 @@ describe("test validate_receipt endpoint", () => {
|
||||
});
|
||||
|
||||
it("should not create a _Product", (done) => {
|
||||
var product = new Parse.Object("_Product");
|
||||
product.save().then(function(){
|
||||
fail("Should not be able to save");
|
||||
done();
|
||||
}, function(err){
|
||||
expect(err.code).toEqual(Parse.Error.INCORRECT_TYPE);
|
||||
done();
|
||||
})
|
||||
var product = new Parse.Object("_Product");
|
||||
product.save().then(function(){
|
||||
fail("Should not be able to save");
|
||||
done();
|
||||
}, function(err){
|
||||
expect(err.code).toEqual(Parse.Error.INCORRECT_TYPE);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it("should be able to update a _Product", (done) => {
|
||||
var query = new Parse.Query("_Product");
|
||||
query.first().then(function(product) {
|
||||
if (!product) {
|
||||
return Promise.reject(new Error('Product should be found'));
|
||||
}
|
||||
product.set("title", "a new title");
|
||||
return product.save();
|
||||
}).then(function(productAgain){
|
||||
expect(productAgain.get('downloadName')).toEqual(productAgain.get('download').name());
|
||||
expect(productAgain.get("title")).toEqual("a new title");
|
||||
done();
|
||||
}).fail(function(err){
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
var query = new Parse.Query("_Product");
|
||||
query.first().then(function(product) {
|
||||
if (!product) {
|
||||
return Promise.reject(new Error('Product should be found'));
|
||||
}
|
||||
product.set("title", "a new title");
|
||||
return product.save();
|
||||
}).then(function(productAgain){
|
||||
expect(productAgain.get('downloadName')).toEqual(productAgain.get('download').name());
|
||||
expect(productAgain.get("title")).toEqual("a new title");
|
||||
done();
|
||||
}).fail(function(err){
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should not be able to remove a require key in a _Product", (done) => {
|
||||
var query = new Parse.Query("_Product");
|
||||
query.first().then(function(product){
|
||||
if (!product) {
|
||||
return Promise.reject(new Error('Product should be found'));
|
||||
}
|
||||
product.unset("title");
|
||||
return product.save();
|
||||
}).then(function(productAgain){
|
||||
fail("Should not succeed");
|
||||
done();
|
||||
}).fail(function(err){
|
||||
expect(err.code).toEqual(Parse.Error.INCORRECT_TYPE);
|
||||
expect(err.message).toEqual("title is required.");
|
||||
done();
|
||||
});
|
||||
var query = new Parse.Query("_Product");
|
||||
query.first().then(function(product){
|
||||
if (!product) {
|
||||
return Promise.reject(new Error('Product should be found'));
|
||||
}
|
||||
product.unset("title");
|
||||
return product.save();
|
||||
}).then(function(){
|
||||
fail("Should not succeed");
|
||||
done();
|
||||
}).fail(function(err){
|
||||
expect(err.code).toEqual(Parse.Error.INCORRECT_TYPE);
|
||||
expect(err.message).toEqual("title is required.");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ var Config = require('../src/Config');
|
||||
|
||||
const successfulTransmissions = function(body, installations) {
|
||||
|
||||
let promises = installations.map((device) => {
|
||||
let promises = installations.map((device) => {
|
||||
return Promise.resolve({
|
||||
transmitted: true,
|
||||
device: device,
|
||||
@@ -17,7 +17,7 @@ const successfulTransmissions = function(body, installations) {
|
||||
|
||||
const successfulIOS = function(body, installations) {
|
||||
|
||||
let promises = installations.map((device) => {
|
||||
let promises = installations.map((device) => {
|
||||
return Promise.resolve({
|
||||
transmitted: device.deviceType == "ios",
|
||||
device: device,
|
||||
@@ -98,8 +98,8 @@ describe('PushController', () => {
|
||||
// Make mock request
|
||||
var timeStr = '2015-03-19T22:05:08Z';
|
||||
var body = {
|
||||
'expiration_time': timeStr
|
||||
}
|
||||
'expiration_time': timeStr
|
||||
}
|
||||
|
||||
var time = PushController.getExpirationTime(body);
|
||||
expect(time).toEqual(new Date(timeStr).valueOf());
|
||||
@@ -132,114 +132,70 @@ describe('PushController', () => {
|
||||
|
||||
it('properly increment badges', (done) => {
|
||||
|
||||
var payload = {data:{
|
||||
alert: "Hello World!",
|
||||
badge: "Increment",
|
||||
}}
|
||||
var installations = [];
|
||||
while(installations.length != 10) {
|
||||
var installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("badge", installations.length);
|
||||
installation.set("originalBadge", installations.length);
|
||||
installation.set("deviceType", "ios");
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
while(installations.length != 15) {
|
||||
var installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("deviceType", "android");
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
var badge = body.data.badge;
|
||||
installations.forEach((installation) => {
|
||||
if (installation.deviceType == "ios") {
|
||||
expect(installation.badge).toEqual(badge);
|
||||
expect(installation.originalBadge+1).toEqual(installation.badge);
|
||||
} else {
|
||||
expect(installation.badge).toBeUndefined();
|
||||
}
|
||||
})
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios", "android"];
|
||||
var payload = {data:{
|
||||
alert: "Hello World!",
|
||||
badge: "Increment",
|
||||
}}
|
||||
var installations = [];
|
||||
while(installations.length != 10) {
|
||||
let installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("badge", installations.length);
|
||||
installation.set("originalBadge", installations.length);
|
||||
installation.set("deviceType", "ios");
|
||||
installations.push(installation);
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
while(installations.length != 15) {
|
||||
let installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("deviceType", "android");
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then((installations) => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then((result) => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
var badge = body.data.badge;
|
||||
installations.forEach((installation) => {
|
||||
if (installation.deviceType == "ios") {
|
||||
expect(installation.badge).toEqual(badge);
|
||||
expect(installation.originalBadge+1).toEqual(installation.badge);
|
||||
} else {
|
||||
expect(installation.badge).toBeUndefined();
|
||||
}
|
||||
})
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios", "android"];
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then(() => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('properly set badges to 1', (done) => {
|
||||
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
var installations = [];
|
||||
while(installations.length != 10) {
|
||||
var installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("badge", installations.length);
|
||||
installation.set("originalBadge", installations.length);
|
||||
installation.set("deviceType", "ios");
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
var badge = body.data.badge;
|
||||
installations.forEach((installation) => {
|
||||
expect(installation.badge).toEqual(badge);
|
||||
expect(1).toEqual(installation.badge);
|
||||
})
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then((installations) => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then((result) => {
|
||||
done();
|
||||
}, (err) => {
|
||||
fail("should not fail");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('properly creates _PushStatus', (done) => {
|
||||
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
var installations = [];
|
||||
while(installations.length != 10) {
|
||||
var installation = new Parse.Object("_Installation");
|
||||
@@ -251,188 +207,232 @@ describe('PushController', () => {
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
var badge = body.data.badge;
|
||||
installations.forEach((installation) => {
|
||||
expect(installation.badge).toEqual(badge);
|
||||
expect(1).toEqual(installation.badge);
|
||||
})
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then(() => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then(() => {
|
||||
done();
|
||||
}, () => {
|
||||
fail("should not fail");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('properly creates _PushStatus', (done) => {
|
||||
|
||||
var installations = [];
|
||||
while(installations.length != 10) {
|
||||
let installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("badge", installations.length);
|
||||
installation.set("originalBadge", installations.length);
|
||||
installation.set("deviceType", "ios");
|
||||
installations.push(installation);
|
||||
}
|
||||
|
||||
while(installations.length != 15) {
|
||||
var installation = new Parse.Object("_Installation");
|
||||
let installation = new Parse.Object("_Installation");
|
||||
installation.set("installationId", "installation_"+installations.length);
|
||||
installation.set("deviceToken","device_token_"+installations.length)
|
||||
installation.set("deviceType", "android");
|
||||
installations.push(installation);
|
||||
}
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulIOS(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then(() => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then((result) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, 1000);
|
||||
});
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
return query.find({useMasterKey: true});
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let result = results[0];
|
||||
expect(result.createdAt instanceof Date).toBe(true);
|
||||
expect(result.updatedAt instanceof Date).toBe(true);
|
||||
expect(result.id.length).toBe(10);
|
||||
expect(result.get('source')).toEqual('rest');
|
||||
expect(result.get('query')).toEqual(JSON.stringify({}));
|
||||
expect(typeof result.get('payload')).toEqual("string");
|
||||
expect(JSON.parse(result.get('payload'))).toEqual(payload.data);
|
||||
expect(result.get('status')).toEqual('succeeded');
|
||||
expect(result.get('numSent')).toEqual(10);
|
||||
expect(result.get('sentPerType')).toEqual({
|
||||
'ios': 10 // 10 ios
|
||||
});
|
||||
expect(result.get('numFailed')).toEqual(5);
|
||||
expect(result.get('failedPerType')).toEqual({
|
||||
'android': 5 // android
|
||||
});
|
||||
// Try to get it without masterKey
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should properly report failures in _PushStatus', (done) => {
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return installations.map((installation) => {
|
||||
return Promise.resolve({
|
||||
deviceType: installation.deviceType
|
||||
})
|
||||
})
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
let where = { 'channels': {
|
||||
'$ins': ['Giants', 'Mets']
|
||||
}};
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}).catch(() => {
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
query.find({useMasterKey: true}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let pushStatus = results[0];
|
||||
expect(pushStatus.get('status')).toBe('failed');
|
||||
done();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
it('should support full RESTQuery for increment', (done) => {
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 'Increment',
|
||||
}}
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulIOS(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
let where = {
|
||||
'deviceToken': {
|
||||
'$inQuery': {
|
||||
'where': {
|
||||
'deviceType': 'ios'
|
||||
},
|
||||
className: '_Installation'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then((result) => {
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
Parse.Object.saveAll(installations).then(() => {
|
||||
return pushController.sendPush(payload, {}, config, auth);
|
||||
}).then(() => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, 1000);
|
||||
});
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
return query.find({useMasterKey: true});
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let result = results[0];
|
||||
expect(result.createdAt instanceof Date).toBe(true);
|
||||
expect(result.updatedAt instanceof Date).toBe(true);
|
||||
expect(result.id.length).toBe(10);
|
||||
expect(result.get('source')).toEqual('rest');
|
||||
expect(result.get('query')).toEqual(JSON.stringify({}));
|
||||
expect(typeof result.get('payload')).toEqual("string");
|
||||
expect(JSON.parse(result.get('payload'))).toEqual(payload.data);
|
||||
expect(result.get('status')).toEqual('succeeded');
|
||||
expect(result.get('numSent')).toEqual(10);
|
||||
expect(result.get('sentPerType')).toEqual({
|
||||
'ios': 10 // 10 ios
|
||||
});
|
||||
expect(result.get('numFailed')).toEqual(5);
|
||||
expect(result.get('failedPerType')).toEqual({
|
||||
'android': 5 // android
|
||||
});
|
||||
// Try to get it without masterKey
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should properly report failures in _PushStatus', (done) => {
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return installations.map((installation) => {
|
||||
return Promise.resolve({
|
||||
deviceType: installation.deviceType
|
||||
})
|
||||
})
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
let where = { 'channels': {
|
||||
'$ins': ['Giants', 'Mets']
|
||||
}};
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 1,
|
||||
}}
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then(() => {
|
||||
fail('should not succeed');
|
||||
done();
|
||||
}).catch(() => {
|
||||
let query = new Parse.Query('_PushStatus');
|
||||
query.find({useMasterKey: true}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
let pushStatus = results[0];
|
||||
expect(pushStatus.get('status')).toBe('failed');
|
||||
done();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
it('should support full RESTQuery for increment', (done) => {
|
||||
var payload = {data: {
|
||||
alert: "Hello World!",
|
||||
badge: 'Increment',
|
||||
}}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
let where = {
|
||||
'deviceToken': {
|
||||
'$inQuery': {
|
||||
'where': {
|
||||
'deviceType': 'ios'
|
||||
},
|
||||
className: '_Installation'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then(() => {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support object type for alert', (done) => {
|
||||
it('should support object type for alert', (done) => {
|
||||
var payload = {data: {
|
||||
alert: {
|
||||
'loc-key': 'hello_world',
|
||||
},
|
||||
}}
|
||||
alert: {
|
||||
'loc-key': 'hello_world',
|
||||
},
|
||||
}}
|
||||
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
var pushAdapter = {
|
||||
send: function(body, installations) {
|
||||
return successfulTransmissions(body, installations);
|
||||
},
|
||||
getValidPushTypes: function() {
|
||||
return ["ios"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
var config = new Config(Parse.applicationId);
|
||||
var auth = {
|
||||
isMaster: true
|
||||
}
|
||||
|
||||
let where = {
|
||||
'deviceToken': {
|
||||
'$inQuery': {
|
||||
'where': {
|
||||
'deviceType': 'ios'
|
||||
},
|
||||
className: '_Installation'
|
||||
}
|
||||
}
|
||||
}
|
||||
let where = {
|
||||
'deviceToken': {
|
||||
'$inQuery': {
|
||||
'where': {
|
||||
'deviceType': 'ios'
|
||||
},
|
||||
className: '_Installation'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then((result) => {
|
||||
var pushController = new PushController(pushAdapter, Parse.applicationId, defaultConfiguration.push);
|
||||
pushController.sendPush(payload, where, config, auth).then(() => {
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -10,14 +10,14 @@ describe('RedisPubSub', function() {
|
||||
});
|
||||
|
||||
it('can create publisher', function() {
|
||||
var publisher = RedisPubSub.createPublisher({redisURL: 'redisAddress'});
|
||||
RedisPubSub.createPublisher({redisURL: 'redisAddress'});
|
||||
|
||||
var redis = require('redis');
|
||||
expect(redis.createClient).toHaveBeenCalledWith('redisAddress', { no_ready_check: true });
|
||||
});
|
||||
|
||||
it('can create subscriber', function() {
|
||||
var subscriber = RedisPubSub.createSubscriber({redisURL: 'redisAddress'});
|
||||
RedisPubSub.createSubscriber({redisURL: 'redisAddress'});
|
||||
|
||||
var redis = require('redis');
|
||||
expect(redis.createClient).toHaveBeenCalledWith('redisAddress', { no_ready_check: true });
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
// These tests check the "create" / "update" functionality of the REST API.
|
||||
var auth = require('../src/Auth');
|
||||
var cache = require('../src/cache');
|
||||
var Config = require('../src/Config');
|
||||
var Parse = require('parse/node').Parse;
|
||||
var rest = require('../src/rest');
|
||||
@@ -12,7 +11,7 @@ let database = config.database;
|
||||
|
||||
describe('rest create', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(() => {
|
||||
config = new Config('test');
|
||||
});
|
||||
|
||||
@@ -93,7 +92,7 @@ describe('rest create', () => {
|
||||
expect(err.message).toEqual('This user is not allowed to access ' +
|
||||
'non-existent class: ClientClassCreation');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('handles create on existent class when disabled client class creation', (done) => {
|
||||
@@ -106,7 +105,7 @@ describe('rest create', () => {
|
||||
})
|
||||
.then(() => {
|
||||
done();
|
||||
}, err => {
|
||||
}, () => {
|
||||
fail('Should not throw error')
|
||||
});
|
||||
});
|
||||
@@ -186,7 +185,6 @@ describe('rest create', () => {
|
||||
username: 'hello',
|
||||
password: 'world'
|
||||
}
|
||||
var username1;
|
||||
var objectId;
|
||||
rest.create(config, auth.nobody(config), '_User', data1)
|
||||
.then((r) => {
|
||||
@@ -197,24 +195,24 @@ describe('rest create', () => {
|
||||
return auth.getAuthForSessionToken({config, sessionToken: r.response.sessionToken })
|
||||
}).then((sessionAuth) => {
|
||||
return rest.update(config, sessionAuth, '_User', objectId, updatedData);
|
||||
}).then((r) => {
|
||||
return Parse.User.logOut().then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logOut().then(() => {
|
||||
return Parse.User.logIn('hello', 'world');
|
||||
})
|
||||
}).then((r) => {
|
||||
expect(r.id).toEqual(objectId);
|
||||
expect(r.get('username')).toEqual('hello');
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('handles no anonymous users config', (done) => {
|
||||
var NoAnnonConfig = Object.assign({}, config);
|
||||
NoAnnonConfig.authDataManager.setEnableAnonymousUsers(false);
|
||||
var data1 = {
|
||||
var NoAnnonConfig = Object.assign({}, config);
|
||||
NoAnnonConfig.authDataManager.setEnableAnonymousUsers(false);
|
||||
var data1 = {
|
||||
authData: {
|
||||
anonymous: {
|
||||
id: '00000000-0000-0000-0000-000000000001'
|
||||
@@ -262,7 +260,7 @@ describe('rest create', () => {
|
||||
var output = response.results[0];
|
||||
expect(output.user.objectId).toEqual(newUserSignedUpByFacebookObjectId);
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -359,7 +357,7 @@ describe('rest create', () => {
|
||||
foo: 'bar',
|
||||
};
|
||||
var sessionLength = 3600, // 1 Hour ahead
|
||||
now = new Date(); // For reference later
|
||||
now = new Date(); // For reference later
|
||||
config.sessionLength = sessionLength;
|
||||
|
||||
rest.create(config, auth.nobody(config), '_User', user)
|
||||
@@ -385,7 +383,7 @@ describe('rest create', () => {
|
||||
expect(actual.getMinutes()).toEqual(expected.getMinutes());
|
||||
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
@@ -415,7 +413,7 @@ describe('rest create', () => {
|
||||
expect(session.expiresAt).toBeUndefined();
|
||||
|
||||
done();
|
||||
}).catch(err => {
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
fail(err);
|
||||
done();
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
'use strict'
|
||||
// These tests check the "find" functionality of the REST API.
|
||||
var auth = require('../src/Auth');
|
||||
var cache = require('../src/cache');
|
||||
var Config = require('../src/Config');
|
||||
var rest = require('../src/rest');
|
||||
|
||||
var querystring = require('querystring');
|
||||
var request = require('request');
|
||||
var rp = require('request-promise');
|
||||
|
||||
var config;
|
||||
@@ -15,7 +13,7 @@ var nobody = auth.nobody(config);
|
||||
|
||||
describe('rest query', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(() => {
|
||||
config = new Config('test');
|
||||
database = config.database;
|
||||
});
|
||||
@@ -145,7 +143,7 @@ describe('rest query', () => {
|
||||
expect(err.message).toEqual('This user is not allowed to access ' +
|
||||
'non-existent class: ClientClassCreation');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('query existent class when disabled client class creation', (done) => {
|
||||
@@ -159,7 +157,7 @@ describe('rest query', () => {
|
||||
.then((result) => {
|
||||
expect(result.results.length).toEqual(0);
|
||||
done();
|
||||
}, err => {
|
||||
}, () => {
|
||||
fail('Should not throw error')
|
||||
});
|
||||
});
|
||||
@@ -179,8 +177,8 @@ describe('rest query', () => {
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestParameterEncode?'
|
||||
+ querystring.stringify({
|
||||
where: '{"foo":{"$ne": "baz"}}',
|
||||
limit: 1
|
||||
where: '{"foo":{"$ne": "baz"}}',
|
||||
limit: 1
|
||||
}).replace('=', '%3D'),
|
||||
}).then(fail, (response) => {
|
||||
let error = response.error;
|
||||
@@ -192,7 +190,7 @@ describe('rest query', () => {
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/classes/TestParameterEncode?'
|
||||
+ querystring.stringify({
|
||||
limit: 1
|
||||
limit: 1
|
||||
}).replace('=', '%3D'),
|
||||
}).then(fail, (response) => {
|
||||
let error = response.error;
|
||||
@@ -200,7 +198,7 @@ describe('rest query', () => {
|
||||
expect(b.code).toEqual(Parse.Error.INVALID_QUERY);
|
||||
});
|
||||
return Promise.all([p0, p1]);
|
||||
}).then(done).catch((err) => {
|
||||
}).then(done).catch((err) => {
|
||||
jfail(err);
|
||||
fail('should not fail');
|
||||
done();
|
||||
@@ -239,14 +237,14 @@ describe('rest query', () => {
|
||||
it('makes sure null pointers are handed correctly #2189', done => {
|
||||
let object = new Parse.Object('AnObject');
|
||||
let anotherObject = new Parse.Object('AnotherObject');
|
||||
anotherObject.save().then(() => {
|
||||
anotherObject.save().then(() => {
|
||||
object.set('values', [null, null, anotherObject]);
|
||||
return object.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AnObject');
|
||||
query.include('values');
|
||||
return query.first();
|
||||
}).then((result) => {
|
||||
}).then((result) => {
|
||||
let values = result.get('values');
|
||||
expect(values.length).toBe(3);
|
||||
let anotherObjectFound = false;
|
||||
@@ -261,7 +259,7 @@ describe('rest query', () => {
|
||||
expect(nullCounts).toBe(2);
|
||||
expect(anotherObjectFound).toBeTruthy();
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
console.error(err);
|
||||
fail(err);
|
||||
done();
|
||||
|
||||
@@ -16,60 +16,60 @@ function createUser() {
|
||||
|
||||
describe_only_db('mongo')('revocable sessions', () => {
|
||||
|
||||
beforeEach((done) => {
|
||||
beforeEach((done) => {
|
||||
// Create 1 user with the legacy
|
||||
createUser().then(done);
|
||||
});
|
||||
|
||||
it('should upgrade legacy session token', done => {
|
||||
it('should upgrade legacy session token', done => {
|
||||
let user = Parse.Object.fromJSON({
|
||||
className: '_User',
|
||||
objectId: '1234567890',
|
||||
sessionToken: sessionToken
|
||||
});
|
||||
user._upgradeToRevocableSession().then((res) => {
|
||||
user._upgradeToRevocableSession().then((res) => {
|
||||
expect(res.getSessionToken().indexOf('r:')).toBe(0);
|
||||
const config = new Config(Parse.applicationId);
|
||||
// use direct access to the DB to make sure we're not
|
||||
// getting the session token stripped
|
||||
return config.database.loadSchema().then(schemaController => {
|
||||
return config.database.loadSchema().then(schemaController => {
|
||||
return schemaController.getOneSchema('_User', true)
|
||||
}).then((schema) => {
|
||||
return config.database.adapter.find('_User', schema, {objectId: '1234567890'}, {})
|
||||
}).then((results) => {
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
expect(results[0].sessionToken).toBeUndefined();
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to become with revocable session token', done => {
|
||||
it('should be able to become with revocable session token', done => {
|
||||
let user = Parse.Object.fromJSON({
|
||||
className: '_User',
|
||||
objectId: '1234567890',
|
||||
sessionToken: sessionToken
|
||||
});
|
||||
user._upgradeToRevocableSession().then((res) => {
|
||||
user._upgradeToRevocableSession().then((res) => {
|
||||
expect(res.getSessionToken().indexOf('r:')).toBe(0);
|
||||
return Parse.User.logOut().then(() => {
|
||||
return Parse.User.become(res.getSessionToken())
|
||||
}).then((user) => {
|
||||
return Parse.User.logOut().then(() => {
|
||||
return Parse.User.become(res.getSessionToken())
|
||||
}).then((user) => {
|
||||
expect(user.id).toEqual('1234567890');
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not upgrade bad legacy session token', done => {
|
||||
it('should not upgrade bad legacy session token', done => {
|
||||
rp.post({
|
||||
url: Parse.serverURL+'/upgradeToRevocableSession',
|
||||
headers: {
|
||||
@@ -78,19 +78,19 @@ describe_only_db('mongo')('revocable sessions', () => {
|
||||
'X-Parse-Session-Token': 'badSessionToken'
|
||||
},
|
||||
json: true
|
||||
}).then((res) => {
|
||||
}).then(() => {
|
||||
fail('should not be able to upgrade a bad token');
|
||||
}, (response) => {
|
||||
expect(response.statusCode).toBe(400);
|
||||
expect(response.error).not.toBeUndefined();
|
||||
expect(response.error.code).toBe(Parse.Error.INVALID_SESSION_TOKEN);
|
||||
expect(response.error.error).toEqual('invalid legacy session token');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not crash without session token #2720', done => {
|
||||
it('should not crash without session token #2720', done => {
|
||||
rp.post({
|
||||
url: Parse.serverURL+'/upgradeToRevocableSession',
|
||||
headers: {
|
||||
@@ -98,14 +98,14 @@ describe_only_db('mongo')('revocable sessions', () => {
|
||||
'X-Parse-Rest-API-Key': 'rest'
|
||||
},
|
||||
json: true
|
||||
}).then((res) => {
|
||||
}).then(() => {
|
||||
fail('should not be able to upgrade a bad token');
|
||||
}, (response) => {
|
||||
expect(response.statusCode).toBe(404);
|
||||
expect(response.error).not.toBeUndefined();
|
||||
expect(response.error.code).toBe(Parse.Error.OBJECT_NOT_FOUND);
|
||||
expect(response.error.error).toEqual('invalid session');
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,14 +20,14 @@ var hasAllPODobject = () => {
|
||||
};
|
||||
|
||||
describe('SchemaController', () => {
|
||||
beforeEach(() => {
|
||||
beforeEach(() => {
|
||||
config = new Config('test');
|
||||
});
|
||||
|
||||
it('can validate one object', (done) => {
|
||||
config.database.loadSchema().then((schema) => {
|
||||
return schema.validateObject('TestObject', {a: 1, b: 'yo', c: false});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (error) => {
|
||||
jfail(error);
|
||||
@@ -38,7 +38,7 @@ describe('SchemaController', () => {
|
||||
it('can validate one object with dot notation', (done) => {
|
||||
config.database.loadSchema().then((schema) => {
|
||||
return schema.validateObject('TestObjectWithSubDoc', {x: false, y: 'YY', z: 1, 'aObject.k1': 'newValue'});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (error) => {
|
||||
jfail(error);
|
||||
@@ -51,7 +51,7 @@ describe('SchemaController', () => {
|
||||
return schema.validateObject('Foo', {x: true, y: 'yyy', z: 0});
|
||||
}).then((schema) => {
|
||||
return schema.validateObject('Foo', {x: false, y: 'YY', z: 1});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -61,7 +61,7 @@ describe('SchemaController', () => {
|
||||
return schema.validateObject('Stuff', {aRelation: {__type:'Relation',className:'Stuff'}});
|
||||
}).then((schema) => {
|
||||
return schema.validateObject('Stuff', {aRelation: {__type:'Pointer',className:'Stuff'}})
|
||||
.then((schema) => {
|
||||
.then(() => {
|
||||
fail('expected invalidity');
|
||||
done();
|
||||
}, done);
|
||||
@@ -103,13 +103,13 @@ describe('SchemaController', () => {
|
||||
return schema.setPermissions('Stuff', {
|
||||
'find': {}
|
||||
});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
var query = new Parse.Query('Stuff');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
fail('Class permissions should have rejected this query.');
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -128,12 +128,12 @@ describe('SchemaController', () => {
|
||||
return schema.setPermissions('Stuff', {
|
||||
'find': find
|
||||
});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
var query = new Parse.Query('Stuff');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Class permissions should have allowed this query.');
|
||||
done();
|
||||
});
|
||||
@@ -155,7 +155,7 @@ describe('SchemaController', () => {
|
||||
'find': find,
|
||||
'get': get
|
||||
});
|
||||
}).then((schema) => {
|
||||
}).then(() => {
|
||||
obj = new Parse.Object('Stuff');
|
||||
obj.set('foo', 'bar');
|
||||
return obj.save();
|
||||
@@ -163,14 +163,14 @@ describe('SchemaController', () => {
|
||||
obj = o;
|
||||
var query = new Parse.Query('Stuff');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
fail('Class permissions should have rejected this query.');
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
var query = new Parse.Query('Stuff');
|
||||
return query.get(obj.id).then((o) => {
|
||||
return query.get(obj.id).then(() => {
|
||||
done();
|
||||
}, (e) => {
|
||||
}, () => {
|
||||
fail('Class permissions should have allowed this get query');
|
||||
done();
|
||||
});
|
||||
@@ -427,7 +427,6 @@ describe('SchemaController', () => {
|
||||
ACL: { type: 'ACL' },
|
||||
aString: { type: 'String' },
|
||||
aNumber: { type: 'Number' },
|
||||
aString: { type: 'String' },
|
||||
aBool: { type: 'Boolean' },
|
||||
aDate: { type: 'Date' },
|
||||
aObject: { type: 'Object' },
|
||||
@@ -591,7 +590,7 @@ describe('SchemaController', () => {
|
||||
jfail(error);
|
||||
});
|
||||
})
|
||||
.catch(error => fail('Couldn\'t load schema'));
|
||||
.catch(() => fail('Couldn\'t load schema'));
|
||||
});
|
||||
|
||||
it('refuses to delete fields from invalid class names', done => {
|
||||
@@ -703,10 +702,10 @@ describe('SchemaController', () => {
|
||||
})
|
||||
.then(() => config.database.collectionExists('_Join:relationField:NewClass'))
|
||||
.then(exist => {
|
||||
on_db('postgres', () => {
|
||||
on_db('postgres', () => {
|
||||
// We create the table when creating the column
|
||||
expect(exist).toEqual(true);
|
||||
}, () => {
|
||||
}, () => {
|
||||
expect(exist).toEqual(false);
|
||||
});
|
||||
|
||||
@@ -730,7 +729,7 @@ describe('SchemaController', () => {
|
||||
Parse.Object.disableSingleInstance();
|
||||
var obj1 = hasAllPODobject();
|
||||
var obj2 = hasAllPODobject();
|
||||
var p = Parse.Object.saveAll([obj1, obj2])
|
||||
Parse.Object.saveAll([obj1, obj2])
|
||||
.then(() => config.database.loadSchema())
|
||||
.then(schema => schema.deleteField('aString', 'HasAllPOD', config.database))
|
||||
.then(() => new Parse.Query('HasAllPOD').get(obj1.id))
|
||||
@@ -824,58 +823,58 @@ describe('SchemaController', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
it('yields a proper schema mismatch error (#2661)', done => {
|
||||
it('yields a proper schema mismatch error (#2661)', done => {
|
||||
let anObject = new Parse.Object('AnObject');
|
||||
let anotherObject = new Parse.Object('AnotherObject');
|
||||
let someObject = new Parse.Object('SomeObject');
|
||||
Parse.Object.saveAll([anObject, anotherObject, someObject]).then(() => {
|
||||
Parse.Object.saveAll([anObject, anotherObject, someObject]).then(() => {
|
||||
anObject.set('pointer', anotherObject);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
anObject.set('pointer', someObject);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('shoud not save correctly');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err instanceof Parse.Error).toBeTruthy();
|
||||
expect(err.message).toEqual('schema mismatch for AnObject.pointer; expected Pointer<AnotherObject> but got Pointer<SomeObject>')
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('yields a proper schema mismatch error bis (#2661)', done => {
|
||||
it('yields a proper schema mismatch error bis (#2661)', done => {
|
||||
let anObject = new Parse.Object('AnObject');
|
||||
let someObject = new Parse.Object('SomeObject');
|
||||
Parse.Object.saveAll([anObject, someObject]).then(() => {
|
||||
Parse.Object.saveAll([anObject, someObject]).then(() => {
|
||||
anObject.set('number', 1);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
anObject.set('number', someObject);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('shoud not save correctly');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err instanceof Parse.Error).toBeTruthy();
|
||||
expect(err.message).toEqual('schema mismatch for AnObject.number; expected Number but got Pointer<SomeObject>')
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('yields a proper schema mismatch error ter (#2661)', done => {
|
||||
it('yields a proper schema mismatch error ter (#2661)', done => {
|
||||
let anObject = new Parse.Object('AnObject');
|
||||
let someObject = new Parse.Object('SomeObject');
|
||||
Parse.Object.saveAll([anObject, someObject]).then(() => {
|
||||
Parse.Object.saveAll([anObject, someObject]).then(() => {
|
||||
anObject.set('pointer', someObject);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
anObject.set('pointer', 1);
|
||||
return anObject.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
fail('shoud not save correctly');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err instanceof Parse.Error).toBeTruthy();
|
||||
expect(err.message).toEqual('schema mismatch for AnObject.pointer; expected Pointer<SomeObject> but got Number')
|
||||
done();
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('SessionTokenCache', function() {
|
||||
it('can get undefined userId', function(done) {
|
||||
var sessionTokenCache = new SessionTokenCache();
|
||||
|
||||
sessionTokenCache.getUserId(undefined).then((userIdFromCache) => {
|
||||
sessionTokenCache.getUserId(undefined).then(() => {
|
||||
}, (error) => {
|
||||
expect(error).not.toBeNull();
|
||||
done();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
let twitter = require('../src/authDataManager/twitter');
|
||||
|
||||
describe('Twitter Auth', () => {
|
||||
it('should use the proper configuration', () => {
|
||||
describe('Twitter Auth', () => {
|
||||
it('should use the proper configuration', () => {
|
||||
// Multiple options, consumer_key found
|
||||
expect(twitter.handleMultipleConfigurations({
|
||||
consumer_key: 'hello',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var request = require('request');
|
||||
const Parse = require("parse/node");
|
||||
let Config = require('../src/Config');
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
done();
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -89,7 +89,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
done();
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -132,7 +132,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -179,7 +179,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -220,8 +220,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.fetch()
|
||||
.then((user) => {
|
||||
return user.save();
|
||||
}).then((user) => {
|
||||
return Parse.User.requestPasswordReset("testSendSimpleAdapter@parse.com").catch((err) => {
|
||||
}).then(() => {
|
||||
return Parse.User.requestPasswordReset("testSendSimpleAdapter@parse.com").catch(() => {
|
||||
fail('Should not fail requesting a password');
|
||||
done();
|
||||
})
|
||||
@@ -230,7 +230,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
done();
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -256,8 +256,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.logIn("zxcv", "asdf"))
|
||||
.then(result => {
|
||||
.then(() => Parse.User.logIn("zxcv", "asdf"))
|
||||
.then(() => {
|
||||
fail('login should have failed');
|
||||
done();
|
||||
}, error => {
|
||||
@@ -296,8 +296,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
}).then(() => {
|
||||
expect(sendEmailOptions).not.toBeUndefined();
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/verify_email_success.html?username=user');
|
||||
user.fetch()
|
||||
@@ -309,7 +309,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
expect(typeof user).toBe('object');
|
||||
expect(user.get('emailVerified')).toBe(true);
|
||||
done();
|
||||
}, error => {
|
||||
}, () => {
|
||||
fail('login should have succeeded');
|
||||
done();
|
||||
});
|
||||
@@ -343,12 +343,12 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.logIn("zxcv", "asdf"))
|
||||
.then(() => Parse.User.logIn("zxcv", "asdf"))
|
||||
.then(user => {
|
||||
expect(typeof user).toBe('object');
|
||||
expect(user.get('emailVerified')).toBe(false);
|
||||
done();
|
||||
}, error => {
|
||||
}, () => {
|
||||
fail('login should have succeeded');
|
||||
done();
|
||||
});
|
||||
@@ -375,7 +375,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(() => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
fail('sending password reset email should not have succeeded');
|
||||
@@ -406,7 +406,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(() => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
fail('sending password reset email should not have succeeded');
|
||||
@@ -434,7 +434,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(() => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
fail('sending password reset email should not have succeeded');
|
||||
@@ -466,8 +466,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setUsername("zxcv");
|
||||
user.set("email", "testInvalidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(result => {
|
||||
.then(() => Parse.User.requestPasswordReset("testInvalidConfig@parse.com"))
|
||||
.then(() => {
|
||||
done();
|
||||
}, error => {
|
||||
done(error);
|
||||
@@ -504,8 +504,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.setPassword("asdf");
|
||||
user.setUsername("testValidConfig@parse.com");
|
||||
user.signUp(null)
|
||||
.then(user => Parse.User.requestPasswordReset("testValidConfig@parse.com"))
|
||||
.then(result => {
|
||||
.then(() => Parse.User.requestPasswordReset("testValidConfig@parse.com"))
|
||||
.then(() => {
|
||||
expect(adapter.sendMail).toHaveBeenCalled();
|
||||
done();
|
||||
}, error => {
|
||||
@@ -544,7 +544,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
done();
|
||||
});
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -579,7 +579,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
expect(emailSent).toBe(true);
|
||||
done();
|
||||
},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -611,8 +611,8 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
}).then(() => {
|
||||
expect(sendEmailOptions).not.toBeUndefined();
|
||||
request.get(sendEmailOptions.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
followRedirect: false,
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/verify_email_success.html?username=user');
|
||||
user.fetch()
|
||||
@@ -645,7 +645,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
.then(() => {
|
||||
request.get('http://localhost:8378/1/apps/test/verify_email', {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done()
|
||||
@@ -667,7 +667,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
.then(() => {
|
||||
request.get('http://localhost:8378/1/apps/test/verify_email?token=asdfasdf&username=sadfasga', {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done();
|
||||
@@ -678,10 +678,10 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
it('does not update email verified if you use an invalid token', done => {
|
||||
var user = new Parse.User();
|
||||
var emailAdapter = {
|
||||
sendVerificationEmail: options => {
|
||||
sendVerificationEmail: () => {
|
||||
request.get('http://localhost:8378/1/apps/test/verify_email?token=invalid&username=zxcv', {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
user.fetch()
|
||||
@@ -706,7 +706,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
user.set('email', 'user@parse.com');
|
||||
user.signUp(null, {
|
||||
success: () => {},
|
||||
error: function(userAgain, error) {
|
||||
error: function() {
|
||||
fail('Failed to save user');
|
||||
done();
|
||||
}
|
||||
@@ -721,9 +721,9 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
sendPasswordResetEmail: options => {
|
||||
request.get(options.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
if (error) {
|
||||
jfail(err);
|
||||
jfail(error);
|
||||
fail("Failed to get the reset link");
|
||||
return;
|
||||
}
|
||||
@@ -771,7 +771,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
.then(() => {
|
||||
request.get('http://localhost:8378/1/apps/test/request_password_reset?token=asdfasdf&username=sadfasga', {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/invalid_link.html');
|
||||
done();
|
||||
@@ -786,7 +786,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
sendPasswordResetEmail: options => {
|
||||
request.get(options.link, {
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
if (error) {
|
||||
jfail(error);
|
||||
fail("Failed to get the reset link");
|
||||
@@ -806,10 +806,10 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
url: "http://localhost:8378/1/apps/test/request_password_reset" ,
|
||||
body: `new_password=hello&token=${token}&username=zxcv`,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
followRedirect: false,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
if (error) {
|
||||
jfail(error);
|
||||
fail("Failed to POST request password reset");
|
||||
@@ -818,7 +818,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/password_reset_success.html?username=zxcv');
|
||||
|
||||
Parse.User.logIn("zxcv", "hello").then(function(user){
|
||||
Parse.User.logIn("zxcv", "hello").then(function(){
|
||||
let config = new Config('test');
|
||||
config.database.adapter.find('_User', { fields: {} }, { 'username': 'zxcv' }, { limit: 1 })
|
||||
.then(results => {
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
var WinstonLoggerAdapter = require('../src/Adapters/Logger/WinstonLoggerAdapter').WinstonLoggerAdapter;
|
||||
var Parse = require('parse/node').Parse;
|
||||
var request = require('request');
|
||||
|
||||
describe('info logs', () => {
|
||||
|
||||
it("Verify INFO logs", (done) => {
|
||||
var winstonLoggerAdapter = new WinstonLoggerAdapter();
|
||||
winstonLoggerAdapter.log('info', 'testing info logs', () => {
|
||||
var winstonLoggerAdapter = new WinstonLoggerAdapter();
|
||||
winstonLoggerAdapter.log('info', 'testing info logs', () => {
|
||||
winstonLoggerAdapter.query({
|
||||
from: new Date(Date.now() - 500),
|
||||
size: 100,
|
||||
level: 'info'
|
||||
}, (results) => {
|
||||
if (results.length == 0) {
|
||||
fail('The adapter should return non-empty results');
|
||||
} else {
|
||||
expect(results[0].message).toEqual('testing info logs');
|
||||
}
|
||||
// Check the error log
|
||||
// Regression #2639
|
||||
winstonLoggerAdapter.query({
|
||||
from: new Date(Date.now() - 500),
|
||||
size: 100,
|
||||
level: 'info'
|
||||
level: 'error'
|
||||
}, (results) => {
|
||||
if (results.length == 0) {
|
||||
fail('The adapter should return non-empty results');
|
||||
} else {
|
||||
expect(results[0].message).toEqual('testing info logs');
|
||||
}
|
||||
// Check the error log
|
||||
// Regression #2639
|
||||
winstonLoggerAdapter.query({
|
||||
from: new Date(Date.now() - 500),
|
||||
size: 100,
|
||||
level: 'error'
|
||||
}, (results) => {
|
||||
expect(results.length).toEqual(0);
|
||||
done();
|
||||
});
|
||||
expect(results.length).toEqual(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('error logs', () => {
|
||||
@@ -79,7 +78,7 @@ describe('verbose logs', () => {
|
||||
request.get({
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/login?username=test&password=moon-y'
|
||||
}, (error, response, body) => {
|
||||
}, () => {
|
||||
let winstonLoggerAdapter = new WinstonLoggerAdapter();
|
||||
return winstonLoggerAdapter.query({
|
||||
from: new Date(Date.now() - 500),
|
||||
@@ -92,7 +91,7 @@ describe('verbose logs', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
fail(JSON.stringify(err));
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -25,7 +25,6 @@ if (global._babelPolyfill) {
|
||||
|
||||
var cache = require('../src/cache').default;
|
||||
var express = require('express');
|
||||
var facebook = require('../src/authDataManager/facebook');
|
||||
var ParseServer = require('../src/index').ParseServer;
|
||||
var path = require('path');
|
||||
var TestUtils = require('../src/TestUtils');
|
||||
@@ -40,8 +39,8 @@ const postgresURI = 'postgres://localhost:5432/parse_server_postgres_adapter_tes
|
||||
let databaseAdapter;
|
||||
// need to bind for mocking mocha
|
||||
|
||||
let startDB = () => {};
|
||||
let stopDB = () => {};
|
||||
let startDB = () => {};
|
||||
let stopDB = () => {};
|
||||
|
||||
if (process.env.PARSE_SERVER_TEST_DB === 'postgres') {
|
||||
databaseAdapter = new PostgresStorageAdapter({
|
||||
@@ -53,7 +52,7 @@ if (process.env.PARSE_SERVER_TEST_DB === 'postgres') {
|
||||
timeout: () => {},
|
||||
slow: () => {}
|
||||
});
|
||||
stopDB = require('mongodb-runner/mocha/after');;
|
||||
stopDB = require('mongodb-runner/mocha/after');
|
||||
databaseAdapter = new MongoStorageAdapter({
|
||||
uri: mongoURI,
|
||||
collectionPrefix: 'test_',
|
||||
@@ -64,9 +63,9 @@ var port = 8378;
|
||||
|
||||
let filesAdapter;
|
||||
|
||||
on_db('mongo', () => {
|
||||
on_db('mongo', () => {
|
||||
filesAdapter = new GridStoreAdapter(mongoURI);
|
||||
}, () => {
|
||||
}, () => {
|
||||
filesAdapter = new FSAdapter();
|
||||
});
|
||||
|
||||
@@ -121,7 +120,7 @@ let openConnections = {};
|
||||
var app = express();
|
||||
var api = new ParseServer(defaultConfiguration);
|
||||
app.use('/1', api);
|
||||
app.use('/1', (req, res) => {
|
||||
app.use('/1', () => {
|
||||
fail('should not call next');
|
||||
});
|
||||
var server = app.listen(port);
|
||||
@@ -143,7 +142,7 @@ const reconfigureServer = changedConfiguration => {
|
||||
api = new ParseServer(newConfiguration);
|
||||
api.use(require('./testing-routes').router);
|
||||
app.use('/1', api);
|
||||
app.use('/1', (req, res) => {
|
||||
app.use('/1', () => {
|
||||
fail('should not call next');
|
||||
});
|
||||
server = app.listen(port);
|
||||
@@ -195,7 +194,7 @@ beforeEach(done => {
|
||||
Parse.initialize('test', 'test', 'test');
|
||||
Parse.serverURL = 'http://localhost:' + port + '/1';
|
||||
done();
|
||||
}, error => {
|
||||
}, () => {
|
||||
Parse.initialize('test', 'test', 'test');
|
||||
Parse.serverURL = 'http://localhost:' + port + '/1';
|
||||
// fail(JSON.stringify(error));
|
||||
@@ -284,7 +283,7 @@ function notEqual(a, b, message) {
|
||||
function expectSuccess(params, done) {
|
||||
return {
|
||||
success: params.success,
|
||||
error: function(e) {
|
||||
error: function() {
|
||||
fail('failure happened in expectSuccess');
|
||||
done ? done() : null;
|
||||
},
|
||||
@@ -417,7 +416,7 @@ global.describe_only_db = db => {
|
||||
} else if (!process.env.PARSE_SERVER_TEST_DB && db == 'mongo') {
|
||||
return describe;
|
||||
} else {
|
||||
return () => {};
|
||||
return () => {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ var express = require('express');
|
||||
const MongoStorageAdapter = require('../src/Adapters/Storage/Mongo/MongoStorageAdapter');
|
||||
|
||||
describe('server', () => {
|
||||
it('requires a master key and app id', done => {
|
||||
it('requires a master key and app id', done => {
|
||||
reconfigureServer({ appId: undefined })
|
||||
.catch(error => {
|
||||
expect(error).toEqual('You must provide an appId!');
|
||||
@@ -32,7 +32,7 @@ describe('server', () => {
|
||||
headers: {
|
||||
'Authorization': 'Basic ' + new Buffer('test:' + 'test').toString('base64')
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
done();
|
||||
});
|
||||
@@ -46,7 +46,7 @@ describe('server', () => {
|
||||
headers: {
|
||||
'Authorization': 'Basic ' + new Buffer('test:javascript-key=' + 'test').toString('base64')
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
done();
|
||||
});
|
||||
@@ -167,20 +167,20 @@ describe('server', () => {
|
||||
it('can respond 200 on path health', done => {
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/health',
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can create a parse-server v1', done => {
|
||||
it('can create a parse-server v1', done => {
|
||||
var parseServer = new ParseServer.default(Object.assign({},
|
||||
defaultConfiguration, {
|
||||
appId: "aTestApp",
|
||||
masterKey: "aTestMasterKey",
|
||||
serverURL: "http://localhost:12666/parse",
|
||||
__indexBuildCompletionCallbackForTests: promise => {
|
||||
promise
|
||||
appId: "aTestApp",
|
||||
masterKey: "aTestMasterKey",
|
||||
serverURL: "http://localhost:12666/parse",
|
||||
__indexBuildCompletionCallbackForTests: promise => {
|
||||
promise
|
||||
.then(() => {
|
||||
expect(Parse.applicationId).toEqual("aTestApp");
|
||||
var app = express();
|
||||
@@ -189,31 +189,31 @@ describe('server', () => {
|
||||
var server = app.listen(12666);
|
||||
var obj = new Parse.Object("AnObject");
|
||||
var objId;
|
||||
obj.save().then((obj) => {
|
||||
obj.save().then((obj) => {
|
||||
objId = obj.id;
|
||||
var q = new Parse.Query("AnObject");
|
||||
return q.first();
|
||||
}).then((obj) => {
|
||||
}).then((obj) => {
|
||||
expect(obj.id).toEqual(objId);
|
||||
server.close(done);
|
||||
}).fail((err) => {
|
||||
}).fail(() => {
|
||||
server.close(done);
|
||||
})
|
||||
});
|
||||
}})
|
||||
}})
|
||||
);
|
||||
});
|
||||
|
||||
it('can create a parse-server v2', done => {
|
||||
it('can create a parse-server v2', done => {
|
||||
let objId;
|
||||
let server
|
||||
let parseServer = ParseServer.ParseServer(Object.assign({},
|
||||
defaultConfiguration, {
|
||||
appId: "anOtherTestApp",
|
||||
masterKey: "anOtherTestMasterKey",
|
||||
serverURL: "http://localhost:12667/parse",
|
||||
__indexBuildCompletionCallbackForTests: promise => {
|
||||
promise
|
||||
appId: "anOtherTestApp",
|
||||
masterKey: "anOtherTestMasterKey",
|
||||
serverURL: "http://localhost:12667/parse",
|
||||
__indexBuildCompletionCallbackForTests: promise => {
|
||||
promise
|
||||
.then(() => {
|
||||
expect(Parse.applicationId).toEqual("anOtherTestApp");
|
||||
let app = express();
|
||||
@@ -223,12 +223,12 @@ describe('server', () => {
|
||||
let obj = new Parse.Object("AnObject");
|
||||
return obj.save()
|
||||
})
|
||||
.then(obj => {
|
||||
.then(obj => {
|
||||
objId = obj.id;
|
||||
let q = new Parse.Query("AnObject");
|
||||
return q.first();
|
||||
})
|
||||
.then(obj => {
|
||||
.then(obj => {
|
||||
expect(obj.id).toEqual(objId);
|
||||
server.close(done);
|
||||
})
|
||||
@@ -240,11 +240,11 @@ describe('server', () => {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}}
|
||||
}}
|
||||
));
|
||||
});
|
||||
|
||||
it('has createLiveQueryServer', done => {
|
||||
it('has createLiveQueryServer', done => {
|
||||
// original implementation through the factory
|
||||
expect(typeof ParseServer.ParseServer.createLiveQueryServer).toEqual('function');
|
||||
// For import calls
|
||||
@@ -261,7 +261,7 @@ describe('server', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
it('properly gives publicServerURL when set', done => {
|
||||
it('properly gives publicServerURL when set', done => {
|
||||
reconfigureServer({ publicServerURL: 'https://myserver.com/1' })
|
||||
.then(() => {
|
||||
var config = new Config('test', 'http://localhost:8378/1');
|
||||
@@ -270,7 +270,7 @@ describe('server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('properly removes trailing slash in mount', done => {
|
||||
it('properly removes trailing slash in mount', done => {
|
||||
reconfigureServer({})
|
||||
.then(() => {
|
||||
var config = new Config('test', 'http://localhost:8378/1/');
|
||||
@@ -279,7 +279,7 @@ describe('server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when getting invalid mount', done => {
|
||||
it('should throw when getting invalid mount', done => {
|
||||
reconfigureServer({ publicServerURL: 'blabla:/some' })
|
||||
.catch(error => {
|
||||
expect(error).toEqual('publicServerURL should be a valid HTTPS URL starting with https://')
|
||||
|
||||
@@ -5,30 +5,30 @@ import {
|
||||
} from '../src/cli/utils/parsers';
|
||||
|
||||
describe('parsers', () => {
|
||||
it('parses correctly with numberParser', () => {
|
||||
const parser = numberParser('key');
|
||||
expect(parser(2)).toEqual(2);
|
||||
expect(parser('2')).toEqual(2);
|
||||
expect(() => {parser('string')}).toThrow();
|
||||
});
|
||||
it('parses correctly with numberParser', () => {
|
||||
const parser = numberParser('key');
|
||||
expect(parser(2)).toEqual(2);
|
||||
expect(parser('2')).toEqual(2);
|
||||
expect(() => {parser('string')}).toThrow();
|
||||
});
|
||||
|
||||
it('parses correctly with numberOrBoolParser', () => {
|
||||
const parser = numberOrBoolParser('key');
|
||||
expect(parser(true)).toEqual(true);
|
||||
expect(parser(false)).toEqual(false);
|
||||
expect(parser('true')).toEqual(true);
|
||||
expect(parser('false')).toEqual(false);
|
||||
expect(parser(1)).toEqual(1);
|
||||
expect(parser('1')).toEqual(1);
|
||||
});
|
||||
it('parses correctly with numberOrBoolParser', () => {
|
||||
const parser = numberOrBoolParser('key');
|
||||
expect(parser(true)).toEqual(true);
|
||||
expect(parser(false)).toEqual(false);
|
||||
expect(parser('true')).toEqual(true);
|
||||
expect(parser('false')).toEqual(false);
|
||||
expect(parser(1)).toEqual(1);
|
||||
expect(parser('1')).toEqual(1);
|
||||
});
|
||||
|
||||
it('parses correctly with booleanParser', () => {
|
||||
const parser = booleanParser;
|
||||
expect(parser(true)).toEqual(true);
|
||||
expect(parser(false)).toEqual(false);
|
||||
expect(parser('true')).toEqual(true);
|
||||
expect(parser('false')).toEqual(false);
|
||||
expect(parser(1)).toEqual(true);
|
||||
expect(parser(2)).toEqual(false);
|
||||
});
|
||||
it('parses correctly with booleanParser', () => {
|
||||
const parser = booleanParser;
|
||||
expect(parser(true)).toEqual(true);
|
||||
expect(parser(false)).toEqual(false);
|
||||
expect(parser('true')).toEqual(true);
|
||||
expect(parser('false')).toEqual(false);
|
||||
expect(parser(1)).toEqual(true);
|
||||
expect(parser(2)).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -118,8 +118,8 @@ var masterKeyHeaders = {
|
||||
|
||||
describe('schemas', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
config.database.schemaCache.clear();
|
||||
beforeEach(() => {
|
||||
config.database.schemaCache.clear();
|
||||
});
|
||||
|
||||
it('requires the master key to get all schemas', (done) => {
|
||||
@@ -298,7 +298,7 @@ describe('schemas', () => {
|
||||
body: {
|
||||
className: 'A',
|
||||
},
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toEqual(null);
|
||||
request.post({
|
||||
url: 'http://localhost:8378/1/schemas',
|
||||
@@ -350,7 +350,7 @@ describe('schemas', () => {
|
||||
it('responds with all fields when getting incomplete schema', done => {
|
||||
config.database.loadSchema()
|
||||
.then(schemaController => schemaController.addClassIfNotExists('_Installation', {}, defaultClassLevelPermissions))
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/schemas/_Installation',
|
||||
headers: masterKeyHeaders,
|
||||
@@ -417,7 +417,7 @@ describe('schemas', () => {
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {},
|
||||
}, (error, response, body) => {
|
||||
}, () => {
|
||||
request.put({
|
||||
url: 'http://localhost:8378/1/schemas/NewClass',
|
||||
headers: noAuthHeaders,
|
||||
@@ -452,7 +452,7 @@ describe('schemas', () => {
|
||||
json: true,
|
||||
body: {
|
||||
fields: {
|
||||
newField: {type: 'String'}
|
||||
newField: {type: 'String'}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
@@ -607,7 +607,7 @@ describe('schemas', () => {
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {},
|
||||
}, (error, response, body) => {
|
||||
}, () => {
|
||||
request.put({
|
||||
url: 'http://localhost:8378/1/schemas/NewClass',
|
||||
headers: masterKeyHeaders,
|
||||
@@ -656,7 +656,7 @@ describe('schemas', () => {
|
||||
url: 'http://localhost:8378/1/schemas/_User',
|
||||
headers: masterKeyHeaders,
|
||||
json: true
|
||||
}, (error, response, body) => {
|
||||
}, () => {
|
||||
request.put({
|
||||
url: 'http://localhost:8378/1/schemas/_User',
|
||||
headers: masterKeyHeaders,
|
||||
@@ -781,7 +781,7 @@ describe('schemas', () => {
|
||||
url: 'http://localhost:8378/1/schemas/HasAllPOD',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.body).toEqual(plainOldDataSchema);
|
||||
done();
|
||||
});
|
||||
@@ -860,7 +860,7 @@ describe('schemas', () => {
|
||||
url: 'http://localhost:8378/1/schemas/MyOtherClass',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body).toEqual({});
|
||||
config.database.collectionExists('_Join:aRelation:MyOtherClass').then(exists => {
|
||||
@@ -903,14 +903,14 @@ describe('schemas', () => {
|
||||
body: {
|
||||
className: 'NewClassForDelete'
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(error).toEqual(null);
|
||||
expect(response.body.className).toEqual('NewClassForDelete');
|
||||
request.del({
|
||||
url: 'http://localhost:8378/1/schemas/NewClassForDelete',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body).toEqual({});
|
||||
config.database.loadSchema().then(schema => {
|
||||
@@ -931,27 +931,27 @@ describe('schemas', () => {
|
||||
body: {
|
||||
className: 'NewClassForDelete'
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(error).toEqual(null);
|
||||
expect(response.body.className).toEqual('NewClassForDelete');
|
||||
request.post({
|
||||
url: 'http://localhost:8378/1/classes/NewClassForDelete',
|
||||
headers: restKeyHeaders,
|
||||
json: true
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(error).toEqual(null);
|
||||
expect(typeof response.body.objectId).toEqual('string');
|
||||
request.del({
|
||||
url: 'http://localhost:8378/1/classes/NewClassForDelete/' + response.body.objectId,
|
||||
headers: restKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toEqual(null);
|
||||
request.del({
|
||||
url: 'http://localhost:8378/1/schemas/NewClassForDelete',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body).toEqual({});
|
||||
config.database.loadSchema().then(schema => {
|
||||
@@ -981,13 +981,13 @@ describe('schemas', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toEqual(null);
|
||||
request.get({
|
||||
url: 'http://localhost:8378/1/schemas/AClass',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body.classLevelPermissions).toEqual({
|
||||
find: {
|
||||
@@ -1054,11 +1054,11 @@ describe('schemas', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toEqual(null);
|
||||
let object = new Parse.Object('AClass');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
fail('should not be able to add a field');
|
||||
done();
|
||||
}, (err) => {
|
||||
@@ -1083,13 +1083,13 @@ describe('schemas', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
}, (error) => {
|
||||
expect(error).toEqual(null);
|
||||
let object = new Parse.Object('AClass');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
return object.save().then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should be able to add a field');
|
||||
done();
|
||||
})
|
||||
@@ -1109,7 +1109,7 @@ describe('schemas', () => {
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
expect(body.error).toEqual("'1234567890A' is not a valid key for class level permissions");
|
||||
expect(body.error).toEqual("'1234567890A' is not a valid key for class level permissions");
|
||||
done();
|
||||
})
|
||||
});
|
||||
@@ -1217,7 +1217,7 @@ describe('schemas', () => {
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
expect(body.error).toEqual("'' is not a valid value for class level permissions find:*:");
|
||||
expect(body.error).toEqual("'' is not a valid value for class level permissions find:*:");
|
||||
done();
|
||||
})
|
||||
});
|
||||
@@ -1229,22 +1229,22 @@ describe('schemas', () => {
|
||||
op = request.put;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
op({
|
||||
url: 'http://localhost:8378/1/schemas/'+className,
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {
|
||||
classLevelPermissions: permissions
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
if (body.error) {
|
||||
return reject(body);
|
||||
}
|
||||
return resolve(body);
|
||||
})
|
||||
op({
|
||||
url: 'http://localhost:8378/1/schemas/'+className,
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {
|
||||
classLevelPermissions: permissions
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
if (body.error) {
|
||||
return reject(body);
|
||||
}
|
||||
return resolve(body);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1263,33 +1263,33 @@ describe('schemas', () => {
|
||||
'find': {
|
||||
'role:admin': true
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Object.saveAll([user, admin, role], {useMasterKey: true});
|
||||
}).then(()=> {
|
||||
role.relation('users').add(admin);
|
||||
return role.save(null, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
let obj = new Parse.Object('AClass');
|
||||
return obj.save(null, {useMasterKey: true});
|
||||
})
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((err) => {
|
||||
return query.find().then(() => {
|
||||
fail('Use should hot be able to find!')
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
})
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('admin', 'admin');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
done();
|
||||
}).catch( (err) => {
|
||||
}).catch( (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -1310,21 +1310,21 @@ describe('schemas', () => {
|
||||
'find': {
|
||||
'role:admin': true
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Object.saveAll([user, admin, role], {useMasterKey: true});
|
||||
}).then(()=> {
|
||||
role.relation('users').add(admin);
|
||||
return role.save(null, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
let obj = new Parse.Object('AClass');
|
||||
return obj.save(null, {useMasterKey: true});
|
||||
})
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((err) => {
|
||||
return query.find().then(() => {
|
||||
fail('User should not be able to find!')
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
})
|
||||
@@ -1340,19 +1340,19 @@ describe('schemas', () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((result) => {
|
||||
expect(result.length).toBe(1);
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('User should be able to find!')
|
||||
done();
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('admin', 'admin');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
done();
|
||||
}).catch( (err) => {
|
||||
}).catch( (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -1373,21 +1373,21 @@ describe('schemas', () => {
|
||||
'find': {
|
||||
'role:admin': true
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Object.saveAll([user, admin, role], {useMasterKey: true});
|
||||
}).then(()=> {
|
||||
role.relation('users').add(admin);
|
||||
return role.save(null, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
let obj = new Parse.Object('AClass');
|
||||
return obj.save(null, {useMasterKey: true});
|
||||
})
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((err) => {
|
||||
return query.find().then(() => {
|
||||
fail('User should not be able to find!')
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
})
|
||||
@@ -1398,13 +1398,13 @@ describe('schemas', () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((result) => {
|
||||
expect(result.length).toBe(1);
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('User should be able to find!')
|
||||
done();
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('admin', 'admin');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
@@ -1431,21 +1431,21 @@ describe('schemas', () => {
|
||||
'find': {
|
||||
'role:admin': true
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.Object.saveAll([user, admin, role], {useMasterKey: true});
|
||||
}).then(()=> {
|
||||
role.relation('users').add(admin);
|
||||
return role.save(null, {useMasterKey: true});
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
let obj = new Parse.Object('AClass');
|
||||
return obj.save(null, {useMasterKey: true});
|
||||
})
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((err) => {
|
||||
return query.find().then(() => {
|
||||
fail('User should not be able to find!')
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
})
|
||||
@@ -1455,28 +1455,28 @@ describe('schemas', () => {
|
||||
'found': {
|
||||
'role:admin': true
|
||||
}
|
||||
}, true).then(() => {
|
||||
}, true).then(() => {
|
||||
fail("Should not be able to save a borked CLP");
|
||||
}, () => {
|
||||
}, () => {
|
||||
return Promise.resolve();
|
||||
})
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((result) => {
|
||||
return query.find().then(() => {
|
||||
fail('User should not be able to find!')
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
});
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('admin', 'admin');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(1);
|
||||
done();
|
||||
}).catch( (err) => {
|
||||
}).catch( (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
@@ -1496,11 +1496,11 @@ describe('schemas', () => {
|
||||
|
||||
let role = new Parse.Role('admin', new Parse.ACL());
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
Promise.resolve().then(() => {
|
||||
return Parse.Object.saveAll([user, user2, admin, role], {useMasterKey: true});
|
||||
}).then(()=> {
|
||||
role.relation('users').add(admin);
|
||||
return role.save(null, {useMasterKey: true}).then(() => {
|
||||
return role.save(null, {useMasterKey: true}).then(() => {
|
||||
let perm = {
|
||||
find: {}
|
||||
};
|
||||
@@ -1508,8 +1508,8 @@ describe('schemas', () => {
|
||||
perm['find'][user.id] = true;
|
||||
return setPermissionsOnClass('AClass', perm);
|
||||
})
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user').then(() => {
|
||||
let obj = new Parse.Object('AClass');
|
||||
return obj.save();
|
||||
})
|
||||
@@ -1517,38 +1517,38 @@ describe('schemas', () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find().then((res) => {
|
||||
expect(res.length).toEqual(1);
|
||||
}, (err) => {
|
||||
fail('User should be able to find!')
|
||||
}, () => {
|
||||
fail('User should be able to find!')
|
||||
return Promise.resolve();
|
||||
})
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('admin', 'admin');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
fail("should not be able to read!");
|
||||
return Promise.resolve();
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action create on class AClass.');
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user2', 'user2');
|
||||
}).then( () => {
|
||||
}).then( () => {
|
||||
let query = new Parse.Query('AClass');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
}).then(() => {
|
||||
fail("should not be able to read!");
|
||||
return Promise.resolve();
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for action find on class AClass.');
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can query with include and CLP (issue #2005)', (done) => {
|
||||
it('can query with include and CLP (issue #2005)', (done) => {
|
||||
setPermissionsOnClass('AnotherObject', {
|
||||
get: {"*": true},
|
||||
find: {},
|
||||
@@ -1556,43 +1556,43 @@ describe('schemas', () => {
|
||||
update: {'*': true},
|
||||
delete: {'*': true},
|
||||
addField:{'*': true}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let obj = new Parse.Object('AnObject');
|
||||
let anotherObject = new Parse.Object('AnotherObject');
|
||||
return obj.save({
|
||||
anotherObject
|
||||
})
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AnObject');
|
||||
query.include('anotherObject');
|
||||
return query.find();
|
||||
}).then((res) => {
|
||||
}).then((res) => {
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].get('anotherObject')).not.toBeUndefined();
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it('can add field as master (issue #1257)', (done) => {
|
||||
it('can add field as master (issue #1257)', (done) => {
|
||||
setPermissionsOnClass('AClass', {
|
||||
'addField': {}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
var obj = new Parse.Object('AClass');
|
||||
obj.set('key', 'value');
|
||||
return obj.save(null, {useMasterKey: true})
|
||||
}).then((obj) => {
|
||||
}).then((obj) => {
|
||||
expect(obj.get('key')).toEqual('value');
|
||||
done();
|
||||
}, (err) => {
|
||||
}, () => {
|
||||
fail('should not fail');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can login when addFields is false (issue #1355)', (done) => {
|
||||
it('can login when addFields is false (issue #1355)', (done) => {
|
||||
setPermissionsOnClass('_User', {
|
||||
'create': {'*': true},
|
||||
'addField': {}
|
||||
@@ -1616,7 +1616,7 @@ describe('schemas', () => {
|
||||
url: 'http://localhost:8378/1/schemas/MyClass',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
}, (error, response, body) => {
|
||||
}, (error, response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body).toEqual({});
|
||||
done();
|
||||
@@ -1641,56 +1641,56 @@ describe('schemas', () => {
|
||||
'update': {'role:admin': true},
|
||||
'delete': {'role:admin': true}
|
||||
})
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return obj.save();
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'user')
|
||||
}).then(() => {
|
||||
return obj.destroy();
|
||||
}).then((result) => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('AnObject');
|
||||
return query.find();
|
||||
}).then((results) => {
|
||||
expect(results.length).toBe(0);
|
||||
done();
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
fail('should not fail');
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('regression test for #2246', done => {
|
||||
it('regression test for #2246', done => {
|
||||
let profile = new Parse.Object('UserProfile');
|
||||
let user = new Parse.User();
|
||||
function initialize() {
|
||||
return user.save({
|
||||
username: 'user',
|
||||
password: 'password'
|
||||
}).then(() => {
|
||||
return profile.save({user}).then(() => {
|
||||
return user.save({
|
||||
}).then(() => {
|
||||
return profile.save({user}).then(() => {
|
||||
return user.save({
|
||||
userProfile: profile
|
||||
}, {useMasterKey: true});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initialize().then(() => {
|
||||
initialize().then(() => {
|
||||
return setPermissionsOnClass('UserProfile', {
|
||||
'readUserFields': ['user'],
|
||||
'writeUserFields': ['user']
|
||||
}, true);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return Parse.User.logIn('user', 'password')
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
let query = new Parse.Query('_User');
|
||||
query.include('userProfile');
|
||||
return query.get(user.id);
|
||||
}).then((user) => {
|
||||
}).then((user) => {
|
||||
expect(user.get('userProfile')).not.toBeUndefined();
|
||||
done();
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// This class handles the Account Lockout Policy settings.
|
||||
|
||||
import Config from './Config';
|
||||
import Parse from 'parse/node';
|
||||
|
||||
export class AccountLockout {
|
||||
constructor(user, config) {
|
||||
@@ -13,7 +12,7 @@ export class AccountLockout {
|
||||
*/
|
||||
_setFailedLoginCount(value) {
|
||||
let query = {
|
||||
username: this._user.username,
|
||||
username: this._user.username
|
||||
};
|
||||
|
||||
const updateFields = {
|
||||
@@ -76,7 +75,7 @@ export class AccountLockout {
|
||||
*/
|
||||
_incrementFailedLoginCount() {
|
||||
const query = {
|
||||
username: this._user.username,
|
||||
username: this._user.username
|
||||
};
|
||||
|
||||
const updateFields = {_failed_login_count: {__op: 'Increment', amount: 1}};
|
||||
@@ -93,7 +92,7 @@ export class AccountLockout {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = {
|
||||
username: this._user.username,
|
||||
_failed_login_count: { $gte: this._config.accountLockout.threshold },
|
||||
_failed_login_count: { $gte: this._config.accountLockout.threshold }
|
||||
};
|
||||
|
||||
const now = new Date();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
export class AnalyticsAdapter {
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
export class CacheAdapter {
|
||||
/**
|
||||
* Get a value in the cache
|
||||
|
||||
@@ -7,7 +7,7 @@ export class InMemoryCacheAdapter {
|
||||
}
|
||||
|
||||
get(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
let record = this.cache.get(key);
|
||||
if (record == null) {
|
||||
return resolve(null);
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
export class NullCacheAdapter {
|
||||
|
||||
constructor(ctx) {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
get(key) {
|
||||
return new Promise((resolve, _) => {
|
||||
get() {
|
||||
return new Promise((resolve) => {
|
||||
return resolve(null);
|
||||
})
|
||||
}
|
||||
|
||||
put(key, value, ttl) {
|
||||
put() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
del(key) {
|
||||
del() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import logger from '../../logger';
|
||||
|
||||
const DEFAULT_REDIS_TTL = 30 * 1000; // 30 seconds in milliseconds
|
||||
|
||||
function debug() {
|
||||
function debug() {
|
||||
logger.debug.apply(logger, ['RedisCacheAdapter', ...arguments]);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ export class RedisCacheAdapter {
|
||||
|
||||
get(key) {
|
||||
debug('get', key);
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve, _) => {
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve) => {
|
||||
this.client.get(key, function(err, res) {
|
||||
debug('-> get', key, res);
|
||||
if(!res) {
|
||||
@@ -39,14 +39,14 @@ export class RedisCacheAdapter {
|
||||
if (ttl < 0 || isNaN(ttl)) {
|
||||
ttl = DEFAULT_REDIS_TTL;
|
||||
}
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve, _) => {
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve) => {
|
||||
if (ttl === Infinity) {
|
||||
this.client.set(key, value, function(err, res) {
|
||||
this.client.set(key, value, function() {
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
this.client.psetex(key, ttl, value, function(err, res) {
|
||||
this.client.psetex(key, ttl, value, function() {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
@@ -57,9 +57,9 @@ export class RedisCacheAdapter {
|
||||
|
||||
del(key) {
|
||||
debug('del', key);
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve, _) => {
|
||||
this.client.del(key, function(err, res) {
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve) => {
|
||||
this.client.del(key, function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -69,9 +69,9 @@ export class RedisCacheAdapter {
|
||||
|
||||
clear() {
|
||||
debug('clear');
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve, _) => {
|
||||
this.client.flushall(function(err, res) {
|
||||
this.p = this.p.then(() => {
|
||||
return new Promise((resolve) => {
|
||||
this.client.flushall(function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
/*
|
||||
Mail Adapter prototype
|
||||
A MailAdapter should implement at least sendMail()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
// Files Adapter
|
||||
//
|
||||
// Allows you to change the file storage mechanism.
|
||||
|
||||
@@ -28,7 +28,7 @@ export class GridStoreAdapter extends FilesAdapter {
|
||||
|
||||
// For a given config object, filename, and data, store a file
|
||||
// Returns a promise
|
||||
createFile(filename: string, data, contentType) {
|
||||
createFile(filename: string, data) {
|
||||
return this._connect().then(database => {
|
||||
let gridStore = new GridStore(database, filename, 'w');
|
||||
return gridStore.open();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
// Logger Adapter
|
||||
//
|
||||
// Allows you to change the logger mechanism
|
||||
|
||||
@@ -37,7 +37,7 @@ function updateTransports(options) {
|
||||
}, options));
|
||||
}
|
||||
// Mount the additional transports
|
||||
additionalTransports.forEach((transport) => {
|
||||
additionalTransports.forEach((transport) => {
|
||||
transports[transport.name] = transport;
|
||||
});
|
||||
logger.configure({
|
||||
@@ -65,7 +65,7 @@ export function configureLogger({
|
||||
}
|
||||
try {
|
||||
fs.mkdirSync(logsFolder);
|
||||
} catch (exception) {}
|
||||
} catch (e) { /* */ }
|
||||
}
|
||||
options.dirname = logsFolder;
|
||||
options.level = logLevel;
|
||||
@@ -90,7 +90,7 @@ export function removeTransport(transport) {
|
||||
logger.configure({
|
||||
transports: _.values(transports)
|
||||
});
|
||||
_.remove(additionalTransports, (transport) => {
|
||||
_.remove(additionalTransports, (transport) => {
|
||||
return transport.name === transportName;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,11 +3,6 @@ import { logger, addTransport, configureLogger } from './WinstonLogger';
|
||||
|
||||
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
// returns Date object rounded to nearest day
|
||||
let _getNearestDay = (date) => {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
}
|
||||
|
||||
export class WinstonLoggerAdapter extends LoggerAdapter {
|
||||
constructor(options) {
|
||||
super();
|
||||
@@ -38,18 +33,16 @@ export class WinstonLoggerAdapter extends LoggerAdapter {
|
||||
let limit = options.size || 10;
|
||||
let order = options.order || 'desc';
|
||||
let level = options.level || 'info';
|
||||
let roundedUntil = _getNearestDay(until);
|
||||
let roundedFrom = _getNearestDay(from);
|
||||
|
||||
var options = {
|
||||
const queryOptions = {
|
||||
from,
|
||||
until,
|
||||
limit,
|
||||
order
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
logger.query(options, (err, res) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
logger.query(queryOptions, (err, res) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return reject(err);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*eslint no-unused-vars: "off"*/
|
||||
// Push Adapter
|
||||
//
|
||||
// Allows you to change the push notification mechanism.
|
||||
|
||||
@@ -84,7 +84,7 @@ export default class MongoCollection {
|
||||
|
||||
_ensureSparseUniqueIndexInBackground(indexRequest) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._mongoCollection.ensureIndex(indexRequest, { unique: true, background: true, sparse: true }, (error, indexName) => {
|
||||
this._mongoCollection.ensureIndex(indexRequest, { unique: true, background: true, sparse: true }, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import MongoCollection from './MongoCollection';
|
||||
import Parse from 'parse/node';
|
||||
|
||||
function mongoFieldToParseSchemaField(type) {
|
||||
if (type[0] === '*') {
|
||||
@@ -14,16 +15,16 @@ function mongoFieldToParseSchemaField(type) {
|
||||
};
|
||||
}
|
||||
switch (type) {
|
||||
case 'number': return {type: 'Number'};
|
||||
case 'string': return {type: 'String'};
|
||||
case 'boolean': return {type: 'Boolean'};
|
||||
case 'date': return {type: 'Date'};
|
||||
case 'map':
|
||||
case 'object': return {type: 'Object'};
|
||||
case 'array': return {type: 'Array'};
|
||||
case 'geopoint': return {type: 'GeoPoint'};
|
||||
case 'file': return {type: 'File'};
|
||||
case 'bytes': return {type: 'Bytes'};
|
||||
case 'number': return {type: 'Number'};
|
||||
case 'string': return {type: 'String'};
|
||||
case 'boolean': return {type: 'Boolean'};
|
||||
case 'date': return {type: 'Date'};
|
||||
case 'map':
|
||||
case 'object': return {type: 'Object'};
|
||||
case 'array': return {type: 'Array'};
|
||||
case 'geopoint': return {type: 'GeoPoint'};
|
||||
case 'file': return {type: 'File'};
|
||||
case 'bytes': return {type: 'Bytes'};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,16 +88,16 @@ function _mongoSchemaQueryFromNameQuery(name: string, query) {
|
||||
// Does no validation. That is expected to be done in Parse Server.
|
||||
function parseFieldTypeToMongoFieldType({ type, targetClass }) {
|
||||
switch (type) {
|
||||
case 'Pointer': return `*${targetClass}`;
|
||||
case 'Relation': return `relation<${targetClass}>`;
|
||||
case 'Number': return 'number';
|
||||
case 'String': return 'string';
|
||||
case 'Boolean': return 'boolean';
|
||||
case 'Date': return 'date';
|
||||
case 'Object': return 'object';
|
||||
case 'Array': return 'array';
|
||||
case 'GeoPoint': return 'geopoint';
|
||||
case 'File': return 'file';
|
||||
case 'Pointer': return `*${targetClass}`;
|
||||
case 'Relation': return `relation<${targetClass}>`;
|
||||
case 'Number': return 'number';
|
||||
case 'String': return 'string';
|
||||
case 'Boolean': return 'boolean';
|
||||
case 'Date': return 'date';
|
||||
case 'Object': return 'object';
|
||||
case 'Array': return 'array';
|
||||
case 'GeoPoint': return 'geopoint';
|
||||
case 'File': return 'file';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ import {
|
||||
transformWhere,
|
||||
transformUpdate,
|
||||
} from './MongoTransform';
|
||||
import Parse from 'parse/node';
|
||||
import _ from 'lodash';
|
||||
import defaults from '../../../defaults';
|
||||
|
||||
let mongodb = require('mongodb');
|
||||
let MongoClient = mongodb.MongoClient;
|
||||
@@ -63,7 +65,7 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
|
||||
}
|
||||
|
||||
if (typeof classLevelPermissions !== 'undefined') {
|
||||
mongoObject._metadata = mongoObject._metadata || {};
|
||||
mongoObject._metadata = mongoObject._metadata || {};
|
||||
if (!classLevelPermissions) {
|
||||
delete mongoObject._metadata.class_permissions;
|
||||
} else {
|
||||
@@ -111,14 +113,14 @@ export class MongoStorageAdapter {
|
||||
delete this.connectionPromise;
|
||||
return;
|
||||
}
|
||||
database.on('error', (error) => {
|
||||
database.on('error', () => {
|
||||
delete this.connectionPromise;
|
||||
});
|
||||
database.on('close', (error) => {
|
||||
database.on('close', () => {
|
||||
delete this.connectionPromise;
|
||||
});
|
||||
this.database = database;
|
||||
}).catch((err) => {
|
||||
}).catch((err) => {
|
||||
delete this.connectionPromise;
|
||||
return Promise.reject(err);
|
||||
});
|
||||
@@ -288,7 +290,7 @@ export class MongoStorageAdapter {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}, error => {
|
||||
}, () => {
|
||||
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error');
|
||||
});
|
||||
}
|
||||
@@ -327,7 +329,7 @@ export class MongoStorageAdapter {
|
||||
schema = convertParseSchemaToMongoSchema(schema);
|
||||
let mongoWhere = transformWhere(className, query, schema);
|
||||
let mongoSort = _.mapKeys(sort, (value, fieldName) => transformKey(className, fieldName, schema));
|
||||
let mongoKeys = _.reduce(keys, (memo, key) => {
|
||||
let mongoKeys = _.reduce(keys, (memo, key) => {
|
||||
memo[transformKey(className, key, schema)] = 1;
|
||||
return memo;
|
||||
}, {});
|
||||
|
||||
@@ -6,10 +6,10 @@ var Parse = require('parse/node').Parse;
|
||||
const transformKey = (className, fieldName, schema) => {
|
||||
// Check if the schema is known since it's a built-in field.
|
||||
switch(fieldName) {
|
||||
case 'objectId': return '_id';
|
||||
case 'createdAt': return '_created_at';
|
||||
case 'updatedAt': return '_updated_at';
|
||||
case 'sessionToken': return '_session_token';
|
||||
case 'objectId': return '_id';
|
||||
case 'createdAt': return '_created_at';
|
||||
case 'updatedAt': return '_updated_at';
|
||||
case 'sessionToken': return '_session_token';
|
||||
}
|
||||
|
||||
if (schema.fields[fieldName] && schema.fields[fieldName].__type == 'Pointer') {
|
||||
@@ -197,7 +197,7 @@ function transformQueryKeyValue(className, key, value, schema) {
|
||||
return {key: '$or', value: value.map(subQuery => transformWhere(className, subQuery, schema))};
|
||||
case '$and':
|
||||
return {key: '$and', value: value.map(subQuery => transformWhere(className, subQuery, schema))};
|
||||
default:
|
||||
default: {
|
||||
// Other auth data
|
||||
const authDataMatch = key.match(/^authData\.([a-zA-Z0-9_]+)\.id$/);
|
||||
if (authDataMatch) {
|
||||
@@ -206,6 +206,7 @@ function transformQueryKeyValue(className, key, value, schema) {
|
||||
return {key: `_auth_data_${provider}.id`, value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const expectedTypeIsArray =
|
||||
schema &&
|
||||
@@ -530,8 +531,8 @@ function transformConstraint(constraint, inArray) {
|
||||
break;
|
||||
|
||||
case '$in':
|
||||
case '$nin':
|
||||
var arr = constraint[key];
|
||||
case '$nin': {
|
||||
let arr = constraint[key];
|
||||
if (!(arr instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value');
|
||||
}
|
||||
@@ -543,16 +544,16 @@ function transformConstraint(constraint, inArray) {
|
||||
return result;
|
||||
});
|
||||
break;
|
||||
|
||||
case '$all':
|
||||
var arr = constraint[key];
|
||||
}
|
||||
case '$all': {
|
||||
let arr = constraint[key];
|
||||
if (!(arr instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON,
|
||||
'bad ' + key + ' value');
|
||||
}
|
||||
answer[key] = arr.map(transformInteriorAtom);
|
||||
break;
|
||||
|
||||
}
|
||||
case '$regex':
|
||||
var s = constraint[key];
|
||||
if (typeof s !== 'string') {
|
||||
@@ -736,7 +737,7 @@ const mongoObjectToParseObject = (className, mongoObject, schema) => {
|
||||
case 'symbol':
|
||||
case 'function':
|
||||
throw 'bad value in mongoObjectToParseObject';
|
||||
case 'object':
|
||||
case 'object': {
|
||||
if (mongoObject === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -868,6 +869,7 @@ const mongoObjectToParseObject = (className, mongoObject, schema) => {
|
||||
});
|
||||
|
||||
return { ...restObject, ...relationFields };
|
||||
}
|
||||
default:
|
||||
throw 'unknown js type';
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createClient } from './PostgresClient';
|
||||
import Parse from 'parse/node';
|
||||
|
||||
const PostgresRelationDoesNotExistError = '42P01';
|
||||
const PostgresDuplicateRelationError = '42P07';
|
||||
@@ -16,21 +17,21 @@ const debug = function(){
|
||||
|
||||
const parseTypeToPostgresType = type => {
|
||||
switch (type.type) {
|
||||
case 'String': return 'text';
|
||||
case 'Date': return 'timestamp with time zone';
|
||||
case 'Object': return 'jsonb';
|
||||
case 'File': return 'text';
|
||||
case 'Boolean': return 'boolean';
|
||||
case 'Pointer': return 'char(10)';
|
||||
case 'Number': return 'double precision';
|
||||
case 'GeoPoint': return 'point';
|
||||
case 'Array':
|
||||
if (type.contents && type.contents.type === 'String') {
|
||||
return 'text[]';
|
||||
} else {
|
||||
return 'jsonb';
|
||||
}
|
||||
default: throw `no type for ${JSON.stringify(type)} yet`;
|
||||
case 'String': return 'text';
|
||||
case 'Date': return 'timestamp with time zone';
|
||||
case 'Object': return 'jsonb';
|
||||
case 'File': return 'text';
|
||||
case 'Boolean': return 'boolean';
|
||||
case 'Pointer': return 'char(10)';
|
||||
case 'Number': return 'double precision';
|
||||
case 'GeoPoint': return 'point';
|
||||
case 'Array':
|
||||
if (type.contents && type.contents.type === 'String') {
|
||||
return 'text[]';
|
||||
} else {
|
||||
return 'jsonb';
|
||||
}
|
||||
default: throw `no type for ${JSON.stringify(type)} yet`;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,7 +42,7 @@ const ParseToPosgresComparator = {
|
||||
'$lte': '<='
|
||||
}
|
||||
|
||||
const toPostgresValue = value => {
|
||||
const toPostgresValue = value => {
|
||||
if (typeof value === 'object') {
|
||||
if (value.__type === 'Date') {
|
||||
return value.iso;
|
||||
@@ -53,7 +54,7 @@ const toPostgresValue = value => {
|
||||
return value;
|
||||
}
|
||||
|
||||
const transformValue = value => {
|
||||
const transformValue = value => {
|
||||
if (value.__type === 'Pointer') {
|
||||
return value.objectId;
|
||||
}
|
||||
@@ -79,7 +80,7 @@ const defaultCLPS = Object.freeze({
|
||||
addField: {'*': true},
|
||||
});
|
||||
|
||||
const toParseSchema = (schema) => {
|
||||
const toParseSchema = (schema) => {
|
||||
if (schema.className === '_User') {
|
||||
delete schema.fields._hashed_password;
|
||||
}
|
||||
@@ -98,7 +99,7 @@ const toParseSchema = (schema) => {
|
||||
};
|
||||
}
|
||||
|
||||
const toPostgresSchema = (schema) => {
|
||||
const toPostgresSchema = (schema) => {
|
||||
if (!schema) {
|
||||
return schema;
|
||||
}
|
||||
@@ -111,8 +112,8 @@ const toPostgresSchema = (schema) => {
|
||||
return schema;
|
||||
}
|
||||
|
||||
const handleDotFields = (object) => {
|
||||
Object.keys(object).forEach(fieldName => {
|
||||
const handleDotFields = (object) => {
|
||||
Object.keys(object).forEach(fieldName => {
|
||||
if (fieldName.indexOf('.') > -1) {
|
||||
let components = fieldName.split('.');
|
||||
let first = components.shift();
|
||||
@@ -123,7 +124,9 @@ const handleDotFields = (object) => {
|
||||
if (value && value.__op === 'Delete') {
|
||||
value = undefined;
|
||||
}
|
||||
/* eslint-disable no-cond-assign */
|
||||
while(next = components.shift()) {
|
||||
/* eslint-enable no-cond-assign */
|
||||
currentObj[next] = currentObj[next] || {};
|
||||
if (components.length === 0) {
|
||||
currentObj[next] = value;
|
||||
@@ -151,7 +154,7 @@ const validateKeys = (object) => {
|
||||
}
|
||||
|
||||
// Returns the list of join tables on a schema
|
||||
const joinTablesForSchema = (schema) => {
|
||||
const joinTablesForSchema = (schema) => {
|
||||
let list = [];
|
||||
if (schema) {
|
||||
Object.keys(schema.fields).forEach((field) => {
|
||||
@@ -185,11 +188,11 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
|
||||
if (fieldName.indexOf('.') >= 0) {
|
||||
let components = fieldName.split('.').map((cmpt, index) => {
|
||||
let components = fieldName.split('.').map((cmpt, index) => {
|
||||
if (index === 0) {
|
||||
return `"${cmpt}"`;
|
||||
}
|
||||
return `'${cmpt}'`;
|
||||
return `'${cmpt}'`;
|
||||
});
|
||||
let name = components.slice(0, components.length-1).join('->');
|
||||
name+='->>'+components[components.length-1];
|
||||
@@ -209,7 +212,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
} else if (fieldName === '$or' || fieldName === '$and') {
|
||||
let clauses = [];
|
||||
let clauseValues = [];
|
||||
fieldValue.forEach((subQuery, idx) => {
|
||||
fieldValue.forEach((subQuery) => {
|
||||
let clause = buildWhereClause({ schema, query: subQuery, index });
|
||||
if (clause.pattern.length > 0) {
|
||||
clauses.push(clause.pattern);
|
||||
@@ -268,7 +271,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
index = index + 1 + inPatterns.length;
|
||||
} else if (isInOrNin) {
|
||||
var createConstraint = (baseArray, notIn) => {
|
||||
var createConstraint = (baseArray, notIn) => {
|
||||
if (baseArray.length > 0) {
|
||||
let not = notIn ? ' NOT ' : '';
|
||||
if (isArrayField) {
|
||||
@@ -375,7 +378,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
index += 2;
|
||||
}
|
||||
|
||||
Object.keys(ParseToPosgresComparator).forEach(cmp => {
|
||||
Object.keys(ParseToPosgresComparator).forEach(cmp => {
|
||||
if (fieldValue[cmp]) {
|
||||
let pgComparator = ParseToPosgresComparator[cmp];
|
||||
patterns.push(`$${index}:name ${pgComparator} $${index + 1}`);
|
||||
@@ -416,10 +419,10 @@ export class PostgresStorageAdapter {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
classExists(name) {
|
||||
return this._client.one(`SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)`, [name]).then((res) => {
|
||||
return this._client.one(`SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)`, [name]).then((res) => {
|
||||
return res.exists;
|
||||
});
|
||||
}
|
||||
@@ -433,15 +436,15 @@ export class PostgresStorageAdapter {
|
||||
|
||||
createClass(className, schema) {
|
||||
return this._client.tx(t => {
|
||||
const q1 = this.createTable(className, schema, t);
|
||||
const q2 = t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)', { className, schema });
|
||||
const q1 = this.createTable(className, schema, t);
|
||||
const q2 = t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)', { className, schema });
|
||||
|
||||
return t.batch([q1, q2]);
|
||||
return t.batch([q1, q2]);
|
||||
})
|
||||
.then(() => {
|
||||
return toParseSchema(schema)
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err) => {
|
||||
if (Array.isArray(err.data) && err.data.length > 1 && err.data[0].result.code === PostgresTransactionAbortedError) {
|
||||
err = err.data[1].result;
|
||||
}
|
||||
@@ -500,9 +503,9 @@ export class PostgresStorageAdapter {
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// Create the relation tables
|
||||
return Promise.all(relations.map((fieldName) => {
|
||||
return Promise.all(relations.map((fieldName) => {
|
||||
return conn.none('CREATE TABLE IF NOT EXISTS $<joinTable:name> ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', {joinTable: `_Join:${fieldName}:${className}`});
|
||||
}));
|
||||
});
|
||||
@@ -551,11 +554,11 @@ export class PostgresStorageAdapter {
|
||||
// Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.)
|
||||
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
|
||||
deleteClass(className) {
|
||||
return Promise.resolve().then(() => {
|
||||
return Promise.resolve().then(() => {
|
||||
let operations = [[`DROP TABLE IF EXISTS $1:name`, [className]],
|
||||
[`DELETE FROM "_SCHEMA" WHERE "className"=$1`, [className]]];
|
||||
return this._client.tx(t=>t.batch(operations.map(statement=>t.none(statement[0], statement[1]))));
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
// resolves with false when _Join table
|
||||
return className.indexOf('_Join:') != 0;
|
||||
});
|
||||
@@ -567,7 +570,7 @@ export class PostgresStorageAdapter {
|
||||
debug('deleteAllClasses');
|
||||
return this._client.any('SELECT * FROM "_SCHEMA"')
|
||||
.then(results => {
|
||||
let joins = results.reduce((list, schema) => {
|
||||
let joins = results.reduce((list, schema) => {
|
||||
return list.concat(joinTablesForSchema(schema.schema));
|
||||
}, []);
|
||||
const classes = ['_SCHEMA','_PushStatus','_JobStatus','_Hooks','_GlobalConfig', ...results.map(result => result.className), ...joins];
|
||||
@@ -579,7 +582,7 @@ export class PostgresStorageAdapter {
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
debug(`deleteAllClasses done in ${new Date().getTime() - now}`);
|
||||
});
|
||||
}
|
||||
@@ -600,8 +603,8 @@ export class PostgresStorageAdapter {
|
||||
deleteFields(className, schema, fieldNames) {
|
||||
debug('deleteFields', className, fieldNames);
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
fieldNames = fieldNames.reduce((list, fieldName) => {
|
||||
.then(() => {
|
||||
fieldNames = fieldNames.reduce((list, fieldName) => {
|
||||
let field = schema.fields[fieldName]
|
||||
if (field.type !== 'Relation') {
|
||||
list.push(fieldName);
|
||||
@@ -611,11 +614,11 @@ export class PostgresStorageAdapter {
|
||||
}, []);
|
||||
|
||||
let values = [className, ...fieldNames];
|
||||
let columns = fieldNames.map((name, idx) => {
|
||||
let columns = fieldNames.map((name, idx) => {
|
||||
return `$${idx+2}:name`;
|
||||
}).join(',');
|
||||
|
||||
let doBatch = (t) => {
|
||||
let doBatch = (t) => {
|
||||
let batch = [
|
||||
t.none('UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>', {schema, className})
|
||||
];
|
||||
@@ -624,7 +627,7 @@ export class PostgresStorageAdapter {
|
||||
}
|
||||
return batch;
|
||||
}
|
||||
return this._client.tx((t) => {
|
||||
return this._client.tx((t) => {
|
||||
return t.batch(doBatch(t));
|
||||
});
|
||||
});
|
||||
@@ -658,7 +661,6 @@ export class PostgresStorageAdapter {
|
||||
createObject(className, schema, object) {
|
||||
debug('createObject', className, object);
|
||||
let columnsArray = [];
|
||||
let newFieldsArray = [];
|
||||
let valuesArray = [];
|
||||
schema = toPostgresSchema(schema);
|
||||
let geoPoints = {};
|
||||
@@ -705,39 +707,39 @@ export class PostgresStorageAdapter {
|
||||
return;
|
||||
}
|
||||
switch (schema.fields[fieldName].type) {
|
||||
case 'Date':
|
||||
if (object[fieldName]) {
|
||||
valuesArray.push(object[fieldName].iso);
|
||||
} else {
|
||||
valuesArray.push(null);
|
||||
}
|
||||
break;
|
||||
case 'Pointer':
|
||||
valuesArray.push(object[fieldName].objectId);
|
||||
break;
|
||||
case 'Array':
|
||||
if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) {
|
||||
valuesArray.push(object[fieldName]);
|
||||
} else {
|
||||
valuesArray.push(JSON.stringify(object[fieldName]));
|
||||
}
|
||||
break;
|
||||
case 'Object':
|
||||
case 'String':
|
||||
case 'Number':
|
||||
case 'Boolean':
|
||||
case 'Date':
|
||||
if (object[fieldName]) {
|
||||
valuesArray.push(object[fieldName].iso);
|
||||
} else {
|
||||
valuesArray.push(null);
|
||||
}
|
||||
break;
|
||||
case 'Pointer':
|
||||
valuesArray.push(object[fieldName].objectId);
|
||||
break;
|
||||
case 'Array':
|
||||
if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) {
|
||||
valuesArray.push(object[fieldName]);
|
||||
break;
|
||||
case 'File':
|
||||
valuesArray.push(object[fieldName].name);
|
||||
break;
|
||||
case 'GeoPoint':
|
||||
} else {
|
||||
valuesArray.push(JSON.stringify(object[fieldName]));
|
||||
}
|
||||
break;
|
||||
case 'Object':
|
||||
case 'String':
|
||||
case 'Number':
|
||||
case 'Boolean':
|
||||
valuesArray.push(object[fieldName]);
|
||||
break;
|
||||
case 'File':
|
||||
valuesArray.push(object[fieldName].name);
|
||||
break;
|
||||
case 'GeoPoint':
|
||||
// pop the point and process later
|
||||
geoPoints[fieldName] = object[fieldName];
|
||||
columnsArray.pop();
|
||||
break;
|
||||
default:
|
||||
throw `Type ${schema.fields[fieldName].type} not supported yet`;
|
||||
geoPoints[fieldName] = object[fieldName];
|
||||
columnsArray.pop();
|
||||
break;
|
||||
default:
|
||||
throw `Type ${schema.fields[fieldName].type} not supported yet`;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -752,7 +754,7 @@ export class PostgresStorageAdapter {
|
||||
}
|
||||
return `$${index + 2 + columnsArray.length}${termination}`;
|
||||
});
|
||||
let geoPointsInjects = Object.keys(geoPoints).map((key, idx) => {
|
||||
let geoPointsInjects = Object.keys(geoPoints).map((key) => {
|
||||
let value = geoPoints[key];
|
||||
valuesArray.push(value.longitude, value.latitude);
|
||||
let l = valuesArray.length + columnsArray.length;
|
||||
@@ -802,13 +804,12 @@ export class PostgresStorageAdapter {
|
||||
// Return value not currently well specified.
|
||||
findOneAndUpdate(className, schema, query, update) {
|
||||
debug('findOneAndUpdate', className, query, update);
|
||||
return this.updateObjectsByQuery(className, schema, query, update).then((val) => val[0]);
|
||||
return this.updateObjectsByQuery(className, schema, query, update).then((val) => val[0]);
|
||||
}
|
||||
|
||||
// Apply the update to all objects that match the given Parse Query.
|
||||
updateObjectsByQuery(className, schema, query, update) {
|
||||
debug('updateObjectsByQuery', className, query, update);
|
||||
let conditionPatterns = [];
|
||||
let updatePatterns = [];
|
||||
let values = [className]
|
||||
let index = 2;
|
||||
@@ -838,8 +839,8 @@ export class PostgresStorageAdapter {
|
||||
} else if (fieldName == 'authData') {
|
||||
// This recursively sets the json_object
|
||||
// Only 1 level deep
|
||||
let generate = (jsonb, key, value) => {
|
||||
return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`;
|
||||
let generate = (jsonb, key, value) => {
|
||||
return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`;
|
||||
}
|
||||
let lastKey = `$${index}:name`;
|
||||
let fieldNameIndex = index;
|
||||
@@ -930,10 +931,10 @@ export class PostgresStorageAdapter {
|
||||
return p + ` - '$${index + 1 + i}:value'`;
|
||||
}, '');
|
||||
|
||||
updatePatterns.push(`$${index}:name = ( COALESCE($${index}:name, '{}'::jsonb) ${deletePatterns} || $${index + 1 + keysToDelete.length}::jsonb )`);
|
||||
updatePatterns.push(`$${index}:name = ( COALESCE($${index}:name, '{}'::jsonb) ${deletePatterns} || $${index + 1 + keysToDelete.length}::jsonb )`);
|
||||
|
||||
values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue));
|
||||
index += 2 + keysToDelete.length;
|
||||
values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue));
|
||||
index += 2 + keysToDelete.length;
|
||||
} else if (Array.isArray(fieldValue)
|
||||
&& schema.fields[fieldName]
|
||||
&& schema.fields[fieldName].type === 'Array') {
|
||||
@@ -970,7 +971,7 @@ export class PostgresStorageAdapter {
|
||||
upsertOneObject(className, schema, query, update) {
|
||||
debug('upsertOneObject', {className, query, update});
|
||||
let createValue = Object.assign({}, query, update);
|
||||
return this.createObject(className, schema, createValue).catch((err) => {
|
||||
return this.createObject(className, schema, createValue).catch((err) => {
|
||||
// ignore duplicate value errors as it's upsert
|
||||
if (err.code === Parse.Error.DUPLICATE_VALUE) {
|
||||
return this.findOneAndUpdate(className, schema, query, update);
|
||||
@@ -999,26 +1000,26 @@ export class PostgresStorageAdapter {
|
||||
|
||||
let sortPattern = '';
|
||||
if (sort) {
|
||||
let sorting = Object.keys(sort).map((key) => {
|
||||
let sorting = Object.keys(sort).map((key) => {
|
||||
// Using $idx pattern gives: non-integer constant in ORDER BY
|
||||
if (sort[key] === 1) {
|
||||
return `"${key}" ASC`;
|
||||
}
|
||||
return `"${key}" DESC`;
|
||||
}).join(',');
|
||||
sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : '';
|
||||
sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : '';
|
||||
}
|
||||
if (where.sorts && Object.keys(where.sorts).length > 0) {
|
||||
if (where.sorts && Object.keys(where.sorts).length > 0) {
|
||||
sortPattern = `ORDER BY ${where.sorts.join(',')}`;
|
||||
}
|
||||
|
||||
let columns = '*';
|
||||
if (keys) {
|
||||
// Exclude empty keys
|
||||
keys = keys.filter((key) => {
|
||||
keys = keys.filter((key) => {
|
||||
return key.length > 0;
|
||||
});
|
||||
columns = keys.map((key, index) => {
|
||||
columns = keys.map((key, index) => {
|
||||
return `$${index+values.length+1}:name`;
|
||||
}).join(',');
|
||||
values = values.concat(keys);
|
||||
@@ -1027,7 +1028,7 @@ export class PostgresStorageAdapter {
|
||||
const qs = `SELECT ${columns} FROM $1:name ${wherePattern} ${sortPattern} ${limitPattern} ${skipPattern}`;
|
||||
debug(qs, values);
|
||||
return this._client.any(qs, values)
|
||||
.catch((err) => {
|
||||
.catch((err) => {
|
||||
// Query on non existing table, don't crash
|
||||
if (err.code === PostgresRelationDoesNotExistError) {
|
||||
return [];
|
||||
@@ -1127,7 +1128,7 @@ export class PostgresStorageAdapter {
|
||||
|
||||
const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : '';
|
||||
const qs = `SELECT count(*) FROM $1:name ${wherePattern}`;
|
||||
return this._client.one(qs, values, a => +a.count).catch((err) => {
|
||||
return this._client.one(qs, values, a => +a.count).catch((err) => {
|
||||
if (err.code === PostgresRelationDoesNotExistError) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1138,7 +1139,7 @@ export class PostgresStorageAdapter {
|
||||
performInitialization({ VolatileClassesSchemas }) {
|
||||
let now = new Date().getTime();
|
||||
debug('performInitialization');
|
||||
let promises = VolatileClassesSchemas.map((schema) => {
|
||||
let promises = VolatileClassesSchemas.map((schema) => {
|
||||
return this.createTable(schema.className, schema).catch((err) =>{
|
||||
if (err.code === PostgresDuplicateRelationError || err.code === Parse.Error.INVALID_CLASS_NAME) {
|
||||
return Promise.resolve();
|
||||
@@ -1146,36 +1147,34 @@ export class PostgresStorageAdapter {
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
/* eslint-disable no-console */
|
||||
promises = promises.concat([
|
||||
this._client.any(json_object_set_key).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_add).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_add_unique).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_remove).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_contains_all).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_contains).catch((err) => {
|
||||
console.error(err);
|
||||
})
|
||||
]);
|
||||
return Promise.all(promises).then(() => {
|
||||
this._client.any(json_object_set_key).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_add).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_add_unique).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_remove).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_contains_all).catch((err) => {
|
||||
console.error(err);
|
||||
}),
|
||||
this._client.any(array_contains).catch((err) => {
|
||||
console.error(err);
|
||||
})
|
||||
]);
|
||||
/* eslint-enable no-console */
|
||||
return Promise.all(promises).then(() => {
|
||||
debug(`initialzationDone in ${new Date().getTime() - now}`);
|
||||
}, (err) => {});
|
||||
}, () => {});
|
||||
}
|
||||
}
|
||||
|
||||
function notImplemented() {
|
||||
return Promise.reject(new Error('Not implemented yet.'));
|
||||
}
|
||||
|
||||
function removeWhiteSpace(regex) {
|
||||
if (!regex.endsWith('\n')){
|
||||
regex += '\n';
|
||||
|
||||
11
src/Auth.js
11
src/Auth.js
@@ -1,4 +1,3 @@
|
||||
var deepcopy = require('deepcopy');
|
||||
var Parse = require('parse/node').Parse;
|
||||
var RestQuery = require('./RestQuery');
|
||||
|
||||
@@ -80,13 +79,13 @@ var getAuthForSessionToken = function({ config, sessionToken, installationId } =
|
||||
|
||||
var getAuthForLegacySessionToken = function({config, sessionToken, installationId } = {}) {
|
||||
var restOptions = {
|
||||
limit: 1
|
||||
limit: 1
|
||||
};
|
||||
var query = new RestQuery(config, master(config), '_User', { sessionToken: sessionToken}, restOptions);
|
||||
return query.execute().then((response) => {
|
||||
return query.execute().then((response) => {
|
||||
var results = response.results;
|
||||
if (results.length !== 1) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token');
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token');
|
||||
}
|
||||
let obj = results[0];
|
||||
obj.className = '_User';
|
||||
@@ -163,7 +162,7 @@ Auth.prototype._loadRoles = function() {
|
||||
|
||||
// Given a list of roleIds, find all the parent roles, returns a promise with all names
|
||||
Auth.prototype._getAllRolesNamesForRoleIds = function(roleIDs, names = [], queriedRoles = {}) {
|
||||
let ins = roleIDs.filter((roleID) => {
|
||||
let ins = roleIDs.filter((roleID) => {
|
||||
return queriedRoles[roleID] !== true;
|
||||
}).map((roleID) => {
|
||||
// mark as queried
|
||||
@@ -194,7 +193,7 @@ Auth.prototype._getAllRolesNamesForRoleIds = function(roleIDs, names = [], queri
|
||||
return Promise.resolve(names);
|
||||
}
|
||||
// Map the results with all Ids and names
|
||||
let resultMap = results.reduce((memo, role) => {
|
||||
let resultMap = results.reduce((memo, role) => {
|
||||
memo.names.push(role.name);
|
||||
memo.ids.push(role.objectId);
|
||||
return memo;
|
||||
|
||||
@@ -50,15 +50,15 @@ export class AdaptableController {
|
||||
|
||||
// Makes sure the prototype matches
|
||||
let mismatches = Object.getOwnPropertyNames(Type.prototype).reduce( (obj, key) => {
|
||||
const adapterType = typeof adapter[key];
|
||||
const expectedType = typeof Type.prototype[key];
|
||||
if (adapterType !== expectedType) {
|
||||
obj[key] = {
|
||||
expected: expectedType,
|
||||
actual: adapterType
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
const adapterType = typeof adapter[key];
|
||||
const expectedType = typeof Type.prototype[key];
|
||||
if (adapterType !== expectedType) {
|
||||
obj[key] = {
|
||||
expected: expectedType,
|
||||
actual: adapterType
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
if (Object.keys(mismatches).length > 0) {
|
||||
|
||||
@@ -7,7 +7,7 @@ export class AnalyticsController extends AdaptableController {
|
||||
return this.adapter.appOpened(req.body, req);
|
||||
}).then((response) => {
|
||||
return { response: response || {} };
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
return { response: {} };
|
||||
});
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export class AnalyticsController extends AdaptableController {
|
||||
return this.adapter.trackEvent(req.params.eventName, req.body, req);
|
||||
}).then((response) => {
|
||||
return { response: response || {} };
|
||||
}).catch((err) => {
|
||||
}).catch(() => {
|
||||
return { response: {} };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import { Parse } from 'parse/node';
|
||||
import _ from 'lodash';
|
||||
import mongdb from 'mongodb';
|
||||
import intersect from 'intersect';
|
||||
import deepcopy from 'deepcopy';
|
||||
import logger from '../logger';
|
||||
@@ -45,7 +44,7 @@ const transformObjectACL = ({ ACL, ...result }) => {
|
||||
|
||||
const specialQuerykeys = ['$and', '$or', '_rperm', '_wperm', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count'];
|
||||
|
||||
const isSpecialQueryKey = key => {
|
||||
const isSpecialQueryKey = key => {
|
||||
return specialQuerykeys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
@@ -148,7 +147,7 @@ DatabaseController.prototype.validateObject = function(className, object, query,
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this.canAddField(schema, className, object, aclGroup);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
return schema.validateObject(className, object, query);
|
||||
});
|
||||
};
|
||||
@@ -193,7 +192,7 @@ const filterSensitiveData = (isMaster, aclGroup, className, object) => {
|
||||
// write permissions.
|
||||
const specialKeysForUpdate = ['_hashed_password', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count', '_perishable_token_expires_at', '_password_changed_at'];
|
||||
|
||||
const isSpecialUpdateKey = key => {
|
||||
const isSpecialUpdateKey = key => {
|
||||
return specialKeysForUpdate.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
@@ -208,7 +207,6 @@ DatabaseController.prototype.update = function(className, query, update, {
|
||||
|
||||
var isMaster = acl === undefined;
|
||||
var aclGroup = acl || [];
|
||||
var mongoUpdate;
|
||||
return this.loadSchema()
|
||||
.then(schemaController => {
|
||||
return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'update'))
|
||||
@@ -280,7 +278,7 @@ function sanitizeDatabaseResult(originalObject, result) {
|
||||
let keyUpdate = originalObject[key];
|
||||
// determine if that was an op
|
||||
if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op
|
||||
&& ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) {
|
||||
&& ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) {
|
||||
// only valid ops that produce an actionable result
|
||||
response[key] = result[key];
|
||||
}
|
||||
@@ -302,7 +300,7 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
return;
|
||||
}
|
||||
if (op.__op == 'AddRelation') {
|
||||
for (var object of op.objects) {
|
||||
for (let object of op.objects) {
|
||||
pending.push(this.addRelation(key, className,
|
||||
objectId,
|
||||
object.objectId));
|
||||
@@ -311,7 +309,7 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
}
|
||||
|
||||
if (op.__op == 'RemoveRelation') {
|
||||
for (var object of op.objects) {
|
||||
for (let object of op.objects) {
|
||||
pending.push(this.removeRelation(key, className,
|
||||
objectId,
|
||||
object.objectId));
|
||||
@@ -326,10 +324,10 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
}
|
||||
};
|
||||
|
||||
for (var key in update) {
|
||||
for (let key in update) {
|
||||
process(update[key], key);
|
||||
}
|
||||
for (var key of deleteMe) {
|
||||
for (let key of deleteMe) {
|
||||
delete update[key];
|
||||
}
|
||||
return Promise.all(pending);
|
||||
@@ -415,35 +413,35 @@ const flattenUpdateOperatorsForCreate = object => {
|
||||
for (let key in object) {
|
||||
if (object[key] && object[key].__op) {
|
||||
switch (object[key].__op) {
|
||||
case 'Increment':
|
||||
if (typeof object[key].amount !== 'number') {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].amount;
|
||||
break;
|
||||
case 'Add':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].objects;
|
||||
break;
|
||||
case 'AddUnique':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].objects;
|
||||
break;
|
||||
case 'Remove':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = []
|
||||
break;
|
||||
case 'Delete':
|
||||
delete object[key];
|
||||
break;
|
||||
default:
|
||||
throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`);
|
||||
case 'Increment':
|
||||
if (typeof object[key].amount !== 'number') {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].amount;
|
||||
break;
|
||||
case 'Add':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].objects;
|
||||
break;
|
||||
case 'AddUnique':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = object[key].objects;
|
||||
break;
|
||||
case 'Remove':
|
||||
if (!(object[key].objects instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array');
|
||||
}
|
||||
object[key] = []
|
||||
break;
|
||||
case 'Delete':
|
||||
delete object[key];
|
||||
break;
|
||||
default:
|
||||
throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -451,7 +449,7 @@ const flattenUpdateOperatorsForCreate = object => {
|
||||
|
||||
const transformAuthData = (className, object, schema) => {
|
||||
if (object.authData && className === '_User') {
|
||||
Object.keys(object.authData).forEach(provider => {
|
||||
Object.keys(object.authData).forEach(provider => {
|
||||
const providerData = object.authData[provider];
|
||||
const fieldName = `_auth_data_${provider}`;
|
||||
if (providerData == null) {
|
||||
@@ -504,7 +502,7 @@ DatabaseController.prototype.canAddField = function(schema, className, object, a
|
||||
}
|
||||
let fields = Object.keys(object);
|
||||
let schemaFields = Object.keys(classSchema);
|
||||
let newKeys = fields.filter((field) => {
|
||||
let newKeys = fields.filter((field) => {
|
||||
return schemaFields.indexOf(field) < 0;
|
||||
})
|
||||
if (newKeys.length > 0) {
|
||||
@@ -523,20 +521,6 @@ DatabaseController.prototype.deleteEverything = function() {
|
||||
]);
|
||||
};
|
||||
|
||||
// Finds the keys in a query. Returns a Set. REST format only
|
||||
function keysForQuery(query) {
|
||||
var sublist = query['$and'] || query['$or'];
|
||||
if (sublist) {
|
||||
let answer = sublist.reduce((memo, subquery) => {
|
||||
return memo.concat(keysForQuery(subquery));
|
||||
}, []);
|
||||
|
||||
return new Set(answer);
|
||||
}
|
||||
|
||||
return new Set(Object.keys(query));
|
||||
}
|
||||
|
||||
// Returns a promise for a list of related ids given an owning id.
|
||||
// className here is the owning className.
|
||||
DatabaseController.prototype.relatedIds = function(className, key, owningId) {
|
||||
@@ -561,10 +545,10 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
if (query['$or']) {
|
||||
let ors = query['$or'];
|
||||
return Promise.all(ors.map((aQuery, index) => {
|
||||
return this.reduceInRelation(className, aQuery, schema).then((aQuery) => {
|
||||
return this.reduceInRelation(className, aQuery, schema).then((aQuery) => {
|
||||
query['$or'][index] = aQuery;
|
||||
});
|
||||
})).then(() => {
|
||||
})).then(() => {
|
||||
return Promise.resolve(query);
|
||||
});
|
||||
}
|
||||
@@ -575,7 +559,6 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
if (!t || t.type !== 'Relation') {
|
||||
return Promise.resolve(query);
|
||||
}
|
||||
let relatedClassName = t.targetClass;
|
||||
// Build the list of queries
|
||||
let queries = Object.keys(query[key]).map((constraintKey) => {
|
||||
let relatedIds;
|
||||
@@ -625,7 +608,7 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
return Promise.resolve();
|
||||
})
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return Promise.all(promises).then(() => {
|
||||
return Promise.resolve(query);
|
||||
})
|
||||
};
|
||||
@@ -839,7 +822,7 @@ DatabaseController.prototype.deleteSchema = function(className) {
|
||||
})
|
||||
.then(schema => {
|
||||
return this.collectionExists(className)
|
||||
.then(exist => this.adapter.count(className, { fields: {} }))
|
||||
.then(() => this.adapter.count(className, { fields: {} }))
|
||||
.then(count => {
|
||||
if (count > 0) {
|
||||
throw new Parse.Error(255, `Class ${className} is not empty, contains ${count} objects, cannot drop schema.`);
|
||||
@@ -866,10 +849,10 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className,
|
||||
let perms = schema.perms[className];
|
||||
let field = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
let userACL = aclGroup.filter((acl) => {
|
||||
return acl.indexOf('role:') != 0 && acl != '*';
|
||||
return acl.indexOf('role:') != 0 && acl != '*';
|
||||
});
|
||||
// the ACL should have exactly 1 user
|
||||
if (perms && perms[field] && perms[field].length > 0) {
|
||||
if (perms && perms[field] && perms[field].length > 0) {
|
||||
// No user set return undefined
|
||||
// If the length is > 1, that means we didn't dedup users correctly
|
||||
if (userACL.length != 1) {
|
||||
@@ -877,20 +860,19 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className,
|
||||
}
|
||||
let userId = userACL[0];
|
||||
let userPointer = {
|
||||
"__type": "Pointer",
|
||||
"className": "_User",
|
||||
"objectId": userId
|
||||
};
|
||||
"__type": "Pointer",
|
||||
"className": "_User",
|
||||
"objectId": userId
|
||||
};
|
||||
|
||||
let constraints = {};
|
||||
let permFields = perms[field];
|
||||
let ors = permFields.map((key) => {
|
||||
let ors = permFields.map((key) => {
|
||||
let q = {
|
||||
[key]: userPointer
|
||||
};
|
||||
return {'$and': [q, query]};
|
||||
});
|
||||
if (ors.length > 1) {
|
||||
if (ors.length > 1) {
|
||||
return {'$or': ors};
|
||||
}
|
||||
return ors[0];
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// FilesController.js
|
||||
import { Parse } from 'parse/node';
|
||||
import { randomHexString } from '../cryptoUtils';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { FilesAdapter } from '../Adapters/Files/FilesAdapter';
|
||||
@@ -85,7 +84,7 @@ export class FilesController extends AdaptableController {
|
||||
|
||||
getFileStream(config, filename) {
|
||||
return this.adapter.getFileStream(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FilesController;
|
||||
|
||||
@@ -51,8 +51,7 @@ export class HooksController {
|
||||
return this._removeHooks({ className: className, triggerName: triggerName });
|
||||
}
|
||||
|
||||
_getHooks(query = {}, limit) {
|
||||
let options = limit ? { limit: limit } : undefined;
|
||||
_getHooks(query = {}) {
|
||||
return this.database.find(DefaultHooksCollectionName, query).then((results) => {
|
||||
return results.map((result) => {
|
||||
delete result.objectId;
|
||||
@@ -113,7 +112,7 @@ export class HooksController {
|
||||
}
|
||||
|
||||
return this.addHook(hook);
|
||||
};
|
||||
}
|
||||
|
||||
createHook(aHook) {
|
||||
if (aHook.functionName) {
|
||||
@@ -134,7 +133,7 @@ export class HooksController {
|
||||
}
|
||||
|
||||
throw new Parse.Error(143, "invalid hook declaration");
|
||||
};
|
||||
}
|
||||
|
||||
updateHook(aHook) {
|
||||
if (aHook.functionName) {
|
||||
@@ -153,7 +152,7 @@ export class HooksController {
|
||||
});
|
||||
}
|
||||
throw new Parse.Error(143, "invalid hook declaration");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function wrapToHTTPRequest(hook, key) {
|
||||
@@ -170,7 +169,7 @@ function wrapToHTTPRequest(hook, key) {
|
||||
jsonBody.original = req.original.toJSON();
|
||||
jsonBody.original.className = req.original.className;
|
||||
}
|
||||
let jsonRequest = {
|
||||
let jsonRequest: any = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
|
||||
@@ -5,7 +5,6 @@ export class LiveQueryController {
|
||||
liveQueryPublisher: any;
|
||||
|
||||
constructor(config: any) {
|
||||
let classNames;
|
||||
// If config is empty, we just assume no classs needs to be registered as LiveQuery
|
||||
if (!config || !config.classNames) {
|
||||
this.classNames = new Set();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Parse } from 'parse/node';
|
||||
import PromiseRouter from '../PromiseRouter';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { LoggerAdapter } from '../Adapters/Logger/LoggerAdapter';
|
||||
import url from 'url';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Parse } from 'parse/node';
|
||||
import PromiseRouter from '../PromiseRouter';
|
||||
import rest from '../rest';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { PushAdapter } from '../Adapters/Push/PushAdapter';
|
||||
@@ -9,7 +8,6 @@ import RestWrite from '../RestWrite';
|
||||
import { master } from '../Auth';
|
||||
import { pushStatusHandler } from '../StatusHandler';
|
||||
|
||||
const FEATURE_NAME = 'push';
|
||||
const UNSUPPORTED_BADGE_KEY = "unsupported";
|
||||
|
||||
export class PushController extends AdaptableController {
|
||||
@@ -24,7 +22,7 @@ export class PushController extends AdaptableController {
|
||||
var deviceTypes = [];
|
||||
if (typeof deviceTypeField === 'string') {
|
||||
deviceTypes.push(deviceTypeField);
|
||||
} else if (typeof deviceTypeField['$in'] === 'array') {
|
||||
} else if (Array.isArray(deviceTypeField['$in'])) {
|
||||
deviceTypes.concat(deviceTypeField['$in']);
|
||||
}
|
||||
for (var i = 0; i < deviceTypes.length; i++) {
|
||||
@@ -98,13 +96,13 @@ export class PushController extends AdaptableController {
|
||||
}).then((results) => {
|
||||
return pushStatus.complete(results);
|
||||
}).catch((err) => {
|
||||
return pushStatus.fail(err).then(() => {
|
||||
return pushStatus.fail(err).then(() => {
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
sendToAdapter(body, installations, pushStatus, config) {
|
||||
sendToAdapter(body, installations, pushStatus) {
|
||||
if (body.data && body.data.badge && typeof body.data.badge == 'string' && body.data.badge.toLowerCase() == "increment") {
|
||||
// Collect the badges to reduce the # of calls
|
||||
let badgeInstallationsMap = installations.reduce((map, installation) => {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default class SchemaCache {
|
||||
}
|
||||
|
||||
put(key, value) {
|
||||
return this.cache.get(this.prefix+ALL_KEYS).then((allKeys) => {
|
||||
return this.cache.get(this.prefix+ALL_KEYS).then((allKeys) => {
|
||||
allKeys = allKeys || {};
|
||||
allKeys[key] = true;
|
||||
return Promise.all([this.cache.put(this.prefix+ALL_KEYS, allKeys, this.ttl), this.cache.put(key, value, this.ttl)]);
|
||||
@@ -72,8 +72,7 @@ export default class SchemaCache {
|
||||
|
||||
clear() {
|
||||
// That clears all caches...
|
||||
let promise = Promise.resolve();
|
||||
return this.cache.get(this.prefix+ALL_KEYS).then((allKeys) => {
|
||||
return this.cache.get(this.prefix+ALL_KEYS).then((allKeys) => {
|
||||
if (!allKeys) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
// TODO: hide all schema logic inside the database adapter.
|
||||
|
||||
const Parse = require('parse/node').Parse;
|
||||
import _ from 'lodash';
|
||||
|
||||
const defaultColumns = Object.freeze({
|
||||
// Contain the default columns for every parse object type (except _Join collection)
|
||||
@@ -152,7 +151,7 @@ function validateCLP(perms, fields) {
|
||||
} else {
|
||||
perms[operation].forEach((key) => {
|
||||
if (!fields[key] || fields[key].type != 'Pointer' || fields[key].targetClass != '_User') {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid column for class level pointer permissions ${operation}`);
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid column for class level pointer permissions ${operation}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -222,19 +221,19 @@ const fieldTypeIsInvalid = ({ type, targetClass }) => {
|
||||
if (!targetClass) {
|
||||
return new Parse.Error(135, `type ${type} needs a class name`);
|
||||
} else if (typeof targetClass !== 'string') {
|
||||
return invalidJsonError;
|
||||
return invalidJsonError;
|
||||
} else if (!classNameIsValid(targetClass)) {
|
||||
return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass));
|
||||
} else {
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (typeof type !== 'string') {
|
||||
}
|
||||
}
|
||||
if (typeof type !== 'string') {
|
||||
return invalidJsonError;
|
||||
}
|
||||
}
|
||||
if (validNonRelationOrPointerTypes.indexOf(type) < 0) {
|
||||
return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -280,14 +279,14 @@ const injectDefaultSchema = ({className, fields, classLevelPermissions}) => ({
|
||||
const _HooksSchema = {className: "_Hooks", fields: defaultColumns._Hooks};
|
||||
const _GlobalConfigSchema = { className: "_GlobalConfig", fields: defaultColumns._GlobalConfig }
|
||||
const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
||||
className: "_PushStatus",
|
||||
fields: {},
|
||||
classLevelPermissions: {}
|
||||
className: "_PushStatus",
|
||||
fields: {},
|
||||
classLevelPermissions: {}
|
||||
}));
|
||||
const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
||||
className: "_JobStatus",
|
||||
fields: {},
|
||||
classLevelPermissions: {}
|
||||
className: "_JobStatus",
|
||||
fields: {},
|
||||
classLevelPermissions: {}
|
||||
}));
|
||||
const VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _PushStatusSchema, _GlobalConfigSchema];
|
||||
|
||||
@@ -325,7 +324,7 @@ export default class SchemaController {
|
||||
reloadData(options = {clearCache: false}) {
|
||||
let promise = Promise.resolve();
|
||||
if (options.clearCache) {
|
||||
promise = promise.then(() => {
|
||||
promise = promise.then(() => {
|
||||
return this._cache.clear();
|
||||
});
|
||||
}
|
||||
@@ -334,7 +333,7 @@ export default class SchemaController {
|
||||
}
|
||||
this.data = {};
|
||||
this.perms = {};
|
||||
this.reloadDataPromise = promise.then(() => {
|
||||
this.reloadDataPromise = promise.then(() => {
|
||||
return this.getAllClasses(options);
|
||||
})
|
||||
.then(allSchemas => {
|
||||
@@ -352,7 +351,7 @@ export default class SchemaController {
|
||||
});
|
||||
});
|
||||
delete this.reloadDataPromise;
|
||||
}, (err) => {
|
||||
}, (err) => {
|
||||
delete this.reloadDataPromise;
|
||||
throw err;
|
||||
});
|
||||
@@ -364,16 +363,16 @@ export default class SchemaController {
|
||||
if (options.clearCache) {
|
||||
promise = this._cache.clear();
|
||||
}
|
||||
return promise.then(() => {
|
||||
return this._cache.getAllClasses()
|
||||
}).then((allClasses) => {
|
||||
return promise.then(() => {
|
||||
return this._cache.getAllClasses()
|
||||
}).then((allClasses) => {
|
||||
if (allClasses && allClasses.length && !options.clearCache) {
|
||||
return Promise.resolve(allClasses);
|
||||
}
|
||||
return this._dbAdapter.getAllClasses()
|
||||
.then(allSchemas => allSchemas.map(injectDefaultSchema))
|
||||
.then(allSchemas => {
|
||||
return this._cache.setAllClasses(allSchemas).then(() => {
|
||||
return this._cache.setAllClasses(allSchemas).then(() => {
|
||||
return allSchemas;
|
||||
});
|
||||
})
|
||||
@@ -385,18 +384,18 @@ export default class SchemaController {
|
||||
if (options.clearCache) {
|
||||
promise = this._cache.clear();
|
||||
}
|
||||
return promise.then(() => {
|
||||
return promise.then(() => {
|
||||
if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) {
|
||||
return Promise.resolve(this.data[className]);
|
||||
}
|
||||
return this._cache.getOneSchema(className).then((cached) => {
|
||||
return this._cache.getOneSchema(className).then((cached) => {
|
||||
if (cached && !options.clearCache) {
|
||||
return Promise.resolve(cached);
|
||||
}
|
||||
return this._dbAdapter.getClass(className)
|
||||
.then(injectDefaultSchema)
|
||||
.then((result) => {
|
||||
return this._cache.setOneSchema(className, result).then(() => {
|
||||
.then((result) => {
|
||||
return this._cache.setOneSchema(className, result).then(() => {
|
||||
return result;
|
||||
})
|
||||
});
|
||||
@@ -419,9 +418,9 @@ export default class SchemaController {
|
||||
|
||||
return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ fields, classLevelPermissions, className }))
|
||||
.then(convertAdapterSchemaToParseSchema)
|
||||
.then((res) => {
|
||||
return this._cache.clear().then(() => {
|
||||
return Promise.resolve(res);
|
||||
.then((res) => {
|
||||
return this._cache.clear().then(() => {
|
||||
return Promise.resolve(res);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -504,7 +503,7 @@ export default class SchemaController {
|
||||
return this.addClassIfNotExists(className)
|
||||
// The schema update succeeded. Reload the schema
|
||||
.then(() => this.reloadData({ clearCache: true }))
|
||||
.catch(error => {
|
||||
.catch(() => {
|
||||
// The schema update failed. This can be okay - it might
|
||||
// have failed because there's a race condition and a different
|
||||
// client is making the exact same schema update that we want.
|
||||
@@ -519,7 +518,7 @@ export default class SchemaController {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
.catch(() => {
|
||||
// The schema still doesn't validate. Give up
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate');
|
||||
});
|
||||
@@ -586,7 +585,7 @@ export default class SchemaController {
|
||||
// object if the provided className-fieldName-type tuple is valid.
|
||||
// The className must already be validated.
|
||||
// If 'freeze' is true, refuse to update the schema for this field.
|
||||
enforceFieldExists(className, fieldName, type, freeze) {
|
||||
enforceFieldExists(className, fieldName, type) {
|
||||
if (fieldName.indexOf(".") > 0) {
|
||||
// subdocument key (x.y) => ok if x is of type 'object'
|
||||
fieldName = fieldName.split(".")[ 0 ];
|
||||
@@ -620,14 +619,14 @@ export default class SchemaController {
|
||||
return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).then(() => {
|
||||
// The update succeeded. Reload the schema
|
||||
return this.reloadData({ clearCache: true });
|
||||
}, error => {
|
||||
}, () => {
|
||||
//TODO: introspect the error and only reload if the error is one for which is makes sense to reload
|
||||
|
||||
// The update failed. This can be okay - it might have been a race
|
||||
// condition where another client updated the schema in the same
|
||||
// way that we wanted to. So, just reload the schema
|
||||
return this.reloadData({ clearCache: true });
|
||||
}).then(error => {
|
||||
}).then(() => {
|
||||
// Ensure that the schema now validates
|
||||
if (!dbTypeMatchesObjectType(this.getExpectedType(className, fieldName), type)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`);
|
||||
@@ -676,7 +675,7 @@ export default class SchemaController {
|
||||
.then(() => database.adapter.deleteClass(`_Join:${fieldName}:${className}`));
|
||||
}
|
||||
return database.adapter.deleteFields(className, schema, [fieldName]);
|
||||
}).then(() => {
|
||||
}).then(() => {
|
||||
this._cache.clear();
|
||||
});
|
||||
}
|
||||
@@ -772,7 +771,6 @@ export default class SchemaController {
|
||||
return true;
|
||||
}
|
||||
let classPerms = this.perms[className];
|
||||
let perms = classPerms[operation];
|
||||
// No matching CLP, let's check the Pointer permissions
|
||||
// And handle those later
|
||||
let permissionField = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
@@ -785,11 +783,11 @@ export default class SchemaController {
|
||||
|
||||
// Process the readUserFields later
|
||||
if (Array.isArray(classPerms[permissionField]) && classPerms[permissionField].length > 0) {
|
||||
return Promise.resolve();
|
||||
return Promise.resolve();
|
||||
}
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN,
|
||||
`Permission denied for action ${operation} on class ${className}.`);
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the expected type for a className+key combination
|
||||
// or undefined if the schema is not set
|
||||
@@ -799,7 +797,7 @@ export default class SchemaController {
|
||||
return expectedType === 'map' ? 'Object' : expectedType;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
}
|
||||
|
||||
// Checks if a given class is in the schema.
|
||||
hasClass(className) {
|
||||
@@ -859,23 +857,23 @@ function thenValidateRequiredColumns(schemaPromise, className, object, query) {
|
||||
function getType(obj) {
|
||||
let type = typeof obj;
|
||||
switch(type) {
|
||||
case 'boolean':
|
||||
return 'Boolean';
|
||||
case 'string':
|
||||
return 'String';
|
||||
case 'number':
|
||||
return 'Number';
|
||||
case 'map':
|
||||
case 'object':
|
||||
if (!obj) {
|
||||
return undefined;
|
||||
}
|
||||
return getObjectType(obj);
|
||||
case 'function':
|
||||
case 'symbol':
|
||||
case 'undefined':
|
||||
default:
|
||||
throw 'bad obj: ' + obj;
|
||||
case 'boolean':
|
||||
return 'Boolean';
|
||||
case 'string':
|
||||
return 'String';
|
||||
case 'number':
|
||||
return 'Number';
|
||||
case 'map':
|
||||
case 'object':
|
||||
if (!obj) {
|
||||
return undefined;
|
||||
}
|
||||
return getObjectType(obj);
|
||||
case 'function':
|
||||
case 'symbol':
|
||||
case 'undefined':
|
||||
default:
|
||||
throw 'bad obj: ' + obj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,63 +886,68 @@ function getObjectType(obj) {
|
||||
}
|
||||
if (obj.__type){
|
||||
switch(obj.__type) {
|
||||
case 'Pointer' :
|
||||
if(obj.className) {
|
||||
return {
|
||||
type: 'Pointer',
|
||||
targetClass: obj.className
|
||||
}
|
||||
case 'Pointer' :
|
||||
if(obj.className) {
|
||||
return {
|
||||
type: 'Pointer',
|
||||
targetClass: obj.className
|
||||
}
|
||||
case 'Relation' :
|
||||
if(obj.className) {
|
||||
return {
|
||||
type: 'Relation',
|
||||
targetClass: obj.className
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'Relation' :
|
||||
if(obj.className) {
|
||||
return {
|
||||
type: 'Relation',
|
||||
targetClass: obj.className
|
||||
}
|
||||
case 'File' :
|
||||
if(obj.name) {
|
||||
return 'File';
|
||||
}
|
||||
case 'Date' :
|
||||
if(obj.iso) {
|
||||
return 'Date';
|
||||
}
|
||||
case 'GeoPoint' :
|
||||
if(obj.latitude != null && obj.longitude != null) {
|
||||
return 'GeoPoint';
|
||||
}
|
||||
case 'Bytes' :
|
||||
if(obj.base64) {
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, "This is not a valid "+obj.__type);
|
||||
}
|
||||
break;
|
||||
case 'File' :
|
||||
if(obj.name) {
|
||||
return 'File';
|
||||
}
|
||||
break;
|
||||
case 'Date' :
|
||||
if(obj.iso) {
|
||||
return 'Date';
|
||||
}
|
||||
break;
|
||||
case 'GeoPoint' :
|
||||
if(obj.latitude != null && obj.longitude != null) {
|
||||
return 'GeoPoint';
|
||||
}
|
||||
break;
|
||||
case 'Bytes' :
|
||||
if(obj.base64) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, "This is not a valid "+obj.__type);
|
||||
}
|
||||
if (obj['$ne']) {
|
||||
return getObjectType(obj['$ne']);
|
||||
}
|
||||
if (obj.__op) {
|
||||
switch(obj.__op) {
|
||||
case 'Increment':
|
||||
return 'Number';
|
||||
case 'Delete':
|
||||
return null;
|
||||
case 'Add':
|
||||
case 'AddUnique':
|
||||
case 'Remove':
|
||||
return 'Array';
|
||||
case 'AddRelation':
|
||||
case 'RemoveRelation':
|
||||
return {
|
||||
type: 'Relation',
|
||||
targetClass: obj.objects[0].className
|
||||
}
|
||||
case 'Batch':
|
||||
return getObjectType(obj.ops[0]);
|
||||
default:
|
||||
throw 'unexpected op: ' + obj.__op;
|
||||
case 'Increment':
|
||||
return 'Number';
|
||||
case 'Delete':
|
||||
return null;
|
||||
case 'Add':
|
||||
case 'AddUnique':
|
||||
case 'Remove':
|
||||
return 'Array';
|
||||
case 'AddRelation':
|
||||
case 'RemoveRelation':
|
||||
return {
|
||||
type: 'Relation',
|
||||
targetClass: obj.objects[0].className
|
||||
}
|
||||
case 'Batch':
|
||||
return getObjectType(obj.ops[0]);
|
||||
default:
|
||||
throw 'unexpected op: ' + obj.__op;
|
||||
}
|
||||
}
|
||||
return 'Object';
|
||||
|
||||
@@ -3,10 +3,9 @@ import { inflate } from '../triggers';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import MailAdapter from '../Adapters/Email/MailAdapter';
|
||||
import rest from '../rest';
|
||||
import Parse from 'parse/node';
|
||||
|
||||
var RestWrite = require('../RestWrite');
|
||||
var RestQuery = require('../RestQuery');
|
||||
var hash = require('../password').hash;
|
||||
var Auth = require('../Auth');
|
||||
|
||||
export class UserController extends AdaptableController {
|
||||
@@ -118,7 +117,7 @@ export class UserController extends AdaptableController {
|
||||
}
|
||||
const token = encodeURIComponent(user._email_verify_token);
|
||||
// We may need to fetch the user in case of update email
|
||||
this.getUserIfNeeded(user).then((user) => {
|
||||
this.getUserIfNeeded(user).then((user) => {
|
||||
const username = encodeURIComponent(user.username);
|
||||
let link = `${this.config.verifyEmailURL}?token=${token}&username=${username}`;
|
||||
let options = {
|
||||
@@ -148,7 +147,6 @@ export class UserController extends AdaptableController {
|
||||
if (!this.adapter) {
|
||||
throw "Trying to send a reset password but no adapter is set";
|
||||
// TODO: No adapter?
|
||||
return;
|
||||
}
|
||||
|
||||
return this.setPasswordResetToken(email)
|
||||
@@ -173,7 +171,7 @@ export class UserController extends AdaptableController {
|
||||
});
|
||||
}
|
||||
|
||||
updatePassword(username, token, password, config) {
|
||||
updatePassword(username, token, password) {
|
||||
return this.checkResetTokenValidity(username, token)
|
||||
.then(user => updateUserPassword(user.objectId, password, this.config))
|
||||
// clear reset password token
|
||||
@@ -191,9 +189,9 @@ export class UserController extends AdaptableController {
|
||||
|
||||
defaultVerificationEmail({link, user, appName, }) {
|
||||
let text = "Hi,\n\n" +
|
||||
"You are being asked to confirm the e-mail address " + user.get("email") + " with " + appName + "\n\n" +
|
||||
"" +
|
||||
"Click here to confirm it:\n" + link;
|
||||
"You are being asked to confirm the e-mail address " + user.get("email") + " with " + appName + "\n\n" +
|
||||
"" +
|
||||
"Click here to confirm it:\n" + link;
|
||||
let to = user.get("email");
|
||||
let subject = 'Please verify your e-mail for ' + appName;
|
||||
return { text, to, subject };
|
||||
@@ -215,6 +213,6 @@ function updateUserPassword(userId, password, config) {
|
||||
return rest.update(config, Auth.master(config), '_User', userId, {
|
||||
password: password
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default UserController;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import Parse from 'parse/node';
|
||||
import logger from '../logger';
|
||||
|
||||
import type { FlattenedObjectData } from './Subscription';
|
||||
@@ -54,7 +53,7 @@ class Client {
|
||||
this.subscriptionInfos.set(requestId, subscriptionInfo);
|
||||
}
|
||||
|
||||
getSubscriptionInfo(requestId: numner): any {
|
||||
getSubscriptionInfo(requestId: number): any {
|
||||
return this.subscriptionInfos.get(requestId);
|
||||
}
|
||||
|
||||
|
||||
@@ -251,21 +251,21 @@ class ParseLiveQueryServer {
|
||||
}
|
||||
|
||||
switch(request.op) {
|
||||
case 'connect':
|
||||
this._handleConnect(parseWebsocket, request);
|
||||
break;
|
||||
case 'subscribe':
|
||||
this._handleSubscribe(parseWebsocket, request);
|
||||
break;
|
||||
case 'update':
|
||||
this._handleUpdateSubscription(parseWebsocket, request);
|
||||
break;
|
||||
case 'unsubscribe':
|
||||
this._handleUnsubscribe(parseWebsocket, request);
|
||||
break;
|
||||
default:
|
||||
Client.pushError(parseWebsocket, 3, 'Get unknown operation');
|
||||
logger.error('Get unknown operation', request.op);
|
||||
case 'connect':
|
||||
this._handleConnect(parseWebsocket, request);
|
||||
break;
|
||||
case 'subscribe':
|
||||
this._handleSubscribe(parseWebsocket, request);
|
||||
break;
|
||||
case 'update':
|
||||
this._handleUpdateSubscription(parseWebsocket, request);
|
||||
break;
|
||||
case 'unsubscribe':
|
||||
this._handleUnsubscribe(parseWebsocket, request);
|
||||
break;
|
||||
default:
|
||||
Client.pushError(parseWebsocket, 3, 'Get unknown operation');
|
||||
logger.error('Get unknown operation', request.op);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -335,48 +335,48 @@ class ParseLiveQueryServer {
|
||||
// Resolve false right away if the acl doesn't have any roles
|
||||
const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith("role:"));
|
||||
if (!acl_has_roles) {
|
||||
return resolve(false);
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
this.sessionTokenCache.getUserId(subscriptionSessionToken)
|
||||
.then((userId) => {
|
||||
|
||||
// Pass along a null if there is no user id
|
||||
if (!userId) {
|
||||
return Parse.Promise.as(null);
|
||||
}
|
||||
if (!userId) {
|
||||
return Parse.Promise.as(null);
|
||||
}
|
||||
|
||||
// Prepare a user object to query for roles
|
||||
// To eliminate a query for the user, create one locally with the id
|
||||
var user = new Parse.User();
|
||||
user.id = userId;
|
||||
return user;
|
||||
var user = new Parse.User();
|
||||
user.id = userId;
|
||||
return user;
|
||||
|
||||
})
|
||||
.then((user) => {
|
||||
|
||||
// Pass along an empty array (of roles) if no user
|
||||
if (!user) {
|
||||
return Parse.Promise.as([]);
|
||||
}
|
||||
if (!user) {
|
||||
return Parse.Promise.as([]);
|
||||
}
|
||||
|
||||
// Then get the user's roles
|
||||
var rolesQuery = new Parse.Query(Parse.Role);
|
||||
rolesQuery.equalTo("users", user);
|
||||
return rolesQuery.find();
|
||||
var rolesQuery = new Parse.Query(Parse.Role);
|
||||
rolesQuery.equalTo("users", user);
|
||||
return rolesQuery.find();
|
||||
}).
|
||||
then((roles) => {
|
||||
|
||||
// Finally, see if any of the user's roles allow them read access
|
||||
for (let role of roles) {
|
||||
if (acl.getRoleReadAccess(role)) {
|
||||
return resolve(true);
|
||||
}
|
||||
for (let role of roles) {
|
||||
if (acl.getRoleReadAccess(role)) {
|
||||
return resolve(true);
|
||||
}
|
||||
resolve(false);
|
||||
}
|
||||
resolve(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
reject(error);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -393,7 +393,7 @@ class ParseLiveQueryServer {
|
||||
});
|
||||
}).then((isMatched) => {
|
||||
return Parse.Promise.as(isMatched);
|
||||
}, (error) => {
|
||||
}, () => {
|
||||
return Parse.Promise.as(false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ export class ParseWebSocket {
|
||||
this.ws.on(wsType, callback);
|
||||
}
|
||||
|
||||
send(message: any, channel: string): void {
|
||||
send(message: any): void {
|
||||
this.ws.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,117 +167,118 @@ function matchesKeyConstraints(object, key, constraints) {
|
||||
compareTo = Parse._decode(key, compareTo);
|
||||
}
|
||||
switch (condition) {
|
||||
case '$lt':
|
||||
if (object[key] >= compareTo) {
|
||||
case '$lt':
|
||||
if (object[key] >= compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$lte':
|
||||
if (object[key] > compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$gt':
|
||||
if (object[key] <= compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$gte':
|
||||
if (object[key] < compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$ne':
|
||||
if (equalObjects(object[key], compareTo)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$in':
|
||||
if (compareTo.indexOf(object[key]) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$nin':
|
||||
if (compareTo.indexOf(object[key]) > -1) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$all':
|
||||
for (i = 0; i < compareTo.length; i++) {
|
||||
if (object[key].indexOf(compareTo[i]) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$lte':
|
||||
if (object[key] > compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$gt':
|
||||
if (object[key] <= compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$gte':
|
||||
if (object[key] < compareTo) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$ne':
|
||||
if (equalObjects(object[key], compareTo)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$in':
|
||||
if (compareTo.indexOf(object[key]) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$nin':
|
||||
if (compareTo.indexOf(object[key]) > -1) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$all':
|
||||
for (i = 0; i < compareTo.length; i++) {
|
||||
if (object[key].indexOf(compareTo[i]) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '$exists':
|
||||
let propertyExists = typeof object[key] !== 'undefined';
|
||||
let existenceIsRequired = constraints['$exists'];
|
||||
if (typeof constraints['$exists'] !== 'boolean') {
|
||||
}
|
||||
break;
|
||||
case '$exists': {
|
||||
let propertyExists = typeof object[key] !== 'undefined';
|
||||
let existenceIsRequired = constraints['$exists'];
|
||||
if (typeof constraints['$exists'] !== 'boolean') {
|
||||
// The SDK will never submit a non-boolean for $exists, but if someone
|
||||
// tries to submit a non-boolean for $exits outside the SDKs, just ignore it.
|
||||
break;
|
||||
}
|
||||
if ((!propertyExists && existenceIsRequired) || (propertyExists && !existenceIsRequired)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$regex':
|
||||
if (typeof compareTo === 'object') {
|
||||
return compareTo.test(object[key]);
|
||||
}
|
||||
}
|
||||
if ((!propertyExists && existenceIsRequired) || (propertyExists && !existenceIsRequired)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '$regex':
|
||||
if (typeof compareTo === 'object') {
|
||||
return compareTo.test(object[key]);
|
||||
}
|
||||
// JS doesn't support perl-style escaping
|
||||
var expString = '';
|
||||
var escapeEnd = -2;
|
||||
var escapeStart = compareTo.indexOf('\\Q');
|
||||
while (escapeStart > -1) {
|
||||
var expString = '';
|
||||
var escapeEnd = -2;
|
||||
var escapeStart = compareTo.indexOf('\\Q');
|
||||
while (escapeStart > -1) {
|
||||
// Add the unescaped portion
|
||||
expString += compareTo.substring(escapeEnd + 2, escapeStart);
|
||||
escapeEnd = compareTo.indexOf('\\E', escapeStart);
|
||||
if (escapeEnd > -1) {
|
||||
expString += compareTo.substring(escapeStart + 2, escapeEnd)
|
||||
expString += compareTo.substring(escapeEnd + 2, escapeStart);
|
||||
escapeEnd = compareTo.indexOf('\\E', escapeStart);
|
||||
if (escapeEnd > -1) {
|
||||
expString += compareTo.substring(escapeStart + 2, escapeEnd)
|
||||
.replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&');
|
||||
}
|
||||
}
|
||||
|
||||
escapeStart = compareTo.indexOf('\\Q', escapeEnd);
|
||||
}
|
||||
expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2));
|
||||
var exp = new RegExp(expString, constraints.$options || '');
|
||||
if (!exp.test(object[key])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$nearSphere':
|
||||
var distance = compareTo.radiansTo(object[key]);
|
||||
var max = constraints.$maxDistance || Infinity;
|
||||
return distance <= max;
|
||||
case '$within':
|
||||
var southWest = compareTo.$box[0];
|
||||
var northEast = compareTo.$box[1];
|
||||
if (southWest.latitude > northEast.latitude ||
|
||||
escapeStart = compareTo.indexOf('\\Q', escapeEnd);
|
||||
}
|
||||
expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2));
|
||||
var exp = new RegExp(expString, constraints.$options || '');
|
||||
if (!exp.test(object[key])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '$nearSphere':
|
||||
var distance = compareTo.radiansTo(object[key]);
|
||||
var max = constraints.$maxDistance || Infinity;
|
||||
return distance <= max;
|
||||
case '$within':
|
||||
var southWest = compareTo.$box[0];
|
||||
var northEast = compareTo.$box[1];
|
||||
if (southWest.latitude > northEast.latitude ||
|
||||
southWest.longitude > northEast.longitude) {
|
||||
// Invalid box, crosses the date line
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
object[key].latitude > southWest.latitude &&
|
||||
object[key].latitude < northEast.latitude &&
|
||||
object[key].longitude > southWest.longitude &&
|
||||
object[key].longitude < northEast.longitude
|
||||
);
|
||||
case '$options':
|
||||
);
|
||||
case '$options':
|
||||
// Not a query type, but a way to add options to $regex. Ignore and
|
||||
// avoid the default
|
||||
break;
|
||||
case '$maxDistance':
|
||||
break;
|
||||
case '$maxDistance':
|
||||
// Not a query type, but a way to add a cap to $nearSphere. Ignore and
|
||||
// avoid the default
|
||||
break;
|
||||
case '$select':
|
||||
return false;
|
||||
case '$dontSelect':
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
case '$select':
|
||||
return false;
|
||||
case '$dontSelect':
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -61,7 +61,7 @@ let subscribe = {
|
||||
'fields': {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
@@ -99,7 +99,7 @@ let update = {
|
||||
'fields': {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {matchesQuery, queryHash} from './QueryTools';
|
||||
import logger from '../logger';
|
||||
|
||||
export type FlattenedObjectData = { [attr: string]: any };
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
// ParseServer - open-source compatible API Server for Parse apps
|
||||
|
||||
var batch = require('./batch'),
|
||||
bodyParser = require('body-parser'),
|
||||
express = require('express'),
|
||||
middlewares = require('./middlewares'),
|
||||
multer = require('multer'),
|
||||
Parse = require('parse/node').Parse,
|
||||
path = require('path'),
|
||||
url = require('url'),
|
||||
authDataManager = require('./authDataManager');
|
||||
bodyParser = require('body-parser'),
|
||||
express = require('express'),
|
||||
middlewares = require('./middlewares'),
|
||||
Parse = require('parse/node').Parse,
|
||||
path = require('path'),
|
||||
url = require('url'),
|
||||
authDataManager = require('./authDataManager');
|
||||
|
||||
import defaults from './defaults';
|
||||
import * as logging from './logger';
|
||||
import AppCache from './cache';
|
||||
import Config from './Config';
|
||||
import parseServerPackage from '../package.json';
|
||||
import PromiseRouter from './PromiseRouter';
|
||||
import requiredParameter from './requiredParameter';
|
||||
import { AnalyticsRouter } from './Routers/AnalyticsRouter';
|
||||
@@ -43,7 +41,6 @@ import { PublicAPIRouter } from './Routers/PublicAPIRouter';
|
||||
import { PushController } from './Controllers/PushController';
|
||||
import { PushRouter } from './Routers/PushRouter';
|
||||
import { CloudCodeRouter } from './Routers/CloudCodeRouter';
|
||||
import { randomString } from './cryptoUtils';
|
||||
import { RolesRouter } from './Routers/RolesRouter';
|
||||
import { SchemasRouter } from './Routers/SchemasRouter';
|
||||
import { SessionsRouter } from './Routers/SessionsRouter';
|
||||
@@ -260,20 +257,20 @@ class ParseServer {
|
||||
try {
|
||||
const parsedURI = url.parse(databaseURI);
|
||||
protocol = parsedURI.protocol ? parsedURI.protocol.toLowerCase() : null;
|
||||
} catch(e) {}
|
||||
} catch(e) { /* */ }
|
||||
switch (protocol) {
|
||||
case 'postgres:':
|
||||
return new PostgresStorageAdapter({
|
||||
uri: databaseURI,
|
||||
collectionPrefix,
|
||||
databaseOptions
|
||||
});
|
||||
default:
|
||||
return new MongoStorageAdapter({
|
||||
uri: databaseURI,
|
||||
collectionPrefix,
|
||||
mongoOptions: databaseOptions,
|
||||
});
|
||||
case 'postgres:':
|
||||
return new PostgresStorageAdapter({
|
||||
uri: databaseURI,
|
||||
collectionPrefix,
|
||||
databaseOptions
|
||||
});
|
||||
default:
|
||||
return new MongoStorageAdapter({
|
||||
uri: databaseURI,
|
||||
collectionPrefix,
|
||||
mongoOptions: databaseOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +306,9 @@ class ParseServer {
|
||||
if (!process.env.TESTING) {
|
||||
process.on('uncaughtException', (err) => {
|
||||
if ( err.code === "EADDRINUSE" ) { // user-friendly message for this common error
|
||||
/* eslint-disable no-console */
|
||||
console.error(`Unable to listen on port ${err.port}. The port is already in use.`);
|
||||
/* eslint-enable no-console */
|
||||
process.exit(0);
|
||||
} else {
|
||||
throw err;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user