From 024aaa8a2c2522fa2ba2ffd4bfa9873dd77cf3a5 Mon Sep 17 00:00:00 2001 From: Martin M Date: Wed, 11 Sep 2019 23:46:17 -0300 Subject: [PATCH] Release v1.4.1 (#13) * specific error when requested channel is bigger than total * fix for multi-channel devices * updated test expectations * fixes with uiid api changes * fix wrong error message * added new test cases * return expected error on wrong channel number * added more devices * version bump --- main.js | 33 +++++++--- package-lock.json | 2 +- package.json | 2 +- test/_setup/credentials.json | 5 +- test/_setup/expectations.js | 12 +++- test/main-env-node.spec.js | 95 ++++++++++++++++++++++----- test/main-env-serverless.spec.js | 38 +++++++---- test/main-invalid-credentials.spec.js | 21 ++++-- test/main-valid-credentials.spec.js | 33 ++++++++-- test/power-usage.spec.js | 1 + 10 files changed, 190 insertions(+), 52 deletions(-) diff --git a/main.js b/main.js index b7ffcdf..cd3e519 100644 --- a/main.js +++ b/main.js @@ -165,11 +165,18 @@ class eWeLink { async getDevicePowerState(deviceId, channel = 1) { const device = await this.getDevice(deviceId); const error = _get(device, 'error', false); + const uiid = _get(device, 'extra.extra.uiid', false); + let state = _get(device, 'params.switch', false); const switches = _get(device, 'params.switches', false); - const switchesAmount = getDeviceChannelCount(device.uiid); - if (error || switchesAmount < channel || (!state && !switches)) { + const switchesAmount = getDeviceChannelCount(uiid); + + if (switchesAmount > 0 && switchesAmount < channel) { + return { error, msg: 'Device channel does not exist' }; + } + + if (error || (!state && !switches)) { if (error && parseInt(error) === 401) { return device; } @@ -195,11 +202,18 @@ class eWeLink { async setDevicePowerState(deviceId, state, channel = 1) { const device = await this.getDevice(deviceId); const error = _get(device, 'error', false); - const status = _get(device, 'params.switch', false); - const switches = _get(device, 'params.switches', false); - const switchesAmount = getDeviceChannelCount(device.uiid); + const uiid = _get(device, 'extra.extra.uiid', false); - if (error || switchesAmount < channel || (!status && !switches)) { + let status = _get(device, 'params.switch', false); + const switches = _get(device, 'params.switches', false); + + const switchesAmount = getDeviceChannelCount(uiid); + + if (switchesAmount > 0 && switchesAmount < channel) { + return { error, msg: 'Device channel does not exist' }; + } + + if (error || (!status && !switches)) { if (error && parseInt(error) === 401) { return device; } @@ -207,13 +221,16 @@ class eWeLink { } let stateToSwitch = state; + const params = {}; + + if (switches) { + status = switches[channel - 1].switch; + } if (state === 'toggle') { stateToSwitch = status === 'on' ? 'off' : 'on'; } - const params = {}; - if (switches) { params.switches = switches; params.switches[channel - 1].switch = stateToSwitch; diff --git a/package-lock.json b/package-lock.json index d7700a0..d9c1bee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.3.0", + "version": "1.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 408c3d0..5801aa2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.4.0", + "version": "1.4.1", "description": "eWeLink API for Node.js", "author": "Martín M.", "license": "MIT", diff --git a/test/_setup/credentials.json b/test/_setup/credentials.json index 10c70aa..fad99fd 100644 --- a/test/_setup/credentials.json +++ b/test/_setup/credentials.json @@ -1,7 +1,8 @@ { "email": "", "password": "", - "deviceId": "", + "singleChannelDeviceId": "", "deviceIdWithPower": "", - "deviceIdWithoutPower": "" + "deviceIdWithoutPower": "", + "fourChannelsDevice": "" } \ No newline at end of file diff --git a/test/_setup/expectations.js b/test/_setup/expectations.js index ff16dc8..4c674e1 100644 --- a/test/_setup/expectations.js +++ b/test/_setup/expectations.js @@ -10,7 +10,11 @@ const allDevicesExpectations = { apikey: expect.any(String), params: expect.any(Object), showBrand: expect.any(Boolean), - uiid: expect.any(Number), + extra: { + extra: { + uiid: expect.any(Number), + }, + }, }; const specificDeviceExpectations = { @@ -18,7 +22,11 @@ const specificDeviceExpectations = { deviceid: expect.any(String), apikey: expect.any(String), online: expect.any(Boolean), - uiid: expect.any(Number), + extra: { + extra: { + uiid: expect.any(Number), + }, + }, }; const rawPowerUsageExpectations = { diff --git a/test/main-env-node.spec.js b/test/main-env-node.spec.js index 8369263..50efdc5 100644 --- a/test/main-env-node.spec.js +++ b/test/main-env-node.spec.js @@ -1,7 +1,12 @@ const delay = require('delay'); const ewelink = require('../main'); -const { email, password, deviceId } = require('./_setup/credentials.json'); +const { + email, + password, + singleChannelDeviceId, + fourChannelsDevice, +} = require('./_setup/credentials.json'); const { loginExpectations, allDevicesExpectations, @@ -15,6 +20,10 @@ describe('env: node script', () => { conn = new ewelink({ email, password }); }); + beforeEach(async () => { + await delay(1000); + }); + test('login into ewelink', async () => { const login = await conn.login(); expect(typeof login).toBe('object'); @@ -28,49 +37,103 @@ describe('env: node script', () => { }); test('get specific device', async () => { - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); expect(typeof device).toBe('object'); - expect(device.deviceid).toBe(deviceId); + expect(device.deviceid).toBe(singleChannelDeviceId); expect(device).toMatchObject(specificDeviceExpectations); }); - test('get device power state', async () => { - const device = await conn.getDevice(deviceId); + test('get single channel device power state', async () => { + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; - const powerState = await conn.getDevicePowerState(deviceId); + const powerState = await conn.getDevicePowerState(singleChannelDeviceId); expect(typeof powerState).toBe('object'); expect(powerState.status).toBe('ok'); expect(powerState.state).toBe(currentState); }); - test('set device power state', async () => { + test('get multi channel device power state', async () => { + const channel = 3; + const device = await conn.getDevice(fourChannelsDevice); + const currentState = device.params.switches[channel - 1].switch; + const powerState = await conn.getDevicePowerState( + fourChannelsDevice, + channel + ); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(currentState); + }); + + test('set single channel device power state', async () => { jest.setTimeout(30000); await delay(3000); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; const newState = currentState === 'on' ? 'off' : 'on'; - const powerState = await conn.setDevicePowerState(deviceId, newState); + const powerState = await conn.setDevicePowerState( + singleChannelDeviceId, + newState + ); expect(typeof powerState).toBe('object'); expect(powerState.status).toBe('ok'); expect(powerState.state).toBe(newState); - const deviceVerify = await conn.getDevice(deviceId); + const deviceVerify = await conn.getDevice(singleChannelDeviceId); const currentStateVerify = deviceVerify.params.switch; expect(newState).toBe(currentStateVerify); }); - test('toggle device power state', async () => { + test('set multi channel device power state', async () => { jest.setTimeout(30000); await delay(3000); - const device = await conn.getDevice(deviceId); + const channel = 3; + const device = await conn.getDevice(fourChannelsDevice); + const currentState = device.params.switches[channel - 1].switch; + const newState = currentState === 'on' ? 'off' : 'on'; + const powerState = await conn.setDevicePowerState( + fourChannelsDevice, + newState, + channel + ); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(newState); + const deviceVerify = await conn.getDevice(fourChannelsDevice); + const currentStateVerify = deviceVerify.params.switches[channel - 1].switch; + expect(newState).toBe(currentStateVerify); + }); + + test('toggle single channel device power state', async () => { + jest.setTimeout(30000); + await delay(3000); + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; const newState = currentState === 'on' ? 'off' : 'on'; - await conn.toggleDevice(deviceId); - const deviceVerify = await conn.getDevice(deviceId); + await conn.toggleDevice(singleChannelDeviceId); + const deviceVerify = await conn.getDevice(singleChannelDeviceId); const currentStateVerify = deviceVerify.params.switch; expect(newState).toBe(currentStateVerify); - await conn.toggleDevice(deviceId); - const deviceVerifyAgain = await conn.getDevice(deviceId); + await conn.toggleDevice(singleChannelDeviceId); + const deviceVerifyAgain = await conn.getDevice(singleChannelDeviceId); const currentStateVerifyAgain = deviceVerifyAgain.params.switch; expect(currentState).toBe(currentStateVerifyAgain); }); + + test('toggle multi channel device power state', async () => { + jest.setTimeout(30000); + await delay(3000); + const channel = 3; + const device = await conn.getDevice(fourChannelsDevice); + const currentState = device.params.switches[channel - 1].switch; + const newState = currentState === 'on' ? 'off' : 'on'; + await conn.toggleDevice(fourChannelsDevice, channel); + const deviceVerify = await conn.getDevice(fourChannelsDevice); + const currentStateVerify = deviceVerify.params.switches[channel - 1].switch; + expect(newState).toBe(currentStateVerify); + await conn.toggleDevice(fourChannelsDevice, channel); + const deviceVerifyAgain = await conn.getDevice(fourChannelsDevice); + const currentStateVerifyAgain = + deviceVerifyAgain.params.switches[channel - 1].switch; + expect(currentState).toBe(currentStateVerifyAgain); + }); }); diff --git a/test/main-env-serverless.spec.js b/test/main-env-serverless.spec.js index 9af7be7..99f0f0b 100644 --- a/test/main-env-serverless.spec.js +++ b/test/main-env-serverless.spec.js @@ -1,7 +1,12 @@ const delay = require('delay'); const ewelink = require('../main'); -const { email, password, deviceId } = require('./_setup/credentials.json'); + +const { + email, + password, + singleChannelDeviceId, +} = require('./_setup/credentials.json'); const { loginExpectations, allDevicesExpectations, @@ -12,6 +17,10 @@ describe('env: serverless', () => { let accessToken; let apiKey; + beforeEach(async () => { + await delay(1000); + }); + test('login into ewelink', async () => { const conn = new ewelink({ email, password }); const login = await conn.login(); @@ -30,17 +39,17 @@ describe('env: serverless', () => { test('get specific device', async () => { const conn = new ewelink({ at: accessToken }); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); expect(typeof device).toBe('object'); - expect(device.deviceid).toBe(deviceId); + expect(device.deviceid).toBe(singleChannelDeviceId); expect(device).toMatchObject(specificDeviceExpectations); }); test('get device power state', async () => { const conn = new ewelink({ at: accessToken }); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; - const powerState = await conn.getDevicePowerState(deviceId); + const powerState = await conn.getDevicePowerState(singleChannelDeviceId); expect(typeof powerState).toBe('object'); expect(powerState.status).toBe('ok'); expect(powerState.state).toBe(currentState); @@ -50,14 +59,17 @@ describe('env: serverless', () => { jest.setTimeout(30000); await delay(3000); const conn = new ewelink({ at: accessToken, apiKey }); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; const newState = currentState === 'on' ? 'off' : 'on'; - const powerState = await conn.setDevicePowerState(deviceId, newState); + const powerState = await conn.setDevicePowerState( + singleChannelDeviceId, + newState + ); expect(typeof powerState).toBe('object'); expect(powerState.status).toBe('ok'); expect(powerState.state).toBe(newState); - const deviceVerify = await conn.getDevice(deviceId); + const deviceVerify = await conn.getDevice(singleChannelDeviceId); const currentStateVerify = deviceVerify.params.switch; expect(newState).toBe(currentStateVerify); }); @@ -66,15 +78,15 @@ describe('env: serverless', () => { jest.setTimeout(30000); await delay(3000); const conn = new ewelink({ at: accessToken, apiKey }); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); const currentState = device.params.switch; const newState = currentState === 'on' ? 'off' : 'on'; - await conn.toggleDevice(deviceId); - const deviceVerify = await conn.getDevice(deviceId); + await conn.toggleDevice(singleChannelDeviceId); + const deviceVerify = await conn.getDevice(singleChannelDeviceId); const currentStateVerify = deviceVerify.params.switch; expect(newState).toBe(currentStateVerify); - await conn.toggleDevice(deviceId); - const deviceVerifyAgain = await conn.getDevice(deviceId); + await conn.toggleDevice(singleChannelDeviceId); + const deviceVerifyAgain = await conn.getDevice(singleChannelDeviceId); const currentStateVerifyAgain = deviceVerifyAgain.params.switch; expect(currentState).toBe(currentStateVerifyAgain); }); diff --git a/test/main-invalid-credentials.spec.js b/test/main-invalid-credentials.spec.js index 108cbab..ac11fa2 100644 --- a/test/main-invalid-credentials.spec.js +++ b/test/main-invalid-credentials.spec.js @@ -1,7 +1,17 @@ +const delay = require('delay'); + const ewelink = require('../main'); -const { deviceId, deviceIdWithPower } = require('./_setup/credentials.json'); + +const { + singleChannelDeviceId, + deviceIdWithPower, +} = require('./_setup/credentials.json'); describe('invalid credentials', () => { + beforeEach(async () => { + await delay(1000); + }); + test('no credentials given', async () => { const conn = new ewelink({}); expect(typeof conn).toBe('object'); @@ -26,7 +36,7 @@ describe('invalid credentials', () => { test('get error response on specific device', async () => { const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const device = await conn.getDevice(deviceId); + const device = await conn.getDevice(singleChannelDeviceId); expect(typeof device).toBe('object'); expect(device.msg).toBe('Authentication error'); expect(device.error).toBe(401); @@ -34,7 +44,7 @@ describe('invalid credentials', () => { test('get device power state should fail', async () => { const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const powerState = await conn.getDevicePowerState(deviceId); + const powerState = await conn.getDevicePowerState(singleChannelDeviceId); expect(typeof powerState).toBe('object'); expect(powerState.msg).toBe('Authentication error'); expect(powerState.error).toBe(401); @@ -43,7 +53,10 @@ describe('invalid credentials', () => { test('set device power state should fail', async () => { jest.setTimeout(30000); const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const powerState = await conn.setDevicePowerState(deviceId, 'on'); + const powerState = await conn.setDevicePowerState( + singleChannelDeviceId, + 'on' + ); expect(typeof powerState).toBe('object'); expect(powerState.msg).toBe('Authentication error'); expect(powerState.error).toBe(401); diff --git a/test/main-valid-credentials.spec.js b/test/main-valid-credentials.spec.js index fc91b4b..1678c9c 100644 --- a/test/main-valid-credentials.spec.js +++ b/test/main-valid-credentials.spec.js @@ -6,7 +6,9 @@ const { email, password, deviceIdWithoutPower, + fourChannelsDevice, } = require('./_setup/credentials.json'); + const { loginExpectations } = require('./_setup/expectations'); describe('valid credentials, invalid device', () => { @@ -14,7 +16,7 @@ describe('valid credentials, invalid device', () => { await delay(1000); }); - test('get device power state should fail', async () => { + test('get power state on invalid device should fail', async () => { const conn = new ewelink({ email, password }); const powerState = await conn.getDevicePowerState('invalid deviceid'); expect(typeof powerState).toBe('object'); @@ -22,7 +24,15 @@ describe('valid credentials, invalid device', () => { expect(powerState.error).toBe(500); }); - test('set device power state should fail', async () => { + test('get power state on wrong device channel should fail', async () => { + const conn = new ewelink({ email, password }); + const powerState = await conn.getDevicePowerState(fourChannelsDevice, 8); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Device channel does not exist'); + expect(powerState.error).toBe(false); + }); + + test('set power state on invalid device should fail', async () => { jest.setTimeout(30000); const conn = new ewelink({ email, password }); const powerState = await conn.setDevicePowerState('invalid deviceid', 'on'); @@ -31,7 +41,20 @@ describe('valid credentials, invalid device', () => { expect(powerState.error).toBe(500); }); - test('toggle device power state should fail', async () => { + test('set power state on wrong device channel should fail', async () => { + jest.setTimeout(30000); + const conn = new ewelink({ email, password }); + const powerState = await conn.setDevicePowerState( + fourChannelsDevice, + 'on', + 8 + ); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Device channel does not exist'); + expect(powerState.error).toBe(false); + }); + + test('toggle power state on invalid device should fail', async () => { jest.setTimeout(30000); const conn = new ewelink({ email, password }); const powerState = await conn.toggleDevice('invalid deviceid'); @@ -40,7 +63,7 @@ describe('valid credentials, invalid device', () => { expect(powerState.error).toBe(500); }); - test('raw power usage should fail', async () => { + test('raw power usage on invalid device should fail', async () => { jest.setTimeout(30000); const conn = new ewelink({ email, password }); const powerUsage = await conn.getDeviceRawPowerUsage('invalid deviceid'); @@ -48,7 +71,7 @@ describe('valid credentials, invalid device', () => { expect(powerUsage.error).toBe('No power usage data found.'); }); - test('current month power usage should fail', async () => { + test('current month power usage on invalid device should fail', async () => { jest.setTimeout(30000); const conn = new ewelink({ email, password }); const powerUsage = await conn.getDevicePowerUsage('invalid deviceid'); diff --git a/test/power-usage.spec.js b/test/power-usage.spec.js index 6268513..2e2a810 100644 --- a/test/power-usage.spec.js +++ b/test/power-usage.spec.js @@ -7,6 +7,7 @@ const { password, deviceIdWithPower, } = require('./_setup/credentials.json'); + const { rawPowerUsageExpectations, currentMonthPowerUsageExpectations,