Commit d6046d78 by Clinton Blackburn

Fixed bug for courses without an honor mode

parent 2cbe6fde
......@@ -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.'
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.'
NO_HONOR_MODE = u'Course {course_id} does not have an honor mode.'
......@@ -237,7 +237,6 @@ class OrdersViewTests(ModuleStoreTestCase):
response = self._post_to_view()
# Validate the response
self._mock_ecommerce_api()
self.assertEqual(response.status_code, 200)
msg = Messages.NO_ECOM_API.format(username=self.user.username, course_id=self.course.id)
self.assertResponseMessage(response, msg)
......@@ -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
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
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):
if not valid:
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
ecommerce_api_url = getattr(settings, 'ECOMMERCE_API_URL', None)
ecommerce_api_signing_key = getattr(settings, 'ECOMMERCE_API_SIGNING_KEY', None)
if not (ecommerce_api_url and ecommerce_api_signing_key):
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)
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
headers = {
'Content-Type': 'application/json',
......@@ -111,7 +116,7 @@ class OrdersView(APIView):
try:
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)
except Exception as ex: # pylint: disable=broad-except
log.exception('Call to E-Commerce API failed: %s.', ex.message)
......@@ -143,7 +148,7 @@ class OrdersView(APIView):
'status': order_status,
'complete_status': OrderStatus.COMPLETE,
'username': user.username,
'course_id': unicode(course_key),
'course_id': course_id,
}
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