From f64f51ba09f26358cecc4e677362b33a52e31c37 Mon Sep 17 00:00:00 2001 From: jcelik Date: Sat, 26 Jan 2019 17:59:34 +0100 Subject: [PATCH] fix: Fixed how heos commands are parsed The system expects the message object to have a specific structure. The structure should that the command property is an object with two properties. It was a string. --- __tests__/listen/responseParser.ts | 39 ++++++++++++++++++++------- src/listen/responseParser.ts | 43 +++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/__tests__/listen/responseParser.ts b/__tests__/listen/responseParser.ts index 08d38a6..b622f8d 100644 --- a/__tests__/listen/responseParser.ts +++ b/__tests__/listen/responseParser.ts @@ -6,7 +6,7 @@ describe('Heos response messages can be correctly parsed', () => { const messageParser: ResponseParser = new ResponseParser(mockCallback) - messageParser.put('{"heos": {"command": "", "result": "", "message": ""}}\r\n') + messageParser.put('{"heos": {"command": "test/test", "result": "", "message": ""}}\r\n') expect(mockCallback).toBeCalledTimes(1) }) @@ -17,16 +17,18 @@ describe('Heos response messages can be correctly parsed', () => { const messageParser: ResponseParser = new ResponseParser(mockCallback) messageParser.put('{"he') - messageParser.put('os": {"command": "", "result": "", "message": ""}}\r\n') + messageParser.put('os": {"command": "test/test", "result": "", "message": ""}}\r\n') expect(mockCallback).toBeCalledTimes(1) messageParser.put( - '{"heos": {"command": "", "result": "", "message": ""}}\r\n{"heos": {"command": "", "result": "", "message": ""}}\r\n' + '{"heos": {"command": "test/test", "result": "", "message": ""}}\r\n{"heos": {"command": "test/test", "result": "", "message": ""}}\r\n' ) expect(mockCallback).toBeCalledTimes(3) - messageParser.put('{"heos": {"command": "", "result": "", "message": ""}}\r\n{ "heos":') + messageParser.put( + '{"heos": {"command": "test/test", "result": "", "message": ""}}\r\n{ "heos":' + ) expect(mockCallback).toBeCalledTimes(4) }) @@ -35,12 +37,15 @@ describe('Heos response messages can be correctly parsed', () => { const messageParser: ResponseParser = new ResponseParser(mockCallback) - const mockObject = { heos: { command: '', result: '', message: '' } } + const mockObject = { heos: { command: 'test/test', result: '', message: '' } } + const expectedObject = { + heos: { command: { commandGroup: 'test', command: 'test' }, result: '', message: '' } + } messageParser.put(JSON.stringify(mockObject) + '\r\n') expect(mockCallback).toBeCalledTimes(1) - expect(mockCallback.mock.calls[0][0]).toEqual(mockObject) + expect(mockCallback.mock.calls[0][0]).toEqual(expectedObject) }) test('The parser returns the message as a HeosResponse', () => { @@ -60,7 +65,10 @@ describe('Heos response messages can be correctly parsed', () => { expect(mockCallback.mock.calls[0][0]).toEqual({ heos: { - command: expect.any(String), + command: { + commandGroup: expect.any(String), + command: expect.any(String) + }, result: expect.any(String), message: expect.any(String) } @@ -115,6 +123,12 @@ describe('Heos response messages can be correctly parsed', () => { } } + const expectedObject = { + heos: { + command: { commandGroup: 'event', command: 'sources_changed' } + } + } + const mockObject2 = { heos: { command: 'event/sources_changed', @@ -122,11 +136,18 @@ describe('Heos response messages can be correctly parsed', () => { } } + const expectedObject2 = { + heos: { + command: { commandGroup: 'event', command: 'sources_changed' }, + message: 'test_message' + } + } + messageParser.put(JSON.stringify(mockObject) + '\r\n') messageParser.put(JSON.stringify(mockObject2) + '\r\n') expect(mockCallback).toBeCalledTimes(2) - expect(mockCallback.mock.calls[0][0]).toEqual(mockObject) - expect(mockCallback.mock.calls[1][0]).toEqual(mockObject2) + expect(mockCallback.mock.calls[0][0]).toEqual(expectedObject) + expect(mockCallback.mock.calls[1][0]).toEqual(expectedObject2) }) }) diff --git a/src/listen/responseParser.ts b/src/listen/responseParser.ts index c760ec0..cbcbaca 100644 --- a/src/listen/responseParser.ts +++ b/src/listen/responseParser.ts @@ -1,7 +1,16 @@ import { HeosResponse, HeosEvent } from '../types' +import { parseHeosCommandString } from './heosCommand' const messageDelimiter = '\r\n' +function isCorrectResponse(response: any): boolean { + return ( + response.hasOwnProperty('heos') && + response.heos.hasOwnProperty('command') && + typeof response.heos.command === 'string' + ) +} + function isHeosResponse(response: any): response is HeosResponse { if (response.hasOwnProperty('heos')) { const heos: any = response.heos @@ -12,11 +21,21 @@ function isHeosResponse(response: any): response is HeosResponse { heos.hasOwnProperty('message') ) { if ( - typeof heos.command === 'string' && + typeof heos.command === 'object' && typeof heos.result === 'string' && typeof heos.message === 'string' ) { - return true + if ( + heos.command.hasOwnProperty('commandGroup') && + heos.command.hasOwnProperty('command') + ) { + if ( + typeof heos.command.commandGroup === 'string' && + typeof heos.command.command === 'string' + ) { + return true + } + } } } } @@ -28,7 +47,13 @@ function isHeosEvent(response: any): response is HeosEvent { const heos: any = response.heos if (heos.hasOwnProperty('command')) { - if (typeof heos.command === 'string') { + if ( + typeof heos.command === 'object' && + heos.command.hasOwnProperty('commandGroup') && + heos.command.hasOwnProperty('command') && + typeof heos.command.commandGroup === 'string' && + typeof heos.command.command === 'string' + ) { if (heos.hasOwnProperty('message')) { return typeof heos.message === 'string' } else { @@ -65,6 +90,18 @@ export class ResponseParser { messages .filter((row: string) => row.length > 0) .map((message: string) => JSON.parse(message)) + .map((response: any) => { + if (isCorrectResponse) { + return response + } else { + throw new TypeError() + } + }) + .map(response => { + const command = parseHeosCommandString(response.heos.command) + response.heos.command = command + return response + }) .map((response: any) => { if (isHeosResponse(response) || isHeosEvent(response)) { return response