From 01c6c336f462a9e7d685da179d82c98c355db7a7 Mon Sep 17 00:00:00 2001 From: Syed Sajjad Hussain Shah Date: Wed, 4 Dec 2024 13:44:36 +0500 Subject: [PATCH] fix: handle final review --- .../apps/commercetools/tests/test_utils.py | 57 ++++++++++++++++++- .../apps/commercetools/utils.py | 6 +- commerce_coordinator/apps/lms/tasks.py | 27 ++++----- .../apps/lms/tests/test_tasks.py | 2 +- commerce_coordinator/settings/base.py | 2 +- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/commerce_coordinator/apps/commercetools/tests/test_utils.py b/commerce_coordinator/apps/commercetools/tests/test_utils.py index a0c30dec..3603d318 100644 --- a/commerce_coordinator/apps/commercetools/tests/test_utils.py +++ b/commerce_coordinator/apps/commercetools/tests/test_utils.py @@ -28,7 +28,8 @@ has_full_refund_transaction, has_refund_transaction, send_order_confirmation_email, - translate_stripe_refund_status_to_transaction_status + send_unsupported_mode_fulfillment_error_email, + translate_stripe_refund_status_to_transaction_status, ) @@ -126,6 +127,60 @@ def test_send_order_confirmation_email_failure(self, mock_logger, mock_get_braze mock_logger.assert_called_once_with('Encountered exception sending Order confirmation email. ' 'Exception: Error sending Braze email') + @override_settings( + BRAZE_API_KEY="braze_api_key", + BRAZE_API_SERVER="braze_api_server", + BRAZE_CT_FULFILLMENT_UNSUPPORTED_MODE_ERROR_CANVAS_ID="dummy_canvas" + ) + @patch('commerce_coordinator.apps.commercetools.utils.get_braze_client') + def test_send_unsupported_mode_fulfillment_error_email_success(self, mock_get_braze_client): + mock_braze_client = Mock() + mock_get_braze_client.return_value = mock_braze_client + + canvas_entry_properties = {} + lms_user_id = 'user123' + lms_user_email = 'user@example.com' + + with patch.object(mock_braze_client, 'send_canvas_message') as mock_send_canvas_message: + send_unsupported_mode_fulfillment_error_email( + lms_user_id, lms_user_email, canvas_entry_properties + ) + + mock_send_canvas_message.assert_called_once_with( + canvas_id='dummy_canvas', + recipients=[{"external_user_id": lms_user_id, "attributes": {"email": lms_user_email}}], + canvas_entry_properties=canvas_entry_properties, + ) + + @override_settings( + BRAZE_API_KEY="braze_api_key", + BRAZE_API_SERVER="braze_api_server", + BRAZE_CT_FULFILLMENT_UNSUPPORTED_MODE_ERROR_CANVAS_ID="dummy_canvas" + ) + @patch('commerce_coordinator.apps.commercetools.utils.get_braze_client') + @patch('commerce_coordinator.apps.commercetools.utils.logger.exception') + def test_send_unsupported_mode_fulfillment_error_email_failure(self, mock_logger, mock_get_braze_client): + mock_braze_client = Mock() + mock_get_braze_client.return_value = mock_braze_client + + canvas_entry_properties = {} + lms_user_id = 'user123' + lms_user_email = 'user@example.com' + + with patch.object(mock_braze_client, 'send_canvas_message') as mock_send_canvas_message: + mock_send_canvas_message.side_effect = Exception('Error sending Braze email') + send_unsupported_mode_fulfillment_error_email( + lms_user_id, lms_user_email, canvas_entry_properties + ) + + mock_send_canvas_message.assert_called_once_with( + canvas_id='dummy_canvas', + recipients=[{"external_user_id": lms_user_id, "attributes": {"email": lms_user_email}}], + canvas_entry_properties=canvas_entry_properties, + ) + mock_logger.assert_called_once_with('Encountered exception sending Fulfillment unsupported mode error ' + 'email. Exception: Error sending Braze email') + def test_extract_ct_product_information_for_braze_canvas(self): order = gen_order(EXAMPLE_FULFILLMENT_SIGNAL_PAYLOAD['order_number']) line_item = order.line_items[0] diff --git a/commerce_coordinator/apps/commercetools/utils.py b/commerce_coordinator/apps/commercetools/utils.py index 49a0b239..f7e8b415 100644 --- a/commerce_coordinator/apps/commercetools/utils.py +++ b/commerce_coordinator/apps/commercetools/utils.py @@ -65,14 +65,14 @@ def send_order_confirmation_email( logger.exception(f"Encountered exception sending Order confirmation email. Exception: {exc}") -def send_fulfillment_error_email( +def send_unsupported_mode_fulfillment_error_email( lms_user_id, lms_user_email, canvas_entry_properties ): """ Sends fulfillment error email via Braze. """ recipients = [{"external_user_id": lms_user_id, "attributes": { "email": lms_user_email, }}] - canvas_id = settings.BRAZE_CT_FULFILLMENT_ERROR_CANVAS_ID + canvas_id = settings.BRAZE_CT_FULFILLMENT_UNSUPPORTED_MODE_ERROR_CANVAS_ID try: braze_client = get_braze_client() @@ -83,7 +83,7 @@ def send_fulfillment_error_email( canvas_entry_properties=canvas_entry_properties, ) except Exception as exc: # pylint: disable=broad-exception-caught - logger.exception(f"Encountered exception sending Fulfillment Error email. Exception: {exc}") + logger.exception(f"Encountered exception sending Fulfillment unsupported mode error email. Exception: {exc}") def format_amount_for_braze_canvas(centAmount): diff --git a/commerce_coordinator/apps/lms/tasks.py b/commerce_coordinator/apps/lms/tasks.py index ecf26669..d98b998e 100644 --- a/commerce_coordinator/apps/lms/tasks.py +++ b/commerce_coordinator/apps/lms/tasks.py @@ -12,7 +12,7 @@ from commerce_coordinator.apps.commercetools.catalog_info.constants import TwoUKeys from commerce_coordinator.apps.commercetools.clients import CommercetoolsAPIClient -from commerce_coordinator.apps.commercetools.utils import send_fulfillment_error_email +from commerce_coordinator.apps.commercetools.utils import send_unsupported_mode_fulfillment_error_email from commerce_coordinator.apps.lms.clients import LMSAPIClient # Use the special Celery logger for our tasks @@ -34,39 +34,36 @@ def on_failure(self, exc, task_id, args, kwargs, einfo): error_message = ( json.loads(exc.response.text).get('message', '') - if hasattr(exc, 'response') and exc.response is not None + if isinstance(exc, RequestException) and exc.response is not None else str(exc) ) logger.error( - f"Task {self.name} failed after max retries with error message: {error_message} " - f"for user with User Id: {edx_lms_user_id}, Email: {user_email}, " - f"Order Number: {order_number}, Course Title: {course_title}" + f"Post-purchase fulfillment task {self.name} failed after max " + f"retries with the error message: {error_message} " + f"for user with user Id: {edx_lms_user_id}, email: {user_email}, " + f"order number: {order_number}, and course Title: {course_title}" ) # This error is returned from LMS if the course mode is unsupported # https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/enrollments/views.py#L870 course_mode_expired_error = "course mode is expired or otherwise unavailable for course run" - if ( - self.request.retries >= self.max_retries - and course_mode_expired_error in error_message - ): - + if course_mode_expired_error in error_message: logger.info( - f"Sending Fulfillment Error Email for user with " - f"User ID: {edx_lms_user_id}, Email: {user_email}, " - f"Order Number: {order_number}, Course Title: {course_title}" + f"Sending unsupported course mode fulfillment error email " + f"for the user with user ID: {edx_lms_user_id}, email: {user_email}, " + f"order number: {order_number}, and course title: {course_title}" ) canvas_entry_properties = { 'order_number': order_number, - 'product_type': 'course', + 'product_type': 'course', # TODO: Fetch product type from commercetools product object 'product_name': course_title, 'first_name': user_first_name, } # Send failure notification email - send_fulfillment_error_email(edx_lms_user_id, user_email, canvas_entry_properties) + send_unsupported_mode_fulfillment_error_email(edx_lms_user_id, user_email, canvas_entry_properties) @shared_task( diff --git a/commerce_coordinator/apps/lms/tests/test_tasks.py b/commerce_coordinator/apps/lms/tests/test_tasks.py index 5a0df4de..120bd07a 100644 --- a/commerce_coordinator/apps/lms/tests/test_tasks.py +++ b/commerce_coordinator/apps/lms/tests/test_tasks.py @@ -134,7 +134,7 @@ def test_retry_logic(self, mock_ct_get_order, mock_ct_get_state, mock_client): mock_ct_get_state.assert_called_with(TwoUKeys.FAILURE_FULFILMENT_STATE) mock_ct_get_order.assert_called_with(EXAMPLE_FULFILLMENT_SIGNAL_PAYLOAD.get('order_id')) - @patch('commerce_coordinator.apps.lms.tasks.send_fulfillment_error_email') + @patch('commerce_coordinator.apps.lms.tasks.send_unsupported_mode_fulfillment_error_email') @patch.object(fulfill_order_placed_send_enroll_in_course_task, 'max_retries', 5) def test_fulfillment_error_email_is_sent_on_failure( self, mock_send_email, mock_client diff --git a/commerce_coordinator/settings/base.py b/commerce_coordinator/settings/base.py index a51d87cb..de5d3b0f 100644 --- a/commerce_coordinator/settings/base.py +++ b/commerce_coordinator/settings/base.py @@ -468,7 +468,7 @@ def root(*path_fragments): BRAZE_API_KEY = None BRAZE_API_SERVER = None BRAZE_CT_ORDER_CONFIRMATION_CANVAS_ID = '' -BRAZE_CT_FULFILLMENT_ERROR_CANVAS_ID = '' +BRAZE_CT_FULFILLMENT_UNSUPPORTED_MODE_ERROR_CANVAS_ID = '' # SEGMENT WRITE KEY SEGMENT_KEY = None