Test improvements (#1207)

* Add missing `zcl-id` dependency

* Improve devicePublish test

Now passes in both mocha and jest
Each test now waits for all publishes, such as readbacks,
and asserts their number.
Replaced `calledOnce` and such with numeric assertion,
for a more informative error message.

* Use sinon default sandbox

* Take assert out of chai

Improves clutter, but also `jest-codemods` also makes use of this.

* Replace proxyquire with simple cache delete

* Reduce shared mutable state in settings.test
This commit is contained in:
Mihal Malostanidis authored and Koen Kanters committed 2019-03-08 16:56:53 +01:00
1 parent e892a54013
commit bb6c226d55
8 files changed
+646 -609

No files matched your search

+1 -1
View File
@@ -43,6 +43,7 @@
"rimraf": "*",
"semver": "*",
"winston": "2.4.2",
"zcl-id": "git+https://github.com/Koenkk/zcl-id.git#77ba3058c6c4b09a9958761ae5e3046765c12872",
"ziee": "*",
"zigbee-shepherd": "git+https://github.com/Koenkk/zigbee-shepherd.git#ce12cdd9c7aa11ac9f7464839db6215d05926207",
"zigbee-shepherd-converters": "7.2.5",
@@ -56,7 +57,6 @@
"eslint-plugin-mocha": "*",
"mocha": "*",
"nyc": "*",
"proxyquire": "*",
"sinon": "*",
"tmp": "*"
}
+18 -19
View File
@@ -1,21 +1,20 @@
const chai = require('chai');
const assert = require('chai').assert;
const sinon = require('sinon');
const Controller = require('../lib/controller');
const settings = require('../lib/util/settings');
const mqtt = require('../lib/mqtt');
const utils = require('./utils');
const sandbox = sinon.createSandbox();
describe('Controller', () => {
let controller;
let mqttPublish;
beforeEach(() => {
utils.stubLogger(sandbox);
sandbox.stub(settings, 'getDevice').callsFake((ieeeAddr) => {
utils.stubLogger(sinon);
sinon.stub(settings, 'getDevice').callsFake((ieeeAddr) => {
return {friendly_name: 'test'};
});
mqttPublish = sandbox.stub(mqtt.prototype, 'publish').callsFake(() => {});
mqttPublish = sinon.stub(mqtt.prototype, 'publish').callsFake(() => {});
controller = new Controller();
controller.zigbee = {
getDevice: () => {
@@ -28,7 +27,7 @@ describe('Controller', () => {
});
afterEach(() => {
sandbox.restore();
sinon.restore();
});
describe('Handling zigbee messages', () => {
@@ -36,15 +35,15 @@ describe('Controller', () => {
const device = {ieeeAddr: '0x12345678', modelId: 'TRADFRI bulb E27 CWS opal 600lm'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'devChange', {onOff: 1}, 1);
controller.onZigbeeMessage(message);
chai.assert.isTrue(mqttPublish.calledOnce);
chai.assert.strictEqual(
assert.isTrue(mqttPublish.calledOnce);
assert.strictEqual(
mqttPublish.getCall(0).args[1],
JSON.stringify({state: 'ON'})
);
});
it('Should handle a zigbee message when include_device_information is set', () => {
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
mqtt: {
include_device_information: true,
@@ -61,8 +60,8 @@ describe('Controller', () => {
const device = {ieeeAddr: '0x12345678', modelId: 'TRADFRI bulb E27 CWS opal 600lm'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'devChange', {onOff: 1}, 1);
controller.onZigbeeMessage(message);
chai.assert.isTrue(mqttPublish.calledOnce);
chai.assert.strictEqual(
assert.isTrue(mqttPublish.calledOnce);
assert.strictEqual(
mqttPublish.getCall(0).args[1],
`{"state":"ON","device":{"ieeeAddr":"0x12345678","friendlyName":"test",` +
`"manufName":"IKEA","modelId":"TRADFRI bulb E27 CWS opal 600lm"}}`
@@ -72,15 +71,15 @@ describe('Controller', () => {
it('Should output to json by default', () => {
const payload = {temperature: 1, humidity: 2};
controller.publishEntityState('0x12345678', payload);
chai.assert.isTrue(mqttPublish.calledOnce);
chai.assert.deepEqual(
assert.isTrue(mqttPublish.calledOnce);
assert.deepEqual(
JSON.parse(mqttPublish.getCall(0).args[1]),
payload
);
});
it('Should output to attribute', () => {
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
mqtt: {
include_device_information: false,
@@ -96,11 +95,11 @@ describe('Controller', () => {
const payload = {temperature: 1, humidity: 2};
controller.publishEntityState('0x12345678', payload);
chai.assert.isTrue(mqttPublish.calledTwice);
chai.assert.deepEqual(mqttPublish.getCall(0).args[0], 'test/temperature');
chai.assert.deepEqual(mqttPublish.getCall(0).args[1], '1');
chai.assert.deepEqual(mqttPublish.getCall(1).args[0], 'test/humidity');
chai.assert.deepEqual(mqttPublish.getCall(1).args[1], '2');
assert.isTrue(mqttPublish.calledTwice);
assert.deepEqual(mqttPublish.getCall(0).args[0], 'test/temperature');
assert.deepEqual(mqttPublish.getCall(0).args[1], '1');
assert.deepEqual(mqttPublish.getCall(1).args[0], 'test/humidity');
assert.deepEqual(mqttPublish.getCall(1).args[1], '2');
});
});
});
+3 -3
View File
@@ -1,4 +1,4 @@
const chai = require('chai');
const assert = require('chai').assert;
const data = require('../lib/util/data.js');
const path = require('path');
@@ -7,7 +7,7 @@ describe('Data', () => {
it('Should return correct path', () => {
const expected = path.normalize(path.join(__dirname, '..', 'data'));
const actual = data.getPath();
chai.assert.strictEqual(actual, expected);
assert.strictEqual(actual, expected);
});
it('Should return correct path when ZIGBEE2MQTT_DATA set', () => {
@@ -15,7 +15,7 @@ describe('Data', () => {
process.env.ZIGBEE2MQTT_DATA = expected;
data._reload();
const actual = data.getPath();
chai.assert.strictEqual(actual, expected);
assert.strictEqual(actual, expected);
delete process.env.ZIGBEE2MQTT_DATA;
data._reload();
});
+6 -7
View File
@@ -1,19 +1,18 @@
const chai = require('chai');
const assert = require('chai').assert;
const sinon = require('sinon');
const Availability = require('../lib/extension/deviceAvailability');
const utils = require('./utils');
const sandbox = sinon.createSandbox();
describe('Availability', () => {
let availability;
beforeEach(() => {
utils.stubLogger(sandbox);
utils.stubLogger(sinon);
availability = new Availability(null, null, null, () => {});
});
afterEach(() => {
sandbox.restore();
sinon.restore();
});
describe('Determine pingable devices', () => {
@@ -23,7 +22,7 @@ describe('Availability', () => {
type: 'Router',
};
chai.assert.isTrue(availability.isPingable(device));
assert.isTrue(availability.isPingable(device));
});
it('Battery device should not be a pingable device', () => {
@@ -32,7 +31,7 @@ describe('Availability', () => {
type: 'EndDevice',
};
chai.assert.isFalse(availability.isPingable(device));
assert.isFalse(availability.isPingable(device));
});
it('E11-G13 should be a pingable device', () => {
@@ -43,7 +42,7 @@ describe('Availability', () => {
manufId: 4448,
};
chai.assert.isTrue(availability.isPingable(device));
assert.isTrue(availability.isPingable(device));
});
});
});
+459 -414
View File
File diff suppressed because it is too large. Load diff
+46 -47
View File
@@ -1,10 +1,9 @@
const chai = require('chai');
const assert = require('chai').assert;
const sinon = require('sinon');
const DeviceReceive = require('../lib/extension/deviceReceive');
const settings = require('../lib/util/settings');
const devices = require('zigbee-shepherd-converters').devices;
const utils = require('./utils');
const sandbox = sinon.createSandbox();
// Devices
const WXKG11LM = devices.find((d) => d.model === 'WXKG11LM');
@@ -21,14 +20,14 @@ describe('DeviceReceive', () => {
let publishEntityState;
beforeEach(() => {
utils.stubLogger(sandbox);
sandbox.stub(settings, 'addDevice').callsFake(() => {});
utils.stubLogger(sinon);
sinon.stub(settings, 'addDevice').callsFake(() => {});
publishEntityState = sinon.spy();
deviceReceive = new DeviceReceive(null, mqtt, null, publishEntityState);
});
afterEach(() => {
sandbox.restore();
sinon.restore();
});
describe('Handling zigbee messages', () => {
@@ -36,24 +35,24 @@ describe('DeviceReceive', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'single'});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'single'});
});
it('Should handle a zigbee message which uses ep (left)', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'left'});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'left'});
});
it('Should handle a zigbee message which uses ep (right)', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 2);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'right'});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {click: 'right'});
});
it('Should handle a zigbee message with default precision', () => {
@@ -62,39 +61,39 @@ describe('DeviceReceive', () => {
device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1
);
deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.85});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.85});
});
it('Should handle a zigbee message with 1 precision', () => {
const device = {ieeeAddr: '0x12345678'};
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {temperature_precision: 1};
});
const message = utils.zigbeeMessage(
device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1
);
deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.8});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.8});
});
it('Should handle a zigbee message with 0 precision', () => {
const device = {ieeeAddr: '0x12345678'};
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {temperature_precision: 0};
});
const message = utils.zigbeeMessage(
device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1
);
deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -1});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -1});
});
it('Should handle a zigbee message with 1 precision when set via device_options', () => {
const device = {ieeeAddr: '0x12345678'};
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
device_options: {
temperature_precision: 1,
@@ -104,20 +103,20 @@ describe('DeviceReceive', () => {
},
};
});
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {};
});
const message = utils.zigbeeMessage(
device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1
);
deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.8});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.8});
});
it('Should handle a zigbee message with 2 precision when overrides device_options', () => {
const device = {ieeeAddr: '0x12345678'};
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
device_options: {
temperature_precision: 1,
@@ -127,7 +126,7 @@ describe('DeviceReceive', () => {
},
};
});
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {
temperature_precision: 2,
};
@@ -136,44 +135,44 @@ describe('DeviceReceive', () => {
device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1
);
deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.85});
assert.isTrue(publishEntityState.calledOnce);
assert.deepEqual(publishEntityState.getCall(0).args[1], {temperature: -0.85});
});
it('Should handle a zigbee message with voltage 3010', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', {'65281': {'1': 3010}}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
assert.isTrue(publishEntityState.calledOnce);
const expected = {battery: 100, voltage: 3010};
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
});
it('Should handle a zigbee message with voltage 2850', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', {'65281': {'1': 2850}}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
assert.isTrue(publishEntityState.calledOnce);
const expected = {battery: 35, voltage: 2850};
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
});
it('Should handle a zigbee message with voltage 2650', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', {'65281': {'1': 2650}}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
assert.isTrue(publishEntityState.calledOnce);
const expected = {battery: 14, voltage: 2650};
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
});
it('Should handle a zigbee message with voltage 2000', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', {'65281': {'1': 2000}}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
assert.isTrue(publishEntityState.calledOnce);
const expected = {battery: 0, voltage: 2000};
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
});
it('Should publish 1 message when converted twice', () => {
@@ -183,9 +182,9 @@ describe('DeviceReceive', () => {
};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', payload, 1);
deviceReceive.onZigbeeMessage(message, device, RTCGQ11LM);
chai.assert.isTrue(publishEntityState.calledOnce);
assert.isTrue(publishEntityState.calledOnce);
const expected = {'battery': 100, 'illuminance': 381, 'voltage': 3045};
chai.assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
assert.deepEqual(publishEntityState.getCall(0).args[1], expected);
});
it('Should publish no message when converted without result', () => {
@@ -193,13 +192,13 @@ describe('DeviceReceive', () => {
const payload = {'9999': {'1': 3045}};
const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', payload, 1);
deviceReceive.onZigbeeMessage(message, device, RTCGQ11LM);
chai.assert.isTrue(publishEntityState.notCalled);
assert.isTrue(publishEntityState.notCalled);
});
it('Should publish last_seen epoch', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
advanced: {
last_seen: 'epoch',
@@ -207,14 +206,14 @@ describe('DeviceReceive', () => {
};
});
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'number');
assert.isTrue(publishEntityState.calledOnce);
assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'number');
});
it('Should publish last_seen ISO_8601', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
advanced: {
last_seen: 'ISO_8601',
@@ -222,14 +221,14 @@ describe('DeviceReceive', () => {
};
});
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
assert.isTrue(publishEntityState.calledOnce);
assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
});
it('Should publish last_seen ISO_8601_local', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
sandbox.stub(settings, 'get').callsFake(() => {
sinon.stub(settings, 'get').callsFake(() => {
return {
advanced: {
last_seen: 'ISO_8601_local',
@@ -237,8 +236,8 @@ describe('DeviceReceive', () => {
};
});
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
assert.isTrue(publishEntityState.calledOnce);
assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
});
});
});
+75 -76
View File
@@ -1,8 +1,7 @@
const devices = require('zigbee-shepherd-converters').devices;
const HomeassistantExtension = require('../lib/extension/homeassistant');
const chai = require('chai');
const assert = require('chai').assert;
const sinon = require('sinon');
const sandbox = sinon.createSandbox();
const settings = require('../lib/util/settings');
const WSDCGQ11LM = devices.find((d) => d.model === 'WSDCGQ11LM');
@@ -22,7 +21,7 @@ describe('HomeAssistant extension', () => {
});
afterEach(() => {
sandbox.restore();
sinon.restore();
});
it('Should have mapping for all devices supported by zigbee-shepherd-converters', () => {
@@ -34,17 +33,17 @@ describe('HomeAssistant extension', () => {
}
});
chai.assert.strictEqual(missing.length, 0, `Missing HomeAssistant mapping for: ${missing.join(', ')}`);
assert.strictEqual(missing.length, 0, `Missing HomeAssistant mapping for: ${missing.join(', ')}`);
});
it('Should discover devices', () => {
let payload = null;
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {friendly_name: 'my_device'};
});
homeassistant.discover('0x12345678', WSDCGQ11LM, false);
chai.assert.equal(mqtt.publish.callCount, 5);
assert.equal(mqtt.publish.callCount, 5);
// 1
payload = {
@@ -65,10 +64,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(0).args[3], null);
chai.assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(0).args[3], null);
assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
// 2
payload = {
@@ -89,10 +88,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(1).args[3], null);
chai.assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(1).args[3], null);
assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
// 3
payload = {
@@ -113,10 +112,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(2).args[3], null);
chai.assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(2).args[3], null);
assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
// 4
payload = {
@@ -137,10 +136,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(3).args[3], null);
chai.assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(3).args[3], null);
assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
// 5
payload = {
@@ -160,15 +159,15 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(4).args[3], null);
chai.assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(4).args[3], null);
assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
});
it('Should discover devices with precision', () => {
let payload = null;
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {
friendly_name: 'my_device',
humidity_precision: 0,
@@ -178,7 +177,7 @@ describe('HomeAssistant extension', () => {
});
homeassistant.discover('0x12345678', WSDCGQ11LM, false);
chai.assert.equal(mqtt.publish.callCount, 5);
assert.equal(mqtt.publish.callCount, 5);
// 1
payload = {
@@ -199,10 +198,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(0).args[3], null);
chai.assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(0).args[3], null);
assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
// 2
payload = {
@@ -223,10 +222,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(1).args[3], null);
chai.assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(1).args[3], null);
assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
// 3
payload = {
@@ -247,10 +246,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(2).args[3], null);
chai.assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(2).args[3], null);
assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
// 4
payload = {
@@ -271,10 +270,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(3).args[3], null);
chai.assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(3).args[3], null);
assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
// 5
payload = {
@@ -294,15 +293,15 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(4).args[3], null);
chai.assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(4).args[3], null);
assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
});
it('Should discover devices with overriden user configuration', () => {
let payload = null;
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {
friendly_name: 'my_device',
homeassistant: {
@@ -316,7 +315,7 @@ describe('HomeAssistant extension', () => {
});
homeassistant.discover('0x12345678', WSDCGQ11LM, false);
chai.assert.equal(mqtt.publish.callCount, 5);
assert.equal(mqtt.publish.callCount, 5);
// 1
payload = {
@@ -339,10 +338,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(0).args[3], null);
chai.assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(0).args[3], null);
assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
// 2
payload = {
@@ -365,10 +364,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(1).args[3], null);
chai.assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(1).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(1).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(1).args[3], null);
assert.equal(mqtt.publish.getCall(1).args[4], 'homeassistant');
// 3
payload = {
@@ -391,10 +390,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(2).args[3], null);
chai.assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(2).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(2).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(2).args[3], null);
assert.equal(mqtt.publish.getCall(2).args[4], 'homeassistant');
// 4
payload = {
@@ -417,10 +416,10 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(3).args[3], null);
chai.assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(3).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(3).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(3).args[3], null);
assert.equal(mqtt.publish.getCall(3).args[4], 'homeassistant');
// 5
payload = {
@@ -442,20 +441,20 @@ describe('HomeAssistant extension', () => {
'availability_topic': 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(4).args[3], null);
chai.assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(4).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(4).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(4).args[3], null);
assert.equal(mqtt.publish.getCall(4).args[4], 'homeassistant');
});
it('Should discover devices with cover_position', () => {
let payload = null;
sandbox.stub(settings, 'getDevice').callsFake(() => {
sinon.stub(settings, 'getDevice').callsFake(() => {
return {friendly_name: 'my_device'};
});
homeassistant.discover('0x12345678', SV01, false);
chai.assert.equal(mqtt.publish.callCount, 5);
assert.equal(mqtt.publish.callCount, 5);
// 1
payload = {
@@ -476,9 +475,9 @@ describe('HomeAssistant extension', () => {
availability_topic: 'zigbee2mqtt/bridge/state',
};
chai.assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
chai.assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
chai.assert.equal(mqtt.publish.getCall(0).args[3], null);
chai.assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
assert.deepEqual(JSON.parse(mqtt.publish.getCall(0).args[1]), payload);
assert.deepEqual(mqtt.publish.getCall(0).args[2], {retain: true, qos: 0});
assert.equal(mqtt.publish.getCall(0).args[3], null);
assert.equal(mqtt.publish.getCall(0).args[4], 'homeassistant');
});
});
+38 -42
View File
@@ -1,10 +1,7 @@
const chai = require('chai');
const assert = require('chai').assert;
const sinon = require('sinon');
const data = require('../lib/util/data');
const proxyquire = require('proxyquire').noPreserveCache();
const settingsProxy = () => proxyquire('../lib/util/settings.js', {});
const tmp = require('tmp');
const sandbox = sinon.createSandbox();
const path = require('path');
const fs = require('fs');
const yaml = require('js-yaml');
@@ -12,8 +9,6 @@ const rimraf = require('rimraf');
describe('Settings', () => {
let dir = null;
let settings = null;
let configurationFile = null;
const write = (file, json) => {
fs.writeFileSync(file, yaml.safeDump(json));
@@ -24,40 +19,42 @@ describe('Settings', () => {
};
const setup = (configuration) => {
configurationFile = path.join(dir.name, 'configuration.yaml');
const configurationFile = path.join(dir.name, 'configuration.yaml');
write(configurationFile, configuration);
settings = settingsProxy();
delete require.cache[require.resolve('../lib/util/settings.js')];
const settings = require('../lib/util/settings.js');
return {configurationFile, settings};
};
beforeEach(() => {
dir = tmp.dirSync();
sandbox.stub(data, 'joinPath').callsFake((file) => {
sinon.stub(data, 'joinPath').callsFake((file) => {
return path.join(dir.name, file);
});
});
afterEach(() => {
rimraf.sync(dir.name);
sandbox.restore();
sinon.restore();
});
describe('Settings', () => {
it('Should return default settings', () => {
setup({});
const {settings} = setup({});
const s = settings.get();
chai.assert.deepEqual(s, settings._getDefaults());
assert.deepEqual(s, settings._getDefaults());
});
it('Should return settings', () => {
setup({permit_join: true});
const {settings} = setup({permit_join: true});
const s = settings.get();
const expected = settings._getDefaults();
expected.permit_join = true;
chai.assert.deepEqual(s, expected);
assert.deepEqual(s, expected);
});
it('Should add devices', () => {
setup({});
const {settings, configurationFile} = setup({});
settings.addDevice('0x12345678');
const actual = read(configurationFile);
@@ -70,7 +67,7 @@ describe('Settings', () => {
},
};
chai.assert.deepEqual(actual, expected);
assert.deepEqual(actual, expected);
});
it('Should read devices', () => {
@@ -83,7 +80,7 @@ describe('Settings', () => {
},
};
setup(content);
const {settings} = setup(content);
const device = settings.getDevice('0x12345678');
const expected = {
@@ -91,7 +88,7 @@ describe('Settings', () => {
retain: false,
};
chai.assert.deepEqual(device, expected);
assert.deepEqual(device, expected);
});
it('Should read devices form a seperate file', () => {
@@ -107,7 +104,7 @@ describe('Settings', () => {
};
write(path.join(dir.name, 'devices.yaml'), contentDevices);
setup(contentConfiguration);
const {settings} = setup(contentConfiguration);
const device = settings.getDevice('0x12345678');
const expected = {
@@ -115,7 +112,7 @@ describe('Settings', () => {
retain: false,
};
chai.assert.deepEqual(device, expected);
assert.deepEqual(device, expected);
});
it('Should add devices to a seperate file', () => {
@@ -132,11 +129,11 @@ describe('Settings', () => {
const devicesFile = path.join(dir.name, 'devices.yaml');
write(devicesFile, contentDevices);
setup(contentConfiguration);
const {settings, configurationFile} = setup(contentConfiguration);
settings.addDevice('0x1234');
chai.assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
const expected = {
'0x12345678': {
@@ -149,7 +146,7 @@ describe('Settings', () => {
},
};
chai.assert.deepEqual(read(devicesFile), expected);
assert.deepEqual(read(devicesFile), expected);
});
it('Should add devices to a seperate file if devices.yaml doesnt exist', () => {
@@ -158,11 +155,11 @@ describe('Settings', () => {
};
const devicesFile = path.join(dir.name, 'devices.yaml');
setup(contentConfiguration);
const {settings, configurationFile} = setup(contentConfiguration);
settings.addDevice('0x1234');
chai.assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
const expected = {
'0x1234': {
@@ -171,7 +168,7 @@ describe('Settings', () => {
},
};
chai.assert.deepEqual(read(devicesFile), expected);
assert.deepEqual(read(devicesFile), expected);
});
it('Should add and remove devices to a seperate file if devices.yaml doesnt exist', () => {
@@ -180,15 +177,15 @@ describe('Settings', () => {
};
const devicesFile = path.join(dir.name, 'devices.yaml');
setup(contentConfiguration);
const {settings, configurationFile} = setup(contentConfiguration);
settings.addDevice('0x1234');
chai.assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
settings.removeDevice('0x1234');
chai.assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
assert.deepEqual(read(configurationFile), {devices: 'devices.yaml'});
chai.assert.deepEqual(read(devicesFile), {});
assert.deepEqual(read(devicesFile), {});
});
it('Should read groups', () => {
@@ -200,14 +197,14 @@ describe('Settings', () => {
},
};
setup(content);
const {settings} = setup(content);
const group = settings.getGroup('1');
const expected = {
friendly_name: '123',
};
chai.assert.deepEqual(group, expected);
assert.deepEqual(group, expected);
});
it('Should read groups form a seperate file', () => {
@@ -222,14 +219,14 @@ describe('Settings', () => {
};
write(path.join(dir.name, 'groups.yaml'), contentGroups);
setup(contentConfiguration);
const {settings} = setup(contentConfiguration);
const group = settings.getGroup('1');
const expected = {
friendly_name: '123',
};
chai.assert.deepEqual(group, expected);
assert.deepEqual(group, expected);
});
it('Combine everything! groups and devices from separte file :)', () => {
@@ -245,21 +242,20 @@ describe('Settings', () => {
};
write(path.join(dir.name, 'groups.yaml'), contentGroups);
setup(contentConfiguration);
const {settings, configurationFile} = setup(contentConfiguration);
const devicesFile = path.join(dir.name, 'devices.yaml');
setup(contentConfiguration);
const expectedConfiguration = {
devices: 'devices.yaml',
groups: 'groups.yaml',
};
chai.assert.deepEqual(read(configurationFile), expectedConfiguration);
assert.deepEqual(read(configurationFile), expectedConfiguration);
settings.addDevice('0x1234');
chai.assert.deepEqual(read(configurationFile), expectedConfiguration);
assert.deepEqual(read(configurationFile), expectedConfiguration);
const expectedDevice = {
'0x1234': {
@@ -268,23 +264,23 @@ describe('Settings', () => {
},
};
chai.assert.deepEqual(read(devicesFile), expectedDevice);
assert.deepEqual(read(devicesFile), expectedDevice);
const group = settings.getGroup('1');
const expectedGroup = {
friendly_name: '123',
};
chai.assert.deepEqual(group, expectedGroup);
assert.deepEqual(group, expectedGroup);
chai.assert.deepEqual(read(configurationFile), expectedConfiguration);
assert.deepEqual(read(configurationFile), expectedConfiguration);
const expectedDevice2 = {
friendly_name: '0x1234',
retain: false,
};
chai.assert.deepEqual(settings.getDevice('0x1234'), expectedDevice2);
assert.deepEqual(settings.getDevice('0x1234'), expectedDevice2);
});
});
});