Skip to content

Commit

Permalink
fix: handled exception gracefully and returned proper response (#300)
Browse files Browse the repository at this point in the history
* fix: handled exception gracefully and returned proper response

* fix: liniting issues

* refactor: logged error and returned appropriate message

* refactor: updated log message

* test: added unit tests for graceful exception handling
  • Loading branch information
abdullahwaheed authored Nov 27, 2024
1 parent d33974a commit 2c8885a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class OrdersViewTests(TestCase):
test_user_username = 'test' # Different from ORDER_HISTORY_GET_PARAMETERS username.
test_user_email = '[email protected]'
test_user_password = 'secret'
url = reverse('frontend_app_ecommerce:order_history')

def setUp(self):
"""Create test user before test starts."""
Expand All @@ -69,7 +70,7 @@ def test_view_rejects_post(self, _mock_ctorders, _mock_ecommerce_client):
self.client.login(username=self.test_user_username, password=self.test_user_password)

# Perform POST
response = self.client.post(reverse('frontend_app_ecommerce:order_history'), ORDER_HISTORY_GET_PARAMETERS)
response = self.client.post(self.url, ORDER_HISTORY_GET_PARAMETERS)

# Check 405 Method Not Allowed
self.assertEqual(response.status_code, 405)
Expand All @@ -78,7 +79,7 @@ def test_view_rejects_unauthorized(self, _mock_ctorders, _mock_ecommerce_client)
"""Check unauthorized users querying orders are redirected to login page."""

# Perform GET without logging in.
response = self.client.get(reverse('frontend_app_ecommerce:order_history'), ORDER_HISTORY_GET_PARAMETERS)
response = self.client.get(self.url, ORDER_HISTORY_GET_PARAMETERS)

# Check 302 Found with redirect to login page.
self.assertEqual(response.status_code, 302)
Expand All @@ -91,7 +92,7 @@ def test_view_returns_ok(self, _mock_ctorders, _mock_ecommerce_client):
self.client.login(username=self.test_user_username, password=self.test_user_password)

# Perform GET
response = self.client.get(reverse('frontend_app_ecommerce:order_history'), ORDER_HISTORY_GET_PARAMETERS)
response = self.client.get(self.url, ORDER_HISTORY_GET_PARAMETERS)
# Check 200 OK
self.assertEqual(response.status_code, 200)

Expand All @@ -104,7 +105,7 @@ def test_view_returns_expected_ecommerce_response(self, is_redirect_mock, _mock_
self.client.login(username=self.test_user_username, password=self.test_user_password)

# Perform GET
response = self.client.get(reverse('frontend_app_ecommerce:order_history'), ORDER_HISTORY_GET_PARAMETERS)
response = self.client.get(self.url, ORDER_HISTORY_GET_PARAMETERS)

# Check expected response
self.assertEqual(response.json()['results'][1], ECOMMERCE_REQUEST_EXPECTED_RESPONSE['results'][0])
Expand All @@ -116,14 +117,33 @@ def test_view_passes_username(self, _mock_ctorders, mock_ecommerce_client):
self.client.login(username=self.test_user_username, password=self.test_user_password)

# Perform GET
self.client.get(reverse('frontend_app_ecommerce:order_history'), ORDER_HISTORY_GET_PARAMETERS)
self.client.get(self.url, ORDER_HISTORY_GET_PARAMETERS)

# Get username sent to ecommerce client
request_username = mock_ecommerce_client.call_args.args[0]['username']

# Check username is passed to ecommerce client
self.assertEqual(request_username, self.test_user_username)

@patch(
'commerce_coordinator.apps.commercetools.pipeline.GetCommercetoolsOrders.run_filter',
side_effect=Exception('Something went wrong')
)
def test_view_crashes_with_some_error(self, _mock_pipeline, _mock_ctorders, _mock_ecommerce_client):
"""Check exception is handled gracefully if pipeline crashes."""

# Login
self.client.login(username=self.test_user_username, password=self.test_user_password)

# Perform GET request
response = self.client.get(self.url, ORDER_HISTORY_GET_PARAMETERS)

# Assert the response status is 400
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

# Assert the response content matches the error message
self.assertEqual(response.data, 'Something went wrong!')


@ddt.ddt
class ReceiptRedirectViewTests(APITestCase):
Expand Down
29 changes: 17 additions & 12 deletions commerce_coordinator/apps/frontend_app_ecommerce/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from edx_rest_framework_extensions.permissions import LoginRedirectIfUnauthenticated
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from rest_framework.status import HTTP_303_SEE_OTHER
from rest_framework.status import HTTP_303_SEE_OTHER, HTTP_400_BAD_REQUEST
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

Expand Down Expand Up @@ -94,18 +94,23 @@ def get(self, request):
if not request.user.lms_user_id: # pragma: no cover
raise PermissionDenied(detail="Could not detect LMS user id.")

order_data = OrderHistoryRequested.run_filter(request, params)
try:
order_data = OrderHistoryRequested.run_filter(request, params)

output_orders = []
output_orders = []

for order_set in order_data:
output_orders.extend(order_set['results'])
for order_set in order_data:
output_orders.extend(order_set['results'])

output = {
"count": request.query_params['page_size'], # This suppresses the ecomm mfe Order History Pagination ctrl
"next": None,
"previous": None,
"results": sorted(output_orders, key=lambda item: date_conv(item["date_placed"]), reverse=True)
}
output = {
# This suppresses the ecomm mfe Order History Pagination control
"count": request.query_params['page_size'],
"next": None,
"previous": None,
"results": sorted(output_orders, key=lambda item: date_conv(item["date_placed"]), reverse=True)
}

return Response(output)
return Response(output)
except Exception as exc: # pylint: disable=broad-except
logger.error(f'[UserOrdersView] An error occured while fetching Order History.\n Data: [{exc}]')
return Response(status=HTTP_400_BAD_REQUEST, data='Something went wrong!')

0 comments on commit 2c8885a

Please sign in to comment.