From ca5ab52c5ad3035dadd691e37ff407c4b48d2687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrey=20Ca=C3=B1on?= <36200299+andrey-canon@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:41:25 -0500 Subject: [PATCH] feat: raise exception on api response error (#215) --- eox_nelp/pearson_vue/tasks.py | 9 +++++--- eox_nelp/pearson_vue/tests/test_tasks.py | 26 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/eox_nelp/pearson_vue/tasks.py b/eox_nelp/pearson_vue/tasks.py index 5bea8931..e8e562ab 100644 --- a/eox_nelp/pearson_vue/tasks.py +++ b/eox_nelp/pearson_vue/tasks.py @@ -4,9 +4,9 @@ Functions: real_time_import_task(data: dict) -> None: Performs an asynchronous call to the RTI service. """ - from celery import shared_task from django.contrib.auth import get_user_model +from requests import exceptions from eox_nelp.api_clients.pearson_engine import PearsonEngineApiClient from eox_nelp.pearson_vue.constants import ALLOWED_RTI_ACTIONS @@ -101,7 +101,7 @@ def rti_error_handler_task(self, pipeline_index=0, **kwargs): self.retry(exc=exc, kwargs=error_rti.backend_data) -@shared_task +@shared_task(autoretry_for=(exceptions.Timeout, exceptions.ConnectionError), retry_backoff=5) def real_time_import_task_v2(user_id, exam_id=None, action_name="rti", **kwargs): """ Asynchronous task to perform a real-time import action using the Pearson Engine API. @@ -131,10 +131,13 @@ def real_time_import_task_v2(user_id, exam_id=None, action_name="rti", **kwargs) def audit_pearson_engine_action(user_id, exam_id, action_key, **kwargs): action = getattr(PearsonEngineApiClient(), action_key) - action( + response = action( user=User.objects.get(id=user_id), exam_id=exam_id, **kwargs ) + if response.get("error"): + raise Exception(response.get("message", "Unknown error")) # pylint: disable=broad-exception-raised + audit_pearson_engine_action(user_id, exam_id, action_key, **kwargs) diff --git a/eox_nelp/pearson_vue/tests/test_tasks.py b/eox_nelp/pearson_vue/tests/test_tasks.py index 11657d01..54d81d8a 100644 --- a/eox_nelp/pearson_vue/tests/test_tasks.py +++ b/eox_nelp/pearson_vue/tests/test_tasks.py @@ -126,6 +126,7 @@ def test_real_time_import_rti(self, mock_api_client): - The real_time_import method is called with the correct parameters. """ mock_action = MagicMock() + mock_action.return_value = {"error": False} mock_api_client.return_value = MagicMock(**{"real_time_import": mock_action}) real_time_import_task_v2(self.user.id, action_name="rti", **self.kwargs) @@ -140,6 +141,7 @@ def test_real_time_import_cdd(self, mock_api_client): - The import_candidate_demographics method is called with the correct parameters. """ mock_action = MagicMock() + mock_action.return_value = {"error": False} mock_api_client.return_value = MagicMock(**{"import_candidate_demographics": mock_action}) real_time_import_task_v2(self.user.id, action_name="cdd", **self.kwargs) @@ -154,6 +156,7 @@ def test_real_time_import_ead(self, mock_api_client): - The import_exam_authorization method is called with the correct parameters. """ mock_action = MagicMock() + mock_action.return_value = {"error": False} mock_api_client.return_value = MagicMock(**{"import_exam_authorization": mock_action}) real_time_import_task_v2(self.user.id, exam_id=self.exam_id, action_name="ead", **self.kwargs) @@ -178,3 +181,26 @@ def test_real_time_import_user_not_found(self, mock_api_client): # pylint: disa """ with self.assertRaises(User.DoesNotExist): real_time_import_task_v2(12345678, action_name="rti") + + @patch("eox_nelp.pearson_vue.tasks.PearsonEngineApiClient") + def test_raise_exception_on_error_response(self, mock_api_client): + """Test that an exception is raised when the API response contains an Error. + + Expected behavior: + - The exception is raised. + - The action method is called with the correct parameters. + - Exception contains the expected message. + """ + mock_action = MagicMock() + expected_message = "Timeout error" + mock_action.return_value = { + "error": True, + "message": expected_message, + } + mock_api_client.return_value = MagicMock(**{"real_time_import": mock_action}) + + with self.assertRaises(Exception) as context: + real_time_import_task_v2(self.user.id, action_name="rti", **self.kwargs) + + mock_action.assert_called_once_with(user=self.user, exam_id=None, **self.kwargs) + self.assertEqual(expected_message, str(context.exception))