diff --git a/.eslintrc b/.eslintrc index 9300a97..d962771 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,8 @@ { "extends": [ "wesbos" - ] + ], + "rules": { + "new-cap": "off" + } } \ No newline at end of file diff --git a/README.md b/README.md index c5049d7..7bf0ea9 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,19 @@ # ewelink-api > eWeLink API for Node.js + ## Installation ``` sh npm install ewelink-api ``` + ## Usage -``` -const ewelink = require('ewelink-api'); +Check `demo/` directory for examples. -(async () => { - const conn = new ewelink({ - email: '', - password: '', - }); +## Testing +1. open `test/_setup/credentials.json` and update parameters. +2. in a terminal, `npm run test` - /* get all devices */ - const devices = await conn.getDevices(); - console.log(devices); - -})(); -``` - -Check `demo/` directory for more examples. \ No newline at end of file +* Tests needs to be performed serially, so if run jest manually, add `--runInBand` parameter. \ No newline at end of file diff --git a/lib/ewelink-helper.js b/lib/ewelink-helper.js index d061724..d2c28a7 100644 --- a/lib/ewelink-helper.js +++ b/lib/ewelink-helper.js @@ -146,10 +146,9 @@ const getDeviceChannelCountByType = deviceType => { return DEVICE_CHANNEL_LENGTH[deviceType] || 0; }; -const getDeviceTotalChannels = deviceUUID => { +const getDeviceChannelCount = deviceUUID => { const deviceType = getDeviceTypeByUiid(deviceUUID); - const channels = getDeviceChannelCountByType(deviceType); - return channels; + return getDeviceChannelCountByType(deviceType); }; module.exports = { @@ -157,5 +156,5 @@ module.exports = { loginPayload, wssLoginPayload, wssUpdatePayload, - getDeviceTotalChannels, + getDeviceChannelCount, }; diff --git a/main.js b/main.js index bce30d7..62901ca 100644 --- a/main.js +++ b/main.js @@ -10,7 +10,7 @@ const { loginPayload, wssLoginPayload, wssUpdatePayload, - getDeviceTotalChannels, + getDeviceChannelCount, } = require('./lib/ewelink-helper'); class eWeLink { @@ -112,7 +112,7 @@ class eWeLink { async getDevicePowerState(deviceId, channel = 1) { const device = await this.getDevice(deviceId); const error = _get(device, 'error', false); - const switchesAmount = getDeviceTotalChannels(device.uiid); + const switchesAmount = getDeviceChannelCount(device.uiid); let state = _get(device, 'params.switch', false); const switches = _get(device, 'params.switches', false); @@ -133,7 +133,7 @@ class eWeLink { async setDevicePowerState(deviceId, state, channel = 1) { const device = await this.getDevice(deviceId); const error = _get(device, 'error', false); - const switchesAmount = getDeviceTotalChannels(device.uiid); + const switchesAmount = getDeviceChannelCount(device.uiid); const status = _get(device, 'params.switch', false); const switches = _get(device, 'params.switches', false); @@ -183,19 +183,7 @@ class eWeLink { const newState = state === 'on' ? 'off' : 'on'; - const newResponse = await this.setDevicePowerState( - deviceId, - newState, - channel - ); - - return newResponse; - } - - async getDeviceChannelCount(deviceId) { - const device = await this.getDevice(deviceId); - const switchesAmount = getDeviceTotalChannels(device.uiid); - return switchesAmount; + return this.setDevicePowerState(deviceId, newState, channel); } } diff --git a/package-lock.json b/package-lock.json index 794b93b..efbd224 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.2.0", + "version": "1.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 77c2af0..2046fb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.2.0", + "version": "1.2.1", "description": "eWeLink API for Node.js", "author": "Martín M.", "license": "MIT", @@ -20,8 +20,7 @@ ], "main": "main.js", "scripts": { - "demo": "node ./demo/example.js", - "test": "jest --testPathIgnorePatterns '(node_modules|.cache)'" + "test": "jest --runInBand --verbose --testPathIgnorePatterns '(node_modules|.cache)'" }, "dependencies": { "delay": "^4.3.0", diff --git a/test/credentials.json b/test/_setup/credentials.json similarity index 100% rename from test/credentials.json rename to test/_setup/credentials.json diff --git a/test/_expectations.js b/test/_setup/expectations.js similarity index 100% rename from test/_expectations.js rename to test/_setup/expectations.js diff --git a/test/main-env-node.spec.js b/test/main-env-node.spec.js new file mode 100644 index 0000000..1df68fc --- /dev/null +++ b/test/main-env-node.spec.js @@ -0,0 +1,72 @@ +const ewelink = require('../main'); +const { email, password, deviceId } = require('./_setup/credentials.json'); +const { + loginExpectations, + allDevicesExpectations, + specificDeviceExpectations, +} = require('./_setup/expectations'); + +describe('env: node script', () => { + let conn; + + beforeAll(() => { + conn = new ewelink({ email, password }); + }); + + test('login into ewelink', async () => { + const login = await conn.login(); + expect(typeof login).toBe('object'); + expect(login).toMatchObject(loginExpectations); + }); + + test('get all devices', async () => { + const devices = await conn.getDevices(); + expect(Array.isArray(devices)).toBe(true); + expect(devices[0]).toMatchObject(allDevicesExpectations); + }); + + test('get specific device', async () => { + const device = await conn.getDevice(deviceId); + expect(typeof device).toBe('object'); + expect(device.deviceid).toBe(deviceId); + expect(device).toMatchObject(specificDeviceExpectations); + }); + + test('get device power state', async () => { + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const powerState = await conn.getDevicePowerState(deviceId); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(currentState); + }); + + test('set device power state', async () => { + jest.setTimeout(30000); + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const newState = currentState === 'on' ? 'off' : 'on'; + const powerState = await conn.setDevicePowerState(deviceId, newState); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(newState); + const deviceVerify = await conn.getDevice(deviceId); + const currentStateVerify = deviceVerify.params.switch; + expect(newState).toBe(currentStateVerify); + }); + + test('toggle device power state', async () => { + jest.setTimeout(30000); + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const newState = currentState === 'on' ? 'off' : 'on'; + await conn.toggleDevice(deviceId); + const deviceVerify = await conn.getDevice(deviceId); + const currentStateVerify = deviceVerify.params.switch; + expect(newState).toBe(currentStateVerify); + await conn.toggleDevice(deviceId); + const deviceVerifyAgain = await conn.getDevice(deviceId); + const currentStateVerifyAgain = deviceVerifyAgain.params.switch; + expect(currentState).toBe(currentStateVerifyAgain); + }); +}); diff --git a/test/main-env-serverless.spec.js b/test/main-env-serverless.spec.js new file mode 100644 index 0000000..68e4827 --- /dev/null +++ b/test/main-env-serverless.spec.js @@ -0,0 +1,77 @@ +const ewelink = require('../main'); +const { email, password, deviceId } = require('./_setup/credentials.json'); +const { + loginExpectations, + allDevicesExpectations, + specificDeviceExpectations, +} = require('./_setup/expectations'); + +describe('env: serverless', () => { + let accessToken; + let apiKey; + + test('login into ewelink', async () => { + const conn = new ewelink({ email, password }); + const login = await conn.login(); + accessToken = login.at; + apiKey = login.user.apikey; + expect(typeof login).toBe('object'); + expect(login).toMatchObject(loginExpectations); + }); + + test('get all devices', async () => { + const conn = new ewelink({ at: accessToken }); + const devices = await conn.getDevices(); + expect(Array.isArray(devices)).toBe(true); + expect(devices[0]).toMatchObject(allDevicesExpectations); + }); + + test('get specific device', async () => { + const conn = new ewelink({ at: accessToken }); + const device = await conn.getDevice(deviceId); + expect(typeof device).toBe('object'); + expect(device.deviceid).toBe(deviceId); + expect(device).toMatchObject(specificDeviceExpectations); + }); + + test('get device power state', async () => { + const conn = new ewelink({ at: accessToken }); + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const powerState = await conn.getDevicePowerState(deviceId); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(currentState); + }); + + test('set device power state', async () => { + jest.setTimeout(30000); + const conn = new ewelink({ at: accessToken, apiKey }); + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const newState = currentState === 'on' ? 'off' : 'on'; + const powerState = await conn.setDevicePowerState(deviceId, newState); + expect(typeof powerState).toBe('object'); + expect(powerState.status).toBe('ok'); + expect(powerState.state).toBe(newState); + const deviceVerify = await conn.getDevice(deviceId); + const currentStateVerify = deviceVerify.params.switch; + expect(newState).toBe(currentStateVerify); + }); + + test('toggle device power state', async () => { + jest.setTimeout(30000); + const conn = new ewelink({ at: accessToken, apiKey }); + const device = await conn.getDevice(deviceId); + const currentState = device.params.switch; + const newState = currentState === 'on' ? 'off' : 'on'; + await conn.toggleDevice(deviceId); + const deviceVerify = await conn.getDevice(deviceId); + const currentStateVerify = deviceVerify.params.switch; + expect(newState).toBe(currentStateVerify); + await conn.toggleDevice(deviceId); + const deviceVerifyAgain = await conn.getDevice(deviceId); + 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 new file mode 100644 index 0000000..c2c3f19 --- /dev/null +++ b/test/main-invalid-credentials.spec.js @@ -0,0 +1,51 @@ +const ewelink = require('../main'); +const { deviceId } = require('./_setup/credentials.json'); + +describe('invalid credentials', () => { + test('no credentials given', async () => { + const conn = new ewelink({}); + expect(typeof conn).toBe('object'); + expect(conn.error).toBe('No credentials provided'); + }); + + test('get error response on api login', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const login = await conn.login(); + expect(typeof login).toBe('object'); + expect(login.msg).toBe('Authentication error'); + expect(login.error).toBe(400); + }); + + test('get error response on all devices', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const devices = await conn.getDevices(); + expect(typeof devices).toBe('object'); + expect(devices.msg).toBe('Authentication error'); + expect(devices.error).toBe(401); + }); + + test('get error response on specific device', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const device = await conn.getDevice(deviceId); + expect(typeof device).toBe('object'); + expect(device.msg).toBe('Authentication error'); + expect(device.error).toBe(401); + }); + + test('get device power state should fail', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const powerState = await conn.getDevicePowerState(deviceId); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Authentication error'); + expect(powerState.error).toBe(401); + }); + + 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'); + 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 new file mode 100644 index 0000000..209bc47 --- /dev/null +++ b/test/main-valid-credentials.spec.js @@ -0,0 +1,40 @@ +const ewelink = require('../main'); +const { email, password } = require('./_setup/credentials.json'); +const { loginExpectations } = require('./_setup/expectations'); + +describe('valid credentials, invalid device', () => { + test('get device power state should fail', async () => { + const conn = new ewelink({ email, password }); + const powerState = await conn.getDevicePowerState('invalid deviceid'); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Device does not exist'); + expect(powerState.error).toBe(500); + }); + + test('set device power state should fail', async () => { + jest.setTimeout(30000); + const conn = new ewelink({ email, password }); + const powerState = await conn.setDevicePowerState('invalid deviceid', 'on'); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Device does not exist'); + expect(powerState.error).toBe(500); + }); + + test('toggle device power state should fail', async () => { + jest.setTimeout(30000); + const conn = new ewelink({ email, password }); + const powerState = await conn.toggleDevice('invalid deviceid'); + expect(typeof powerState).toBe('object'); + expect(powerState.msg).toBe('Device does not exist'); + expect(powerState.error).toBe(500); + }); +}); + +describe('valid credentials, wrong region', () => { + test('should login in the right region', async () => { + const conn = new ewelink({ email, password, region: 'eu' }); + const login = await conn.login(); + expect(typeof login).toBe('object'); + expect(login).toMatchObject(loginExpectations); + }); +}); diff --git a/test/main.spec.js b/test/main.spec.js deleted file mode 100644 index 2b65102..0000000 --- a/test/main.spec.js +++ /dev/null @@ -1,190 +0,0 @@ -const ewelink = require('../main'); -const { email, password, deviceId } = require('./credentials.json'); -const { - loginExpectations, - allDevicesExpectations, - specificDeviceExpectations, -} = require('./_expectations'); - -describe('env: node script', () => { - let conn; - - beforeAll(() => { - conn = new ewelink({ email, password }); - }); - - test('login into ewelink', async () => { - const login = await conn.login(); - expect(typeof login).toBe('object'); - expect(login).toMatchObject(loginExpectations); - }); - - test('get all devices', async () => { - const devices = await conn.getDevices(); - expect(Array.isArray(devices)).toBe(true); - expect(devices[0]).toMatchObject(allDevicesExpectations); - }); - - test('get specific device', async () => { - const device = await conn.getDevice(deviceId); - expect(typeof device).toBe('object'); - expect(device.deviceid).toBe(deviceId); - expect(device).toMatchObject(specificDeviceExpectations); - }); - - test('get device power state', async () => { - const device = await conn.getDevice(deviceId); - const currentState = device.params.switch; - const powerState = await conn.getDevicePowerState(deviceId); - expect(typeof powerState).toBe('object'); - expect(powerState.status).toBe('ok'); - expect(powerState.state).toBe(currentState); - }); - - test('set device power state', async () => { - jest.setTimeout(30000); - const device = await conn.getDevice(deviceId); - const currentState = device.params.switch; - const newState = currentState === 'on' ? 'off' : 'on'; - const powerState = await conn.setDevicePowerState(deviceId, newState); - expect(typeof powerState).toBe('object'); - expect(powerState.status).toBe('ok'); - expect(powerState.state).toBe(newState); - const deviceVerify = await conn.getDevice(deviceId); - const currentStateVerify = deviceVerify.params.switch; - expect(newState).toBe(currentStateVerify); - }); -}); - -describe('env: serverless', () => { - let accessToken; - let apiKey; - - test('login into ewelink', async () => { - const conn = new ewelink({ email, password }); - const login = await conn.login(); - accessToken = login.at; - apiKey = login.user.apikey; - expect(typeof login).toBe('object'); - expect(login).toMatchObject(loginExpectations); - }); - - test('get all devices', async () => { - const conn = new ewelink({ at: accessToken }); - const devices = await conn.getDevices(); - expect(Array.isArray(devices)).toBe(true); - expect(devices[0]).toMatchObject(allDevicesExpectations); - }); - - test('get specific device', async () => { - const conn = new ewelink({ at: accessToken }); - const device = await conn.getDevice(deviceId); - expect(typeof device).toBe('object'); - expect(device.deviceid).toBe(deviceId); - expect(device).toMatchObject(specificDeviceExpectations); - }); - - test('get device power state', async () => { - const conn = new ewelink({ at: accessToken }); - const device = await conn.getDevice(deviceId); - const currentState = device.params.switch; - const powerState = await conn.getDevicePowerState(deviceId); - expect(typeof powerState).toBe('object'); - expect(powerState.status).toBe('ok'); - expect(powerState.state).toBe(currentState); - }); - - test('set device power state', async () => { - jest.setTimeout(30000); - const conn = new ewelink({ at: accessToken, apiKey }); - const device = await conn.getDevice(deviceId); - const currentState = device.params.switch; - const newState = currentState === 'on' ? 'off' : 'on'; - const powerState = await conn.setDevicePowerState(deviceId, newState); - expect(typeof powerState).toBe('object'); - expect(powerState.status).toBe('ok'); - expect(powerState.state).toBe(newState); - const deviceVerify = await conn.getDevice(deviceId); - const currentStateVerify = deviceVerify.params.switch; - expect(newState).toBe(currentStateVerify); - }); -}); - -describe('valid credentials, invalid device', () => { - test('get device power state should fail', async () => { - const conn = new ewelink({ email, password }); - const powerState = await conn.getDevicePowerState('invalid deviceid'); - expect(typeof powerState).toBe('object'); - expect(powerState.msg).toBe('Device does not exist'); - expect(powerState.error).toBe(500); - }); - - test('set device power state should fail', async () => { - jest.setTimeout(30000); - const conn = new ewelink({ email, password }); - const powerState = await conn.setDevicePowerState('invalid deviceid', 'on'); - expect(typeof powerState).toBe('object'); - expect(powerState.msg).toBe('Device does not exist'); - expect(powerState.error).toBe(500); - }); -}); - -describe('valid credentials, wrong region', () => { - test('login into ewelink should fail', async () => { - const conn = new ewelink({ region: 'eu', email, password }); - expect(conn.region).toBe('eu'); - const login = await conn.login(); - expect(typeof login).toBe('object'); - expect(login).toMatchObject(loginExpectations); - expect(conn.region).toBe('us'); - }); -}); - -describe('invalid credentials', () => { - test('no credentials given', async () => { - const conn = new ewelink({}); - expect(typeof conn).toBe('object'); - expect(conn.error).toBe('No credentials provided'); - }); - - test('get error response on api login', async () => { - const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const login = await conn.login(); - expect(typeof login).toBe('object'); - expect(login.msg).toBe('Authentication error'); - expect(login.error).toBe(400); - }); - - test('get error response on all devices', async () => { - const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const devices = await conn.getDevices(); - expect(typeof devices).toBe('object'); - expect(devices.msg).toBe('Authentication error'); - expect(devices.error).toBe(401); - }); - - test('get error response on specific device', async () => { - const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const device = await conn.getDevice(deviceId); - expect(typeof device).toBe('object'); - expect(device.msg).toBe('Authentication error'); - expect(device.error).toBe(401); - }); - - test('get device power state should fail', async () => { - const conn = new ewelink({ email: 'invalid', password: 'credentials' }); - const powerState = await conn.getDevicePowerState(deviceId); - expect(typeof powerState).toBe('object'); - expect(powerState.msg).toBe('Authentication error'); - expect(powerState.error).toBe(401); - }); - - 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'); - expect(typeof powerState).toBe('object'); - expect(powerState.msg).toBe('Authentication error'); - expect(powerState.error).toBe(401); - }); -});