From 3d7c7fe72bcfba2c31e7398b5f1ea2f0400657b7 Mon Sep 17 00:00:00 2001 From: Pierre-Gilles Leymarie Date: Fri, 20 May 2022 14:29:03 +0100 Subject: [PATCH] Fix execute on multiple device feature + reject when device is not found --- server/services/alexa/lib/alexa.onExecute.js | 12 +++++++-- .../services/alexa/lib/alexa.onReportState.js | 4 +++ .../alexa/lib/alexa.onExecute.test.js | 4 +++ .../alexa/lib/alexa.onReportState.test.js | 27 +++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/server/services/alexa/lib/alexa.onExecute.js b/server/services/alexa/lib/alexa.onExecute.js index b581df8bb5..8417a0029d 100644 --- a/server/services/alexa/lib/alexa.onExecute.js +++ b/server/services/alexa/lib/alexa.onExecute.js @@ -1,6 +1,12 @@ const uuid = require('uuid'); const get = require('get-value'); -const { EVENTS, ACTIONS, ACTIONS_STATUS, DEVICE_FEATURE_CATEGORIES } = require('../../../utils/constants'); +const { + EVENTS, + ACTIONS, + ACTIONS_STATUS, + DEVICE_FEATURE_CATEGORIES, + DEVICE_FEATURE_TYPES, +} = require('../../../utils/constants'); const { BadParameters, NotFoundError } = require('../../../utils/coreErrors'); const { writeValues, readValues } = require('./deviceMappings'); @@ -25,7 +31,9 @@ function onExecute(body) { switch (directiveNamespace) { case 'Alexa.PowerController': deviceFeature = deviceInMemory.features.find( - (f) => f.category === DEVICE_FEATURE_CATEGORIES.SWITCH || f.category === DEVICE_FEATURE_CATEGORIES.LIGHT, + (f) => + (f.category === DEVICE_FEATURE_CATEGORIES.SWITCH || f.category === DEVICE_FEATURE_CATEGORIES.LIGHT) && + f.type === DEVICE_FEATURE_TYPES.LIGHT.BINARY, ); value = writeValues['Alexa.PowerController'](directiveName); break; diff --git a/server/services/alexa/lib/alexa.onReportState.js b/server/services/alexa/lib/alexa.onReportState.js index a090ec69db..b032d256ce 100644 --- a/server/services/alexa/lib/alexa.onReportState.js +++ b/server/services/alexa/lib/alexa.onReportState.js @@ -2,6 +2,7 @@ const uuid = require('uuid'); const get = require('get-value'); const { mappings, readValues } = require('./deviceMappings'); +const { NotFoundError } = require('../../../utils/coreErrors'); /** * @public @@ -13,6 +14,9 @@ const { mappings, readValues } = require('./deviceMappings'); function onReportState(body) { const deviceSelector = get(body, 'directive.endpoint.endpointId'); const device = this.gladys.stateManager.get('device', deviceSelector); + if (!device) { + throw new NotFoundError(`Device "${deviceSelector}" not found`); + } const properties = []; const now = new Date().toISOString(); device.features.forEach((feature) => { diff --git a/server/test/services/alexa/lib/alexa.onExecute.test.js b/server/test/services/alexa/lib/alexa.onExecute.test.js index 4c5ae00c4e..c51bb0833e 100644 --- a/server/test/services/alexa/lib/alexa.onExecute.test.js +++ b/server/test/services/alexa/lib/alexa.onExecute.test.js @@ -13,6 +13,10 @@ const DEVICE_1_LIGHT = { selector: 'device-1', external_id: 'device-1-external-id', features: [ + { + category: 'light', + type: 'brightness', + }, { category: 'light', type: 'binary', diff --git a/server/test/services/alexa/lib/alexa.onReportState.test.js b/server/test/services/alexa/lib/alexa.onReportState.test.js index 702aec9c5e..7cdd594bb5 100644 --- a/server/test/services/alexa/lib/alexa.onReportState.test.js +++ b/server/test/services/alexa/lib/alexa.onReportState.test.js @@ -73,4 +73,31 @@ describe('alexa.onReportState', () => { }, }); }); + it('Should return device not found', async () => { + const gladys = { + stateManager: { + get: fake.returns(null), + }, + }; + + const alexaHandler = new AlexaHandler(gladys, serviceId); + const body = { + directive: { + header: { + namespace: 'Alexa', + name: 'ReportState', + payloadVersion: '3', + messageId: 'a05c8249-1cdd-41dd-bc1d-5a14ab4b98eb', + correlationToken: + 'AAAAAAAAAQBe8ATzt+PzWVqbUXXQAv6JAAIAAAAAAADgCDHXLLn3nx8SmjtElD2w8CfsniSH6KxFhbRSgD/sELuMpZTr4Jl/E3Nip62gpI2QqFNm/TrQ/Pi+XSFtf/4AVCDxe4bV2FAXSVu61AsuUlhbdqdvjUoaHOuqSLW8F3Qj9z3HWhfvTCMEbbhw4XVDWOsyXb9nknvswimA+R4ftNdBx5POWZGxWtbvU+yeBStTV+QwSSZaHWjzQdi/LAo1KW35MkmLikny7Y7J097LTTL1Tof6IkLsi9/gxOtUUFvnD4yIkWeHTT110Ch6R4kDuonNtOiHsTmMMRtsY5kRWoIL9VMfX6QHWjamhvd+XJp4sXkLMBdtJ3aTzfsUNrQIdrcPTox9qTNjShunTlbAYkq1TSUXaylEGHvcwHrbo7ZoUlBvidqnJGUNRJPxOHHyfCm5VqFzuFI8AG1W/dj1W4Di0AAND/mwzjZKUTRsiX4uEaRw8/Na4Qj/GBMuT18hUoGpe7t/UYw5JFw+MXm0kn/5jKe9r62xil3TN8BK9ODQDP9zq08+iiT0CBtEX5F4Drrowb57IwcW7nt/hkCeeyR59B/Z6nPsSq0NQ+rd1w4a1iHIyaTU6acQsKwmaX1OeTvtT2p7U/HhqfhVMSqA7ybGhQDF4FPPzIbh+o+D1S+AX9m9nVSSJNwoevikdZimCbk1l1HmUrhz78GO+j0yFg==', + }, + endpoint: { endpointId: 'device-1' }, + payload: {}, + }, + user: { id: 'cbd42dc1-1b15-4c59-bea6-7e01968a9603', local_user_id: '275faa00-8a9c-4747-8fbe-417ddb966b16' }, + }; + expect(() => { + alexaHandler.onReportState(body); + }).to.throw('Device "device-1" not found'); + }); });