From f205dd7ed8fded217efcfceaced2e3207a378501 Mon Sep 17 00:00:00 2001 From: Sebastian Krauskopf Date: Sun, 26 May 2024 22:47:33 +0200 Subject: [PATCH] fix: add more tests to handle node address with invalid symbols --- README.md | 3 +- test/ctrlx-datalayer-request.test.js | 43 ++++++++++++++++++++++ test/ctrlx-datalayer-subscribe.test.js | 50 ++++++++++++++++++++++++++ test/helper/CtrlxMockupV2.js | 12 +++++++ 4 files changed, 107 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d6f3aef..b53efcf 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,8 @@ Any use of the source code and related documents of this repository in applicati * 2023-09-04: 1.9.3 - fix: subscription with ipv6 address that contains a zone index * 2024-03-13: 1.9.4 - fix: timeout of connection with Node.js v19. "Read timeout, received no data in undefinedms, assuming connection is dead" * 2024-03-19: 1.9.5 - fix: update dependencies in package-lock -* 2024-05-24: 1.9.6 - fix: catch exception when server sends invalid/incomplete json in subscription (Bug849302) +* 2024-05-24: 1.9.6 - fix: catch exception when server sends invalid/incomplete json in subscription (Bug849302). + - fix: add more tests to handle node address with invalid symbols ``` ## About diff --git a/test/ctrlx-datalayer-request.test.js b/test/ctrlx-datalayer-request.test.js index ebe8b96..e544e00 100644 --- a/test/ctrlx-datalayer-request.test.js +++ b/test/ctrlx-datalayer-request.test.js @@ -165,6 +165,49 @@ describe('ctrlx-datalayer-request', function () { }); + it('should read a node with strange address', function (done) { + + let path = 'with/strange/symbols/abc=1;nichts-ist.wahr:("alles[ist]erlaubt")42/x.y.z'; + + let flow = [ + { "id": "h1", "type": "helper" }, + { "id": "n1", "type": "ctrlx-datalayer-request", "device": "c1", "method": "READ", "path": path, "name": "request", "wires": [["h1"]] }, + { "id": "c1", "type": "ctrlx-config", "name": "ctrlx", "hostname": getHostname(), "debug": true } + ]; + let credentials = { + c1: { + username: getUsername(), + password: getPassword() + } + }; + + helper.load([ctrlxConfigNode, ctrlxDatalayerRequestNode], flow, credentials, () => { + + let n1 = helper.getNode("n1"); + let h1 = helper.getNode("h1"); + + // @ts-ignore + h1.on("input", (msg) => { + try { + expect(msg).to.have.property('payload').with.property('value').that.is.a('string').eql('/automation/api/v2/nodes/' + encodeURI(path)); + expect(msg).to.have.property('payload').with.property('type').that.is.a('string').eql('string'); + + done(); + } + catch (err) { + done(err); + } + }); + n1.on('call:error', (call) => { + done(call.firstArg); + }); + + // @ts-ignore + n1.receive({ payload: "" }); + }); + }); + + it('should read a value and set the empty msg.topic', function (done) { let flow = [ diff --git a/test/ctrlx-datalayer-subscribe.test.js b/test/ctrlx-datalayer-subscribe.test.js index a2b5c60..569abf3 100644 --- a/test/ctrlx-datalayer-subscribe.test.js +++ b/test/ctrlx-datalayer-subscribe.test.js @@ -462,6 +462,56 @@ describe('ctrlx-datalayer-subscribe', function () { }); }); + + it('should subscribe a node with strange address', function (done) { + + let path = 'with/strange/symbols/abc=1;nichts-ist.wahr:("alles[ist]erlaubt")42/x.y.z'; + + let flow = [ + { "id": "f1", "type": "tab", "label": "Test flow"}, + { "id": "h1", "z":"f1", "type": "helper" }, + { "id": "n1", "z":"f1", "type": "ctrlx-datalayer-subscribe", "subscription": "s1", "path": path, "name": "subscribe", "wires": [["h1"]] }, + { "id": "s1", "z":"f1", "type": "ctrlx-config-subscription", "device": "c1", "name": "sub1", "publishIntervalMs": "1000" }, + { "id": "c1", "z":"f1", "type": "ctrlx-config", "name": "ctrlx", "hostname": getHostname(), "debug": true }, + ]; + let credentials = { + c1: { + username: getUsername(), + password: getPassword() + } + }; + + helper.load([ctrlxConfigNode, ctrlxConfigSubscriptionNode, ctrlxDatalayerSubscribeNode], flow, credentials, () => { + + let s1 = helper.getNode("s1"); + let h1 = helper.getNode("h1"); + let n1 = helper.getNode("n1"); + + // @ts-ignore + h1.on("input", (msg) => { + try { + expect(msg).to.have.property('topic').to.be.a('string').eql(path); + expect(msg).to.have.property('timestamp').to.be.a('number'); + expect(msg).to.have.property('type').to.be.a('string').eql('double'); + expect(msg).to.have.property('payload').to.be.a('number').eql(23); + + s1.subscription.close(); + done(); + } + catch (err) { + s1.subscription.close(); + done(err); + } + }); + + // We expect to reveive an error message, because the mockup will send an invalid JSON message. + n1.on('call:error', call => { + //numErrors++; + }); + + }); + }); + }); describe('ctrlx-datalayer-subscribe: Error Handling', function () { diff --git a/test/helper/CtrlxMockupV2.js b/test/helper/CtrlxMockupV2.js index e82e9b5..f4cd949 100644 --- a/test/helper/CtrlxMockupV2.js +++ b/test/helper/CtrlxMockupV2.js @@ -274,6 +274,14 @@ class CtrlxMockupV2 { }, 10); }); + this.app.get('/automation/api/v2/nodes/with/strange/symbols/*', authenticateJWT, (req, res) => { + res.statusCode = 200; + res.json({ + value: req.path, + type: 'string' + }); + }); + // // Builtin Data Mockups - Create/Delete @@ -534,6 +542,10 @@ class CtrlxMockupV2 { data.value = { "valid": "data" }; data.type = 'object'; break; + case 'with/strange/symbols/abc=1;nichts-ist.wahr:("alles[ist]erlaubt")42/x.y.z': + data.value = 23; + data.type = 'double'; + break; default: data.value = 'error: unknown value';