Skip to content

Commit ba2e105

Browse files
committed
Merge pull request #311 from ParsePlatform/wangmengyan.add_push_api
Add support for push
2 parents 6db40f0 + 273a207 commit ba2e105

10 files changed

+856
-143
lines changed

spec/APNS.spec.js

Lines changed: 259 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,65 @@
11
var APNS = require('../src/APNS');
22

33
describe('APNS', () => {
4+
5+
it('can initialize with single cert', (done) => {
6+
var args = {
7+
cert: 'prodCert.pem',
8+
key: 'prodKey.pem',
9+
production: true,
10+
bundleId: 'bundleId'
11+
}
12+
var apns = new APNS(args);
13+
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);
23+
done();
24+
});
25+
26+
it('can initialize with multiple certs', (done) => {
27+
var args = [
28+
{
29+
cert: 'devCert.pem',
30+
key: 'devKey.pem',
31+
production: false,
32+
bundleId: 'bundleId'
33+
},
34+
{
35+
cert: 'prodCert.pem',
36+
key: 'prodKey.pem',
37+
production: true,
38+
bundleId: 'bundleIdAgain'
39+
}
40+
]
41+
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);
60+
done();
61+
});
62+
463
it('can generate APNS notification', (done) => {
564
//Mock request data
665
var data = {
@@ -29,12 +88,195 @@ describe('APNS', () => {
2988
done();
3089
});
3190

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]);
126+
done();
127+
});
128+
129+
it('can choose conns for device with invalid appIdentifier', (done) => {
130+
// Mock conns
131+
var conns = [
132+
{
133+
bundleId: 'bundleId'
134+
},
135+
{
136+
bundleId: 'bundleIdAgain'
137+
}
138+
];
139+
// Mock device
140+
var device = {
141+
appIdentifier: 'invalid'
142+
};
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();
264+
done();
265+
});
266+
32267
it('can send APNS notification', (done) => {
33-
var apns = new APNS();
34-
var sender = {
35-
pushNotification: jasmine.createSpy('send')
268+
var args = {
269+
cert: 'prodCert.pem',
270+
key: 'prodKey.pem',
271+
production: true,
272+
bundleId: 'bundleId'
273+
}
274+
var apns = new APNS(args);
275+
var conn = {
276+
pushNotification: jasmine.createSpy('send'),
277+
bundleId: 'bundleId'
36278
};
37-
apns.sender = sender;
279+
apns.conns = [ conn ];
38280
// Mock data
39281
var expirationTime = 1454571491354
40282
var data = {
@@ -43,16 +285,23 @@ describe('APNS', () => {
43285
'alert': 'alert'
44286
}
45287
}
46-
// Mock registrationTokens
47-
var deviceTokens = ['token'];
288+
// Mock devices
289+
var devices = [
290+
{
291+
deviceToken: '112233',
292+
appIdentifier: 'bundleId'
293+
}
294+
];
48295

49-
var promise = apns.send(data, deviceTokens);
50-
expect(sender.pushNotification).toHaveBeenCalled();
51-
var args = sender.pushNotification.calls.first().args;
296+
var promise = apns.send(data, devices);
297+
expect(conn.pushNotification).toHaveBeenCalled();
298+
var args = conn.pushNotification.calls.first().args;
52299
var notification = args[0];
53300
expect(notification.alert).toEqual(data.data.alert);
54301
expect(notification.expiry).toEqual(data['expiration_time']);
55-
expect(args[1]).toEqual(deviceTokens);
302+
var apnDevice = args[1]
303+
expect(apnDevice.connIndex).toEqual(0);
304+
expect(apnDevice.appIdentifier).toEqual('bundleId');
56305
done();
57306
});
58307
});

spec/GCM.spec.js

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
var GCM = require('../src/GCM');
22

33
describe('GCM', () => {
4+
it('can initialize', (done) => {
5+
var args = {
6+
apiKey: 'apiKey'
7+
};
8+
var gcm = new GCM(args);
9+
expect(gcm.sender.key).toBe(args.apiKey);
10+
done();
11+
});
12+
13+
it('can throw on initializing with invalid args', (done) => {
14+
var args = 123
15+
expect(function() {
16+
new GCM(args);
17+
}).toThrow();
18+
done();
19+
});
20+
421
it('can generate GCM Payload without expiration time', (done) => {
522
//Mock request data
623
var data = {
@@ -90,7 +107,9 @@ describe('GCM', () => {
90107
});
91108

92109
it('can send GCM request', (done) => {
93-
var gcm = new GCM('apiKey');
110+
var gcm = new GCM({
111+
apiKey: 'apiKey'
112+
});
94113
// Mock gcm sender
95114
var sender = {
96115
send: jasmine.createSpy('send')
@@ -104,34 +123,37 @@ describe('GCM', () => {
104123
'alert': 'alert'
105124
}
106125
}
107-
// Mock registrationTokens
108-
var registrationTokens = ['token'];
126+
// Mock devices
127+
var devices = [
128+
{
129+
deviceToken: 'token'
130+
}
131+
];
109132

110-
var promise = gcm.send(data, registrationTokens);
133+
gcm.send(data, devices);
111134
expect(sender.send).toHaveBeenCalled();
112135
var args = sender.send.calls.first().args;
113136
// It is too hard to verify message of gcm library, we just verify tokens and retry times
114-
expect(args[1].registrationTokens).toEqual(registrationTokens);
137+
expect(args[1].registrationTokens).toEqual(['token']);
115138
expect(args[2]).toEqual(5);
116139
done();
117140
});
118141

119-
it('can throw on sending when we have too many registration tokens', (done) => {
120-
var gcm = new GCM('apiKey');
121-
// Mock gcm sender
122-
var sender = {
123-
send: jasmine.createSpy('send')
124-
};
125-
gcm.sender = sender;
126-
// Mock registrationTokens
127-
var registrationTokens = [];
128-
for (var i = 0; i <= 2000; i++) {
129-
registrationTokens.push(i.toString());
130-
}
142+
it('can slice devices', (done) => {
143+
// Mock devices
144+
var devices = [makeDevice(1), makeDevice(2), makeDevice(3), makeDevice(4)];
131145

132-
expect(function() {
133-
gcm.send({}, registrationTokens);
134-
}).toThrow();
146+
var chunkDevices = GCM.sliceDevices(devices, 3);
147+
expect(chunkDevices).toEqual([
148+
[makeDevice(1), makeDevice(2), makeDevice(3)],
149+
[makeDevice(4)]
150+
]);
135151
done();
136152
});
153+
154+
function makeDevice(deviceToken) {
155+
return {
156+
deviceToken: deviceToken
157+
};
158+
}
137159
});

0 commit comments

Comments
 (0)