Skip to content

Commit 6c0bbc5

Browse files
committed
Updates tests
1 parent 4f39d4e commit 6c0bbc5

File tree

5 files changed

+158
-70
lines changed

5 files changed

+158
-70
lines changed

spec/APNS.spec.js

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const Parse = require('parse/node');
22
const APNS = require('../src/APNS').default;
3+
const MockAPNProvider = require('./MockAPNProvider');
34

45
describe('APNS', () => {
56

@@ -46,56 +47,72 @@ describe('APNS', () => {
4647
fail('should not be reached');
4748
});
4849

49-
xit('fails to initialize without a bundleID', (done) => {
50-
const apnsArgs = {
51-
production: true,
52-
bundle: 'hello'
53-
};
54-
try {
55-
new APNS(apnsArgs);
56-
} catch(e) {
57-
expect(e.code).toBe(Parse.Error.PUSH_MISCONFIGURED);
58-
done();
59-
return;
60-
}
61-
fail('should not be reached');
50+
it('fails to initialize without a bundleID', (done) => {
51+
expect(() => {
52+
new APNS({
53+
key: new Buffer('key'),
54+
production: true,
55+
bundle: 'hello'
56+
});
57+
}).toThrow();
58+
59+
expect(() => {
60+
new APNS({
61+
cert: 'pfx',
62+
production: true,
63+
bundle: 'hello'
64+
});
65+
}).toThrow();
66+
67+
expect(() => {
68+
new APNS({
69+
pfx: new Buffer(''),
70+
production: true,
71+
bundle: 'hello'
72+
});
73+
}).toThrow();
6274
done();
6375
});
6476

6577
it('can initialize with multiple certs', (done) => {
6678
var args = [
6779
{
68-
cert: 'devCert.pem',
69-
key: 'devKey.pem',
80+
cert: '-----BEGIN CERTIFICATE-----fPEYJtQrEMXLC9JtFUJ6emXAWv2QdKu93QE+6o5htM+Eu/2oNFIEj2A71WUBu7kA-----END CERTIFICATE-----',
81+
key: new Buffer('testKey'),
7082
production: false,
7183
bundleId: 'bundleId'
7284
},
7385
{
74-
cert: 'prodCert.pem',
75-
key: 'prodKey.pem',
86+
cert: '-----BEGIN CERTIFICATE-----fPEYJtQrEMXLC9JtFUJ6emXAWv2QdKu93QE+6o5htM+Eu/2oNFIEj2A71WUBu7kA-----END CERTIFICATE-----',
87+
key: new Buffer('testKey'),
7688
production: true,
7789
bundleId: 'bundleIdAgain'
7890
}
7991
]
8092

8193
var apns = new APNS(args);
82-
expect(apns.conns.length).toBe(2);
83-
var devApnsConnection = apns.conns[1];
94+
expect(apns.providers.length).toBe(2);
95+
var devApnsConnection = apns.providers[1];
8496
expect(devApnsConnection.index).toBe(1);
85-
var devApnsOptions = devApnsConnection.options;
97+
var devApnsOptions = devApnsConnection.client.config;
8698
expect(devApnsOptions.cert).toBe(args[0].cert);
8799
expect(devApnsOptions.key).toBe(args[0].key);
88100
expect(devApnsOptions.production).toBe(args[0].production);
89-
expect(devApnsConnection.bundleId).toBe(args[0].bundleId);
101+
expect(devApnsOptions.bundleId).toBe(args[0].bundleId);
102+
expect(devApnsOptions.topic).toBe(args[0].bundleId);
103+
expect(devApnsConnection.topic).toBe(args[0].bundleId);
90104

91-
var prodApnsConnection = apns.conns[0];
105+
var prodApnsConnection = apns.providers[0];
92106
expect(prodApnsConnection.index).toBe(0);
107+
93108
// TODO: Remove this checking onec we inject APNS
94-
var prodApnsOptions = prodApnsConnection.options;
109+
var prodApnsOptions = prodApnsConnection.client.config;
95110
expect(prodApnsOptions.cert).toBe(args[1].cert);
96111
expect(prodApnsOptions.key).toBe(args[1].key);
97112
expect(prodApnsOptions.production).toBe(args[1].production);
98113
expect(prodApnsOptions.bundleId).toBe(args[1].bundleId);
114+
expect(prodApnsOptions.topic).toBe(args[1].bundleId);
115+
expect(prodApnsConnection.topic).toBe(args[1].bundleId);
99116
done();
100117
});
101118

@@ -341,8 +358,8 @@ describe('APNS', () => {
341358

342359
it('reports proper error when no conn is available', (done) => {
343360
var args = [{
344-
cert: 'prodCert.pem',
345-
key: 'prodKey.pem',
361+
cert: '-----BEGIN CERTIFICATE-----fPEYJtQrEMXLC9JtFUJ6emXAWv2QdKu93QE+6o5htM+Eu/2oNFIEj2A71WUBu7kA-----END CERTIFICATE-----',
362+
key: new Buffer('testKey'),
346363
production: true,
347364
bundleId: 'bundleId'
348365
}];
@@ -362,11 +379,39 @@ describe('APNS', () => {
362379
expect(results.length).toBe(1);
363380
let result = results[0];
364381
expect(result.transmitted).toBe(false);
365-
expect(result.result.error).toBe('No connection available');
382+
expect(result.response.error).toBe('No Provider found');
366383
done();
367384
}, (err) => {
368385
fail('should not fail');
369386
done();
370387
})
371-
})
388+
});
389+
390+
it('properly parses errors', (done) => {
391+
APNS._handlePushFailure({
392+
device: 'abcd',
393+
status: -1,
394+
response: {
395+
reason: 'Something wrong happend'
396+
}
397+
}).then((result) => {
398+
expect(result.transmitted).toBe(false);
399+
expect(result.device.deviceToken).toBe('abcd');
400+
expect(result.device.deviceType).toBe('ios');
401+
expect(result.response.error).toBe('Something wrong happend');
402+
done();
403+
})
404+
});
405+
406+
it('properly parses errors again', (done) => {
407+
APNS._handlePushFailure({
408+
device: 'abcd',
409+
}).then((result) => {
410+
expect(result.transmitted).toBe(false);
411+
expect(result.device.deviceToken).toBe('abcd');
412+
expect(result.device.deviceType).toBe('ios');
413+
expect(result.response.error).toBe('Unkown status');
414+
done();
415+
})
416+
});
372417
});

spec/MockAPNConnection.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

spec/MockAPNProvider.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const EventEmitter = require('events');
2+
3+
const MockAPNProvider = function (args) {
4+
let emitter = new EventEmitter();
5+
emitter.options = args;
6+
emitter.send = function(push, devices) {
7+
if (!Array.isArray(devices)) {
8+
devices = [devices];
9+
}
10+
let sent = [];
11+
let failed = [];
12+
13+
devices.forEach((device) => {
14+
if (args.shouldFailTransmissions) {
15+
if (args.errorBuilder) {
16+
failed.push()
17+
} else {
18+
failed.push({
19+
error: "Something went wrong",
20+
status: -1,
21+
device
22+
});
23+
}
24+
} else {
25+
sent.push({
26+
device
27+
});
28+
}
29+
})
30+
return Promise.resolve({ sent, failed });
31+
};
32+
return emitter;
33+
}
34+
35+
const makeError = function(device) {
36+
return {
37+
error: "Something went wrong",
38+
status: -1,
39+
device
40+
}
41+
};
42+
43+
MockAPNProvider.makeError = makeError;
44+
MockAPNProvider.restore = function() {
45+
MockAPNProvider.makeError = makeError;
46+
}
47+
48+
module.exports = MockAPNProvider;

spec/ParsePushAdapter.spec.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ var ParsePushAdapter = ParsePushAdapterPackage.ParsePushAdapter;
33
var randomString = require('../src/PushAdapterUtils').randomString;
44
var APNS = require('../src/APNS').default;
55
var GCM = require('../src/GCM').default;
6-
var MockAPNConnection = require('./MockAPNConnection');
6+
var MockAPNProvider = require('./MockAPNProvider');
77

88
describe('ParsePushAdapter', () => {
99

1010
beforeEach(() => {
11-
jasmine.mockLibrary('apn', 'Connection', MockAPNConnection);
11+
jasmine.mockLibrary('apn', 'Provider', MockAPNProvider);
1212
});
1313

1414
afterEach(() => {
15-
jasmine.restoreLibrary('apn', 'Connection');
15+
jasmine.restoreLibrary('apn', 'Provider');
1616
});
1717

1818
it('properly export the module', () => {
@@ -278,17 +278,15 @@ describe('ParsePushAdapter', () => {
278278
cert: new Buffer('testCert'),
279279
key: new Buffer('testKey'),
280280
production: false,
281-
bundleId: 'iosbundleId',
282-
topic: 'topic'
281+
topic: 'iosbundleId'
283282
}
284283
],
285284
osx: [
286285
{
287286
cert: 'cert.cer',
288287
key: 'key.pem',
289288
production: false,
290-
bundleId: 'osxbundleId',
291-
topic: 'topic2'
289+
topic: 'osxbundleId'
292290
}
293291
]
294292
};
@@ -391,15 +389,16 @@ describe('ParsePushAdapter', () => {
391389
expect(typeof device.deviceType).toBe('string');
392390
expect(typeof device.deviceToken).toBe('string');
393391
expect(result.transmitted).toBe(false);
394-
expect(result.response.error.indexOf('APNS can not find vaild connection for ')).toBe(0);
392+
expect(typeof result.response.error).toBe('string');
395393
done();
396394
}).catch((err) => {
397395
fail('Should not fail');
398396
done();
399397
})
400398
});
401399

402-
it('reports properly select connection', (done) => {
400+
// Xited till we can retry on other connections
401+
xit('reports properly select connection', (done) => {
403402
var pushConfig = {
404403
ios: [
405404
{

src/APNS.js

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class APNS {
2424
* @param {String} args.bundleId DEPRECATED: Specifies an App-ID for this Provider
2525
* @param {Number} args.connectionRetryLimit The maximum number of connection failures that will be tolerated before apn.Provider will "give up". (Defaults to: 3)
2626
*/
27-
constructor(args = []) {
27+
constructor(args) {
2828
// Define class members
2929
this.providers = [];
3030

@@ -102,20 +102,30 @@ export class APNS {
102102
allPromises.push(promise);
103103
}
104104

105-
return Promise.all(allPromises);
105+
return Promise.all(allPromises).then((results) => {
106+
// flatten all
107+
return [].concat.apply([], results);
108+
});
109+
}
110+
111+
static _validateAPNArgs(apnsArgs) {
112+
if (apnsArgs.topic) {
113+
return true;
114+
}
115+
return !(apnsArgs.cert || apnsArgs.key || apnsArgs.pfx);
106116
}
107117

108118
/**
109119
* Creates an Provider base on apnsArgs.
110120
*/
111121
static _createProvider(apnsArgs) {
112-
let provider = new apn.Provider(apnsArgs);
113-
114122
// if using certificate, then topic must be defined
115-
if ((apnsArgs.cert || apnsArgs.key || apnsArgs.pfx) && !apnsArgs.topic) {
123+
if (!APNS._validateAPNArgs(apnsArgs)) {
116124
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'topic is mssing for %j', apnsArgs);
117125
}
118126

127+
let provider = new apn.Provider(apnsArgs);
128+
119129
// Sets the topic on this provider
120130
provider.topic = apnsArgs.topic;
121131

@@ -203,17 +213,24 @@ export class APNS {
203213
promises.push(APNS._createSuccesfullPromise(token.device));
204214
});
205215
response.failed.forEach((failure) => {
206-
if (failure.error) {
207-
log.error(LOG_PREFIX, 'APNS error transmitting to device %s with error %s', failure.device, failure.error);
208-
promises.push(APNS._createErrorPromise(failure.device, failure.error));
209-
} else if (failure.status && failure.response && failure.response.reason) {
210-
log.error(LOG_PREFIX, 'APNS error transmitting to device %s with status %s and reason %s', failure.device, failure.status, failure.response.reason);
211-
promises.push(APNS._createErrorPromise(failure.device, failure.response.reason));
212-
}
216+
promises.push(APNS._handlePushFailure(failure));
213217
});
214218
return Promise.all(promises);
215219
}
216220

221+
static _handlePushFailure(failure) {
222+
if (failure.error) {
223+
log.error(LOG_PREFIX, 'APNS error transmitting to device %s with error %s', failure.device, failure.error);
224+
return APNS._createErrorPromise(failure.device, failure.error);
225+
} else if (failure.status && failure.response && failure.response.reason) {
226+
log.error(LOG_PREFIX, 'APNS error transmitting to device %s with status %s and reason %s', failure.device, failure.status, failure.response.reason);
227+
return APNS._createErrorPromise(failure.device, failure.response.reason);
228+
} else {
229+
log.error(LOG_PREFIX, 'APNS error transmitting to device with unkown error');
230+
return APNS._createErrorPromise(failure.device, 'Unkown status');
231+
}
232+
}
233+
217234
/**
218235
* Creates an errorPromise for return.
219236
*
@@ -227,7 +244,7 @@ export class APNS {
227244
deviceToken: token,
228245
deviceType: 'ios'
229246
},
230-
result: { error: errorMessage }
247+
response: { error: errorMessage }
231248
});
232249
}
233250

0 commit comments

Comments
 (0)