Skip to content

Commit dad50d1

Browse files
committed
Upgrade APNS to use HTTP/2
- uses universal certificate - removes tests logs - standardized returned promises from APNS and GCM to something usable in _PushStatus
1 parent a392c08 commit dad50d1

13 files changed

+316
-463
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
],
1919
"license": "BSD-3-Clause",
2020
"dependencies": {
21-
"apn": "^1.7.5",
2221
"aws-sdk": "~2.2.33",
2322
"babel-polyfill": "^6.5.0",
2423
"babel-runtime": "^6.5.0",
@@ -29,6 +28,7 @@
2928
"deepcopy": "^0.6.1",
3029
"express": "^4.13.4",
3130
"gcloud": "^0.28.0",
31+
"http2": "^3.3.2",
3232
"mailgun-js": "^0.7.7",
3333
"mime": "^1.3.4",
3434
"mongodb": "~2.1.0",

spec/APNS.spec.js

Lines changed: 45 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use strict';
12
var APNS = require('../src/APNS');
23

34
describe('APNS', () => {
@@ -9,17 +10,13 @@ describe('APNS', () => {
910
production: true,
1011
bundleId: 'bundleId'
1112
}
12-
var apns = new APNS(args);
13+
var apns = APNS(args);
1314

14-
expect(apns.conns.length).toBe(1);
15-
var apnsConnection = apns.conns[0];
16-
expect(apnsConnection.index).toBe(0);
17-
expect(apnsConnection.bundleId).toBe(args.bundleId);
18-
// TODO: Remove this checking onec we inject APNS
19-
var prodApnsOptions = apnsConnection.options;
20-
expect(prodApnsOptions.cert).toBe(args.cert);
21-
expect(prodApnsOptions.key).toBe(args.key);
22-
expect(prodApnsOptions.production).toBe(args.production);
15+
var apnsConfiguration = apns.getConfiguration();
16+
expect(apnsConfiguration.bundleId).toBe(args.bundleId);
17+
expect(apnsConfiguration.cert).toBe(args.cert);
18+
expect(apnsConfiguration.key).toBe(args.key);
19+
expect(apnsConfiguration.production).toBe(args.production);
2320
done();
2421
});
2522

@@ -39,24 +36,18 @@ describe('APNS', () => {
3936
}
4037
]
4138

42-
var apns = new APNS(args);
43-
expect(apns.conns.length).toBe(2);
44-
var devApnsConnection = apns.conns[1];
45-
expect(devApnsConnection.index).toBe(1);
46-
var devApnsOptions = devApnsConnection.options;
47-
expect(devApnsOptions.cert).toBe(args[0].cert);
48-
expect(devApnsOptions.key).toBe(args[0].key);
49-
expect(devApnsOptions.production).toBe(args[0].production);
50-
expect(devApnsConnection.bundleId).toBe(args[0].bundleId);
51-
52-
var prodApnsConnection = apns.conns[0];
53-
expect(prodApnsConnection.index).toBe(0);
54-
// TODO: Remove this checking onec we inject APNS
55-
var prodApnsOptions = prodApnsConnection.options;
56-
expect(prodApnsOptions.cert).toBe(args[1].cert);
57-
expect(prodApnsOptions.key).toBe(args[1].key);
58-
expect(prodApnsOptions.production).toBe(args[1].production);
59-
expect(prodApnsOptions.bundleId).toBe(args[1].bundleId);
39+
var apns = APNS(args);
40+
var devApnsConfiguration = apns.getConfiguration('bundleId');
41+
expect(devApnsConfiguration.cert).toBe(args[0].cert);
42+
expect(devApnsConfiguration.key).toBe(args[0].key);
43+
expect(devApnsConfiguration.production).toBe(args[0].production);
44+
expect(devApnsConfiguration.bundleId).toBe(args[0].bundleId);
45+
46+
var prodApnsConfiguration = apns.getConfiguration('bundleIdAgain');
47+
expect(prodApnsConfiguration.cert).toBe(args[1].cert);
48+
expect(prodApnsConfiguration.key).toBe(args[1].key);
49+
expect(prodApnsConfiguration.production).toBe(args[1].production);
50+
expect(prodApnsConfiguration.bundleId).toBe(args[1].bundleId);
6051
done();
6152
});
6253

@@ -73,64 +64,22 @@ describe('APNS', () => {
7364
};
7465
var expirationTime = 1454571491354
7566

76-
var notification = APNS.generateNotification(data, expirationTime);
77-
78-
expect(notification.alert).toEqual(data.alert);
79-
expect(notification.badge).toEqual(data.badge);
80-
expect(notification.sound).toEqual(data.sound);
81-
expect(notification.contentAvailable).toEqual(1);
82-
expect(notification.category).toEqual(data.category);
83-
expect(notification.payload).toEqual({
84-
'key': 'value',
85-
'keyAgain': 'valueAgain'
86-
});
87-
expect(notification.expiry).toEqual(expirationTime);
88-
done();
89-
});
90-
91-
it('can choose conns for device without appIdentifier', (done) => {
92-
// Mock conns
93-
var conns = [
94-
{
95-
bundleId: 'bundleId'
96-
},
97-
{
98-
bundleId: 'bundleIdAgain'
99-
}
100-
];
101-
// Mock device
102-
var device = {};
103-
104-
var qualifiedConns = APNS.chooseConns(conns, device);
105-
expect(qualifiedConns).toEqual([0, 1]);
106-
done();
107-
});
108-
109-
it('can choose conns for device with valid appIdentifier', (done) => {
110-
// Mock conns
111-
var conns = [
112-
{
113-
bundleId: 'bundleId'
114-
},
115-
{
116-
bundleId: 'bundleIdAgain'
117-
}
118-
];
119-
// Mock device
120-
var device = {
121-
appIdentifier: 'bundleId'
122-
};
123-
124-
var qualifiedConns = APNS.chooseConns(conns, device);
125-
expect(qualifiedConns).toEqual([0]);
67+
var notification = APNS.generateNotification(data);
68+
expect(notification.aps.alert).toEqual(data.alert);
69+
expect(notification.aps.badge).toEqual(data.badge);
70+
expect(notification.aps.sound).toEqual(data.sound);
71+
expect(notification.aps['content-available']).toEqual(1);
72+
expect(notification.aps.category).toEqual(data.category);
73+
expect(notification.key).toEqual('value');
74+
expect(notification.keyAgain).toEqual('valueAgain');
12675
done();
12776
});
12877

12978
it('can choose conns for device with invalid appIdentifier', (done) => {
13079
// Mock conns
13180
var conns = [
13281
{
133-
bundleId: 'bundleId'
82+
bundleId: 'bundleId',
13483
},
13584
{
13685
bundleId: 'bundleIdAgain'
@@ -140,143 +89,18 @@ describe('APNS', () => {
14089
var device = {
14190
appIdentifier: 'invalid'
14291
};
143-
144-
var qualifiedConns = APNS.chooseConns(conns, device);
145-
expect(qualifiedConns).toEqual([]);
146-
done();
147-
});
148-
149-
it('can handle transmission error when notification is not in cache or device is missing', (done) => {
150-
// Mock conns
151-
var conns = [];
152-
var errorCode = 1;
153-
var notification = undefined;
154-
var device = {};
155-
156-
APNS.handleTransmissionError(conns, errorCode, notification, device);
157-
158-
var notification = {};
159-
var device = undefined;
160-
161-
APNS.handleTransmissionError(conns, errorCode, notification, device);
162-
done();
163-
});
164-
165-
it('can handle transmission error when there are other qualified conns', (done) => {
166-
// Mock conns
167-
var conns = [
168-
{
169-
pushNotification: jasmine.createSpy('pushNotification'),
170-
bundleId: 'bundleId1'
171-
},
172-
{
173-
pushNotification: jasmine.createSpy('pushNotification'),
174-
bundleId: 'bundleId1'
175-
},
176-
{
177-
pushNotification: jasmine.createSpy('pushNotification'),
178-
bundleId: 'bundleId2'
179-
},
180-
];
181-
var errorCode = 1;
182-
var notification = {};
183-
var apnDevice = {
184-
connIndex: 0,
185-
appIdentifier: 'bundleId1'
186-
};
187-
188-
APNS.handleTransmissionError(conns, errorCode, notification, apnDevice);
189-
190-
expect(conns[0].pushNotification).not.toHaveBeenCalled();
191-
expect(conns[1].pushNotification).toHaveBeenCalled();
192-
expect(conns[2].pushNotification).not.toHaveBeenCalled();
193-
done();
194-
});
195-
196-
it('can handle transmission error when there is no other qualified conns', (done) => {
197-
// Mock conns
198-
var conns = [
199-
{
200-
pushNotification: jasmine.createSpy('pushNotification'),
201-
bundleId: 'bundleId1'
202-
},
203-
{
204-
pushNotification: jasmine.createSpy('pushNotification'),
205-
bundleId: 'bundleId1'
206-
},
207-
{
208-
pushNotification: jasmine.createSpy('pushNotification'),
209-
bundleId: 'bundleId1'
210-
},
211-
{
212-
pushNotification: jasmine.createSpy('pushNotification'),
213-
bundleId: 'bundleId2'
214-
},
215-
{
216-
pushNotification: jasmine.createSpy('pushNotification'),
217-
bundleId: 'bundleId1'
218-
}
219-
];
220-
var errorCode = 1;
221-
var notification = {};
222-
var apnDevice = {
223-
connIndex: 2,
224-
appIdentifier: 'bundleId1'
225-
};
226-
227-
APNS.handleTransmissionError(conns, errorCode, notification, apnDevice);
228-
229-
expect(conns[0].pushNotification).not.toHaveBeenCalled();
230-
expect(conns[1].pushNotification).not.toHaveBeenCalled();
231-
expect(conns[2].pushNotification).not.toHaveBeenCalled();
232-
expect(conns[3].pushNotification).not.toHaveBeenCalled();
233-
expect(conns[4].pushNotification).toHaveBeenCalled();
234-
done();
235-
});
236-
237-
it('can handle transmission error when device has no appIdentifier', (done) => {
238-
// Mock conns
239-
var conns = [
240-
{
241-
pushNotification: jasmine.createSpy('pushNotification'),
242-
bundleId: 'bundleId1'
243-
},
244-
{
245-
pushNotification: jasmine.createSpy('pushNotification'),
246-
bundleId: 'bundleId2'
247-
},
248-
{
249-
pushNotification: jasmine.createSpy('pushNotification'),
250-
bundleId: 'bundleId3'
251-
},
252-
];
253-
var errorCode = 1;
254-
var notification = {};
255-
var apnDevice = {
256-
connIndex: 1,
257-
};
258-
259-
APNS.handleTransmissionError(conns, errorCode, notification, apnDevice);
260-
261-
expect(conns[0].pushNotification).not.toHaveBeenCalled();
262-
expect(conns[1].pushNotification).not.toHaveBeenCalled();
263-
expect(conns[2].pushNotification).toHaveBeenCalled();
92+
let apns = APNS(conns);
93+
var config = apns.getConfiguration(device.appIdentifier);
94+
expect(config).toBeUndefined();
26495
done();
26596
});
26697

26798
it('can send APNS notification', (done) => {
26899
var args = {
269-
cert: 'prodCert.pem',
270-
key: 'prodKey.pem',
271100
production: true,
272101
bundleId: 'bundleId'
273102
}
274-
var apns = new APNS(args);
275-
var conn = {
276-
pushNotification: jasmine.createSpy('send'),
277-
bundleId: 'bundleId'
278-
};
279-
apns.conns = [ conn ];
103+
var apns = APNS(args);
280104
// Mock data
281105
var expirationTime = 1454571491354
282106
var data = {
@@ -293,15 +117,18 @@ describe('APNS', () => {
293117
}
294118
];
295119

296-
var promise = apns.send(data, devices);
297-
expect(conn.pushNotification).toHaveBeenCalled();
298-
var args = conn.pushNotification.calls.first().args;
299-
var notification = args[0];
300-
expect(notification.alert).toEqual(data.data.alert);
301-
expect(notification.expiry).toEqual(data['expiration_time']);
302-
var apnDevice = args[1]
303-
expect(apnDevice.connIndex).toEqual(0);
304-
expect(apnDevice.appIdentifier).toEqual('bundleId');
305-
done();
120+
apns.send(data, devices).then((results) => {
121+
let isArray = Array.isArray(results);
122+
expect(isArray).toBe(true);
123+
expect(results.length).toBe(1);
124+
// No provided certificates
125+
expect(results[0].status).toBe(403);
126+
expect(results[0].device).toEqual(devices[0]);
127+
expect(results[0].transmitted).toBe(false);
128+
done();
129+
}, (err) => {
130+
fail('should not fail');
131+
done();
132+
});
306133
});
307134
});

0 commit comments

Comments
 (0)