Make push follow controller and adapter style
This commit is contained in:
@@ -2,14 +2,6 @@ var ParsePushAdapter = require('../src/Adapters/Push/ParsePushAdapter');
|
||||
|
||||
describe('ParsePushAdapter', () => {
|
||||
it('can be initialized', (done) => {
|
||||
var parsePushAdapter = new ParsePushAdapter();
|
||||
|
||||
expect(parsePushAdapter.validPushTypes).toEqual(['ios', 'android']);
|
||||
done();
|
||||
});
|
||||
|
||||
it('can initialize', (done) => {
|
||||
var parsePushAdapter = new ParsePushAdapter();
|
||||
// Make mock config
|
||||
var pushConfig = {
|
||||
android: {
|
||||
@@ -30,7 +22,7 @@ describe('ParsePushAdapter', () => {
|
||||
]
|
||||
};
|
||||
|
||||
parsePushAdapter.initialize(pushConfig);
|
||||
var parsePushAdapter = new ParsePushAdapter(pushConfig);
|
||||
// Check ios
|
||||
var iosSenders = parsePushAdapter.senders['ios'];
|
||||
expect(iosSenders.length).toBe(2);
|
||||
@@ -53,7 +45,6 @@ describe('ParsePushAdapter', () => {
|
||||
});
|
||||
|
||||
it('can throw on initializing with unsupported push type', (done) => {
|
||||
var parsePushAdapter = new ParsePushAdapter();
|
||||
// Make mock config
|
||||
var pushConfig = {
|
||||
win: {
|
||||
@@ -63,20 +54,19 @@ describe('ParsePushAdapter', () => {
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
parsePushAdapter.initialize(pushConfig)
|
||||
new ParsePushAdapter(pushConfig);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
|
||||
it('can throw on initializing with invalid pushConfig', (done) => {
|
||||
var parsePushAdapter = new ParsePushAdapter();
|
||||
// Make mock config
|
||||
var pushConfig = {
|
||||
android: 123
|
||||
};
|
||||
|
||||
expect(function() {
|
||||
parsePushAdapter.initialize(pushConfig)
|
||||
new ParsePushAdapter(pushConfig);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var push = require('../src/push');
|
||||
var PushController = require('../src/Controllers/PushController').PushController;
|
||||
|
||||
describe('push', () => {
|
||||
describe('PushController', () => {
|
||||
it('can check valid master key of request', (done) => {
|
||||
// Make mock request
|
||||
var request = {
|
||||
@@ -13,7 +13,7 @@ describe('push', () => {
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
push.validateMasterKey(request);
|
||||
PushController.validateMasterKey(request);
|
||||
}).not.toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -30,7 +30,7 @@ describe('push', () => {
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
push.validateMasterKey(request);
|
||||
PushController.validateMasterKey(request);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -43,7 +43,7 @@ describe('push', () => {
|
||||
}
|
||||
}
|
||||
|
||||
var where = push.getQueryCondition(request);
|
||||
var where = PushController.getQueryCondition(request);
|
||||
expect(where).toEqual({
|
||||
'channels': {
|
||||
'$in': ['Giants', 'Mets']
|
||||
@@ -62,7 +62,7 @@ describe('push', () => {
|
||||
}
|
||||
}
|
||||
|
||||
var where = push.getQueryCondition(request);
|
||||
var where = PushController.getQueryCondition(request);
|
||||
expect(where).toEqual({
|
||||
'injuryReports': true
|
||||
});
|
||||
@@ -77,7 +77,7 @@ describe('push', () => {
|
||||
}
|
||||
|
||||
expect(function() {
|
||||
push.getQueryCondition(request);
|
||||
PushController.getQueryCondition(request);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -96,7 +96,7 @@ describe('push', () => {
|
||||
}
|
||||
|
||||
expect(function() {
|
||||
push.getQueryCondition(request);
|
||||
PushController.getQueryCondition(request);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -108,7 +108,7 @@ describe('push', () => {
|
||||
var validPushTypes = ['ios', 'android'];
|
||||
|
||||
expect(function(){
|
||||
push.validatePushType(where, validPushTypes);
|
||||
PushController.validatePushType(where, validPushTypes);
|
||||
}).not.toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -121,7 +121,7 @@ describe('push', () => {
|
||||
var validPushTypes = ['ios', 'android'];
|
||||
|
||||
expect(function(){
|
||||
push.validatePushType(where, validPushTypes);
|
||||
PushController.validatePushType(where, validPushTypes);
|
||||
}).not.toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -136,7 +136,7 @@ describe('push', () => {
|
||||
var validPushTypes = ['ios', 'android'];
|
||||
|
||||
expect(function(){
|
||||
push.validatePushType(where, validPushTypes);
|
||||
PushController.validatePushType(where, validPushTypes);
|
||||
}).not.toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -149,7 +149,7 @@ describe('push', () => {
|
||||
var validPushTypes = ['ios', 'android'];
|
||||
|
||||
expect(function(){
|
||||
push.validatePushType(where, validPushTypes);
|
||||
PushController.validatePushType(where, validPushTypes);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -162,7 +162,7 @@ describe('push', () => {
|
||||
var validPushTypes = ['ios', 'android'];
|
||||
|
||||
expect(function(){
|
||||
push.validatePushType(where, validPushTypes);
|
||||
PushController.validatePushType(where, validPushTypes);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -176,7 +176,7 @@ describe('push', () => {
|
||||
}
|
||||
}
|
||||
|
||||
var time = push.getExpirationTime(request);
|
||||
var time = PushController.getExpirationTime(request);
|
||||
expect(time).toEqual(new Date(timeStr).valueOf());
|
||||
done();
|
||||
});
|
||||
@@ -190,7 +190,7 @@ describe('push', () => {
|
||||
}
|
||||
}
|
||||
|
||||
var time = push.getExpirationTime(request);
|
||||
var time = PushController.getExpirationTime(request);
|
||||
expect(time).toEqual(timeNumber * 1000);
|
||||
done();
|
||||
});
|
||||
@@ -204,7 +204,7 @@ describe('push', () => {
|
||||
}
|
||||
|
||||
expect(function(){
|
||||
push.getExpirationTime(request);
|
||||
PushController.getExpirationTime(request);
|
||||
}).toThrow();
|
||||
done();
|
||||
});
|
||||
@@ -7,16 +7,10 @@ const Parse = require('parse/node').Parse;
|
||||
const GCM = require('../../GCM');
|
||||
const APNS = require('../../APNS');
|
||||
|
||||
function ParsePushAdapter() {
|
||||
this.validPushTypes = ['ios', 'android'];
|
||||
this.senders = {};
|
||||
}
|
||||
function ParsePushAdapter(pushConfig) {
|
||||
this.validPushTypes = ['ios', 'android'];
|
||||
this.senders = {};
|
||||
|
||||
/**
|
||||
* Register push senders
|
||||
* @param {Object} pushConfig The push configuration which is given when parse server is initialized
|
||||
*/
|
||||
ParsePushAdapter.prototype.initialize = function(pushConfig) {
|
||||
// Initialize senders
|
||||
for (let validPushType of this.validPushTypes) {
|
||||
this.senders[validPushType] = [];
|
||||
|
||||
@@ -3,27 +3,15 @@
|
||||
// Allows you to change the push notification mechanism.
|
||||
//
|
||||
// Adapter classes must implement the following functions:
|
||||
// * initialize(pushConfig)
|
||||
// * getPushSenders(parseConfig)
|
||||
// * getValidPushTypes(parseConfig)
|
||||
// * getValidPushTypes()
|
||||
// * send(devices, installations)
|
||||
//
|
||||
// Default is ParsePushAdapter, which uses GCM for
|
||||
// android push and APNS for ios push.
|
||||
export class PushAdapter {
|
||||
send(devices, installations) { }
|
||||
|
||||
var ParsePushAdapter = require('./ParsePushAdapter');
|
||||
|
||||
var adapter = new ParsePushAdapter();
|
||||
|
||||
function setAdapter(pushAdapter) {
|
||||
adapter = pushAdapter;
|
||||
getValidPushTypes() { }
|
||||
}
|
||||
|
||||
function getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getAdapter: getAdapter,
|
||||
setAdapter: setAdapter
|
||||
};
|
||||
export default PushAdapter;
|
||||
|
||||
@@ -1,27 +1,44 @@
|
||||
// push.js
|
||||
import { Parse } from 'parse/node';
|
||||
import PromiseRouter from '../PromiseRouter';
|
||||
import rest from '../rest';
|
||||
|
||||
var Parse = require('parse/node').Parse,
|
||||
PromiseRouter = require('./PromiseRouter'),
|
||||
PushAdapter = require('./Adapters/Push/PushAdapter'),
|
||||
rest = require('./rest');
|
||||
export class PushController {
|
||||
|
||||
function handlePushWithoutQueue(req) {
|
||||
validateMasterKey(req);
|
||||
var where = getQueryCondition(req);
|
||||
var pushAdapter = PushAdapter.getAdapter();
|
||||
validatePushType(where, pushAdapter.getValidPushTypes());
|
||||
// Replace the expiration_time with a valid Unix epoch milliseconds time
|
||||
req.body['expiration_time'] = getExpirationTime(req);
|
||||
// TODO: If the req can pass the checking, we return immediately instead of waiting
|
||||
// pushes to be sent. We probably change this behaviour in the future.
|
||||
rest.find(req.config, req.auth, '_Installation', where).then(function(response) {
|
||||
return pushAdapter.send(req.body, response.results);
|
||||
});
|
||||
return Parse.Promise.as({
|
||||
response: {
|
||||
'result': true
|
||||
}
|
||||
});
|
||||
constructor(pushAdapter) {
|
||||
this._pushAdapter = pushAdapter;
|
||||
}
|
||||
|
||||
handlePOST(req) {
|
||||
if (!this._pushAdapter) {
|
||||
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED,
|
||||
'Push adapter is not availabe');
|
||||
}
|
||||
|
||||
validateMasterKey(req);
|
||||
var where = getQueryCondition(req);
|
||||
var pushAdapter = this._pushAdapter;
|
||||
validatePushType(where, pushAdapter.getValidPushTypes());
|
||||
// Replace the expiration_time with a valid Unix epoch milliseconds time
|
||||
req.body['expiration_time'] = getExpirationTime(req);
|
||||
// TODO: If the req can pass the checking, we return immediately instead of waiting
|
||||
// pushes to be sent. We probably change this behaviour in the future.
|
||||
rest.find(req.config, req.auth, '_Installation', where).then(function(response) {
|
||||
return pushAdapter.send(req.body, response.results);
|
||||
});
|
||||
return Parse.Promise.as({
|
||||
response: {
|
||||
'result': true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getExpressRouter() {
|
||||
var router = new PromiseRouter();
|
||||
router.route('POST','/push', (req) => {
|
||||
return this.handlePOST(req);
|
||||
});
|
||||
return router;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,16 +133,11 @@ function validateMasterKey(req) {
|
||||
}
|
||||
}
|
||||
|
||||
var router = new PromiseRouter();
|
||||
router.route('POST','/push', handlePushWithoutQueue);
|
||||
|
||||
module.exports = {
|
||||
router: router,
|
||||
}
|
||||
|
||||
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
||||
module.exports.getQueryCondition = getQueryCondition;
|
||||
module.exports.validateMasterKey = validateMasterKey;
|
||||
module.exports.getExpirationTime = getExpirationTime;
|
||||
module.exports.validatePushType = validatePushType;
|
||||
PushController.getQueryCondition = getQueryCondition;
|
||||
PushController.validateMasterKey = validateMasterKey;
|
||||
PushController.getExpirationTime = getExpirationTime;
|
||||
PushController.validatePushType = validatePushType;
|
||||
}
|
||||
|
||||
export default PushController;
|
||||
25
src/index.js
25
src/index.js
@@ -5,7 +5,6 @@ var batch = require('./batch'),
|
||||
cache = require('./cache'),
|
||||
DatabaseAdapter = require('./DatabaseAdapter'),
|
||||
express = require('express'),
|
||||
PushAdapter = require('./Adapters/Push/PushAdapter'),
|
||||
middlewares = require('./middlewares'),
|
||||
multer = require('multer'),
|
||||
Parse = require('parse/node').Parse,
|
||||
@@ -14,9 +13,12 @@ var batch = require('./batch'),
|
||||
|
||||
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
|
||||
import { S3Adapter } from './Adapters/Files/S3Adapter';
|
||||
|
||||
import { FilesController } from './Controllers/FilesController';
|
||||
|
||||
import ParsePushAdapter from './Adapters/Push/ParsePushAdapter';
|
||||
import { PushController } from './Controllers/PushController';
|
||||
|
||||
|
||||
// Mutate the Parse object to add the Cloud Code handlers
|
||||
addParseCloud();
|
||||
|
||||
@@ -42,6 +44,8 @@ addParseCloud();
|
||||
// "dotNetKey": optional key from Parse dashboard
|
||||
// "restAPIKey": optional key from Parse dashboard
|
||||
// "javascriptKey": optional key from Parse dashboard
|
||||
// "push": optional key from configure push
|
||||
|
||||
function ParseServer(args) {
|
||||
if (!args.appId || !args.masterKey) {
|
||||
throw 'You must provide an appId and masterKey!';
|
||||
@@ -51,8 +55,18 @@ function ParseServer(args) {
|
||||
DatabaseAdapter.setAdapter(args.databaseAdapter);
|
||||
}
|
||||
|
||||
// Make files adapter
|
||||
let filesAdapter = args.filesAdapter || new GridStoreAdapter();
|
||||
|
||||
// Make push adapter
|
||||
let pushConfig = args.push;
|
||||
let pushAdapter;
|
||||
if (pushConfig && pushConfig.adapter) {
|
||||
pushAdapter = pushConfig.adapter;
|
||||
} else if (pushConfig) {
|
||||
pushAdapter = new ParsePushAdapter(pushConfig)
|
||||
}
|
||||
|
||||
if (args.databaseURI) {
|
||||
DatabaseAdapter.setAppDatabaseURI(args.appId, args.databaseURI);
|
||||
}
|
||||
@@ -87,10 +101,6 @@ function ParseServer(args) {
|
||||
cache.apps[args.appId]['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
|
||||
}
|
||||
|
||||
// Register push senders
|
||||
var pushConfig = args.push;
|
||||
PushAdapter.getAdapter().initialize(pushConfig);
|
||||
|
||||
// Initialize the node client SDK automatically
|
||||
Parse.initialize(args.appId, args.javascriptKey || '', args.masterKey);
|
||||
if(args.serverURL) {
|
||||
@@ -122,13 +132,14 @@ function ParseServer(args) {
|
||||
router.merge(require('./sessions'));
|
||||
router.merge(require('./roles'));
|
||||
router.merge(require('./analytics'));
|
||||
router.merge(require('./push').router);
|
||||
router.merge(require('./installations'));
|
||||
router.merge(require('./functions'));
|
||||
router.merge(require('./schemas'));
|
||||
if (process.env.PARSE_EXPERIMENTAL_CONFIG_ENABLED || process.env.TESTING) {
|
||||
router.merge(require('./global_config'));
|
||||
}
|
||||
let pushController = new PushController(pushAdapter);
|
||||
router.merge(pushController.getExpressRouter());
|
||||
|
||||
batch.mountOnto(router);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user