Commit d6046d78 by Clinton Blackburn

Fixed bug for courses without an honor mode

parent 2cbe6fde
...@@ -19,3 +19,4 @@ class Messages(object): ...@@ -19,3 +19,4 @@ class Messages(object):
NO_SKU_ENROLLED = u'The {enrollment_mode} mode for {course_id} does not have a SKU. Enrolling {username} directly.' NO_SKU_ENROLLED = u'The {enrollment_mode} mode for {course_id} does not have a SKU. Enrolling {username} directly.'
ORDER_COMPLETED = u'Order {order_number} was completed.' ORDER_COMPLETED = u'Order {order_number} was completed.'
ORDER_INCOMPLETE_ENROLLED = u'Order {order_number} was created, but is not yet complete. User was enrolled.' ORDER_INCOMPLETE_ENROLLED = u'Order {order_number} was created, but is not yet complete. User was enrolled.'
NO_HONOR_MODE = u'Course {course_id} does not have an honor mode.'
...@@ -237,7 +237,6 @@ class OrdersViewTests(ModuleStoreTestCase): ...@@ -237,7 +237,6 @@ class OrdersViewTests(ModuleStoreTestCase):
response = self._post_to_view() response = self._post_to_view()
# Validate the response # Validate the response
self._mock_ecommerce_api()
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
msg = Messages.NO_ECOM_API.format(username=self.user.username, course_id=self.course.id) msg = Messages.NO_ECOM_API.format(username=self.user.username, course_id=self.course.id)
self.assertResponseMessage(response, msg) self.assertResponseMessage(response, msg)
...@@ -245,3 +244,29 @@ class OrdersViewTests(ModuleStoreTestCase): ...@@ -245,3 +244,29 @@ class OrdersViewTests(ModuleStoreTestCase):
# Ensure that the user is not enrolled and that no calls were made to the E-Commerce API # Ensure that the user is not enrolled and that no calls were made to the E-Commerce API
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
self.assertIsInstance(httpretty.last_request(), HTTPrettyRequestEmpty) self.assertIsInstance(httpretty.last_request(), HTTPrettyRequestEmpty)
def _test_professional_mode_only(self):
""" Verifies that the view behaves appropriately when the course only has a professional mode. """
CourseMode.objects.filter(course_id=self.course.id).delete()
mode = 'no-id-professional'
CourseModeFactory.create(course_id=self.course.id, mode_slug=mode, mode_display_name=mode,
sku=uuid4().hex.decode('ascii'))
self._mock_ecommerce_api()
response = self._post_to_view()
self.assertEqual(response.status_code, 406)
msg = Messages.NO_HONOR_MODE.format(course_id=self.course.id)
self.assertResponseMessage(response, msg)
@httpretty.activate
def test_course_with_professional_mode_only(self):
""" Verifies that the view behaves appropriately when the course only has a professional mode. """
self._test_professional_mode_only()
@httpretty.activate
@override_settings(ECOMMERCE_API_URL=None, ECOMMERCE_API_SIGNING_KEY=None)
def test_no_settings_and_professional_mode_only(self):
"""
Verifies that the view behaves appropriately when the course only has a professional mode and
the E-Commerce API is not configured.
"""
self._test_professional_mode_only()
...@@ -79,28 +79,33 @@ class OrdersView(APIView): ...@@ -79,28 +79,33 @@ class OrdersView(APIView):
if not valid: if not valid:
return DetailResponse(error, status=HTTP_406_NOT_ACCEPTABLE) return DetailResponse(error, status=HTTP_406_NOT_ACCEPTABLE)
# Ensure that the course has an honor mode with SKU
honor_mode = CourseMode.mode_for_course(course_key, CourseMode.HONOR)
course_id = unicode(course_key)
# If there is no honor course mode, this most likely a Prof-Ed course. Return an error so that the JS
# redirects to track selection.
if not honor_mode:
msg = Messages.NO_HONOR_MODE.format(course_id=course_id)
return DetailResponse(msg, status=HTTP_406_NOT_ACCEPTABLE)
elif not honor_mode.sku:
# If there are no course modes with SKUs, enroll the user without contacting the external API.
msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode=CourseMode.HONOR, course_id=course_id,
username=user.username)
log.debug(msg)
self._enroll(course_key, user)
return DetailResponse(msg)
# Ensure that the E-Commerce API is setup properly # Ensure that the E-Commerce API is setup properly
ecommerce_api_url = getattr(settings, 'ECOMMERCE_API_URL', None) ecommerce_api_url = getattr(settings, 'ECOMMERCE_API_URL', None)
ecommerce_api_signing_key = getattr(settings, 'ECOMMERCE_API_SIGNING_KEY', None) ecommerce_api_signing_key = getattr(settings, 'ECOMMERCE_API_SIGNING_KEY', None)
if not (ecommerce_api_url and ecommerce_api_signing_key): if not (ecommerce_api_url and ecommerce_api_signing_key):
self._enroll(course_key, user) self._enroll(course_key, user)
msg = Messages.NO_ECOM_API.format(username=user.username, course_id=unicode(course_key)) msg = Messages.NO_ECOM_API.format(username=user.username, course_id=course_id)
log.debug(msg) log.debug(msg)
return DetailResponse(msg) return DetailResponse(msg)
# Default to honor mode. In the future we may expand this view to support additional modes.
mode = CourseMode.DEFAULT_MODE_SLUG
course_modes = CourseMode.objects.filter(course_id=course_key, mode_slug=mode, sku__isnull=False)
# If there are no course modes with SKUs, enroll the user without contacting the external API.
if not course_modes.exists():
msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode=mode, course_id=unicode(course_key),
username=user.username)
log.debug(msg)
self._enroll(course_key, user)
return DetailResponse(msg)
# Contact external API # Contact external API
headers = { headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...@@ -111,7 +116,7 @@ class OrdersView(APIView): ...@@ -111,7 +116,7 @@ class OrdersView(APIView):
try: try:
timeout = getattr(settings, 'ECOMMERCE_API_TIMEOUT', 5) timeout = getattr(settings, 'ECOMMERCE_API_TIMEOUT', 5)
response = requests.post(url, data=json.dumps({'sku': course_modes[0].sku}), headers=headers, response = requests.post(url, data=json.dumps({'sku': honor_mode.sku}), headers=headers,
timeout=timeout) timeout=timeout)
except Exception as ex: # pylint: disable=broad-except except Exception as ex: # pylint: disable=broad-except
log.exception('Call to E-Commerce API failed: %s.', ex.message) log.exception('Call to E-Commerce API failed: %s.', ex.message)
...@@ -143,7 +148,7 @@ class OrdersView(APIView): ...@@ -143,7 +148,7 @@ class OrdersView(APIView):
'status': order_status, 'status': order_status,
'complete_status': OrderStatus.COMPLETE, 'complete_status': OrderStatus.COMPLETE,
'username': user.username, 'username': user.username,
'course_id': unicode(course_key), 'course_id': course_id,
} }
log.error(msg, msg_kwargs) log.error(msg, msg_kwargs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment