Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ const data = {
clickAction: '', // gcm for android. In ios, category will be used if not supplied
locKey: '', // gcm, apn
titleLocKey: '', // gcm, apn
locArgs: undefined, // gcm, apn
titleLocArgs: undefined, // gcm, apn
locArgs: undefined, // gcm, apn. Expected format: Stringified Array
titleLocArgs: undefined, // gcm, apn. Expected format: Stringified Array
retries: 1, // gcm, apn
encoding: '', // apn
badge: 2, // gcm for ios, apn
Expand Down Expand Up @@ -290,9 +290,9 @@ The following parameters are used to create a GCM message. See https://developer
title: data.title, // Android, iOS (Watch)
body: data.body, // Android, iOS
icon: data.icon, // Android
image: data.image, // Android
style: data.style, // Android
picture: data.picture, // Android
image: data.image, // Android
style: data.style, // Android
picture: data.picture, // Android
sound: data.sound, // Android, iOS
badge: data.badge, // iOS
tag: data.tag, // Android
Expand All @@ -302,7 +302,7 @@ The following parameters are used to create a GCM message. See https://developer
body_loc_args: data.locArgs, // Android, iOS
title_loc_key: data.titleLocKey, // Android, iOS
title_loc_args: data.titleLocArgs, // Android, iOS
android_channel_id: data.android_channel_id, // Android
android_channel_id: data.android_channel_id, // Android
},
}
```
Expand Down
19 changes: 15 additions & 4 deletions src/sendAPN.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ const getPropValueOrUndefinedIfIsSilent = (propName, data) =>
R.prop(propName)
)(data);

const toJSONorUndefined = R.tryCatch(JSON.parse, R.always(undefined));

const alertLocArgsToJSON = R.evolve({
alert: {
'title-loc-args': toJSONorUndefined,
'loc-args': toJSONorUndefined,
},
});

const getDefaultAlert = (data) => ({
title: data.title,
body: data.body,
Expand All @@ -32,13 +41,15 @@ const getDefaultAlert = (data) => ({
action: data.action,
});

const pushDataWithDefaultAlert = (data) =>
const alertOrDefault = (data) =>
R.when(
R.propSatisfies(R.isNil, 'alert'),
R.assoc('alert', getDefaultAlert(data)),
data
R.assoc('alert', getDefaultAlert(data))
);

const getParsedAlertOrDefault = (data) =>
R.pipe(alertOrDefault(data), alertLocArgsToJSON)(data);

class APN {
constructor(settings) {
try {
Expand Down Expand Up @@ -66,7 +77,7 @@ class APN {
sound: getPropValueOrUndefinedIfIsSilent('sound', data),
alert: getPropValueOrUndefinedIfIsSilent(
'alert',
pushDataWithDefaultAlert(data)
getParsedAlertOrDefault(data)
),
topic: data.topic,
category: data.category || data.clickAction,
Expand Down
122 changes: 122 additions & 0 deletions test/send/sendAPN.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ function sendOkMethod() {
expect(message.aps.sound).to.eql(data.sound);
expect(message.aps.alert.title).to.eql(data.title);
expect(message.aps.alert.body).to.equal(data.body);
expect(message.aps.alert).to.eql({
body: data.body,
title: data.title,
action: undefined,
'launch-image': undefined,
'title-loc-key': undefined,
'title-loc-args': undefined,
'loc-key': undefined,
'loc-args': undefined,
});
expect(message.priority).to.equal(10);
expect(message.payload).to.eql(data.custom);
return Promise.resolve({
Expand Down Expand Up @@ -453,6 +463,118 @@ describe('push-notifications-apn', () => {
});
});

describe('parse title-loc-args and loc-args', () => {
describe('when valid string args are passed in alert object', () => {
before(() => {
sendMethod = sinon.stub(
apn.Provider.prototype,
'send',
(message, _regIds) => {
expect(_regIds).to.be.instanceOf(Array);
_regIds.forEach((regId) => expect(regIds).to.include(regId));
expect(message).to.be.instanceOf(apn.Notification);
expect(message.aps.alert['title-loc-args']).to.deep.equal([
{ a: 1 },
]);
expect(message.aps.alert['loc-args']).to.deep.equal([{ b: 2 }]);
return Promise.resolve({
sent: _regIds,
});
}
);
});

after(() => {
sendMethod.restore();
});

it('should parse the stringified arrays to JSON', (done) => {
const locArgsData = {
...data,
alert: {
'title-loc-args': '[{"a":1}]',
'loc-args': '[{"b":2}]',
},
};
pn.send(regIds, locArgsData, (err, results) =>
testSuccess(err, results, done)
);
});
});

describe('when valid string args are passed in top-level data', () => {
before(() => {
sendMethod = sinon.stub(
apn.Provider.prototype,
'send',
(message, _regIds) => {
expect(_regIds).to.be.instanceOf(Array);
_regIds.forEach((regId) => expect(regIds).to.include(regId));
expect(message).to.be.instanceOf(apn.Notification);
expect(message.aps.alert['title-loc-args']).to.deep.equal([
{ a: 1 },
]);
expect(message.aps.alert['loc-args']).to.deep.equal([{ b: 2 }]);
return Promise.resolve({
sent: _regIds,
});
}
);
});

after(() => {
sendMethod.restore();
});

it('should parse the stringified arrays to JSON', (done) => {
const locArgsData = {
...data,
titleLocArgs: '[{"a":1}]',
locArgs: '[{"b":2}]',
};
pn.send(regIds, locArgsData, (err, results) =>
testSuccess(err, results, done)
);
});
});

describe("when args can't be parsed to JSON", () => {
before(() => {
sendMethod = sinon.stub(
apn.Provider.prototype,
'send',
(message, _regIds) => {
expect(_regIds).to.be.instanceOf(Array);
_regIds.forEach((regId) => expect(regIds).to.include(regId));
expect(message).to.be.instanceOf(apn.Notification);
expect(message.aps.alert['title-loc-args']).to.be.undefined();
expect(message.aps.alert['loc-args']).to.be.undefined();
return Promise.resolve({
sent: _regIds,
});
}
);
});

after(() => {
sendMethod.restore();
});

it('should leave the input as is', (done) => {
const invalidLocArgsData = {
...data,
alert: {
'title-loc-args': '[{a:1}]',
'loc-args': '[{b:2}]',
},
};
pn.send(regIds, invalidLocArgsData, (err, results) =>
testSuccess(err, results, done)
);
});
});
});

describe('send push notifications failure (no response message)', () => {
before(() => {
sendMethod = sendFailureMethod1();
Expand Down