From 3c9b399314cf2999488f7c0426ae50530c0ff533 Mon Sep 17 00:00:00 2001 From: Syed Hassan Raza Date: Thu, 4 Aug 2016 16:22:16 +0500 Subject: [PATCH] Handle MultipleObjectsReturned exception for dashboardpage --- common/djangoapps/student/models.py | 11 ++++++- .../djangoapps/student/tests/test_refunds.py | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index bbf6cd8480..9aaf91a745 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -34,7 +34,7 @@ from django.db import models, IntegrityError, transaction from django.db.models import Count from django.db.models.signals import pre_save, post_save from django.dispatch import receiver, Signal -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.utils.translation import ugettext_noop from django.core.cache import cache from django_countries.fields import CountryField @@ -1503,6 +1503,15 @@ class CourseEnrollment(models.Model): attribute = self.attributes.get(namespace='order', name='order_number') except ObjectDoesNotExist: return None + except MultipleObjectsReturned: + # If there are multiple attributes then return the last one. + enrollment_id = self.get_enrollment(self.user, self.course_id).id + log.warning( + u"Multiple CourseEnrollmentAttributes found for user %s with enrollment-ID %s", + self.user.id, + enrollment_id + ) + attribute = self.attributes.filter(namespace='order', name='order_number').last() order_number = attribute.value order = ecommerce_api_client(self.user).orders(order_number).get() diff --git a/common/djangoapps/student/tests/test_refunds.py b/common/djangoapps/student/tests/test_refunds.py index 330be06ad0..6e8e568489 100644 --- a/common/djangoapps/student/tests/test_refunds.py +++ b/common/djangoapps/student/tests/test_refunds.py @@ -170,3 +170,32 @@ class RefundableTest(SharedModuleStoreTestCase): def test_refund_cutoff_date_no_attributes(self): """ Assert that the None is returned when no order number attribute is found.""" self.assertIsNone(self.enrollment.refund_cutoff_date()) + + @httpretty.activate + @override_settings(ECOMMERCE_API_SIGNING_KEY=TEST_API_SIGNING_KEY, ECOMMERCE_API_URL=TEST_API_URL) + def test_multiple_refunds_dashbaord_page_error(self): + """ Order with mutiple refunds will not throw 500 error when dashboard page will access.""" + now = datetime.now(pytz.UTC).replace(microsecond=0) + order_date = now + timedelta(days=1) + order_number = 'OSCR-1000' + expected_content = '{{"date_placed": "{date}"}}'.format(date=order_date.strftime(ECOMMERCE_DATE_FORMAT)) + + httpretty.register_uri( + httpretty.GET, + '{url}/orders/{order}/'.format(url=TEST_API_URL, order=order_number), + status=200, body=expected_content, + adding_headers={'Content-Type': JSON} + ) + + # creating multiple attributes for same order. + for attribute_count in range(2): # pylint: disable=unused-variable + self.enrollment.attributes.add(CourseEnrollmentAttribute( + enrollment=self.enrollment, + namespace='order', + name='order_number', + value=order_number + )) + + self.client.login(username="jack", password="test") + resp = self.client.post(reverse('student.views.dashboard', args=[])) + self.assertEqual(resp.status_code, 200)