123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- const sinon = require('sinon');
- describe('config', function () {
- let config, fakes;
- beforeEach(function () {
- fakes = {
- logger: sinon.spy(),
- prepareCertificate: sinon.stub(),
- prepareToken: sinon.stub(),
- prepareCA: sinon.stub(),
- };
- config = require('../lib/config')(fakes);
- });
- it('supplies sensible defaults', function () {
- expect(config()).to.deep.equal({
- token: null,
- cert: 'cert.pem',
- key: 'key.pem',
- ca: null,
- pfx: null,
- passphrase: null,
- production: false,
- address: 'api.sandbox.push.apple.com',
- port: 443,
- proxy: null,
- rejectUnauthorized: true,
- connectionRetryLimit: 10,
- heartBeat: 60000,
- requestTimeout: 5000,
- });
- });
- describe('address configuration', function () {
- let originalEnv;
- before(function () {
- originalEnv = process.env.NODE_ENV;
- });
- after(function () {
- process.env.NODE_ENV = originalEnv;
- });
- beforeEach(function () {
- process.env.NODE_ENV = '';
- });
- it('should use api.sandbox.push.apple.com as the default connection address', function () {
- expect(config()).to.have.property('address', 'api.sandbox.push.apple.com');
- });
- it('should use api.push.apple.com when NODE_ENV=production', function () {
- process.env.NODE_ENV = 'production';
- expect(config()).to.have.property('address', 'api.push.apple.com');
- });
- it('should give precedence to production flag over NODE_ENV=production', function () {
- process.env.NODE_ENV = 'production';
- expect(config({ production: false })).to.have.property(
- 'address',
- 'api.sandbox.push.apple.com'
- );
- });
- it('should use api.push.apple.com when production:true', function () {
- expect(config({ production: true })).to.have.property('address', 'api.push.apple.com');
- });
- it('should use a custom address when passed', function () {
- expect(config({ address: 'testaddress' })).to.have.property('address', 'testaddress');
- });
- describe('address is passed', function () {
- it('sets production to true when using production address', function () {
- expect(config({ address: 'api.push.apple.com' })).to.have.property('production', true);
- });
- it('sets production to false when using sandbox address', function () {
- process.env.NODE_ENV = 'production';
- expect(config({ address: 'api.sandbox.push.apple.com' })).to.have.property(
- 'production',
- false
- );
- });
- });
- });
- describe('credentials', function () {
- context('`token` not supplied, use certificate', function () {
- describe('passphrase', function () {
- it('throws an error when supplied passphrase is not a string', function () {
- expect(() => config({ passphrase: 123 })).to.throw('Passphrase must be a string');
- });
- it('does not throw when passphrase is a string', function () {
- expect(() => config({ passphrase: 'seekrit' })).to.not.throw();
- });
- it('does not throw when passphrase is not supplied', function () {
- expect(() => config({})).to.not.throw();
- });
- });
- context('pfx value is supplied without cert and key', function () {
- it('includes the value of `pfx`', function () {
- expect(config({ pfx: 'apn.pfx' })).to.have.property('pfx', 'apn.pfx');
- });
- it('does not include a value for `cert`', function () {
- expect(config({ pfx: 'apn.pfx' }).cert).to.be.undefined;
- });
- it('does not include a value for `key`', function () {
- expect(config({ pfx: 'apn.pfx' }).key).to.be.undefined;
- });
- });
- context('pfx value is supplied along with a cert and key', function () {
- it('includes the value of `pfx`', function () {
- expect(config({ pfx: 'apn.pfx', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'pfx',
- 'apn.pfx'
- );
- });
- it('does not include a value for `cert`', function () {
- expect(config({ pfx: 'apn.pfx', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'cert',
- 'cert.pem'
- );
- });
- it('does not include a value for `key`', function () {
- expect(config({ pfx: 'apn.pfx', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'key',
- 'key.pem'
- );
- });
- });
- context('pfxData value is supplied without cert and key', function () {
- it('includes the value of `pfxData`', function () {
- expect(config({ pfxData: 'apnData' })).to.have.property('pfxData', 'apnData');
- });
- it('does not include a value for `cert`', function () {
- expect(config({ pfxData: 'apnData' }).cert).to.be.undefined;
- });
- it('does not include a value for `key`', function () {
- expect(config({ pfxData: 'apnData' }).key).to.be.undefined;
- });
- });
- context('pfxData value is supplied along with a cert and key', function () {
- it('includes the value of `pfxData`', function () {
- expect(config({ pfxData: 'apnData', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'pfxData',
- 'apnData'
- );
- });
- it('does not include a value for `cert`', function () {
- expect(config({ pfxData: 'apnData', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'cert',
- 'cert.pem'
- );
- });
- it('does not include a value for `key`', function () {
- expect(config({ pfxData: 'apnData', cert: 'cert.pem', key: 'key.pem' })).to.have.property(
- 'key',
- 'key.pem'
- );
- });
- });
- it('loads and validates the TLS credentials', function () {
- fakes.prepareCertificate.returns({ cert: 'certData', key: 'keyData', pfx: 'pfxData' });
- const configuration = config({});
- expect(configuration).to.have.property('cert', 'certData');
- expect(configuration).to.have.property('key', 'keyData');
- expect(configuration).to.have.property('pfx', 'pfxData');
- });
- it('prepares the CA certificates', function () {
- fakes.prepareCA.returns({ ca: 'certificate1' });
- const configuration = config({});
- expect(configuration).to.have.property('ca', 'certificate1');
- });
- });
- context('`token` supplied', function () {
- const key = 'testKey';
- const keyId = 'abckeyId';
- const teamId = 'teamId123';
- // Clear these to ensure tls.Socket doesn't attempt to do client-auth
- it('clears the `pfx` property', function () {
- expect(config({ token: { key, keyId, teamId } })).to.not.have.property('pfx');
- });
- it('clears the `key` property', function () {
- expect(config({ token: { key, keyId, teamId } })).to.not.have.property('key');
- });
- it('clears the `cert` property', function () {
- expect(config({ token: { key, keyId, teamId } })).to.not.have.property('cert');
- });
- describe('token', function () {
- it('throws an error if keyId is missing', function () {
- expect(() => config({ token: { key, teamId } })).to.throw(/token\.keyId is missing/);
- });
- it('throws an error if keyId is not a string', function () {
- expect(() => config({ token: { key, teamId, keyId: 123 } })).to.throw(
- /token\.keyId must be a string/
- );
- });
- it('throws an error if teamId is missing', function () {
- expect(() => config({ token: { key, keyId } })).to.throw(/token\.teamId is missing/);
- });
- it('throws an error if teamId is not a string', function () {
- expect(() => config({ token: { key, keyId, teamId: 123 } })).to.throw(
- /token\.teamId must be a string/
- );
- });
- });
- it('does not invoke prepareCertificate', function () {
- config({ token: { key, keyId, teamId } });
- expect(fakes.prepareCertificate).to.have.not.been.called;
- });
- it('prepares a token generator', function () {
- const testConfig = { key, keyId, teamId };
- fakes.prepareToken.withArgs(sinon.match(testConfig)).returns(() => 'fake-token');
- const configuration = config({ token: testConfig });
- expect(fakes.prepareToken).to.have.been.called;
- expect(configuration.token()).to.equal('fake-token');
- });
- it('prepares the CA certificates', function () {
- fakes.prepareCA.returns({ ca: 'certificate1' });
- const configuration = config({});
- expect(configuration).to.have.property('ca', 'certificate1');
- });
- });
- });
- context('a null config value is passed', function () {
- it('should log a message with `debug`', function () {
- config({ address: null });
- expect(fakes.logger).to.be.calledWith(
- 'Option [address] is null. This may cause unexpected behaviour.'
- );
- });
- });
- context('a config value is undefined', function () {
- it('should log a message with `debug`', function () {
- config({ anOption: undefined });
- expect(fakes.logger).to.be.calledWith(
- 'Option [anOption] is undefined. This may cause unexpected behaviour.'
- );
- });
- });
- });
|