From 924e6e37e05c01b82e2d8754645b0c88105a7ae8 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Fri, 26 Sep 2025 17:35:44 +0100 Subject: [PATCH 01/19] CCM-9352: Refactor asserions class - tidy up --- tests/lib/assertion_utils/__init__.py | 0 tests/lib/assertion_utils/common.py | 31 +++ tests/lib/assertion_utils/get_message.py | 91 +++++++ tests/lib/assertion_utils/headers.py | 53 ++++ tests/lib/assertion_utils/message_batches.py | 18 ++ tests/lib/assertion_utils/messages.py | 21 ++ tests/lib/assertion_utils/nhsapp_accounts.py | 52 ++++ tests/lib/assertions.py | 253 ++++++------------- 8 files changed, 342 insertions(+), 177 deletions(-) create mode 100644 tests/lib/assertion_utils/__init__.py create mode 100644 tests/lib/assertion_utils/common.py create mode 100644 tests/lib/assertion_utils/get_message.py create mode 100644 tests/lib/assertion_utils/headers.py create mode 100644 tests/lib/assertion_utils/message_batches.py create mode 100644 tests/lib/assertion_utils/messages.py create mode 100644 tests/lib/assertion_utils/nhsapp_accounts.py diff --git a/tests/lib/assertion_utils/__init__.py b/tests/lib/assertion_utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/lib/assertion_utils/common.py b/tests/lib/assertion_utils/common.py new file mode 100644 index 000000000..57b69af94 --- /dev/null +++ b/tests/lib/assertion_utils/common.py @@ -0,0 +1,31 @@ +def assert_message_type(resp, type): + message_type = resp.json().get("data").get("type") + assert message_type == type + + +def assert_request_id(resp): + request_id = resp.json().get("data").get("id") + assert request_id is not None + assert request_id != "" + + +def assert_routing_plan_id(resp, expected_routing_plan_id=None): + actual_routing_plan_id = resp.json().get("data").get("attributes").get("routingPlan").get("id") + assert actual_routing_plan_id is not None + if expected_routing_plan_id is not None: + assert expected_routing_plan_id == actual_routing_plan_id + + +def assert_routing_plan_version(resp): + actual_routing_plan_version = resp.json().get("data").get("attributes").get("routingPlan").get("version") + assert actual_routing_plan_version is not None + + +def assert_routing_plan_name(resp): + actual_routing_plan_name = resp.json().get("data").get("attributes").get("routingPlan").get("name") + assert actual_routing_plan_name is not None + + +def assert_routing_plan_created_date(resp): + actual_routing_plan_created_date = resp.json().get("data").get("attributes").get("routingPlan").get("createdDate") + assert actual_routing_plan_created_date is not None diff --git a/tests/lib/assertion_utils/get_message.py b/tests/lib/assertion_utils/get_message.py new file mode 100644 index 000000000..ede66d349 --- /dev/null +++ b/tests/lib/assertion_utils/get_message.py @@ -0,0 +1,91 @@ +def assert_message_status(resp, expected_status=None): + message_status = resp.json().get("data").get("attributes").get("messageStatus") + assert message_status is not None + assert message_status != "" + if expected_status is not None: + assert expected_status == message_status + + +def assert_message_reference(resp): + message_reference = resp.json().get("data").get("attributes").get("messageReference") + assert message_reference is not None + assert message_reference != "" + + +def assert_created_timestamp(resp): + created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") + assert created_timestamp is not None + assert created_timestamp != "" + + +def assert_metadata(resp): + metadata = resp.json().get("data").get("attributes").get("metadata") + assert metadata is not None + assert metadata != "" + assert metadata[0].get("queriedAt") is not None + assert metadata[0].get("queriedAt") != "" + assert metadata[0].get("source") is not None + assert metadata[0].get("source") != "" + assert metadata[0].get("version") is not None + assert metadata[0].get("version") != "" + assert metadata[0].get("labels") != "" + + +def assert_channels(resp): + channels = resp.json().get("data").get("attributes").get("channels") + assert channels is not None + assert len(channels) > 0 + for channel in channels: + assert channel.get("channelType") is not None + assert channel.get("channelType") != "" + assert channel.get("to") is not None + assert channel.get("to") != "" + assert channel.get("status") is not None + assert channel.get("status") != "" + assert channel.get("id") is not None + assert channel.get("id") != "" + assert channel.get("timestamps").get("created") is not None + + +def assert_self_link(resp, base_url): + self_link = resp.json().get("data").get("links").get("self") + request_id = resp.json().get("data").get("id") + assert self_link is not None + assert self_link != "" + assert self_link.startswith(base_url) + assert self_link.endswith(f"/v1/messages/{request_id}") + + +def assert_message_status_description(resp, expected_description): + actual_description = resp.json().get("data").get("attributes").get("messageStatusDescription") + assert actual_description is not None + assert actual_description != "" + assert expected_description == actual_description + + +def assert_failure_reason_code(resp, expected_code): + failure_reason_code = resp.json().get("data").get("attributes").get("messageFailureReasonCode") + assert failure_reason_code is not None + assert failure_reason_code != "" + assert expected_code == failure_reason_code + + +def assert_channel_status(channel, expected_status): + channel_status = channel.get("channelStatus") + assert channel_status is not None + assert channel_status != "" + assert expected_status == channel_status + + +def assert_channel_status_description(channel, expected_description): + channel_status_description = channel.get("channelStatusDescription") + assert channel_status_description is not None + assert channel_status_description != "" + assert expected_description == channel_status_description + + +def assert_channel_failure_reason_code(channel, expected_code): + channel_failure_reason_code = channel.get("channelFailureReasonCode") + assert channel_failure_reason_code is not None + assert channel_failure_reason_code != "" + assert expected_code == channel_failure_reason_code diff --git a/tests/lib/assertion_utils/headers.py b/tests/lib/assertion_utils/headers.py new file mode 100644 index 000000000..f5a1d0a98 --- /dev/null +++ b/tests/lib/assertion_utils/headers.py @@ -0,0 +1,53 @@ +def assert_x_content_type_options(resp, expected_options): + # ensure we have our x-content-type-options set correctly + content_type_options = resp.headers.get("X-Content-Type-Options") + assert content_type_options == expected_options + + +def assert_cache_control(resp, expected_cache_control): + # ensure we have our cache-control set correctly + cache_control = resp.headers.get("Cache-Control") + assert cache_control == expected_cache_control + + +def assert_access_control_allow_origin(resp, expected_origin): + # ensure we have our access-control-allow-origin set correctly + allow_origin = resp.headers.get("Access-Control-Allow-Origin") + assert allow_origin == expected_origin + + +def assert_access_control_allow_methods(resp, expected_methods): + # ensure we have our access-control-allow-methods set correctly + allow_methods = resp.headers.get("Access-Control-Allow-Methods") + assert allow_methods == expected_methods + + +def assert_access_control_max_age(resp, expected_max_age): + # ensure we have our access-control-max-age set correctly + max_age = resp.headers.get("Access-Control-Max-Age") + assert max_age == expected_max_age + + +def assert_access_control_allow_headers(resp, expected_headers): + # ensure we have our access-control-allow-headers set correctly + allow_headers = resp.headers.get("Access-Control-Allow-Headers") + assert allow_headers == expected_headers + + +def assert_access_control_expose_headers(resp, expected_expose_headers): + # ensure we have our access-control-expose-headers set correctly + expose_headers = resp.headers.get("Access-Control-Expose-Headers") + assert expose_headers == expected_expose_headers + + +def assert_access_control_resource_policy(resp, expected_policy): + # ensure we have our access-control-resource-policy set correctly + resource_policy = resp.headers.get("Cross-Origin-Resource-Policy") + assert resource_policy == expected_policy + + +def assert_no_aws_headers(resp): + # ensure we do not have any AWS headers leaking through + assert "X-Amzn-Trace-Id" not in resp.headers + assert "x-amzn-RequestId" not in resp.headers + assert "x-amz-apigw-id" not in resp.headers diff --git a/tests/lib/assertion_utils/message_batches.py b/tests/lib/assertion_utils/message_batches.py new file mode 100644 index 000000000..3c42f5395 --- /dev/null +++ b/tests/lib/assertion_utils/message_batches.py @@ -0,0 +1,18 @@ +def assert_message_batch_reference(resp, expected_message_batch_reference): + actual_message_batch_reference = resp.json().get("data").get("attributes").get("messageBatchReference") + assert actual_message_batch_reference is not None + assert expected_message_batch_reference == actual_message_batch_reference + + +def assert_messages(resp, expected_messages): + actual_messages = resp.json().get("data").get("attributes").get("messages") + assert actual_messages is not None + assert len(actual_messages) > 0 + + expected_messages = sorted(expected_messages, key=lambda x: x["messageReference"]) + actual_messages = sorted(actual_messages, key=lambda x: x["messageReference"]) + for i in range(len(actual_messages)): + assert actual_messages[i].get("messageReference") is not None + assert actual_messages[i].get("messageReference") == expected_messages[i].get("messageReference") + assert actual_messages[i].get("id") is not None + assert actual_messages[i].get("id") != "" diff --git a/tests/lib/assertion_utils/messages.py b/tests/lib/assertion_utils/messages.py new file mode 100644 index 000000000..bc9e6a3a7 --- /dev/null +++ b/tests/lib/assertion_utils/messages.py @@ -0,0 +1,21 @@ +def assert_created_timestamp(resp): + created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") + assert created_timestamp is not None + assert created_timestamp != "" + + +def assert_message_status(resp, expected_status=None): + message_status = resp.json().get("data").get("attributes").get("messageStatus") + assert message_status is not None + assert message_status != "" + if expected_status is not None: + assert expected_status == message_status + + +def assert_self_link(resp, base_url): + self_link = resp.json().get("data").get("links").get("self") + request_id = resp.json().get("data").get("id") + assert self_link is not None + assert self_link != "" + assert self_link.startswith(base_url) + assert self_link.endswith(f"/v1/messages/{request_id}") diff --git a/tests/lib/assertion_utils/nhsapp_accounts.py b/tests/lib/assertion_utils/nhsapp_accounts.py new file mode 100644 index 000000000..550ba06e9 --- /dev/null +++ b/tests/lib/assertion_utils/nhsapp_accounts.py @@ -0,0 +1,52 @@ +from urllib.parse import urlparse, parse_qs + + +def get_page_number_from_url(url: str) -> int: + """Extract the 'page' query parameter as an integer from a URL.""" + parsed = urlparse(url) + query_params = parse_qs(parsed.query) + return int(query_params["page"][0]) + + +def assert_ods_code(resp, expected_ods_code): + actual_ods_code = resp.json().get("data").get("id") + assert actual_ods_code is not None + assert actual_ods_code == expected_ods_code + + +def assert_accounts(resp): + accounts = resp.json().get("data").get("attributes").get("accounts") + assert accounts is not None + assert len(accounts) > 0 + for i in range(len(accounts)): + assert accounts[i].get("nhsNumber") is not None + assert accounts[i].get("nhsNumber") != "" + assert accounts[i].get("notificationsEnabled") is not None + + +def assert_self_link(resp, base_url, ods_code, page): + self_link = resp.json().get("links").get("self") + assert self_link.startswith(base_url) + assert self_link.endswith( + f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={page}" + ) + + +def assert_last_link(resp, base_url, ods_code, last_page_number): + last_link = resp.json().get("links").get("last") + assert last_link.startswith(base_url) + assert last_link.endswith( + f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={last_page_number}" + ) + + +def assert_next_link(resp, base_url, ods_code, self_page_number, last_page_number): + next_link = resp.json().get("links").get("next") + if self_page_number == last_page_number: + assert next_link is None + else: + next_page_number = self_page_number + 1 + assert next_link.startswith(base_url) + assert next_link.endswith( + f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={next_page_number}" + ) diff --git a/tests/lib/assertions.py b/tests/lib/assertions.py index d76cbbafd..f738c3d3e 100644 --- a/tests/lib/assertions.py +++ b/tests/lib/assertions.py @@ -1,187 +1,115 @@ +import json +from tests.lib.assertion_utils import get_message from .constants.constants import CORS_METHODS, CORS_MAX_AGE, CORS_ALLOW_HEADERS, CORS_EXPOSE_HEADERS, CORS_POLICY from .error_handler import error_handler -import json -from urllib.parse import urlparse, parse_qs +from lib.assertion_utils import common, message_batches, messages, headers, nhsapp_accounts class Assertions(): @staticmethod - def assert_201_response(resp, data): + def assert_cors_response(resp, website): error_handler.handle_retry(resp) + assert resp.status_code == 200, f"Response: {resp.status_code}: {resp.text}" - assert resp.status_code == 201, f"Response: {resp.status_code}: {resp.text}" + headers.assert_access_control_allow_origin(resp, website) + headers.assert_access_control_allow_methods(resp, CORS_METHODS) + headers.assert_access_control_max_age(resp, CORS_MAX_AGE) + headers.assert_access_control_allow_headers(resp, CORS_ALLOW_HEADERS) + headers.assert_access_control_resource_policy(resp, CORS_POLICY) - message_batch_reference = data["data"]["attributes"]["messageBatchReference"] - routing_plan_id = data["data"]["attributes"]["routingPlanId"] - messages = data["data"]["attributes"]["messages"] + @staticmethod + def assert_cors_headers(resp, website): + error_handler.handle_retry(resp) - response = resp.json().get("data") - assert response.get("type") == "MessageBatch" - assert response.get("id") is not None - assert response.get("id") != "" - assert response.get("attributes").get("messageBatchReference") is not None - assert response.get("attributes").get("messageBatchReference") == message_batch_reference - assert response.get("attributes").get("routingPlan").get("id") is not None - assert response.get("attributes").get("routingPlan").get("id") == routing_plan_id - assert response.get("attributes").get("routingPlan").get("version") is not None - assert response.get("attributes").get("routingPlan").get("name") is not None - assert response.get("attributes").get("routingPlan").get("createdDate") is not None - assert response.get("attributes").get("messages") is not None - assert len(response.get("attributes").get("messages")) > 0 - expected_messages = sorted(messages, key=lambda x: x["messageReference"]) - actual_messages = sorted(response.get("attributes").get("messages"), key=lambda x: x["messageReference"]) - for i in range(len(actual_messages)): - assert actual_messages[i].get("messageReference") is not None - assert actual_messages[i].get("messageReference") == expected_messages[i].get("messageReference") - assert actual_messages[i].get("id") is not None - assert actual_messages[i].get("id") != "" - - # ensure we have our x-content-type-options set correctly - assert resp.headers.get("X-Content-Type-Options") == "nosniff" - - # ensure we have our cache-control set correctly - assert resp.headers.get("Cache-Control") == "no-cache, no-store, must-revalidate" + headers.assert_access_control_allow_origin(resp, website) + headers.assert_access_control_expose_headers(resp, CORS_EXPOSE_HEADERS) + headers.assert_access_control_resource_policy(resp, CORS_POLICY) @staticmethod - def assert_200_response_nhsapp_accounts(resp, base_url, ods_code, page): + def assert_no_aws_headers(resp): + headers.assert_no_aws_headers(resp) + + @staticmethod + def assert_201_response(resp, data): error_handler.handle_retry(resp) + assert resp.status_code == 201, f"Response: {resp.status_code}: {resp.text}" + + common.assert_message_type(resp, "MessageBatch") + common.assert_request_id(resp) + common.assert_routing_plan_id(resp, data["data"]["attributes"]["routingPlanId"]) + common.assert_routing_plan_version(resp) + common.assert_routing_plan_name(resp) + common.assert_routing_plan_created_date(resp) + message_batches.assert_message_batch_reference(resp, data["data"]["attributes"]["messageBatchReference"]) + message_batches.assert_messages(resp, data["data"]["attributes"]["messages"]) + headers.assert_x_content_type_options(resp, "nosniff") + headers.assert_cache_control(resp, "no-cache, no-store, must-revalidate") + @staticmethod + def assert_200_response_nhsapp_accounts(resp, base_url, ods_code, page): + error_handler.handle_retry(resp) assert resp.status_code == 200, f"Response: {resp.status_code}: {resp.text}" + last_page_number = nhsapp_accounts.get_page_number_from_url(resp.json()["links"]["last"]) + self_page_number = nhsapp_accounts.get_page_number_from_url(resp.json()["links"]["self"]) - response = resp.json() - data = response.get("data") - - assert data.get("id") is not None - assert data.get("id") == ods_code - assert data.get("type") == "NhsAppAccounts" - assert data.get("attributes").get("accounts") is not None - assert len(data.get("attributes").get("accounts")) > 0 - for i in range(len(data.get("attributes").get("accounts"))): - assert data.get("attributes").get("accounts")[i].get("nhsNumber") is not None - assert data.get("attributes").get("accounts")[i].get("nhsNumber") != "" - assert data.get("attributes").get("accounts")[i].get("notificationsEnabled") is not None - assert response.get("links").get("self").startswith(base_url) - assert response.get("links").get("self") \ - .endswith(f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={page}") - - last_link = response.get("links").get("last") - parsed_last_link = urlparse(last_link) - last_link_query_params = parse_qs(parsed_last_link.query) - last_page_number = int(last_link_query_params["page"][0]) - - assert last_link.startswith(base_url) - assert response.get("links").get("last") \ - .endswith(f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={last_page_number}") - - self_link = response.get("links").get("self") - parsed_self_link = urlparse(self_link) - self_link_query_params = parse_qs(parsed_self_link.query) - self_page_number = int(self_link_query_params["page"][0]) - - if self_page_number == last_page_number: - assert response.get("links").get("next") is None - else: - next_page_number = self_page_number + 1 - assert response.get("links").get("next").startswith(base_url) - assert response.get("links").get("next") \ - .endswith(f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={next_page_number}") + common.assert_message_type(resp, "NhsAppAccounts") + nhsapp_accounts.assert_ods_code(resp, ods_code) + nhsapp_accounts.assert_accounts(resp) + nhsapp_accounts.assert_self_link(resp, base_url, ods_code, page) + nhsapp_accounts.assert_last_link(resp, base_url, ods_code, last_page_number) + nhsapp_accounts.assert_next_link(resp, base_url, ods_code, self_page_number, last_page_number) @staticmethod def assert_200_response_message(resp, base_url): error_handler.handle_retry(resp) - assert resp.status_code == 200, f"Response: {resp.status_code}: {resp.text}" - - response = resp.json().get("data") - message_status = response.get("attributes").get("messageStatus") - - assert response.get("type") == "Message" - assert response.get("id") is not None - assert response.get("id") != "" - assert response.get("attributes").get("messageStatus") is not None - assert response.get("attributes").get("messageStatus") != "" - assert response.get("attributes").get("messageReference") is not None - assert response.get("attributes").get("messageReference") != "" - assert response.get("attributes").get("routingPlan") is not None - assert response.get("attributes").get("routingPlan") != "" - assert response.get("attributes").get("routingPlan").get("id") is not None - assert response.get("attributes").get("routingPlan").get("id") != "" - assert response.get("attributes").get("routingPlan").get("version") is not None - assert response.get("attributes").get("routingPlan").get("version") != "" - assert response.get("attributes").get("routingPlan").get("name") is not None - assert response.get("attributes").get("routingPlan").get("createdDate") is not None - assert response.get("attributes").get("timestamps").get("created") - assert response.get("attributes").get("timestamps").get("created") is not None - assert response.get("attributes").get("timestamps").get("created") != "" + message_status = resp.json().get("data").get("attributes").get("messageStatus") + + common.assert_request_id(resp) + common.assert_routing_plan_id(resp) + common.assert_routing_plan_version(resp) + common.assert_routing_plan_name(resp) + common.assert_routing_plan_created_date(resp) + get_message.assert_message_status(resp) + get_message.assert_message_reference(resp) + get_message.assert_created_timestamp(resp) + get_message.assert_self_link(resp, base_url) if message_status != "pending_enrichment": - assert response.get("attributes").get("metadata") is not None - assert response.get("attributes").get("metadata") != "" - assert response.get("attributes").get("metadata")[0].get("queriedAt") is not None - assert response.get("attributes").get("metadata")[0].get("queriedAt") != "" - assert response.get("attributes").get("metadata")[0].get("source") is not None - assert response.get("attributes").get("metadata")[0].get("source") != "" - assert response.get("attributes").get("metadata")[0].get("version") is not None - assert response.get("attributes").get("metadata")[0].get("version") != "" - assert response.get("attributes").get("metadata")[0].get("labels") != "" + get_message.assert_metadata(resp) if message_status == "sending" or message_status == "delivered": - assert response.get("attributes").get("channels") is not None - assert response.get("attributes").get("channels")[0].get("type") is not None - assert response.get("attributes").get("channels")[0].get("type") != "" - assert response.get("attributes").get("channels")[0].get("retryCount") is not None - assert response.get("attributes").get("channels")[0].get("retryCount") != "" - assert response.get("attributes").get("channels")[0].get("channelStatus") is not None - assert response.get("attributes").get("channels")[0].get("channelStatus") != "" - assert response.get("attributes").get("channels")[0].get("timestamps") is not None - assert response.get("attributes").get("channels")[0].get("timestamps") != "" - assert response.get("attributes").get("channels")[0].get("routingPlan") is not None - assert response.get("attributes").get("channels")[0].get("routingPlan") != "" - assert response.get("links").get("self").startswith(base_url) - assert response.get("links").get("self").endswith(f"/v1/messages/{response.get('id')}") + get_message.assert_channels(resp) @staticmethod def assert_get_message_status(resp, status, failure_reason=None, failure_reason_code=None): - response = resp.json().get("data") - assert response.get("attributes").get("messageStatus") == status + get_message.assert_message_status(resp, status) if status == "failed": - assert response.get("attributes").get("messageStatusDescription") == failure_reason - assert response.get("attributes").get("messageFailureReasonCode") == failure_reason_code + get_message.assert_message_status_description(resp, failure_reason) + get_message.assert_failure_reason_code(resp, failure_reason_code) @staticmethod def assert_get_message_response_channels(resp, status, failure_reason=None, failure_reason_code=None): response = resp.json().get("data") channels = response.get("attributes").get("channels") - for c in range(len(channels)): - assert response.get("attributes").get("channels")[c].get("channelStatus") == status + for channel in channels: + get_message.assert_channel_status(channel, status) if status == "failed": - assert response.get("attributes").get("channels")[c].get("channelStatusDescription") == failure_reason - assert ( - response.get("attributes").get("channels")[c].get("channelFailureReasonCode") - == failure_reason_code - ) + get_message.assert_channel_status_description(channel, failure_reason) + get_message.assert_channel_failure_reason_code(channel, failure_reason_code) @staticmethod - def assert_201_response_messages(resp, environment): + def assert_201_response_messages(resp, base_url): error_handler.handle_retry(resp) - assert resp.status_code == 201, f"Response: {resp.status_code}: {resp.text}" - response = resp.json().get("data") - assert response.get("type") == "Message" - assert response.get("id") is not None - assert response.get("id") != "" - assert response.get("attributes").get("messageStatus") == "created" - assert response.get("attributes").get("timestamps").get("created") - assert response.get("attributes").get("timestamps").get("created") is not None - assert response.get("attributes").get("timestamps").get("created") != "" - assert response.get("attributes").get("routingPlan") is not None - assert response.get("attributes").get("routingPlan").get("id") != "" - assert response.get("attributes").get("routingPlan").get("version") != "" - assert response.get("attributes").get("routingPlan").get("name") is not None - assert response.get("attributes").get("routingPlan").get("createdDate") is not None - - assert response.get("links").get("self").startswith(environment) - assert response.get("links").get("self").endswith(f"/v1/messages/{response.get('id')}") - assert resp.headers.get("Location") == f"/v1/messages/{response.get('id')}" + common.assert_message_type(resp, "Message") + common.assert_request_id(resp) + common.assert_routing_plan_id(resp) + common.assert_routing_plan_version(resp) + common.assert_routing_plan_name(resp) + common.assert_routing_plan_created_date(resp) + messages.assert_message_status(resp, "created") + messages.assert_created_timestamp(resp) + messages.assert_self_link(resp, base_url) @staticmethod def assert_200_valid_message_id_response_body(resp, message_id, url): @@ -291,12 +219,8 @@ def assert_error_with_optional_correlation_id(resp, code, error, correlation_id) assert error in response_errors Assertions.assert_correlation_id(resp.headers.get("X-Correlation-Id"), correlation_id) - - # ensure we have our x-content-type-options set correctly - assert resp.headers.get("X-Content-Type-Options") == "nosniff" - - # ensure we have our cache-control set correctly - assert resp.headers.get("Cache-Control") == "no-cache, no-store, must-revalidate" + headers.assert_x_content_type_options(resp, "nosniff") + headers.assert_cache_control(resp, "no-cache, no-store, must-revalidate") @staticmethod def assert_correlation_id(res_correlation_id, correlation_id): @@ -305,28 +229,3 @@ def assert_correlation_id(res_correlation_id, correlation_id): assert res_correlation_id == correlation_id else: assert res_correlation_id.startswith('rrt') - - @staticmethod - def assert_cors_response(resp, website): - error_handler.handle_retry(resp) - - assert resp.status_code == 200, f"Response: {resp.status_code}: {resp.text}" - assert resp.headers.get("Access-Control-Allow-Origin") == website - assert resp.headers.get("Access-Control-Allow-Methods") == CORS_METHODS - assert resp.headers.get("Access-Control-Max-Age") == CORS_MAX_AGE - assert resp.headers.get("Access-Control-Allow-Headers") == CORS_ALLOW_HEADERS - assert resp.headers.get("Cross-Origin-Resource-Policy") == CORS_POLICY - - @staticmethod - def assert_cors_headers(resp, website): - error_handler.handle_retry(resp) - - assert resp.headers.get("Access-Control-Allow-Origin") == website - assert resp.headers.get("Access-Control-Expose-Headers") == CORS_EXPOSE_HEADERS - assert resp.headers.get("Cross-Origin-Resource-Policy") == CORS_POLICY - - @staticmethod - def assert_no_aws_headers(resp): - assert "X-Amzn-Trace-Id" not in resp.headers - assert "x-amzn-RequestId" not in resp.headers - assert "x-amz-apigw-id" not in resp.headers From fd70794b2042057d54b2bd2d4f929d00baf1f098 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 11:44:55 +0100 Subject: [PATCH 02/19] CCM-9353: Add additional assertions --- tests/lib/assertion_utils/common.py | 20 +++ tests/lib/assertion_utils/get_message.py | 128 +++++++++++++++---- tests/lib/assertion_utils/message_batches.py | 28 +++- tests/lib/assertion_utils/messages.py | 8 ++ tests/lib/assertion_utils/nhsapp_accounts.py | 17 +++ tests/lib/assertions.py | 10 +- tests/lib/constants/constants.py | 24 ++++ 7 files changed, 205 insertions(+), 30 deletions(-) diff --git a/tests/lib/assertion_utils/common.py b/tests/lib/assertion_utils/common.py index 57b69af94..c10da3085 100644 --- a/tests/lib/assertion_utils/common.py +++ b/tests/lib/assertion_utils/common.py @@ -1,5 +1,14 @@ +from datetime import datetime +from lib.constants.constants import MESSAGE_TYPES +import re + + def assert_message_type(resp, type): message_type = resp.json().get("data").get("type") + assert message_type is not None + assert message_type != "" + assert isinstance(message_type, str) + assert message_type in MESSAGE_TYPES assert message_type == type @@ -7,11 +16,15 @@ def assert_request_id(resp): request_id = resp.json().get("data").get("id") assert request_id is not None assert request_id != "" + assert isinstance(request_id, str) + assert re.match(r"^[a-zA-Z0-9]{27}$", request_id) def assert_routing_plan_id(resp, expected_routing_plan_id=None): actual_routing_plan_id = resp.json().get("data").get("attributes").get("routingPlan").get("id") assert actual_routing_plan_id is not None + assert actual_routing_plan_id != "" + assert isinstance(actual_routing_plan_id, str) if expected_routing_plan_id is not None: assert expected_routing_plan_id == actual_routing_plan_id @@ -19,13 +32,20 @@ def assert_routing_plan_id(resp, expected_routing_plan_id=None): def assert_routing_plan_version(resp): actual_routing_plan_version = resp.json().get("data").get("attributes").get("routingPlan").get("version") assert actual_routing_plan_version is not None + assert actual_routing_plan_version != "" + assert isinstance(actual_routing_plan_version, str) def assert_routing_plan_name(resp): actual_routing_plan_name = resp.json().get("data").get("attributes").get("routingPlan").get("name") assert actual_routing_plan_name is not None + assert isinstance(actual_routing_plan_name, str) def assert_routing_plan_created_date(resp): actual_routing_plan_created_date = resp.json().get("data").get("attributes").get("routingPlan").get("createdDate") assert actual_routing_plan_created_date is not None + assert actual_routing_plan_created_date != "" + assert isinstance(actual_routing_plan_created_date, str) + formatted_date = datetime.fromisoformat(actual_routing_plan_created_date.replace("Z", "+00:00")) + assert formatted_date is not None diff --git a/tests/lib/assertion_utils/get_message.py b/tests/lib/assertion_utils/get_message.py index ede66d349..404a27e41 100644 --- a/tests/lib/assertion_utils/get_message.py +++ b/tests/lib/assertion_utils/get_message.py @@ -1,7 +1,13 @@ +from lib.constants.constants import MESSAGE_STATUS, CHANNEL_STATUS, CHANNEL_TYPE, CASCADE_TYPE, SUPPLIER_STATUS +from datetime import datetime + + def assert_message_status(resp, expected_status=None): message_status = resp.json().get("data").get("attributes").get("messageStatus") assert message_status is not None assert message_status != "" + assert isinstance(message_status, str) + assert message_status in MESSAGE_STATUS if expected_status is not None: assert expected_status == message_status @@ -10,41 +16,43 @@ def assert_message_reference(resp): message_reference = resp.json().get("data").get("attributes").get("messageReference") assert message_reference is not None assert message_reference != "" + assert isinstance(message_reference, str) def assert_created_timestamp(resp): created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") assert created_timestamp is not None assert created_timestamp != "" + assert isinstance(created_timestamp, str) + formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) + assert formatted_date is not None def assert_metadata(resp): metadata = resp.json().get("data").get("attributes").get("metadata") assert metadata is not None assert metadata != "" - assert metadata[0].get("queriedAt") is not None - assert metadata[0].get("queriedAt") != "" - assert metadata[0].get("source") is not None - assert metadata[0].get("source") != "" - assert metadata[0].get("version") is not None - assert metadata[0].get("version") != "" - assert metadata[0].get("labels") != "" + assert isinstance(metadata, list) + assert len(metadata) > 0 + assert_metadata_queried(metadata[0].get("queriedAt")) + assert_metadata_source(metadata[0].get("source")) + assert_metadata_version(metadata[0].get("version")) + assert_metadata_labels(metadata[0].get("labels")) def assert_channels(resp): channels = resp.json().get("data").get("attributes").get("channels") assert channels is not None + assert isinstance(channels, list) assert len(channels) > 0 for channel in channels: - assert channel.get("channelType") is not None - assert channel.get("channelType") != "" - assert channel.get("to") is not None - assert channel.get("to") != "" - assert channel.get("status") is not None - assert channel.get("status") != "" - assert channel.get("id") is not None - assert channel.get("id") != "" - assert channel.get("timestamps").get("created") is not None + assert_channel_type(channel.get("channelType")) + assert_cascade_type(channel.get("cascadeType")) + assert_cascade_order(channel.get("cascadeOrder")) + assert_channel_status(channel.get("channelStatus"), None) + assert_supplier_status(channel.get("supplierStatus")) + assert_channel_created_timestamp(channel.get("timestamps").get("created")) + assert_channel_enriched_timestamp(channel.get("timestamps").get("enriched")) def assert_self_link(resp, base_url): @@ -52,6 +60,7 @@ def assert_self_link(resp, base_url): request_id = resp.json().get("data").get("id") assert self_link is not None assert self_link != "" + assert isinstance(self_link, str) assert self_link.startswith(base_url) assert self_link.endswith(f"/v1/messages/{request_id}") @@ -60,6 +69,7 @@ def assert_message_status_description(resp, expected_description): actual_description = resp.json().get("data").get("attributes").get("messageStatusDescription") assert actual_description is not None assert actual_description != "" + assert isinstance(actual_description, str) assert expected_description == actual_description @@ -67,25 +77,99 @@ def assert_failure_reason_code(resp, expected_code): failure_reason_code = resp.json().get("data").get("attributes").get("messageFailureReasonCode") assert failure_reason_code is not None assert failure_reason_code != "" + assert isinstance(failure_reason_code, str) assert expected_code == failure_reason_code -def assert_channel_status(channel, expected_status): - channel_status = channel.get("channelStatus") +def assert_channel_status(channel_status, expected_status): assert channel_status is not None assert channel_status != "" + assert isinstance(channel_status, str) + assert channel_status in CHANNEL_STATUS assert expected_status == channel_status -def assert_channel_status_description(channel, expected_description): - channel_status_description = channel.get("channelStatusDescription") +def assert_channel_status_description(channel_status_description, expected_description): assert channel_status_description is not None assert channel_status_description != "" + assert isinstance(channel_status_description, str) assert expected_description == channel_status_description -def assert_channel_failure_reason_code(channel, expected_code): - channel_failure_reason_code = channel.get("channelFailureReasonCode") +def assert_channel_failure_reason_code(channel_failure_reason_code, expected_code): assert channel_failure_reason_code is not None assert channel_failure_reason_code != "" + assert isinstance(channel_failure_reason_code, str) assert expected_code == channel_failure_reason_code + + +def assert_metadata_queried(queried_at): + assert queried_at is not None + assert queried_at != "" + assert isinstance(queried_at, str) + formatted_date = datetime.fromisoformat(queried_at.replace("Z", "+00:00")) + assert formatted_date is not None + + +def assert_metadata_source(source): + assert source is not None + assert source != "" + assert isinstance(source, str) + + +def assert_metadata_version(version): + assert version is not None + assert version != "" + assert isinstance(version, str) + + +def assert_metadata_labels(labels): + assert labels is not None + assert isinstance(labels, list) + for label in labels: + assert label is not None + assert label != "" + assert isinstance(label, str) + + +def assert_channel_type(channel_type): + assert channel_type is not None + assert channel_type != "" + assert isinstance(channel_type, str) + assert channel_type in CHANNEL_TYPE + + +def assert_cascade_type(cascade_type): + assert cascade_type is not None + assert cascade_type != "" + assert isinstance(cascade_type, str) + assert cascade_type in CASCADE_TYPE + + +def assert_cascade_order(cascade_order): + assert cascade_order is not None + assert isinstance(cascade_order, int) + assert cascade_order > 0 + + +def assert_supplier_status(supplier_status): + assert supplier_status is not None + assert supplier_status != "" + assert isinstance(supplier_status, str) + assert supplier_status in SUPPLIER_STATUS + + +def assert_channel_created_timestamp(created_timestamp): + assert created_timestamp is not None + assert created_timestamp != "" + assert isinstance(created_timestamp, str) + formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) + assert formatted_date is not None + + +def assert_channel_enriched_timestamp(enriched_timestamp): + assert enriched_timestamp is not None + assert enriched_timestamp != "" + assert isinstance(enriched_timestamp, str) + formatted_date = datetime.fromisoformat(enriched_timestamp.replace("Z", "+00:00")) + assert formatted_date is not None \ No newline at end of file diff --git a/tests/lib/assertion_utils/message_batches.py b/tests/lib/assertion_utils/message_batches.py index 3c42f5395..0407e2dc3 100644 --- a/tests/lib/assertion_utils/message_batches.py +++ b/tests/lib/assertion_utils/message_batches.py @@ -1,18 +1,36 @@ +import re + + def assert_message_batch_reference(resp, expected_message_batch_reference): actual_message_batch_reference = resp.json().get("data").get("attributes").get("messageBatchReference") assert actual_message_batch_reference is not None + assert actual_message_batch_reference != "" + assert isinstance(actual_message_batch_reference, str) assert expected_message_batch_reference == actual_message_batch_reference def assert_messages(resp, expected_messages): actual_messages = resp.json().get("data").get("attributes").get("messages") assert actual_messages is not None + assert isinstance(actual_messages, list) assert len(actual_messages) > 0 - expected_messages = sorted(expected_messages, key=lambda x: x["messageReference"]) actual_messages = sorted(actual_messages, key=lambda x: x["messageReference"]) for i in range(len(actual_messages)): - assert actual_messages[i].get("messageReference") is not None - assert actual_messages[i].get("messageReference") == expected_messages[i].get("messageReference") - assert actual_messages[i].get("id") is not None - assert actual_messages[i].get("id") != "" + assert_message_reference(actual_messages[i].get("messageReference"), expected_messages[i].get("messageReference")) + assert_message_id(actual_messages[i].get("id")) + + +def assert_message_reference(actual_message_reference, expected_message_reference=None): + assert actual_message_reference is not None + assert actual_message_reference != "" + assert isinstance(actual_message_reference, str) + if expected_message_reference is not None: + assert actual_message_reference == expected_message_reference + + +def assert_message_id(actual_message_id): + assert actual_message_id is not None + assert actual_message_id != "" + assert isinstance(actual_message_id, str) + assert re.match(r"^[a-zA-Z0-9]{27}$", actual_message_id) diff --git a/tests/lib/assertion_utils/messages.py b/tests/lib/assertion_utils/messages.py index bc9e6a3a7..2d19b47f5 100644 --- a/tests/lib/assertion_utils/messages.py +++ b/tests/lib/assertion_utils/messages.py @@ -1,13 +1,20 @@ +from datetime import datetime + + def assert_created_timestamp(resp): created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") assert created_timestamp is not None assert created_timestamp != "" + assert isinstance(created_timestamp, str) + formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) + assert formatted_date is not None def assert_message_status(resp, expected_status=None): message_status = resp.json().get("data").get("attributes").get("messageStatus") assert message_status is not None assert message_status != "" + assert isinstance(message_status, str) if expected_status is not None: assert expected_status == message_status @@ -17,5 +24,6 @@ def assert_self_link(resp, base_url): request_id = resp.json().get("data").get("id") assert self_link is not None assert self_link != "" + assert isinstance(self_link, str) assert self_link.startswith(base_url) assert self_link.endswith(f"/v1/messages/{request_id}") diff --git a/tests/lib/assertion_utils/nhsapp_accounts.py b/tests/lib/assertion_utils/nhsapp_accounts.py index 550ba06e9..7b3927ebd 100644 --- a/tests/lib/assertion_utils/nhsapp_accounts.py +++ b/tests/lib/assertion_utils/nhsapp_accounts.py @@ -11,14 +11,19 @@ def get_page_number_from_url(url: str) -> int: def assert_ods_code(resp, expected_ods_code): actual_ods_code = resp.json().get("data").get("id") assert actual_ods_code is not None + assert actual_ods_code != "" + assert isinstance(actual_ods_code, str) assert actual_ods_code == expected_ods_code def assert_accounts(resp): accounts = resp.json().get("data").get("attributes").get("accounts") assert accounts is not None + assert isinstance(accounts, list) assert len(accounts) > 0 for i in range(len(accounts)): + assert_nhs_number(accounts[i].get("nhsNumber")) + assert_notifications_enabled(accounts[i].get("notificationsEnabled")) assert accounts[i].get("nhsNumber") is not None assert accounts[i].get("nhsNumber") != "" assert accounts[i].get("notificationsEnabled") is not None @@ -50,3 +55,15 @@ def assert_next_link(resp, base_url, ods_code, self_page_number, last_page_numbe assert next_link.endswith( f"/channels/nhsapp/accounts?ods-organisation-code={ods_code}&page={next_page_number}" ) + + +def assert_nhs_number(nhs_number): + assert nhs_number is not None + assert nhs_number != "" + assert isinstance(nhs_number, str) + assert len(nhs_number) == 10 + + +def assert_notifications_enabled(notifications_enabled): + assert notifications_enabled is not None + assert isinstance(notifications_enabled, bool) diff --git a/tests/lib/assertions.py b/tests/lib/assertions.py index f738c3d3e..c5342d114 100644 --- a/tests/lib/assertions.py +++ b/tests/lib/assertions.py @@ -91,10 +91,14 @@ def assert_get_message_response_channels(resp, status, failure_reason=None, fail response = resp.json().get("data") channels = response.get("attributes").get("channels") for channel in channels: - get_message.assert_channel_status(channel, status) + get_message.assert_channel_status(channel.get("channelStatus"), status) if status == "failed": - get_message.assert_channel_status_description(channel, failure_reason) - get_message.assert_channel_failure_reason_code(channel, failure_reason_code) + get_message.assert_channel_status_description( + channel.get("channelStatusDescription"), failure_reason + ) + get_message.assert_channel_failure_reason_code( + channel.get("channelFailureReasonCode"), failure_reason_code + ) @staticmethod def assert_201_response_messages(resp, base_url): diff --git a/tests/lib/constants/constants.py b/tests/lib/constants/constants.py index 1ad914d0b..484cb86b3 100644 --- a/tests/lib/constants/constants.py +++ b/tests/lib/constants/constants.py @@ -63,6 +63,30 @@ INVALID_PERSONALISATION_VALUES = [5, "", "some-string", []] NULL_VALUES = [None] +MESSAGE_TYPES = ["MessageBatch", "Message", "NhsAppAccounts"] +MESSAGE_STATUS = ["created", "pending_enrichment", "enriched", "sending", "delivered", "failed"] +CHANNEL_STATUS = ["created", "sending", "delivered", "failed", "skipped"] +CHANNEL_TYPE = ["nhsapp", "email", "sms", "letter"] +CASCADE_TYPE = ["primary", "secondary"] +SUPPLIER_STATUS = [ + "delivered", + "read", + "notification_attempted", + "unnotified", + "rejected", + "notified", + "received", + "permanent_failure", + "temporary_failure", + "technical_failure", + "accepted", + "cancelled", + "pending_virus_check", + "validation_failed", + "unknown" +] +ROUTING_PLAN_TYPE = ["original", "override"] + class Error(): def __init__(self, code, status, title, detail, links={}): From d0ccf7d0fb2260179601708d985f4a80bf68092d Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 11:49:22 +0100 Subject: [PATCH 03/19] CCM-9353: hoy everything in an assertions directory --- tests/lib/__init__.py | 2 +- tests/lib/{assertion_utils => assertions}/__init__.py | 0 tests/lib/{ => assertions}/assertions.py | 8 ++++---- tests/lib/{assertion_utils => assertions}/common.py | 0 tests/lib/{assertion_utils => assertions}/get_message.py | 0 tests/lib/{assertion_utils => assertions}/headers.py | 0 .../{assertion_utils => assertions}/message_batches.py | 0 tests/lib/{assertion_utils => assertions}/messages.py | 0 .../{assertion_utils => assertions}/nhsapp_accounts.py | 0 9 files changed, 5 insertions(+), 5 deletions(-) rename tests/lib/{assertion_utils => assertions}/__init__.py (100%) rename tests/lib/{ => assertions}/assertions.py (97%) rename tests/lib/{assertion_utils => assertions}/common.py (100%) rename tests/lib/{assertion_utils => assertions}/get_message.py (100%) rename tests/lib/{assertion_utils => assertions}/headers.py (100%) rename tests/lib/{assertion_utils => assertions}/message_batches.py (100%) rename tests/lib/{assertion_utils => assertions}/messages.py (100%) rename tests/lib/{assertion_utils => assertions}/nhsapp_accounts.py (100%) diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index cbc87da1b..07c98be0c 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -1,4 +1,4 @@ -from .assertions import Assertions +from .assertions.assertions import Assertions from .permutations import Permutations from .generators import Generators from .authentication import AuthenticationCache diff --git a/tests/lib/assertion_utils/__init__.py b/tests/lib/assertions/__init__.py similarity index 100% rename from tests/lib/assertion_utils/__init__.py rename to tests/lib/assertions/__init__.py diff --git a/tests/lib/assertions.py b/tests/lib/assertions/assertions.py similarity index 97% rename from tests/lib/assertions.py rename to tests/lib/assertions/assertions.py index c5342d114..a29508d68 100644 --- a/tests/lib/assertions.py +++ b/tests/lib/assertions/assertions.py @@ -1,8 +1,8 @@ import json -from tests.lib.assertion_utils import get_message -from .constants.constants import CORS_METHODS, CORS_MAX_AGE, CORS_ALLOW_HEADERS, CORS_EXPOSE_HEADERS, CORS_POLICY -from .error_handler import error_handler -from lib.assertion_utils import common, message_batches, messages, headers, nhsapp_accounts +from tests.lib.assertions import get_message +from lib.constants.constants import CORS_METHODS, CORS_MAX_AGE, CORS_ALLOW_HEADERS, CORS_EXPOSE_HEADERS, CORS_POLICY +from lib.error_handler import error_handler +from lib.assertions import common, message_batches, messages, headers, nhsapp_accounts class Assertions(): diff --git a/tests/lib/assertion_utils/common.py b/tests/lib/assertions/common.py similarity index 100% rename from tests/lib/assertion_utils/common.py rename to tests/lib/assertions/common.py diff --git a/tests/lib/assertion_utils/get_message.py b/tests/lib/assertions/get_message.py similarity index 100% rename from tests/lib/assertion_utils/get_message.py rename to tests/lib/assertions/get_message.py diff --git a/tests/lib/assertion_utils/headers.py b/tests/lib/assertions/headers.py similarity index 100% rename from tests/lib/assertion_utils/headers.py rename to tests/lib/assertions/headers.py diff --git a/tests/lib/assertion_utils/message_batches.py b/tests/lib/assertions/message_batches.py similarity index 100% rename from tests/lib/assertion_utils/message_batches.py rename to tests/lib/assertions/message_batches.py diff --git a/tests/lib/assertion_utils/messages.py b/tests/lib/assertions/messages.py similarity index 100% rename from tests/lib/assertion_utils/messages.py rename to tests/lib/assertions/messages.py diff --git a/tests/lib/assertion_utils/nhsapp_accounts.py b/tests/lib/assertions/nhsapp_accounts.py similarity index 100% rename from tests/lib/assertion_utils/nhsapp_accounts.py rename to tests/lib/assertions/nhsapp_accounts.py From d2d034b0a439db669d1e84cdb1eef58184638c2f Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 13:56:29 +0100 Subject: [PATCH 04/19] CCM-9353: Fix lint issues --- tests/docs/conf.py | 4 ++++ tests/lib/assertions/get_message.py | 2 +- tests/lib/assertions/message_batches.py | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/docs/conf.py b/tests/docs/conf.py index ed486ddab..5e7733313 100644 --- a/tests/docs/conf.py +++ b/tests/docs/conf.py @@ -16,3 +16,7 @@ '.txt': 'markdown', '.md': 'markdown', } + +autodoc_mock_imports = [ + "tests" +] diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index 404a27e41..51ee66c1e 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -172,4 +172,4 @@ def assert_channel_enriched_timestamp(enriched_timestamp): assert enriched_timestamp != "" assert isinstance(enriched_timestamp, str) formatted_date = datetime.fromisoformat(enriched_timestamp.replace("Z", "+00:00")) - assert formatted_date is not None \ No newline at end of file + assert formatted_date is not None diff --git a/tests/lib/assertions/message_batches.py b/tests/lib/assertions/message_batches.py index 0407e2dc3..6a2a04d21 100644 --- a/tests/lib/assertions/message_batches.py +++ b/tests/lib/assertions/message_batches.py @@ -17,7 +17,9 @@ def assert_messages(resp, expected_messages): expected_messages = sorted(expected_messages, key=lambda x: x["messageReference"]) actual_messages = sorted(actual_messages, key=lambda x: x["messageReference"]) for i in range(len(actual_messages)): - assert_message_reference(actual_messages[i].get("messageReference"), expected_messages[i].get("messageReference")) + assert_message_reference( + actual_messages[i].get("messageReference"), expected_messages[i].get("messageReference") + ) assert_message_id(actual_messages[i].get("id")) From 7bc2f29d776b23e022794a6b1006d003ac06d8f2 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 15:29:22 +0100 Subject: [PATCH 05/19] CCM-9353: Fix broken tests --- sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json | 2 +- tests/lib/assertions/get_message.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json index 182a33feb..9d2e2fa94 100644 --- a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json +++ b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json @@ -16,7 +16,7 @@ "type": "email", "retryCount": 0, "cascadeType": "primary", - "cascadeOrder": 1, + "cascadeOrder": "1", "channelStatus": "sending", "timestamps": { "created": "2023-10-09T10:31:59Z" diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index 51ee66c1e..ae502c415 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -46,7 +46,7 @@ def assert_channels(resp): assert isinstance(channels, list) assert len(channels) > 0 for channel in channels: - assert_channel_type(channel.get("channelType")) + assert_channel_type(channel.get("type")) assert_cascade_type(channel.get("cascadeType")) assert_cascade_order(channel.get("cascadeOrder")) assert_channel_status(channel.get("channelStatus"), None) From 542ec5d9b3406b18d582ce1a0ffb6cb20dd22085 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 15:46:29 +0100 Subject: [PATCH 06/19] CCM-9353: Fix broken tests --- sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json | 2 +- tests/lib/assertions/get_message.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json index 57d589cfd..90aa2fee2 100644 --- a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json +++ b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json @@ -22,7 +22,7 @@ { "queriedAt": "2023-10-09T10:31:59Z", "source": "pds", - "version": 1, + "version": "1", "labels": [] } ] diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index ae502c415..51250a6aa 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -86,7 +86,8 @@ def assert_channel_status(channel_status, expected_status): assert channel_status != "" assert isinstance(channel_status, str) assert channel_status in CHANNEL_STATUS - assert expected_status == channel_status + if expected_status is not None: + assert expected_status == channel_status def assert_channel_status_description(channel_status_description, expected_description): From 9f9cf19fcc36d9750789daa279f2863a2c513ebd Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 16:11:18 +0100 Subject: [PATCH 07/19] CCM-9353: Fix broken tests --- tests/lib/assertions/get_message.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index 51250a6aa..b7d0d40d6 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -50,7 +50,6 @@ def assert_channels(resp): assert_cascade_type(channel.get("cascadeType")) assert_cascade_order(channel.get("cascadeOrder")) assert_channel_status(channel.get("channelStatus"), None) - assert_supplier_status(channel.get("supplierStatus")) assert_channel_created_timestamp(channel.get("timestamps").get("created")) assert_channel_enriched_timestamp(channel.get("timestamps").get("enriched")) @@ -153,13 +152,6 @@ def assert_cascade_order(cascade_order): assert cascade_order > 0 -def assert_supplier_status(supplier_status): - assert supplier_status is not None - assert supplier_status != "" - assert isinstance(supplier_status, str) - assert supplier_status in SUPPLIER_STATUS - - def assert_channel_created_timestamp(created_timestamp): assert created_timestamp is not None assert created_timestamp != "" From 7863b528b16e336861cc04a8e1fc997ad58f4537 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Mon, 29 Sep 2025 16:37:41 +0100 Subject: [PATCH 08/19] CCM-9353: Update sandbox responses --- sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json | 1 + sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json | 1 + sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json | 1 + sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json | 1 + sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json | 3 ++- sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json | 3 ++- sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json | 3 ++- sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json | 3 ++- sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 1 + sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json | 2 ++ sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json | 1 + sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json | 1 + sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json | 1 + sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json | 3 +++ 14 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json b/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json index 37351ff87..09f491a89 100644 --- a/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json +++ b/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json b/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json index 91e77ac45..a3222beb9 100644 --- a/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json +++ b/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json b/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json index a1910ab8b..8a7a3a838 100644 --- a/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json +++ b/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json b/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json index a6da3e5e6..8c10c28a3 100644 --- a/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json +++ b/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json b/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json index e2163400a..6ae6633df 100644 --- a/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json +++ b/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json @@ -19,7 +19,8 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json index 9d2e2fa94..7e2a95aef 100644 --- a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json +++ b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json @@ -19,7 +19,8 @@ "cascadeOrder": "1", "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json b/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json index 6987bbc03..ebc3c51ba 100644 --- a/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json +++ b/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json @@ -19,7 +19,8 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json b/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json index 8f6eff721..317dfa643 100644 --- a/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json +++ b/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json @@ -19,7 +19,8 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index 34c2effc2..140cdbecb 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json index a7be3a1e0..485f6f252 100644 --- a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json +++ b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json @@ -22,6 +22,7 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -38,6 +39,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T11:25:23Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json index 0a57b1ad6..892fe0163 100644 --- a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json +++ b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json @@ -56,6 +56,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json index da8d5af1c..b93d78255 100644 --- a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json +++ b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json @@ -74,6 +74,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-12T08:23:41Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json index 03d2a63c3..f66dbb015 100644 --- a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json +++ b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json b/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json index e23424ae8..efca1f1d7 100644 --- a/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json +++ b/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json @@ -21,6 +21,7 @@ "channelStatusDescription": "Message not read in specified time frame", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { @@ -37,6 +38,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { @@ -53,6 +55,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { From 82a966f3aa6f6067c824a02fb9e1ba73e98d84af Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 1 Oct 2025 17:41:00 +0100 Subject: [PATCH 09/19] CCM-9353: Update sandbox enriched timestamps --- sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json | 2 +- sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 7 +++++-- sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json | 6 ++++-- sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json | 5 ++++- sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json | 3 +++ 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json index 7e2a95aef..3b14707fa 100644 --- a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json +++ b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json @@ -16,7 +16,7 @@ "type": "email", "retryCount": 0, "cascadeType": "primary", - "cascadeOrder": "1", + "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { "created": "2023-10-09T10:31:59Z", diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index 140cdbecb..fd75de7c0 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -51,7 +51,9 @@ "cascadeOrder": 3, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z" + }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", @@ -66,7 +68,8 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json index 485f6f252..cdbab2a00 100644 --- a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json +++ b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json @@ -55,7 +55,8 @@ "cascadeOrder": 3, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", @@ -70,7 +71,8 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json index 892fe0163..8aad2ad0f 100644 --- a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json +++ b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json @@ -22,6 +22,7 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -40,6 +41,7 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z", "failed": "2023-10-09T11:25:23Z" }, "routingPlan": { @@ -72,7 +74,8 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json index b93d78255..a19b51bf1 100644 --- a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json +++ b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json @@ -22,6 +22,7 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -40,6 +41,7 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T11:25:23Z" }, "routingPlan": { @@ -58,6 +60,7 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T11:48:52Z" }, "routingPlan": { From fc599d183dac82c6569ab365a1a6bdc40fa1b468 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 1 Oct 2025 17:54:45 +0100 Subject: [PATCH 10/19] CCM-9353: Update sandbox enriched timestamps --- sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index fd75de7c0..fe2cc36d8 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -36,7 +36,9 @@ "cascadeOrder": 2, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z" + "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:39:37Z" + }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", From f84e3db5a40801e2903242e1631664b6fcae1b5f Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Thu, 2 Oct 2025 08:19:06 +0100 Subject: [PATCH 11/19] CCM-9353: Revert Enriched timestamp on created and failed channels --- sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json | 1 - sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 9 +++------ sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json | 7 ++----- sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json | 3 +-- sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json | 1 - tests/lib/assertions/get_message.py | 9 --------- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json index 073d0b13d..e803331a2 100644 --- a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json +++ b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json @@ -35,7 +35,6 @@ ], "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index fe2cc36d8..636dc52ff 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -36,8 +36,7 @@ "cascadeOrder": 2, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { @@ -53,8 +52,7 @@ "cascadeOrder": 3, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { @@ -70,8 +68,7 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json index cdbab2a00..3fe2df55c 100644 --- a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json +++ b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json @@ -22,7 +22,6 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -55,8 +54,7 @@ "cascadeOrder": 3, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", @@ -71,8 +69,7 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json index 8aad2ad0f..d3503a129 100644 --- a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json +++ b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json @@ -74,8 +74,7 @@ "cascadeOrder": 4, "channelStatus": "created", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json index a19b51bf1..27aae3634 100644 --- a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json +++ b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json @@ -22,7 +22,6 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index b7d0d40d6..e8be491b3 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -51,7 +51,6 @@ def assert_channels(resp): assert_cascade_order(channel.get("cascadeOrder")) assert_channel_status(channel.get("channelStatus"), None) assert_channel_created_timestamp(channel.get("timestamps").get("created")) - assert_channel_enriched_timestamp(channel.get("timestamps").get("enriched")) def assert_self_link(resp, base_url): @@ -158,11 +157,3 @@ def assert_channel_created_timestamp(created_timestamp): assert isinstance(created_timestamp, str) formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) assert formatted_date is not None - - -def assert_channel_enriched_timestamp(enriched_timestamp): - assert enriched_timestamp is not None - assert enriched_timestamp != "" - assert isinstance(enriched_timestamp, str) - formatted_date = datetime.fromisoformat(enriched_timestamp.replace("Z", "+00:00")) - assert formatted_date is not None From 7ca746cd9a93655bbff17050f623980d76a62f0e Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Thu, 2 Oct 2025 08:45:57 +0100 Subject: [PATCH 12/19] CCM-9353: whitespace --- sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json | 1 + sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json index e803331a2..64880ab47 100644 --- a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json +++ b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json @@ -24,6 +24,7 @@ "channelFailureReasonCode": "CFR_PDSV_0002", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index 636dc52ff..140cdbecb 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -37,7 +37,6 @@ "channelStatus": "created", "timestamps": { "created": "2023-10-09T10:31:59Z" - }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", @@ -53,7 +52,6 @@ "channelStatus": "created", "timestamps": { "created": "2023-10-09T10:31:59Z" - }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", From e32a5f706a437b5b8920a860869ca435ef1c0aa0 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Thu, 2 Oct 2025 12:02:30 +0100 Subject: [PATCH 13/19] CCM-9353: Remove channel enriched --- sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json | 1 - sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json | 1 - sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json | 1 - sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json | 1 - sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json | 3 +-- sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json | 3 +-- sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json | 3 +-- sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json | 3 +-- sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json | 1 - sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json | 1 - sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json | 1 - sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json | 1 - sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json | 1 - sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json | 1 - sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json | 1 - sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json | 1 - sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json | 3 --- sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json | 3 --- sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json | 2 -- sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json | 3 --- 20 files changed, 4 insertions(+), 31 deletions(-) diff --git a/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json b/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json index 09f491a89..37351ff87 100644 --- a/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json +++ b/sandbox/messages/2WL3qFTEFM0qMY8xjRbt1LIKCzM.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json b/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json index a3222beb9..91e77ac45 100644 --- a/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json +++ b/sandbox/messages/2WL3wwFhpZ6blJNIoh747bDEFNv.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json b/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json index 8a7a3a838..a1910ab8b 100644 --- a/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json +++ b/sandbox/messages/2WL3ydEEk37IzREoWRhuAdolFCE.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json b/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json index 8c10c28a3..a6da3e5e6 100644 --- a/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json +++ b/sandbox/messages/2WL3zxCY9e5vm2VP1ZfYMb53WPF.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json b/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json index 6ae6633df..e2163400a 100644 --- a/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json +++ b/sandbox/messages/2WL44QP7vrKxKKBZdTtUQoB2bWl.json @@ -19,8 +19,7 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json index 3b14707fa..182a33feb 100644 --- a/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json +++ b/sandbox/messages/2WL4GEeFVxXG9S57nRlefBwwKxp.json @@ -19,8 +19,7 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json b/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json index ebc3c51ba..6987bbc03 100644 --- a/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json +++ b/sandbox/messages/2WL4JXrfauCaQnSFbAujoImSKwo.json @@ -19,8 +19,7 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json b/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json index 317dfa643..8f6eff721 100644 --- a/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json +++ b/sandbox/messages/2WL4LuyNMtoGAsJQIpTxZLl8e3e.json @@ -19,8 +19,7 @@ "cascadeOrder": 1, "channelStatus": "sending", "timestamps": { - "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z" + "created": "2023-10-09T10:31:59Z" }, "routingPlan": { "id": "b838b13c-f98c-4def-93f0-515d4e4f4ee1", diff --git a/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json b/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json index 7e95f8003..d9788f5e6 100644 --- a/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json +++ b/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json @@ -15,7 +15,6 @@ "messageFailureReasonCode": "MFR_PDSV_0006", "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:40Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json b/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json index 47dab6ed4..980e2a149 100644 --- a/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json +++ b/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json @@ -15,7 +15,6 @@ "messageFailureReasonCode": "MFR_PDSV_0008", "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:45Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json b/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json index ff33d5031..0130bb480 100644 --- a/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json +++ b/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json @@ -15,7 +15,6 @@ "messageFailureReasonCode": "MFR_PDSV_0112", "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json b/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json index 04e3a74a1..ef99e3aa1 100644 --- a/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json +++ b/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json @@ -15,7 +15,6 @@ "messageFailureReasonCode": "MFR_PDSV_0110", "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json index 90aa2fee2..fc7f0e272 100644 --- a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json +++ b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json @@ -15,7 +15,6 @@ "messageFailureReasonCode": "MFR_PDSV_0001", "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json index 64880ab47..e803331a2 100644 --- a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json +++ b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json @@ -24,7 +24,6 @@ "channelFailureReasonCode": "CFR_PDSV_0002", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json index 140cdbecb..34c2effc2 100644 --- a/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json +++ b/sandbox/messages/2WL5TWl7F7PondWbZ1vctlEtOZ3.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json index 3fe2df55c..a7be3a1e0 100644 --- a/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json +++ b/sandbox/messages/2WL5eDefrbW31uw1il84WdF8ndH.json @@ -38,7 +38,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T11:25:23Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json index d3503a129..0a57b1ad6 100644 --- a/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json +++ b/sandbox/messages/2WL5eYSWGzCHlGmzNxuqVusPxDg.json @@ -22,7 +22,6 @@ "channelFailureReasonCode": "CFR_PDSV_0004", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z", "failed": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -41,7 +40,6 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z", "failed": "2023-10-09T11:25:23Z" }, "routingPlan": { @@ -58,7 +56,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:39:37Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json index 27aae3634..da8d5af1c 100644 --- a/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json +++ b/sandbox/messages/2WL5f8j4XVxUPgd3OOqXVYvVFIW.json @@ -40,7 +40,6 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T11:25:23Z" }, "routingPlan": { @@ -59,7 +58,6 @@ "channelFailureReasonCode": "CFR_SUPE_0007", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T11:48:52Z" }, "routingPlan": { @@ -76,7 +74,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-12T08:23:41Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json index f66dbb015..8cd2d567d 100644 --- a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json +++ b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -32,7 +31,6 @@ ], "timestamps": { "created": "2023-10-09T10:31:37Z", - "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "metadata": [ diff --git a/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json b/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json index efca1f1d7..e23424ae8 100644 --- a/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json +++ b/sandbox/messages/2n7C5wdJ9JSOSeCJTyd50GvtZeR.json @@ -21,7 +21,6 @@ "channelStatusDescription": "Message not read in specified time frame", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { @@ -38,7 +37,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { @@ -55,7 +53,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:51:59Z", "delivered": "2023-10-09T11:48:52Z" }, "routingPlan": { From 05cae080fa643066ed03cc73a5c8fdeda4907264 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Thu, 2 Oct 2025 12:07:45 +0100 Subject: [PATCH 14/19] CCM-9353: Remove channel enriched --- sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json | 1 + sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json | 1 + sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json | 1 + sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json | 1 + sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json | 1 + sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json | 1 + sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json | 1 + 7 files changed, 7 insertions(+) diff --git a/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json b/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json index d9788f5e6..7e95f8003 100644 --- a/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json +++ b/sandbox/messages/2WL4QcKGjNHvHFQeKgYbapZJGHK.json @@ -15,6 +15,7 @@ "messageFailureReasonCode": "MFR_PDSV_0006", "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:40Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json b/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json index 980e2a149..47dab6ed4 100644 --- a/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json +++ b/sandbox/messages/2WL4cPfBRuPKa44JxhyXYf2kr1E.json @@ -15,6 +15,7 @@ "messageFailureReasonCode": "MFR_PDSV_0008", "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:45Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json b/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json index 0130bb480..ff33d5031 100644 --- a/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json +++ b/sandbox/messages/2WL4ibGoigirgbH4yQwqbPaJXyQ.json @@ -15,6 +15,7 @@ "messageFailureReasonCode": "MFR_PDSV_0112", "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json b/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json index ef99e3aa1..04e3a74a1 100644 --- a/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json +++ b/sandbox/messages/2WL4mvx6eBva8dcIK60VEGIfcgZ.json @@ -15,6 +15,7 @@ "messageFailureReasonCode": "MFR_PDSV_0110", "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json index fc7f0e272..90aa2fee2 100644 --- a/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json +++ b/sandbox/messages/2WL4pcpmKxYYblm3PSKVEqcmEPX.json @@ -15,6 +15,7 @@ "messageFailureReasonCode": "MFR_PDSV_0001", "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json index e803331a2..64880ab47 100644 --- a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json +++ b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json @@ -24,6 +24,7 @@ "channelFailureReasonCode": "CFR_PDSV_0002", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { diff --git a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json index 8cd2d567d..45a6cea00 100644 --- a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json +++ b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json @@ -20,6 +20,7 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", + "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { From 94662837824a8f063bf1825b38a140c7acb20daa Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Thu, 2 Oct 2025 12:08:46 +0100 Subject: [PATCH 15/19] CCM-9353: Remove channel enriched --- sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json | 2 +- sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json index 64880ab47..073d0b13d 100644 --- a/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json +++ b/sandbox/messages/2WL4vHFZzInmaYwq6HRNDqTX8dH.json @@ -24,7 +24,6 @@ "channelFailureReasonCode": "CFR_PDSV_0002", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "routingPlan": { @@ -36,6 +35,7 @@ ], "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:59Z", "failed": "2023-10-09T10:31:59Z" }, "metadata": [ diff --git a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json index 45a6cea00..03d2a63c3 100644 --- a/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json +++ b/sandbox/messages/2WL5qbEa7TzSWZXU2IAOCCrLXVL.json @@ -20,7 +20,6 @@ "channelStatus": "delivered", "timestamps": { "created": "2023-10-09T10:31:59Z", - "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "routingPlan": { @@ -32,6 +31,7 @@ ], "timestamps": { "created": "2023-10-09T10:31:37Z", + "enriched": "2023-10-09T10:31:59Z", "delivered": "2023-10-09T10:52:12Z" }, "metadata": [ From 7cf19cd8ae60c67841058d12c044c63dd1023110 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 8 Oct 2025 10:08:28 +0100 Subject: [PATCH 16/19] CCM-9353: Update string int and list assertions to their own function --- tests/lib/assertions/common.py | 41 +++++++----- tests/lib/assertions/get_message.py | 86 +++++++------------------ tests/lib/assertions/message_batches.py | 17 ++--- tests/lib/assertions/messages.py | 15 ++--- tests/lib/assertions/nhsapp_accounts.py | 19 ++---- 5 files changed, 64 insertions(+), 114 deletions(-) diff --git a/tests/lib/assertions/common.py b/tests/lib/assertions/common.py index c10da3085..c79013df5 100644 --- a/tests/lib/assertions/common.py +++ b/tests/lib/assertions/common.py @@ -2,50 +2,57 @@ from lib.constants.constants import MESSAGE_TYPES import re +def assert_valid_string(string): + assert string is not None + assert string != "" + assert isinstance(string, str) + +def assert_valid_list(lst): + assert lst is not None + assert isinstance(lst, list) + for item in lst: + assert_valid_string(item) + +def assert_valid_int(integer): + assert integer is not None + assert isinstance(integer, int) + +def assert_valid_bool(value): + assert value is not None + assert isinstance(value, bool) def assert_message_type(resp, type): message_type = resp.json().get("data").get("type") - assert message_type is not None - assert message_type != "" - assert isinstance(message_type, str) + assert_valid_string(message_type) assert message_type in MESSAGE_TYPES assert message_type == type def assert_request_id(resp): request_id = resp.json().get("data").get("id") - assert request_id is not None - assert request_id != "" - assert isinstance(request_id, str) + assert_valid_string(request_id) assert re.match(r"^[a-zA-Z0-9]{27}$", request_id) def assert_routing_plan_id(resp, expected_routing_plan_id=None): actual_routing_plan_id = resp.json().get("data").get("attributes").get("routingPlan").get("id") - assert actual_routing_plan_id is not None - assert actual_routing_plan_id != "" - assert isinstance(actual_routing_plan_id, str) + assert_valid_string(actual_routing_plan_id) if expected_routing_plan_id is not None: assert expected_routing_plan_id == actual_routing_plan_id def assert_routing_plan_version(resp): actual_routing_plan_version = resp.json().get("data").get("attributes").get("routingPlan").get("version") - assert actual_routing_plan_version is not None - assert actual_routing_plan_version != "" - assert isinstance(actual_routing_plan_version, str) + assert_valid_string(actual_routing_plan_version) def assert_routing_plan_name(resp): actual_routing_plan_name = resp.json().get("data").get("attributes").get("routingPlan").get("name") - assert actual_routing_plan_name is not None - assert isinstance(actual_routing_plan_name, str) + assert_valid_string(actual_routing_plan_name) def assert_routing_plan_created_date(resp): actual_routing_plan_created_date = resp.json().get("data").get("attributes").get("routingPlan").get("createdDate") - assert actual_routing_plan_created_date is not None - assert actual_routing_plan_created_date != "" - assert isinstance(actual_routing_plan_created_date, str) + assert_valid_string(actual_routing_plan_created_date) formatted_date = datetime.fromisoformat(actual_routing_plan_created_date.replace("Z", "+00:00")) assert formatted_date is not None diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index e8be491b3..bbaaa85f6 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -1,12 +1,11 @@ -from lib.constants.constants import MESSAGE_STATUS, CHANNEL_STATUS, CHANNEL_TYPE, CASCADE_TYPE, SUPPLIER_STATUS +from lib.constants.constants import MESSAGE_STATUS, CHANNEL_STATUS, CHANNEL_TYPE, CASCADE_TYPE +from lib.assertions.common import assert_valid_string, assert_valid_list, assert_valid_int from datetime import datetime def assert_message_status(resp, expected_status=None): message_status = resp.json().get("data").get("attributes").get("messageStatus") - assert message_status is not None - assert message_status != "" - assert isinstance(message_status, str) + assert_valid_string(message_status) assert message_status in MESSAGE_STATUS if expected_status is not None: assert expected_status == message_status @@ -14,25 +13,19 @@ def assert_message_status(resp, expected_status=None): def assert_message_reference(resp): message_reference = resp.json().get("data").get("attributes").get("messageReference") - assert message_reference is not None - assert message_reference != "" - assert isinstance(message_reference, str) + assert_valid_string(message_reference) def assert_created_timestamp(resp): created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") - assert created_timestamp is not None - assert created_timestamp != "" - assert isinstance(created_timestamp, str) + assert_valid_string(created_timestamp) formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) - assert formatted_date is not None + assert isinstance(formatted_date, datetime) def assert_metadata(resp): metadata = resp.json().get("data").get("attributes").get("metadata") - assert metadata is not None - assert metadata != "" - assert isinstance(metadata, list) + assert_valid_list(metadata) assert len(metadata) > 0 assert_metadata_queried(metadata[0].get("queriedAt")) assert_metadata_source(metadata[0].get("source")) @@ -42,8 +35,7 @@ def assert_metadata(resp): def assert_channels(resp): channels = resp.json().get("data").get("attributes").get("channels") - assert channels is not None - assert isinstance(channels, list) + assert_valid_list(channels) assert len(channels) > 0 for channel in channels: assert_channel_type(channel.get("type")) @@ -56,104 +48,76 @@ def assert_channels(resp): def assert_self_link(resp, base_url): self_link = resp.json().get("data").get("links").get("self") request_id = resp.json().get("data").get("id") - assert self_link is not None - assert self_link != "" - assert isinstance(self_link, str) + assert_valid_string(self_link) assert self_link.startswith(base_url) assert self_link.endswith(f"/v1/messages/{request_id}") def assert_message_status_description(resp, expected_description): actual_description = resp.json().get("data").get("attributes").get("messageStatusDescription") - assert actual_description is not None - assert actual_description != "" - assert isinstance(actual_description, str) + assert_valid_string(actual_description) assert expected_description == actual_description def assert_failure_reason_code(resp, expected_code): failure_reason_code = resp.json().get("data").get("attributes").get("messageFailureReasonCode") - assert failure_reason_code is not None - assert failure_reason_code != "" - assert isinstance(failure_reason_code, str) + assert_valid_string(failure_reason_code) assert expected_code == failure_reason_code def assert_channel_status(channel_status, expected_status): - assert channel_status is not None - assert channel_status != "" - assert isinstance(channel_status, str) + assert_valid_string(channel_status) assert channel_status in CHANNEL_STATUS if expected_status is not None: assert expected_status == channel_status def assert_channel_status_description(channel_status_description, expected_description): - assert channel_status_description is not None - assert channel_status_description != "" - assert isinstance(channel_status_description, str) + assert_valid_string(channel_status_description) assert expected_description == channel_status_description def assert_channel_failure_reason_code(channel_failure_reason_code, expected_code): - assert channel_failure_reason_code is not None - assert channel_failure_reason_code != "" - assert isinstance(channel_failure_reason_code, str) + assert_valid_string(channel_failure_reason_code) assert expected_code == channel_failure_reason_code def assert_metadata_queried(queried_at): - assert queried_at is not None - assert queried_at != "" - assert isinstance(queried_at, str) + assert_valid_string(queried_at) formatted_date = datetime.fromisoformat(queried_at.replace("Z", "+00:00")) - assert formatted_date is not None + assert isinstance(formatted_date, datetime) def assert_metadata_source(source): - assert source is not None - assert source != "" - assert isinstance(source, str) + assert_valid_string(source) def assert_metadata_version(version): - assert version is not None - assert version != "" - assert isinstance(version, str) + assert_valid_string(version) def assert_metadata_labels(labels): - assert labels is not None - assert isinstance(labels, list) + assert_valid_list(labels) for label in labels: - assert label is not None - assert label != "" - assert isinstance(label, str) + assert_valid_string(label) def assert_channel_type(channel_type): - assert channel_type is not None - assert channel_type != "" - assert isinstance(channel_type, str) + assert_valid_string(channel_type) assert channel_type in CHANNEL_TYPE def assert_cascade_type(cascade_type): - assert cascade_type is not None - assert cascade_type != "" - assert isinstance(cascade_type, str) + assert_valid_string(cascade_type) assert cascade_type in CASCADE_TYPE def assert_cascade_order(cascade_order): - assert cascade_order is not None - assert isinstance(cascade_order, int) + assert_valid_int(cascade_order) assert cascade_order > 0 def assert_channel_created_timestamp(created_timestamp): - assert created_timestamp is not None - assert created_timestamp != "" - assert isinstance(created_timestamp, str) + assert_valid_string(created_timestamp) formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) - assert formatted_date is not None + assert isinstance(formatted_date, datetime) diff --git a/tests/lib/assertions/message_batches.py b/tests/lib/assertions/message_batches.py index 6a2a04d21..73a34ae8f 100644 --- a/tests/lib/assertions/message_batches.py +++ b/tests/lib/assertions/message_batches.py @@ -1,19 +1,16 @@ +from lib.assertions.common import assert_valid_string, assert_valid_list import re def assert_message_batch_reference(resp, expected_message_batch_reference): actual_message_batch_reference = resp.json().get("data").get("attributes").get("messageBatchReference") - assert actual_message_batch_reference is not None - assert actual_message_batch_reference != "" - assert isinstance(actual_message_batch_reference, str) + assert_valid_string(actual_message_batch_reference) assert expected_message_batch_reference == actual_message_batch_reference def assert_messages(resp, expected_messages): actual_messages = resp.json().get("data").get("attributes").get("messages") - assert actual_messages is not None - assert isinstance(actual_messages, list) - assert len(actual_messages) > 0 + assert_valid_list(actual_messages) expected_messages = sorted(expected_messages, key=lambda x: x["messageReference"]) actual_messages = sorted(actual_messages, key=lambda x: x["messageReference"]) for i in range(len(actual_messages)): @@ -24,15 +21,11 @@ def assert_messages(resp, expected_messages): def assert_message_reference(actual_message_reference, expected_message_reference=None): - assert actual_message_reference is not None - assert actual_message_reference != "" - assert isinstance(actual_message_reference, str) + assert_valid_string(actual_message_reference) if expected_message_reference is not None: assert actual_message_reference == expected_message_reference def assert_message_id(actual_message_id): - assert actual_message_id is not None - assert actual_message_id != "" - assert isinstance(actual_message_id, str) + assert_valid_string(actual_message_id) assert re.match(r"^[a-zA-Z0-9]{27}$", actual_message_id) diff --git a/tests/lib/assertions/messages.py b/tests/lib/assertions/messages.py index 2d19b47f5..d3aa9db30 100644 --- a/tests/lib/assertions/messages.py +++ b/tests/lib/assertions/messages.py @@ -1,20 +1,17 @@ from datetime import datetime +from lib.assertions.common import assert_valid_string def assert_created_timestamp(resp): created_timestamp = resp.json().get("data").get("attributes").get("timestamps").get("created") - assert created_timestamp is not None - assert created_timestamp != "" - assert isinstance(created_timestamp, str) + assert_valid_string(created_timestamp) formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) - assert formatted_date is not None + assert isinstance(formatted_date, datetime) def assert_message_status(resp, expected_status=None): message_status = resp.json().get("data").get("attributes").get("messageStatus") - assert message_status is not None - assert message_status != "" - assert isinstance(message_status, str) + assert_valid_string(message_status) if expected_status is not None: assert expected_status == message_status @@ -22,8 +19,6 @@ def assert_message_status(resp, expected_status=None): def assert_self_link(resp, base_url): self_link = resp.json().get("data").get("links").get("self") request_id = resp.json().get("data").get("id") - assert self_link is not None - assert self_link != "" - assert isinstance(self_link, str) + assert_valid_string(self_link) assert self_link.startswith(base_url) assert self_link.endswith(f"/v1/messages/{request_id}") diff --git a/tests/lib/assertions/nhsapp_accounts.py b/tests/lib/assertions/nhsapp_accounts.py index 7b3927ebd..c973e9770 100644 --- a/tests/lib/assertions/nhsapp_accounts.py +++ b/tests/lib/assertions/nhsapp_accounts.py @@ -1,3 +1,4 @@ +from lib.assertions.common import assert_valid_string, assert_valid_list, assert_valid_bool from urllib.parse import urlparse, parse_qs @@ -10,24 +11,17 @@ def get_page_number_from_url(url: str) -> int: def assert_ods_code(resp, expected_ods_code): actual_ods_code = resp.json().get("data").get("id") - assert actual_ods_code is not None - assert actual_ods_code != "" - assert isinstance(actual_ods_code, str) + assert_valid_string(actual_ods_code) assert actual_ods_code == expected_ods_code def assert_accounts(resp): accounts = resp.json().get("data").get("attributes").get("accounts") - assert accounts is not None - assert isinstance(accounts, list) + assert_valid_list(accounts) assert len(accounts) > 0 for i in range(len(accounts)): assert_nhs_number(accounts[i].get("nhsNumber")) assert_notifications_enabled(accounts[i].get("notificationsEnabled")) - assert accounts[i].get("nhsNumber") is not None - assert accounts[i].get("nhsNumber") != "" - assert accounts[i].get("notificationsEnabled") is not None - def assert_self_link(resp, base_url, ods_code, page): self_link = resp.json().get("links").get("self") @@ -58,12 +52,9 @@ def assert_next_link(resp, base_url, ods_code, self_page_number, last_page_numbe def assert_nhs_number(nhs_number): - assert nhs_number is not None - assert nhs_number != "" - assert isinstance(nhs_number, str) + assert_valid_string(nhs_number) assert len(nhs_number) == 10 def assert_notifications_enabled(notifications_enabled): - assert notifications_enabled is not None - assert isinstance(notifications_enabled, bool) + assert_valid_bool(notifications_enabled) From fbd376a237e230da33a5407a783d6aa084154bad Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 8 Oct 2025 11:17:32 +0100 Subject: [PATCH 17/19] CCM-9353: Address PR Comments --- tests/lib/assertions/assertions.py | 2 ++ tests/lib/assertions/common.py | 16 ++++++++++++++-- tests/lib/assertions/get_message.py | 7 +++++++ tests/lib/assertions/headers.py | 6 ++++++ tests/lib/assertions/nhsapp_accounts.py | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/lib/assertions/assertions.py b/tests/lib/assertions/assertions.py index a29508d68..a23d3a0ad 100644 --- a/tests/lib/assertions/assertions.py +++ b/tests/lib/assertions/assertions.py @@ -65,6 +65,7 @@ def assert_200_response_message(resp, base_url): assert resp.status_code == 200, f"Response: {resp.status_code}: {resp.text}" message_status = resp.json().get("data").get("attributes").get("messageStatus") + common.assert_message_type(resp, "Message") common.assert_request_id(resp) common.assert_routing_plan_id(resp) common.assert_routing_plan_version(resp) @@ -114,6 +115,7 @@ def assert_201_response_messages(resp, base_url): messages.assert_message_status(resp, "created") messages.assert_created_timestamp(resp) messages.assert_self_link(resp, base_url) + headers.assert_location_header(resp) @staticmethod def assert_200_valid_message_id_response_body(resp, message_id, url): diff --git a/tests/lib/assertions/common.py b/tests/lib/assertions/common.py index c79013df5..fc900da46 100644 --- a/tests/lib/assertions/common.py +++ b/tests/lib/assertions/common.py @@ -2,25 +2,35 @@ from lib.constants.constants import MESSAGE_TYPES import re + def assert_valid_string(string): assert string is not None assert string != "" assert isinstance(string, str) + def assert_valid_list(lst): assert lst is not None assert isinstance(lst, list) for item in lst: - assert_valid_string(item) + assert_valid_dict(item) + def assert_valid_int(integer): assert integer is not None assert isinstance(integer, int) + def assert_valid_bool(value): assert value is not None assert isinstance(value, bool) + +def assert_valid_dict(dct): + assert dct is not None + assert isinstance(dct, dict) + + def assert_message_type(resp, type): message_type = resp.json().get("data").get("type") assert_valid_string(message_type) @@ -48,7 +58,9 @@ def assert_routing_plan_version(resp): def assert_routing_plan_name(resp): actual_routing_plan_name = resp.json().get("data").get("attributes").get("routingPlan").get("name") - assert_valid_string(actual_routing_plan_name) + # If routing plan name is not present on the routing plan, it will return an empty string + assert actual_routing_plan_name is not None + assert isinstance(actual_routing_plan_name, str) def assert_routing_plan_created_date(resp): diff --git a/tests/lib/assertions/get_message.py b/tests/lib/assertions/get_message.py index bbaaa85f6..c57974a4f 100644 --- a/tests/lib/assertions/get_message.py +++ b/tests/lib/assertions/get_message.py @@ -43,6 +43,7 @@ def assert_channels(resp): assert_cascade_order(channel.get("cascadeOrder")) assert_channel_status(channel.get("channelStatus"), None) assert_channel_created_timestamp(channel.get("timestamps").get("created")) + assert_routing_plan(channel.get("routingPlan")) def assert_self_link(resp, base_url): @@ -121,3 +122,9 @@ def assert_channel_created_timestamp(created_timestamp): assert_valid_string(created_timestamp) formatted_date = datetime.fromisoformat(created_timestamp.replace("Z", "+00:00")) assert isinstance(formatted_date, datetime) + + +def assert_routing_plan(routing_plan): + assert_valid_string(routing_plan.get("id")) + assert_valid_string(routing_plan.get("type")) + assert_valid_string(routing_plan.get("version")) diff --git a/tests/lib/assertions/headers.py b/tests/lib/assertions/headers.py index f5a1d0a98..0593b4caf 100644 --- a/tests/lib/assertions/headers.py +++ b/tests/lib/assertions/headers.py @@ -51,3 +51,9 @@ def assert_no_aws_headers(resp): assert "X-Amzn-Trace-Id" not in resp.headers assert "x-amzn-RequestId" not in resp.headers assert "x-amz-apigw-id" not in resp.headers + + +def assert_location_header(resp): + location_header = resp.headers.get("Location") + expected_value = f"/v1/messages/{resp.json().get('data').get('id')}" + assert location_header == expected_value diff --git a/tests/lib/assertions/nhsapp_accounts.py b/tests/lib/assertions/nhsapp_accounts.py index c973e9770..1ab829616 100644 --- a/tests/lib/assertions/nhsapp_accounts.py +++ b/tests/lib/assertions/nhsapp_accounts.py @@ -23,6 +23,7 @@ def assert_accounts(resp): assert_nhs_number(accounts[i].get("nhsNumber")) assert_notifications_enabled(accounts[i].get("notificationsEnabled")) + def assert_self_link(resp, base_url, ods_code, page): self_link = resp.json().get("links").get("self") assert self_link.startswith(base_url) From af4b5a3358e5b7f45b33c719af1f861a8f91e2aa Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 8 Oct 2025 11:39:28 +0100 Subject: [PATCH 18/19] CCM-9353: Address PR Comments --- .tool-versions | 1 + tests/lib/assertions/common.py | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.tool-versions b/.tool-versions index 8cafcf64f..ed7d3c996 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,4 @@ python 3.11.8 poetry 1.5.0 jq 1.6 +nodejs 24.8.0 diff --git a/tests/lib/assertions/common.py b/tests/lib/assertions/common.py index fc900da46..82bb1c653 100644 --- a/tests/lib/assertions/common.py +++ b/tests/lib/assertions/common.py @@ -12,8 +12,6 @@ def assert_valid_string(string): def assert_valid_list(lst): assert lst is not None assert isinstance(lst, list) - for item in lst: - assert_valid_dict(item) def assert_valid_int(integer): @@ -26,11 +24,6 @@ def assert_valid_bool(value): assert isinstance(value, bool) -def assert_valid_dict(dct): - assert dct is not None - assert isinstance(dct, dict) - - def assert_message_type(resp, type): message_type = resp.json().get("data").get("type") assert_valid_string(message_type) From b2f160533896c8a2058c5cb0bb561e22dfb3a3c3 Mon Sep 17 00:00:00 2001 From: "rachel.kennedy13" Date: Wed, 8 Oct 2025 15:00:19 +0100 Subject: [PATCH 19/19] CCM-9353: Remove nodejs from toolversions --- .tool-versions | 1 - 1 file changed, 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index ed7d3c996..8cafcf64f 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,3 @@ python 3.11.8 poetry 1.5.0 jq 1.6 -nodejs 24.8.0