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
67 changes: 55 additions & 12 deletions spec/ParsePushAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ describe('ParsePushAdapter', () => {
it('can get valid push types', (done) => {
var parsePushAdapter = new ParsePushAdapter();

expect(parsePushAdapter.getValidPushTypes()).toEqual(['ios', 'android', 'fcm']);
expect(parsePushAdapter.getValidPushTypes()).toEqual(['ios', 'osx', 'tvos', 'android', 'fcm']);
done();
});

it('can classify installation', (done) => {
// Mock installations
var validPushTypes = ['ios', 'android', 'fcm'];
var validPushTypes = ['ios', 'osx', 'tvos', 'android', 'fcm'];
var installations = [
{
deviceType: 'android',
Expand All @@ -70,6 +70,14 @@ describe('ParsePushAdapter', () => {
deviceType: 'ios',
deviceToken: 'iosToken'
},
{
deviceType: 'tvos',
deviceToken: 'tvosToken'
},
{
deviceType: 'osx',
deviceToken: 'osxToken'
},
{
deviceType: 'win',
deviceToken: 'winToken'
Expand All @@ -83,21 +91,27 @@ describe('ParsePushAdapter', () => {
var deviceMap = ParsePushAdapter.classifyInstallations(installations, validPushTypes);
expect(deviceMap['android']).toEqual([makeDevice('androidToken', 'android')]);
expect(deviceMap['ios']).toEqual([makeDevice('iosToken', 'ios')]);
expect(deviceMap['osx']).toEqual([makeDevice('osxToken', 'osx')]);
expect(deviceMap['tvos']).toEqual([makeDevice('tvosToken', 'tvos')]);
expect(deviceMap['win']).toBe(undefined);
done();
});


it('can send push notifications', (done) => {
var parsePushAdapter = new ParsePushAdapter();
// Mock android ios senders
// Mock senders
var androidSender = {
send: jasmine.createSpy('send')
};
var iosSender = {
send: jasmine.createSpy('send')
};
var osxSender = {
send: jasmine.createSpy('send')
}
var senderMap = {
osx: osxSender,
ios: iosSender,
android: androidSender
};
Expand All @@ -112,6 +126,10 @@ describe('ParsePushAdapter', () => {
deviceType: 'ios',
deviceToken: 'iosToken'
},
{
deviceType: 'osx',
deviceToken: 'osxToken'
},
{
deviceType: 'win',
deviceToken: 'winToken'
Expand All @@ -136,14 +154,21 @@ describe('ParsePushAdapter', () => {
args = iosSender.send.calls.first().args;
expect(args[0]).toEqual(data);
expect(args[1]).toEqual([
makeDevice('iosToken', 'ios')
makeDevice('iosToken', 'ios'),
]);
// Check osx sender
expect(osxSender.send).toHaveBeenCalled();
args = osxSender.send.calls.first().args;
expect(args[0]).toEqual(data);
expect(args[1]).toEqual([
makeDevice('osxToken', 'osx')
]);
done();
});

it('can send push notifications by pushType and failback by deviceType', (done) => {
var parsePushAdapter = new ParsePushAdapter();
// Mock android ios senders
// Mock senders
var androidSender = {
send: jasmine.createSpy('send')
};
Expand Down Expand Up @@ -233,7 +258,15 @@ describe('ParsePushAdapter', () => {
cert: 'cert.cer',
key: 'key.pem',
production: false,
bundleId: 'bundleId'
bundleId: 'iosbundleId'
}
],
osx: [
{
cert: 'cert.cer',
key: 'key.pem',
production: false,
bundleId: 'osxbundleId'
}
]
};
Expand All @@ -244,13 +277,23 @@ describe('ParsePushAdapter', () => {
},
{
deviceType: 'ios',
deviceToken: 'c5ee8fae0a1c',
appIdentifier: 'anotherBundle'
deviceToken: '0d72a1baa92a2febd9a254cbd6584f750c70b2350af5fc9052d1d12584b738e6',
appIdentifier: 'invalidiosbundleId'
},
{
deviceType: 'ios',
deviceToken: 'c5ee8fae0a1c5805e731cf15496d5b2b3f9b9c577353d3239429d3faaee01c79',
appIdentifier: 'anotherBundle'
deviceToken: 'ff3943ed0b2090c47e5d6f07d8f202a10427941d7897fda5a6b18c6d9fd07d48',
appIdentifier: 'invalidiosbundleId'
},
{
deviceType: 'osx',
deviceToken: '5cda62a8d88eb48d9111a6c436f2e326a053eb0cd72dfc3a0893089342602235',
appIdentifier: 'invalidosxbundleId'
},
{
deviceType: 'tvos',
deviceToken: '3e72a1baa92a2febd9a254cbd6584f750c70b2350af5fc9052d1d12584b738e6',
appIdentifier: 'invalidiosbundleId' // ios and tvos share the same bundleid
},
{
deviceType: 'win',
Expand All @@ -266,8 +309,8 @@ describe('ParsePushAdapter', () => {
parsePushAdapter.send({data: {alert: 'some'}}, installations).then((results) => {
expect(Array.isArray(results)).toBe(true);

// 2x iOS, 1x android
expect(results.length).toBe(3);
// 2x iOS, 1x android, 1x osx, 1x tvos
expect(results.length).toBe(5);
results.forEach((result) => {
expect(result.transmitted).toBe(false);
expect(typeof result.device).toBe('object');
Expand Down
7 changes: 3 additions & 4 deletions src/APNS.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const LOG_PREFIX = 'parse-server-push-adapter APNS';
* @param {Boolean} args.production Specifies which environment to connect to: Production (if true) or Sandbox
*/
function APNS(args) {
// Since for ios, there maybe multiple cert/key pairs,
// typePushConfig can be an array.
let apnsArgsList = [];
if (Array.isArray(args)) {
Expand Down Expand Up @@ -74,7 +73,7 @@ function APNS(args) {
notification: notification,
transmitted: true,
device: {
deviceType: 'ios',
deviceType: device.deviceType,
deviceToken: device.token.toString('hex')
}
});
Expand Down Expand Up @@ -115,7 +114,7 @@ APNS.prototype.send = function(data, devices) {
transmitted: false,
device: {
deviceToken: device.deviceToken,
deviceType: 'ios'
deviceType: device.deviceType
},
result: {error: 'No connection available'}
});
Expand Down Expand Up @@ -177,7 +176,7 @@ function handleTransmissionError(conns, errCode, notification, apnDevice) {
status: errCode,
transmitted: false,
device: {
deviceType: 'ios',
deviceType: apnDevice.deviceType,
deviceToken: apnDevice.token.toString('hex')
}
});
Expand Down
8 changes: 5 additions & 3 deletions src/ParsePushAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class ParsePushAdapter {
supportsPushTracking = true;

constructor(pushConfig = {}) {
this.validPushTypes = ['ios', 'android', 'fcm'];
this.validPushTypes = ['ios', 'osx', 'tvos', 'android', 'fcm'];
this.senderMap = {};
// used in PushController for Dashboard Features
this.feature = {
Expand All @@ -27,6 +27,8 @@ export class ParsePushAdapter {
}
switch (pushType) {
case 'ios':
case 'tvos':
case 'osx':
this.senderMap[pushType] = new APNS(pushConfig[pushType]);
break;
case 'android':
Expand All @@ -51,8 +53,8 @@ export class ParsePushAdapter {
for (let pushType in deviceMap) {
let sender = this.senderMap[pushType];
let devices = deviceMap[pushType];
if(Array.isArray(devices) && devices.length > 0)
{

if(Array.isArray(devices) && devices.length > 0) {
if (!sender) {
log.verbose(LOG_PREFIX, `Can not find sender for push type ${pushType}, ${data}`)
let results = devices.map((device) => {
Expand Down