From b4c66f57d20a7d28b73b14f5c0b09b16038a8e71 Mon Sep 17 00:00:00 2001 From: stephensanchez Date: Wed, 28 Jan 2015 22:11:50 +0000 Subject: [PATCH] Fix the redemption codes to allow upgrading course modes. --- .../shoppingcart/tests/test_views.py | 27 +++++++++++++++++++ lms/djangoapps/shoppingcart/views.py | 26 ++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py index d5402724ee..a729f18e05 100644 --- a/lms/djangoapps/shoppingcart/tests/test_views.py +++ b/lms/djangoapps/shoppingcart/tests/test_views.py @@ -550,6 +550,33 @@ class ShoppingCartViewsTests(ModuleStoreTestCase): self.assertEqual(resp.status_code, 400) self.assertIn("Oops! The code '{0}' you entered is either invalid or expired".format(self.reg_code), resp.content) + def test_upgrade_from_valid_reg_code(self): + """Use a valid registration code to upgrade from honor to verified mode. """ + # Ensure the course has a verified mode + course_key = self.course_key.to_deprecated_string() + self._add_course_mode(mode_slug='verified') + self.add_reg_code(course_key, mode_slug='verified') + + # Enroll as honor in the course with the current user. + CourseEnrollment.enroll(self.user, self.course_key) + self.login_user() + current_enrollment, __ = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key) + self.assertEquals('honor', current_enrollment) + + redeem_url = reverse('register_code_redemption', args=[self.reg_code]) + response = self.client.get(redeem_url) + self.assertEquals(response.status_code, 200) + # check button text + self.assertTrue('Activate Course Enrollment' in response.content) + + #now activate the user by enrolling him/her to the course + response = self.client.post(redeem_url) + self.assertEquals(response.status_code, 200) + + # Once upgraded, should be "verified" + current_enrollment, __ = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key) + self.assertEquals('verified', current_enrollment) + @patch('shoppingcart.views.log.debug') def test_non_existing_coupon_redemption_on_removing_item(self, debug_log): diff --git a/lms/djangoapps/shoppingcart/views.py b/lms/djangoapps/shoppingcart/views.py index 8ed9666922..c4173510ae 100644 --- a/lms/djangoapps/shoppingcart/views.py +++ b/lms/djangoapps/shoppingcart/views.py @@ -24,7 +24,6 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locator import CourseLocator from opaque_keys import InvalidKeyError from courseware.courses import get_course_by_id -from courseware.views import registered_for_course from config_models.decorators import require_config from shoppingcart.reports import RefundReport, ItemizedPurchaseReport, UniversityRevenueShareReport, CertificateStatusReport from student.models import CourseEnrollment, EnrollmentClosedError, CourseFullError, \ @@ -345,7 +344,7 @@ def register_code_redemption(request, registration_code): 'reg_code': registration_code, 'site_name': site_name, 'course': course, - 'registered_for_course': registered_for_course(course, request.user) + 'registered_for_course': not _is_enrollment_code_an_update(course, request.user, course_registration) } return render_to_response(template_to_render, context) elif request.method == "POST": @@ -401,6 +400,29 @@ def register_code_redemption(request, registration_code): return render_to_response(template_to_render, context) +def _is_enrollment_code_an_update(course, user, redemption_code): + """Checks to see if the user's enrollment can be updated by the code. + + Check to see if the enrollment code and the user's enrollment match. If they are different, the code + may be used to alter the enrollment of the user. If the enrollment is inactive, will return True, since + the user may use the code to re-activate an enrollment as well. + + Enrollment redemption codes must be associated with a paid course mode. If the current enrollment is a + different mode then the mode associated with the code, use of the code can be considered an upgrade. + + Args: + course (CourseDescriptor): The course to check for enrollment. + user (User): The user that will be using the redemption code. + redemption_code (CourseRegistrationCode): The redemption code that will be used to update the user's enrollment. + + Returns: + True if the redemption code can be used to upgrade the enrollment, or re-activate it. + + """ + enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course.id) + return not is_active or enrollment_mode != redemption_code.mode_slug + + def use_registration_code(course_reg, user): """ This method utilize course registration code.