Skip to content

Commit d6fd33c

Browse files
Ross Bayerflovilmart
Ross Bayer
authored andcommitted
Support incrementing push badge value by more than 1 (parse-community#4889)
* Support 'IncrementByN' badge value for higher push badge increments * Fix test * Rely on object for badge incrementation (i.e. {increment: 3}) rather than string (IncrementBy3) * For badge incrementation, utilize format similar to other operation notation
1 parent 8d56f4b commit d6fd33c

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

spec/PushController.spec.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,84 @@ describe('PushController', () => {
245245
});
246246
});
247247

248+
it('properly increment badges by more than 1', (done) => {
249+
const pushAdapter = {
250+
send: function(body, installations) {
251+
const badge = body.data.badge;
252+
installations.forEach((installation) => {
253+
expect(installation.badge).toEqual(badge);
254+
expect(installation.originalBadge + 3).toEqual(installation.badge);
255+
})
256+
return successfulTransmissions(body, installations);
257+
},
258+
getValidPushTypes: function() {
259+
return ["ios", "android"];
260+
}
261+
}
262+
const payload = {data:{
263+
alert: "Hello World!",
264+
badge: { __op: 'Increment', amount: 3 },
265+
}}
266+
const installations = [];
267+
while(installations.length != 10) {
268+
const installation = new Parse.Object("_Installation");
269+
installation.set("installationId", "installation_" + installations.length);
270+
installation.set("deviceToken","device_token_" + installations.length)
271+
installation.set("badge", installations.length);
272+
installation.set("originalBadge", installations.length);
273+
installation.set("deviceType", "ios");
274+
installations.push(installation);
275+
}
276+
277+
while(installations.length != 15) {
278+
const installation = new Parse.Object("_Installation");
279+
installation.set("installationId", "installation_" + installations.length);
280+
installation.set("deviceToken","device_token_" + installations.length);
281+
installation.set("badge", installations.length);
282+
installation.set("originalBadge", installations.length);
283+
installation.set("deviceType", "android");
284+
installations.push(installation);
285+
}
286+
const config = Config.get(Parse.applicationId);
287+
const auth = {
288+
isMaster: true
289+
}
290+
291+
const pushController = new PushController();
292+
reconfigureServer({
293+
push: { adapter: pushAdapter }
294+
}).then(() => {
295+
return Parse.Object.saveAll(installations)
296+
}).then(() => {
297+
return pushController.sendPush(payload, {}, config, auth);
298+
}).then(() => {
299+
// Wait so the push is completed.
300+
return new Promise((resolve) => { setTimeout(() => { resolve(); }, 1000); });
301+
}).then(() => {
302+
// Check we actually sent 15 pushes.
303+
const query = new Parse.Query('_PushStatus');
304+
return query.find({ useMasterKey: true })
305+
}).then((results) => {
306+
expect(results.length).toBe(1);
307+
const pushStatus = results[0];
308+
expect(pushStatus.get('numSent')).toBe(15);
309+
}).then(() => {
310+
// Check that the installations were actually updated.
311+
const query = new Parse.Query('_Installation');
312+
return query.find({ useMasterKey: true })
313+
}).then((results) => {
314+
expect(results.length).toBe(15);
315+
for (let i = 0; i < 15; i++) {
316+
const installation = results[i];
317+
expect(installation.get('badge')).toBe(parseInt(installation.get('originalBadge')) + 3);
318+
}
319+
done()
320+
}).catch((err) => {
321+
jfail(err);
322+
done();
323+
});
324+
});
325+
248326
it('properly set badges to 1', (done) => {
249327

250328
const pushAdapter = {

src/Controllers/PushController.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ export class PushController {
4444
let restUpdate = {};
4545
if (typeof badge == 'string' && badge.toLowerCase() === 'increment') {
4646
restUpdate = { badge: { __op: 'Increment', amount: 1 } }
47+
} else if (typeof badge == 'object' && typeof badge.__op == 'string' &&
48+
badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) {
49+
restUpdate = { badge: { __op: 'Increment', amount: badge.amount } }
4750
} else if (Number(badge)) {
4851
restUpdate = { badge: badge }
4952
} else {
50-
throw "Invalid value for badge, expected number or 'Increment'";
53+
throw "Invalid value for badge, expected number or 'Increment' or {increment: number}";
5154
}
5255

5356
// Force filtering on only valid device tokens

src/Push/utils.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@ import Parse from 'parse/node';
22
import deepcopy from 'deepcopy';
33

44
export function isPushIncrementing(body) {
5-
return body.data &&
6-
body.data.badge &&
7-
typeof body.data.badge == 'string' &&
8-
body.data.badge.toLowerCase() == "increment"
5+
if (!body.data || !body.data.badge) {
6+
return false;
7+
}
8+
9+
const badge = body.data.badge;
10+
if (typeof badge == 'string' && badge.toLowerCase() == "increment") {
11+
return true;
12+
}
13+
14+
return typeof badge == 'object' && typeof badge.__op == 'string' &&
15+
badge.__op.toLowerCase() == "increment" && Number(badge.amount);
916
}
1017

1118
const localizableKeys = ['alert', 'title'];

0 commit comments

Comments
 (0)