Skip to content

Commit

Permalink
Check if a service callback api is suspended before sending (#2280)
Browse files Browse the repository at this point in the history
- Added some typing
  • Loading branch information
whabanks authored Sep 3, 2024
1 parent 84c3ecb commit 8b7db3a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
8 changes: 4 additions & 4 deletions app/dao/service_callback_api_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,20 @@ def reset_service_callback_api(service_callback_api, updated_by_id, url=None, be
db.session.add(service_callback_api)


def get_service_callback_api_with_service_id(service_id):
def get_service_callback_api_with_service_id(service_id) -> ServiceCallbackApi:
# There is ONLY one callback configured per service
return ServiceCallbackApi.query.filter_by(service_id=service_id).all()


def get_service_callback_api(service_callback_api_id, service_id):
def get_service_callback_api(service_callback_api_id, service_id) -> ServiceCallbackApi:
return ServiceCallbackApi.query.filter_by(id=service_callback_api_id, service_id=service_id).first()


def get_service_delivery_status_callback_api_for_service(service_id):
def get_service_delivery_status_callback_api_for_service(service_id) -> ServiceCallbackApi:
return ServiceCallbackApi.query.filter_by(service_id=service_id, callback_type=DELIVERY_STATUS_CALLBACK_TYPE).first()


def get_service_complaint_callback_api_for_service(service_id):
def get_service_complaint_callback_api_for_service(service_id) -> ServiceCallbackApi:
return ServiceCallbackApi.query.filter_by(service_id=service_id, callback_type=COMPLAINT_CALLBACK_TYPE).first()


Expand Down
10 changes: 9 additions & 1 deletion app/notifications/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ def _check_and_queue_callback_task(notification):
if notification is None:
current_app.logger.warning("No notification provided, cannot queue callback task")
return
# queue callback task only if the service_callback_api exists

service_callback_api = get_service_delivery_status_callback_api_for_service(service_id=notification.service_id)

# queue callback task only if the service_callback_api exists and it is not in a suspended state
if service_callback_api:
if service_callback_api.is_suspended:
current_app.logger.warning(
f"Service callback API: {service_callback_api.id} for service: {notification.service_id} is suspended. Cannot queue callback task for notification: {notification.id}"
)
return

notification_data = create_delivery_status_callback_data(notification, service_callback_api)
send_delivery_status_to_service.apply_async([str(notification.id), notification_data], queue=QueueNames.CALLBACKS)

Expand Down
2 changes: 2 additions & 0 deletions tests/app/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,14 @@ def create_service_inbound_api(
def create_service_callback_api(
service,
url="https://something.com",
is_suspended=False,
bearer_token="some_super_secret",
callback_type="delivery_status",
):
service_callback_api = ServiceCallbackApi(
service_id=service.id,
url=url,
is_suspended=is_suspended,
bearer_token=bearer_token,
updated_by_id=service.users[0].id,
callback_type=callback_type,
Expand Down
52 changes: 52 additions & 0 deletions tests/app/notifications/test_callbacks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from datetime import datetime
from unittest.mock import patch

from app import DATETIME_FORMAT, signer_complaint, signer_delivery_status
from app.notifications.callbacks import (
_check_and_queue_callback_task,
create_complaint_callback_data,
create_delivery_status_callback_data,
)
Expand Down Expand Up @@ -65,3 +67,53 @@ def test_create_complaint_callback_data(
"service_callback_api_url": callback_api.url,
"service_callback_api_bearer_token": callback_api.bearer_token,
}


def test_check_and_queue_callback_task_calls_delivery_task(
notify_db,
notify_db_session,
sample_email_template,
):
notification = create_sample_notification(
notify_db,
notify_db_session,
template=sample_email_template,
status="sending",
)
callback_api = create_service_callback_api(service=sample_email_template.service, url="https://original_url.com")

with patch("app.notifications.callbacks.send_delivery_status_to_service.apply_async") as mock_apply_async:
_check_and_queue_callback_task(notification)

mock_apply_async.assert_called_once_with(
[str(notification.id), create_delivery_status_callback_data(notification, callback_api)],
queue="service-callbacks",
)


def test_check_and_queue_callback_task_does_not_call_delivery_task_when_service_callback_api_is_suspended(
notify_db,
notify_db_session,
sample_email_template,
):
notification = create_sample_notification(
notify_db,
notify_db_session,
template=sample_email_template,
status="sending",
)
create_service_callback_api(service=sample_email_template.service, url="https://original_url.com", is_suspended=True)

with patch("app.notifications.callbacks.send_delivery_status_to_service.apply_async") as mock_apply_async:
_check_and_queue_callback_task(notification)
mock_apply_async.assert_not_called()


def test_check_and_queue_callback_task_does_not_call_delivery_task_when_notification_is_empty(
sample_email_template,
):
create_service_callback_api(service=sample_email_template.service, url="https://original_url.com", is_suspended=True)

with patch("app.notifications.callbacks.send_delivery_status_to_service.apply_async") as mock_apply_async:
_check_and_queue_callback_task(None)
mock_apply_async.assert_not_called()

0 comments on commit 8b7db3a

Please sign in to comment.