From 73db2678ed6084e5660dd6f85a9e825c95bb3bed Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Tue, 17 Jan 2023 14:32:02 +0000
Subject: [PATCH] test: add coverage for protocol methods

---
 dist/protocol.esm.js                             |  6 +++++-
 dist/protocol.js                                 |  6 +++++-
 features/protocol_decode.feature                 | 11 +++++++++++
 features/protocol_encode.feature                 | 11 +++++++++++
 features/protocol_get-type.feature               | 12 ++++++++++++
 features/protocol_validate.feature               | 12 ++++++++++++
 src/protocol/index.js                            |  6 +++++-
 test/cucumber/adapter/common.steps.js            | 16 ++++++++++++++++
 test/cucumber/adapter/poll.steps.js              |  7 -------
 test/cucumber/adapter/publish.steps.js           |  7 -------
 test/cucumber/adapter/validate.steps.js          | 10 ----------
 test/cucumber/protocol/common.steps.js           |  6 ++++++
 test/cucumber/protocol/decode.steps.js           |  6 ++++++
 test/cucumber/protocol/encode.steps.js           |  6 ++++++
 test/cucumber/protocol/get-type.steps.js         | 14 ++++++++++++++
 test/cucumber/protocol/validate.steps.js         | 16 ++++++++++++++++
 .../fixtures/message-vehicle-status-invalid.json |  6 +++---
 17 files changed, 128 insertions(+), 30 deletions(-)
 create mode 100644 features/protocol_decode.feature
 create mode 100644 features/protocol_encode.feature
 create mode 100644 features/protocol_get-type.feature
 create mode 100644 features/protocol_validate.feature
 create mode 100644 test/cucumber/protocol/common.steps.js
 create mode 100644 test/cucumber/protocol/decode.steps.js
 create mode 100644 test/cucumber/protocol/encode.steps.js
 create mode 100644 test/cucumber/protocol/get-type.steps.js
 create mode 100644 test/cucumber/protocol/validate.steps.js

diff --git a/dist/protocol.esm.js b/dist/protocol.esm.js
index 3bf81eb..e2120da 100644
--- a/dist/protocol.esm.js
+++ b/dist/protocol.esm.js
@@ -50,7 +50,11 @@ class GenericProtocol {
    * @returns {string}
    */
   getType(message) {
-    return message.message_type;
+    try {
+      return message.payload.message_type;
+    } catch(error) {
+      return null;
+    }
   }
 
   /**
diff --git a/dist/protocol.js b/dist/protocol.js
index f5e618c..7d0716e 100644
--- a/dist/protocol.js
+++ b/dist/protocol.js
@@ -52,7 +52,11 @@ class GenericProtocol {
    * @returns {string}
    */
   getType(message) {
-    return message.message_type;
+    try {
+      return message.payload.message_type;
+    } catch(error) {
+      return null;
+    }
   }
 
   /**
diff --git a/features/protocol_decode.feature b/features/protocol_decode.feature
new file mode 100644
index 0000000..ab2a50f
--- /dev/null
+++ b/features/protocol_decode.feature
@@ -0,0 +1,11 @@
+# Decode and encode are provided as stubs which are intended to be overridden 
+# These can be used to translate the message or to invoke other functions 
+# to take action based on the type and content of messages
+
+Feature: Decode stubs passthru message unchanged
+  The protocol decode method works as expected
+
+  Scenario: Decode passes the message through unaltered
+    Given a valid message
+    When the protocol.decode method is called
+    Then the message is returned unaltered
diff --git a/features/protocol_encode.feature b/features/protocol_encode.feature
new file mode 100644
index 0000000..41bb57c
--- /dev/null
+++ b/features/protocol_encode.feature
@@ -0,0 +1,11 @@
+# Decode and encode are provided as stubs which are intended to be overridden 
+# These can be used to translate the message or to invoke other functions 
+# to take action based on the type and content of messages
+
+Feature: Encode stubs passthru message unchanged
+  The protocol encode method works as expected
+
+  Scenario: Encode passes the message through unaltered
+    Given a valid message
+    When the protocol.encode method is called
+    Then the message is returned unaltered
\ No newline at end of file
diff --git a/features/protocol_get-type.feature b/features/protocol_get-type.feature
new file mode 100644
index 0000000..829ae6d
--- /dev/null
+++ b/features/protocol_get-type.feature
@@ -0,0 +1,12 @@
+Feature: Can the protocol determine message type
+  The protocol getType method works as expected
+
+  Scenario: A valid message is successfully typed
+    Given a valid message
+    When protocol getType is called
+    Then getType returns message.payload.message_type if present
+
+  Scenario: An invalid message returns type:null
+    Given an invalid message
+    When protocol getType is called
+    Then getType returns null if message.payload.message_type is not present
diff --git a/features/protocol_validate.feature b/features/protocol_validate.feature
new file mode 100644
index 0000000..a5293c4
--- /dev/null
+++ b/features/protocol_validate.feature
@@ -0,0 +1,12 @@
+Feature: Can the protocol validate messages?
+  The adapter validate method works as expected
+
+  Scenario: A valid message is successfully validated against the protocol schema
+    Given a valid message
+    When the protocol.validate method is called
+    Then the message is validated successfully  
+  
+  Scenario: An invalid message fails to validate against the protocol schema
+    Given an invalid message
+    When the protocol.validate method is called
+    Then the message fails to validate
\ No newline at end of file
diff --git a/src/protocol/index.js b/src/protocol/index.js
index 646194a..d4d3316 100644
--- a/src/protocol/index.js
+++ b/src/protocol/index.js
@@ -50,7 +50,11 @@ export class GenericProtocol {
    * @returns {string}
    */
   getType(message) {
-    return message.message_type;
+    try {
+      return message.payload.message_type;
+    } catch(error) {
+      return null;
+    }
   }
 
   /**
diff --git a/test/cucumber/adapter/common.steps.js b/test/cucumber/adapter/common.steps.js
index e69de29..5236e90 100644
--- a/test/cucumber/adapter/common.steps.js
+++ b/test/cucumber/adapter/common.steps.js
@@ -0,0 +1,16 @@
+const assert = require('assert');
+const { When, Then } = require('@cucumber/cucumber');
+
+Then('a successful response is returned with status {int}', function(expectedStatus) {
+  this.call
+  .then(response => {
+    assert.equal(response.status, expectedStatus);
+  });
+});
+
+Then('an error response is returned with status {int}', function(expectedStatus) {
+  this.call
+  .catch((error) => {
+    assert.equal(error.response.status, expectedStatus);
+  });
+});
\ No newline at end of file
diff --git a/test/cucumber/adapter/poll.steps.js b/test/cucumber/adapter/poll.steps.js
index 3d7ddaf..db3b564 100644
--- a/test/cucumber/adapter/poll.steps.js
+++ b/test/cucumber/adapter/poll.steps.js
@@ -45,10 +45,3 @@ Then('the protocol {string} method is called {int} times', function(method, xInv
   const decodes = this.protocol.getTrackedCalls(method);
   assert.equal(decodes.length, xInvokes);
 });
-
-Then('an error response is returned with status {int}', function(expectedStatus) {
-  this.call
-  .catch((error) => {
-    assert.equal(error.response.status, expectedStatus);
-  });
-});
diff --git a/test/cucumber/adapter/publish.steps.js b/test/cucumber/adapter/publish.steps.js
index 055c7fd..95a0f62 100644
--- a/test/cucumber/adapter/publish.steps.js
+++ b/test/cucumber/adapter/publish.steps.js
@@ -24,11 +24,4 @@ When('the publish method is called', function() {
   const topic = message.metadata.destination;
   const body = JSON.stringify(message);
   this.call = this.adapter.publish(topic, body);
-});
-
-Then('a successful response is returned with status {int}', function(expectedStatus) {
-  this.call
-  .then(response => {
-    assert.equal(response.status, expectedStatus);
-  });
 });
\ No newline at end of file
diff --git a/test/cucumber/adapter/validate.steps.js b/test/cucumber/adapter/validate.steps.js
index 86596aa..a55a00d 100644
--- a/test/cucumber/adapter/validate.steps.js
+++ b/test/cucumber/adapter/validate.steps.js
@@ -13,14 +13,4 @@ Given('an invalid message', function() {
 
 When('the validate method is called', function() {
   this.validation = this.adapter.validate(this.message);
-});
-
-Then('the message is validated successfully', function() {
-  assert.equal(this.validation.valid, true);
-  assert.equal(this.validation.errorCount, 0);
-});
-
-Then('the message fails to validate', function() {
-  assert.equal(this.validation.valid, false);
-  assert.notEqual(this.validation.errorCount, 0);
 });
\ No newline at end of file
diff --git a/test/cucumber/protocol/common.steps.js b/test/cucumber/protocol/common.steps.js
new file mode 100644
index 0000000..734211c
--- /dev/null
+++ b/test/cucumber/protocol/common.steps.js
@@ -0,0 +1,6 @@
+const assert = require('assert');
+const { Then } = require('@cucumber/cucumber');
+
+Then('the message is returned unaltered', function() {
+  assert.equal(this.message, this.response);
+});
\ No newline at end of file
diff --git a/test/cucumber/protocol/decode.steps.js b/test/cucumber/protocol/decode.steps.js
new file mode 100644
index 0000000..d831b81
--- /dev/null
+++ b/test/cucumber/protocol/decode.steps.js
@@ -0,0 +1,6 @@
+const { When } = require('@cucumber/cucumber');
+
+When('the protocol.decode method is called', function() {
+  const type = this.protocol.getType(this.message);
+  this.response = this.protocol.decode(type, this.message);
+});
\ No newline at end of file
diff --git a/test/cucumber/protocol/encode.steps.js b/test/cucumber/protocol/encode.steps.js
new file mode 100644
index 0000000..be79d26
--- /dev/null
+++ b/test/cucumber/protocol/encode.steps.js
@@ -0,0 +1,6 @@
+const { When } = require('@cucumber/cucumber');
+
+When('the protocol.encode method is called', function() {
+  const type = this.protocol.getType(this.message);
+  this.response = this.protocol.encode(type, this.message);
+});
\ No newline at end of file
diff --git a/test/cucumber/protocol/get-type.steps.js b/test/cucumber/protocol/get-type.steps.js
new file mode 100644
index 0000000..61b7808
--- /dev/null
+++ b/test/cucumber/protocol/get-type.steps.js
@@ -0,0 +1,14 @@
+const assert = require('assert');
+const { When, Then } = require('@cucumber/cucumber');
+
+When('protocol getType is called', function() {
+  this.type = this.protocol.getType(this.message);
+});
+
+Then('getType returns message.payload.message_type if present', function() {
+  assert.equal(this.type, this.message.payload.message_type);
+});
+
+Then('getType returns null if message.payload.message_type is not present', function() {
+  assert.equal(this.type, null);
+});
\ No newline at end of file
diff --git a/test/cucumber/protocol/validate.steps.js b/test/cucumber/protocol/validate.steps.js
new file mode 100644
index 0000000..fdf86ab
--- /dev/null
+++ b/test/cucumber/protocol/validate.steps.js
@@ -0,0 +1,16 @@
+const assert = require('assert');
+const { When, Then } = require('@cucumber/cucumber');
+
+When('the protocol.validate method is called', function() {
+  this.validation = this.protocol.validate(this.message);
+});
+
+Then('the message is validated successfully', function() {
+  assert.equal(this.validation.valid, true);
+  assert.equal(this.validation.errorCount, 0);
+});
+
+Then('the message fails to validate', function() {
+  assert.equal(this.validation.valid, false);
+  assert.notEqual(this.validation.errorCount, 0);
+});
\ No newline at end of file
diff --git a/test/fixtures/message-vehicle-status-invalid.json b/test/fixtures/message-vehicle-status-invalid.json
index cbcf162..c59f56d 100644
--- a/test/fixtures/message-vehicle-status-invalid.json
+++ b/test/fixtures/message-vehicle-status-invalid.json
@@ -6,9 +6,9 @@
     "message_id": "test"
   },
   "payload": {
-    "message_type": "VehicleStatus",
-    "xoperator_id": 1,
-    "xvehicle_id": 12,
+    "messagetype": "VehicleStatus",
+    "operatorID": 1,
+    "vehicleID": 12,
     "coordinates": {
       "latitude": "monkeys",
       "longitude": "janvier",
-- 
GitLab