diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 4485412211..9a2c549c94 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -317,6 +317,45 @@ describe('PushController', () => { }); + 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); + 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!", diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 2272a708ad..8a5f864150 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -52,7 +52,6 @@ export class PushController extends AdaptableController { let badgeUpdate = () => { return Promise.resolve(); } - if (body.data && body.data.badge) { let badge = body.data.badge; let op = {}; @@ -89,10 +88,16 @@ export class PushController extends AdaptableController { }).then(() => { return rest.find(config, auth, '_Installation', where); }).then((response) => { - pushStatus.setRunning(); + if (!response.results) { + return Promise.reject({error: 'PushController: no results in query'}) + } + pushStatus.setRunning(response.results); return this.sendToAdapter(body, response.results, pushStatus, config); }).then((results) => { return pushStatus.complete(results); + }).catch((err) => { + pushStatus.fail(err); + return Promise.reject(err); }); } diff --git a/src/pushStatusHandler.js b/src/pushStatusHandler.js index 5c49be2e77..593942e56b 100644 --- a/src/pushStatusHandler.js +++ b/src/pushStatusHandler.js @@ -1,4 +1,5 @@ import { md5Hash, newObjectId } from './cryptoUtils'; +import { logger } from './logger'; export function flatten(array) { return array.reduce((memo, element) => { @@ -20,8 +21,9 @@ export default function pushStatusHandler(config) { return config.database.adaptiveCollection('_PushStatus'); } - let setInitial = function(body, where, options = {source: 'rest'}) { + let setInitial = function(body = {}, where, options = {source: 'rest'}) { let now = new Date(); + let data = body.data || {}; let object = { objectId: newObjectId(), pushTime: now.toISOString(), @@ -33,7 +35,7 @@ export default function pushStatusHandler(config) { expiry: body.expiration_time, status: "pending", numSent: 0, - pushHash: md5Hash(JSON.stringify(body.data)), + pushHash: md5Hash(JSON.stringify(data)), // lockdown! _wperm: [], _rperm: [] @@ -49,7 +51,8 @@ export default function pushStatusHandler(config) { return initialPromise; } - let setRunning = function() { + let setRunning = function(installations) { + logger.verbose('sending push to %d installations', installations.length); return initialPromise.then(() => { return collection(); }).then((collection) => { @@ -86,7 +89,7 @@ export default function pushStatusHandler(config) { return memo; }, update); } - + logger.verbose('sent push! %d success, %d failures', update.numSent, update.numFailed); return initialPromise.then(() => { return collection(); }).then((collection) => { @@ -94,9 +97,23 @@ export default function pushStatusHandler(config) { }); } + let fail = function(err) { + let update = { + errorMessage: JSON.stringify(err), + status: 'failed' + } + logger.error('error while sending push', err); + return initialPromise.then(() => { + return collection(); + }).then((collection) => { + return collection.updateOne({objectId: pushStatus.objectId}, {$set: update}); + }); + } + return Object.freeze({ setInitial, setRunning, - complete + complete, + fail }) }