diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 2a4ed2060..df73166cb 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -499,42 +499,6 @@ } } }, - "@sinonjs/commons": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", - "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", - "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz", - "integrity": "sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.0.2", - "array-from": "^2.1.1", - "lodash": "^4.17.11" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, "@types/babel__core": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz", @@ -704,14 +668,6 @@ "resolved": "https://registry.npmjs.org/areq/-/areq-0.2.0.tgz", "integrity": "sha1-ad0ojIF8hy3HLDfp0eciayayMcU=" }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -736,12 +692,6 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -2389,12 +2339,6 @@ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, "diff-sequences": { "version": "24.3.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.3.0.tgz", @@ -2760,11 +2704,6 @@ "eslint-visitor-keys": "^1.0.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", @@ -3350,8 +3289,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.0", @@ -3873,8 +3811,7 @@ "istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", - "dev": true + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==" }, "istanbul-lib-hook": { "version": "2.0.3", @@ -4388,8 +4325,19 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "jsbn": { @@ -4505,12 +4453,6 @@ "verror": "1.10.0" } }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true - }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -4603,12 +4545,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lolex": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", - "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4622,7 +4558,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, "requires": { "pify": "^3.0.0" } @@ -4894,27 +4829,6 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "nise": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", - "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.1.0", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^2.3.2", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - } - } - }, "node-abi": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.7.1.tgz", @@ -5302,23 +5216,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -5342,8 +5239,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "pirates": { "version": "4.0.1", @@ -5929,21 +5825,6 @@ "simple-concat": "^1.0.0" } }, - "sinon": { - "version": "7.2.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.7.tgz", - "integrity": "sha512-rlrre9F80pIQr3M36gOdoCEWzFAMDgHYD8+tocqOw+Zw9OZ8F84a80Ds69eZfcjnzDqqG88ulFld0oin/6rG/g==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.1", - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/samsam": "^3.2.0", - "diff": "^3.5.0", - "lolex": "^3.1.0", - "nise": "^1.4.10", - "supports-color": "^5.5.0" - } - }, "sisteransi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", @@ -6189,11 +6070,6 @@ "through2": "^2.0.2" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", diff --git a/package.json b/package.json index dca5d0a36..092d3a081 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "eslint": "*", "eslint-config-google": "*", "eslint-plugin-jest": "^22.3.0", - "jest": "^24.3.1", - "sinon": "*" + "jest": "^24.3.1" } } diff --git a/test/controller.test.js b/test/controller.test.js index 187d023e7..1108ac553 100644 --- a/test/controller.test.js +++ b/test/controller.test.js @@ -1,4 +1,3 @@ -const sinon = require('sinon'); const Controller = require('../lib/controller'); const settings = require('../lib/util/settings'); const mqtt = require('../lib/mqtt'); @@ -9,11 +8,11 @@ describe('Controller', () => { let mqttPublish; beforeEach(() => { - utils.stubLogger(sinon); - sinon.stub(settings, 'getDevice').callsFake((ieeeAddr) => { + utils.stubLogger(jest); + jest.spyOn(settings, 'getDevice').mockImplementation((ieeeAddr) => { return {friendly_name: 'test'}; }); - mqttPublish = sinon.stub(mqtt.prototype, 'publish').callsFake(() => {}); + mqttPublish = jest.spyOn(mqtt.prototype, 'publish').mockImplementation(() => {}); controller = new Controller(); controller.zigbee = { getDevice: () => { @@ -26,7 +25,7 @@ describe('Controller', () => { }); afterEach(() => { - sinon.restore(); + jest.restoreAllMocks(); }); describe('Handling zigbee messages', () => { @@ -34,12 +33,12 @@ 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); - expect(mqttPublish.calledOnce).toBe(true); - expect(mqttPublish.getCall(0).args[1]).toBe(JSON.stringify({state: 'ON'})); + expect(mqttPublish).toHaveBeenCalledTimes(1); + expect(mqttPublish.mock.calls[0][1]).toBe(JSON.stringify({state: 'ON'})); }); it('Should handle a zigbee message when include_device_information is set', () => { - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { mqtt: { include_device_information: true, @@ -56,8 +55,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); - expect(mqttPublish.calledOnce).toBe(true); - expect(mqttPublish.getCall(0).args[1]).toBe( + expect(mqttPublish).toHaveBeenCalledTimes(1); + expect(mqttPublish.mock.calls[0][1]).toBe( `{"state":"ON","device":{"ieeeAddr":"0x12345678","friendlyName":"test",` + `"manufName":"IKEA","modelId":"TRADFRI bulb E27 CWS opal 600lm"}}` ); @@ -67,12 +66,12 @@ describe('Controller', () => { it('Should output to json by default', () => { const payload = {temperature: 1, humidity: 2}; controller.publishEntityState('0x12345678', payload); - expect(mqttPublish.calledOnce).toBe(true); - expect(JSON.parse(mqttPublish.getCall(0).args[1])).toEqual(payload); + expect(mqttPublish).toHaveBeenCalledTimes(1); + expect(JSON.parse(mqttPublish.mock.calls[0][1])).toEqual(payload); }); it('Should output to attribute', () => { - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { mqtt: { include_device_information: false, @@ -88,11 +87,11 @@ describe('Controller', () => { const payload = {temperature: 1, humidity: 2}; controller.publishEntityState('0x12345678', payload); - expect(mqttPublish.calledTwice).toBe(true); - expect(mqttPublish.getCall(0).args[0]).toEqual('test/temperature'); - expect(mqttPublish.getCall(0).args[1]).toEqual('1'); - expect(mqttPublish.getCall(1).args[0]).toEqual('test/humidity'); - expect(mqttPublish.getCall(1).args[1]).toEqual('2'); + expect(mqttPublish).toHaveBeenCalledTimes(2); + expect(mqttPublish.mock.calls[0][0]).toEqual('test/temperature'); + expect(mqttPublish.mock.calls[0][1]).toEqual('1'); + expect(mqttPublish.mock.calls[1][0]).toEqual('test/humidity'); + expect(mqttPublish.mock.calls[1][1]).toEqual('2'); }); }); }); diff --git a/test/deviceAvailability.test.js b/test/deviceAvailability.test.js index 88debd665..824cb6e19 100644 --- a/test/deviceAvailability.test.js +++ b/test/deviceAvailability.test.js @@ -1,4 +1,3 @@ -const sinon = require('sinon'); const Availability = require('../lib/extension/deviceAvailability'); const utils = require('./utils'); @@ -6,12 +5,12 @@ describe('Availability', () => { let availability; beforeEach(() => { - utils.stubLogger(sinon); + utils.stubLogger(jest); availability = new Availability(null, null, null, () => {}); }); afterEach(() => { - sinon.restore(); + jest.restoreAllMocks(); }); describe('Determine pingable devices', () => { diff --git a/test/devicePublish.test.js b/test/devicePublish.test.js index aff5b292d..fbf61cf96 100644 --- a/test/devicePublish.test.js +++ b/test/devicePublish.test.js @@ -1,4 +1,3 @@ -const sinon = require('sinon'); const DevicePublish = require('../lib/extension/devicePublish'); const settings = require('../lib/util/settings'); const utils = require('./utils'); @@ -11,13 +10,12 @@ const mqtt = { const zigbee = { getDevice: null, - publish: sinon.stub().callsFake((entityID, entityType, cid, cmd, cmdType, zclData, cfg, ep, callback) => { + publish: jest.fn((entityID, entityType, cid, cmd, cmdType, zclData, cfg, ep, callback) => { callback(false, null); }), }; -const publishEntityState = sinon.stub().callsFake((entityID, payload, cache) => { -}); +const publishEntityState = jest.fn(); const cfg = { default: { @@ -30,519 +28,519 @@ describe('DevicePublish', () => { let devicePublish; beforeEach(() => { - utils.stubLogger(sinon); + utils.stubLogger(jest); devicePublish = new DevicePublish(zigbee, mqtt, null, publishEntityState); }); afterEach(() => { - sinon.restore(); + jest.restoreAllMocks(); }); /* eslint-disable jest/no-identical-title */ // TODO: FIXME describe('Parse topic', () => { it('Should publish messages to zigbee devices', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000001/set', JSON.stringify({brightness: '200'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000001'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 200, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000001'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 200}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000001'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 200, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000001'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 200}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); }); it('Should publish messages to zigbee devices', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - sinon.stub(settings, 'getIeeeAddrByFriendlyName').callsFake(() => '0x00000002'); - zigbee.getDevice = sinon.fake.returns({modelId: 'LCT003'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + jest.spyOn(settings, 'getIeeeAddrByFriendlyName').mockImplementation(() => '0x00000002'); + zigbee.getDevice = () => ({modelId: 'LCT003'}); devicePublish.onMQTTMessage('zigbee2mqtt/wohnzimmer.light.wall.right/set', JSON.stringify({state: 'ON'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000002'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('on'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000002'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000002'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('on'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000002'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); it('Should publish messages to zigbee devices when brightness is in %', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000003/set', JSON.stringify({brightness_percent: '92'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000003'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 235, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000003'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 235}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000003'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 235, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000003'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 235}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); } ); it('Should publish messages to zigbee devices when brightness is in number', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000004/set', JSON.stringify({brightness: 230})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000004'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 230, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000004'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 230}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000004'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 230, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000004'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 230}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); } ); it('Should publish messages to zigbee devices with color_temp', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 WS opal 980lm'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 WS opal 980lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000005/set', JSON.stringify({color_temp: '222'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000005'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToColorTemp'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({colortemp: '222', transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000005'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColorTemp'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({colortemp: '222', transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); }); it('Should publish messages to zigbee devices with color_temp in %', async () => { - publishEntityState.resetHistory(); - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 WS opal 980lm'}); + publishEntityState.mockClear(); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 WS opal 980lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000006/set', JSON.stringify({color_temp_percent: '100'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000006'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToColorTemp'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({colortemp: '500', transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.notCalled).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000006'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColorTemp'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({colortemp: '500', transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(0); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); } ); it('Should publish messages to zigbee devices with non-default ep', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'lumi.ctrl_neutral1'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'lumi.ctrl_neutral1'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000007/set', JSON.stringify({state: 'OFF'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000007'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000007'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBe(2); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); } ); it('Should publish messages to zigbee devices with non-default ep and postfix', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'lumi.ctrl_neutral2'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'lumi.ctrl_neutral2'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000008/right/set', JSON.stringify({state: 'OFF'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000008'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBe(3); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000008'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state_right: 'OFF'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000008'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBe(3); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000008'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state_right: 'OFF'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); } ); it('Should publish messages to zigbee gledopto with [11,13]', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'GLEDOPTO', epList: [11, 13]}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'GLEDOPTO', epList: [11, 13]}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000009/set', JSON.stringify({state: 'OFF'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000009'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBe(11); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000009'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'OFF'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000009'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBe(11); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000009'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'OFF'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); it('Should publish messages to zigbee gledopto with [11,12,13]', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'GLEDOPTO', epList: [11, 12, 13]}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'GLEDOPTO', epList: [11, 12, 13]}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000010/set', JSON.stringify({state: 'OFF', brightness: 50})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000010'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBe(12); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000010'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'OFF'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000010'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBe(12); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000010'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'OFF'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); } ); it('Should publish messages to zigbee devices with color xy', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000011/set', JSON.stringify({color: {x: 100, y: 50}})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000011'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000011'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); }); it('Should publish messages to zigbee devices with color xy and state', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); const payload = {color: {x: 100, y: 50}, state: 'ON'}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000012/set', JSON.stringify(payload)); - expect(zigbee.publish.callCount).toBe(2); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000012'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('on'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(zigbee.publish.getCall(1).args[0]).toBe('0x00000012'); - expect(zigbee.publish.getCall(1).args[1]).toBe('device'); - expect(zigbee.publish.getCall(1).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(1).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(1).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(1).args[5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); - expect(zigbee.publish.getCall(1).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(1).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000012'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000012'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('on'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(zigbee.publish.mock.calls[1][0]).toBe('0x00000012'); + expect(zigbee.publish.mock.calls[1][1]).toBe('device'); + expect(zigbee.publish.mock.calls[1][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[1][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[1][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[1][5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); + expect(zigbee.publish.mock.calls[1][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[1][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000012'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(3); + expect(zigbee.publish).toHaveBeenCalledTimes(3); } ); it('Should publish messages to zigbee devices with color xy and brightness', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); const payload = {color: {x: 100, y: 50}, brightness: 20}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000013/set', JSON.stringify(payload)); - expect(zigbee.publish.callCount).toBe(2); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000013'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 20, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(zigbee.publish.getCall(1).args[0]).toBe('0x00000013'); - expect(zigbee.publish.getCall(1).args[1]).toBe('device'); - expect(zigbee.publish.getCall(1).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(1).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(1).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(1).args[5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); - expect(zigbee.publish.getCall(1).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(1).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000013'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 20}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000013'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 20, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(zigbee.publish.mock.calls[1][0]).toBe('0x00000013'); + expect(zigbee.publish.mock.calls[1][1]).toBe('device'); + expect(zigbee.publish.mock.calls[1][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[1][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[1][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[1][5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); + expect(zigbee.publish.mock.calls[1][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[1][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000013'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 20}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(4); + expect(zigbee.publish).toHaveBeenCalledTimes(4); } ); it('Should publish messages to zigbee devices with color xy, brightness and state on', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); const payload = {color: {x: 100, y: 50}, brightness: 20, state: 'oN'}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000014/set', JSON.stringify(payload)); - expect(zigbee.publish.callCount).toBe(2); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000014'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 20, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(zigbee.publish.getCall(1).args[0]).toBe('0x00000014'); - expect(zigbee.publish.getCall(1).args[1]).toBe('device'); - expect(zigbee.publish.getCall(1).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(1).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(1).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(1).args[5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); - expect(zigbee.publish.getCall(1).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(1).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000014'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 20}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000014'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 20, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(zigbee.publish.mock.calls[1][0]).toBe('0x00000014'); + expect(zigbee.publish.mock.calls[1][1]).toBe('device'); + expect(zigbee.publish.mock.calls[1][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[1][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[1][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[1][5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); + expect(zigbee.publish.mock.calls[1][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[1][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000014'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 20}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(4); + expect(zigbee.publish).toHaveBeenCalledTimes(4); } ); it('Should publish messages to zigbee devices with color xy, brightness and state off', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); const payload = {color: {x: 100, y: 50}, brightness: 20, state: 'oFF'}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000015/set', JSON.stringify(payload)); - expect(zigbee.publish.callCount).toBe(2); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000015'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(zigbee.publish.getCall(1).args[0]).toBe('0x00000015'); - expect(zigbee.publish.getCall(1).args[1]).toBe('device'); - expect(zigbee.publish.getCall(1).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(1).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(1).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(1).args[5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); - expect(zigbee.publish.getCall(1).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(1).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000015'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'OFF'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000015'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(zigbee.publish.mock.calls[1][0]).toBe('0x00000015'); + expect(zigbee.publish.mock.calls[1][1]).toBe('device'); + expect(zigbee.publish.mock.calls[1][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[1][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[1][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[1][5]).toEqual({colorx: 6553500, colory: 3276750, transtime: 0}); + expect(zigbee.publish.mock.calls[1][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[1][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000015'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'OFF'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(3); + expect(zigbee.publish).toHaveBeenCalledTimes(3); } ); it('Should publish messages to zigbee devices with color rgb', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000016/set', JSON.stringify({color: {r: 100, g: 200, b: 10}})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000016'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({colorx: 17085, colory: 44000, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000016'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({colorx: 17085, colory: 44000, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); }); it('Should publish messages to zigbee devices with color rgb string', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000017/set', JSON.stringify({color: {rgb: '100,200,10'}})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000017'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('lightingColorCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToColor'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({colorx: 17085, colory: 44000, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000017'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToColor'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({colorx: 17085, colory: 44000, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); } ); it('Should publish 1 message when brightness with state is send', async () => { - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); + zigbee.getDevice = () => ({modelId: 'TRADFRI bulb E27 CWS opal 600lm'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000018/set', JSON.stringify({state: 'ON', brightness: '50'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe('0x00000018'); - expect(zigbee.publish.getCall(0).args[1]).toBe('device'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 50, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe('0x00000018'); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 50}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe('0x00000018'); + expect(zigbee.publish.mock.calls[0][1]).toBe('device'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 50, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe('0x00000018'); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 50}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); } ); it('Should publish messages to groups', async () => { - sinon.stub(settings, 'getGroupIDByFriendlyName').callsFake(() => '1'); - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); + jest.spyOn(settings, 'getGroupIDByFriendlyName').mockImplementation(() => '1'); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); devicePublish.onMQTTMessage('zigbee2mqtt/group/group_1/set', JSON.stringify({state: 'ON'})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe(1); - expect(zigbee.publish.getCall(0).args[1]).toBe('group'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('on'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe(1); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe(1); + expect(zigbee.publish.mock.calls[0][1]).toBe('group'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('on'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); it('Should publish messages to groups with brightness_percent', async () => { - sinon.stub(settings, 'getGroupIDByFriendlyName').callsFake(() => '1'); - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); + jest.spyOn(settings, 'getGroupIDByFriendlyName').mockImplementation(() => '1'); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); devicePublish.onMQTTMessage('zigbee2mqtt/group/group_1/set', JSON.stringify({brightness_percent: 50})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe(1); - expect(zigbee.publish.getCall(0).args[1]).toBe('group'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 127, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe(1); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 127}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe(1); + expect(zigbee.publish.mock.calls[0][1]).toBe('group'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 127, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 127}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); it('Should publish messages to groups with on and brightness', async () => { - sinon.stub(settings, 'getGroupIDByFriendlyName').callsFake(() => '1'); - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); + jest.spyOn(settings, 'getGroupIDByFriendlyName').mockImplementation(() => '1'); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); devicePublish.onMQTTMessage('zigbee2mqtt/group/group_1/set', JSON.stringify({state: 'ON', brightness: 50})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe(1); - expect(zigbee.publish.getCall(0).args[1]).toBe('group'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genLevelCtrl'); - expect(zigbee.publish.getCall(0).args[3]).toBe('moveToLevelWithOnOff'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({level: 50, transtime: 0}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe(1); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'ON', brightness: 50}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe(1); + expect(zigbee.publish.mock.calls[0][1]).toBe('group'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genLevelCtrl'); + expect(zigbee.publish.mock.calls[0][3]).toBe('moveToLevelWithOnOff'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({level: 50, transtime: 0}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'ON', brightness: 50}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); it('Should publish messages to groups with off and brightness', async () => { - sinon.stub(settings, 'getGroupIDByFriendlyName').callsFake(() => '1'); - zigbee.publish.resetHistory(); - publishEntityState.resetHistory(); + jest.spyOn(settings, 'getGroupIDByFriendlyName').mockImplementation(() => '1'); + zigbee.publish.mockClear(); + publishEntityState.mockClear(); devicePublish.onMQTTMessage('zigbee2mqtt/group/group_1/set', JSON.stringify({state: 'OFF', brightness: 5})); - expect(zigbee.publish.callCount).toBe(1); - expect(zigbee.publish.getCall(0).args[0]).toBe(1); - expect(zigbee.publish.getCall(0).args[1]).toBe('group'); - expect(zigbee.publish.getCall(0).args[2]).toBe('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toBe('off'); - expect(zigbee.publish.getCall(0).args[4]).toBe('functional'); - expect(zigbee.publish.getCall(0).args[5]).toEqual({}); - expect(zigbee.publish.getCall(0).args[6]).toEqual(cfg.default); - expect(zigbee.publish.getCall(0).args[7]).toBeNull(); - expect(publishEntityState.callCount).toBe(1); - expect(publishEntityState.getCall(0).args[0]).toBe(1); - expect(publishEntityState.getCall(0).args[1]).toEqual({state: 'OFF'}); - expect(publishEntityState.getCall(0).args[2]).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(1); + expect(zigbee.publish.mock.calls[0][0]).toBe(1); + expect(zigbee.publish.mock.calls[0][1]).toBe('group'); + expect(zigbee.publish.mock.calls[0][2]).toBe('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toBe('off'); + expect(zigbee.publish.mock.calls[0][4]).toBe('functional'); + expect(zigbee.publish.mock.calls[0][5]).toEqual({}); + expect(zigbee.publish.mock.calls[0][6]).toEqual(cfg.default); + expect(zigbee.publish.mock.calls[0][7]).toBeNull(); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][0]).toBe(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({state: 'OFF'}); + expect(publishEntityState.mock.calls[0][2]).toBe(true); await wait(10); - expect(zigbee.publish.callCount).toBe(1); + expect(zigbee.publish).toHaveBeenCalledTimes(1); }); }); @@ -594,7 +592,7 @@ describe('DevicePublish', () => { }); it('Should parse topic with when base topic has multiple slashes', () => { - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { mqtt: { base_topic: 'zigbee2mqtt/at/my/home', @@ -618,7 +616,7 @@ describe('DevicePublish', () => { }); it('Should parse topic with when base and deviceID have multiple slashes', () => { - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { mqtt: { base_topic: 'zigbee2mqtt/at/my/basement', @@ -683,7 +681,7 @@ describe('DevicePublish', () => { }); it('Should parse set with and slashes in base and deviceID postfix topic', () => { - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { mqtt: { base_topic: 'zigbee2mqtt/at/my/home', @@ -701,42 +699,42 @@ describe('DevicePublish', () => { }); it('Should not publish messages to zigbee devices when payload is invalid', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'lumi.ctrl_neutral1'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'lumi.ctrl_neutral1'}); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000019/set', JSON.stringify({state: true})); await wait(10); - expect(zigbee.publish.notCalled).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(0); devicePublish.onMQTTMessage('zigbee2mqtt/0x00000019/set', JSON.stringify({state: 1})); await wait(10); - expect(zigbee.publish.notCalled).toBe(true); + expect(zigbee.publish).toHaveBeenCalledTimes(0); } ); it('Should set state before color', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'LCT001'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'LCT001'}); const msg = {'state': 'ON', 'color': {'x': 0.701, 'y': 0.299}}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000020/set', JSON.stringify(msg)); - expect(zigbee.publish.callCount).toEqual(2); - expect(zigbee.publish.getCall(0).args[2]).toEqual('genOnOff'); - expect(zigbee.publish.getCall(0).args[3]).toEqual('on'); - expect(zigbee.publish.getCall(1).args[2]).toEqual('lightingColorCtrl'); - expect(zigbee.publish.getCall(1).args[3]).toEqual('moveToColor'); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][2]).toEqual('genOnOff'); + expect(zigbee.publish.mock.calls[0][3]).toEqual('on'); + expect(zigbee.publish.mock.calls[1][2]).toEqual('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[1][3]).toEqual('moveToColor'); await wait(10); - expect(zigbee.publish.callCount).toEqual(3); - expect(zigbee.publish.getCall(2).args[2]).toEqual('lightingColorCtrl'); - expect(zigbee.publish.getCall(2).args[3]).toEqual('read'); + expect(zigbee.publish).toHaveBeenCalledTimes(3); + expect(zigbee.publish.mock.calls[2][2]).toEqual('lightingColorCtrl'); + expect(zigbee.publish.mock.calls[2][3]).toEqual('read'); }); it('Should set state with brightness before color', async () => { - zigbee.publish.resetHistory(); - zigbee.getDevice = sinon.fake.returns({modelId: 'LCT001'}); + zigbee.publish.mockClear(); + zigbee.getDevice = () => ({modelId: 'LCT001'}); const msg = {'state': 'ON', 'color': {'x': 0.701, 'y': 0.299}, 'transition': 3, 'brightness': 100}; devicePublish.onMQTTMessage('zigbee2mqtt/0x00000021/set', JSON.stringify(msg)); - expect(zigbee.publish.callCount).toBe(2); - expect(zigbee.publish.getCall(0).args[2]).toEqual('genLevelCtrl'); - expect(zigbee.publish.getCall(1).args[2]).toEqual('lightingColorCtrl'); + expect(zigbee.publish).toHaveBeenCalledTimes(2); + expect(zigbee.publish.mock.calls[0][2]).toEqual('genLevelCtrl'); + expect(zigbee.publish.mock.calls[1][2]).toEqual('lightingColorCtrl'); await wait(10); - expect(zigbee.publish.callCount).toBe(2); + expect(zigbee.publish).toHaveBeenCalledTimes(2); }); }); diff --git a/test/deviceReceive.test.js b/test/deviceReceive.test.js index 348428226..e3be20c72 100644 --- a/test/deviceReceive.test.js +++ b/test/deviceReceive.test.js @@ -1,4 +1,3 @@ -const sinon = require('sinon'); const DeviceReceive = require('../lib/extension/deviceReceive'); const settings = require('../lib/util/settings'); const devices = require('zigbee-shepherd-converters').devices; @@ -19,14 +18,14 @@ describe('DeviceReceive', () => { let publishEntityState; beforeEach(() => { - utils.stubLogger(sinon); - sinon.stub(settings, 'addDevice').callsFake(() => {}); - publishEntityState = sinon.spy(); + utils.stubLogger(jest); + jest.spyOn(settings, 'addDevice').mockImplementation(() => {}); + publishEntityState = jest.fn(); deviceReceive = new DeviceReceive(null, mqtt, null, publishEntityState); }); afterEach(() => { - sinon.restore(); + jest.restoreAllMocks(); }); describe('Handling zigbee messages', () => { @@ -34,24 +33,24 @@ describe('DeviceReceive', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); deviceReceive.onZigbeeMessage(message, device, WXKG11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({click: 'single'}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({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); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({click: 'left'}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({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); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({click: 'right'}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({click: 'right'}); }); it('Should handle a zigbee message with default precision', () => { @@ -60,39 +59,39 @@ describe('DeviceReceive', () => { device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1 ); deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({temperature: -0.85}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({temperature: -0.85}); }); it('Should handle a zigbee message with 1 precision', () => { const device = {ieeeAddr: '0x12345678'}; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return {temperature_precision: 1}; }); const message = utils.zigbeeMessage( device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1 ); deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({temperature: -0.8}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({temperature: -0.8}); }); it('Should handle a zigbee message with 0 precision', () => { const device = {ieeeAddr: '0x12345678'}; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return {temperature_precision: 0}; }); const message = utils.zigbeeMessage( device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1 ); deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({temperature: -1}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({temperature: -1}); }); it('Should handle a zigbee message with 1 precision when set via device_options', () => { const device = {ieeeAddr: '0x12345678'}; - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { device_options: { temperature_precision: 1, @@ -102,21 +101,21 @@ describe('DeviceReceive', () => { }, }; }); - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return {}; }); const message = utils.zigbeeMessage( device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1 ); deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({temperature: -0.8}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({temperature: -0.8}); } ); it('Should handle a zigbee message with 2 precision when overrides device_options', () => { const device = {ieeeAddr: '0x12345678'}; - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { device_options: { temperature_precision: 1, @@ -126,7 +125,7 @@ describe('DeviceReceive', () => { }, }; }); - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return { temperature_precision: 2, }; @@ -135,8 +134,8 @@ describe('DeviceReceive', () => { device, 'msTemperatureMeasurement', 'attReport', {measuredValue: -85}, 1 ); deviceReceive.onZigbeeMessage(message, device, WSDCGQ11LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(publishEntityState.getCall(0).args[1]).toEqual({temperature: -0.85}); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(publishEntityState.mock.calls[0][1]).toEqual({temperature: -0.85}); } ); @@ -144,36 +143,36 @@ describe('DeviceReceive', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genBasic', 'attReport', {'65281': {'1': 3010}}, 1); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - expect(publishEntityState.calledOnce).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(1); const expected = {battery: 100, voltage: 3010}; - expect(publishEntityState.getCall(0).args[1]).toEqual(expected); + expect(publishEntityState.mock.calls[0][1]).toEqual(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); - expect(publishEntityState.calledOnce).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(1); const expected = {battery: 35, voltage: 2850}; - expect(publishEntityState.getCall(0).args[1]).toEqual(expected); + expect(publishEntityState.mock.calls[0][1]).toEqual(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); - expect(publishEntityState.calledOnce).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(1); const expected = {battery: 14, voltage: 2650}; - expect(publishEntityState.getCall(0).args[1]).toEqual(expected); + expect(publishEntityState.mock.calls[0][1]).toEqual(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); - expect(publishEntityState.calledOnce).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(1); const expected = {battery: 0, voltage: 2000}; - expect(publishEntityState.getCall(0).args[1]).toEqual(expected); + expect(publishEntityState.mock.calls[0][1]).toEqual(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); - expect(publishEntityState.calledOnce).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(1); const expected = {'battery': 100, 'illuminance': 381, 'voltage': 3045}; - expect(publishEntityState.getCall(0).args[1]).toEqual(expected); + expect(publishEntityState.mock.calls[0][1]).toEqual(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); - expect(publishEntityState.notCalled).toBe(true); + expect(publishEntityState).toHaveBeenCalledTimes(0); }); it('Should publish last_seen epoch', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { advanced: { last_seen: 'epoch', @@ -207,14 +206,14 @@ describe('DeviceReceive', () => { }; }); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(typeof publishEntityState.getCall(0).args[1].last_seen).toEqual('number'); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(typeof publishEntityState.mock.calls[0][1].last_seen).toEqual('number'); }); it('Should publish last_seen ISO_8601', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { advanced: { last_seen: 'ISO_8601', @@ -222,14 +221,14 @@ describe('DeviceReceive', () => { }; }); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(typeof publishEntityState.getCall(0).args[1].last_seen).toEqual('string'); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(typeof publishEntityState.mock.calls[0][1].last_seen).toEqual('string'); }); it('Should publish last_seen ISO_8601_local', () => { const device = {ieeeAddr: '0x12345678'}; const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1); - sinon.stub(settings, 'get').callsFake(() => { + jest.spyOn(settings, 'get').mockImplementation(() => { return { advanced: { last_seen: 'ISO_8601_local', @@ -237,8 +236,8 @@ describe('DeviceReceive', () => { }; }); deviceReceive.onZigbeeMessage(message, device, WXKG02LM); - expect(publishEntityState.calledOnce).toBe(true); - expect(typeof publishEntityState.getCall(0).args[1].last_seen).toEqual('string'); + expect(publishEntityState).toHaveBeenCalledTimes(1); + expect(typeof publishEntityState.mock.calls[0][1].last_seen).toEqual('string'); }); }); }); diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index 1ffc2b9de..83559f653 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -1,6 +1,5 @@ const devices = require('zigbee-shepherd-converters').devices; const HomeassistantExtension = require('../lib/extension/homeassistant'); -const sinon = require('sinon'); const settings = require('../lib/util/settings'); const WSDCGQ11LM = devices.find((d) => d.model === 'WSDCGQ11LM'); @@ -12,7 +11,7 @@ describe('HomeAssistant extension', () => { beforeEach(() => { mqtt = { - publish: sinon.spy(), + publish: jest.fn(), }; homeassistant = new HomeassistantExtension(null, mqtt, null, null); @@ -20,7 +19,7 @@ describe('HomeAssistant extension', () => { }); afterEach(() => { - sinon.restore(); + jest.restoreAllMocks(); }); it('Should have mapping for all devices supported by zigbee-shepherd-converters', () => { @@ -38,12 +37,12 @@ describe('HomeAssistant extension', () => { it('Should discover devices', () => { let payload = null; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return {friendly_name: 'my_device'}; }); homeassistant.discover('0x12345678', WSDCGQ11LM, false); - expect(mqtt.publish.callCount).toEqual(5); + expect(mqtt.publish).toHaveBeenCalledTimes(5); // 1 payload = { @@ -64,10 +63,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(0).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(0).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(0).args[3]).toBeNull(); - expect(mqtt.publish.getCall(0).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[0][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[0][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[0][3]).toBeNull(); + expect(mqtt.publish.mock.calls[0][4]).toEqual('homeassistant'); // 2 payload = { @@ -88,10 +87,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(1).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(1).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(1).args[3]).toBeNull(); - expect(mqtt.publish.getCall(1).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[1][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[1][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[1][3]).toBeNull(); + expect(mqtt.publish.mock.calls[1][4]).toEqual('homeassistant'); // 3 payload = { @@ -112,10 +111,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(2).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(2).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(2).args[3]).toBeNull(); - expect(mqtt.publish.getCall(2).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[2][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[2][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[2][3]).toBeNull(); + expect(mqtt.publish.mock.calls[2][4]).toEqual('homeassistant'); // 4 payload = { @@ -136,10 +135,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(3).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(3).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(3).args[3]).toBeNull(); - expect(mqtt.publish.getCall(3).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[3][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[3][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[3][3]).toBeNull(); + expect(mqtt.publish.mock.calls[3][4]).toEqual('homeassistant'); // 5 payload = { @@ -159,15 +158,15 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(4).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(4).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(4).args[3]).toBeNull(); - expect(mqtt.publish.getCall(4).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[4][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[4][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[4][3]).toBeNull(); + expect(mqtt.publish.mock.calls[4][4]).toEqual('homeassistant'); }); it('Should discover devices with precision', () => { let payload = null; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return { friendly_name: 'my_device', humidity_precision: 0, @@ -177,7 +176,7 @@ describe('HomeAssistant extension', () => { }); homeassistant.discover('0x12345678', WSDCGQ11LM, false); - expect(mqtt.publish.callCount).toEqual(5); + expect(mqtt.publish).toHaveBeenCalledTimes(5); // 1 payload = { @@ -198,10 +197,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(0).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(0).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(0).args[3]).toBeNull(); - expect(mqtt.publish.getCall(0).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[0][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[0][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[0][3]).toBeNull(); + expect(mqtt.publish.mock.calls[0][4]).toEqual('homeassistant'); // 2 payload = { @@ -222,10 +221,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(1).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(1).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(1).args[3]).toBeNull(); - expect(mqtt.publish.getCall(1).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[1][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[1][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[1][3]).toBeNull(); + expect(mqtt.publish.mock.calls[1][4]).toEqual('homeassistant'); // 3 payload = { @@ -246,10 +245,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(2).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(2).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(2).args[3]).toBeNull(); - expect(mqtt.publish.getCall(2).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[2][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[2][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[2][3]).toBeNull(); + expect(mqtt.publish.mock.calls[2][4]).toEqual('homeassistant'); // 4 payload = { @@ -270,10 +269,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(3).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(3).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(3).args[3]).toBeNull(); - expect(mqtt.publish.getCall(3).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[3][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[3][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[3][3]).toBeNull(); + expect(mqtt.publish.mock.calls[3][4]).toEqual('homeassistant'); // 5 payload = { @@ -293,15 +292,15 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(4).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(4).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(4).args[3]).toBeNull(); - expect(mqtt.publish.getCall(4).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[4][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[4][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[4][3]).toBeNull(); + expect(mqtt.publish.mock.calls[4][4]).toEqual('homeassistant'); }); it('Should discover devices with overriden user configuration', () => { let payload = null; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return { friendly_name: 'my_device', homeassistant: { @@ -315,7 +314,7 @@ describe('HomeAssistant extension', () => { }); homeassistant.discover('0x12345678', WSDCGQ11LM, false); - expect(mqtt.publish.callCount).toEqual(5); + expect(mqtt.publish).toHaveBeenCalledTimes(5); // 1 payload = { @@ -338,10 +337,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(0).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(0).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(0).args[3]).toBeNull(); - expect(mqtt.publish.getCall(0).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[0][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[0][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[0][3]).toBeNull(); + expect(mqtt.publish.mock.calls[0][4]).toEqual('homeassistant'); // 2 payload = { @@ -364,10 +363,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(1).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(1).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(1).args[3]).toBeNull(); - expect(mqtt.publish.getCall(1).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[1][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[1][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[1][3]).toBeNull(); + expect(mqtt.publish.mock.calls[1][4]).toEqual('homeassistant'); // 3 payload = { @@ -390,10 +389,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(2).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(2).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(2).args[3]).toBeNull(); - expect(mqtt.publish.getCall(2).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[2][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[2][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[2][3]).toBeNull(); + expect(mqtt.publish.mock.calls[2][4]).toEqual('homeassistant'); // 4 payload = { @@ -416,10 +415,10 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(3).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(3).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(3).args[3]).toBeNull(); - expect(mqtt.publish.getCall(3).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[3][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[3][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[3][3]).toBeNull(); + expect(mqtt.publish.mock.calls[3][4]).toEqual('homeassistant'); // 5 payload = { @@ -441,20 +440,20 @@ describe('HomeAssistant extension', () => { 'availability_topic': 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(4).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(4).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(4).args[3]).toBeNull(); - expect(mqtt.publish.getCall(4).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[4][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[4][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[4][3]).toBeNull(); + expect(mqtt.publish.mock.calls[4][4]).toEqual('homeassistant'); }); it('Should discover devices with cover_position', () => { let payload = null; - sinon.stub(settings, 'getDevice').callsFake(() => { + jest.spyOn(settings, 'getDevice').mockImplementation(() => { return {friendly_name: 'my_device'}; }); homeassistant.discover('0x12345678', SV01, false); - expect(mqtt.publish.callCount).toEqual(5); + expect(mqtt.publish).toHaveBeenCalledTimes(5); // 1 payload = { @@ -475,9 +474,9 @@ describe('HomeAssistant extension', () => { availability_topic: 'zigbee2mqtt/bridge/state', }; - expect(JSON.parse(mqtt.publish.getCall(0).args[1])).toEqual(payload); - expect(mqtt.publish.getCall(0).args[2]).toEqual({retain: true, qos: 0}); - expect(mqtt.publish.getCall(0).args[3]).toBeNull(); - expect(mqtt.publish.getCall(0).args[4]).toEqual('homeassistant'); + expect(JSON.parse(mqtt.publish.mock.calls[0][1])).toEqual(payload); + expect(mqtt.publish.mock.calls[0][2]).toEqual({retain: true, qos: 0}); + expect(mqtt.publish.mock.calls[0][3]).toBeNull(); + expect(mqtt.publish.mock.calls[0][4]).toEqual('homeassistant'); }); }); diff --git a/test/settings.test.js b/test/settings.test.js index 3e2a4bf2e..47f98e0d9 100644 --- a/test/settings.test.js +++ b/test/settings.test.js @@ -1,4 +1,3 @@ -const sinon = require('sinon'); const objectAssignDeep = require('object-assign-deep'); const data = require('../lib/util/data'); @@ -17,15 +16,15 @@ describe('Settings', () => { const files = new Map(); beforeAll(() => { - sinon.stub(fs, 'readYaml').callsFake((file) => { + jest.spyOn(fs, 'readYaml').mockImplementation((file) => { if (files.has(file)) return objectAssignDeep.noMutate(files.get(file)); throw new Error(`Fake file not found: ${file}`); }); - sinon.stub(fs, 'readYamlIfExists').callsFake((file) => { + jest.spyOn(fs, 'readYamlIfExists').mockImplementation((file) => { if (files.has(file)) return objectAssignDeep.noMutate(files.get(file)); return null; }); - sinon.stub(fs, 'writeYaml').callsFake((file, content) => { + jest.spyOn(fs, 'writeYaml').mockImplementation((file, content) => { files.set(file, objectAssignDeep.noMutate(content)); }); }); @@ -36,9 +35,9 @@ describe('Settings', () => { }); afterAll(() => { - fs.readYaml.restore(); - fs.readYamlIfExists.restore(); - fs.writeYaml.restore(); + fs.readYaml.mockRestore(); + fs.readYamlIfExists.mockRestore(); + fs.writeYaml.mockRestore(); }); describe('Settings', () => { diff --git a/test/utils.js b/test/utils.js index 9f7fefd1b..27a46882e 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,11 +1,11 @@ const logger = require('../lib/util/logger'); module.exports = { - stubLogger: (sandbox) => { - sandbox.stub(logger, 'info').callsFake(() => {}); - sandbox.stub(logger, 'warn').callsFake(() => {}); - sandbox.stub(logger, 'debug').callsFake(() => {}); - sandbox.stub(logger, 'error').callsFake(() => {}); + stubLogger: (jest) => { + jest.spyOn(logger, 'info').mockImplementation(() => {}); + jest.spyOn(logger, 'warn').mockImplementation(() => {}); + jest.spyOn(logger, 'debug').mockImplementation(() => {}); + jest.spyOn(logger, 'error').mockImplementation(() => {}); }, zigbeeMessage: (device, cid, type, data, epId) => { return {data: {cid, data}, type, endpoints: [{device, epId}]};