Skip to content

Commit 6b5f8a7

Browse files
authored
housekeeping and bug fixes (#63)
* Adds more tests * Adds mockAPNS connection for further testing
1 parent 030e889 commit 6b5f8a7

File tree

8 files changed

+129
-9
lines changed

8 files changed

+129
-9
lines changed

.istanbul.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
instrumentation:
2+
excludes: ["**/spec/**"]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"babel-preset-es2015": "^6.6.0",
2929
"babel-preset-stage-0": "^6.22.0",
3030
"codecov": "^1.0.1",
31-
"istanbul": "^0.4.5",
31+
"istanbul": "1.1.0-alpha.1",
3232
"jasmine": "2.5.3",
3333
"jasmine-spec-reporter": "^3.2.0"
3434
},

spec/APNS.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var APNS = require('../src/APNS');
2+
var Parse = require('parse/node');
23

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

@@ -23,6 +24,33 @@ describe('APNS', () => {
2324
done();
2425
});
2526

27+
it('fails to initialize with bad data', (done) => {
28+
try {
29+
new APNS("args");
30+
} catch(e) {
31+
expect(e.code).toBe(Parse.Error.PUSH_MISCONFIGURED);
32+
done();
33+
return;
34+
}
35+
fail('should not be reached');
36+
});
37+
38+
it('fails to initialize without a bundleID', (done) => {
39+
const apnsArgs = {
40+
production: true,
41+
bundle: 'hello'
42+
};
43+
try {
44+
new APNS(apnsArgs);
45+
} catch(e) {
46+
expect(e.code).toBe(Parse.Error.PUSH_MISCONFIGURED);
47+
done();
48+
return;
49+
}
50+
fail('should not be reached');
51+
done();
52+
});
53+
2654
it('can initialize with multiple certs', (done) => {
2755
var args = [
2856
{

spec/MockAPNConnection.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const EventEmitter = require('events');
2+
3+
module.exports = function (args) {
4+
let emitter = new EventEmitter();
5+
emitter.options = args;
6+
emitter.pushNotification = function(push, devices) {
7+
devices.forEach((device) => {
8+
process.nextTick(() => {
9+
emitter.emit('transmitted', push, device);
10+
});
11+
});
12+
};
13+
return emitter;
14+
}

spec/ParsePushAdapter.spec.js

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
var ParsePushAdapter = require('../src/index').ParsePushAdapter;
2+
var randomString = require('../src/PushAdapterUtils').randomString;
23
var APNS = require('../src/APNS');
34
var GCM = require('../src/GCM');
5+
var MockAPNConnection = require('./MockAPNConnection');
46

57
describe('ParsePushAdapter', () => {
8+
9+
beforeEach(() => {
10+
jasmine.mockLibrary('apn', 'Connection', MockAPNConnection);
11+
});
12+
13+
afterEach(() => {
14+
jasmine.restoreLibrary('apn', 'Connection');
15+
});
16+
617
it('can be initialized', (done) => {
718
// Make mock config
819
var pushConfig = {
@@ -278,22 +289,22 @@ describe('ParsePushAdapter', () => {
278289
{
279290
deviceType: 'ios',
280291
deviceToken: '0d72a1baa92a2febd9a254cbd6584f750c70b2350af5fc9052d1d12584b738e6',
281-
appIdentifier: 'invalidiosbundleId'
292+
appIdentifier: 'iosbundleId'
282293
},
283294
{
284295
deviceType: 'ios',
285296
deviceToken: 'ff3943ed0b2090c47e5d6f07d8f202a10427941d7897fda5a6b18c6d9fd07d48',
286-
appIdentifier: 'invalidiosbundleId'
297+
appIdentifier: 'iosbundleId'
287298
},
288299
{
289300
deviceType: 'osx',
290301
deviceToken: '5cda62a8d88eb48d9111a6c436f2e326a053eb0cd72dfc3a0893089342602235',
291-
appIdentifier: 'invalidosxbundleId'
302+
appIdentifier: 'osxbundleId'
292303
},
293304
{
294305
deviceType: 'tvos',
295306
deviceToken: '3e72a1baa92a2febd9a254cbd6584f750c70b2350af5fc9052d1d12584b738e6',
296-
appIdentifier: 'invalidiosbundleId' // ios and tvos share the same bundleid
307+
appIdentifier: 'iosbundleId' // ios and tvos share the same bundleid
297308
},
298309
{
299310
deviceType: 'win',
@@ -312,10 +323,19 @@ describe('ParsePushAdapter', () => {
312323
// 2x iOS, 1x android, 1x osx, 1x tvos
313324
expect(results.length).toBe(5);
314325
results.forEach((result) => {
315-
expect(result.transmitted).toBe(false);
316326
expect(typeof result.device).toBe('object');
317-
expect(typeof result.device.deviceType).toBe('string');
318-
expect(typeof result.device.deviceToken).toBe('string');
327+
if (!result.device) {
328+
fail('result should have device');
329+
return;
330+
}
331+
const device = result.device;
332+
expect(typeof device.deviceType).toBe('string');
333+
expect(typeof device.deviceToken).toBe('string');
334+
if (device.deviceType === 'ios' || device.deviceType === 'osx') {
335+
expect(result.transmitted).toBe(true);
336+
} else {
337+
expect(result.transmitted).toBe(false);
338+
}
319339
})
320340
done();
321341
}).catch((err) => {
@@ -324,6 +344,41 @@ describe('ParsePushAdapter', () => {
324344
})
325345
});
326346

347+
it('properly marks not transmitter when sender is missing', (done) => {
348+
var pushConfig = {
349+
android: {
350+
senderId: 'senderId',
351+
apiKey: 'apiKey'
352+
}
353+
};
354+
var installations = [{
355+
deviceType: 'ios',
356+
deviceToken: '0d72a1baa92a2febd9a254cbd6584f750c70b2350af5fc9052d1d12584b738e6',
357+
appIdentifier: 'invalidiosbundleId'
358+
},
359+
{
360+
deviceType: 'ios',
361+
deviceToken: 'ff3943ed0b2090c47e5d6f07d8f202a10427941d7897fda5a6b18c6d9fd07d48',
362+
appIdentifier: 'invalidiosbundleId'
363+
}]
364+
var parsePushAdapter = new ParsePushAdapter(pushConfig);
365+
parsePushAdapter.send({data: {alert: 'some'}}, installations).then((results) => {
366+
expect(results.length).toBe(2);
367+
results.forEach((result) => {
368+
expect(result.transmitted).toBe(false);
369+
expect(typeof result.device).toBe('object');
370+
expect(typeof result.device.deviceType).toBe('string');
371+
expect(typeof result.device.deviceToken).toBe('string');
372+
expect(result.response.error.indexOf('Can not find sender for push type ios, ')).toBe(0);
373+
});
374+
done();
375+
});
376+
});
377+
378+
it('random string throws with size <=0', () => {
379+
expect(() => randomString(0)).toThrow();
380+
});
381+
327382
function makeDevice(deviceToken, deviceType, appIdentifier) {
328383
return {
329384
deviceToken: deviceToken,

spec/helper.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,19 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 5000
55
jasmine.getEnv().clearReporters();
66
jasmine.getEnv().addReporter(new SpecReporter());
77

8+
var libraryCache = {};
9+
jasmine.mockLibrary = function(library, name, mock) {
10+
var original = require(library)[name];
11+
if (!libraryCache[library]) {
12+
libraryCache[library] = {};
13+
}
14+
require(library)[name] = mock;
15+
libraryCache[library][name] = original;
16+
}
17+
18+
jasmine.restoreLibrary = function(library, name) {
19+
if (!libraryCache[library] || !libraryCache[library][name]) {
20+
throw 'Can not find library ' + library + ' ' + name;
21+
}
22+
require(library)[name] = libraryCache[library][name];
23+
}

src/APNS.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,25 @@ function APNS(args) {
4747
}
4848

4949
// Set apns client callbacks
50+
/* istanbul ignore next */
5051
conn.on('connected', () => {
5152
log.verbose(LOG_PREFIX, 'APNS Connection %d Connected', conn.index);
5253
});
5354

5455
conn.on('transmissionError', (errCode, notification, apnDevice) => {
5556
handleTransmissionError(this.conns, errCode, notification, apnDevice);
5657
});
57-
58+
/* istanbul ignore next */
5859
conn.on('timeout', () => {
5960
log.verbose(LOG_PREFIX, 'APNS Connection %d Timeout', conn.index);
6061
});
6162

63+
/* istanbul ignore next */
6264
conn.on('disconnected', () => {
6365
log.verbose(LOG_PREFIX, 'APNS Connection %d Disconnected', conn.index);
6466
});
6567

68+
/* istanbul ignore next */
6669
conn.on('socketError', () => {
6770
log.verbose(LOG_PREFIX, 'APNS Connection %d Socket Error', conn.index);
6871
});
@@ -121,6 +124,7 @@ APNS.prototype.send = function(data, devices) {
121124
allPromises.push(promise);
122125
} else {
123126
let apnDevice = new apn.Device(device.deviceToken);
127+
apnDevice.deviceType = device.deviceType;
124128
apnDevice.connIndex = qualifiedConnIndexs[0];
125129
if (device.appIdentifier) {
126130
apnDevice.appIdentifier = device.appIdentifier;

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// for ios push.
55
import log from 'npmlog';
66

7+
/* istanbul ignore if */
78
if (process.env.VERBOSE || process.env.VERBOSE_PARSE_SERVER_PUSH_ADAPTER) {
89
log.level = 'verbose';
910
}

0 commit comments

Comments
 (0)