Stores the _PushStatus when sending push, set pending, and running states
This commit is contained in:
@@ -222,6 +222,47 @@ describe('PushController', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('properly creates _PushStatus', (done) => {
|
||||||
|
|
||||||
|
var payload = {data: {
|
||||||
|
alert: "Hello World!",
|
||||||
|
badge: 1,
|
||||||
|
}}
|
||||||
|
|
||||||
|
var pushAdapter = {
|
||||||
|
send: function(body, installations) {
|
||||||
|
var badge = body.data.badge;
|
||||||
|
return Promise.resolve({
|
||||||
|
body: body,
|
||||||
|
installations: installations
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getValidPushTypes: function() {
|
||||||
|
return ["ios"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = new Config(Parse.applicationId);
|
||||||
|
var auth = {
|
||||||
|
isMaster: true
|
||||||
|
}
|
||||||
|
|
||||||
|
var pushController = new PushController(pushAdapter, Parse.applicationId);
|
||||||
|
pushController.sendPush(payload, {}, config, auth).then((result) => {
|
||||||
|
let query = new Parse.Query('_PushStatus');
|
||||||
|
return query.find({useMasterKey: true});
|
||||||
|
}).then((results) => {
|
||||||
|
expect(results.length).toBe(1);
|
||||||
|
let result = results[0];
|
||||||
|
expect(result.get('source')).toEqual('rest');
|
||||||
|
expect(result.get('query')).toEqual(JSON.stringify({}));
|
||||||
|
expect(result.get('payload')).toEqual(payload.data);
|
||||||
|
expect(result.get('status')).toEqual("running");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
it('should support full RESTQuery for increment', (done) => {
|
it('should support full RESTQuery for increment', (done) => {
|
||||||
var payload = {data: {
|
var payload = {data: {
|
||||||
alert: "Hello World!",
|
alert: "Hello World!",
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
//
|
//
|
||||||
// Adapter classes must implement the following functions:
|
// Adapter classes must implement the following functions:
|
||||||
// * getValidPushTypes()
|
// * getValidPushTypes()
|
||||||
// * send(devices, installations)
|
// * send(devices, installations, pushStatus)
|
||||||
//
|
//
|
||||||
// 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 {
|
export class PushAdapter {
|
||||||
send(devices, installations) { }
|
send(devices, installations, pushStatus) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of valid push types.
|
* Get an array of valid push types.
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import rest from '../rest';
|
|||||||
import AdaptableController from './AdaptableController';
|
import AdaptableController from './AdaptableController';
|
||||||
import { PushAdapter } from '../Adapters/Push/PushAdapter';
|
import { PushAdapter } from '../Adapters/Push/PushAdapter';
|
||||||
import deepcopy from 'deepcopy';
|
import deepcopy from 'deepcopy';
|
||||||
|
import { md5Hash } from '../cryptoUtils';
|
||||||
import features from '../features';
|
import features from '../features';
|
||||||
import RestQuery from '../RestQuery';
|
import RestQuery from '../RestQuery';
|
||||||
|
import RestWrite from '../RestWrite';
|
||||||
|
|
||||||
const FEATURE_NAME = 'push';
|
const FEATURE_NAME = 'push';
|
||||||
const UNSUPPORTED_BADGE_KEY = "unsupported";
|
const UNSUPPORTED_BADGE_KEY = "unsupported";
|
||||||
@@ -81,8 +83,13 @@ export class PushController extends AdaptableController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let pushStatus;
|
||||||
return badgeUpdate().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
|
return this.saveInitialPushStatus(body, where, config);
|
||||||
|
}).then((res) => {
|
||||||
|
pushStatus = res.response;
|
||||||
|
return badgeUpdate();
|
||||||
|
}).then(() => {
|
||||||
return rest.find(config, auth, '_Installation', where);
|
return rest.find(config, auth, '_Installation', where);
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
if (body.data && body.data.badge && body.data.badge == "Increment") {
|
if (body.data && body.data.badge && body.data.badge == "Increment") {
|
||||||
@@ -105,14 +112,38 @@ export class PushController extends AdaptableController {
|
|||||||
} else {
|
} else {
|
||||||
payload.data.badge = parseInt(badge);
|
payload.data.badge = parseInt(badge);
|
||||||
}
|
}
|
||||||
return pushAdapter.send(payload, badgeInstallationsMap[badge]);
|
return pushAdapter.send(payload, badgeInstallationsMap[badge], pushStatus);
|
||||||
});
|
});
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
return pushAdapter.send(body, response.results);
|
return pushAdapter.send(body, response.results, pushStatus);
|
||||||
|
}).then(() => {
|
||||||
|
return this.updatePushStatus({status: "running"}, pushStatus, config);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveInitialPushStatus(body, where, config, options = {source: 'rest'}) {
|
||||||
|
let pushStatus = {
|
||||||
|
pushTime: (new Date()).toISOString(),
|
||||||
|
query: JSON.stringify(where),
|
||||||
|
payload: body.data,
|
||||||
|
source: options.source,
|
||||||
|
title: options.title,
|
||||||
|
expiry: body.expiration_time,
|
||||||
|
status: "pending",
|
||||||
|
numSent: 0,
|
||||||
|
pushHash: md5Hash(JSON.stringify(body.data)),
|
||||||
|
ACL: new Parse.ACL() // lockdown!
|
||||||
|
}
|
||||||
|
let restWrite = new RestWrite(config, {isMaster: true},'_PushStatus',null, pushStatus);
|
||||||
|
return restWrite.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePushStatus(update, pushStatus, config) {
|
||||||
|
let restWrite = new RestWrite(config, {isMaster: true}, '_PushStatus', {objectId: pushStatus.objectId, "status": "pending"}, update);
|
||||||
|
return restWrite.execute();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get expiration time from the request body.
|
* Get expiration time from the request body.
|
||||||
* @param {Object} request A request object
|
* @param {Object} request A request object
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ var defaultColumns = {
|
|||||||
},
|
},
|
||||||
_PushStatus: {
|
_PushStatus: {
|
||||||
"pushTime": {type:'String'},
|
"pushTime": {type:'String'},
|
||||||
"source": {type:'String'}, // rest or web
|
"source": {type:'String'}, // rest or webui
|
||||||
"query": {type:'String'}, // the stringified JSON query
|
"query": {type:'String'}, // the stringified JSON query
|
||||||
"payload": {type:'Object'}, // the JSON payload,
|
"payload": {type:'Object'}, // the JSON payload,
|
||||||
"title": {type:'String'},
|
"title": {type:'String'},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
import { randomBytes } from 'crypto';
|
import { randomBytes, createHash } from 'crypto';
|
||||||
|
|
||||||
// Returns a new random hex string of the given even size.
|
// Returns a new random hex string of the given even size.
|
||||||
export function randomHexString(size: number): string {
|
export function randomHexString(size: number): string {
|
||||||
@@ -44,3 +44,7 @@ export function newObjectId(): string {
|
|||||||
export function newToken(): string {
|
export function newToken(): string {
|
||||||
return randomHexString(32);
|
return randomHexString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function md5Hash(string: string): string {
|
||||||
|
return createHash('md5').update(string).digest('hex');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user