1
var assert = require('assert')
2
, http = require('http')
3
, request = require('supertest')
5
var app = require('../app')
9
'push_url': 'http://push',
13
'happy_retry_secs': 0.02,
17
return JSON.parse(JSON.stringify(cfg))
20
var PLAY_NOTIFY_FORM = '/play-notify-form'
22
suite('app', function() {
25
this.app = app.wire(this.db, cloneCfg())
26
this.reg = this.app.get('_reg')
27
this.inbox = this.app.get('_inbox')
28
this.notifier = this.app.get('_notifier')
31
test('wire', function() {
33
assert.ok(this.notifier)
34
assert.equal(this.notifier.baseURL, 'http://push')
36
this.app.on('pushError', function(err, resp, body) {
37
emitted = [err, resp, body]
39
this.notifier.pushError('err', 'resp', 'body')
40
assert.deepEqual(emitted, ["err", "resp", "body"])
43
test('wire-unknownToken', function() {
45
this.reg.removeToken = function(nick, token, doneCb, errCb) {
49
this.notifier.emit('unknownToken', "N", "T")
50
assert.deepEqual(got, ["N", "T"])
53
test('wire-unknownToken-mongoError', function() {
55
this.app.on('mongoError', function(err) {
58
this.reg.removeToken = function(nick, token, doneCb, errCb) {
61
this.notifier.emit('unknownToken', "N", "T")
65
test('_check', function(done) {
67
this.db.command = function(cmd, cb) {
73
.expect('Content-Type', 'application/json; charset=utf-8')
75
.expect(200, function(err) {
76
assert.deepEqual(pingCmd, {ping: 1})
81
test('_check-unavailable', function(done) {
83
this.db.command = function(cmd, cb) {
89
.expect('Content-Type', 'application/json; charset=utf-8')
90
.expect({error: "unavailable"})
91
.expect(503, function(err) {
96
test('any-broken', function(done) {
99
.set('Content-Type', 'application/json')
101
.expect('Content-Type', 'application/json; charset=utf-8')
102
.expect({error: 'invalid', message: 'invalid json, empty body'})
106
test('register', function(done) {
108
this.reg.insertToken = function(nick, token, doneCb, dupCb, errCb) {
114
.set('Content-Type', 'application/json')
115
.send({nick: "N", token: "T"})
116
.expect('Content-Type', 'application/json; charset=utf-8')
118
.expect(200, function(err) {
119
assert.deepEqual(got, ["N", "T"])
124
test('register-invalid', function(done) {
127
.set('Content-Type', 'application/json')
129
.expect('Content-Type', 'application/json; charset=utf-8')
130
.expect({error: 'invalid'})
134
test('register-dup', function(done) {
135
this.reg.insertToken = function(nick, token, doneCb, dupCb, errCb) {
140
.set('Content-Type', 'application/json')
141
.send({nick: "N", token: "T"})
142
.expect('Content-Type', 'application/json; charset=utf-8')
143
.expect({error: 'dup'})
147
test('register-unavailable', function(done) {
148
this.reg.insertToken = function(nick, token, doneCb, dupCb, errCb) {
153
.set('Content-Type', 'application/json')
154
.send({nick: "N", token: "T"})
155
.expect('Content-Type', 'application/json; charset=utf-8')
156
.expect({error: 'unavailable'})
160
test('message', function(done) {
164
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
172
this.inbox.pushMessage = function(token, msg, doneCb, errCb) {
177
this.notifier.notify = function(nick, token, data) {
178
notify = [nick, token, data]
182
.set('Content-Type', 'application/json')
183
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
184
.expect('Content-Type', 'application/json; charset=utf-8')
186
.expect(200, function(err) {
187
assert.deepEqual(lookup, ["N", "N2"])
188
assert.deepEqual(pushed, ["T2"])
189
assert.deepEqual(notify, ["N2", "T2", {m: 1,_from: "N",_serial: 10}])
194
test('message-unauthorized', function(done) {
195
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
204
.set('Content-Type', 'application/json')
205
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "Z"})
206
.expect('Content-Type', 'application/json; charset=utf-8')
207
.expect({error: "unauthorized"})
211
test('message-unknown-nick', function(done) {
212
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
221
.set('Content-Type', 'application/json')
222
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
223
.expect('Content-Type', 'application/json; charset=utf-8')
224
.expect({error: "unknown-nick"})
228
test('message-invalid', function(done) {
231
.set('Content-Type', 'application/json')
232
.send({nick: "N"}) // missing data
233
.expect('Content-Type', 'application/json; charset=utf-8')
234
.expect({error: 'invalid'})
238
test('message-check-token-unavailable', function(done) {
240
this.app.on('mongoError', function(err) {
243
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
252
.set('Content-Type', 'application/json')
253
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
254
.expect('Content-Type', 'application/json; charset=utf-8')
255
.expect({error: 'unavailable'})
256
.expect(503, function(err) {
262
test('message-inbox-unavailable', function(done) {
263
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
270
this.inbox.pushMessage = function(token, msg, doneCb, errCb) {
275
.set('Content-Type', 'application/json')
276
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
277
.expect('Content-Type', 'application/json; charset=utf-8')
278
.expect({error: 'unavailable'})
282
test('message-notify-unavailable', function(done) {
283
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
292
.set('Content-Type', 'application/json')
293
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
294
.expect('Content-Type', 'application/json; charset=utf-8')
295
.expect({error: 'unavailable'})
296
.expect(503, function(err) {
301
test('index', function(done) {
304
.expect(new RegExp('<title>pushAppServer'))
305
.expect('Content-Type', 'text/html; charset=UTF-8')
309
test('play-notify-form-absent', function(done) {
311
.post(PLAY_NOTIFY_FORM)
313
.send({nick: "N", data: '{"m": 1}'})
317
test('drain', function(done) {
320
var msgs = [{'m': 42, _timestamp: 4000, _serial: 20}]
321
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
325
this.inbox.drain = function(token, timestamp, doneCb, errCb) {
326
got = [token, timestamp]
331
.set('Content-Type', 'application/json')
332
.send({nick: "N", token: "T", timestamp: 4000})
333
.expect('Content-Type', 'application/json; charset=utf-8')
334
.expect({ok: true, msgs: msgs})
335
.expect(200, function(err) {
336
assert.deepEqual(lookup, ["N"])
337
assert.deepEqual(got, ["T", 4000])
342
test('drain-unavailable', function(done) {
343
var msgs = [{'m': 42, _timestamp: 4000, _serial: 20}]
344
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
347
this.inbox.drain = function(token, timestamp, doneCb, errCb) {
352
.set('Content-Type', 'application/json')
353
.send({nick: "N", token: "T", timestamp: 4000})
354
.expect('Content-Type', 'application/json; charset=utf-8')
355
.expect({error: 'unavailable'})
356
.expect(503, function(err) {
361
test('drain-invalid', function(done) {
364
.set('Content-Type', 'application/json')
365
.send({nick: "N"}) // missing data
366
.expect('Content-Type', 'application/json; charset=utf-8')
367
.expect({error: 'invalid'})
371
test('drain-invalid-timestamp', function(done) {
374
.set('Content-Type', 'application/json')
375
.send({nick: "N", token: "T", timestamp: "foo"})
376
.expect('Content-Type', 'application/json; charset=utf-8')
377
.expect({error: 'invalid'})
383
suite('app-with-play-notify', function() {
387
cfg.play_notify_form = true
388
this.app = app.wire(this.db, cfg)
389
this.reg = this.app.get('_reg')
390
this.notifier = this.app.get('_notifier')
393
test('root-form', function(done) {
396
.expect(new RegExp('<form.*action="' + PLAY_NOTIFY_FORM + '"(.|\n)*<input id="nick" name="nick"'))
397
.expect('Content-Type', 'text/html; charset=UTF-8')
401
test('play-notify-form', function(done) {
404
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
407
this.notifier.notify = function(nick, token, data) {
408
notify = [nick, token, data]
411
.post(PLAY_NOTIFY_FORM)
413
.send({nick: "N", data: '{"m": 1}'})
414
.expect('Content-Type', 'text/plain; charset=utf-8')
416
.expect(200, function(err) {
417
assert.deepEqual(notify.slice(0, 2), ["N", "T"])
419
assert.equal(typeof(data._ephemeral), "number")
420
assert.ok(data._ephemeral >= start)
421
delete data._ephemeral
422
assert.deepEqual(data, {"m": 1})
427
test('play-notify-form-not-json', function(done) {
429
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
432
this.notifier.notify = function(nick, token, data) {
433
notify = [nick, token, data]
436
.post(PLAY_NOTIFY_FORM)
438
.send({nick: "N", data: '{X'})
439
.expect('Content-Type', 'text/plain; charset=utf-8')
440
.expect("data is not JSON\n")
444
test('play-notify-form-unknown-nick', function(done) {
445
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
449
.post(PLAY_NOTIFY_FORM)
450
.set('Content-Type', 'application/json')
451
.send({nick: "N", data: '{"m": 1}'})
452
.expect('Content-Type', 'text/plain; charset=utf-8')
453
.expect("unknown nick\n")
457
test('play-notify-form-unavailable', function(done) {
458
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
462
.post(PLAY_NOTIFY_FORM)
464
.send({nick: "N", data: '{"m": 1}'})
465
.expect('Content-Type', 'text/plain; charset=utf-8')
466
.expect('db is hopefully only momentarily :(\n')
467
.expect(503, function(err) {
472
test('play-notify-form-invalid', function(done) {
473
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
477
.post(PLAY_NOTIFY_FORM)
478
.set('Content-Type', 'application/json')
479
.send({nick: "", data: '{"m": 1}'})
480
.expect('Content-Type', 'text/plain; charset=utf-8')
481
.expect("invalid/empty fields\n")
485
test('play-notify-form-broken', function(done) {
487
.post(PLAY_NOTIFY_FORM)
495
suite('app-with-no-inbox', function() {
500
this.app = app.wire(this.db, cfg)
501
this.reg = this.app.get('_reg')
502
this.inbox = this.app.get('_inbox')
503
this.notifier = this.app.get('_notifier')
506
test('no-inbox', function() {
507
assert.equal(this.inbox, null)
510
test('message-no-inbox', function(done) {
514
this.reg.findToken = function(nick, foundCb, notFoundCb, errCb) {
522
this.notifier.notify = function(nick, token, data) {
523
notify = [nick, token, data]
527
.set('Content-Type', 'application/json')
528
.send({nick: "N2", data: {"m": 1}, from_nick: "N", from_token: "T"})
529
.expect('Content-Type', 'application/json; charset=utf-8')
531
.expect(200, function(err) {
532
assert.deepEqual(lookup, ["N", "N2"])
533
assert.deepEqual(notify.slice(0, 2), ["N2", "T2"])
535
assert.equal(typeof(data._ephemeral), "number")
536
assert.ok(data._ephemeral >= start)
537
delete data._ephemeral
538
assert.deepEqual(data, {"m": 1, _from:"N"})
543
test('drain-not-there', function(done) {
546
.set('Content-Type', 'application/json')
547
.send({nick: "N", token: "T", timestamp: 4000})