Commit 497622d4 by Peter Fogg

Switch default course mode to 'audit'.

ECOM-2972
parent 347bfcbb
...@@ -360,7 +360,7 @@ def certificates_list_handler(request, course_key_string): ...@@ -360,7 +360,7 @@ def certificates_list_handler(request, course_key_string):
certificate_web_view_url = get_lms_link_for_certificate_web_view( certificate_web_view_url = get_lms_link_for_certificate_web_view(
user_id=request.user.id, user_id=request.user.id,
course_key=course_key, course_key=course_key,
mode=course_modes[0] # CourseMode.modes_for_course returns default mode 'honor' if doesn't find anyone. mode=course_modes[0] # CourseMode.modes_for_course returns default mode if doesn't find anyone.
) )
certificates = None certificates = None
is_active = False is_active = False
......
...@@ -94,8 +94,8 @@ class CourseMode(models.Model): ...@@ -94,8 +94,8 @@ class CourseMode(models.Model):
NO_ID_PROFESSIONAL_MODE = "no-id-professional" NO_ID_PROFESSIONAL_MODE = "no-id-professional"
CREDIT_MODE = "credit" CREDIT_MODE = "credit"
DEFAULT_MODE = Mode(HONOR, _('Honor Code Certificate'), 0, '', 'usd', None, None, None) DEFAULT_MODE = Mode(AUDIT, _('Audit'), 0, '', 'usd', None, None, None)
DEFAULT_MODE_SLUG = HONOR DEFAULT_MODE_SLUG = AUDIT
# Modes that allow a student to pursue a verified certificate # Modes that allow a student to pursue a verified certificate
VERIFIED_MODES = [VERIFIED, PROFESSIONAL] VERIFIED_MODES = [VERIFIED, PROFESSIONAL]
...@@ -107,7 +107,7 @@ class CourseMode(models.Model): ...@@ -107,7 +107,7 @@ class CourseMode(models.Model):
CREDIT_MODES = [CREDIT_MODE] CREDIT_MODES = [CREDIT_MODE]
# Modes that are allowed to upsell # Modes that are allowed to upsell
UPSELL_TO_VERIFIED_MODES = [HONOR] UPSELL_TO_VERIFIED_MODES = [HONOR, AUDIT]
class Meta(object): class Meta(object):
unique_together = ('course_id', 'mode_slug', 'currency') unique_together = ('course_id', 'mode_slug', 'currency')
...@@ -507,7 +507,7 @@ class CourseMode(models.Model): ...@@ -507,7 +507,7 @@ class CourseMode(models.Model):
return False return False
# Check that the default mode is available. # Check that the default mode is available.
return cls.HONOR in modes_dict return cls.DEFAULT_MODE_SLUG in modes_dict
@classmethod @classmethod
def is_white_label(cls, course_id, modes_dict=None): def is_white_label(cls, course_id, modes_dict=None):
......
...@@ -177,6 +177,7 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase): ...@@ -177,6 +177,7 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
# Mapping of course modes to the POST parameters sent # Mapping of course modes to the POST parameters sent
# when the user chooses that mode. # when the user chooses that mode.
POST_PARAMS_FOR_COURSE_MODE = { POST_PARAMS_FOR_COURSE_MODE = {
'audit': {},
'honor': {'honor_mode': True}, 'honor': {'honor_mode': True},
'verified': {'verified_mode': True, 'contribution': '1.23'}, 'verified': {'verified_mode': True, 'contribution': '1.23'},
'unsupported': {'unsupported_mode': True}, 'unsupported': {'unsupported_mode': True},
...@@ -227,9 +228,9 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase): ...@@ -227,9 +228,9 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
expected_amount = decimal.Decimal(self.POST_PARAMS_FOR_COURSE_MODE['verified']['contribution']) expected_amount = decimal.Decimal(self.POST_PARAMS_FOR_COURSE_MODE['verified']['contribution'])
self.assertEqual(actual_amount, expected_amount) self.assertEqual(actual_amount, expected_amount)
def test_successful_honor_enrollment(self): def test_successful_default_enrollment(self):
# Create the course modes # Create the course modes
for mode in ('honor', 'verified'): for mode in (CourseMode.DEFAULT_MODE_SLUG, 'verified'):
CourseModeFactory(mode_slug=mode, course_id=self.course.id) CourseModeFactory(mode_slug=mode, course_id=self.course.id)
# Enroll the user in the default mode (honor) to emulate # Enroll the user in the default mode (honor) to emulate
...@@ -242,11 +243,11 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase): ...@@ -242,11 +243,11 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
# Explicitly select the honor mode (POST request) # Explicitly select the honor mode (POST request)
choose_track_url = reverse('course_modes_choose', args=[unicode(self.course.id)]) choose_track_url = reverse('course_modes_choose', args=[unicode(self.course.id)])
self.client.post(choose_track_url, self.POST_PARAMS_FOR_COURSE_MODE['honor']) self.client.post(choose_track_url, self.POST_PARAMS_FOR_COURSE_MODE[CourseMode.DEFAULT_MODE_SLUG])
# Verify that the user's enrollment remains unchanged # Verify that the user's enrollment remains unchanged
mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertEqual(mode, 'honor') self.assertEqual(mode, CourseMode.DEFAULT_MODE_SLUG)
self.assertEqual(is_active, True) self.assertEqual(is_active, True)
def test_unsupported_enrollment_mode_failure(self): def test_unsupported_enrollment_mode_failure(self):
......
...@@ -7,6 +7,7 @@ import importlib ...@@ -7,6 +7,7 @@ import importlib
import logging import logging
from django.conf import settings from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
from course_modes.models import CourseMode
from enrollment import errors from enrollment import errors
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -132,10 +133,10 @@ def get_enrollment(user_id, course_id): ...@@ -132,10 +133,10 @@ def get_enrollment(user_id, course_id):
return _data_api().get_course_enrollment(user_id, course_id) return _data_api().get_course_enrollment(user_id, course_id)
def add_enrollment(user_id, course_id, mode='honor', is_active=True): def add_enrollment(user_id, course_id, mode=CourseMode.DEFAULT_MODE_SLUG, is_active=True):
"""Enrolls a user in a course. """Enrolls a user in a course.
Enrolls a user in a course. If the mode is not specified, this will default to 'honor'. Enrolls a user in a course. If the mode is not specified, this will default to `CourseMode.DEFAULT_MODE_SLUG`.
Arguments: Arguments:
user_id (str): The user to enroll. user_id (str): The user to enroll.
...@@ -143,7 +144,7 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True): ...@@ -143,7 +144,7 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
Keyword Arguments: Keyword Arguments:
mode (str): Optional argument for the type of enrollment to create. Ex. 'audit', 'honor', 'verified', mode (str): Optional argument for the type of enrollment to create. Ex. 'audit', 'honor', 'verified',
'professional'. If not specified, this defaults to 'honor'. 'professional'. If not specified, this defaults to the default course mode.
is_active (boolean): Optional argument for making the new enrollment inactive. If not specified, is_active is_active (boolean): Optional argument for making the new enrollment inactive. If not specified, is_active
defaults to True. defaults to True.
...@@ -154,7 +155,7 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True): ...@@ -154,7 +155,7 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
>>> add_enrollment("Bob", "edX/DemoX/2014T2", mode="audit") >>> add_enrollment("Bob", "edX/DemoX/2014T2", mode="audit")
{ {
"created": "2014-10-20T20:18:00Z", "created": "2014-10-20T20:18:00Z",
"mode": "honor", "mode": "audit",
"is_active": True, "is_active": True,
"user": "Bob", "user": "Bob",
"course": { "course": {
...@@ -165,8 +166,8 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True): ...@@ -165,8 +166,8 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
"course_end": "2015-05-06T00:00:00Z", "course_end": "2015-05-06T00:00:00Z",
"course_modes": [ "course_modes": [
{ {
"slug": "honor", "slug": "audit",
"name": "Honor Code Certificate", "name": "Audit",
"min_price": 0, "min_price": 0,
"suggested_prices": "", "suggested_prices": "",
"currency": "usd", "currency": "usd",
......
...@@ -47,7 +47,7 @@ class EnrollmentTestMixin(object): ...@@ -47,7 +47,7 @@ class EnrollmentTestMixin(object):
expected_status=status.HTTP_200_OK, expected_status=status.HTTP_200_OK,
email_opt_in=None, email_opt_in=None,
as_server=False, as_server=False,
mode=CourseMode.HONOR, mode=CourseMode.DEFAULT_MODE_SLUG,
is_active=None, is_active=None,
enrollment_attributes=None, enrollment_attributes=None,
min_mongo_calls=0, min_mongo_calls=0,
...@@ -169,13 +169,13 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -169,13 +169,13 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
@ddt.data( @ddt.data(
# Default (no course modes in the database) # Default (no course modes in the database)
# Expect that users are automatically enrolled as "honor". # Expect that users are automatically enrolled as the default
([], CourseMode.HONOR), ([], CourseMode.DEFAULT_MODE_SLUG),
# Audit / Verified / Honor # Audit / Verified
# We should always go to the "choose your course" page. # We should always go to the "choose your course" page.
# We should also be enrolled as "honor" by default. # We should also be enrolled as the default.
([CourseMode.HONOR, CourseMode.VERIFIED, CourseMode.AUDIT], CourseMode.HONOR), ([CourseMode.VERIFIED, CourseMode.AUDIT], CourseMode.DEFAULT_MODE_SLUG),
) )
@ddt.unpack @ddt.unpack
def test_enroll(self, course_modes, enrollment_mode): def test_enroll(self, course_modes, enrollment_mode):
...@@ -198,8 +198,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -198,8 +198,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
def test_check_enrollment(self): def test_check_enrollment(self):
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
# Create an enrollment # Create an enrollment
self.assert_enrollment_status() self.assert_enrollment_status()
...@@ -209,7 +209,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -209,7 +209,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(resp.status_code, status.HTTP_200_OK)
data = json.loads(resp.content) data = json.loads(resp.content)
self.assertEqual(unicode(self.course.id), data['course_details']['course_id']) self.assertEqual(unicode(self.course.id), data['course_details']['course_id'])
self.assertEqual(CourseMode.HONOR, data['mode']) self.assertEqual(CourseMode.DEFAULT_MODE_SLUG, data['mode'])
self.assertTrue(data['is_active']) self.assertTrue(data['is_active'])
@ddt.data( @ddt.data(
...@@ -258,8 +258,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -258,8 +258,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
def test_user_not_specified(self): def test_user_not_specified(self):
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
# Create an enrollment # Create an enrollment
self.assert_enrollment_status() self.assert_enrollment_status()
...@@ -269,7 +269,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -269,7 +269,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(resp.status_code, status.HTTP_200_OK)
data = json.loads(resp.content) data = json.loads(resp.content)
self.assertEqual(unicode(self.course.id), data['course_details']['course_id']) self.assertEqual(unicode(self.course.id), data['course_details']['course_id'])
self.assertEqual(CourseMode.HONOR, data['mode']) self.assertEqual(CourseMode.DEFAULT_MODE_SLUG, data['mode'])
self.assertTrue(data['is_active']) self.assertTrue(data['is_active'])
def test_user_not_authenticated(self): def test_user_not_authenticated(self):
...@@ -306,8 +306,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -306,8 +306,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
# Try to enroll a user that is not the authenticated user. # Try to enroll a user that is not the authenticated user.
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
self.assert_enrollment_status(username=self.other_user.username, expected_status=status.HTTP_404_NOT_FOUND) self.assert_enrollment_status(username=self.other_user.username, expected_status=status.HTTP_404_NOT_FOUND)
# Verify that the server still has access to this endpoint. # Verify that the server still has access to this endpoint.
...@@ -340,8 +340,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -340,8 +340,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
for course in self.course, other_course: for course in self.course, other_course:
CourseModeFactory.create( CourseModeFactory.create(
course_id=unicode(course.id), course_id=unicode(course.id),
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
self.assert_enrollment_status( self.assert_enrollment_status(
course_id=unicode(course.id), course_id=unicode(course.id),
...@@ -520,8 +520,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -520,8 +520,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.rate_limit_config.save() self.rate_limit_config.save()
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
for attempt in xrange(self.rate_limit + 10): for attempt in xrange(self.rate_limit + 10):
...@@ -534,8 +534,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -534,8 +534,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.rate_limit_config.save() self.rate_limit_config.save()
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=CourseMode.HONOR, mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.HONOR, mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
) )
for attempt in xrange(self.rate_limit + 10): for attempt in xrange(self.rate_limit + 10):
...@@ -595,7 +595,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -595,7 +595,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
def test_update_enrollment_with_mode(self): def test_update_enrollment_with_mode(self):
"""With the right API key, update an existing enrollment with a new mode. """ """With the right API key, update an existing enrollment with a new mode. """
# Create an honor and verified mode for a course. This allows an update. # Create an honor and verified mode for a course. This allows an update.
for mode in [CourseMode.HONOR, CourseMode.VERIFIED]: for mode in [CourseMode.DEFAULT_MODE_SLUG, CourseMode.VERIFIED]:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=mode, mode_slug=mode,
...@@ -605,11 +605,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -605,11 +605,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
# Create an enrollment # Create an enrollment
self.assert_enrollment_status(as_server=True) self.assert_enrollment_status(as_server=True)
# Check that the enrollment is honor. # Check that the enrollment is default.
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
# Check that the enrollment upgraded to verified. # Check that the enrollment upgraded to verified.
self.assert_enrollment_status(as_server=True, mode=CourseMode.VERIFIED, expected_status=status.HTTP_200_OK) self.assert_enrollment_status(as_server=True, mode=CourseMode.VERIFIED, expected_status=status.HTTP_200_OK)
...@@ -621,7 +621,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -621,7 +621,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
"""With the right API key, update an existing enrollment with credit """With the right API key, update an existing enrollment with credit
mode and set enrollment attributes. mode and set enrollment attributes.
""" """
for mode in [CourseMode.HONOR, CourseMode.CREDIT_MODE]: for mode in [CourseMode.DEFAULT_MODE_SLUG, CourseMode.CREDIT_MODE]:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=mode, mode_slug=mode,
...@@ -631,11 +631,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -631,11 +631,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
# Create an enrollment # Create an enrollment
self.assert_enrollment_status(as_server=True) self.assert_enrollment_status(as_server=True)
# Check that the enrollment is honor. # Check that the enrollment is the default.
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
# Check that the enrollment upgraded to credit. # Check that the enrollment upgraded to credit.
enrollment_attributes = [{ enrollment_attributes = [{
...@@ -657,7 +657,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -657,7 +657,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
"""Check response status is bad request when invalid enrollment """Check response status is bad request when invalid enrollment
attributes are passed attributes are passed
""" """
for mode in [CourseMode.HONOR, CourseMode.CREDIT_MODE]: for mode in [CourseMode.DEFAULT_MODE_SLUG, CourseMode.CREDIT_MODE]:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=mode, mode_slug=mode,
...@@ -667,11 +667,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -667,11 +667,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
# Create an enrollment # Create an enrollment
self.assert_enrollment_status(as_server=True) self.assert_enrollment_status(as_server=True)
# Check that the enrollment is honor. # Check that the enrollment is the default.
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
# Check that the enrollment upgraded to credit. # Check that the enrollment upgraded to credit.
enrollment_attributes = [{ enrollment_attributes = [{
...@@ -687,12 +687,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -687,12 +687,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
) )
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
def test_downgrade_enrollment_with_mode(self): def test_downgrade_enrollment_with_mode(self):
"""With the right API key, downgrade an existing enrollment with a new mode. """ """With the right API key, downgrade an existing enrollment with a new mode. """
# Create an honor and verified mode for a course. This allows an update. # Create an honor and verified mode for a course. This allows an update.
for mode in [CourseMode.HONOR, CourseMode.VERIFIED]: for mode in [CourseMode.DEFAULT_MODE_SLUG, CourseMode.VERIFIED]:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=mode, mode_slug=mode,
...@@ -708,16 +708,20 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -708,16 +708,20 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.VERIFIED) self.assertEqual(course_mode, CourseMode.VERIFIED)
# Check that the enrollment downgraded to honor. # Check that the enrollment was downgraded to the default mode.
self.assert_enrollment_status(as_server=True, mode=CourseMode.HONOR, expected_status=status.HTTP_200_OK) self.assert_enrollment_status(
as_server=True,
mode=CourseMode.DEFAULT_MODE_SLUG,
expected_status=status.HTTP_200_OK
)
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
@ddt.data( @ddt.data(
((CourseMode.HONOR, ), CourseMode.HONOR), ((CourseMode.DEFAULT_MODE_SLUG, ), CourseMode.DEFAULT_MODE_SLUG),
((CourseMode.HONOR, CourseMode.VERIFIED), CourseMode.HONOR), ((CourseMode.DEFAULT_MODE_SLUG, CourseMode.VERIFIED), CourseMode.DEFAULT_MODE_SLUG),
((CourseMode.HONOR, CourseMode.VERIFIED), CourseMode.VERIFIED), ((CourseMode.DEFAULT_MODE_SLUG, CourseMode.VERIFIED), CourseMode.VERIFIED),
((CourseMode.PROFESSIONAL, ), CourseMode.PROFESSIONAL), ((CourseMode.PROFESSIONAL, ), CourseMode.PROFESSIONAL),
((CourseMode.NO_ID_PROFESSIONAL_MODE, ), CourseMode.NO_ID_PROFESSIONAL_MODE), ((CourseMode.NO_ID_PROFESSIONAL_MODE, ), CourseMode.NO_ID_PROFESSIONAL_MODE),
((CourseMode.VERIFIED, CourseMode.CREDIT_MODE), CourseMode.VERIFIED), ((CourseMode.VERIFIED, CourseMode.CREDIT_MODE), CourseMode.VERIFIED),
...@@ -758,8 +762,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -758,8 +762,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.assert_enrollment_activation(False, selected_mode) self.assert_enrollment_activation(False, selected_mode)
# Verify that omitting the mode returns 400 for course configurations # Verify that omitting the mode returns 400 for course configurations
# in which the default (honor) mode doesn't exist. # in which the default mode doesn't exist.
expected_status = status.HTTP_200_OK if CourseMode.HONOR in configured_modes else status.HTTP_400_BAD_REQUEST expected_status = (
status.HTTP_200_OK
if CourseMode.DEFAULT_MODE_SLUG in configured_modes
else status.HTTP_400_BAD_REQUEST
)
self.assert_enrollment_status( self.assert_enrollment_status(
as_server=True, as_server=True,
is_active=False, is_active=False,
...@@ -788,8 +796,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -788,8 +796,8 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
def test_change_mode_from_user(self): def test_change_mode_from_user(self):
"""Users should not be able to alter the enrollment mode on an enrollment. """ """Users should not be able to alter the enrollment mode on an enrollment. """
# Create an honor and verified mode for a course. This allows an update. # Create a default and a verified mode for a course. This allows an update.
for mode in [CourseMode.HONOR, CourseMode.VERIFIED]: for mode in [CourseMode.DEFAULT_MODE_SLUG, CourseMode.VERIFIED]:
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
mode_slug=mode, mode_slug=mode,
...@@ -803,13 +811,13 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase): ...@@ -803,13 +811,13 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase):
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
# Get a 403 response when trying to upgrade yourself. # Get a 403 response when trying to upgrade yourself.
self.assert_enrollment_status(mode=CourseMode.VERIFIED, expected_status=status.HTTP_403_FORBIDDEN) self.assert_enrollment_status(mode=CourseMode.VERIFIED, expected_status=status.HTTP_403_FORBIDDEN)
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, CourseMode.HONOR) self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
@ddt.data(*itertools.product( @ddt.data(*itertools.product(
(CourseMode.HONOR, CourseMode.VERIFIED), (CourseMode.HONOR, CourseMode.VERIFIED),
......
...@@ -287,9 +287,10 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -287,9 +287,10 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
* Enroll the currently signed in user in a course. * Enroll the currently signed in user in a course.
Currently a user can use this command only to enroll the user in Currently a user can use this command only to enroll the
honor mode. If honor mode is not supported for the course, the user in the default course mode. If this is not
request fails and returns the available modes. supported for the course, the request fails and returns
the available modes.
This command can use a server-to-server call to enroll a user in This command can use a server-to-server call to enroll a user in
other modes, such as "verified", "professional", or "credit". If other modes, such as "verified", "professional", or "credit". If
...@@ -325,7 +326,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -325,7 +326,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
You cannot use the command to enroll a different user. You cannot use the command to enroll a different user.
* mode: Optional. The course mode for the enrollment. Individual * mode: Optional. The course mode for the enrollment. Individual
users cannot upgrade their enrollment mode from 'honor'. Only users cannot upgrade their enrollment mode from the default. Only
server-to-server requests can enroll with other modes. server-to-server requests can enroll with other modes.
* is_active: Optional. A Boolean value indicating whether the * is_active: Optional. A Boolean value indicating whether the
...@@ -353,7 +354,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -353,7 +354,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
deactivate an enrollment. deactivate an enrollment.
* mode: Optional. The course mode for the enrollment. Individual * mode: Optional. The course mode for the enrollment. Individual
users cannot upgrade their enrollment mode from "honor". Only users cannot upgrade their enrollment mode from the default. Only
server-to-server requests can enroll with other modes. server-to-server requests can enroll with other modes.
* user: Optional. The user ID of the currently logged in user. You * user: Optional. The user ID of the currently logged in user. You
...@@ -519,7 +520,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -519,7 +520,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
} }
) )
mode = request.data.get('mode', CourseMode.HONOR) mode = request.data.get('mode', CourseMode.DEFAULT_MODE_SLUG)
has_api_key_permissions = self.has_api_key_permissions(request) has_api_key_permissions = self.has_api_key_permissions(request)
...@@ -531,7 +532,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn): ...@@ -531,7 +532,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
# other users, do not let them deduce the existence of an enrollment. # other users, do not let them deduce the existence of an enrollment.
return Response(status=status.HTTP_404_NOT_FOUND) return Response(status=status.HTTP_404_NOT_FOUND)
if mode != CourseMode.HONOR and not has_api_key_permissions: if mode != CourseMode.DEFAULT_MODE_SLUG and not has_api_key_permissions:
return Response( return Response(
status=status.HTTP_403_FORBIDDEN, status=status.HTTP_403_FORBIDDEN,
data={ data={
......
...@@ -895,7 +895,7 @@ class CourseEnrollment(models.Model): ...@@ -895,7 +895,7 @@ class CourseEnrollment(models.Model):
# Represents the modes that are possible. We'll update this later with a # Represents the modes that are possible. We'll update this later with a
# list of possible values. # list of possible values.
mode = models.CharField(default="honor", max_length=100) mode = models.CharField(default=CourseMode.DEFAULT_MODE_SLUG, max_length=100)
objects = CourseEnrollmentManager() objects = CourseEnrollmentManager()
...@@ -957,7 +957,7 @@ class CourseEnrollment(models.Model): ...@@ -957,7 +957,7 @@ class CourseEnrollment(models.Model):
# If we *did* just create a new enrollment, set some defaults # If we *did* just create a new enrollment, set some defaults
if created: if created:
enrollment.mode = "honor" enrollment.mode = CourseMode.DEFAULT_MODE_SLUG
enrollment.is_active = False enrollment.is_active = False
enrollment.save() enrollment.save()
...@@ -1043,8 +1043,8 @@ class CourseEnrollment(models.Model): ...@@ -1043,8 +1043,8 @@ class CourseEnrollment(models.Model):
u"mode:{}".format(self.mode)] u"mode:{}".format(self.mode)]
) )
if mode_changed: if mode_changed:
# the user's default mode is "honor" and disabled for a course # Only emit mode change events when the user's enrollment
# mode change events will only be emitted when the user's mode changes from this # mode has changed from its previous setting
self.emit_event(EVENT_NAME_ENROLLMENT_MODE_CHANGED) self.emit_event(EVENT_NAME_ENROLLMENT_MODE_CHANGED)
def emit_event(self, event_name): def emit_event(self, event_name):
...@@ -1090,7 +1090,7 @@ class CourseEnrollment(models.Model): ...@@ -1090,7 +1090,7 @@ class CourseEnrollment(models.Model):
) )
@classmethod @classmethod
def enroll(cls, user, course_key, mode="honor", check_access=False): def enroll(cls, user, course_key, mode=CourseMode.DEFAULT_MODE_SLUG, check_access=False):
""" """
Enroll a user in a course. This saves immediately. Enroll a user in a course. This saves immediately.
...@@ -1103,8 +1103,8 @@ class CourseEnrollment(models.Model): ...@@ -1103,8 +1103,8 @@ class CourseEnrollment(models.Model):
`course_key` is our usual course_id string (e.g. "edX/Test101/2013_Fall) `course_key` is our usual course_id string (e.g. "edX/Test101/2013_Fall)
`mode` is a string specifying what kind of enrollment this is. The `mode` is a string specifying what kind of enrollment this is. The
default is 'honor', meaning honor certificate. Other options default is the default course mode, 'audit'. Other options
include 'professional', 'verified', 'audit', include 'professional', 'verified', 'honor',
'no-id-professional' and 'credit'. 'no-id-professional' and 'credit'.
See CourseMode in common/djangoapps/course_modes/models.py. See CourseMode in common/djangoapps/course_modes/models.py.
...@@ -1165,7 +1165,7 @@ class CourseEnrollment(models.Model): ...@@ -1165,7 +1165,7 @@ class CourseEnrollment(models.Model):
return enrollment return enrollment
@classmethod @classmethod
def enroll_by_email(cls, email, course_id, mode="honor", ignore_errors=True): def enroll_by_email(cls, email, course_id, mode=CourseMode.DEFAULT_MODE_SLUG, ignore_errors=True):
""" """
Enroll a user in a course given their email. This saves immediately. Enroll a user in a course given their email. This saves immediately.
...@@ -1181,9 +1181,10 @@ class CourseEnrollment(models.Model): ...@@ -1181,9 +1181,10 @@ class CourseEnrollment(models.Model):
`course_id` is our usual course_id string (e.g. "edX/Test101/2013_Fall) `course_id` is our usual course_id string (e.g. "edX/Test101/2013_Fall)
`mode` is a string specifying what kind of enrollment this is. The `mode` is a string specifying what kind of enrollment this is. The
default is "honor", meaning honor certificate. Future options default is the default course mode, 'audit'. Other options
may include "audit", "verified_id", etc. Please don't use it include 'professional', 'verified', 'honor',
until we have these mapped out. 'no-id-professional' and 'credit'.
See CourseMode in common/djangoapps/course_modes/models.py.
`ignore_errors` is a boolean indicating whether we should suppress `ignore_errors` is a boolean indicating whether we should suppress
`User.DoesNotExist` errors (returning None) or let it `User.DoesNotExist` errors (returning None) or let it
......
...@@ -52,8 +52,8 @@ class CourseModeFactory(DjangoModelFactory): ...@@ -52,8 +52,8 @@ class CourseModeFactory(DjangoModelFactory):
model = CourseMode model = CourseMode
course_id = None course_id = None
mode_display_name = u'Honor Code', mode_display_name = CourseMode.DEFAULT_MODE.name
mode_slug = 'honor' mode_slug = CourseMode.DEFAULT_MODE_SLUG
min_price = 0 min_price = 0
suggested_prices = '' suggested_prices = ''
currency = 'usd' currency = 'usd'
......
...@@ -7,6 +7,7 @@ from mock import patch ...@@ -7,6 +7,7 @@ from mock import patch
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from course_modes.models import CourseMode
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from util.testing import UrlResetMixin from util.testing import UrlResetMixin
...@@ -41,13 +42,13 @@ class EnrollmentTest(UrlResetMixin, ModuleStoreTestCase): ...@@ -41,13 +42,13 @@ class EnrollmentTest(UrlResetMixin, ModuleStoreTestCase):
@ddt.data( @ddt.data(
# Default (no course modes in the database) # Default (no course modes in the database)
# Expect that we're redirected to the dashboard # Expect that we're redirected to the dashboard
# and automatically enrolled as "honor" # and automatically enrolled
([], '', 'honor'), ([], '', CourseMode.DEFAULT_MODE_SLUG),
# Audit / Verified / Honor # Audit / Verified / Honor
# We should always go to the "choose your course" page. # We should always go to the "choose your course" page.
# We should also be enrolled as "honor" by default. # We should also be enrolled as the default mode.
(['honor', 'verified', 'audit'], 'course_modes_choose', 'honor'), (['honor', 'verified', 'audit'], 'course_modes_choose', CourseMode.DEFAULT_MODE_SLUG),
# Professional ed # Professional ed
# Expect that we're sent to the "choose your track" page # Expect that we're sent to the "choose your track" page
......
...@@ -127,22 +127,21 @@ class TestRecentEnrollments(ModuleStoreTestCase): ...@@ -127,22 +127,21 @@ class TestRecentEnrollments(ModuleStoreTestCase):
self.assertContains(response, "Thank you for enrolling in") self.assertContains(response, "Thank you for enrolling in")
@ddt.data( @ddt.data(
#Register as an honor in any course modes with no payment option # Register as honor in any course modes with no payment option
([('audit', 0), ('honor', 0)], 'honor', True), ([('audit', 0), ('honor', 0)], 'honor', True),
([('honor', 0)], 'honor', True), ([('honor', 0)], 'honor', True),
([], 'honor', True), # Register as honor in any course modes which has payment option
#Register as an honor in any course modes which has payment option
([('honor', 10)], 'honor', False), # This is a paid course ([('honor', 10)], 'honor', False), # This is a paid course
([('audit', 0), ('honor', 0), ('professional', 20)], 'honor', True), ([('audit', 0), ('honor', 0), ('professional', 20)], 'honor', True),
([('audit', 0), ('honor', 0), ('verified', 20)], 'honor', True), ([('audit', 0), ('honor', 0), ('verified', 20)], 'honor', True),
([('audit', 0), ('honor', 0), ('verified', 20), ('professional', 20)], 'honor', True), ([('audit', 0), ('honor', 0), ('verified', 20), ('professional', 20)], 'honor', True),
([], 'honor', True), # Register as audit in any course modes with no payment option
#Register as an audit in any course modes with no payment option
([('audit', 0), ('honor', 0)], 'audit', True), ([('audit', 0), ('honor', 0)], 'audit', True),
([('audit', 0)], 'audit', True), ([('audit', 0)], 'audit', True),
#Register as an audit in any course modes which has no payment option ([], 'audit', True),
# Register as audit in any course modes which has no payment option
([('audit', 0), ('honor', 0), ('verified', 10)], 'audit', True), ([('audit', 0), ('honor', 0), ('verified', 10)], 'audit', True),
#Register as a verified in any course modes which has payment option # Register as verified in any course modes which has payment option
([('professional', 20)], 'professional', False), ([('professional', 20)], 'professional', False),
([('verified', 20)], 'verified', False), ([('verified', 20)], 'verified', False),
([('professional', 20), ('verified', 20)], 'verified', False), ([('professional', 20), ('verified', 20)], 'verified', False),
......
...@@ -18,6 +18,7 @@ from django.core.urlresolvers import reverse ...@@ -18,6 +18,7 @@ from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from django.test.client import Client from django.test.client import Client
from course_modes.models import CourseMode
from student.models import ( from student.models import (
anonymous_id_for_user, user_by_anonymous_id, CourseEnrollment, anonymous_id_for_user, user_by_anonymous_id, CourseEnrollment,
unique_id_for_user, LinkedInAddToProfileConfiguration unique_id_for_user, LinkedInAddToProfileConfiguration
...@@ -321,7 +322,12 @@ class DashboardTest(ModuleStoreTestCase): ...@@ -321,7 +322,12 @@ class DashboardTest(ModuleStoreTestCase):
course_id=self.course.id course_id=self.course.id
) )
course_reg_code = shoppingcart.models.CourseRegistrationCode( course_reg_code = shoppingcart.models.CourseRegistrationCode(
code="abcde", course_id=self.course.id, created_by=self.user, invoice=sale_invoice_1, invoice_item=invoice_item, mode_slug='honor' code="abcde",
course_id=self.course.id,
created_by=self.user,
invoice=sale_invoice_1,
invoice_item=invoice_item,
mode_slug=CourseMode.DEFAULT_MODE_SLUG
) )
course_reg_code.save() course_reg_code.save()
...@@ -339,7 +345,6 @@ class DashboardTest(ModuleStoreTestCase): ...@@ -339,7 +345,6 @@ class DashboardTest(ModuleStoreTestCase):
#now activate the user by enrolling him/her to the course #now activate the user by enrolling him/her to the course
response = self.client.post(redeem_url) response = self.client.post(redeem_url)
self.assertEquals(response.status_code, 200) self.assertEquals(response.status_code, 200)
response = self.client.get(reverse('dashboard')) response = self.client.get(reverse('dashboard'))
self.assertIn('You can no longer access this course because payment has not yet been received', response.content) self.assertIn('You can no longer access this course because payment has not yet been received', response.content)
optout_object = Optout.objects.filter(user=self.user, course_id=self.course.id) optout_object = Optout.objects.filter(user=self.user, course_id=self.course.id)
...@@ -566,7 +571,7 @@ class EnrollmentEventTestMixin(EventTestMixin): ...@@ -566,7 +571,7 @@ class EnrollmentEventTestMixin(EventTestMixin):
{ {
'course_id': course_key.to_deprecated_string(), 'course_id': course_key.to_deprecated_string(),
'user_id': user.pk, 'user_id': user.pk,
'mode': 'honor' 'mode': CourseMode.DEFAULT_MODE_SLUG
} }
) )
self.mock_tracker.reset_mock() self.mock_tracker.reset_mock()
...@@ -578,7 +583,7 @@ class EnrollmentEventTestMixin(EventTestMixin): ...@@ -578,7 +583,7 @@ class EnrollmentEventTestMixin(EventTestMixin):
{ {
'course_id': course_key.to_deprecated_string(), 'course_id': course_key.to_deprecated_string(),
'user_id': user.pk, 'user_id': user.pk,
'mode': 'honor' 'mode': CourseMode.DEFAULT_MODE_SLUG
} }
) )
self.mock_tracker.reset_mock() self.mock_tracker.reset_mock()
...@@ -754,18 +759,18 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, TestCase): ...@@ -754,18 +759,18 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, TestCase):
user = User.objects.create(username="justin", email="jh@fake.edx.org") user = User.objects.create(username="justin", email="jh@fake.edx.org")
course_id = SlashSeparatedCourseKey("edX", "Test101", "2013") course_id = SlashSeparatedCourseKey("edX", "Test101", "2013")
CourseEnrollment.enroll(user, course_id) CourseEnrollment.enroll(user, course_id, "audit")
self.assert_enrollment_event_was_emitted(user, course_id) self.assert_enrollment_event_was_emitted(user, course_id)
CourseEnrollment.enroll(user, course_id, "audit") CourseEnrollment.enroll(user, course_id, "honor")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "audit") self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "honor")
# same enrollment mode does not emit an event # same enrollment mode does not emit an event
CourseEnrollment.enroll(user, course_id, "audit") CourseEnrollment.enroll(user, course_id, "honor")
self.assert_no_events_were_emitted() self.assert_no_events_were_emitted()
CourseEnrollment.enroll(user, course_id, "honor") CourseEnrollment.enroll(user, course_id, "audit")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "honor") self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "audit")
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
...@@ -789,7 +794,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase): ...@@ -789,7 +794,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
) )
return response return response
def test_enroll_as_honor(self): def test_enroll_as_default(self):
"""Tests that a student can successfully enroll through this view""" """Tests that a student can successfully enroll through this view"""
response = self._enroll_through_view(self.course) response = self._enroll_through_view(self.course)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -797,7 +802,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase): ...@@ -797,7 +802,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id self.user, self.course.id
) )
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(enrollment_mode, u'honor') self.assertEqual(enrollment_mode, CourseMode.DEFAULT_MODE_SLUG)
def test_cannot_enroll_if_already_enrolled(self): def test_cannot_enroll_if_already_enrolled(self):
""" """
...@@ -810,14 +815,14 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase): ...@@ -810,14 +815,14 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
response = self._enroll_through_view(self.course) response = self._enroll_through_view(self.course)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
def test_change_to_honor_if_verified(self): def test_change_to_default_if_verified(self):
""" """
Tests that a student that is a currently enrolled verified student cannot Tests that a student that is a currently enrolled verified student cannot
accidentally change their enrollment to verified accidentally change their enrollment mode
""" """
CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified') CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified')
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
# now try to enroll the student in the honor mode: # now try to enroll the student in the default mode:
response = self._enroll_through_view(self.course) response = self._enroll_through_view(self.course)
self.assertEqual(response.status_code, 400) self.assertEqual(response.status_code, 400)
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user( enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
...@@ -826,7 +831,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase): ...@@ -826,7 +831,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(enrollment_mode, u'verified') self.assertEqual(enrollment_mode, u'verified')
def test_change_to_honor_if_verified_not_active(self): def test_change_to_default_if_verified_not_active(self):
""" """
Tests that one can renroll for a course if one has already unenrolled Tests that one can renroll for a course if one has already unenrolled
""" """
...@@ -847,7 +852,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase): ...@@ -847,7 +852,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id self.user, self.course.id
) )
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(enrollment_mode, u'honor') self.assertEqual(enrollment_mode, CourseMode.DEFAULT_MODE_SLUG)
class AnonymousLookupTable(ModuleStoreTestCase): class AnonymousLookupTable(ModuleStoreTestCase):
......
...@@ -13,6 +13,7 @@ from xmodule.modulestore.tests.factories import CourseFactory ...@@ -13,6 +13,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from student.models import CourseEnrollment from student.models import CourseEnrollment
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory from course_modes.tests.factories import CourseModeFactory
from config_models.models import cache from config_models.models import cache
from util.testing import EventTestMixin from util.testing import EventTestMixin
...@@ -305,6 +306,7 @@ class GenerateExampleCertificatesTest(TestCase): ...@@ -305,6 +306,7 @@ class GenerateExampleCertificatesTest(TestCase):
def test_generate_example_certs(self): def test_generate_example_certs(self):
# Generate certificates for the course # Generate certificates for the course
CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug=CourseMode.HONOR)
with self._mock_xqueue() as mock_queue: with self._mock_xqueue() as mock_queue:
certs_api.generate_example_certificates(self.COURSE_KEY) certs_api.generate_example_certificates(self.COURSE_KEY)
......
...@@ -197,7 +197,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase) ...@@ -197,7 +197,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
with mock_create_basket(response=return_value): with mock_create_basket(response=return_value):
self._test_successful_ecommerce_api_call(False) self._test_successful_ecommerce_api_call(False)
def _test_course_without_sku(self): def _test_course_without_sku(self, enrollment_mode=CourseMode.DEFAULT_MODE_SLUG):
""" """
Validates the view bypasses the E-Commerce API when the course has no CourseModes with SKUs. Validates the view bypasses the E-Commerce API when the course has no CourseModes with SKUs.
""" """
...@@ -207,13 +207,16 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase) ...@@ -207,13 +207,16 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
# Validate the response content # Validate the response content
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode='honor', course_id=self.course.id, msg = Messages.NO_SKU_ENROLLED.format(
username=self.user.username) enrollment_mode=enrollment_mode,
course_id=self.course.id,
username=self.user.username
)
self.assertResponseMessage(response, msg) self.assertResponseMessage(response, msg)
def test_course_without_sku(self): def test_course_without_sku_default(self):
""" """
If the course does NOT have a SKU, the user should be enrolled in the course (under the honor mode) and If the course does NOT have a SKU, the user should be enrolled in the course (under the default mode) and
redirected to the user dashboard. redirected to the user dashboard.
""" """
# Remove SKU from all course modes # Remove SKU from all course modes
...@@ -223,6 +226,24 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase) ...@@ -223,6 +226,24 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
self._test_course_without_sku() self._test_course_without_sku()
def test_course_without_sku_honor(self):
"""
If the course does not have an SKU and has an honor mode, the user
should be enrolled as honor. This ensures backwards
compatibility with courses existing before the removal of
honor certificates.
"""
# Remove all existing course modes
CourseMode.objects.filter(course_id=self.course.id).delete()
# Ensure that honor mode exists
CourseMode(
mode_slug=CourseMode.HONOR,
mode_display_name="Honor Cert",
course_id=self.course.id
).save()
# We should be enrolled in honor mode
self._test_course_without_sku(enrollment_mode=CourseMode.HONOR)
@override_settings(ECOMMERCE_API_URL=None, ECOMMERCE_API_SIGNING_KEY=None) @override_settings(ECOMMERCE_API_URL=None, ECOMMERCE_API_SIGNING_KEY=None)
def test_ecommerce_service_not_configured(self): def test_ecommerce_service_not_configured(self):
""" """
...@@ -240,7 +261,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase) ...@@ -240,7 +261,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
def assertProfessionalModeBypassed(self): def assertProfessionalModeBypassed(self):
""" Verifies that the view returns HTTP 406 when a course with no honor mode is encountered. """ """ Verifies that the view returns HTTP 406 when a course with no honor or audit mode is encountered. """
CourseMode.objects.filter(course_id=self.course.id).delete() CourseMode.objects.filter(course_id=self.course.id).delete()
mode = CourseMode.NO_ID_PROFESSIONAL_MODE mode = CourseMode.NO_ID_PROFESSIONAL_MODE
...@@ -252,7 +273,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase) ...@@ -252,7 +273,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
# The view should return an error status code # The view should return an error status code
self.assertEqual(response.status_code, 406) self.assertEqual(response.status_code, 406)
msg = Messages.NO_HONOR_MODE.format(course_id=self.course.id) msg = Messages.NO_DEFAULT_ENROLLMENT_MODE.format(course_id=self.course.id)
self.assertResponseMessage(response, msg) self.assertResponseMessage(response, msg)
def test_course_with_professional_mode_only(self): def test_course_with_professional_mode_only(self):
......
...@@ -59,9 +59,9 @@ class BasketsView(APIView): ...@@ -59,9 +59,9 @@ class BasketsView(APIView):
return True, course_key, None return True, course_key, None
def _enroll(self, course_key, user): def _enroll(self, course_key, user, mode=CourseMode.DEFAULT_MODE_SLUG):
""" Enroll the user in the course. """ """ Enroll the user in the course. """
add_enrollment(user.username, unicode(course_key)) add_enrollment(user.username, unicode(course_key), mode)
def _handle_marketing_opt_in(self, request, course_key, user): def _handle_marketing_opt_in(self, request, course_key, user):
""" """
...@@ -100,19 +100,28 @@ class BasketsView(APIView): ...@@ -100,19 +100,28 @@ class BasketsView(APIView):
msg = Messages.ENROLLMENT_EXISTS.format(course_id=course_id, username=user.username) msg = Messages.ENROLLMENT_EXISTS.format(course_id=course_id, username=user.username)
return DetailResponse(msg, status=HTTP_409_CONFLICT) return DetailResponse(msg, status=HTTP_409_CONFLICT)
# If there is no honor course mode, this most likely a Prof-Ed course. Return an error so that the JS # If there is no audit or honor course mode, this most likely
# redirects to track selection. # a Prof-Ed course. Return an error so that the JS redirects
# to track selection.
honor_mode = CourseMode.mode_for_course(course_key, CourseMode.HONOR) honor_mode = CourseMode.mode_for_course(course_key, CourseMode.HONOR)
audit_mode = CourseMode.mode_for_course(course_key, CourseMode.AUDIT)
if not honor_mode: # Accept either honor or audit as an enrollment mode to
msg = Messages.NO_HONOR_MODE.format(course_id=course_id) # maintain backwards compatibility with existing courses
default_enrollment_mode = audit_mode or honor_mode
if not default_enrollment_mode:
msg = Messages.NO_DEFAULT_ENROLLMENT_MODE.format(course_id=course_id)
return DetailResponse(msg, status=HTTP_406_NOT_ACCEPTABLE) return DetailResponse(msg, status=HTTP_406_NOT_ACCEPTABLE)
elif not honor_mode.sku: elif default_enrollment_mode and not default_enrollment_mode.sku:
# If there are no course modes with SKUs, enroll the user without contacting the external API. # 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, msg = Messages.NO_SKU_ENROLLED.format(
username=user.username) enrollment_mode=default_enrollment_mode.slug,
course_id=course_id,
username=user.username
)
log.info(msg) log.info(msg)
self._enroll(course_key, user) self._enroll(course_key, user, default_enrollment_mode.slug)
self._handle_marketing_opt_in(request, course_key, user) self._handle_marketing_opt_in(request, course_key, user)
return DetailResponse(msg) return DetailResponse(msg)
...@@ -131,7 +140,7 @@ class BasketsView(APIView): ...@@ -131,7 +140,7 @@ class BasketsView(APIView):
# Make the API call # Make the API call
try: try:
response_data = api.baskets.post({ response_data = api.baskets.post({
'products': [{'sku': honor_mode.sku}], 'products': [{'sku': default_enrollment_mode.sku}],
'checkout': True, 'checkout': True,
}) })
...@@ -158,7 +167,7 @@ class BasketsView(APIView): ...@@ -158,7 +167,7 @@ class BasketsView(APIView):
audit_log( audit_log(
'checkout_requested', 'checkout_requested',
course_id=course_id, course_id=course_id,
mode=honor_mode.slug, mode=default_enrollment_mode.slug,
processor_name=None, processor_name=None,
user_id=user.id user_id=user.id
) )
......
...@@ -285,7 +285,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase) ...@@ -285,7 +285,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
expected_modes = [ expected_modes = [
CourseMode( CourseMode(
mode_slug=u'honor', mode_slug=CourseMode.DEFAULT_MODE_SLUG,
min_price=150, currency=u'USD', min_price=150, currency=u'USD',
sku=u'ABC123' sku=u'ABC123'
) )
......
...@@ -15,4 +15,5 @@ class Messages(object): ...@@ -15,4 +15,5 @@ class Messages(object):
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.' NO_HONOR_MODE = u'Course {course_id} does not have an honor mode.'
NO_DEFAULT_ENROLLMENT_MODE = u'Course {course_id} does not have an honor or audit mode.'
ENROLLMENT_EXISTS = u'User {username} is already enrolled in {course_id}.' ENROLLMENT_EXISTS = u'User {username} is already enrolled in {course_id}.'
""" """
Test helpers for testing course block transformers. Test helpers for testing course block transformers.
""" """
from course_modes.models import CourseMode
from student.tests.factories import CourseEnrollmentFactory, UserFactory from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
...@@ -221,7 +222,12 @@ class BlockParentsMapTestCase(ModuleStoreTestCase): ...@@ -221,7 +222,12 @@ class BlockParentsMapTestCase(ModuleStoreTestCase):
self.password = 'test' self.password = 'test'
self.student = UserFactory.create(is_staff=False, username='test_student', password=self.password) self.student = UserFactory.create(is_staff=False, username='test_student', password=self.password)
self.staff = UserFactory.create(is_staff=True, username='test_staff', password=self.password) self.staff = UserFactory.create(is_staff=True, username='test_staff', password=self.password)
CourseEnrollmentFactory.create(is_active=True, mode='honor', user=self.student, course_id=self.course.id) CourseEnrollmentFactory.create(
is_active=True,
mode=CourseMode.DEFAULT_MODE_SLUG,
user=self.student,
course_id=self.course.id
)
def assert_transform_results( def assert_transform_results(
self, self,
......
...@@ -58,10 +58,12 @@ class AboutTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, EventTrackingT ...@@ -58,10 +58,12 @@ class AboutTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, EventTrackingT
) )
self.purchase_course = CourseFactory.create(org='MITx', number='buyme', display_name='Course To Buy') self.purchase_course = CourseFactory.create(org='MITx', number='buyme', display_name='Course To Buy')
self.course_mode = CourseMode(course_id=self.purchase_course.id, self.course_mode = CourseMode(
mode_slug="honor", course_id=self.purchase_course.id,
mode_display_name="honor cert", mode_slug=CourseMode.DEFAULT_MODE_SLUG,
min_price=10) mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10
)
self.course_mode.save() self.course_mode.save()
def test_anonymous_user(self): def test_anonymous_user(self):
...@@ -248,8 +250,7 @@ class AboutWithCappedEnrollmentsTestCase(LoginEnrollmentTestCase, ModuleStoreTes ...@@ -248,8 +250,7 @@ class AboutWithCappedEnrollmentsTestCase(LoginEnrollmentTestCase, ModuleStoreTes
self.email = 'foo_second@test.com' self.email = 'foo_second@test.com'
self.password = 'bar' self.password = 'bar'
self.username = 'test_second' self.username = 'test_second'
self.create_account(self.username, self.create_account(self.username, self.email, self.password)
self.email, self.password)
self.activate_user(self.email) self.activate_user(self.email)
self.login(self.email, self.password) self.login(self.email, self.password)
...@@ -417,8 +418,8 @@ class AboutPurchaseCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase): ...@@ -417,8 +418,8 @@ class AboutPurchaseCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
""" """
course_mode = CourseMode( course_mode = CourseMode(
course_id=course.id, course_id=course.id,
mode_slug="honor", mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name="honor cert", mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10, min_price=10,
) )
course_mode.save() course_mode.save()
......
...@@ -201,8 +201,8 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -201,8 +201,8 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" """
course_mode = CourseMode( course_mode = CourseMode(
course_id=self.course_with_visibility.id, course_id=self.course_with_visibility.id,
mode_slug="honor", mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name="honor cert", mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10, min_price=10,
) )
course_mode.save() course_mode.save()
......
...@@ -27,6 +27,7 @@ from xblock.core import XBlock ...@@ -27,6 +27,7 @@ from xblock.core import XBlock
from xblock.fragment import Fragment from xblock.fragment import Fragment
from capa.tests.response_xml_factory import OptionResponseXMLFactory from capa.tests.response_xml_factory import OptionResponseXMLFactory
from course_modes.models import CourseMode
from courseware import module_render as render from courseware import module_render as render
from courseware.courses import get_course_with_access, course_image_url, get_course_info_section from courseware.courses import get_course_with_access, course_image_url, get_course_info_section
from courseware.field_overrides import OverrideFieldData from courseware.field_overrides import OverrideFieldData
...@@ -724,9 +725,9 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -724,9 +725,9 @@ class TestProctoringRendering(ModuleStoreTestCase):
) )
@ddt.data( @ddt.data(
('honor', False, None, None), (CourseMode.DEFAULT_MODE_SLUG, False, None, None),
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
'eligible', 'eligible',
{ {
...@@ -737,7 +738,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -737,7 +738,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
'submitted', 'submitted',
{ {
...@@ -748,7 +749,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -748,7 +749,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
'error', 'error',
{ {
...@@ -759,7 +760,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -759,7 +760,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
None, None,
{ {
...@@ -770,7 +771,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -770,7 +771,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'declined', 'declined',
{ {
...@@ -781,7 +782,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -781,7 +782,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'submitted', 'submitted',
{ {
...@@ -792,7 +793,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -792,7 +793,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'verified', 'verified',
{ {
...@@ -803,7 +804,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -803,7 +804,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'rejected', 'rejected',
{ {
...@@ -814,7 +815,7 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -814,7 +815,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
} }
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'error', 'error',
{ {
...@@ -851,56 +852,56 @@ class TestProctoringRendering(ModuleStoreTestCase): ...@@ -851,56 +852,56 @@ class TestProctoringRendering(ModuleStoreTestCase):
@ddt.data( @ddt.data(
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
None, None,
'Try a proctored exam', 'Try a proctored exam',
True True
), ),
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
'submitted', 'submitted',
'You have submitted this practice proctored exam', 'You have submitted this practice proctored exam',
False False
), ),
( (
'honor', CourseMode.DEFAULT_MODE_SLUG,
True, True,
'error', 'error',
'There was a problem with your practice proctoring session', 'There was a problem with your practice proctoring session',
True True
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
None, None,
'This exam is proctored', 'This exam is proctored',
False False
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'submitted', 'submitted',
'You have submitted this proctored exam for review', 'You have submitted this proctored exam for review',
True True
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'verified', 'verified',
'Your proctoring session was reviewed and passed all requirements', 'Your proctoring session was reviewed and passed all requirements',
False False
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'rejected', 'rejected',
'Your proctoring session was reviewed and did not pass requirements', 'Your proctoring session was reviewed and did not pass requirements',
True True
), ),
( (
'verified', CourseMode.VERIFIED,
False, False,
'error', 'error',
'There was a problem with your proctoring session', 'There was a problem with your proctoring session',
......
...@@ -708,7 +708,7 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -708,7 +708,7 @@ class ProgressPageTests(ModuleStoreTestCase):
) )
# Enroll student into course # Enroll student into course
CourseEnrollment.enroll(self.user, self.course.id, mode='honor') CourseEnrollment.enroll(self.user, self.course.id)
resp = views.progress(self.request, course_id=self.course.id.to_deprecated_string(), student_id=self.user.id) resp = views.progress(self.request, course_id=self.course.id.to_deprecated_string(), student_id=self.user.id)
# Assert that valid 'student_id' returns 200 status # Assert that valid 'student_id' returns 200 status
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
......
...@@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse ...@@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse
from django.core.mail import send_mail from django.core.mail import send_mail
from django.utils.translation import override as override_language from django.utils.translation import override as override_language
from course_modes.models import CourseMode
from student.models import CourseEnrollment, CourseEnrollmentAllowed from student.models import CourseEnrollment, CourseEnrollmentAllowed
from courseware.models import StudentModule from courseware.models import StudentModule
from edxmako.shortcuts import render_to_string from edxmako.shortcuts import render_to_string
...@@ -110,7 +111,7 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal ...@@ -110,7 +111,7 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal
if previous_state.user: if previous_state.user:
# if the student is currently unenrolled, don't enroll them in their # if the student is currently unenrolled, don't enroll them in their
# previous mode # previous mode
course_mode = u"honor" course_mode = CourseMode.DEFAULT_MODE_SLUG
if previous_state.enrollment: if previous_state.enrollment:
course_mode = previous_state.mode course_mode = previous_state.mode
......
...@@ -1275,7 +1275,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest ...@@ -1275,7 +1275,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
create paid course mode. create paid course mode.
""" """
paid_course = CourseFactory.create() paid_course = CourseFactory.create()
CourseModeFactory.create(course_id=paid_course.id, min_price=50) CourseModeFactory.create(course_id=paid_course.id, min_price=50, mode_slug=CourseMode.HONOR)
CourseInstructorRole(paid_course.id).add_users(self.instructor) CourseInstructorRole(paid_course.id).add_users(self.instructor)
return paid_course return paid_course
...@@ -1405,7 +1405,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest ...@@ -1405,7 +1405,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
def test_unenroll_and_enroll_verified(self): def test_unenroll_and_enroll_verified(self):
""" """
Test that unenrolling and enrolling a student from a verified track Test that unenrolling and enrolling a student from a verified track
results in that student being in an honor track results in that student being in the default track
""" """
course_enrollment = CourseEnrollment.objects.get( course_enrollment = CourseEnrollment.objects.get(
user=self.enrolled_student, course_id=self.course.id user=self.enrolled_student, course_id=self.course.id
...@@ -1422,7 +1422,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest ...@@ -1422,7 +1422,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
course_enrollment = CourseEnrollment.objects.get( course_enrollment = CourseEnrollment.objects.get(
user=self.enrolled_student, course_id=self.course.id user=self.enrolled_student, course_id=self.course.id
) )
self.assertEqual(course_enrollment.mode, u'honor') self.assertEqual(course_enrollment.mode, CourseMode.DEFAULT_MODE_SLUG)
def _change_student_enrollment(self, user, course, action): def _change_student_enrollment(self, user, course, action):
""" """
...@@ -2138,7 +2138,11 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment ...@@ -2138,7 +2138,11 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
company_contact_email='test@123', recipient_name='R1', company_contact_email='test@123', recipient_name='R1',
recipient_email='', customer_reference_number='PO#23') recipient_email='', customer_reference_number='PO#23')
paid_course_reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course.id) paid_course_reg_item = PaidCourseRegistration.add_to_order(
self.cart,
self.course.id,
mode_slug=CourseMode.HONOR
)
# update the quantity of the cart item paid_course_reg_item # update the quantity of the cart item paid_course_reg_item
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': paid_course_reg_item.id, 'qty': '4'}) resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': paid_course_reg_item.id, 'qty': '4'})
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
......
""" """
Test for the registration code status information. Test for the registration code status information.
""" """
from course_modes.models import CourseMode
from courseware.tests.factories import InstructorFactory from courseware.tests.factories import InstructorFactory
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
...@@ -116,7 +117,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase): ...@@ -116,7 +117,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor, created_by=self.instructor,
invoice=self.sale_invoice, invoice=self.sale_invoice,
invoice_item=self.invoice_item, invoice_item=self.invoice_item,
mode_slug='honor' mode_slug=CourseMode.DEFAULT_MODE_SLUG
) )
reg_code = CourseRegistrationCode.objects.all()[0] reg_code = CourseRegistrationCode.objects.all()[0]
...@@ -247,7 +248,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase): ...@@ -247,7 +248,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor, created_by=self.instructor,
invoice=self.sale_invoice, invoice=self.sale_invoice,
invoice_item=self.invoice_item, invoice_item=self.invoice_item,
mode_slug='honor', mode_slug=CourseMode.DEFAULT_MODE_SLUG,
is_valid=False is_valid=False
) )
...@@ -278,7 +279,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase): ...@@ -278,7 +279,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor, created_by=self.instructor,
invoice=self.sale_invoice, invoice=self.sale_invoice,
invoice_item=self.invoice_item, invoice_item=self.invoice_item,
mode_slug='honor' mode_slug=CourseMode.DEFAULT_MODE_SLUG,
) )
reg_code = CourseRegistrationCode.objects.all()[0] reg_code = CourseRegistrationCode.objects.all()[0]
......
...@@ -56,10 +56,12 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT ...@@ -56,10 +56,12 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
display_name='<script>alert("XSS")</script>' display_name='<script>alert("XSS")</script>'
) )
self.course_mode = CourseMode(course_id=self.course.id, self.course_mode = CourseMode(
mode_slug="honor", course_id=self.course.id,
mode_display_name="honor cert", mode_slug=CourseMode.DEFAULT_MODE_SLUG,
min_price=40) mode_display_name=CourseMode.DEFAULT_MODE.name,
min_price=40
)
self.course_mode.save() self.course_mode.save()
# Create instructor account # Create instructor account
self.instructor = AdminFactory.create() self.instructor = AdminFactory.create()
......
...@@ -476,7 +476,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour ...@@ -476,7 +476,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour
created_by=self.instructor, created_by=self.instructor,
invoice=self.sale_invoice_1, invoice=self.sale_invoice_1,
invoice_item=self.invoice_item, invoice_item=self.invoice_item,
mode_slug='honor' mode_slug=CourseMode.DEFAULT_MODE_SLUG
) )
course_registration_code.save() course_registration_code.save()
...@@ -517,7 +517,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour ...@@ -517,7 +517,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour
created_by=self.instructor, created_by=self.instructor,
invoice=self.sale_invoice_1, invoice=self.sale_invoice_1,
invoice_item=self.invoice_item, invoice_item=self.invoice_item,
mode_slug='honor' mode_slug=CourseMode.DEFAULT_MODE_SLUG
) )
course_registration_code.save() course_registration_code.save()
......
""" """
Test utils for Facebook functionality Test utils for Facebook functionality
""" """
import httpretty import httpretty
...@@ -10,6 +10,7 @@ from django.conf import settings ...@@ -10,6 +10,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from social.apps.django_app.default.models import UserSocialAuth from social.apps.django_app.default.models import UserSocialAuth
from course_modes.models import CourseMode
from student.models import CourseEnrollment from student.models import CourseEnrollment
from student.views import login_oauth_token from student.views import login_oauth_token
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference
...@@ -182,4 +183,4 @@ class SocialFacebookTestCase(ModuleStoreTestCase, APITestCase): ...@@ -182,4 +183,4 @@ class SocialFacebookTestCase(ModuleStoreTestCase, APITestCase):
self.assertTrue(CourseEnrollment.is_enrolled(user, course.id)) self.assertTrue(CourseEnrollment.is_enrolled(user, course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course.id) course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course.id)
self.assertTrue(is_active) self.assertTrue(is_active)
self.assertEqual(course_mode, 'honor') self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from django.core.management import call_command from django.core.management import call_command
from course_modes.models import CourseMode
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from shoppingcart.models import Order, CertificateItem from shoppingcart.models import Order, CertificateItem
...@@ -16,6 +17,11 @@ class TestRetireOrder(ModuleStoreTestCase): ...@@ -16,6 +17,11 @@ class TestRetireOrder(ModuleStoreTestCase):
course = CourseFactory.create() course = CourseFactory.create()
self.course_key = course.id self.course_key = course.id
CourseMode.objects.create(
course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name=CourseMode.HONOR
)
# set up test carts # set up test carts
self.cart, __ = self._create_cart() self.cart, __ = self._create_cart()
......
...@@ -56,7 +56,13 @@ class OrderTest(ModuleStoreTestCase): ...@@ -56,7 +56,13 @@ class OrderTest(ModuleStoreTestCase):
self.course_key = course.id self.course_key = course.id
self.other_course_keys = [] self.other_course_keys = []
for __ in xrange(1, 5): for __ in xrange(1, 5):
self.other_course_keys.append(CourseFactory.create().id) course_key = CourseFactory.create().id
CourseMode.objects.create(
course_id=course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="Honor"
)
self.other_course_keys.append(course_key)
self.cost = 40 self.cost = 40
# Add mock tracker for event testing. # Add mock tracker for event testing.
...@@ -64,6 +70,12 @@ class OrderTest(ModuleStoreTestCase): ...@@ -64,6 +70,12 @@ class OrderTest(ModuleStoreTestCase):
self.mock_tracker = patcher.start() self.mock_tracker = patcher.start()
self.addCleanup(patcher.stop) self.addCleanup(patcher.stop)
CourseMode.objects.create(
course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="Honor"
)
def test_get_cart_for_user(self): def test_get_cart_for_user(self):
# create a cart # create a cart
cart = Order.get_cart_for_user(user=self.user) cart = Order.get_cart_for_user(user=self.user)
...@@ -479,10 +491,12 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -479,10 +491,12 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.cost = 40 self.cost = 40
self.course = CourseFactory.create() self.course = CourseFactory.create()
self.course_key = self.course.id self.course_key = self.course.id
self.course_mode = CourseMode(course_id=self.course_key, self.course_mode = CourseMode(
mode_slug="honor", course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert", mode_display_name="honor cert",
min_price=self.cost) min_price=self.cost
)
self.course_mode.save() self.course_mode.save()
self.percentage_discount = 20.0 self.percentage_discount = 20.0
self.cart = Order.get_cart_for_user(self.user) self.cart = Order.get_cart_for_user(self.user)
...@@ -492,7 +506,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -492,7 +506,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
Test to check the total amount of the Test to check the total amount of the
purchased items. purchased items.
""" """
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=CourseMode.HONOR)
self.cart.purchase() self.cart.purchase()
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key=self.course_key) total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key=self.course_key)
...@@ -507,7 +521,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -507,7 +521,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.assertEqual(total_amount, 0.00) self.assertEqual(total_amount, 0.00)
def test_add_to_order(self): def test_add_to_order(self):
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key) reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=CourseMode.HONOR)
self.assertEqual(reg1.unit_cost, self.cost) self.assertEqual(reg1.unit_cost, self.cost)
self.assertEqual(reg1.line_cost, self.cost) self.assertEqual(reg1.line_cost, self.cost)
...@@ -545,7 +559,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -545,7 +559,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.cart.order_type = 'business' self.cart.order_type = 'business'
self.cart.save() self.cart.save()
item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2) item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug=CourseMode.HONOR)
self.cart.purchase() self.cart.purchase()
registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key) registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
self.assertEqual(registration_codes.count(), item.qty) self.assertEqual(registration_codes.count(), item.qty)
...@@ -710,14 +724,15 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -710,14 +724,15 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
def test_add_with_default_mode(self): def test_add_with_default_mode(self):
""" """
Tests add_to_cart where the mode specified in the argument is NOT in the database Tests add_to_cart where the mode specified in the argument is NOT
and NOT the default "honor". In this case it just adds the user in the CourseMode.DEFAULT_MODE, 0 price in the database and NOT the default "audit". In this case it
just adds the user in the CourseMode.DEFAULT_MODE for free.
""" """
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug="DNE") reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug="DNE")
self.assertEqual(reg1.unit_cost, 0) self.assertEqual(reg1.unit_cost, 0)
self.assertEqual(reg1.line_cost, 0) self.assertEqual(reg1.line_cost, 0)
self.assertEqual(reg1.mode, "honor") self.assertEqual(reg1.mode, CourseMode.DEFAULT_MODE_SLUG)
self.assertEqual(reg1.user, self.user) self.assertEqual(reg1.user, self.user)
self.assertEqual(reg1.status, "cart") self.assertEqual(reg1.status, "cart")
self.assertEqual(self.cart.total_cost, 0) self.assertEqual(self.cart.total_cost, 0)
...@@ -727,7 +742,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -727,7 +742,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.assertEqual(course_reg_code_item.unit_cost, 0) self.assertEqual(course_reg_code_item.unit_cost, 0)
self.assertEqual(course_reg_code_item.line_cost, 0) self.assertEqual(course_reg_code_item.line_cost, 0)
self.assertEqual(course_reg_code_item.mode, "honor") self.assertEqual(course_reg_code_item.mode, CourseMode.DEFAULT_MODE_SLUG)
self.assertEqual(course_reg_code_item.user, self.user) self.assertEqual(course_reg_code_item.user, self.user)
self.assertEqual(course_reg_code_item.status, "cart") self.assertEqual(course_reg_code_item.status, "cart")
self.assertEqual(self.cart.total_cost, 0) self.assertEqual(self.cart.total_cost, 0)
......
...@@ -184,7 +184,7 @@ class ItemizedPurchaseReportTest(ModuleStoreTestCase): ...@@ -184,7 +184,7 @@ class ItemizedPurchaseReportTest(ModuleStoreTestCase):
self.course_reg_code_annotation = CourseRegCodeItemAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION) self.course_reg_code_annotation = CourseRegCodeItemAnnotation(course_id=self.course_key, annotation=self.TEST_ANNOTATION)
self.course_reg_code_annotation.save() self.course_reg_code_annotation.save()
self.cart = Order.get_cart_for_user(self.user) self.cart = Order.get_cart_for_user(self.user)
self.reg = PaidCourseRegistration.add_to_order(self.cart, self.course_key) self.reg = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=course_mode.mode_slug)
self.cert_item = CertificateItem.add_to_order(self.cart, self.course_key, self.cost, 'verified') self.cert_item = CertificateItem.add_to_order(self.cart, self.course_key, self.cost, 'verified')
self.cart.purchase() self.cart.purchase()
self.now = datetime.datetime.now(pytz.UTC) self.now = datetime.datetime.now(pytz.UTC)
......
...@@ -94,20 +94,41 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -94,20 +94,41 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
self.coupon_code = 'abcde' self.coupon_code = 'abcde'
self.reg_code = 'qwerty' self.reg_code = 'qwerty'
self.percentage_discount = 10 self.percentage_discount = 10
self.course_mode = CourseMode(course_id=self.course_key, self.course_mode = CourseMode(
mode_slug="honor", course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert", mode_display_name="honor cert",
min_price=self.cost) min_price=self.cost
)
self.course_mode.save() self.course_mode.save()
# Saving another testing course mode # Saving another testing course mode
self.testing_cost = 20 self.testing_cost = 20
self.testing_course_mode = CourseMode(course_id=self.testing_course.id, self.testing_course_mode = CourseMode(
mode_slug="honor", course_id=self.testing_course.id,
mode_slug=CourseMode.HONOR,
mode_display_name="testing honor cert", mode_display_name="testing honor cert",
min_price=self.testing_cost) min_price=self.testing_cost
)
self.testing_course_mode.save() self.testing_course_mode.save()
# And for the XSS course
CourseMode(
course_id=self.xss_course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert",
min_price=self.cost
).save()
# And the verified course
self.verified_course_mode = CourseMode(
course_id=self.verified_course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert",
min_price=self.cost
)
self.verified_course_mode.save()
self.cart = Order.get_cart_for_user(self.user) self.cart = Order.get_cart_for_user(self.user)
self.addCleanup(patcher.stop) self.addCleanup(patcher.stop)
...@@ -131,10 +152,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -131,10 +152,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
percentage_discount=self.percentage_discount, created_by=self.user, is_active=is_active) percentage_discount=self.percentage_discount, created_by=self.user, is_active=is_active)
coupon.save() coupon.save()
def add_reg_code(self, course_key, mode_slug='honor', is_valid=True): def add_reg_code(self, course_key, mode_slug=None, is_valid=True):
""" """
add dummy registration code into models add dummy registration code into models
""" """
if mode_slug is None:
mode_slug = self.course_mode.mode_slug
course_reg_code = CourseRegistrationCode( course_reg_code = CourseRegistrationCode(
code=self.reg_code, course_id=course_key, code=self.reg_code, course_id=course_key,
created_by=self.user, mode_slug=mode_slug, created_by=self.user, mode_slug=mode_slug,
...@@ -159,7 +182,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -159,7 +182,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
adding course to user cart adding course to user cart
""" """
self.login_user() self.login_user()
reg_item = PaidCourseRegistration.add_to_order(self.cart, course_key) reg_item = PaidCourseRegistration.add_to_order(self.cart, course_key, mode_slug=self.course_mode.mode_slug)
return reg_item return reg_item
def login_user(self): def login_user(self):
...@@ -224,9 +247,18 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -224,9 +247,18 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
test to check that that the same coupon code applied on multiple test to check that that the same coupon code applied on multiple
items in the cart. 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() self.login_user()
# add first course to user cart # add first course to user cart
resp = self.client.post(reverse('shoppingcart.views.add_course_to_cart', args=[self.course_key.to_deprecated_string()])) resp = self.client.post(
reverse('shoppingcart.views.add_course_to_cart', args=[self.course_key.to_deprecated_string()])
)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
# add and apply the coupon code to course in the cart # add and apply the coupon code to course in the cart
self.add_coupon(self.course_key, True, self.coupon_code) self.add_coupon(self.course_key, True, self.coupon_code)
...@@ -237,7 +269,9 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -237,7 +269,9 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
self.add_coupon(self.testing_course.id, True, self.coupon_code) self.add_coupon(self.testing_course.id, True, self.coupon_code)
#now add the second course to cart, the coupon code should be #now add the second course to cart, the coupon code should be
# applied when adding the second course to the cart # applied when adding the second course to the cart
resp = self.client.post(reverse('shoppingcart.views.add_course_to_cart', args=[self.testing_course.id.to_deprecated_string()])) resp = self.client.post(
reverse('shoppingcart.views.add_course_to_cart', args=[self.testing_course.id.to_deprecated_string()])
)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
#now check the user cart and see that the discount has been applied on both the courses #now check the user cart and see that the discount has been applied on both the courses
resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[])) resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
...@@ -586,7 +620,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -586,7 +620,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
self.add_reg_code(course_key, mode_slug='verified') self.add_reg_code(course_key, mode_slug='verified')
# Enroll as honor in the course with the current user. # Enroll as honor in the course with the current user.
CourseEnrollment.enroll(self.user, self.course_key) CourseEnrollment.enroll(self.user, self.course_key, mode=CourseMode.HONOR)
self.login_user() self.login_user()
current_enrollment, __ = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key) current_enrollment, __ = CourseEnrollment.enrollment_mode_for_user(self.user, self.course_key)
self.assertEquals('honor', current_enrollment) self.assertEquals('honor', current_enrollment)
...@@ -753,8 +787,17 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -753,8 +787,17 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
@patch('shoppingcart.views.render_to_response', render_mock) @patch('shoppingcart.views.render_to_response', render_mock)
def test_show_cart(self): def test_show_cart(self):
self.login_user() self.login_user()
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_key) reg_item = PaidCourseRegistration.add_to_order(
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
cert_item = CertificateItem.add_to_order(
self.cart,
self.verified_course_key,
self.cost,
self.course_mode.mode_slug
)
resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[])) resp = self.client.get(reverse('shoppingcart.views.show_cart', args=[]))
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
...@@ -860,7 +903,6 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -860,7 +903,6 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
for __ in range(num_items): for __ in range(num_items):
CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
self.cart.purchase() self.cart.purchase()
self.login_user() self.login_user()
url = reverse('shoppingcart.views.show_receipt', args=[self.cart.id]) url = reverse('shoppingcart.views.show_receipt', args=[self.cart.id])
resp = self.client.get(url, HTTP_ACCEPT="application/json") resp = self.client.get(url, HTTP_ACCEPT="application/json")
...@@ -891,7 +933,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -891,7 +933,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
'unit_cost': 40, 'unit_cost': 40,
'quantity': 1, 'quantity': 1,
'line_cost': 40, 'line_cost': 40,
'line_desc': 'Honor Code Certificate for course Test Course', 'line_desc': '{} for course Test Course'.format(self.verified_course_mode.mode_display_name),
'course_key': unicode(self.verified_course_key) 'course_key': unicode(self.verified_course_key)
}) })
...@@ -922,8 +964,17 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -922,8 +964,17 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
def test_show_receipt_json_multiple_items(self): def test_show_receipt_json_multiple_items(self):
# Two different item types # Two different item types
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(
CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
CertificateItem.add_to_order(
self.cart,
self.verified_course_key,
self.cost,
self.verified_course_mode.mode_slug
)
self.cart.purchase() self.cart.purchase()
self.login_user() self.login_user()
...@@ -950,7 +1001,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -950,7 +1001,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
'unit_cost': 40, 'unit_cost': 40,
'quantity': 1, 'quantity': 1,
'line_cost': 40, 'line_cost': 40,
'line_desc': 'Honor Code Certificate for course Test Course', 'line_desc': '{} for course Test Course'.format(self.verified_course_mode.mode_display_name),
'course_key': unicode(self.verified_course_key) 'course_key': unicode(self.verified_course_key)
}) })
...@@ -1011,7 +1062,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1011,7 +1062,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
self.client.login(username=self.instructor.username, password="test") self.client.login(username=self.instructor.username, password="test")
cart = Order.get_cart_for_user(self.instructor) cart = Order.get_cart_for_user(self.instructor)
PaidCourseRegistration.add_to_order(cart, self.course_key) PaidCourseRegistration.add_to_order(cart, self.course_key, mode_slug=self.course_mode.mode_slug)
cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course_key) total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course_key)
...@@ -1058,8 +1109,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1058,8 +1109,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
# Two courses in user shopping cart # Two courses in user shopping cart
self.login_user() self.login_user()
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=self.course_mode.mode_slug)
item2 = PaidCourseRegistration.add_to_order(self.cart, self.testing_course.id) item2 = PaidCourseRegistration.add_to_order(
self.cart,
self.testing_course.id,
mode_slug=self.course_mode.mode_slug
)
self.assertEquals(self.cart.orderitem_set.count(), 2) self.assertEquals(self.cart.orderitem_set.count(), 2)
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code}) resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': self.reg_code})
...@@ -1113,7 +1168,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1113,7 +1168,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
@patch('shoppingcart.views.render_to_response', render_mock) @patch('shoppingcart.views.render_to_response', render_mock)
def test_show_receipt_success(self): def test_show_receipt_success(self):
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_key) reg_item = PaidCourseRegistration.add_to_order(
self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
...@@ -1157,7 +1216,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1157,7 +1216,7 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
def test_courseregcode_item_total_price(self): def test_courseregcode_item_total_price(self):
self.cart.order_type = 'business' self.cart.order_type = 'business'
self.cart.save() self.cart.save()
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2) CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug=self.course_mode.mode_slug)
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
self.assertEquals(CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key), 80) self.assertEquals(CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key), 80)
...@@ -1165,7 +1224,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1165,7 +1224,12 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
def test_show_receipt_success_with_order_type_business(self): def test_show_receipt_success_with_order_type_business(self):
self.cart.order_type = 'business' self.cart.order_type = 'business'
self.cart.save() self.cart.save()
reg_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2) reg_item = CourseRegCodeItem.add_to_order(
self.cart,
self.course_key,
2,
mode_slug=self.course_mode.mode_slug
)
self.cart.add_billing_details(company_name='T1Omega', company_contact_name='C1', self.cart.add_billing_details(company_name='T1Omega', company_contact_name='C1',
company_contact_email='test@t1.com', recipient_email='test@t2.com') company_contact_email='test@t1.com', recipient_email='test@t2.com')
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
...@@ -1230,7 +1294,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1230,7 +1294,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
@patch('shoppingcart.views.render_to_response', render_mock) @patch('shoppingcart.views.render_to_response', render_mock)
def test_show_receipt_success_with_upgrade(self): def test_show_receipt_success_with_upgrade(self):
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_key) reg_item = PaidCourseRegistration.add_to_order(
self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
...@@ -1255,7 +1323,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): ...@@ -1255,7 +1323,11 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
@patch('shoppingcart.views.render_to_response', render_mock) @patch('shoppingcart.views.render_to_response', render_mock)
def test_show_receipt_success_refund(self): def test_show_receipt_success_refund(self):
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_key) reg_item = PaidCourseRegistration.add_to_order(
self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor') cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_key, self.cost, 'honor')
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123') self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
cert_item.status = "refunded" cert_item.status = "refunded"
...@@ -1493,10 +1565,12 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase): ...@@ -1493,10 +1565,12 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course') self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course')
self.course_key = self.course.id self.course_key = self.course.id
self.course_mode = CourseMode(course_id=self.course_key, self.course_mode = CourseMode(
mode_slug="honor", course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert", mode_display_name="honor cert",
min_price=self.cost) min_price=self.cost
)
self.course_mode.save() self.course_mode.save()
self.testing_course = CourseFactory.create( self.testing_course = CourseFactory.create(
org='Edx', org='Edx',
...@@ -1504,6 +1578,13 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase): ...@@ -1504,6 +1578,13 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
display_name='Testing Super Course', display_name='Testing Super Course',
metadata={"invitation_only": False} metadata={"invitation_only": False}
) )
self.testing_course_mode = CourseMode(
course_id=self.testing_course.id,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert",
min_price=self.cost
)
self.course_mode.save()
self.percentage_discount = 20.0 self.percentage_discount = 20.0
self.coupon_code = 'asdsad' self.coupon_code = 'asdsad'
self.course_mode = CourseMode(course_id=self.testing_course.id, self.course_mode = CourseMode(course_id=self.testing_course.id,
...@@ -1570,8 +1651,16 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase): ...@@ -1570,8 +1651,16 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
def test_to_check_that_cart_item_enrollment_is_closed_when_clicking_the_payment_button(self): def test_to_check_that_cart_item_enrollment_is_closed_when_clicking_the_payment_button(self):
self.login_user() self.login_user()
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(
PaidCourseRegistration.add_to_order(self.cart, self.testing_course.id) self.cart,
self.course_key,
mode_slug=self.course_mode.mode_slug
)
PaidCourseRegistration.add_to_order(
self.cart,
self.testing_course.id,
mode_slug=self.testing_course_mode.mode_slug
)
# update the testing_course enrollment dates # update the testing_course enrollment dates
self.testing_course.enrollment_start = self.tomorrow self.testing_course.enrollment_start = self.tomorrow
...@@ -1593,8 +1682,8 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase): ...@@ -1593,8 +1682,8 @@ class ShoppingcartViewsClosedEnrollment(ModuleStoreTestCase):
self.login_user() self.login_user()
self.cart.order_type = 'business' self.cart.order_type = 'business'
self.cart.save() self.cart.save()
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=self.course_mode.mode_slug)
CourseRegCodeItem.add_to_order(self.cart, self.testing_course.id, 2) CourseRegCodeItem.add_to_order(self.cart, self.testing_course.id, 2, mode_slug=self.course_mode.mode_slug)
# update the testing_course enrollment dates # update the testing_course enrollment dates
self.testing_course.enrollment_start = self.tomorrow self.testing_course.enrollment_start = self.tomorrow
...@@ -2039,7 +2128,7 @@ class CSVReportViewsTest(SharedModuleStoreTestCase): ...@@ -2039,7 +2128,7 @@ class CSVReportViewsTest(SharedModuleStoreTestCase):
report_type = 'itemized_purchase_report' report_type = 'itemized_purchase_report'
start_date = '1970-01-01' start_date = '1970-01-01'
end_date = '2100-01-01' end_date = '2100-01-01'
PaidCourseRegistration.add_to_order(self.cart, self.course_key) PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=self.course_mode.mode_slug)
self.cart.purchase() self.cart.purchase()
self.login_user() self.login_user()
self.add_to_download_group(self.user) self.add_to_download_group(self.user)
......
...@@ -339,8 +339,11 @@ def register_code_redemption(request, registration_code): ...@@ -339,8 +339,11 @@ def register_code_redemption(request, registration_code):
} }
return render_to_response(template_to_render, context) return render_to_response(template_to_render, context)
elif request.method == "POST": elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code, reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(
request, limiter) registration_code,
request,
limiter
)
course = get_course_by_id(course_registration.course_id, depth=0) course = get_course_by_id(course_registration.course_id, depth=0)
# Restrict the user from enrolling based on country access rules # Restrict the user from enrolling based on country access rules
......
...@@ -17,6 +17,7 @@ from django.test import TestCase ...@@ -17,6 +17,7 @@ from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from django.http import HttpRequest from django.http import HttpRequest
from course_modes.models import CourseMode
from openedx.core.djangoapps.user_api.accounts.api import activate_account, create_account from openedx.core.djangoapps.user_api.accounts.api import activate_account, create_account
from openedx.core.djangoapps.user_api.accounts import EMAIL_MAX_LENGTH from openedx.core.djangoapps.user_api.accounts import EMAIL_MAX_LENGTH
from openedx.core.lib.js_utils import escape_json_dumps from openedx.core.lib.js_utils import escape_json_dumps
...@@ -263,7 +264,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi ...@@ -263,7 +264,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
params = [ params = [
('course_id', 'edX/DemoX/Demo_Course'), ('course_id', 'edX/DemoX/Demo_Course'),
('enrollment_action', 'enroll'), ('enrollment_action', 'enroll'),
('course_mode', 'honor'), ('course_mode', CourseMode.DEFAULT_MODE_SLUG),
('email_opt_in', 'true'), ('email_opt_in', 'true'),
('next', '/custom/final/destination') ('next', '/custom/final/destination')
] ]
...@@ -294,7 +295,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi ...@@ -294,7 +295,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
params = [ params = [
('course_id', 'course-v1:Org+Course+Run'), ('course_id', 'course-v1:Org+Course+Run'),
('enrollment_action', 'enroll'), ('enrollment_action', 'enroll'),
('course_mode', 'honor'), ('course_mode', CourseMode.DEFAULT_MODE_SLUG),
('email_opt_in', 'true'), ('email_opt_in', 'true'),
('next', '/custom/final/destination'), ('next', '/custom/final/destination'),
] ]
......
...@@ -472,6 +472,7 @@ class TestPhotoVerification(ModuleStoreTestCase): ...@@ -472,6 +472,7 @@ class TestPhotoVerification(ModuleStoreTestCase):
@ddt.unpack @ddt.unpack
@ddt.data( @ddt.data(
{'enrollment_mode': 'honor', 'status': None, 'output': 'N/A'}, {'enrollment_mode': 'honor', 'status': None, 'output': 'N/A'},
{'enrollment_mode': 'audit', 'status': None, 'output': 'N/A'},
{'enrollment_mode': 'verified', 'status': False, 'output': 'Not ID Verified'}, {'enrollment_mode': 'verified', 'status': False, 'output': 'Not ID Verified'},
{'enrollment_mode': 'verified', 'status': True, 'output': 'ID Verified'}, {'enrollment_mode': 'verified', 'status': True, 'output': 'ID Verified'},
) )
......
...@@ -105,7 +105,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -105,7 +105,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("verified", "professional") @ddt.data("verified", "professional")
def test_start_flow_not_verified(self, course_mode): def test_start_flow_not_verified(self, course_mode):
course = self._create_course(course_mode) course = self._create_course(course_mode)
self._enroll(course.id, "honor") self._enroll(course.id)
response = self._get_page('verify_student_start_flow', course.id) response = self._get_page('verify_student_start_flow', course.id)
self._assert_displayed_mode(response, course_mode) self._assert_displayed_mode(response, course_mode)
self._assert_steps_displayed( self._assert_steps_displayed(
...@@ -123,8 +123,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -123,8 +123,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("no-id-professional") @ddt.data("no-id-professional")
def test_start_flow_with_no_id_professional(self, course_mode): def test_start_flow_with_no_id_professional(self, course_mode):
course = self._create_course(course_mode) course = self._create_course(course_mode)
# by default enrollment is honor self._enroll(course.id)
self._enroll(course.id, "honor")
response = self._get_page('verify_student_start_flow', course.id) response = self._get_page('verify_student_start_flow', course.id)
self._assert_displayed_mode(response, course_mode) self._assert_displayed_mode(response, course_mode)
self._assert_steps_displayed( self._assert_steps_displayed(
...@@ -164,7 +163,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -164,7 +163,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.unpack @ddt.unpack
def test_start_flow_already_verified(self, course_mode, verification_status): def test_start_flow_already_verified(self, course_mode, verification_status):
course = self._create_course(course_mode) course = self._create_course(course_mode)
self._enroll(course.id, "honor") self._enroll(course.id)
self._set_verification_status(verification_status) self._set_verification_status(verification_status)
response = self._get_page('verify_student_start_flow', course.id) response = self._get_page('verify_student_start_flow', course.id)
self._assert_displayed_mode(response, course_mode) self._assert_displayed_mode(response, course_mode)
...@@ -323,7 +322,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -323,7 +322,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
) )
def test_verify_now_not_paid(self, page_name): def test_verify_now_not_paid(self, page_name):
course = self._create_course("verified") course = self._create_course("verified")
self._enroll(course.id, "honor") self._enroll(course.id)
response = self._get_page(page_name, course.id, expected_status_code=302) response = self._get_page(page_name, course.id, expected_status_code=302)
self._assert_redirects_to_upgrade(response, course.id) self._assert_redirects_to_upgrade(response, course.id)
...@@ -440,7 +439,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -440,7 +439,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("verified", "professional") @ddt.data("verified", "professional")
def test_upgrade(self, course_mode): def test_upgrade(self, course_mode):
course = self._create_course(course_mode) course = self._create_course(course_mode)
self._enroll(course.id, "honor") self._enroll(course.id)
response = self._get_page('verify_student_upgrade_and_verify', course.id) response = self._get_page('verify_student_upgrade_and_verify', course.id)
self._assert_displayed_mode(response, course_mode) self._assert_displayed_mode(response, course_mode)
...@@ -459,7 +458,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -459,7 +458,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
def test_upgrade_already_verified(self): def test_upgrade_already_verified(self):
course = self._create_course("verified") course = self._create_course("verified")
self._enroll(course.id, "honor") self._enroll(course.id)
self._set_verification_status("submitted") self._set_verification_status("submitted")
response = self._get_page('verify_student_upgrade_and_verify', course.id) response = self._get_page('verify_student_upgrade_and_verify', course.id)
...@@ -746,7 +745,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -746,7 +745,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
return course return course
def _enroll(self, course_key, mode): def _enroll(self, course_key, mode=CourseMode.DEFAULT_MODE_SLUG):
"""Enroll the user in a course. """ """Enroll the user in a course. """
CourseEnrollmentFactory.create( CourseEnrollmentFactory.create(
user=self.user, user=self.user,
...@@ -923,8 +922,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -923,8 +922,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
"""Check the course information on the page. """ """Check the course information on the page. """
mode_display_name = u"Introduction à l'astrophysique" mode_display_name = u"Introduction à l'astrophysique"
course = CourseFactory.create(display_name=mode_display_name) course = CourseFactory.create(display_name=mode_display_name)
for course_mode in ["honor", "verified"]: for course_mode in [CourseMode.DEFAULT_MODE_SLUG, "verified"]:
min_price = (self.MIN_PRICE if course_mode != "honor" else 0) min_price = (self.MIN_PRICE if course_mode != CourseMode.DEFAULT_MODE_SLUG else 0)
CourseModeFactory( CourseModeFactory(
course_id=course.id, course_id=course.id,
mode_slug=course_mode, mode_slug=course_mode,
...@@ -932,7 +931,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -932,7 +931,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
min_price=min_price min_price=min_price
) )
self._enroll(course.id, "honor") self._enroll(course.id)
response_dict = self._get_page_data(self._get_page('verify_student_start_flow', course.id)) response_dict = self._get_page_data(self._get_page('verify_student_start_flow', course.id))
self.assertEqual(response_dict['course_name'], mode_display_name) self.assertEqual(response_dict['course_name'], mode_display_name)
...@@ -948,7 +947,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): ...@@ -948,7 +947,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
# setting a nonempty sku on the course will a trigger calls to # setting a nonempty sku on the course will a trigger calls to
# the ecommerce api to get payment processors. # the ecommerce api to get payment processors.
course = self._create_course("verified", sku='nonempty-sku') course = self._create_course("verified", sku='nonempty-sku')
self._enroll(course.id, "honor") self._enroll(course.id)
# mock out the payment processors endpoint # mock out the payment processors endpoint
httpretty.register_uri( httpretty.register_uri(
......
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
); );
}); });
it('sends the user to the payment flow when the course mode is not honor', function() { it('sends the user to the payment flow for a paid course mode', function() {
// Simulate providing enrollment query string params // Simulate providing enrollment query string params
// AND specifying a course mode. // AND specifying a course mode.
setFakeQueryParams({ setFakeQueryParams({
...@@ -114,13 +114,13 @@ ...@@ -114,13 +114,13 @@
); );
}); });
it('sends the user to the student dashboard when the course mode is honor', function() { it('sends the user to the student dashboard for an unpaid course mode', function() {
// Simulate providing enrollment query string params // Simulate providing enrollment query string params
// AND specifying a course mode. // AND specifying a course mode.
setFakeQueryParams({ setFakeQueryParams({
'?enrollment_action': 'enroll', '?enrollment_action': 'enroll',
'?course_id': COURSE_KEY, '?course_id': COURSE_KEY,
'?course_mode': 'honor' '?course_mode': 'audit'
}); });
ajaxSpyAndInitialize(this); ajaxSpyAndInitialize(this);
......
...@@ -26,7 +26,7 @@ var edx = edx || {}; ...@@ -26,7 +26,7 @@ var edx = edx || {};
hasVisibleReqs: false, hasVisibleReqs: false,
platformName: '', platformName: '',
alreadyVerified: false, alreadyVerified: false,
courseModeSlug: 'honor', courseModeSlug: 'audit',
verificationGoodUntil: '' verificationGoodUntil: ''
}; };
}, },
......
...@@ -22,7 +22,7 @@ from lms.djangoapps.verify_student.views import PayAndVerifyView ...@@ -22,7 +22,7 @@ from lms.djangoapps.verify_student.views import PayAndVerifyView
${_(u"The verification deadline for {course_name} was {date}. Verification is no longer available.").format( ${_(u"The verification deadline for {course_name} was {date}. Verification is no longer available.").format(
course_name=course.display_name, date=deadline)} course_name=course.display_name, date=deadline)}
% elif deadline_name == PayAndVerifyView.UPGRADE_DEADLINE: % elif deadline_name == PayAndVerifyView.UPGRADE_DEADLINE:
${_(u"The deadline to upgrade to a verified certificate for this course has passed. You can still earn an honor code certificate.")} ${_(u"The deadline to upgrade to a verified certificate for this course has passed.")}
% endif % endif
</p> </p>
</section> </section>
......
...@@ -25,6 +25,15 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -25,6 +25,15 @@ class CreditServiceTests(ModuleStoreTestCase):
self.credit_course = CreditCourse.objects.create(course_key=self.course.id, enabled=True) self.credit_course = CreditCourse.objects.create(course_key=self.course.id, enabled=True)
self.profile = UserProfile.objects.create(user_id=self.user.id, name='Foo Bar') self.profile = UserProfile.objects.create(user_id=self.user.id, name='Foo Bar')
def enroll(self, course_id=None):
"""
Enroll the test user in the given course's honor mode, or the test
course if not provided.
"""
if course_id is None:
course_id = self.course.id
return CourseEnrollment.enroll(self.user, course_id, mode='honor')
def test_user_not_found(self): def test_user_not_found(self):
""" """
Makes sure that get_credit_state returns None if user_id cannot be found Makes sure that get_credit_state returns None if user_id cannot be found
...@@ -46,7 +55,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -46,7 +55,7 @@ class CreditServiceTests(ModuleStoreTestCase):
inactive inactive
""" """
enrollment = CourseEnrollment.enroll(self.user, self.course.id) enrollment = self.enroll()
enrollment.is_active = False enrollment.is_active = False
enrollment.save() enrollment.save()
...@@ -58,7 +67,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -58,7 +67,7 @@ class CreditServiceTests(ModuleStoreTestCase):
Credit eligible Credit eligible
""" """
CourseEnrollment.enroll(self.user, self.course.id) self.enroll()
self.credit_course.enabled = False self.credit_course.enabled = False
self.credit_course.save() self.credit_course.save()
...@@ -86,7 +95,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -86,7 +95,7 @@ class CreditServiceTests(ModuleStoreTestCase):
self.assertTrue(self.service.is_credit_course(self.course.id)) self.assertTrue(self.service.is_credit_course(self.course.id))
CourseEnrollment.enroll(self.user, self.course.id) self.enroll()
# set course requirements # set course requirements
set_credit_requirements( set_credit_requirements(
...@@ -127,7 +136,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -127,7 +136,7 @@ class CreditServiceTests(ModuleStoreTestCase):
""" """
self.assertTrue(self.service.is_credit_course(self.course.id)) self.assertTrue(self.service.is_credit_course(self.course.id))
CourseEnrollment.enroll(self.user, self.course.id) self.enroll()
# set course requirements # set course requirements
set_credit_requirements( set_credit_requirements(
...@@ -216,7 +225,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -216,7 +225,7 @@ class CreditServiceTests(ModuleStoreTestCase):
self.assertFalse(self.service.is_credit_course(no_credit_course.id)) self.assertFalse(self.service.is_credit_course(no_credit_course.id))
CourseEnrollment.enroll(self.user, no_credit_course.id) self.enroll(no_credit_course.id)
# this should be a no-op # this should be a no-op
self.service.remove_credit_requirement_status( self.service.remove_credit_requirement_status(
...@@ -237,7 +246,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -237,7 +246,7 @@ class CreditServiceTests(ModuleStoreTestCase):
Make sure we can get back the optional course name Make sure we can get back the optional course name
""" """
CourseEnrollment.enroll(self.user, self.course.id) self.enroll()
# make sure it is not returned by default # make sure it is not returned by default
credit_state = self.service.get_credit_state(self.user.id, self.course.id) credit_state = self.service.get_credit_state(self.user.id, self.course.id)
...@@ -258,7 +267,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -258,7 +267,7 @@ class CreditServiceTests(ModuleStoreTestCase):
self.assertFalse(self.service.is_credit_course(no_credit_course.id)) self.assertFalse(self.service.is_credit_course(no_credit_course.id))
CourseEnrollment.enroll(self.user, no_credit_course.id) self.enroll(no_credit_course.id)
# this should be a no-op # this should be a no-op
self.service.set_credit_requirement_status( self.service.set_credit_requirement_status(
...@@ -308,7 +317,7 @@ class CreditServiceTests(ModuleStoreTestCase): ...@@ -308,7 +317,7 @@ class CreditServiceTests(ModuleStoreTestCase):
Make sure we can pass a course_id (string) and get back correct results as well Make sure we can pass a course_id (string) and get back correct results as well
""" """
CourseEnrollment.enroll(self.user, self.course.id) self.enroll()
# set course requirements # set course requirements
set_credit_requirements( set_credit_requirements(
......
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