diff --git a/src/lib/cloud-provider.js b/src/lib/cloud-provider.js index 44d81c823cfe23fd446296278aaeaf2e7a588fb1..8116813ebd17c98549b3fc55565944747f19054d 100644 --- a/src/lib/cloud-provider.js +++ b/src/lib/cloud-provider.js @@ -34,29 +34,35 @@ class CloudProvider { this.connection = new WebSocket((location.protocol === 'http:' ? 'ws://' : 'wss://') + cloudHost); - this.connection.onerror = e => { - log.error(`Websocket connection error: ${JSON.stringify(e)}`); - - // TODO Add re-connection attempt logic here - this.clear(); - }; - - this.connection.onmessage = event => { - const messageString = event.data; - log.info(`Received websocket message: ${messageString}`); - const message = JSON.parse(messageString); - const parsedData = this.parseMessage(message); + this.connection.onerror = this.onError.bind(this); + this.connection.onmessage = this.onMessage.bind(this); + this.connection.onopen = this.onOpen.bind(this); + this.connection.onclose = this.onClose.bind(this); + } + + onError (event) { + log.error(`Websocket connection error: ${JSON.stringify(event)}`); + // TODO Add re-connection attempt logic here + this.clear(); + } + + onMessage (event) { + const messageString = event.data; + log.info(`Received websocket message: ${messageString}`); + // Multiple commands can be received, newline separated + messageString.split('\n').forEach(message => { + const parsedData = this.parseMessage(JSON.parse(message)); this.vm.postIOData('cloud', parsedData); - }; + }); + } - this.connection.onopen = () => { - this.writeToServer('handshake'); - log.info(`Successfully connected to clouddata server.`); - }; + onOpen () { + this.writeToServer('handshake'); + log.info(`Successfully connected to clouddata server.`); + } - this.connection.onclose = () => { - log.info(`Closed connection to websocket`); - }; + onClose () { + log.info(`Closed connection to websocket`); } parseMessage (message) { diff --git a/test/unit/util/cloud-provider.test.js b/test/unit/util/cloud-provider.test.js index 65ebbc06e4b50d36c6e111e6cea83ccf3679c795..c81588ddeccad21e2e7e9116f9ae9d5ce7f081a2 100644 --- a/test/unit/util/cloud-provider.test.js +++ b/test/unit/util/cloud-provider.test.js @@ -6,8 +6,10 @@ global.WebSocket = null; describe('CloudProvider', () => { let cloudProvider = null; let sentMessage = null; + let vmIOData = []; beforeEach(() => { + vmIOData = []; cloudProvider = new CloudProvider(); // Stub connection cloudProvider.connection = { @@ -15,6 +17,12 @@ describe('CloudProvider', () => { sentMessage = msg; } }; + // Stub vm + cloudProvider.vm = { + postIOData: (_namespace, data) => { + vmIOData.push(data); + } + }; }); test('updateVariable', () => { @@ -41,4 +49,39 @@ describe('CloudProvider', () => { expect(obj.value).toEqual(5); expect(obj.index).toEqual(0); }); + + test('onMessage ack', () => { + const msg = JSON.stringify({ + method: 'ack', + name: 'name' + }); + cloudProvider.onMessage({data: msg}); + expect(vmIOData[0].varCreate.name).toEqual('name'); + }); + + test('onMessage set', () => { + const msg = JSON.stringify({ + method: 'set', + name: 'name', + value: 'value' + }); + cloudProvider.onMessage({data: msg}); + expect(vmIOData[0].varUpdate.name).toEqual('name'); + expect(vmIOData[0].varUpdate.value).toEqual('value'); + }); + + test('onMessage with multiple commands', () => { + const msg1 = JSON.stringify({ + method: 'set', + name: 'name1', + value: 'value' + }); + const msg2 = JSON.stringify({ + method: 'ack', + name: 'name2' + }); + cloudProvider.onMessage({data: `${msg1}\n${msg2}`}); + expect(vmIOData[0].varUpdate.name).toEqual('name1'); + expect(vmIOData[1].varCreate.name).toEqual('name2'); + }); });