From 65911044fd840424223091491c8057206f9fbfeb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 07:36:55 -0700 Subject: [PATCH 01/26] lazy initialize zendesk_client --- app/__init__.py | 19 +++++++++++++++++-- app/celery/scheduled_tasks.py | 4 +++- setup.cfg | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 7704e73750..2361199c2b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -99,7 +99,7 @@ def apply_driver_hacks(self, app, info, options): aws_cloudwatch_client = AwsCloudwatchClient() aws_pinpoint_client = AwsPinpointClient() encryption = Encryption() -zendesk_client = ZendeskClient() +zendesk_client = None redis_store = RedisClient() document_download_client = DocumentDownloadClient() @@ -118,6 +118,16 @@ def apply_driver_hacks(self, app, info, options): authenticated_service = LocalProxy(lambda: g.authenticated_service) +def get_zendesk_client(): + global zendesk_client + # Our unit tests mock anyway + if os.environ.get("NOTIFY_ENVIRONMENT") == "test": + return None + if zendesk_client is None: + raise RuntimeError(f"Celery not initialized zendesk_client: {zendesk_client}") + return zendesk_client + + def create_app(application): from app.config import configs @@ -136,7 +146,6 @@ def create_app(application): request_helper.init_app(application) db.init_app(application) migrate.init_app(application, db=db) - zendesk_client.init_app(application) logging.init_app(application) aws_sns_client.init_app(application) @@ -144,6 +153,12 @@ def create_app(application): aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) aws_cloudwatch_client.init_app(application) aws_pinpoint_client.init_app(application) + + # start lazy initialization for gevent + zendesk_client = ZendeskClient() + zendesk_client.init_app(application) + # end lazy initialization + # If a stub url is provided for SES, then use the stub client rather than the real SES boto client email_clients = ( [aws_ses_stub_client] diff --git a/app/celery/scheduled_tasks.py b/app/celery/scheduled_tasks.py index 05d4f72a76..a8a097030a 100644 --- a/app/celery/scheduled_tasks.py +++ b/app/celery/scheduled_tasks.py @@ -5,7 +5,7 @@ from sqlalchemy import between, select, union from sqlalchemy.exc import SQLAlchemyError -from app import db, notify_celery, redis_store, zendesk_client +from app import db, get_zendesk_client, notify_celery, redis_store from app.celery.tasks import ( get_recipient_csv_and_template_and_sender_id, process_incomplete_jobs, @@ -44,6 +44,8 @@ MAX_NOTIFICATION_FAILS = 10000 +zendesk_client = get_zendesk_client() + @notify_celery.task(name="run-scheduled-jobs") def run_scheduled_jobs(): diff --git a/setup.cfg b/setup.cfg index f6dc999cb5..c3af9dc694 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,7 +6,7 @@ xfail_strict=true exclude = venv*,__pycache__,node_modules,cache,migrations,build,sample_cap_xml_documents.py max-line-length = 120 # W504 line break after binary operator -extend_ignore=B306, W504, E203 +extend_ignore=B306, W504, E203, F824 [isort] profile = black From 829ef7c2588b344b131680f50c1a2e0818c1d922 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 08:04:09 -0700 Subject: [PATCH 02/26] use MagicMock --- tests/app/celery/test_scheduled_tasks.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/app/celery/test_scheduled_tasks.py b/tests/app/celery/test_scheduled_tasks.py index 894afa6f7e..f162541cf2 100644 --- a/tests/app/celery/test_scheduled_tasks.py +++ b/tests/app/celery/test_scheduled_tasks.py @@ -498,10 +498,9 @@ def test_check_for_services_with_high_failure_rates_or_sending_to_tv_numbers( ): mock_logger = mocker.patch("app.celery.tasks.current_app.logger.warning") mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__") - mock_send_ticket_to_zendesk = mocker.patch( - "app.celery.scheduled_tasks.zendesk_client.send_ticket_to_zendesk", - autospec=True, - ) + mock_zendesk_client = MagicMock() + mocker.patch("app.celery.scheduled_tasks.zendesk_client", mock_zendesk_client) + mock_send_ticket_to_zendesk = mock_zendesk_client.send_ticket_to_zendesk mock_failure_rates = mocker.patch( "app.celery.scheduled_tasks.dao_find_services_with_high_failure_rates", return_value=failure_rates, From 6c72c466a467a37e140f706ed411f1f30ab2378d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 08:18:12 -0700 Subject: [PATCH 03/26] lazy initialize document_download_client --- app/__init__.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 2361199c2b..f4db8d6bac 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -31,7 +31,6 @@ from app.clients.document_download import DocumentDownloadClient from app.clients.email.aws_ses import AwsSesClient from app.clients.email.aws_ses_stub import AwsSesStubClient -from app.clients.pinpoint.aws_pinpoint import AwsPinpointClient from app.clients.sms.aws_sns import AwsSnsClient from notifications_utils import logging, request_helper from notifications_utils.clients.encryption.encryption_client import Encryption @@ -97,11 +96,10 @@ def apply_driver_hacks(self, app, info, options): aws_ses_stub_client = AwsSesStubClient() aws_sns_client = AwsSnsClient() aws_cloudwatch_client = AwsCloudwatchClient() -aws_pinpoint_client = AwsPinpointClient() encryption = Encryption() zendesk_client = None redis_store = RedisClient() -document_download_client = DocumentDownloadClient() +document_download_client = None socketio = SocketIO( cors_allowed_origins=[ @@ -128,6 +126,18 @@ def get_zendesk_client(): return zendesk_client +def get_document_download_client(): + global document_download_client + # Our unit tests mock anyway + if os.environ.get("NOTIFY_ENVIRONMENT") == "test": + return None + if document_download_client is None: + raise RuntimeError( + f"Celery not initialized document_download_client: {document_download_client}" + ) + return document_download_client + + def create_app(application): from app.config import configs @@ -152,11 +162,13 @@ def create_app(application): aws_ses_client.init_app() aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) aws_cloudwatch_client.init_app(application) - aws_pinpoint_client.init_app(application) # start lazy initialization for gevent zendesk_client = ZendeskClient() zendesk_client.init_app(application) + document_download_client = DocumentDownloadClient() + document_download_client.init_app(application) + # end lazy initialization # If a stub url is provided for SES, then use the stub client rather than the real SES boto client From b9ad22584811f07c1bf36f921042cd6c1c58758f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 09:19:05 -0700 Subject: [PATCH 04/26] lazy init migrate --- app/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index f4db8d6bac..6aa1589539 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -90,10 +90,10 @@ def apply_driver_hacks(self, app, info, options): "pool_pre_ping": True, } ) -migrate = Migrate() +migrate = None notify_celery = NotifyCelery() aws_ses_client = AwsSesClient() -aws_ses_stub_client = AwsSesStubClient() +aws_ses_stub_client = None aws_sns_client = AwsSnsClient() aws_cloudwatch_client = AwsCloudwatchClient() encryption = Encryption() @@ -155,20 +155,23 @@ def create_app(application): register_socket_handlers(socketio) request_helper.init_app(application) db.init_app(application) - migrate.init_app(application, db=db) logging.init_app(application) aws_sns_client.init_app(application) aws_ses_client.init_app() - aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) aws_cloudwatch_client.init_app(application) # start lazy initialization for gevent + migrate = Migrate() + migrate.init_app(application, db=db) zendesk_client = ZendeskClient() zendesk_client.init_app(application) document_download_client = DocumentDownloadClient() document_download_client.init_app(application) + aws_ses_stub_client = AwsSesStubClient() + aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) + # end lazy initialization # If a stub url is provided for SES, then use the stub client rather than the real SES boto client @@ -184,7 +187,6 @@ def create_app(application): notify_celery.init_app(application) encryption.init_app(application) redis_store.init_app(application) - document_download_client.init_app(application) register_blueprint(application) From 96b8424a4060ec5ed5876d1a6d2f7d86fed6964a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 09:38:02 -0700 Subject: [PATCH 05/26] lazy init aws_cloudwatch_client --- app/__init__.py | 6 +++--- tests/app/clients/test_aws_cloudwatch.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 6aa1589539..30770000a5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -95,7 +95,7 @@ def apply_driver_hacks(self, app, info, options): aws_ses_client = AwsSesClient() aws_ses_stub_client = None aws_sns_client = AwsSnsClient() -aws_cloudwatch_client = AwsCloudwatchClient() +aws_cloudwatch_client = None encryption = Encryption() zendesk_client = None redis_store = RedisClient() @@ -159,7 +159,6 @@ def create_app(application): aws_sns_client.init_app(application) aws_ses_client.init_app() - aws_cloudwatch_client.init_app(application) # start lazy initialization for gevent migrate = Migrate() @@ -168,7 +167,8 @@ def create_app(application): zendesk_client.init_app(application) document_download_client = DocumentDownloadClient() document_download_client.init_app(application) - + aws_cloudwatch_client = AwsCloudwatchClient() + aws_cloudwatch_client.init_app(application) aws_ses_stub_client = AwsSesStubClient() aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) diff --git a/tests/app/clients/test_aws_cloudwatch.py b/tests/app/clients/test_aws_cloudwatch.py index 15f57516e3..0f0bfadd4b 100644 --- a/tests/app/clients/test_aws_cloudwatch.py +++ b/tests/app/clients/test_aws_cloudwatch.py @@ -7,9 +7,10 @@ import pytest from flask import current_app -from app import aws_cloudwatch_client from app.clients.cloudwatch.aws_cloudwatch import AwsCloudwatchClient +aws_cloudwatch_client = MagicMock() + def test_check_sms_no_event_error_condition(notify_api, mocker): boto_mock = mocker.patch.object(aws_cloudwatch_client, "_client", create=True) From 6d9e996817a1fbb4a4c9b53dfd9a1d350811a5c0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 10:49:05 -0700 Subject: [PATCH 06/26] more mocks --- app/__init__.py | 6 ++-- tests/app/clients/test_aws_ses.py | 7 +++-- tests/app/delivery/test_send_to_providers.py | 30 ++++++++++++++------ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 30770000a5..05d86f6982 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -92,7 +92,7 @@ def apply_driver_hacks(self, app, info, options): ) migrate = None notify_celery = NotifyCelery() -aws_ses_client = AwsSesClient() +aws_ses_client = None aws_ses_stub_client = None aws_sns_client = AwsSnsClient() aws_cloudwatch_client = None @@ -158,8 +158,6 @@ def create_app(application): logging.init_app(application) aws_sns_client.init_app(application) - aws_ses_client.init_app() - # start lazy initialization for gevent migrate = Migrate() migrate.init_app(application, db=db) @@ -169,6 +167,8 @@ def create_app(application): document_download_client.init_app(application) aws_cloudwatch_client = AwsCloudwatchClient() aws_cloudwatch_client.init_app(application) + aws_ses_client = AwsSesClient() + aws_ses_client.init_app() aws_ses_stub_client = AwsSesStubClient() aws_ses_stub_client.init_app(stub_url=application.config["SES_STUB_URL"]) diff --git a/tests/app/clients/test_aws_ses.py b/tests/app/clients/test_aws_ses.py index 302fe2dd97..32cd502c0c 100644 --- a/tests/app/clients/test_aws_ses.py +++ b/tests/app/clients/test_aws_ses.py @@ -1,19 +1,22 @@ import json from unittest import mock -from unittest.mock import ANY, Mock +from unittest.mock import ANY, MagicMock, Mock import botocore import pytest -from app import AwsSesStubClient, aws_ses_client from app.clients.email import EmailClientNonRetryableException from app.clients.email.aws_ses import ( AwsSesClientException, AwsSesClientThrottlingSendRateException, get_aws_responses, ) +from app.clients.email.aws_ses_stub import AwsSesStubClient from app.enums import NotificationStatus, StatisticsType +# comes from app/__init__.py but we mock it for the tests +aws_ses_client = MagicMock() + def test_should_return_correct_details_for_delivery(): response_dict = get_aws_responses("Delivery") diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index a06d13a519..e2040d6c05 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -1,6 +1,6 @@ import json from collections import namedtuple -from unittest.mock import ANY +from unittest.mock import ANY, MagicMock import pytest from flask import current_app @@ -142,7 +142,9 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist template=sample_email_template_with_html, ) db_notification.personalisation = {"name": "Jo"} - mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_ses_client) send_to_providers.send_email_to_provider(db_notification) app.aws_ses_client.send_email.assert_called_once_with( f'"Sample service" ', @@ -176,7 +178,9 @@ def test_should_not_send_email_message_when_service_is_inactive_notifcation_is_i sample_service, sample_notification, mocker ): sample_service.active = False - send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + send_mock = mocker.patch("app.aws_ses_client", mock_ses_client) mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3") mock_s3.return_value = "2028675309" @@ -419,7 +423,8 @@ def test_send_email_to_provider_should_not_send_to_provider_when_status_is_not_c notification = create_notification( template=sample_email_template, status=NotificationStatus.SENDING ) - mocker.patch("app.aws_ses_client.send_email") + mock_ses_client = MagicMock() + mocker.patch("app.aws_ses_client", mock_ses_client) mocker.patch("app.delivery.send_to_providers.send_email_response") mocker.patch("app.delivery.send_to_providers.update_notification_message_id") @@ -438,7 +443,9 @@ def test_send_email_to_provider_should_not_send_to_provider_when_status_is_not_c def test_send_email_should_use_service_reply_to_email( sample_service, sample_email_template, mocker ): - mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_ses_client) mock_redis = mocker.patch("app.delivery.send_to_providers.redis_store") mock_redis.get.return_value = "test@example.com".encode("utf-8") @@ -819,8 +826,9 @@ def test_send_email_to_provider_uses_reply_to_from_notification( "test@example.com".encode("utf-8"), json.dumps({}).encode("utf-8"), ] - - mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_ses_client) db_notification = create_notification( template=sample_email_template, @@ -878,7 +886,9 @@ def test_send_sms_to_provider_should_use_normalised_to(mocker, client, sample_te def test_send_email_to_provider_should_user_normalised_to( mocker, client, sample_email_template ): - send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + send_mock = mocker.patch("app.aws_ses_client", mock_ses_client) notification = create_notification( template=sample_email_template, ) @@ -995,7 +1005,9 @@ def test_send_email_to_provider_should_return_template_if_found_in_redis( "app.dao.templates_dao.dao_get_template_by_id_and_service_id" ) mock_get_service = mocker.patch("app.dao.services_dao.dao_fetch_service_by_id") - send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference") + mock_ses_client = MagicMock() + mock_ses_client.send_email.return_value = "reference" + send_mock = mocker.patch("app.aws_ses_client", mock_ses_client) notification = create_notification( template=sample_email_template, ) From 346b7818be836024219b353b374e968b7c7275e3 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 11:22:16 -0700 Subject: [PATCH 07/26] fix tests --- tests/app/clients/test_aws_cloudwatch.py | 41 +++++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/tests/app/clients/test_aws_cloudwatch.py b/tests/app/clients/test_aws_cloudwatch.py index 0f0bfadd4b..4671dd56d4 100644 --- a/tests/app/clients/test_aws_cloudwatch.py +++ b/tests/app/clients/test_aws_cloudwatch.py @@ -9,11 +9,11 @@ from app.clients.cloudwatch.aws_cloudwatch import AwsCloudwatchClient -aws_cloudwatch_client = MagicMock() - def test_check_sms_no_event_error_condition(notify_api, mocker): - boto_mock = mocker.patch.object(aws_cloudwatch_client, "_client", create=True) + client = AwsCloudwatchClient() + + boto_mock = mocker.patch.object(client, "_client", create=True) # TODO # we do this to get the AWS account number, and it seems like unit tests locally have # access to the env variables but when we push the PR they do not. Is there a better way to get it? @@ -22,9 +22,9 @@ def test_check_sms_no_event_error_condition(notify_api, mocker): notification_id = "bbb" boto_mock.filter_log_events.return_value = [] with notify_api.app_context(): - aws_cloudwatch_client.init_app(current_app) + client.init_app(current_app) try: - aws_cloudwatch_client.check_sms(message_id, notification_id) + client.check_sms(message_id, notification_id) assert 1 == 0 except Exception: assert 1 == 1 @@ -62,7 +62,9 @@ def side_effect(filterPattern, logGroupName, startTime, endTime): def test_extract_account_number_gov_cloud(): domain_arn = "arn:aws-us-gov:ses:us-gov-west-1:12345:identity/ses-abc.xxx.xxx.xxx" - actual_account_number = aws_cloudwatch_client._extract_account_number(domain_arn) + client = AwsCloudwatchClient() + client.init_app(current_app) + actual_account_number = client._extract_account_number(domain_arn) assert len(actual_account_number) == 6 expected_account_number = "12345" assert actual_account_number[4] == expected_account_number @@ -70,19 +72,24 @@ def test_extract_account_number_gov_cloud(): def test_extract_account_number_gov_staging(): domain_arn = "arn:aws:ses:us-south-14:12345:identity/ses-abc.xxx.xxx.xxx" - actual_account_number = aws_cloudwatch_client._extract_account_number(domain_arn) + client = AwsCloudwatchClient() + client.init_app(current_app) + actual_account_number = client._extract_account_number(domain_arn) assert len(actual_account_number) == 6 expected_account_number = "12345" assert actual_account_number[4] == expected_account_number def test_event_to_db_format_with_missing_fields(): + client = AwsCloudwatchClient() + client.init_app(current_app) + event = { "notification": {"messageId": "12345"}, "status": "UNKNOWN", "delivery": {}, } - result = aws_cloudwatch_client.event_to_db_format(event) + result = client.event_to_db_format(event) assert result == { "notification.messageId": "12345", "status": "UNKNOWN", @@ -105,7 +112,10 @@ def test_event_to_db_format_with_string_input(): }, } ) - result = aws_cloudwatch_client.event_to_db_format(event) + client = AwsCloudwatchClient() + client.init_app(current_app) + + result = client.event_to_db_format(event) assert result == { "notification.messageId": "67890", "status": "FAILED", @@ -129,8 +139,7 @@ def fake_event(): } -@patch("app.clients.cloudwatch.aws_cloudwatch.current_app") -def test_warn_if_dev_is_opted_out(current_app_mock): +def test_warn_if_dev_is_opted_out(): # os.environ["NOTIFIY_ENVIRONMENT"] = "development" client = AwsCloudwatchClient() logline = client.warn_if_dev_is_opted_out("Number is opted out", "notif123") @@ -183,8 +192,8 @@ def test_extract_account_number(): @patch("app.clients.cloudwatch.aws_cloudwatch.client") def test_get_log_with_pagination(mock_client): client = AwsCloudwatchClient() + client.init_app(current_app) client._client = mock_client - mock_client.filter_log_events.side_effect = [ {"events": [{"message": "msg1"}], "nextToken": "abc"}, {"events": [{"message": "msg2"}]}, @@ -199,8 +208,8 @@ def test_get_log_with_pagination(mock_client): assert logs[1]["message"] == "msg2" -@patch("app.clients.cloudwatch.aws_cloudwatch.current_app") -def test_get_receipts(mock_current_app): +# @patch("app.clients.cloudwatch.aws_cloudwatch.current_app") +def test_get_receipts(): client = AwsCloudwatchClient() client._get_log = MagicMock( return_value=[ @@ -226,9 +235,9 @@ def test_get_receipts(mock_current_app): assert event["status"] == "DELIVERED" -@patch("app.clients.cloudwatch.aws_cloudwatch.current_app") +# @patch("app.clients.cloudwatch.aws_cloudwatch.current_app") @patch("app.clients.cloudwatch.aws_cloudwatch.cloud_config") -def test_check_delivery_receipts(mock_cloud_config, current_app_mock): +def test_check_delivery_receipts(mock_cloud_config): client = AwsCloudwatchClient() mock_cloud_config.sns_regions = "us-north-1" mock_cloud_config.ses_domain_arn = ( From e40dca8904b7f79c92ae1c6548a78eb5837df487 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 11:31:48 -0700 Subject: [PATCH 08/26] fix tests --- tests/app/clients/test_aws_ses.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/app/clients/test_aws_ses.py b/tests/app/clients/test_aws_ses.py index 32cd502c0c..14d48e0519 100644 --- a/tests/app/clients/test_aws_ses.py +++ b/tests/app/clients/test_aws_ses.py @@ -1,12 +1,13 @@ import json from unittest import mock -from unittest.mock import ANY, MagicMock, Mock +from unittest.mock import ANY, Mock import botocore import pytest from app.clients.email import EmailClientNonRetryableException from app.clients.email.aws_ses import ( + AwsSesClient, AwsSesClientException, AwsSesClientThrottlingSendRateException, get_aws_responses, @@ -14,8 +15,6 @@ from app.clients.email.aws_ses_stub import AwsSesStubClient from app.enums import NotificationStatus, StatisticsType -# comes from app/__init__.py but we mock it for the tests -aws_ses_client = MagicMock() def test_should_return_correct_details_for_delivery(): @@ -68,6 +67,8 @@ def test_should_be_none_if_unrecognised_status_code(): def test_send_email_handles_reply_to_address( notify_api, mocker, reply_to_address, expected_value ): + aws_ses_client = AwsSesClient() + boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) with notify_api.app_context(): @@ -85,6 +86,7 @@ def test_send_email_handles_reply_to_address( def test_send_email_handles_punycode_to_address(notify_api, mocker): + aws_ses_client = AwsSesClient() boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) with notify_api.app_context(): @@ -107,6 +109,7 @@ def test_send_email_handles_punycode_to_address(notify_api, mocker): def test_send_email_raises_invalid_parameter_value_error_as_EmailClientNonRetryableException( mocker, ): + aws_ses_client = AwsSesClient() boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) error_response = { "Error": { @@ -133,6 +136,7 @@ def test_send_email_raises_invalid_parameter_value_error_as_EmailClientNonRetrya def test_send_email_raises_send_rate_throttling_as_AwsSesClientThrottlingSendRateException( mocker, ): + aws_ses_client = AwsSesClient() boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) error_response = { "Error": { @@ -154,6 +158,7 @@ def test_send_email_raises_send_rate_throttling_as_AwsSesClientThrottlingSendRat def test_send_email_does_not_raise_AwsSesClientThrottlingSendRateException_if_non_send_rate_throttling( mocker, ): + aws_ses_client = AwsSesClient() boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) error_response = { "Error": { @@ -173,6 +178,7 @@ def test_send_email_does_not_raise_AwsSesClientThrottlingSendRateException_if_no def test_send_email_raises_other_errs_as_AwsSesClientException(mocker): + aws_ses_client = AwsSesClient() boto_mock = mocker.patch.object(aws_ses_client, "_client", create=True) error_response = { "Error": { From f5bd0e3bb15d16b4de7245c42cb05a8cdebbba5d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 11:36:27 -0700 Subject: [PATCH 09/26] fix tests --- tests/app/clients/test_aws_ses.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/app/clients/test_aws_ses.py b/tests/app/clients/test_aws_ses.py index 14d48e0519..a4fe8003e9 100644 --- a/tests/app/clients/test_aws_ses.py +++ b/tests/app/clients/test_aws_ses.py @@ -16,7 +16,6 @@ from app.enums import NotificationStatus, StatisticsType - def test_should_return_correct_details_for_delivery(): response_dict = get_aws_responses("Delivery") assert response_dict["message"] == "Delivered" From 816e6ad818dd11cf51c61f17e855c1727e5e1ff1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 11:56:20 -0700 Subject: [PATCH 10/26] fix tests --- app/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/__init__.py b/app/__init__.py index 05d86f6982..18dbceb7ae 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -126,6 +126,15 @@ def get_zendesk_client(): return zendesk_client +def get_aws_ses_client(): + global aws_ses_client + if os.environ.get("NOTIFY_ENVIRONMENT") == "test": + return AwsSesClient() + if aws_ses_client is None: + raise RuntimeError(f"Celery not initialized aws_ses_client: {aws_ses_client}") + return aws_ses_client + + def get_document_download_client(): global document_download_client # Our unit tests mock anyway From eaea9d14150e9c6cb283599ecf7773b7d639d436 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 12:20:03 -0700 Subject: [PATCH 11/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index e2040d6c05..5d67c16ce4 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -142,9 +142,7 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist template=sample_email_template_with_html, ) db_notification.personalisation = {"name": "Jo"} - mock_ses_client = MagicMock() - mock_ses_client.send_email.return_value = "reference" - mocker.patch("app.aws_ses_client", mock_ses_client) + mocker.patch("app.aws_ses_client.send_email", return_value="reference") send_to_providers.send_email_to_provider(db_notification) app.aws_ses_client.send_email.assert_called_once_with( f'"Sample service" ', @@ -178,9 +176,7 @@ def test_should_not_send_email_message_when_service_is_inactive_notifcation_is_i sample_service, sample_notification, mocker ): sample_service.active = False - mock_ses_client = MagicMock() - mock_ses_client.send_email.return_value = "reference" - send_mock = mocker.patch("app.aws_ses_client", mock_ses_client) + send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference") mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3") mock_s3.return_value = "2028675309" From a94cca54a6736e7f63a0b3bfdbe09e6d1f188a55 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 13:00:18 -0700 Subject: [PATCH 12/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 5d67c16ce4..29e37f5acc 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -9,6 +9,7 @@ import app from app import aws_sns_client, db, notification_provider_clients +from app.clients.email.aws_ses import AwsSesClient from app.cloudfoundry_config import cloud_config from app.dao import notifications_dao from app.dao.provider_details_dao import get_provider_details_by_identifier @@ -142,6 +143,11 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist template=sample_email_template_with_html, ) db_notification.personalisation = {"name": "Jo"} + + mock_client = AwsSesClient() + mock_client.init_app() + mocker.patch("app.aws_ses.client", mock_client) + mocker.patch("app.aws_ses_client.send_email", return_value="reference") send_to_providers.send_email_to_provider(db_notification) app.aws_ses_client.send_email.assert_called_once_with( From 3929ffb5fb71e717ec5115b55da43a1ff4791f54 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 13:08:29 -0700 Subject: [PATCH 13/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 29e37f5acc..88d0d1c2f7 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -146,7 +146,7 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist mock_client = AwsSesClient() mock_client.init_app() - mocker.patch("app.aws_ses.client", mock_client) + mocker.patch("app.aws_ses_client", mock_client) mocker.patch("app.aws_ses_client.send_email", return_value="reference") send_to_providers.send_email_to_provider(db_notification) From 4b1d03439f75343bbd4015bfbee32866b575dcb7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 13:22:36 -0700 Subject: [PATCH 14/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 88d0d1c2f7..fc9242dcdc 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -182,7 +182,10 @@ def test_should_not_send_email_message_when_service_is_inactive_notifcation_is_i sample_service, sample_notification, mocker ): sample_service.active = False - send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference") + + mock_client = MagicMock() + mock_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_client) mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3") mock_s3.return_value = "2028675309" @@ -205,7 +208,7 @@ def test_should_not_send_email_message_when_service_is_inactive_notifcation_is_i with pytest.raises(NotificationTechnicalFailureException) as e: send_to_providers.send_email_to_provider(sample_notification) assert str(sample_notification.id) in str(e.value) - send_mock.assert_not_called() + mock_client.send_email.assert_not_called() assert ( db.session.get(Notification, sample_notification.id).status == NotificationStatus.TECHNICAL_FAILURE From f266602f2adf2d1d7326f61c242207e9bce69223 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 13:32:45 -0700 Subject: [PATCH 15/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index fc9242dcdc..df1aa2ac0c 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -9,7 +9,6 @@ import app from app import aws_sns_client, db, notification_provider_clients -from app.clients.email.aws_ses import AwsSesClient from app.cloudfoundry_config import cloud_config from app.dao import notifications_dao from app.dao.provider_details_dao import get_provider_details_by_identifier @@ -144,8 +143,8 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist ) db_notification.personalisation = {"name": "Jo"} - mock_client = AwsSesClient() - mock_client.init_app() + mock_client = MagicMock() + mock_client.send_email.return_value = "reference" mocker.patch("app.aws_ses_client", mock_client) mocker.patch("app.aws_ses_client.send_email", return_value="reference") From 1a61013ea3a8e561f22a3451fd33746341c6f3d7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 13:43:25 -0700 Subject: [PATCH 16/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index df1aa2ac0c..387ce62511 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -147,7 +147,6 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist mock_client.send_email.return_value = "reference" mocker.patch("app.aws_ses_client", mock_client) - mocker.patch("app.aws_ses_client.send_email", return_value="reference") send_to_providers.send_email_to_provider(db_notification) app.aws_ses_client.send_email.assert_called_once_with( f'"Sample service" ', @@ -185,6 +184,7 @@ def test_should_not_send_email_message_when_service_is_inactive_notifcation_is_i mock_client = MagicMock() mock_client.send_email.return_value = "reference" mocker.patch("app.aws_ses_client", mock_client) + mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3") mock_s3.return_value = "2028675309" From e1b1564321dc6f9948f340d335e1ad8569135879 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 14:31:34 -0700 Subject: [PATCH 17/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 387ce62511..beffb9d043 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -143,12 +143,17 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist ) db_notification.personalisation = {"name": "Jo"} - mock_client = MagicMock() - mock_client.send_email.return_value = "reference" - mocker.patch("app.aws_ses_client", mock_client) + mock_boto_client = mocker.patch("boto3.client") + mock_ses = MagicMock() + mock_boto_client.return_value = mock_ses + mock_ses.send_email.return_value = "reference" + mocker.patch( + "app.notification_provider_clients.get_client_by_name_and_type", + return_value=mock_ses, + ) send_to_providers.send_email_to_provider(db_notification) - app.aws_ses_client.send_email.assert_called_once_with( + mock_ses.send_email.assert_called_once_with( f'"Sample service" ', "jo.smith@example.com", "Jo some HTML", @@ -427,8 +432,10 @@ def test_send_email_to_provider_should_not_send_to_provider_when_status_is_not_c notification = create_notification( template=sample_email_template, status=NotificationStatus.SENDING ) - mock_ses_client = MagicMock() - mocker.patch("app.aws_ses_client", mock_ses_client) + + mock_client = MagicMock() + mock_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_client) mocker.patch("app.delivery.send_to_providers.send_email_response") mocker.patch("app.delivery.send_to_providers.update_notification_message_id") From ec0a0a5ddba0dffdc57cac92bd7903d6221934eb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 14:43:36 -0700 Subject: [PATCH 18/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index beffb9d043..d0f64e42ee 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -147,6 +147,7 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist mock_ses = MagicMock() mock_boto_client.return_value = mock_ses mock_ses.send_email.return_value = "reference" + mock_ses.name = "ses" mocker.patch( "app.notification_provider_clients.get_client_by_name_and_type", return_value=mock_ses, From 7fea6bcb66d0d7f14e3f2bda73e81c966a11c74c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 2 Oct 2025 15:01:34 -0700 Subject: [PATCH 19/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index d0f64e42ee..46e2018d25 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -973,6 +973,10 @@ def test_send_sms_to_provider_should_return_template_if_found_in_redis( ) mock_personalisation.return_value = {"ignore": "ignore"} + mock_client = MagicMock() + mock_client.send_email.return_value = "reference" + mocker.patch("app.aws_ses_client", mock_client) + send_to_providers.send_sms_to_provider(notification) assert mock_get_template.called is False assert mock_get_service.called is False @@ -1017,9 +1021,16 @@ def test_send_email_to_provider_should_return_template_if_found_in_redis( "app.dao.templates_dao.dao_get_template_by_id_and_service_id" ) mock_get_service = mocker.patch("app.dao.services_dao.dao_fetch_service_by_id") + mock_ses_client = MagicMock() mock_ses_client.send_email.return_value = "reference" send_mock = mocker.patch("app.aws_ses_client", mock_ses_client) + mock_ses_client.name = "ses" + mocker.patch( + "app.notification_provider_clients.get_client_by_name_and_type", + return_value=mock_ses_client, + ) + notification = create_notification( template=sample_email_template, ) From 7a78dfe96fde8ba85292a68133fc51dab1dcfb55 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 3 Oct 2025 07:40:12 -0700 Subject: [PATCH 20/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 46e2018d25..5b406630c3 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -149,7 +149,7 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist mock_ses.send_email.return_value = "reference" mock_ses.name = "ses" mocker.patch( - "app.notification_provider_clients.get_client_by_name_and_type", + "app.delivery.send_to_providers.provider_to_use", return_value=mock_ses, ) From d2f2cc7a3c322fef16c34b42ab903749714cde17 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 3 Oct 2025 07:50:43 -0700 Subject: [PATCH 21/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 5b406630c3..4029886120 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -163,11 +163,11 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist reply_to_address=None, ) - assert " Date: Fri, 3 Oct 2025 07:59:21 -0700 Subject: [PATCH 22/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 4029886120..54fc9266a2 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -163,11 +163,11 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist reply_to_address=None, ) - # assert " Date: Fri, 3 Oct 2025 08:09:37 -0700 Subject: [PATCH 23/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 54fc9266a2..9beaf436ea 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -455,9 +455,15 @@ def test_send_email_to_provider_should_not_send_to_provider_when_status_is_not_c def test_send_email_should_use_service_reply_to_email( sample_service, sample_email_template, mocker ): - mock_ses_client = MagicMock() - mock_ses_client.send_email.return_value = "reference" - mocker.patch("app.aws_ses_client", mock_ses_client) + mock_boto_client = mocker.patch("boto3.client") + mock_ses = MagicMock() + mock_boto_client.return_value = mock_ses + mock_ses.send_email.return_value = "reference" + mock_ses.name = "ses" + mocker.patch( + "app.delivery.send_to_providers.provider_to_use", + return_value=mock_ses, + ) mock_redis = mocker.patch("app.delivery.send_to_providers.redis_store") mock_redis.get.return_value = "test@example.com".encode("utf-8") @@ -477,7 +483,7 @@ def test_send_email_should_use_service_reply_to_email( send_to_providers.send_email_to_provider(db_notification) - app.aws_ses_client.send_email.assert_called_once_with( + mock_ses.send_email.assert_called_once_with( ANY, ANY, ANY, From e017d052e3b581e799b29c7c38b00ab96c88897d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 3 Oct 2025 08:24:49 -0700 Subject: [PATCH 24/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 47 +++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 9beaf436ea..30bbc8a6ff 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -165,8 +165,8 @@ def test_should_send_personalised_template_to_correct_email_provider_and_persist assert " Date: Fri, 3 Oct 2025 08:56:03 -0700 Subject: [PATCH 25/26] fix tests --- tests/app/delivery/test_send_to_providers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 30bbc8a6ff..ba0837f8e8 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -907,7 +907,7 @@ def test_send_sms_to_provider_should_use_normalised_to(mocker, client, sample_te ) -def test_send_email_to_provider_should_user_normalised_to( +def test_send_email_to_provider_should_use_normalised_to( mocker, client, sample_email_template ): mock_boto_client = mocker.patch("boto3.client") @@ -935,7 +935,7 @@ def test_send_email_to_provider_should_user_normalised_to( mock_redis.get.side_effect = [email, personalisation] send_to_providers.send_email_to_provider(notification) - mock_ses.assert_called_once_with( + mock_ses.send_email.assert_called_once_with( ANY, "test@example.com", ANY, @@ -1057,7 +1057,7 @@ def test_send_email_to_provider_should_return_template_if_found_in_redis( send_to_providers.send_email_to_provider(notification) assert mock_get_template.called is False assert mock_get_service.called is False - mock_ses.assert_called_once_with( + mock_ses.send_email.assert_called_once_with( ANY, "test@example.com", ANY, From 8b6999f375e9d0e9e94a96cd12a1df3c4c9b3bed Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 3 Oct 2025 09:22:55 -0700 Subject: [PATCH 26/26] cleanup --- app/__init__.py | 6 ++++-- app/job/rest.py | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 18dbceb7ae..9fad21e300 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -122,7 +122,7 @@ def get_zendesk_client(): if os.environ.get("NOTIFY_ENVIRONMENT") == "test": return None if zendesk_client is None: - raise RuntimeError(f"Celery not initialized zendesk_client: {zendesk_client}") + zendesk_client = ZendeskClient() return zendesk_client @@ -148,6 +148,7 @@ def get_document_download_client(): def create_app(application): + global zendesk_client, migrate, document_download_client, aws_ses_client, aws_ses_stub_client from app.config import configs notify_environment = os.environ["NOTIFY_ENVIRONMENT"] @@ -170,7 +171,8 @@ def create_app(application): # start lazy initialization for gevent migrate = Migrate() migrate.init_app(application, db=db) - zendesk_client = ZendeskClient() + if zendesk_client is None: + zendesk_client = ZendeskClient() zendesk_client.init_app(application) document_download_client = DocumentDownloadClient() document_download_client.init_app(application) diff --git a/app/job/rest.py b/app/job/rest.py index 45207147ce..fa7165d284 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -49,7 +49,6 @@ @job_blueprint.route("/", methods=["GET"]) def get_job_by_service_and_job_id(service_id, job_id): - current_app.logger.info(hilite("ENTER get_job_by_service_and_job_id")) check_suspicious_id(service_id, job_id) job = dao_get_job_by_service_id_and_job_id(service_id, job_id) statistics = dao_get_notification_outcomes_for_job(service_id, job_id) @@ -150,7 +149,6 @@ def get_all_notifications_for_service_job(service_id, job_id): notifications = notification_with_template_schema.dump( paginated_notifications.items, many=True ) - current_app.logger.info(hilite("Got the dumped notifications and returning")) return ( jsonify(