kinvey-flex-sdk
Version:
SDK for creating Kinvey Flex Services
480 lines (424 loc) • 16.7 kB
JavaScript
/**
* Copyright (c) 2018 Kinvey Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
const EventEmitter = require('events').EventEmitter;
const should = require('should');
const sinon = require('sinon');
const FAKE_BAAS_URL = 'http://baas.baas';
describe('modules / push', () => {
let pushModule = null;
let pushInstance = null;
let requestStub = null;
const emitter = new EventEmitter();
const recipients = [
{
_id: 'id1'
}, {
_id: 'id2'
}
];
const recipient = {
_id: 'id1'
};
const appMetadata = {
_id: 'kid_abcd1234',
applicationId: 'abc123',
mastersecret: '12345',
baasUrl: FAKE_BAAS_URL
};
const taskMetadata = {
taskId: 'abcd1234'
};
const requestMetadata = {
requestId: 'ea85600029b04a18a754d57629cff62d'
};
before((done) => {
requestStub = {
post: sinon.stub()
};
const requestDefaultsStub = sinon.stub();
requestDefaultsStub.returns(requestStub);
delete require.cache[require.resolve('../../../../lib/service/modules/push')];
require.cache[require.resolve('request')].exports.defaults = requestDefaultsStub;
pushModule = require('../../../../lib/service/modules/push'); // eslint-disable-line global-require
pushInstance = pushModule(appMetadata, taskMetadata, requestMetadata, emitter);
done();
});
afterEach((done) => {
requestStub.post.reset();
done();
});
it('\'send\' and \'sendMessage\' point to the same method', (done) => {
pushInstance.send.should.eql(pushInstance.sendMessage);
done();
});
it('\'broadcast\' and \'broadcastMessage\' point to the same method', (done) => {
pushInstance.broadcast.should.eql(pushInstance.broadcastMessage);
done();
});
describe('methods / send', () => {
it('should return a Promise', (done) => {
requestStub.post.callsArg(1);
(pushInstance.send(recipients, 'hello')).should.be.a.Promise(); // eslint-disable-line new-cap
done();
});
it('should invoke the callback if specified', (done) => {
requestStub.post.callsArg(1);
pushInstance.send(recipients, 'hello', (err) => {
should.not.exist(err);
done();
});
});
it('should invoke the promise handlers if no callback specified', (done) => {
requestStub.post.callsArg(1);
const promise = pushInstance.send(recipients, 'hello');
promise.then(() => done());
});
it('appends authorization header details to the request object', (done) => {
requestStub.post.callsArg(1);
(() => pushInstance.send(recipients, 'hello')).should.not.throw();
requestStub.post.args[0][0].auth.user.should.eql(appMetadata._id);
requestStub.post.args[0][0].auth.pass.should.eql(appMetadata.mastersecret);
done();
});
it('calls back an error if one has occurred while communicating with the server', (done) => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.send(recipients, 'hello', (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes rejection handler if an error has occurred while communicating with the server', () => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.send(recipients, 'hello')
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('calls back an error if the server returned a status code greater than or equal to 400', (done) => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.send(recipients, 'hello', (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes rejection handler if the server returned a status code greater than or equal to 400', () => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.send(recipients, 'hello')
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('POSTs to the server\'s /push/sendMessage URL', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.send(recipients, 'hello', () => {
requestStub.post.args[0][0].url.should.eql(`${FAKE_BAAS_URL}/push/${appMetadata._id}/sendMessage`);
done();
});
});
it('rejects if no receipents are specified', (done) => {
requestStub.post.callsArgWith(1, {});
(pushInstance.send(null, 'hello')).should.be.rejectedWith(/.*users.*/);
(pushInstance.send()).should.be.rejectedWith(/.*users.*/);
done();
});
it('rejects if no message is specified', (done) => {
requestStub.post.callsArgWith(1, {});
(pushInstance.send(recipients, null)).should.be.rejectedWith(/.*message.*/);
done();
});
it('send the appropriate arguments to the server', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.send(recipients, 'hello', () => {
const requestBody = requestStub.post.args[0][0].json;
requestBody.recipients.should.eql(recipients);
requestBody.messageContent.should.eql('hello');
done();
});
});
it('converts a user single object to an array', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.send(recipient, 'hello', () => {
const requestBody = requestStub.post.args[0][0].json;
requestBody.recipients.constructor.should.eql(Array);
requestBody.recipients.should.eql([recipient]);
requestBody.messageContent.should.eql('hello');
done();
});
});
});
describe('methods / broadcast', () => {
it('should return a Promise', (done) => {
requestStub.post.callsArg(1);
(pushInstance.broadcast('hello')).should.be.a.Promise(); // eslint-disable-line new-cap
done();
});
it('should invoke the callback if specified', (done) => {
requestStub.post.callsArg(1);
pushInstance.broadcast('hello', (err) => {
should.not.exist(err);
done();
});
});
it('should invoke the promise handlers if no callback specified', (done) => {
requestStub.post.callsArg(1);
const promise = pushInstance.broadcast('hello');
promise.then(() => done());
});
it('calls back an error if one has occurred while communicating with the server', (done) => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.broadcast('hello', (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes rejection handler if an error has occurred while communicating with the server', () => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.broadcast('hello')
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('calls back an error if the server returned a status code greater than or equal to 400', (done) => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.broadcast('hello', (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes the rejection handler if the server returned a status code greater than or equal to 400', () => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.broadcast('hello')
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('POSTs to the server\'s /push/sendBroadcast URL', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.broadcast('hello', () => {
requestStub.post.args[0][0].url.should.eql(`${FAKE_BAAS_URL}/push/${appMetadata._id}/sendBroadcast`);
done();
});
});
it('rejects if no message is specified', (done) => {
requestStub.post.callsArgWith(1, {});
(pushInstance.broadcast()).should.be.rejectedWith(/.*message.*/);
(pushInstance.broadcast(null)).should.be.rejectedWith(/.*message.*/);
done();
});
it('sends the appropriate arguments to the server', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.broadcast('hello', () => {
const requestBody = requestStub.post.args[0][0].json;
requestBody.messageContent.should.eql('hello');
const outgoingRequestHeaders = requestStub.post.args[0][0].headers;
outgoingRequestHeaders.should.have.property('x-kinvey-api-version');
outgoingRequestHeaders['x-kinvey-api-version'].should.equal('3');
done();
});
});
});
describe('methods / sendPayload', () => {
const iOSAps = 'iOS APs';
const iOSExtras = 'iOS extras';
const androidPayload = 'android payload';
it('should return a Promise', (done) => {
requestStub.post.callsArg(1);
// eslint-disable-next-line new-cap
(pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload)).should.be.a.Promise();
done();
});
it('should invoke the callback if specified', (done) => {
requestStub.post.callsArg(1);
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload, (err) => {
should.not.exist(err);
done();
});
});
it('should invoke the promise handlers if no callback specified', (done) => {
requestStub.post.callsArg(1);
const promise = pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload);
promise.then(() => done());
});
it('calls back an error if one has occurred while communicating with the server', (done) => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload, (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes the rejection handler if an error has occurred while communicating with the server', () => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload)
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('calls back an error if the server returned a status code greater than or equal to 400', (done) => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload, (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes the rejection handler if the server returned a status code greater than or equal to 400', () => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload)
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('POSTs to the server\'s /push/sendMessage URL', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload, () => {
requestStub.post.args[0][0].url.should.eql(`${FAKE_BAAS_URL}/push/${appMetadata._id}/sendMessage`);
done();
});
});
it('rejects if no receipents are specified', (done) => {
requestStub.post.callsArgWith(1, {});
(pushInstance.sendPayload(null, iOSAps, iOSExtras, androidPayload)).should.be.rejectedWith(/.*users.*/);
(pushInstance.sendPayload()).should.be.rejectedWith(/.*users.*/);
done();
});
it('sends the appropriate arguments to the server', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.sendPayload(recipients, iOSAps, iOSExtras, androidPayload, () => {
const requestBody = requestStub.post.args[0][0].json;
requestBody.recipients.should.eql(recipients);
requestBody.messageContent.should.eql({
iOSAps,
iOSExtras,
androidPayload
});
const outgoingRequestHeaders = requestStub.post.args[0][0].headers;
outgoingRequestHeaders.should.have.property('x-kinvey-api-version');
outgoingRequestHeaders['x-kinvey-api-version'].should.equal('3');
done();
});
});
});
describe('methods / broadcastPayload', () => {
const iOSAps = 'iOS APs';
const iOSExtras = 'iOS extras';
const androidPayload = 'android payload';
it('should return a Promise', (done) => {
requestStub.post.callsArg(1);
// eslint-disable-next-line new-cap
(pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload)).should.be.a.Promise();
done();
});
it('should invoke the callback if specified', (done) => {
requestStub.post.callsArg(1);
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload, (err) => {
should.not.exist(err);
done();
});
});
it('should invoke the promise handlers if no callback specified', (done) => {
requestStub.post.callsArg(1);
const promise = pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload);
promise.then(() => done());
});
it('calls back an error if one has occurred while communicating with the server', (done) => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload, (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes the rejection handler if an error has occurred while communicating with the server', () => {
requestStub.post.callsArgWith(1, 'error!');
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload)
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('calls back an error if the server returned a status code greater than or equal to 400', (done) => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload, (err, result) => {
should.exist(err);
err.should.eql('error!');
should.not.exist(result);
done();
});
});
it('invokes the rejection handler if the server returned a status code greater than or equal to 400', () => {
requestStub.post.callsArgWith(1, null, {
statusCode: 401
}, 'error!');
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload)
.catch((err) => {
should.exist(err);
err.should.eql('error!');
});
});
it('POSTs to the server\'s /push/sendBroadcast URL', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload, () => {
requestStub.post.args[0][0].url.should.eql(`${FAKE_BAAS_URL}/push/${appMetadata._id}/sendBroadcast`);
done();
});
});
it('sends the appropriate arguments to the server', (done) => {
requestStub.post.callsArgWith(1, {});
pushInstance.broadcastPayload(iOSAps, iOSExtras, androidPayload, () => {
const requestBody = requestStub.post.args[0][0].json;
requestBody.messageContent.should.eql({
iOSAps,
iOSExtras,
androidPayload
});
const outgoingRequestHeaders = requestStub.post.args[0][0].headers;
outgoingRequestHeaders.should.have.property('x-kinvey-api-version');
outgoingRequestHeaders['x-kinvey-api-version'].should.equal('3');
done();
});
});
});
});