From e7dd4d96488dd3cda6a73d2d749aa67fb79417d4 Mon Sep 17 00:00:00 2001 From: Ross David Bayer Date: Wed, 11 Jul 2018 19:15:54 -0700 Subject: [PATCH 1/4] Support 'IncrementByN' badge value for higher push badge increments --- spec/PushController.spec.js | 78 +++++++++++++++++++++++++++++++ src/Controllers/PushController.js | 7 ++- src/Push/utils.js | 17 +++++-- 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 2f25fa1bed..0d59318e6b 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -245,6 +245,84 @@ describe('PushController', () => { }); }); + it('properly increment badges by more than 1', (done) => { + const pushAdapter = { + send: function(body, installations) { + const badge = body.data.badge; + installations.forEach((installation) => { + expect(installation.badge).toEqual(badge); + expect(installation.originalBadge + 1).toEqual(installation.badge); + }) + return successfulTransmissions(body, installations); + }, + getValidPushTypes: function() { + return ["ios", "android"]; + } + } + const payload = {data:{ + alert: "Hello World!", + badge: "IncrementBy3", + }} + const installations = []; + while(installations.length != 10) { + const 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) { + const 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", "android"); + installations.push(installation); + } + const config = Config.get(Parse.applicationId); + const auth = { + isMaster: true + } + + const pushController = new PushController(); + reconfigureServer({ + push: { adapter: pushAdapter } + }).then(() => { + return Parse.Object.saveAll(installations) + }).then(() => { + return pushController.sendPush(payload, {}, config, auth); + }).then(() => { + // Wait so the push is completed. + return new Promise((resolve) => { setTimeout(() => { resolve(); }, 1000); }); + }).then(() => { + // Check we actually sent 15 pushes. + const query = new Parse.Query('_PushStatus'); + return query.find({ useMasterKey: true }) + }).then((results) => { + expect(results.length).toBe(1); + const pushStatus = results[0]; + expect(pushStatus.get('numSent')).toBe(15); + }).then(() => { + // Check that the installations were actually updated. + const query = new Parse.Query('_Installation'); + return query.find({ useMasterKey: true }) + }).then((results) => { + expect(results.length).toBe(15); + for (let i = 0; i < 15; i++) { + const installation = results[i]; + expect(installation.get('badge')).toBe(parseInt(installation.get('originalBadge')) + 3); + } + done() + }).catch((err) => { + jfail(err); + done(); + }); + }); + it('properly set badges to 1', (done) => { const pushAdapter = { diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 416b0ea4ff..34220c5a28 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -41,13 +41,18 @@ export class PushController { if (body.data && body.data.badge) { const badge = body.data.badge; + const incrementby = 'incrementby'; // make a variable to reduce likelihood of a typo below let restUpdate = {}; if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { restUpdate = { badge: { __op: 'Increment', amount: 1 } } + } else if (typeof badge == 'string' && badge.toLowerCase().startsWith(incrementby) && + parseInt(badge.substring(incrementby.length), 10) == badge.substring(incrementby.length) && + parseInt(badge.substring(incrementby.length), 10) > 0) { + restUpdate = { badge: { __op: 'Increment', amount: parseInt(badge.substring(incrementby.length), 10) } } } else if (Number(badge)) { restUpdate = { badge: badge } } else { - throw "Invalid value for badge, expected number or 'Increment'"; + throw "Invalid value for badge, expected number or 'Increment' or 'IncrementByN' (where N is a +ve integer)"; } // Force filtering on only valid device tokens diff --git a/src/Push/utils.js b/src/Push/utils.js index ed33a66a14..fbb4ab3b0d 100644 --- a/src/Push/utils.js +++ b/src/Push/utils.js @@ -2,10 +2,19 @@ import Parse from 'parse/node'; import deepcopy from 'deepcopy'; export function isPushIncrementing(body) { - return body.data && - body.data.badge && - typeof body.data.badge == 'string' && - body.data.badge.toLowerCase() == "increment" + if (!body.data || !body.data.badge || typeof body.data.badge != 'string') { + return false; + } + + const badge = body.data.badge; + if (badge.toLowerCase() == "increment") { + return true; + } + + const incrementby = 'incrementby'; // make a variable to reduce likelihood of a typo below + return badge.toLowerCase().startsWith(incrementby) && + parseInt(badge.substring(incrementby.length), 10) == badge.substring(incrementby.length) && + parseInt(badge.substring(incrementby.length), 10) > 0; } const localizableKeys = ['alert', 'title']; From 0f5b3393f11b75972c4de69be511d4e03626ec65 Mon Sep 17 00:00:00 2001 From: Ross David Bayer Date: Wed, 11 Jul 2018 19:35:38 -0700 Subject: [PATCH 2/4] Fix test --- spec/PushController.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 0d59318e6b..dd0ce8a945 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -251,7 +251,7 @@ describe('PushController', () => { const badge = body.data.badge; installations.forEach((installation) => { expect(installation.badge).toEqual(badge); - expect(installation.originalBadge + 1).toEqual(installation.badge); + expect(installation.originalBadge + 3).toEqual(installation.badge); }) return successfulTransmissions(body, installations); }, From db9adb8b326a0f851d95907701a45ce65df88d7a Mon Sep 17 00:00:00 2001 From: Ross David Bayer Date: Wed, 11 Jul 2018 22:26:11 -0700 Subject: [PATCH 3/4] Rely on object for badge incrementation (i.e. {increment: 3}) rather than string (IncrementBy3) --- spec/PushController.spec.js | 2 +- src/Controllers/PushController.js | 9 +++------ src/Push/utils.js | 9 +++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index dd0ce8a945..11116823d0 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -261,7 +261,7 @@ describe('PushController', () => { } const payload = {data:{ alert: "Hello World!", - badge: "IncrementBy3", + badge: {increment: 3}, }} const installations = []; while(installations.length != 10) { diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 34220c5a28..479c552044 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -41,18 +41,15 @@ export class PushController { if (body.data && body.data.badge) { const badge = body.data.badge; - const incrementby = 'incrementby'; // make a variable to reduce likelihood of a typo below let restUpdate = {}; if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { restUpdate = { badge: { __op: 'Increment', amount: 1 } } - } else if (typeof badge == 'string' && badge.toLowerCase().startsWith(incrementby) && - parseInt(badge.substring(incrementby.length), 10) == badge.substring(incrementby.length) && - parseInt(badge.substring(incrementby.length), 10) > 0) { - restUpdate = { badge: { __op: 'Increment', amount: parseInt(badge.substring(incrementby.length), 10) } } + } else if (typeof badge == 'object' && 'increment' in badge && Number(badge.increment)) { + restUpdate = { badge: { __op: 'Increment', amount: badge.increment } } } else if (Number(badge)) { restUpdate = { badge: badge } } else { - throw "Invalid value for badge, expected number or 'Increment' or 'IncrementByN' (where N is a +ve integer)"; + throw "Invalid value for badge, expected number or 'Increment' or {increment: number}"; } // Force filtering on only valid device tokens diff --git a/src/Push/utils.js b/src/Push/utils.js index fbb4ab3b0d..32d1535e98 100644 --- a/src/Push/utils.js +++ b/src/Push/utils.js @@ -2,19 +2,16 @@ import Parse from 'parse/node'; import deepcopy from 'deepcopy'; export function isPushIncrementing(body) { - if (!body.data || !body.data.badge || typeof body.data.badge != 'string') { + if (!body.data || !body.data.badge) { return false; } const badge = body.data.badge; - if (badge.toLowerCase() == "increment") { + if (typeof badge == 'string' && badge.toLowerCase() == "increment") { return true; } - const incrementby = 'incrementby'; // make a variable to reduce likelihood of a typo below - return badge.toLowerCase().startsWith(incrementby) && - parseInt(badge.substring(incrementby.length), 10) == badge.substring(incrementby.length) && - parseInt(badge.substring(incrementby.length), 10) > 0; + return typeof badge == 'object' && 'increment' in badge && Number(badge.increment); } const localizableKeys = ['alert', 'title']; From ba86f9cc4f44ddf14f4882297276a291aed4308f Mon Sep 17 00:00:00 2001 From: Ross David Bayer Date: Thu, 12 Jul 2018 10:44:12 -0700 Subject: [PATCH 4/4] For badge incrementation, utilize format similar to other operation notation --- spec/PushController.spec.js | 2 +- src/Controllers/PushController.js | 5 +++-- src/Push/utils.js | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 11116823d0..059f0d6632 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -261,7 +261,7 @@ describe('PushController', () => { } const payload = {data:{ alert: "Hello World!", - badge: {increment: 3}, + badge: { __op: 'Increment', amount: 3 }, }} const installations = []; while(installations.length != 10) { diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 479c552044..8b645a3680 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -44,8 +44,9 @@ export class PushController { let restUpdate = {}; if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { restUpdate = { badge: { __op: 'Increment', amount: 1 } } - } else if (typeof badge == 'object' && 'increment' in badge && Number(badge.increment)) { - restUpdate = { badge: { __op: 'Increment', amount: badge.increment } } + } else if (typeof badge == 'object' && typeof badge.__op == 'string' && + badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) { + restUpdate = { badge: { __op: 'Increment', amount: badge.amount } } } else if (Number(badge)) { restUpdate = { badge: badge } } else { diff --git a/src/Push/utils.js b/src/Push/utils.js index 32d1535e98..f9b1a4118f 100644 --- a/src/Push/utils.js +++ b/src/Push/utils.js @@ -11,7 +11,8 @@ export function isPushIncrementing(body) { return true; } - return typeof badge == 'object' && 'increment' in badge && Number(badge.increment); + return typeof badge == 'object' && typeof badge.__op == 'string' && + badge.__op.toLowerCase() == "increment" && Number(badge.amount); } const localizableKeys = ['alert', 'title'];