Skip to content

Commit 34bdeef

Browse files
committed
Add support for firebase messaging
1 parent d1bdb43 commit 34bdeef

File tree

2 files changed

+317
-0
lines changed

2 files changed

+317
-0
lines changed

src/messaging.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,124 @@
1+
/*
2+
Mock for admin.messaging.Messaging
3+
https://firebase.google.com/docs/reference/admin/node/admin.messaging
4+
*/
15
'use strict';
6+
var _ = require('./lodash');
7+
var assert = require('assert');
8+
var Promise = require('rsvp').Promise;
9+
var autoId = require('firebase-auto-ids');
10+
var Queue = require('./queue').Queue;
211

312
function MockMessaging() {
13+
this.results = {};
14+
this.queue = new Queue();
15+
this.flushDelay = false;
416
}
517

18+
// https://firebase.google.com/docs/reference/admin/node/admin.messaging.Messaging.html#send
19+
MockMessaging.prototype.send = function(message, dryRun) {
20+
assert(!_.isUndefined(message), 'message must not be undefined');
21+
return this._send(_.toArray(arguments), 'send', function() {
22+
var messageId = autoId(new Date().getTime());
23+
console.log(typeof(result));
24+
return messageId;
25+
});
26+
};
27+
28+
// https://firebase.google.com/docs/reference/admin/node/admin.messaging.Messaging.html#send-all
29+
MockMessaging.prototype.sendAll = function(messages, dryRun) {
30+
assert(Array.isArray(messages), 'messages must be an "Array"');
31+
var self = this;
32+
return this._send(_.toArray(arguments), 'sendAll', function() {
33+
return self._mapMessagesToBatchResponse(messages);
34+
});
35+
};
36+
37+
// https://firebase.google.com/docs/reference/admin/node/admin.messaging.Messaging.html#send-multicast
38+
MockMessaging.prototype.sendMulticast = function(multicastMessage, dryRun) {
39+
assert(!_.isUndefined(multicastMessage), 'multicastMessage must not be undefined');
40+
assert(Array.isArray(multicastMessage.tokens));
41+
var self = this;
42+
return this._send(_.toArray(arguments), 'sendMulticast', function() {
43+
return self._mapMessagesToBatchResponse(multicastMessage.tokens);
44+
});
45+
};
46+
47+
MockMessaging.prototype.flush = function(delay) {
48+
this.queue.flush(delay);
49+
return this;
50+
};
51+
52+
MockMessaging.prototype.autoFlush = function (delay) {
53+
if (_.isUndefined(delay)) {
54+
delay = true;
55+
}
56+
57+
this.flushDelay = delay;
58+
59+
return this;
60+
};
61+
62+
MockMessaging.prototype.failNext = function(methodName, err) {
63+
assert(err instanceof Error, 'err must be an "Error" object');
64+
this.results[methodName] = err;
65+
};
66+
67+
MockMessaging.prototype.nextResult = function(methodName, result) {
68+
assert(!_.isUndefined(result), 'result must not be undefined');
69+
assert(!(result instanceof Error), 'result must not be an "Error" object');
70+
this.results[methodName] = result;
71+
};
72+
73+
MockMessaging.prototype._send = function(args, methodName, defaultResultFn) {
74+
var result = this._nextResult(methodName);
75+
var self = this;
76+
return new Promise(function (resolve, reject) {
77+
self._defer(methodName, args, function () {
78+
if (result === null) {
79+
resolve(defaultResultFn());
80+
} else if (result instanceof Error) {
81+
reject(result);
82+
} else {
83+
resolve(result);
84+
}
85+
});
86+
});
87+
};
88+
89+
MockMessaging.prototype._nextResult = function(type) {
90+
var err = this.results[type];
91+
delete this.results[type];
92+
return err || null;
93+
};
94+
95+
MockMessaging.prototype._defer = function(sourceMethod, sourceArgs, callback) {
96+
this.queue.push({
97+
fn: callback,
98+
context: this,
99+
sourceData: {
100+
ref: this,
101+
method: sourceMethod,
102+
args: sourceArgs
103+
}
104+
});
105+
if (this.flushDelay !== false) {
106+
this.flush(this.flushDelay);
107+
}
108+
};
109+
110+
MockMessaging.prototype._mapMessagesToBatchResponse = function(messages) {
111+
return {
112+
failureCount: 0,
113+
successCount: messages.length,
114+
responses: messages.map(function(message) {
115+
return {
116+
error: undefined,
117+
messageId: autoId(new Date().getTime()),
118+
success: true,
119+
};
120+
})
121+
};
122+
};
123+
6124
module.exports = MockMessaging;

test/unit/messaging.js

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
'use strict';
2+
3+
var chai = require('chai');
4+
var sinon = require('sinon');
5+
6+
chai.use(require('chai-as-promised'));
7+
chai.use(require('sinon-chai'));
8+
9+
var expect = chai.expect;
10+
var _ = require('../../src/lodash');
11+
var Messaging = require('../../').MockMessaging;
12+
13+
describe('MockMessaging', function() {
14+
15+
var messaging;
16+
beforeEach(function() {
17+
messaging = new Messaging();
18+
});
19+
20+
describe('#flush', function() {
21+
it('flushes the queue and returns itself', function() {
22+
sinon.stub(messaging.queue, 'flush');
23+
expect(messaging.flush(10)).to.equal(messaging);
24+
expect(messaging.queue.flush).to.have.been.calledWith(10);
25+
});
26+
});
27+
28+
describe('#autoFlush', function() {
29+
it('enables autoflush with no args', function() {
30+
messaging.autoFlush();
31+
expect(messaging.flushDelay).to.equal(true);
32+
});
33+
34+
it('can specify a flush delay', function() {
35+
messaging.autoFlush(10);
36+
expect(messaging.flushDelay).to.equal(10);
37+
});
38+
39+
it('returns itself', function() {
40+
expect(messaging.autoFlush()).to.equal(messaging);
41+
});
42+
});
43+
44+
describe('#send', function() {
45+
it('should check that message is not undefined', function() {
46+
expect(function() {
47+
messaging.send();
48+
}).to.throw();
49+
});
50+
51+
it('should return thenable reference', function(done) {
52+
var thenable = messaging.send({
53+
message: 'foo'
54+
});
55+
thenable.then(function(result) {
56+
expect(result).to.be.a('string');
57+
done();
58+
}, done).catch(function(err) {
59+
done(err);
60+
});
61+
messaging.flush();
62+
});
63+
64+
it('can simulate an error', function(done) {
65+
var err = new Error();
66+
messaging.failNext('send', err);
67+
var thenable = messaging.send({message: 'foo'});
68+
messaging.flush();
69+
thenable.then(function() {
70+
done('send() should not resolve');
71+
}).catch(function() {
72+
done();
73+
});
74+
});
75+
76+
it('can return user defined results', function(done) {
77+
messaging.nextResult('send', 'the result');
78+
var thenable = messaging.send({message: 'foo'});
79+
messaging.flush();
80+
thenable.then(function(result) {
81+
expect(result).to.equal('the result');
82+
done();
83+
}).catch(function(err) {
84+
done(err);
85+
});
86+
});
87+
});
88+
89+
describe('#sendAll', function() {
90+
it('should check that messages is an array', function() {
91+
expect(function() {
92+
messaging.sendAll('not an array');
93+
}).to.throw();
94+
});
95+
96+
it('should return thenable reference', function(done) {
97+
var thenable = messaging.sendAll([{message: 'foobar'}]);
98+
thenable.then(function(result) {
99+
expect(result).to.be.not.undefined; // jshint ignore:line
100+
expect(result).to.be.not.null; // jshint ignore:line
101+
expect(result.failureCount).to.be.eql(0);
102+
expect(result.successCount).to.be.eql(1);
103+
expect(result.responses).to.be.an('array');
104+
expect(result.responses).to.have.lengthOf(1);
105+
expect(result.responses[0].error).to.be.undefined; // jshint ignore:line
106+
expect(result.responses[0].messageId).to.be.a('string');
107+
expect(result.responses[0].success).to.be.true; // jshint ignore:line
108+
done();
109+
}, done).catch(function(err) {
110+
done(err);
111+
});
112+
messaging.flush();
113+
});
114+
115+
it('can simulate an error', function(done) {
116+
var err = new Error();
117+
messaging.failNext('sendAll', err);
118+
var thenable = messaging.sendAll([{message: 'foobar'}]);
119+
messaging.flush();
120+
thenable.then(function() {
121+
done('sendAll() should not resolve');
122+
}).catch(function() {
123+
done();
124+
});
125+
});
126+
127+
it('can return user defined results', function(done) {
128+
messaging.nextResult('sendAll', 'the result');
129+
var thenable = messaging.sendAll([{message: 'foobar'}]);
130+
messaging.flush();
131+
thenable.then(function(result) {
132+
expect(result).to.equal('the result');
133+
done();
134+
}).catch(function(err) {
135+
done(err);
136+
});
137+
});
138+
});
139+
140+
describe('#sendMulticast', function() {
141+
it('should check that message is not undefined', function() {
142+
expect(function() {
143+
messaging.sendMulticast();
144+
}).to.throw();
145+
});
146+
147+
it('should check that message contains a "tokens" array', function() {
148+
expect(function() {
149+
messaging.sendMulticast({message: 'foobar'});
150+
}).to.throw();
151+
});
152+
153+
it('should return thenable reference', function(done) {
154+
var thenable = messaging.sendMulticast({message: 'foobar', tokens: ['t1', 't2']});
155+
thenable.then(function(result) {
156+
expect(result).to.be.not.undefined; // jshint ignore:line
157+
expect(result).to.be.not.null; // jshint ignore:line
158+
expect(result.failureCount).to.be.eql(0);
159+
expect(result.successCount).to.be.eql(2);
160+
expect(result.responses).to.be.an('array');
161+
expect(result.responses).to.have.lengthOf(2);
162+
expect(result.responses[0].error).to.be.undefined; // jshint ignore:line
163+
expect(result.responses[0].messageId).to.be.a('string');
164+
expect(result.responses[0].success).to.be.true; // jshint ignore:line
165+
expect(result.responses[1].error).to.be.undefined; // jshint ignore:line
166+
expect(result.responses[1].messageId).to.be.a('string');
167+
expect(result.responses[1].success).to.be.true; // jshint ignore:line
168+
done();
169+
}, done).catch(function(err) {
170+
done(err);
171+
});
172+
messaging.flush();
173+
});
174+
175+
it('can simulate an error', function(done) {
176+
var err = new Error();
177+
messaging.failNext('sendMulticast', err);
178+
var thenable = messaging.sendMulticast({message: 'foobar', tokens: ['t1']});
179+
messaging.flush();
180+
thenable.then(function() {
181+
done('sendMulticast() should not resolve');
182+
}).catch(function() {
183+
done();
184+
});
185+
});
186+
187+
it('can return user defined results', function(done) {
188+
messaging.nextResult('sendMulticast', 'the result');
189+
var thenable = messaging.sendMulticast({message: 'foobar', tokens: ['t1']});
190+
messaging.flush();
191+
thenable.then(function(result) {
192+
expect(result).to.equal('the result');
193+
done();
194+
}).catch(function(err) {
195+
done(err);
196+
});
197+
});
198+
});
199+
});

0 commit comments

Comments
 (0)