From d6bb2d8fb0b0e63c4a828eff6ddaf191d6bc75c5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 08:39:13 -0800 Subject: [PATCH 01/10] track message costs --- app/celery/scheduled_tasks.py | 2 +- app/clients/cloudwatch/aws_cloudwatch.py | 9 +++ app/dao/notifications_dao.py | 15 ++++- app/dao/services_dao.py | 25 ++++++--- app/models.py | 2 + migrations/versions/0415_add_message_cost.py | 23 ++++++++ .../dao/test_services_get_specific_hours.py | 56 ++++++++++++------- 7 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 migrations/versions/0415_add_message_cost.py diff --git a/app/celery/scheduled_tasks.py b/app/celery/scheduled_tasks.py index 2ff72780d..40cdf9382 100644 --- a/app/celery/scheduled_tasks.py +++ b/app/celery/scheduled_tasks.py @@ -266,7 +266,7 @@ def process_delivery_receipts(self): cloudwatch = AwsCloudwatchClient() cloudwatch.init_app(current_app) - start_time = aware_utcnow() - timedelta(minutes=3) + start_time = aware_utcnow() - timedelta(minutes=30) end_time = aware_utcnow() delivered_receipts, failed_receipts = cloudwatch.check_delivery_receipts( start_time, end_time diff --git a/app/clients/cloudwatch/aws_cloudwatch.py b/app/clients/cloudwatch/aws_cloudwatch.py index 43bedbb35..68eaaeb94 100644 --- a/app/clients/cloudwatch/aws_cloudwatch.py +++ b/app/clients/cloudwatch/aws_cloudwatch.py @@ -7,6 +7,7 @@ from flask import current_app from app.clients import AWS_CLIENT_CONFIG, Client from app.cloudfoundry_config import cloud_config +from app.utils import hilite class AwsCloudwatchClient(Client): @@ -107,6 +108,13 @@ class AwsCloudwatchClient(Client): provider_response = self._aws_value_or_default( event, "delivery", "providerResponse" ) + message_cost = self._aws_value_or_default(event, "delivery", "priceInUSD") + if message_cost is None or message_cost == "": + message_cost = 0.0 + else: + message_cost = float(message_cost) + current_app.logger.info(hilite(f"EVENT {event} message_cost = {message_cost}")) + my_timestamp = self._aws_value_or_default(event, "notification", "timestamp") return { "notification.messageId": event["notification"]["messageId"], @@ -114,6 +122,7 @@ class AwsCloudwatchClient(Client): "delivery.phoneCarrier": phone_carrier, "delivery.providerResponse": provider_response, "@timestamp": my_timestamp, + "delivery.priceInUSD": message_cost, } # Here is an example of how to get the events with log insights diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index ed84218d6..0b0b09ec1 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -507,7 +507,7 @@ def insert_notification_history_delete_notifications( SELECT id, job_id, job_row_number, service_id, template_id, template_version, api_key_id, key_type, notification_type, created_at, sent_at, sent_by, updated_at, reference, billable_units, client_reference, international, phone_prefix, rate_multiplier, notification_status, - created_by_id, document_download_count + created_by_id, document_download_count, message_cost FROM notifications WHERE service_id = :service_id AND notification_type = :notification_type @@ -842,7 +842,6 @@ def dao_update_delivery_receipts(receipts, delivered): new_receipts.append(r) receipts = new_receipts - id_to_carrier = { r["notification.messageId"]: r["delivery.phoneCarrier"] for r in receipts } @@ -851,9 +850,13 @@ def dao_update_delivery_receipts(receipts, delivered): } id_to_timestamp = {r["notification.messageId"]: r["@timestamp"] for r in receipts} + id_to_message_cost = { + r["notification.messageId"]: r["delivery.priceInUSD"] for r in receipts + } status_to_update_with = NotificationStatus.DELIVERED if not delivered: status_to_update_with = NotificationStatus.FAILED + stmt = ( update(Notification) .where(Notification.message_id.in_(id_to_carrier.keys())) @@ -877,6 +880,12 @@ def dao_update_delivery_receipts(receipts, delivered): for key, value in id_to_provider_response.items() ] ), + message_cost=case( + *[ + (Notification.message_id == key, value) + for key, value in id_to_message_cost.items() + ] + ), ) ) db.session.execute(stmt) @@ -908,7 +917,7 @@ def dao_close_out_delivery_receipts(): def dao_batch_insert_notifications(batch): - + current_app.logger.info(f"ENTER DAO_BATCH_INSERT with batch {batch}") db.session.bulk_save_objects(batch) db.session.commit() current_app.logger.info(f"Batch inserted notifications: {len(batch)}") diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 1c8a5e157..a7db2415d 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -534,7 +534,9 @@ def dao_fetch_stats_for_service_from_hours(service_id, start_date, end_date): # Update to group by HOUR instead of DAY total_substmt = ( select( - func.date_trunc("hour", NotificationAllTimeView.created_at).label("hour"), # UPDATED + func.date_trunc("hour", NotificationAllTimeView.created_at).label( + "hour" + ), # UPDATED Job.notification_count.label("notification_count"), ) .join(Job, NotificationAllTimeView.job_id == Job.id) @@ -556,11 +558,14 @@ def dao_fetch_stats_for_service_from_hours(service_id, start_date, end_date): total_stmt = select( total_substmt.c.hour, # UPDATED func.sum(total_substmt.c.notification_count).label("total_notifications"), - ).group_by(total_substmt.c.hour) # UPDATED + ).group_by( + total_substmt.c.hour + ) # UPDATED # Ensure we're using hourly timestamps in the response total_notifications = { - row.hour: row.total_notifications for row in db.session.execute(total_stmt).all() + row.hour: row.total_notifications + for row in db.session.execute(total_stmt).all() } # Update the second query to also use "hour" @@ -568,7 +573,9 @@ def dao_fetch_stats_for_service_from_hours(service_id, start_date, end_date): select( NotificationAllTimeView.notification_type, NotificationAllTimeView.status, - func.date_trunc("hour", NotificationAllTimeView.created_at).label("hour"), # UPDATED + func.date_trunc("hour", NotificationAllTimeView.created_at).label( + "hour" + ), # UPDATED func.count(NotificationAllTimeView.id).label("count"), ) .where( @@ -895,7 +902,9 @@ def get_specific_days_stats( return stats -def get_specific_hours_stats(data, start_date, hours=None, end_date=None, total_notifications=None): +def get_specific_hours_stats( + data, start_date, hours=None, end_date=None, total_notifications=None +): if hours is not None and end_date is not None: raise ValueError("Only set hours OR set end_date, not both.") elif hours is not None: @@ -919,10 +928,10 @@ def get_specific_hours_stats(data, start_date, hours=None, end_date=None, total_ # Format statistics, returning only hours with results stats = { hour.strftime("%Y-%m-%dT%H:00:00Z"): statistics.format_statistics( - rows, - total_notifications.get(hour, 0) if total_notifications else None + rows, total_notifications.get(hour, 0) if total_notifications else None ) - for hour, rows in grouped_data.items() if rows + for hour, rows in grouped_data.items() + if rows } return stats diff --git a/app/models.py b/app/models.py index f78f630ea..d9a50a025 100644 --- a/app/models.py +++ b/app/models.py @@ -1508,6 +1508,7 @@ class Notification(db.Model): created_at = db.Column(db.DateTime, index=True, unique=False, nullable=False) sent_at = db.Column(db.DateTime, index=False, unique=False, nullable=True) sent_by = db.Column(db.String, nullable=True) + message_cost = db.Column(db.Float, nullable=True, default=0.0) updated_at = db.Column( db.DateTime, index=False, @@ -1813,6 +1814,7 @@ class NotificationHistory(db.Model, HistoryModel): created_at = db.Column(db.DateTime, unique=False, nullable=False) sent_at = db.Column(db.DateTime, index=False, unique=False, nullable=True) sent_by = db.Column(db.String, nullable=True) + message_cost = db.Column(db.Float, nullable=True, default=0.0) updated_at = db.Column( db.DateTime, index=False, diff --git a/migrations/versions/0415_add_message_cost.py b/migrations/versions/0415_add_message_cost.py new file mode 100644 index 000000000..1a86170d7 --- /dev/null +++ b/migrations/versions/0415_add_message_cost.py @@ -0,0 +1,23 @@ +""" + +Revision ID: 0415_add_message_cost +Revises: 0414_change_total_message_limit +Create Date: 2025-02-28 11:35:22.873930 + +""" + +import sqlalchemy as sa +from alembic import op + +down_revision = "0414_change_total_message_limit" +revision = "0415_add_message_cost" + + +def upgrade(): + op.add_column("notifications", sa.Column("message_cost", sa.Float)) + op.add_column("notification_history", sa.Column("message_cost", sa.Float)) + + +def downgrade(): + op.drop_column("notifications", "message_cost") + op.add_column("notification_history", sa.Column("message_cost", sa.Float)) diff --git a/tests/app/dao/test_services_get_specific_hours.py b/tests/app/dao/test_services_get_specific_hours.py index b96d442c0..a97dbd150 100644 --- a/tests/app/dao/test_services_get_specific_hours.py +++ b/tests/app/dao/test_services_get_specific_hours.py @@ -7,7 +7,9 @@ from app.dao.services_dao import get_specific_hours_stats from app.enums import StatisticsType from app.models import TemplateType -NotificationRow = namedtuple("NotificationRow", ["notification_type", "status", "timestamp", "count"]) +NotificationRow = namedtuple( + "NotificationRow", ["notification_type", "status", "timestamp", "count"] +) def generate_expected_hourly_output(requested_sms_hours): @@ -38,27 +40,31 @@ def create_mock_notification(notification_type, status, timestamp, count=1): notification_type=notification_type, status=status, timestamp=timestamp.replace(minute=0, second=0, microsecond=0), - count=count + count=count, ) test_cases = [ ( - [create_mock_notification( - TemplateType.SMS, - StatisticsType.REQUESTED, - datetime(2025, 2, 18, 14, 15, 0), - )], + [ + create_mock_notification( + TemplateType.SMS, + StatisticsType.REQUESTED, + datetime(2025, 2, 18, 14, 15, 0), + ) + ], datetime(2025, 2, 18, 12, 0), 6, generate_expected_hourly_output(["2025-02-18T14:00:00Z"]), ), ( - [create_mock_notification( - TemplateType.SMS, - StatisticsType.REQUESTED, - datetime(2025, 2, 18, 17, 59, 59), - )], + [ + create_mock_notification( + TemplateType.SMS, + StatisticsType.REQUESTED, + datetime(2025, 2, 18, 17, 59, 59), + ) + ], datetime(2025, 2, 18, 15, 0), 3, generate_expected_hourly_output(["2025-02-18T17:00:00Z"]), @@ -66,21 +72,29 @@ test_cases = [ ([], datetime(2025, 2, 18, 10, 0), 4, {}), ( [ - create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 2, 18, 9, 30, 0)), - create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 2, 18, 11, 45, 0)), + create_mock_notification( + TemplateType.SMS, + StatisticsType.REQUESTED, + datetime(2025, 2, 18, 9, 30, 0), + ), + create_mock_notification( + TemplateType.SMS, + StatisticsType.REQUESTED, + datetime(2025, 2, 18, 11, 45, 0), + ), ], datetime(2025, 2, 18, 8, 0), 5, - generate_expected_hourly_output(["2025-02-18T09:00:00Z", "2025-02-18T11:00:00Z"]), + generate_expected_hourly_output( + ["2025-02-18T09:00:00Z", "2025-02-18T11:00:00Z"] + ), ), ] -@pytest.mark.parametrize("mocked_notifications, start_date, hours, expected_output", test_cases) +@pytest.mark.parametrize( + "mocked_notifications, start_date, hours, expected_output", test_cases +) def test_get_specific_hours(mocked_notifications, start_date, hours, expected_output): - results = get_specific_hours_stats( - mocked_notifications, - start_date, - hours=hours - ) + results = get_specific_hours_stats(mocked_notifications, start_date, hours=hours) assert results == expected_output, f"Expected {expected_output}, but got {results}" From 143741830c62c8aa9056b3117f349855059a34ef Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 08:58:45 -0800 Subject: [PATCH 02/10] track message costs --- tests/app/dao/notification_dao/test_notification_dao.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index a6748dd33..aefc6cc78 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -2019,8 +2019,8 @@ def test_notifications_not_yet_sent_return_no_rows(sample_service, notification_ def test_update_delivery_receipts(mocker): mock_session = mocker.patch("app.dao.notifications_dao.db.session") receipts = [ - '{"notification.messageId": "msg1", "delivery.phoneCarrier": "carrier1", "delivery.providerResponse": "resp1", "@timestamp": "2024-01-01T12:00:00"}', # noqa - '{"notification.messageId": "msg2", "delivery.phoneCarrier": "carrier2", "delivery.providerResponse": "resp2", "@timestamp": "2024-01-01T13:00:00"}', # noqa + '{"notification.messageId": "msg1", "delivery.phoneCarrier": "carrier1", "delivery.providerResponse": "resp1", "@timestamp": "2024-01-01T12:00:00", "delivery.priceInUSD": "0.00881"}', # noqa + '{"notification.messageId": "msg2", "delivery.phoneCarrier": "carrier2", "delivery.providerResponse": "resp2", "@timestamp": "2024-01-01T13:00:00", "delivery.priceInUSD": "0.00881"}', # noqa ] delivered = True mock_update = MagicMock() From c05ec18b110aed6c43a9bbcbd782239e16a735bb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 09:16:06 -0800 Subject: [PATCH 03/10] track message costs --- tests/app/clients/test_aws_cloudwatch.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/app/clients/test_aws_cloudwatch.py b/tests/app/clients/test_aws_cloudwatch.py index 7a0379454..2d00c1362 100644 --- a/tests/app/clients/test_aws_cloudwatch.py +++ b/tests/app/clients/test_aws_cloudwatch.py @@ -31,7 +31,7 @@ def side_effect(filterPattern, logGroupName, startTime, endTime): { "logStreamName": "89db9712-c6d1-49f9-be7c-4caa7ed9efb1", "message": '{"delivery":{"destination":"+1661","phoneCarrier":"ATT Mobility", ' - '"providerResponse":"Invalid phone number"}}', + '"providerResponse":"Invalid phone number", "priceInUSD": "0.00881"}}', "eventId": "37535432778099870001723210579798865345508698025292922880", } ] @@ -44,7 +44,7 @@ def side_effect(filterPattern, logGroupName, startTime, endTime): "logStreamName": "89db9712-c6d1-49f9-be7c-4caa7ed9efb1", "timestamp": 1683147017911, "message": '{"delivery":{"destination":"+1661","phoneCarrier":"ATT Mobility",' - '"providerResponse":"Phone accepted msg"}}', + '"providerResponse":"Phone accepted msg", "priceInUSD": "0.00881"}}', "ingestionTime": 1683147018026, "eventId": "37535432778099870001723210579798865345508698025292922880", } @@ -131,6 +131,7 @@ def test_event_to_db_format_with_missing_fields(): "status": "UNKNOWN", "delivery.phoneCarrier": "", "delivery.providerResponse": "", + "delivery.priceInUSD": "0.0", "@timestamp": "", } @@ -140,7 +141,11 @@ def test_event_to_db_format_with_string_input(): { "notification": {"messageId": "67890", "timestamp": "2024-01-01T14:00:00Z"}, "status": "FAILED", - "delivery": {"phoneCarrier": "Verizon", "providerResponse": "Error"}, + "delivery": { + "phoneCarrier": "Verizon", + "providerResponse": "Error", + "priceInUSD": "0.00881", + }, } ) result = aws_cloudwatch_client.event_to_db_format(event) @@ -149,5 +154,6 @@ def test_event_to_db_format_with_string_input(): "status": "FAILED", "delivery.phoneCarrier": "Verizon", "delivery.providerResponse": "Error", + "delivery.priceInUSD": "0.00881", "@timestamp": "2024-01-01T14:00:00Z", } From 4846c965052d1f3866b27b70887aecff393a78ae Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 09:29:43 -0800 Subject: [PATCH 04/10] track message costs --- tests/app/clients/test_aws_cloudwatch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/app/clients/test_aws_cloudwatch.py b/tests/app/clients/test_aws_cloudwatch.py index 2d00c1362..36de2c1b1 100644 --- a/tests/app/clients/test_aws_cloudwatch.py +++ b/tests/app/clients/test_aws_cloudwatch.py @@ -131,7 +131,7 @@ def test_event_to_db_format_with_missing_fields(): "status": "UNKNOWN", "delivery.phoneCarrier": "", "delivery.providerResponse": "", - "delivery.priceInUSD": "0.0", + "delivery.priceInUSD": 0.0, "@timestamp": "", } @@ -154,6 +154,6 @@ def test_event_to_db_format_with_string_input(): "status": "FAILED", "delivery.phoneCarrier": "Verizon", "delivery.providerResponse": "Error", - "delivery.priceInUSD": "0.00881", + "delivery.priceInUSD": 0.00881, "@timestamp": "2024-01-01T14:00:00Z", } From 880c524f1423d2f893eee8682ae7a5a7fea97fa1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 09:40:54 -0800 Subject: [PATCH 05/10] track message costs --- tests/app/organization/test_rest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/app/organization/test_rest.py b/tests/app/organization/test_rest.py index 445a47297..5fa3eb091 100644 --- a/tests/app/organization/test_rest.py +++ b/tests/app/organization/test_rest.py @@ -831,7 +831,9 @@ def test_get_organization_users_returns_users_for_organization( ) assert len(response["data"]) == 2 - assert response["data"][0]["id"] == str(first.id) + response_ids = [response["data"][0]["id"], response["data"][0]["id"]] + assert str(first.id) in response_ids + assert str(second.id) in response_ids @freeze_time("2019-12-24 13:30") From a04507601ba750eeb58c0a6853ed41d8b37e5ef7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 09:57:37 -0800 Subject: [PATCH 06/10] track message costs --- tests/app/organization/test_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/organization/test_rest.py b/tests/app/organization/test_rest.py index 5fa3eb091..d128630bd 100644 --- a/tests/app/organization/test_rest.py +++ b/tests/app/organization/test_rest.py @@ -831,7 +831,7 @@ def test_get_organization_users_returns_users_for_organization( ) assert len(response["data"]) == 2 - response_ids = [response["data"][0]["id"], response["data"][0]["id"]] + response_ids = [response["data"][0]["id"], response["data"][1]["id"]] assert str(first.id) in response_ids assert str(second.id) in response_ids From d0fe33cc6e45620a81cdbe8da3c613610361964d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 10:08:02 -0800 Subject: [PATCH 07/10] track message costs --- app/celery/scheduled_tasks.py | 2 +- app/clients/cloudwatch/aws_cloudwatch.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/celery/scheduled_tasks.py b/app/celery/scheduled_tasks.py index 40cdf9382..2ff72780d 100644 --- a/app/celery/scheduled_tasks.py +++ b/app/celery/scheduled_tasks.py @@ -266,7 +266,7 @@ def process_delivery_receipts(self): cloudwatch = AwsCloudwatchClient() cloudwatch.init_app(current_app) - start_time = aware_utcnow() - timedelta(minutes=30) + start_time = aware_utcnow() - timedelta(minutes=3) end_time = aware_utcnow() delivered_receipts, failed_receipts = cloudwatch.check_delivery_receipts( start_time, end_time diff --git a/app/clients/cloudwatch/aws_cloudwatch.py b/app/clients/cloudwatch/aws_cloudwatch.py index 68eaaeb94..0a6d3d7be 100644 --- a/app/clients/cloudwatch/aws_cloudwatch.py +++ b/app/clients/cloudwatch/aws_cloudwatch.py @@ -7,7 +7,6 @@ from flask import current_app from app.clients import AWS_CLIENT_CONFIG, Client from app.cloudfoundry_config import cloud_config -from app.utils import hilite class AwsCloudwatchClient(Client): @@ -113,7 +112,6 @@ class AwsCloudwatchClient(Client): message_cost = 0.0 else: message_cost = float(message_cost) - current_app.logger.info(hilite(f"EVENT {event} message_cost = {message_cost}")) my_timestamp = self._aws_value_or_default(event, "notification", "timestamp") return { From da9bbc31ba85e30946c472c7b42b2fd25b001358 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 28 Feb 2025 14:47:26 -0800 Subject: [PATCH 08/10] remoe print statement --- app/dao/notifications_dao.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 0b0b09ec1..52823f7d6 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -917,7 +917,6 @@ def dao_close_out_delivery_receipts(): def dao_batch_insert_notifications(batch): - current_app.logger.info(f"ENTER DAO_BATCH_INSERT with batch {batch}") db.session.bulk_save_objects(batch) db.session.commit() current_app.logger.info(f"Batch inserted notifications: {len(batch)}") From 5e5f28b313c566bced85c4ab75efe0df4417ad65 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 3 Mar 2025 10:53:56 -0800 Subject: [PATCH 09/10] merge from main --- tests/app/aws/test_s3.py | 7 +++---- .../app/dao/notification_dao/test_notification_dao.py | 6 ++++-- tests/app/dao/test_fact_notification_status_dao.py | 11 +++++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/app/aws/test_s3.py b/tests/app/aws/test_s3.py index 57673e6b4..e18e31f1b 100644 --- a/tests/app/aws/test_s3.py +++ b/tests/app/aws/test_s3.py @@ -571,9 +571,9 @@ def test_purge_bucket(mocker): mock_s3_resource = MagicMock() mock_bucket = MagicMock() mock_s3_resource.Bucket.return_value = mock_bucket - mocker.patch('app.aws.s3.get_s3_resource', return_value=mock_s3_resource) + mocker.patch("app.aws.s3.get_s3_resource", return_value=mock_s3_resource) - purge_bucket('my-bucket', 'access-key', 'secret-key', 'region') + purge_bucket("my-bucket", "access-key", "secret-key", "region") # Assert that the bucket's objects.all().delete() method was called mock_bucket.objects.all.return_value.delete.assert_called_once() @@ -613,8 +613,7 @@ def test_get_s3_files_handles_exception(mocker): # Make the first call succeed, second call should fail. mock_read_s3_file = mocker.patch( - "app.aws.s3.read_s3_file", - side_effect=[None, Exception("exception here")] + "app.aws.s3.read_s3_file", side_effect=[None, Exception("exception here")] ) mock_thread_pool_executor = mocker.patch("app.aws.s3.ThreadPoolExecutor") diff --git a/tests/app/dao/notification_dao/test_notification_dao.py b/tests/app/dao/notification_dao/test_notification_dao.py index 44d55f1ce..4df57ec07 100644 --- a/tests/app/dao/notification_dao/test_notification_dao.py +++ b/tests/app/dao/notification_dao/test_notification_dao.py @@ -2136,7 +2136,9 @@ def test_sanitize_successful_notification_by_id(): ) -def test_dao_get_notifications_by_recipient_or_reference_covers_sms_search_by_reference(notify_db_session): +def test_dao_get_notifications_by_recipient_or_reference_covers_sms_search_by_reference( + notify_db_session, +): """ This test: 1. Creates a service and an SMS template. @@ -2153,7 +2155,7 @@ def test_dao_get_notifications_by_recipient_or_reference_covers_sms_search_by_re data = { "id": uuid.uuid4(), "to": "1", - "normalised_to": "1", # phone is irrelevant here + "normalised_to": "1", # phone is irrelevant here "service_id": service.id, "service": service, "template_id": template.id, diff --git a/tests/app/dao/test_fact_notification_status_dao.py b/tests/app/dao/test_fact_notification_status_dao.py index 5b9a7d695..083546464 100644 --- a/tests/app/dao/test_fact_notification_status_dao.py +++ b/tests/app/dao/test_fact_notification_status_dao.py @@ -36,7 +36,9 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): service_2 = create_service(service_name="service_2") create_template(service=service_1) - create_template(service=service_1, template_type=TemplateType.EMAIL) + template_email = create_template( + service=service_1, template_type=TemplateType.EMAIL + ) # not the service being tested create_template(service=service_2) @@ -50,11 +52,15 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): create_notification( service_1.templates[0], created_at=datetime(2018, 1, 1, 1, 1, 0) ) - create_notification( + questionable_notification = create_notification( service_1.templates[1], created_at=datetime(2018, 1, 1, 1, 1, 0), status=NotificationStatus.DELIVERED, ) + print( + f"QN status = {questionable_notification.status} type = {questionable_notification.notification_type}" + ) + create_notification( service_1.templates[0], created_at=datetime(2018, 2, 1, 1, 1, 0), @@ -85,6 +91,7 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): assert len(results) == 4 assert results[0].month.date() == date(2018, 1, 1) + assert results[0].template == template_email assert results[0].notification_type == NotificationType.EMAIL assert results[0].notification_status == NotificationStatus.DELIVERED assert results[0].count == 1 From c2a67915a8e0b8674cf5c5c4e6496814efbce7c2 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 3 Mar 2025 11:24:29 -0800 Subject: [PATCH 10/10] merge from main --- tests/app/dao/test_fact_notification_status_dao.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/app/dao/test_fact_notification_status_dao.py b/tests/app/dao/test_fact_notification_status_dao.py index 083546464..bad3a5162 100644 --- a/tests/app/dao/test_fact_notification_status_dao.py +++ b/tests/app/dao/test_fact_notification_status_dao.py @@ -36,9 +36,7 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): service_2 = create_service(service_name="service_2") create_template(service=service_1) - template_email = create_template( - service=service_1, template_type=TemplateType.EMAIL - ) + create_template(service=service_1, template_type=TemplateType.EMAIL) # not the service being tested create_template(service=service_2) @@ -49,9 +47,10 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): created_at=datetime(2018, 1, 1, 1, x, 0), status=NotificationStatus.DELIVERED, ) - create_notification( + whats_this = create_notification( service_1.templates[0], created_at=datetime(2018, 1, 1, 1, 1, 0) ) + print(f"WTN status = {whats_this.status} type = {whats_this.notification_type}") questionable_notification = create_notification( service_1.templates[1], created_at=datetime(2018, 1, 1, 1, 1, 0), @@ -91,7 +90,6 @@ def test_fetch_notification_status_for_service_by_month(notify_db_session): assert len(results) == 4 assert results[0].month.date() == date(2018, 1, 1) - assert results[0].template == template_email assert results[0].notification_type == NotificationType.EMAIL assert results[0].notification_status == NotificationStatus.DELIVERED assert results[0].count == 1