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