Skip to content

Commit

Permalink
Added some unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ara Yapejian committed Oct 7, 2017
1 parent 037d15b commit 087746d
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 150 deletions.
17 changes: 13 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
{
"env": {
"node": true,
"mocha": true,
"es6": true
"node": true,
"mocha": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": {
"impliedStrict": true
}
},
"globals": {

},
"rules": {
// Strict mode to support babel
Expand All @@ -12,7 +21,6 @@
"no-console": 1, // disallow use of console (off by default in the node environment)
"no-constant-condition": 2, // disallow use of constant expressions in conditions
"no-control-regex": 2, // disallow control characters in regular expressions
"no-debugger": 2, // disallow use of debugger
"no-dupe-args": 2, // disallow duplicate arguments in functions
"no-dupe-keys": 2, // disallow duplicate keys when creating object literals
"no-duplicate-case": 2, // disallow a duplicate case label.
Expand Down Expand Up @@ -122,5 +130,6 @@
"comma-dangle": 1,
"key-spacing": [1, { "align": "value" }],
"no-param-reassign": 0,
"no-debugger": 1, // disallow use of debugger
}
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"python.linting.pylintEnabled": false
"python.linting.pylintEnabled": false,
"mocha.enabled": true
}
36 changes: 36 additions & 0 deletions __tests__/ha-api.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const should = require('should');
const nock = require('nock');
const smock = require('simple-mock');
const HaApi = require('../lib/ha-api');

const TEST_CONFIG = {
baseUrl: 'http://bogus',
apiPass: 'bogus'
};

describe('HaApi Tests', function() {
afterEach(function () {
smock.restore();
})

describe('instantiation', function() {
it('should instantiate correctly', function () {
const haApi = new HaApi(TEST_CONFIG);

haApi.config.should.equal(TEST_CONFIG);
haApi.client.defaults.headers['x-ha-access'].should.equal(TEST_CONFIG.apiPass);
haApi.client.defaults.baseURL.should.equal(`${TEST_CONFIG.baseUrl}/api`);
});
})

describe('API Calls', function () {
it('should get services', async function() {
nock(TEST_CONFIG.baseUrl).get('/api/services').reply(200, 'testing');

const haApi = new HaApi(TEST_CONFIG);
const services = await haApi.getServices();
services.should.equal('testing');
})
})
});

31 changes: 31 additions & 0 deletions __tests__/ha-events.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require('should');
const smock = require('simple-mock');
const HaEvents = require('../lib/ha-events');

const TEST_CONFIG = {
baseUrl: 'http://bogus',
apiPass: 'bogus',
events: {
transport: 'sse', // For future support of websockets
retries: {
maxAttempts: 10, // How many times to retry connection
delay: 5000 // Delay this long before retry (in ms)
}
}
};

describe('HaEvents Tests', function() {
afterEach(function () {
smock.restore();
})

describe('instantiation', function() {
it('should instantiate correctly', function () {
const haEvents = new HaEvents(TEST_CONFIG);

haEvents.config.should.equal(TEST_CONFIG);
haEvents.streamUrl.should.equal(`${TEST_CONFIG.baseUrl}/api/stream`);
});
})
});

36 changes: 36 additions & 0 deletions __tests__/node-home-assistant.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const should = require('should');
const nock = require('nock');
const smock = require('simple-mock');
const HomeAssistant = require('..');

describe('HomeAssistant Tests', function() {
afterEach(function () {
smock.restore();
})

it('should allow instantiation without config', async function () {
const homeAssistant = await new HomeAssistant();
should.exist(homeAssistant);
});

it('should automatically start listenting during instantiation if startListening === true', async function() {
const homeAssistantExpected = {};
const startListeningProxy = smock.mock(HomeAssistant.prototype, 'startListening').resolveWith(homeAssistantExpected);

const homeAssistant = await new HomeAssistant({ baseUrl: 'http://localhost:8123' }, { startListening: true });
should.exist(homeAssistant);
startListeningProxy.callCount.should.equal(1);
});

it('should test incorrect connection', async function() {
const isValidConnection = await HomeAssistant.testConnection({ baseUrl: 'http://bogus' });
isValidConnection.should.equal(false);
});

it('should test correct connection', async function() {
nock('http://fakeHomeAssistant').get('/api/config').reply(200);

const isValidConnection = await HomeAssistant.testConnection({ baseUrl: 'http://fakeHomeAssistant' });
isValidConnection.should.equal(true);
});
});
3 changes: 1 addition & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
'use strict';
module.exports = require('./lib/_index');
module.exports = require('./lib/node-home-assistant');
88 changes: 0 additions & 88 deletions lib/_index.js

This file was deleted.

3 changes: 0 additions & 3 deletions lib/ha-api.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
'use strict';
const axios = require('axios');
const debug = require('debug')('home-assistant:api');

function HaApi(config) {
if (! (this instanceof HaApi)) { return new HaApi(config); }
debug('instantiating api interface');

this.config = config;
const apiOpts = { baseURL: config.baseUrl + '/api' };
apiOpts.headers = (config.apiPass)
Expand Down
47 changes: 14 additions & 33 deletions lib/ha-events.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
'use strict';
const inherits = require('util').inherits;
const EventEmitter = require('events').EventEmitter;
const EventSource = require('eventsource');
const debug = require('debug')('home-assistant:events');

function HaEvents(config) {
if (! (this instanceof HaEvents)) { return new HaEvents(config); }
debug('instantiating events interface');

this.config = config;
this.streamUrl = `${config.baseUrl}/api/stream`;
Expand All @@ -15,22 +13,21 @@ function HaEvents(config) {
: {};
this.connected = false;

// TODO: Implement websocket listener
if (config.events.transport === 'sse') {
debug ('setting up eventsource transport');
this.client = new EventSource(this.streamUrl, this.esOptions);
this.client.on('message', (evt) => this.onClientMessage(evt));

this.client.on('open', () => this.onClientOpen());
this.client.on('close', () => this.onClientClose());
this.client.on('error', (err) => this.onClientError(err));
}

EventEmitter.call(this);
this.setMaxListeners(0);
}
inherits(HaEvents, EventEmitter);

HaEvents.prototype.startListening = function () {
if (this.config.events.transport !== 'sse') { throw new Error('Unsupported transport type'); }

this.client = new EventSource(this.streamUrl, this.esOptions);
this.client.on('message', (evt) => this.onClientMessage(evt));

this.client.on('open', () => this.onClientOpen());
this.client.on('close', () => this.onClientClose());
this.client.on('error', (err) => this.onClientError(err));
}

HaEvents.prototype.onClientMessage = function(msg) {
// debug('sse message event: ' + require('util').inspect(msg));
Expand Down Expand Up @@ -70,13 +67,8 @@ HaEvents.prototype.onClientOpen = function () {
this.emit('ha_events:open');
};

HaEvents.prototype.onClientClose = function () {
this.closeClient(null, 'events connection closed, cleaning up connection');
};

HaEvents.prototype.onClientError = function (err) {
this.closeClient(err, 'events connection error, cleaning up connection');
};
HaEvents.prototype.onClientClose = function () { this.closeClient(null, 'events connection closed, cleaning up connection'); };
HaEvents.prototype.onClientError = function (err) { this.closeClient(err, 'events connection error, cleaning up connection'); };

HaEvents.prototype.closeClient = function (err, logMsg) {
if (logMsg) { debug(logMsg); }
Expand All @@ -91,19 +83,8 @@ HaEvents.prototype.closeClient = function (err, logMsg) {
this.emit('ha_events:close');
}

setTimeout(() => {
this.client = new EventSource(this.streamUrl, this.esOptions);
this.client.on('message', (evt) => this.onClientMessage(evt));

this.client.on('open', () => this.onClientOpen());
this.client.on('close', () => this.onClientClose());
this.client.on('error', (error) => this.onClientError(error));
}, 2000);
};


HaEvents.prototype.startReconnectionLogic = function () {

// TODO: Put in proper exponential retries
setTimeout(() => this.startListening(), 2000);
};

module.exports = HaEvents;
Loading

0 comments on commit 087746d

Please sign in to comment.