From 1780539810b341ef4c067f42cbb8b5b94d7d3bfc Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Wed, 18 Jan 2023 16:01:32 +0000
Subject: [PATCH 01/33] feat: features and fixtures from js adapter

---
 LICENCE.md                                    |   7 +
 README.md                                     |  20 +-
 features/adapter_auth.feature                 |  13 +
 features/adapter_broadcast.feature            |  18 ++
 .../adapter_get-authorization-header.feature  |  21 ++
 features/adapter_poll.feature                 |  42 +++
 features/adapter_publish.feature              |  18 ++
 features/adapter_token-valid.feature          |  21 ++
 features/adapter_validate.feature             |  16 ++
 features/protocol_decode.feature              |  11 +
 features/protocol_encode.feature              |  11 +
 features/protocol_get-type.feature            |  12 +
 features/protocol_validate.feature            |  12 +
 features/schema_validate.feature              |  10 +
 fixtures/config-invalid.json                  |   7 +
 fixtures/config-valid.json                    |   7 +
 fixtures/message-vehicle-status-invalid.json  |  20 ++
 fixtures/message-vehicle-status.json          |  20 ++
 fixtures/response-denied-token.json           |   3 +
 fixtures/response-valid-token.json            |   4 +
 fixtures/schema-swagger.json                  | 252 ++++++++++++++++++
 21 files changed, 544 insertions(+), 1 deletion(-)
 create mode 100644 LICENCE.md
 create mode 100644 features/adapter_auth.feature
 create mode 100644 features/adapter_broadcast.feature
 create mode 100644 features/adapter_get-authorization-header.feature
 create mode 100644 features/adapter_poll.feature
 create mode 100644 features/adapter_publish.feature
 create mode 100644 features/adapter_token-valid.feature
 create mode 100644 features/adapter_validate.feature
 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 features/schema_validate.feature
 create mode 100644 fixtures/config-invalid.json
 create mode 100644 fixtures/config-valid.json
 create mode 100644 fixtures/message-vehicle-status-invalid.json
 create mode 100644 fixtures/message-vehicle-status.json
 create mode 100644 fixtures/response-denied-token.json
 create mode 100644 fixtures/response-valid-token.json
 create mode 100644 fixtures/schema-swagger.json

diff --git a/LICENCE.md b/LICENCE.md
new file mode 100644
index 0000000..10bb2c1
--- /dev/null
+++ b/LICENCE.md
@@ -0,0 +1,7 @@
+Copyright 2023 [NOC](https://noc.ac.uk)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 82d8c17..88d1c4e 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,21 @@
 # backbone-adapter-testsuite
 
-Gherkin feature definitions and fixtures to run against all language ports of the adapter. 
\ No newline at end of file
+Gherkin feature definitions and fixtures to run against all language ports of the backbone-adapter. 
+
+## Contents 
+
+### /features 
+
+Gherkin `.feature` files describing a suite of tests which 
+should be run against all language ports of the adapter 
+
+### /fixtures
+
+A set of fixtures to be used to configure the tests.
+
+### Implementations 
+
+You can see existing implementations of the test suite here 
+
+- [JS-Cucumber](https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-javascript) 
+Step definitions are in `test/cucumber`
\ No newline at end of file
diff --git a/features/adapter_auth.feature b/features/adapter_auth.feature
new file mode 100644
index 0000000..c55e271
--- /dev/null
+++ b/features/adapter_auth.feature
@@ -0,0 +1,13 @@
+Feature: Does the adapter authenticate?
+  When an adapter instance is created it authenticates and receives a token
+
+  Scenario: A token is granted with valid config
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    Then the adapter credentials are populated
+
+  Scenario: Auth fails with invalid config
+    Given invalid config
+    When the adapter instance is created
+    Then the adapter auth fails
\ No newline at end of file
diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
new file mode 100644
index 0000000..e37344a
--- /dev/null
+++ b/features/adapter_broadcast.feature
@@ -0,0 +1,18 @@
+Feature: Can the adapter broadcast messages?
+  The adapter publish method works as expected
+
+  Scenario: A message can be published successfully
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock notify API response is configured to return success
+    When the broadcast method is called
+    Then a successful response is returned with status 200
+
+  Scenario: A failed publish returns a 403
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock notify API response is configured to return an error
+    When the broadcast method is called
+    Then an error response is returned with status 403
\ No newline at end of file
diff --git a/features/adapter_get-authorization-header.feature b/features/adapter_get-authorization-header.feature
new file mode 100644
index 0000000..59de9a4
--- /dev/null
+++ b/features/adapter_get-authorization-header.feature
@@ -0,0 +1,21 @@
+Feature: Does the adapter authenticate?
+  When an adapter instance is created it authenticates and receives a token
+
+  Scenario: getAuthorizationHeader returns a bearer token
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When the getAuthorizationHeader method is called
+    Then a headers object is returned containing a bearer token authorization header
+
+  Scenario: getAuthorizationHeader implicitly calls auth if required
+    Given valid config
+    When the adapter instance is created
+    When the getAuthorizationHeader method is called
+    Then a headers object is returned containing a bearer token authorization header
+
+  Scenario: getAuthorizationHeader implicitly calls auth if required
+    Given invalid config
+    When the adapter instance is created
+    When the getAuthorizationHeader method is called
+    Then an error response is returned with status 403
\ No newline at end of file
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
new file mode 100644
index 0000000..9ecc9e9
--- /dev/null
+++ b/features/adapter_poll.feature
@@ -0,0 +1,42 @@
+# When the queue contains x messages 
+# only mocks the API response 
+# Testing how the API behaves with a full queue are defined in the API 
+
+Feature: Can the adapter receive messages?
+  The adapter poll method works as expected
+
+  Scenario: No messages are received succecssfully if the queue is empty
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock receive API response is configured to return 0 messages
+    When the poll method is called
+    Then a successful response is returned with 0 messages  
+
+  Scenario: 2 messages are received succecssfully if the queue contains 2 messages
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock receive API response is configured to return 2 messages 
+    When the poll method is called
+    Then a successful response is returned with 2 messages
+    Then the protocol "validate" method is called 2 times
+    Then the protocol "decode" method is called 2 times
+
+  Scenario: 10 messages are received succecssfully if the queue contains 10 messages
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock receive API response is configured to return 10 messages 
+    When the poll method is called
+    Then a successful response is returned with 10 messages
+    Then the protocol "validate" method is called 10 times
+    Then the protocol "decode" method is called 10 times
+
+  Scenario: An invalid token returns a forbidden response 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock receive API response is configured to return an error
+    When the poll method is called 
+    Then an error response is returned with status 403
diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
new file mode 100644
index 0000000..7e7e7de
--- /dev/null
+++ b/features/adapter_publish.feature
@@ -0,0 +1,18 @@
+Feature: Can the adapter publish messages?
+  The adapter publish method works as expected
+
+  Scenario: A message can be published successfully
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock send API response is configured to return success
+    When the publish method is called
+    Then a successful response is returned with status 200
+
+  Scenario: A failed publish returns a 403
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When a mock send API response is configured to return an error
+    When the publish method is called
+    Then an error response is returned with status 403
diff --git a/features/adapter_token-valid.feature b/features/adapter_token-valid.feature
new file mode 100644
index 0000000..53fe89d
--- /dev/null
+++ b/features/adapter_token-valid.feature
@@ -0,0 +1,21 @@
+Feature: Is the token valid?
+  The adapter tokenValid method works as expected
+
+  Scenario: If adapter has not authed token is invalid
+    Given valid config
+    When the adapter instance is created
+    Then tokenValid returns false  
+
+  Scenario: If credentials.expiry is in the future token is valid
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When the token expiry is in the future
+    Then tokenValid returns true  
+
+  Scenario: If credentials.expiry is in the past token is invalid
+    Given valid config
+    When the adapter instance is created
+    When the auth method is called
+    When the token expiry is in the past
+    Then tokenValid returns false 
diff --git a/features/adapter_validate.feature b/features/adapter_validate.feature
new file mode 100644
index 0000000..c2af9f1
--- /dev/null
+++ b/features/adapter_validate.feature
@@ -0,0 +1,16 @@
+Feature: Can the adapter validate messages?
+  The adapter validate method works as expected
+
+  Scenario: A valid message is successfully validated against the protocol schema
+    Given valid config
+    Given a valid message
+    When the adapter instance is created
+    When the validate method is called
+    Then the message is validated successfully  
+  
+  Scenario: An invalid message fails to validate against the protocol schema
+    Given valid config
+    Given an invalid message
+    When the adapter instance is created
+    When the validate method is called
+    Then the message fails to validate  
\ No newline at end of file
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/features/schema_validate.feature b/features/schema_validate.feature
new file mode 100644
index 0000000..34f457a
--- /dev/null
+++ b/features/schema_validate.feature
@@ -0,0 +1,10 @@
+# If the mock schema fixture fails to validate 
+# it can cause invalid messages to show as valid
+
+Feature: Is the mock schema valid?
+  The mock schema must validate in order for the adapter test to work
+
+  Scenario: The schema matches the OpenAPI specification
+    Given the test schema
+    When it is validated
+    Then it matches the OpenAPI specification  
\ No newline at end of file
diff --git a/fixtures/config-invalid.json b/fixtures/config-invalid.json
new file mode 100644
index 0000000..82625f6
--- /dev/null
+++ b/fixtures/config-invalid.json
@@ -0,0 +1,7 @@
+{
+  "api": "https://example.backbone.com/api",
+  "client_id": "invalid-client-id",
+  "client_name": "InvalidClientName",
+  "subscription": "dot.delimited.topic.subscription.#",
+  "secret": "TheCollaredDoveCoosInTheChimneyPot"
+}
\ No newline at end of file
diff --git a/fixtures/config-valid.json b/fixtures/config-valid.json
new file mode 100644
index 0000000..8b765ec
--- /dev/null
+++ b/fixtures/config-valid.json
@@ -0,0 +1,7 @@
+{
+  "api": "https://example.backbone.com/api",
+  "client_id": "unique-client-id",
+  "client_name": "UniqueClientName",
+  "subscription": "dot.delimited.topic.subscription.#",
+  "secret": "TheGeeseFlySouthInWinter"
+}
\ No newline at end of file
diff --git a/fixtures/message-vehicle-status-invalid.json b/fixtures/message-vehicle-status-invalid.json
new file mode 100644
index 0000000..c59f56d
--- /dev/null
+++ b/fixtures/message-vehicle-status-invalid.json
@@ -0,0 +1,20 @@
+{
+  "metadata": {
+    "source": "ae",
+    "destination": "soar.po.ecosub.eco1",
+    "delivery_type": "publish",
+    "message_id": "test"
+  },
+  "payload": {
+    "messagetype": "VehicleStatus",
+    "operatorID": 1,
+    "vehicleID": 12,
+    "coordinates": {
+      "latitude": "monkeys",
+      "longitude": "janvier",
+      "depth": "twenty five metres please",
+      "projection": 4326
+    },
+    "battery_percentage": "plenty"
+  }
+}
\ No newline at end of file
diff --git a/fixtures/message-vehicle-status.json b/fixtures/message-vehicle-status.json
new file mode 100644
index 0000000..55cdd81
--- /dev/null
+++ b/fixtures/message-vehicle-status.json
@@ -0,0 +1,20 @@
+{
+  "metadata": {
+    "source": "ae",
+    "destination": "soar.po.ecosub.eco1",
+    "delivery_type": "publish",
+    "message_id": "test"
+  },
+  "payload": {
+    "message_type": "VehicleStatus",
+    "operator_id": "po",
+    "vehicle_id": "eco1",
+    "coordinates": {
+      "latitude": 57.234,
+      "longitude": -8.432,
+      "depth": 50,
+      "projection": 4326
+    },
+    "battery_percentage": 64
+  }
+}
\ No newline at end of file
diff --git a/fixtures/response-denied-token.json b/fixtures/response-denied-token.json
new file mode 100644
index 0000000..d5fb311
--- /dev/null
+++ b/fixtures/response-denied-token.json
@@ -0,0 +1,3 @@
+{
+  "message": "Invalid client credentials"
+}
\ No newline at end of file
diff --git a/fixtures/response-valid-token.json b/fixtures/response-valid-token.json
new file mode 100644
index 0000000..87306ff
--- /dev/null
+++ b/fixtures/response-valid-token.json
@@ -0,0 +1,4 @@
+{
+  "token": "gAAAAABjwB-vxtER44M2en6xYyt7G1WXp8QwfsiHw-ijCqNBZpQPwxxrBHzUU1fQ9lfPPo4QHj50p-yh203dV6zLLoTzuiReqGzE2InqAxOwv4gddlQWNFJKyrmg4mVVMX2VZe2cCAljmHxEo66BHgt_T24AieedMnI4VR2kw4SFiooFv5nr2W8=",
+  "expiry": "2030-12-31T23:59:59.000000"
+}
\ No newline at end of file
diff --git a/fixtures/schema-swagger.json b/fixtures/schema-swagger.json
new file mode 100644
index 0000000..35999bc
--- /dev/null
+++ b/fixtures/schema-swagger.json
@@ -0,0 +1,252 @@
+{
+  "openapi": "3.0.3",
+  "info": {
+    "title": "soar",
+    "version": "1.0",
+    "description": "SoAR message schemas"
+  },
+  "paths": {},
+  "components": {
+    "schemas": {
+      "Message": {
+        "properties": {
+          "metadata": {
+            "$ref": "#/components/schemas/Metadata"
+          },
+          "payload": {
+            "$ref": "#/components/schemas/Payload"
+          }
+        },
+        "required": ["metadata", "payload"]
+      },
+      "Payload": {
+        "discriminator": {
+          "propertyName": "message_type",
+          "mapping": {
+            "VehicleStatus": "#/components/schemas/VehicleStatus",
+            "VehicleMission": "#/components/schemas/VehicleMission",
+            "AreaOfInterest": "#/components/schemas/AreaOfInterest"
+          }
+        },
+        "oneOf": [
+          {
+            "$ref": "#/components/schemas/VehicleStatus"
+          },
+          {
+            "$ref": "#/components/schemas/VehicleMission"
+          },
+          {
+            "$ref": "#/components/schemas/AreaOfInterest"
+          }
+        ]
+      },
+      "Metadata": {
+        "properties": {
+          "source": {
+            "type": "string",
+            "description": "The sender.",
+            "example": "autonomy-engine"
+          },
+          "destination": {
+            "type": "string",
+            "description": "Publisher topic.",
+            "example": "soar.noc.autosub.ah1.status"
+          },
+          "delivery_type": {
+            "type": "string",
+            "description": "Published or broadcast",
+            "enum": ["broadcast", "publish"],
+            "example": "2.0.0"
+          },
+          "message_id": {
+            "type": "string",
+            "description": "An identifier for the type of message received.",
+            "example": "VehicleStatus"
+          }
+        },
+        "required": ["source","destination","message_id"],
+        "type": "object"
+      },
+      "Coordinates": {
+        "properties": {
+          "latitude": {
+            "type": "number",
+            "description": "Latitude in decimal degrees.",
+            "example": 54.234
+          },
+          "longitude": {
+            "type": "number",
+            "description": "Longitude in decimal degrees.",
+            "example": -1.432
+          },
+          "depth": {
+            "type": "number",
+            "description": "Target depth",
+            "default": 0,
+            "example": 50
+          },
+          "altitude": {
+            "type": "number",
+            "description": "Target altitude above bottom",
+            "default": 0,
+            "example": 50
+          },
+          "projection": {
+            "type": "integer",
+            "description": "EPSG Projection Code",
+            "example": 4326,
+            "default": 4326
+          }
+        },
+        "required": ["latitude", "longitude"],
+        "type": "object"
+      },
+      "VehicleStatus": {
+        "properties": {
+          "message_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "VehicleStatus",
+            "enum": ["VehicleStatus"]
+          },
+          "operator_id": {
+            "type": "string",
+            "description": "An identifier for the operator.",
+            "example": "noc"
+          },
+          "vehicle_id": {
+            "type": "string",
+            "description": "An identifier for the vehicle.",
+            "example": "noc_ah1"
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          },
+          "battery_percentage": {
+            "type": "number",
+            "description": "The remaining battery capacity.",
+            "example": 64
+          }
+        },
+        "required": ["message_type", "operator_id", "vehicle_id", "coordinates", "battery_percentage"],
+        "type": "object"
+      },
+      "VehicleMission": {
+        "properties": {
+          "message_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "VehicleMission",
+            "enum": ["VehicleMission"]
+          },
+          "operator_id": {
+            "type": "string",
+            "description": "An identifier for the operator.",
+            "example": "noc"
+          },
+          "vehicle_id": {
+            "type": "string",
+            "description": "An identifier for the vehicle.",
+            "example": "noc_ah1"
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          },
+          "actions": {
+            "type": "array",
+            "items": {
+              "discriminator": {
+                "propertyName": "action_type",
+                "mapping": {
+                  "GoToWaypoint": "#/components/schemas/GoToWaypoint",
+                  "DescendToAltitude": "#/components/schemas/DescendToAltitude",
+                  "AscendToSurface": "#/components/schemas/AscendToSurface"
+                }
+              },
+              "oneOf": [
+                {
+                  "$ref": "#/components/schemas/VehicleStatus"
+                },
+                {
+                  "$ref": "#/components/schemas/VehicleMission"
+                },
+                {
+                  "$ref": "#/components/schemas/AreaOfInterest"
+                }
+              ]
+            }
+          }
+        },
+        "required": ["message_type", "operator_id", "vehicle_id", "coordinates", "actions"],
+        "type": "object"
+      },
+      "AreaOfInterest": {
+        "properties": {
+          "message_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "AreaOfInterest",
+            "enum": ["AreaOfInterest"]
+          },
+          "operator_id": {
+            "type": "string",
+            "description": "An identifier for the operator.",
+            "example": "noc"
+          },
+          "vehicle_id": {
+            "type": "string",
+            "description": "An identifier for the vehicle.",
+            "example": "noc_ah1"
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          }
+        },
+        "required": ["message_type", "operator_id", "vehicle_id", "coordinates"],
+        "type": "object"
+      },
+      "GoToWaypoint": {
+        "properties": {
+          "action_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "GoToWaypoint",
+            "enum": ["GoToWaypoint"]
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          }
+        },
+        "type": "object"
+      },
+      "DescendToAltitude": {
+        "properties": {
+          "action_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "DescendToAltitude",
+            "enum": ["DescendToAltitude"]
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          }
+        },
+        "type": "object"
+      },
+      "AscendToSurface": {
+        "properties": {
+          "action_type": {
+            "type": "string",
+            "description": "An identifier for the payload type.",
+            "example": "AscendToSurface",
+            "enum": ["AscendToSurface"]
+          },
+          "coordinates": {
+            "$ref": "#/components/schemas/Coordinates"
+          }
+        },
+        "type": "object"
+      }
+    }
+  }
+}
-- 
GitLab


From ddd182c92ba717786c72d9e55deefca91baf69fe Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 09:09:31 +0000
Subject: [PATCH 02/33] fix: correct feature description for auth header

---
 features/adapter_get-authorization-header.feature | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/features/adapter_get-authorization-header.feature b/features/adapter_get-authorization-header.feature
index 59de9a4..554acdf 100644
--- a/features/adapter_get-authorization-header.feature
+++ b/features/adapter_get-authorization-header.feature
@@ -1,5 +1,5 @@
-Feature: Does the adapter authenticate?
-  When an adapter instance is created it authenticates and receives a token
+Feature: Can the adapter create an authorization header?
+  The adapter getAuthorizationHeader method works as expected
 
   Scenario: getAuthorizationHeader returns a bearer token
     Given valid config
-- 
GitLab


From 40b9fe63ed9cbdd7130904f8c69d6a07dfdf1641 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 14:52:49 +0000
Subject: [PATCH 03/33] test: experiment with installing with npm and pip

---
 package.json | 23 +++++++++++++++++++++++
 setup.py     |  9 +++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 package.json
 create mode 100644 setup.py

diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3dab9b5
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+  "name": "backbone-adapter-testsuite",
+  "description": "Common test suite to run on all adapter language ports",
+  "repository": {
+    "type": "git",
+    "url": "git@git.noc.ac.uk:communications-backbone-system/backbone-adapter-testsuite.git"
+  },
+  "contributors": [
+    {
+      "name": "James Kirk",
+      "email": "james.kirk@noc.ac.uk"
+    },
+    {
+      "name": "Dan Jones",
+      "email": "dan.jones@noc.ac.uk"
+    },
+    {
+      "name": "Trishna Saeharaseelan",
+      "email": "trishna.saeharaseelan@noc.ac.uk"
+    }
+  ],
+  "license": "MIT"
+}
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..5e932fa
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,9 @@
+setup(
+   name='backbone-adapter-testsuite',
+   packages=find_packages(),
+   package_data={
+      'myapp': ['features/*.feature', 'fixtures/*.json'],
+   },
+   include_package_data=True,
+   zip_safe=False
+)
\ No newline at end of file
-- 
GitLab


From 97b7f98c81ab77d8900a26e627f5040ff7240634 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:07:10 +0000
Subject: [PATCH 04/33] fix: import setup

---
 setup.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/setup.py b/setup.py
index 5e932fa..1f90bd8 100644
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,5 @@
+from setuptools import setup
+
 setup(
    name='backbone-adapter-testsuite',
    packages=find_packages(),
-- 
GitLab


From a82e040fb87489ead13408733c8a2962392f11a4 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:08:38 +0000
Subject: [PATCH 05/33] fix: import find_packages

---
 setup.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/setup.py b/setup.py
index 1f90bd8..4aff18b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-from setuptools import setup
+from setuptools import setup, find_packages
 
 setup(
    name='backbone-adapter-testsuite',
@@ -8,4 +8,4 @@ setup(
    },
    include_package_data=True,
    zip_safe=False
-)
\ No newline at end of file
+)
-- 
GitLab


From ddfef10d09507d55110eff4b077cd508537fb171 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:19:01 +0000
Subject: [PATCH 06/33] fix: change package data name

---
 setup.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index 4aff18b..f05a85b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,10 +1,11 @@
 from setuptools import setup, find_packages
 
+
 setup(
    name='backbone-adapter-testsuite',
    packages=find_packages(),
    package_data={
-      'myapp': ['features/*.feature', 'fixtures/*.json'],
+      'backbone-adapter-testsuite': ['features/*.feature', 'fixtures/*.json'],
    },
    include_package_data=True,
    zip_safe=False
-- 
GitLab


From be9e95cc68c60f8fb032e9c5b9d12283d164fc28 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:23:24 +0000
Subject: [PATCH 07/33] fix: change package_data config

---
 setup.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index f05a85b..4bfd512 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,8 @@ setup(
    name='backbone-adapter-testsuite',
    packages=find_packages(),
    package_data={
-      'backbone-adapter-testsuite': ['features/*.feature', 'fixtures/*.json'],
+      'features': ['features/*.feature'], 
+      'fixtures': ['*.json'],
    },
    include_package_data=True,
    zip_safe=False
-- 
GitLab


From a06070b8caa47508d800541240d5bc2918dd37da Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:26:36 +0000
Subject: [PATCH 08/33] fix declare package_data from root

---
 setup.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/setup.py b/setup.py
index 4bfd512..5e8d14f 100644
--- a/setup.py
+++ b/setup.py
@@ -5,8 +5,7 @@ setup(
    name='backbone-adapter-testsuite',
    packages=find_packages(),
    package_data={
-      'features': ['features/*.feature'], 
-      'fixtures': ['*.json'],
+      '': ['features/*.feature', 'fixtures/*.json'], 
    },
    include_package_data=True,
    zip_safe=False
-- 
GitLab


From 3581c145d04279ef232f611a42e501dd6452d43a Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:31:09 +0000
Subject: [PATCH 09/33] fix: add package data to MANIFEST.in

---
 MANIFEST.in | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 MANIFEST.in

diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..4f01146
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,2 @@
+include features/*.feature
+include fixtures/*.json
-- 
GitLab


From 778abaff656b01820e3aeecfc8e555c6ea35f5e4 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Thu, 19 Jan 2023 15:44:39 +0000
Subject: [PATCH 10/33] fix: identify location of package

---
 setup.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/setup.py b/setup.py
index 5e8d14f..5f409e4 100644
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,14 @@
-from setuptools import setup, find_packages
+from setuptools import setup
 
 
 setup(
    name='backbone-adapter-testsuite',
-   packages=find_packages(),
+   packages=['testsuite'],
+   package_dir: {
+      'testsuite': '.',
+   },
    package_data={
-      '': ['features/*.feature', 'fixtures/*.json'], 
+      'testsuite': ['features/*.feature', 'fixtures/*.json'], 
    },
    include_package_data=True,
-   zip_safe=False
 )
-- 
GitLab


From 07f7f064bd544bed47b7115c1665bf48e3cf0cc4 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 20 Jan 2023 09:29:39 +0000
Subject: [PATCH 11/33] fix: correct indentation

---
 setup.py | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/setup.py b/setup.py
index 5f409e4..6e8bc2e 100644
--- a/setup.py
+++ b/setup.py
@@ -2,13 +2,13 @@ from setuptools import setup
 
 
 setup(
-   name='backbone-adapter-testsuite',
-   packages=['testsuite'],
-   package_dir: {
-      'testsuite': '.',
-   },
-   package_data={
-      'testsuite': ['features/*.feature', 'fixtures/*.json'], 
-   },
-   include_package_data=True,
+    name='backbone-adapter-testsuite',
+    packages=['testsuite'],
+    package_dir={
+        'testsuite': '.',
+    },
+    package_data={
+        'testsuite': ['features/*.feature', 'fixtures/*.json'], 
+    },
+    include_package_data=True,
 )
-- 
GitLab


From 7bcad5e26dfea49a37ffed718a9ce27107228e86 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 20 Jan 2023 15:35:52 +0000
Subject: [PATCH 12/33] feat: add post install setup for python

---
 README.md     | 31 +++++++++++++++++++++++++++++--
 copy_tests.py | 25 +++++++++++++++++++++++++
 setup.cfg     |  3 +++
 setup.py      |  2 +-
 4 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 copy_tests.py
 create mode 100644 setup.cfg

diff --git a/README.md b/README.md
index 88d1c4e..ddb70bc 100644
--- a/README.md
+++ b/README.md
@@ -13,9 +13,36 @@ should be run against all language ports of the adapter
 
 A set of fixtures to be used to configure the tests.
 
-### Implementations 
+## Implementations 
 
 You can see existing implementations of the test suite here 
 
 - [JS-Cucumber](https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-javascript) 
-Step definitions are in `test/cucumber`
\ No newline at end of file
+Step definitions are in `test/cucumber`
+
+## Installing
+
+The intention is to install a tagged version of the testsuite into each adapter so that if we develop 
+the testsuite existing adapter implementations won't break. 
+
+### NPM 
+
+```bash
+npm install --saveDev git+https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite.git#[tag|branch|commit]
+```
+
+### Yarn 
+
+```bash
+yarn add --dev git+https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite.git#[tag|branch|commit]
+```
+
+### PIP 
+
+```bash
+echo
+"git+https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite.git@[tag|branch|commit]#egg=backbone-adapter-testsuite" >> requirements.txt 
+pip install -r reqiurements.txt
+# copy features and fixtures into test directory
+copy_tests
+```
diff --git a/copy_tests.py b/copy_tests.py
new file mode 100644
index 0000000..631c831
--- /dev/null
+++ b/copy_tests.py
@@ -0,0 +1,25 @@
+import os
+from shutil import copytree
+import site 
+
+
+def copy_directory(src, dest, directory):
+    copytree(os.path.join(src, directory), os.path.join(dest, directory))
+
+
+def copy(): 
+    here = os.getcwd();
+    package_locations = site.getsitepackages()
+
+    for root_path in package_locations:
+        dirs = [x[0] for x in os.walk(root_path)]
+        for dirx in dirs: 
+            if dirx.endswith('testsuite'):
+                src = dirx
+                dest = os.path.join(here, 'test')
+                copy_directory(src, dest, 'features')
+                copy_directory(src, dest, 'fixtures') 
+
+
+if __name__ == '__main__':
+    copy()
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..a8aeb66
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,3 @@
+[options.entry_points]
+console_scripts=
+    copy_tests = testsuite.copy_tests:copy
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 6e8bc2e..b025934 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup
 
 
 setup(
-    name='backbone-adapter-testsuite',
+    name='backbone_adapter_testsuite',
     packages=['testsuite'],
     package_dir={
         'testsuite': '.',
-- 
GitLab


From 95692094de5498d55ab3b7cb05787424069c4882 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 20 Jan 2023 15:40:39 +0000
Subject: [PATCH 13/33] fix: add version to package.json

---
 package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/package.json b/package.json
index 3dab9b5..6cc5121 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
 {
   "name": "backbone-adapter-testsuite",
+  "version": "0.0.1",
   "description": "Common test suite to run on all adapter language ports",
   "repository": {
     "type": "git",
-- 
GitLab


From 66f7e6f115bc08ced8bd3edba5dd9baba8f7dd13 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 20 Jan 2023 16:08:20 +0000
Subject: [PATCH 14/33] docs: draw attention to the git url versioning

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index ddb70bc..0bc3abc 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,8 @@ Step definitions are in `test/cucumber`
 The intention is to install a tagged version of the testsuite into each adapter so that if we develop 
 the testsuite existing adapter implementations won't break. 
 
+In JS the target tag/branch/commit is specified with # after the git url
+
 ### NPM 
 
 ```bash
@@ -39,6 +41,8 @@ yarn add --dev git+https://git.noc.ac.uk/communications-backbone-system/backbone
 
 ### PIP 
 
+In pip the target tag/branch/commit is specified with @ after the git url
+
 ```bash
 echo
 "git+https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite.git@[tag|branch|commit]#egg=backbone-adapter-testsuite" >> requirements.txt 
-- 
GitLab


From 06cefe4e050901fe4ca880f976dd9750f37550eb Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 23 Jan 2023 15:27:52 +0000
Subject: [PATCH 15/33] fix: correct typos in scenario names

---
 features/adapter_poll.feature | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index 9ecc9e9..ff05566 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -5,7 +5,7 @@
 Feature: Can the adapter receive messages?
   The adapter poll method works as expected
 
-  Scenario: No messages are received succecssfully if the queue is empty
+  Scenario: No messages are received successfully if the queue is empty
     Given valid config
     When the adapter instance is created
     When the auth method is called
@@ -13,7 +13,7 @@ Feature: Can the adapter receive messages?
     When the poll method is called
     Then a successful response is returned with 0 messages  
 
-  Scenario: 2 messages are received succecssfully if the queue contains 2 messages
+  Scenario: 2 messages are received successfully if the queue contains 2 messages
     Given valid config
     When the adapter instance is created
     When the auth method is called
@@ -23,7 +23,7 @@ Feature: Can the adapter receive messages?
     Then the protocol "validate" method is called 2 times
     Then the protocol "decode" method is called 2 times
 
-  Scenario: 10 messages are received succecssfully if the queue contains 10 messages
+  Scenario: 10 messages are received successfully if the queue contains 10 messages
     Given valid config
     When the adapter instance is created
     When the auth method is called
-- 
GitLab


From 89f4449612b1ec80c69283e95c18032448407669 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 23 Jan 2023 15:42:04 +0000
Subject: [PATCH 16/33] fix: clearer grammar for token scenarios

---
 features/adapter_token-valid.feature | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/features/adapter_token-valid.feature b/features/adapter_token-valid.feature
index 53fe89d..e0e105b 100644
--- a/features/adapter_token-valid.feature
+++ b/features/adapter_token-valid.feature
@@ -1,19 +1,19 @@
 Feature: Is the token valid?
   The adapter tokenValid method works as expected
 
-  Scenario: If adapter has not authed token is invalid
+  Scenario: If adapter has not authed then the tokenValid returns false
     Given valid config
     When the adapter instance is created
     Then tokenValid returns false  
 
-  Scenario: If credentials.expiry is in the future token is valid
+  Scenario: If credentials.expiry is in the future then the token is valid
     Given valid config
     When the adapter instance is created
     When the auth method is called
     When the token expiry is in the future
     Then tokenValid returns true  
 
-  Scenario: If credentials.expiry is in the past token is invalid
+  Scenario: If credentials.expiry is in the past then the token is invalid
     Given valid config
     When the adapter instance is created
     When the auth method is called
-- 
GitLab


From 797ebbcb35e49b48b9eaf38e613d4e9ec9792019 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 23 Jan 2023 16:28:31 +0000
Subject: [PATCH 17/33] docs: explain expected behaviour of tokenValid

---
 features/adapter_token-valid.feature | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/features/adapter_token-valid.feature b/features/adapter_token-valid.feature
index e0e105b..c7290a7 100644
--- a/features/adapter_token-valid.feature
+++ b/features/adapter_token-valid.feature
@@ -1,3 +1,9 @@
+# tokenValid returns true if there is a token and the expiry is in the future
+# tokenValid returns false if the token expiry is in the past 
+# or if there is no token 
+# In the case where invalid credentials are supplied 
+# the auth will fail so there will be no token available 
+
 Feature: Is the token valid?
   The adapter tokenValid method works as expected
 
-- 
GitLab


From ec09b26945415b1d75edccdcc7ddf7945e6fcd2b Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Wed, 25 Jan 2023 08:14:32 +0000
Subject: [PATCH 18/33] fix: correct action schema references

---
 fixtures/schema-swagger.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fixtures/schema-swagger.json b/fixtures/schema-swagger.json
index 35999bc..c0638af 100644
--- a/fixtures/schema-swagger.json
+++ b/fixtures/schema-swagger.json
@@ -165,13 +165,13 @@
               },
               "oneOf": [
                 {
-                  "$ref": "#/components/schemas/VehicleStatus"
+                  "$ref": "#/components/schemas/GoToWaypoint"
                 },
                 {
-                  "$ref": "#/components/schemas/VehicleMission"
+                  "$ref": "#/components/schemas/DescendToAltitude"
                 },
                 {
-                  "$ref": "#/components/schemas/AreaOfInterest"
+                  "$ref": "#/components/schemas/AscendToSurface"
                 }
               ]
             }
-- 
GitLab


From d75d34e952c5a842587b5c4f5862c5a187d12e71 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 12:42:49 +0000
Subject: [PATCH 19/33] feat: add tests for publish retry on 403

---
 features/adapter_publish.feature | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index 7e7e7de..e3429c6 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -16,3 +16,24 @@ Feature: Can the adapter publish messages?
     When a mock send API response is configured to return an error
     When the publish method is called
     Then an error response is returned with status 403
+
+  Scenario: On 403 the message is retried once with new credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock send API response is configured to return an error 
+    When the publish method is called 
+    Then an error response is returned with status 403 
+    Then the credentials are deleted
+    Then the publish method is called with is_retry on
+    Then the getAuthorizationHeader method is called 
+    
+  Scenario: On a retried 403 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock send API response is configured to return an error 
+    When the publish method is called with is_retry on
+    Then an error response is returned with status 403
+    Then the credentials are deleted 
+    Then the publish method is not called again
-- 
GitLab


From c53f1efe503d2435acc37d85413eeeb4548e061b Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 14:49:02 +0000
Subject: [PATCH 20/33] fix: separate ambiguous step definitions

Cucumber doesn't like having both a When and Then step
with the same text.
---
 features/adapter_publish.feature | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index e3429c6..0ff7806 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -25,7 +25,7 @@ Feature: Can the adapter publish messages?
     When the publish method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
-    Then the publish method is called with is_retry on
+    Then the publish method was called with is_retry on
     Then the getAuthorizationHeader method is called 
     
   Scenario: On a retried 403 the message is not retried again
-- 
GitLab


From 74a0fd7b410fe8495840b2a4d5e2677915fa423a Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 15:19:05 +0000
Subject: [PATCH 21/33] test: add tests for broadcast and poll retries

Retry once on 403 with new credentials
---
 features/adapter_broadcast.feature | 23 ++++++++++++++++++++++-
 features/adapter_poll.feature      | 21 +++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
index e37344a..34fea13 100644
--- a/features/adapter_broadcast.feature
+++ b/features/adapter_broadcast.feature
@@ -15,4 +15,25 @@ Feature: Can the adapter broadcast messages?
     When the auth method is called
     When a mock notify API response is configured to return an error
     When the broadcast method is called
-    Then an error response is returned with status 403
\ No newline at end of file
+    Then an error response is returned with status 403
+
+  Scenario: On 403 the message is retried once with new credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock notify API response is configured to return an error 
+    When the broadcast method is called 
+    Then an error response is returned with status 403 
+    Then the credentials are deleted
+    Then the broadcast method was called with is_retry on
+    Then the getAuthorizationHeader method is called 
+    
+  Scenario: On a retried 403 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock notify API response is configured to return an error 
+    When the broadcast method is called with is_retry on
+    Then an error response is returned with status 403
+    Then the credentials are deleted 
+    Then the broadcast method is not called again
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index ff05566..1a860b7 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -40,3 +40,24 @@ Feature: Can the adapter receive messages?
     When a mock receive API response is configured to return an error
     When the poll method is called 
     Then an error response is returned with status 403
+
+  Scenario: On 403 the message is retried once with new credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock receive API response is configured to return an error 
+    When the publish method is called 
+    Then an error response is returned with status 403 
+    Then the credentials are deleted
+    Then the receive method was called with is_retry on
+    Then the getAuthorizationHeader method is called 
+    
+  Scenario: On a retried 403 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock receive API response is configured to return an error 
+    When the receive method is called with is_retry on
+    Then an error response is returned with status 403
+    Then the credentials are deleted 
+    Then the receive method is not called again
-- 
GitLab


From dd29691affa53b04ac65b5fe7dc90df8e0286867 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 15:23:22 +0000
Subject: [PATCH 22/33] test: correct expected calls in poll method

---
 features/adapter_poll.feature | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index 1a860b7..348266a 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -46,10 +46,10 @@ Feature: Can the adapter receive messages?
     When the adapter instance is created 
     When the auth method is called 
     When a mock receive API response is configured to return an error 
-    When the publish method is called 
+    When the poll method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
-    Then the receive method was called with is_retry on
+    Then the poll method was called with is_retry on
     Then the getAuthorizationHeader method is called 
     
   Scenario: On a retried 403 the message is not retried again
@@ -57,7 +57,7 @@ Feature: Can the adapter receive messages?
     When the adapter instance is created 
     When the auth method is called 
     When a mock receive API response is configured to return an error 
-    When the receive method is called with is_retry on
+    When the poll method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the receive method is not called again
+    Then the poll method is not called again
-- 
GitLab


From 7bb6235a8543d17a39f2b3a926cf1612dc3a059d Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 16:18:16 +0000
Subject: [PATCH 23/33] test: add tests for 503 retries

---
 features/adapter_broadcast.feature | 27 ++++++++++++++++++++++++---
 features/adapter_poll.feature      | 28 +++++++++++++++++++++++++---
 features/adapter_publish.feature   | 27 ++++++++++++++++++++++++---
 3 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
index 34fea13..7d3e02d 100644
--- a/features/adapter_broadcast.feature
+++ b/features/adapter_broadcast.feature
@@ -13,7 +13,7 @@ Feature: Can the adapter broadcast messages?
     Given valid config
     When the adapter instance is created
     When the auth method is called
-    When a mock notify API response is configured to return an error
+    When a mock notify API response is configured to return a 403 error
     When the broadcast method is called
     Then an error response is returned with status 403
 
@@ -21,7 +21,7 @@ Feature: Can the adapter broadcast messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock notify API response is configured to return an error 
+    When a mock notify API response is configured to return a 403 error 
     When the broadcast method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
@@ -32,8 +32,29 @@ Feature: Can the adapter broadcast messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock notify API response is configured to return an error 
+    When a mock notify API response is configured to return a 403 error 
     When the broadcast method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
     Then the broadcast method is not called again
+
+  Scenario: On 503 the message is retried once with the same credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock notify API response is configured to return a 503 error 
+    When the broadcast method is called 
+    Then an error response is returned with status 503 
+    Then the credentials are not deleted
+    Then the broadcast method was called with is_retry on
+    Then the getAuthorizationHeader method is not called again 
+    
+  Scenario: On a retried 503 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock notify API response is configured to return a 503 error 
+    When the broadcast method is called with is_retry on
+    Then an error response is returned with status 503
+    Then the credentials are not deleted 
+    Then the broadcast method is not called again
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index 348266a..4e7116e 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -37,7 +37,7 @@ Feature: Can the adapter receive messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock receive API response is configured to return an error
+    When a mock receive API response is configured to return a 403 error
     When the poll method is called 
     Then an error response is returned with status 403
 
@@ -45,7 +45,7 @@ Feature: Can the adapter receive messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock receive API response is configured to return an error 
+    When a mock receive API response is configured to return a 403 error 
     When the poll method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
@@ -56,8 +56,30 @@ Feature: Can the adapter receive messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock receive API response is configured to return an error 
+    When a mock receive API response is configured to return a 403 error 
     When the poll method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
     Then the poll method is not called again
+
+  Scenario: On 503 the message is retried once with the same credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock receive API response is configured to return a 503 error 
+    When the poll method is called 
+    Then an error response is returned with status 503 
+    Then the credentials are not deleted
+    Then the poll method was called with is_retry on
+    Then the getAuthorizationHeader method is not called again 
+    
+  Scenario: On a retried 503 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock receive API response is configured to return a 503 error 
+    When the poll method is called with is_retry on
+    Then an error response is returned with status 503
+    Then the credentials are not deleted 
+    Then the poll method is not called again
+  
\ No newline at end of file
diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index 0ff7806..10e4f5d 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -13,7 +13,7 @@ Feature: Can the adapter publish messages?
     Given valid config
     When the adapter instance is created
     When the auth method is called
-    When a mock send API response is configured to return an error
+    When a mock send API response is configured to return a 403 error
     When the publish method is called
     Then an error response is returned with status 403
 
@@ -21,7 +21,7 @@ Feature: Can the adapter publish messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock send API response is configured to return an error 
+    When a mock send API response is configured to return a 403 error 
     When the publish method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
@@ -32,8 +32,29 @@ Feature: Can the adapter publish messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock send API response is configured to return an error 
+    When a mock send API response is configured to return a 403 error 
     When the publish method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
     Then the publish method is not called again
+  
+  Scenario: On 503 the message is retried once with new credentials 
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock send API response is configured to return a 503 error 
+    When the publish method is called 
+    Then an error response is returned with status 503 
+    Then the credentials are not deleted
+    Then the publish method was called with is_retry on
+    Then the getAuthorizationHeader method is not called again 
+    
+  Scenario: On a retried 503 the message is not retried again
+    Given valid config 
+    When the adapter instance is created 
+    When the auth method is called 
+    When a mock send API response is configured to return a 503 error 
+    When the publish method is called with is_retry on
+    Then an error response is returned with status 503
+    Then the credentials are not deleted 
+    Then the publish method is not called again
-- 
GitLab


From a89f9bf6d1f28856b1536af02ac3a11c92ec9e22 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Mon, 20 Feb 2023 16:32:19 +0000
Subject: [PATCH 24/33] refactor: use parameters for not called again test

---
 features/adapter_broadcast.feature | 6 +++---
 features/adapter_poll.feature      | 6 +++---
 features/adapter_publish.feature   | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
index 7d3e02d..8063a2a 100644
--- a/features/adapter_broadcast.feature
+++ b/features/adapter_broadcast.feature
@@ -36,7 +36,7 @@ Feature: Can the adapter broadcast messages?
     When the broadcast method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the broadcast method is not called again
+    Then the "broadcast" method is not called again
 
   Scenario: On 503 the message is retried once with the same credentials 
     Given valid config 
@@ -47,7 +47,7 @@ Feature: Can the adapter broadcast messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the broadcast method was called with is_retry on
-    Then the getAuthorizationHeader method is not called again 
+    Then the "getAuthorizationHeader" method is not called again 
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -57,4 +57,4 @@ Feature: Can the adapter broadcast messages?
     When the broadcast method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the broadcast method is not called again
+    Then the "broadcast" method is not called again
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index 4e7116e..115d04b 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -60,7 +60,7 @@ Feature: Can the adapter receive messages?
     When the poll method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the poll method is not called again
+    Then the "poll" method is not called again
 
   Scenario: On 503 the message is retried once with the same credentials 
     Given valid config 
@@ -71,7 +71,7 @@ Feature: Can the adapter receive messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the poll method was called with is_retry on
-    Then the getAuthorizationHeader method is not called again 
+    Then the "getAuthorizationHeader" method is not called again 
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -81,5 +81,5 @@ Feature: Can the adapter receive messages?
     When the poll method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the poll method is not called again
+    Then the "poll" method is not called again
   
\ No newline at end of file
diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index 10e4f5d..cd17cb5 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -36,7 +36,7 @@ Feature: Can the adapter publish messages?
     When the publish method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the publish method is not called again
+    Then the "publish" method is not called again
   
   Scenario: On 503 the message is retried once with new credentials 
     Given valid config 
@@ -47,7 +47,7 @@ Feature: Can the adapter publish messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the publish method was called with is_retry on
-    Then the getAuthorizationHeader method is not called again 
+    Then the "getAuthorizationHeader" method is not called again 
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -57,4 +57,4 @@ Feature: Can the adapter publish messages?
     When the publish method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the publish method is not called again
+    Then the "publish" method is not called again
-- 
GitLab


From f00902eaf7ab6b2e3a7870b45e94ebd18bc45888 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Tue, 21 Feb 2023 08:46:44 +0000
Subject: [PATCH 25/33] refactor: change how call counts are expected

---
 features/adapter_broadcast.feature | 14 ++++++++------
 features/adapter_poll.feature      | 12 +++++++-----
 features/adapter_publish.feature   | 13 ++++++++-----
 3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
index 8063a2a..5672212 100644
--- a/features/adapter_broadcast.feature
+++ b/features/adapter_broadcast.feature
@@ -21,12 +21,13 @@ Feature: Can the adapter broadcast messages?
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
-    When a mock notify API response is configured to return a 403 error 
+    When a mock notify API response is configured to return a 403 error
     When the broadcast method is called 
     Then an error response is returned with status 403 
     Then the credentials are deleted
     Then the broadcast method was called with is_retry on
-    Then the getAuthorizationHeader method is called 
+    Then the total number of calls to "broadcast" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 2
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -36,8 +37,8 @@ Feature: Can the adapter broadcast messages?
     When the broadcast method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the "broadcast" method is not called again
-
+    Then the total number of calls to "broadcast" was 1
+    
   Scenario: On 503 the message is retried once with the same credentials 
     Given valid config 
     When the adapter instance is created 
@@ -47,7 +48,8 @@ Feature: Can the adapter broadcast messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the broadcast method was called with is_retry on
-    Then the "getAuthorizationHeader" method is not called again 
+    Then the total number of calls to "broadcast" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 1
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -57,4 +59,4 @@ Feature: Can the adapter broadcast messages?
     When the broadcast method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the "broadcast" method is not called again
+    Then the total number of calls to "broadcast" was 1
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index 115d04b..bef9538 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -50,7 +50,8 @@ Feature: Can the adapter receive messages?
     Then an error response is returned with status 403 
     Then the credentials are deleted
     Then the poll method was called with is_retry on
-    Then the getAuthorizationHeader method is called 
+    Then the total number of calls to "poll" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 1
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -60,8 +61,8 @@ Feature: Can the adapter receive messages?
     When the poll method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the "poll" method is not called again
-
+    Then the total number of calls to "poll" was 1
+  
   Scenario: On 503 the message is retried once with the same credentials 
     Given valid config 
     When the adapter instance is created 
@@ -71,7 +72,8 @@ Feature: Can the adapter receive messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the poll method was called with is_retry on
-    Then the "getAuthorizationHeader" method is not called again 
+    Then the total number of calls to "poll" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 1
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -81,5 +83,5 @@ Feature: Can the adapter receive messages?
     When the poll method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the "poll" method is not called again
+    Then the total number of calls to "poll" was 1
   
\ No newline at end of file
diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index cd17cb5..6675b4e 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -26,7 +26,8 @@ Feature: Can the adapter publish messages?
     Then an error response is returned with status 403 
     Then the credentials are deleted
     Then the publish method was called with is_retry on
-    Then the getAuthorizationHeader method is called 
+    Then the total number of calls to "publish" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 2  
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -36,9 +37,9 @@ Feature: Can the adapter publish messages?
     When the publish method is called with is_retry on
     Then an error response is returned with status 403
     Then the credentials are deleted 
-    Then the "publish" method is not called again
+    Then the total number of calls to "publish" was 1
   
-  Scenario: On 503 the message is retried once with new credentials 
+  Scenario: On 503 the message is retried once with the same credentials 
     Given valid config 
     When the adapter instance is created 
     When the auth method is called 
@@ -47,7 +48,8 @@ Feature: Can the adapter publish messages?
     Then an error response is returned with status 503 
     Then the credentials are not deleted
     Then the publish method was called with is_retry on
-    Then the "getAuthorizationHeader" method is not called again 
+    Then the total number of calls to "publish" was 2
+    Then the total number of calls to "getAuthorizationHeader" was 1
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
@@ -57,4 +59,5 @@ Feature: Can the adapter publish messages?
     When the publish method is called with is_retry on
     Then an error response is returned with status 503
     Then the credentials are not deleted 
-    Then the "publish" method is not called again
+    Then the total number of calls to "publish" was 1
+  
\ No newline at end of file
-- 
GitLab


From 1fd8622a217eda84f05c91a9a7181d5cfad0aace Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Tue, 21 Feb 2023 09:05:25 +0000
Subject: [PATCH 26/33] fix: count api calls to /token

getAuthorizationHeader is called again but only
requests a new token if a valid one is not available
---
 features/adapter_broadcast.feature | 4 ++--
 features/adapter_poll.feature      | 6 +++---
 features/adapter_publish.feature   | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/features/adapter_broadcast.feature b/features/adapter_broadcast.feature
index 5672212..9440f93 100644
--- a/features/adapter_broadcast.feature
+++ b/features/adapter_broadcast.feature
@@ -27,7 +27,7 @@ Feature: Can the adapter broadcast messages?
     Then the credentials are deleted
     Then the broadcast method was called with is_retry on
     Then the total number of calls to "broadcast" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 2
+    Then the total number of "GET" requests to "/token" was 2
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -49,7 +49,7 @@ Feature: Can the adapter broadcast messages?
     Then the credentials are not deleted
     Then the broadcast method was called with is_retry on
     Then the total number of calls to "broadcast" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 1
+    Then the total number of "GET" requests to "/token" was 1
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
diff --git a/features/adapter_poll.feature b/features/adapter_poll.feature
index bef9538..a30ea04 100644
--- a/features/adapter_poll.feature
+++ b/features/adapter_poll.feature
@@ -51,7 +51,7 @@ Feature: Can the adapter receive messages?
     Then the credentials are deleted
     Then the poll method was called with is_retry on
     Then the total number of calls to "poll" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 1
+    Then the total number of "GET" requests to "/token" was 2
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -73,8 +73,8 @@ Feature: Can the adapter receive messages?
     Then the credentials are not deleted
     Then the poll method was called with is_retry on
     Then the total number of calls to "poll" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 1
-    
+    Then the total number of "GET" requests to "/token" was 1
+  
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
     When the adapter instance is created 
diff --git a/features/adapter_publish.feature b/features/adapter_publish.feature
index 6675b4e..5e626bf 100644
--- a/features/adapter_publish.feature
+++ b/features/adapter_publish.feature
@@ -27,7 +27,7 @@ Feature: Can the adapter publish messages?
     Then the credentials are deleted
     Then the publish method was called with is_retry on
     Then the total number of calls to "publish" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 2  
+    Then the total number of "GET" requests to "/token" was 2
     
   Scenario: On a retried 403 the message is not retried again
     Given valid config 
@@ -49,7 +49,7 @@ Feature: Can the adapter publish messages?
     Then the credentials are not deleted
     Then the publish method was called with is_retry on
     Then the total number of calls to "publish" was 2
-    Then the total number of calls to "getAuthorizationHeader" was 1
+    Then the total number of "GET" requests to "/token" was 1
     
   Scenario: On a retried 503 the message is not retried again
     Given valid config 
-- 
GitLab


From 670204fec080bd3cab971e9c9870a41795ade413 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Tue, 21 Feb 2023 10:23:22 +0000
Subject: [PATCH 27/33] fix: remove old fixtures/features before copy

copytree fails if destination already exists
---
 copy_tests.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/copy_tests.py b/copy_tests.py
index 631c831..f6c33a4 100644
--- a/copy_tests.py
+++ b/copy_tests.py
@@ -1,9 +1,10 @@
 import os
-from shutil import copytree
+from shutil import copytree, rmtree
 import site 
 
 
 def copy_directory(src, dest, directory):
+    rmtree(os.path.join(dest, directory))
     copytree(os.path.join(src, directory), os.path.join(dest, directory))
 
 
-- 
GitLab


From 09029c5981b898548841992b6f56a091c54ab5af Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Tue, 21 Feb 2023 17:02:38 +0000
Subject: [PATCH 28/33] fix: use unresolvable domain for tests

backbone.com is a real domain owned by someone else
Protect against accidentally sending requests to their
domain if the API mockers are not working.
---
 fixtures/config-invalid.json | 2 +-
 fixtures/config-valid.json   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fixtures/config-invalid.json b/fixtures/config-invalid.json
index 82625f6..6085b87 100644
--- a/fixtures/config-invalid.json
+++ b/fixtures/config-invalid.json
@@ -1,5 +1,5 @@
 {
-  "api": "https://example.backbone.com/api",
+  "api": "https://example.backbone.fake/api",
   "client_id": "invalid-client-id",
   "client_name": "InvalidClientName",
   "subscription": "dot.delimited.topic.subscription.#",
diff --git a/fixtures/config-valid.json b/fixtures/config-valid.json
index 8b765ec..ba57073 100644
--- a/fixtures/config-valid.json
+++ b/fixtures/config-valid.json
@@ -1,5 +1,5 @@
 {
-  "api": "https://example.backbone.com/api",
+  "api": "https://example.backbone.fake/api",
   "client_id": "unique-client-id",
   "client_name": "UniqueClientName",
   "subscription": "dot.delimited.topic.subscription.#",
-- 
GitLab


From f774bd168f5174a5e97e09ce7f809ce72e0444f4 Mon Sep 17 00:00:00 2001
From: James Kirk <james.kirk@noc.ac.uk>
Date: Thu, 23 Mar 2023 17:19:53 +0000
Subject: [PATCH 29/33] refactor: gitlabbing up, only to run tag_git

---
 .gitlab-ci.yml | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..c9f05ac
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,10 @@
+include:
+  - project: communications-backbone-system/backbone-infrastructure-config
+    ref: master
+    file: gitlab/all.yml
+
+variables:
+  CI_SKIP_DOCKER_TAG: 1
+  CI_SKIP_BUILD: 1
+  CI_SKIP_LINT: 1
+  CI_SKIP_TEST: 1
\ No newline at end of file
-- 
GitLab


From 710fe5b0f975149a5408510bda346e70c6dc940a Mon Sep 17 00:00:00 2001
From: James Kirk <james.kirk@noc.ac.uk>
Date: Thu, 23 Mar 2023 17:22:05 +0000
Subject: [PATCH 30/33] refactor: typo

---
 .gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c9f05ac..bd48c3c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,4 +7,4 @@ variables:
   CI_SKIP_DOCKER_TAG: 1
   CI_SKIP_BUILD: 1
   CI_SKIP_LINT: 1
-  CI_SKIP_TEST: 1
\ No newline at end of file
+  CI_SKIP_TESTS: 1
\ No newline at end of file
-- 
GitLab


From a020d166e8f36f4ca62d34f323328476ef36da96 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 24 Mar 2023 11:11:26 +0000
Subject: [PATCH 31/33] release: v0.1

Add changelog
Update version in package.json and setup.py
Update org name in licence
---
 CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++
 LICENCE.md   |  2 +-
 package.json |  2 +-
 setup.py     |  1 +
 yarn.lock    |  4 ++++
 5 files changed, 42 insertions(+), 2 deletions(-)
 create mode 100644 CHANGELOG.md
 create mode 100644 yarn.lock

diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..594c6fe
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,35 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [v0.1] - 2023-03-24
+
+### Added
+
+Tests and associated fixtures 
+
+Added tests for schema 
+- mock schema is valid
+
+Added tests for adapter 
+- auth 
+- getAuthorizationHeader
+- broadcast
+- poll
+- publish
+- tokenValid
+- validate (message delegated to protocol)
+
+Added tests for protocol 
+- decode 
+- encode 
+- getType
+- validate (message) 
+
+[v0.1]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/72413c71...v0.1
+[unreleased]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/v0.1...dev
\ No newline at end of file
diff --git a/LICENCE.md b/LICENCE.md
index 10bb2c1..7f45c48 100644
--- a/LICENCE.md
+++ b/LICENCE.md
@@ -1,4 +1,4 @@
-Copyright 2023 [NOC](https://noc.ac.uk)
+Copyright 2023 [National Oceanography Centre](https://noc.ac.uk)
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 
diff --git a/package.json b/package.json
index 6cc5121..6945ecf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "backbone-adapter-testsuite",
-  "version": "0.0.1",
+  "version": "0.1",
   "description": "Common test suite to run on all adapter language ports",
   "repository": {
     "type": "git",
diff --git a/setup.py b/setup.py
index b025934..7998415 100644
--- a/setup.py
+++ b/setup.py
@@ -2,6 +2,7 @@ from setuptools import setup
 
 
 setup(
+    version='0.1',
     name='backbone_adapter_testsuite',
     packages=['testsuite'],
     package_dir={
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..fb57ccd
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
-- 
GitLab


From 1f98d67293bc7331d3e7e09342ba41a4d646deb1 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 24 Mar 2023 11:15:20 +0000
Subject: [PATCH 32/33] fix: compare urls in changelog

---
 CHANGELOG.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 594c6fe..77e2f30 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,5 +31,5 @@ Added tests for protocol
 - getType
 - validate (message) 
 
-[v0.1]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/72413c71...v0.1
-[unreleased]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/v0.1...dev
\ No newline at end of file
+[v0.1]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/72413c71..v0.1
+[unreleased]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/v0.1..dev
\ No newline at end of file
-- 
GitLab


From 1608e5cad24aef18d0683f74ad7ea00620fc7d86 Mon Sep 17 00:00:00 2001
From: Dan Jones <dan.jones@noc.ac.uk>
Date: Fri, 24 Mar 2023 11:18:07 +0000
Subject: [PATCH 33/33] fix: revert change to compare URLs

---
 CHANGELOG.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77e2f30..594c6fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,5 +31,5 @@ Added tests for protocol
 - getType
 - validate (message) 
 
-[v0.1]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/72413c71..v0.1
-[unreleased]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/v0.1..dev
\ No newline at end of file
+[v0.1]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/72413c71...v0.1
+[unreleased]: https://git.noc.ac.uk/communications-backbone-system/backbone-adapter-testsuite/compare/v0.1...dev
\ No newline at end of file
-- 
GitLab