diff --git a/common/djangoapps/course_modes/admin.py b/common/djangoapps/course_modes/admin.py index 6781227f5c..8356f9134d 100644 --- a/common/djangoapps/course_modes/admin.py +++ b/common/djangoapps/course_modes/admin.py @@ -39,7 +39,9 @@ class CourseModeForm(forms.ModelForm): [(CourseMode.DEFAULT_MODE_SLUG, CourseMode.DEFAULT_MODE_SLUG)] + [(mode_slug, mode_slug) for mode_slug in CourseMode.VERIFIED_MODES] + [(CourseMode.NO_ID_PROFESSIONAL_MODE, CourseMode.NO_ID_PROFESSIONAL_MODE)] + - [(mode_slug, mode_slug) for mode_slug in CourseMode.CREDIT_MODES] + [(mode_slug, mode_slug) for mode_slug in CourseMode.CREDIT_MODES] + + # need to keep legacy modes around for awhile + [(CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG)] ) mode_slug = forms.ChoiceField(choices=COURSE_MODE_SLUG_CHOICES, label=_("Mode")) diff --git a/common/djangoapps/course_modes/models.py b/common/djangoapps/course_modes/models.py index 4402a3e00a..022de21c21 100644 --- a/common/djangoapps/course_modes/models.py +++ b/common/djangoapps/course_modes/models.py @@ -114,6 +114,13 @@ class CourseMode(models.Model): # Modes that are allowed to upsell UPSELL_TO_VERIFIED_MODES = [HONOR, AUDIT] + # Courses purchased through the shoppingcart + # should be "honor". Since we've changed the DEFAULT_MODE_SLUG from + # "honor" to "audit", we still need to have the shoppingcart + # use "honor" + DEFAULT_SHOPPINGCART_MODE_SLUG = HONOR + DEFAULT_SHOPPINGCART_MODE = Mode(HONOR, _('Honor'), 0, '', 'usd', None, None, None) + class Meta(object): unique_together = ('course_id', 'mode_slug', 'currency') diff --git a/lms/djangoapps/instructor/enrollment.py b/lms/djangoapps/instructor/enrollment.py index d963721508..e134964fa2 100644 --- a/lms/djangoapps/instructor/enrollment.py +++ b/lms/djangoapps/instructor/enrollment.py @@ -111,7 +111,16 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal if previous_state.user: # if the student is currently unenrolled, don't enroll them in their # previous mode - course_mode = CourseMode.DEFAULT_MODE_SLUG + + # for now, White Labels use 'shoppingcart' which is based on the + # "honor" course_mode. Given the change to use "audit" as the default + # course_mode in Open edX, we need to be backwards compatible with + # how White Labels approach enrollment modes. + if CourseMode.is_white_label(course_id): + course_mode = CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG + else: + course_mode = CourseMode.DEFAULT_MODE_SLUG + if previous_state.enrollment: course_mode = previous_state.mode diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 9a51b00835..6a8b087f39 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -362,6 +362,11 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour def setUp(self): super(TestInstructorDetailedEnrollmentReport, self).setUp() self.course = CourseFactory.create() + CourseModeFactory.create( + course_id=self.course.id, + min_price=50, + mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG + ) # create testing invoice 1 self.instructor = InstructorFactory(course_key=self.course.id) @@ -476,7 +481,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour created_by=self.instructor, invoice=self.sale_invoice_1, invoice_item=self.invoice_item, - mode_slug=CourseMode.DEFAULT_MODE_SLUG + mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG ) course_registration_code.save() @@ -517,7 +522,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour created_by=self.instructor, invoice=self.sale_invoice_1, invoice_item=self.invoice_item, - mode_slug=CourseMode.DEFAULT_MODE_SLUG + mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG ) course_registration_code.save() @@ -845,7 +850,11 @@ class TestExecutiveSummaryReport(TestReportMixin, InstructorTaskCourseTestCase): def setUp(self): super(TestExecutiveSummaryReport, self).setUp() self.course = CourseFactory.create() - CourseModeFactory.create(course_id=self.course.id, min_price=50) + CourseModeFactory.create( + course_id=self.course.id, + min_price=50, + mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG + ) self.instructor = InstructorFactory(course_key=self.course.id) self.student1 = UserFactory() diff --git a/lms/djangoapps/shoppingcart/models.py b/lms/djangoapps/shoppingcart/models.py index 9a935a2d89..ae74ee9d46 100644 --- a/lms/djangoapps/shoppingcart/models.py +++ b/lms/djangoapps/shoppingcart/models.py @@ -1,3 +1,4 @@ +# pylint: disable=arguments-differ """ Models for the shopping cart and assorted purchase types """ from collections import namedtuple @@ -1473,7 +1474,7 @@ class PaidCourseRegistration(OrderItem): app_label = "shoppingcart" course_id = CourseKeyField(max_length=128, db_index=True) - mode = models.SlugField(default=CourseMode.DEFAULT_MODE_SLUG) + mode = models.SlugField(default=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG) course_enrollment = models.ForeignKey(CourseEnrollment, null=True) @classmethod @@ -1526,7 +1527,8 @@ class PaidCourseRegistration(OrderItem): @classmethod @transaction.atomic - def add_to_order(cls, order, course_id, mode_slug=CourseMode.DEFAULT_MODE_SLUG, cost=None, currency=None): + def add_to_order(cls, order, course_id, mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG, + cost=None, currency=None): # pylint: disable=arguments-differ """ A standardized way to create these objects, with sensible defaults filled in. Will update the cost if called on an order that already carries the course. @@ -1561,7 +1563,7 @@ class PaidCourseRegistration(OrderItem): course_mode = CourseMode.mode_for_course(course_id, mode_slug) if not course_mode: # user could have specified a mode that's not set, in that case return the DEFAULT_MODE - course_mode = CourseMode.DEFAULT_MODE + course_mode = CourseMode.DEFAULT_SHOPPINGCART_MODE if not cost: cost = course_mode.min_price if not currency: @@ -1660,7 +1662,7 @@ class CourseRegCodeItem(OrderItem): app_label = "shoppingcart" course_id = CourseKeyField(max_length=128, db_index=True) - mode = models.SlugField(default=CourseMode.DEFAULT_MODE_SLUG) + mode = models.SlugField(default=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG) @classmethod def get_bulk_purchased_seat_count(cls, course_key, status='purchased'): @@ -1706,7 +1708,8 @@ class CourseRegCodeItem(OrderItem): @classmethod @transaction.atomic - def add_to_order(cls, order, course_id, qty, mode_slug=CourseMode.DEFAULT_MODE_SLUG, cost=None, currency=None): # pylint: disable=arguments-differ + def add_to_order(cls, order, course_id, qty, mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG, + cost=None, currency=None): # pylint: disable=arguments-differ """ A standardized way to create these objects, with sensible defaults filled in. Will update the cost if called on an order that already carries the course. @@ -1736,8 +1739,8 @@ class CourseRegCodeItem(OrderItem): ### handle default arguments for mode_slug, cost, currency course_mode = CourseMode.mode_for_course(course_id, mode_slug) if not course_mode: - # user could have specified a mode that's not set, in that case return the DEFAULT_MODE - course_mode = CourseMode.DEFAULT_MODE + # user could have specified a mode that's not set, in that case return the DEFAULT_SHOPPINGCART_MODE + course_mode = CourseMode.DEFAULT_SHOPPINGCART_MODE if not cost: cost = course_mode.min_price if not currency: diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index 98db8769b7..29c3352739 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -732,7 +732,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): self.assertEqual(reg1.unit_cost, 0) self.assertEqual(reg1.line_cost, 0) - self.assertEqual(reg1.mode, CourseMode.DEFAULT_MODE_SLUG) + self.assertEqual(reg1.mode, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG) self.assertEqual(reg1.user, self.user) self.assertEqual(reg1.status, "cart") self.assertEqual(self.cart.total_cost, 0) @@ -742,7 +742,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): self.assertEqual(course_reg_code_item.unit_cost, 0) self.assertEqual(course_reg_code_item.line_cost, 0) - self.assertEqual(course_reg_code_item.mode, CourseMode.DEFAULT_MODE_SLUG) + self.assertEqual(course_reg_code_item.mode, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG) self.assertEqual(course_reg_code_item.user, self.user) self.assertEqual(course_reg_code_item.status, "cart") self.assertEqual(self.cart.total_cost, 0) diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py index 381277ed52..56ea2adff7 100644 --- a/lms/djangoapps/shoppingcart/tests/test_views.py +++ b/lms/djangoapps/shoppingcart/tests/test_views.py @@ -247,13 +247,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): test to check that that the same coupon code applied on multiple items in the cart. """ - for course_key, cost in ((self.course_key, 40), (self.testing_course.id, 20)): - CourseMode( - course_id=course_key, - mode_slug=CourseMode.DEFAULT_MODE_SLUG, - mode_display_name=CourseMode.DEFAULT_MODE_SLUG, - min_price=cost - ).save() + self.login_user() # add first course to user cart resp = self.client.post(