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):
certificate_web_view_url = get_lms_link_for_certificate_web_view(
user_id=request.user.id,
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
is_active = False
......
......@@ -94,8 +94,8 @@ class CourseMode(models.Model):
NO_ID_PROFESSIONAL_MODE = "no-id-professional"
CREDIT_MODE = "credit"
DEFAULT_MODE = Mode(HONOR, _('Honor Code Certificate'), 0, '', 'usd', None, None, None)
DEFAULT_MODE_SLUG = HONOR
DEFAULT_MODE = Mode(AUDIT, _('Audit'), 0, '', 'usd', None, None, None)
DEFAULT_MODE_SLUG = AUDIT
# Modes that allow a student to pursue a verified certificate
VERIFIED_MODES = [VERIFIED, PROFESSIONAL]
......@@ -107,7 +107,7 @@ class CourseMode(models.Model):
CREDIT_MODES = [CREDIT_MODE]
# Modes that are allowed to upsell
UPSELL_TO_VERIFIED_MODES = [HONOR]
UPSELL_TO_VERIFIED_MODES = [HONOR, AUDIT]
class Meta(object):
unique_together = ('course_id', 'mode_slug', 'currency')
......@@ -507,7 +507,7 @@ class CourseMode(models.Model):
return False
# Check that the default mode is available.
return cls.HONOR in modes_dict
return cls.DEFAULT_MODE_SLUG in modes_dict
@classmethod
def is_white_label(cls, course_id, modes_dict=None):
......
......@@ -177,6 +177,7 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
# Mapping of course modes to the POST parameters sent
# when the user chooses that mode.
POST_PARAMS_FOR_COURSE_MODE = {
'audit': {},
'honor': {'honor_mode': True},
'verified': {'verified_mode': True, 'contribution': '1.23'},
'unsupported': {'unsupported_mode': True},
......@@ -227,9 +228,9 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
expected_amount = decimal.Decimal(self.POST_PARAMS_FOR_COURSE_MODE['verified']['contribution'])
self.assertEqual(actual_amount, expected_amount)
def test_successful_honor_enrollment(self):
def test_successful_default_enrollment(self):
# 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)
# Enroll the user in the default mode (honor) to emulate
......@@ -242,11 +243,11 @@ class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
# Explicitly select the honor mode (POST request)
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
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)
def test_unsupported_enrollment_mode_failure(self):
......
......@@ -7,6 +7,7 @@ import importlib
import logging
from django.conf import settings
from django.core.cache import cache
from course_modes.models import CourseMode
from enrollment import errors
log = logging.getLogger(__name__)
......@@ -132,10 +133,10 @@ def get_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. 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:
user_id (str): The user to enroll.
......@@ -143,7 +144,7 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
Keyword Arguments:
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
defaults to 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")
{
"created": "2014-10-20T20:18:00Z",
"mode": "honor",
"mode": "audit",
"is_active": True,
"user": "Bob",
"course": {
......@@ -165,8 +166,8 @@ def add_enrollment(user_id, course_id, mode='honor', is_active=True):
"course_end": "2015-05-06T00:00:00Z",
"course_modes": [
{
"slug": "honor",
"name": "Honor Code Certificate",
"slug": "audit",
"name": "Audit",
"min_price": 0,
"suggested_prices": "",
"currency": "usd",
......
......@@ -287,9 +287,10 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
* Enroll the currently signed in user in a course.
Currently a user can use this command only to enroll the user in
honor mode. If honor mode is not supported for the course, the
request fails and returns the available modes.
Currently a user can use this command only to enroll the
user in the default course mode. If this is not
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
other modes, such as "verified", "professional", or "credit". If
......@@ -325,7 +326,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
You cannot use the command to enroll a different user.
* 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.
* is_active: Optional. A Boolean value indicating whether the
......@@ -353,7 +354,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
deactivate an enrollment.
* 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.
* user: Optional. The user ID of the currently logged in user. You
......@@ -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)
......@@ -531,7 +532,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
# other users, do not let them deduce the existence of an enrollment.
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(
status=status.HTTP_403_FORBIDDEN,
data={
......
......@@ -895,7 +895,7 @@ class CourseEnrollment(models.Model):
# Represents the modes that are possible. We'll update this later with a
# 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()
......@@ -957,7 +957,7 @@ class CourseEnrollment(models.Model):
# If we *did* just create a new enrollment, set some defaults
if created:
enrollment.mode = "honor"
enrollment.mode = CourseMode.DEFAULT_MODE_SLUG
enrollment.is_active = False
enrollment.save()
......@@ -1043,8 +1043,8 @@ class CourseEnrollment(models.Model):
u"mode:{}".format(self.mode)]
)
if mode_changed:
# the user's default mode is "honor" and disabled for a course
# mode change events will only be emitted when the user's mode changes from this
# Only emit mode change events when the user's enrollment
# mode has changed from its previous setting
self.emit_event(EVENT_NAME_ENROLLMENT_MODE_CHANGED)
def emit_event(self, event_name):
......@@ -1090,7 +1090,7 @@ class CourseEnrollment(models.Model):
)
@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.
......@@ -1103,8 +1103,8 @@ class CourseEnrollment(models.Model):
`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
default is 'honor', meaning honor certificate. Other options
include 'professional', 'verified', 'audit',
default is the default course mode, 'audit'. Other options
include 'professional', 'verified', 'honor',
'no-id-professional' and 'credit'.
See CourseMode in common/djangoapps/course_modes/models.py.
......@@ -1165,7 +1165,7 @@ class CourseEnrollment(models.Model):
return enrollment
@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.
......@@ -1181,9 +1181,10 @@ class CourseEnrollment(models.Model):
`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
default is "honor", meaning honor certificate. Future options
may include "audit", "verified_id", etc. Please don't use it
until we have these mapped out.
default is the default course mode, 'audit'. Other options
include 'professional', 'verified', 'honor',
'no-id-professional' and 'credit'.
See CourseMode in common/djangoapps/course_modes/models.py.
`ignore_errors` is a boolean indicating whether we should suppress
`User.DoesNotExist` errors (returning None) or let it
......
......@@ -52,8 +52,8 @@ class CourseModeFactory(DjangoModelFactory):
model = CourseMode
course_id = None
mode_display_name = u'Honor Code',
mode_slug = 'honor'
mode_display_name = CourseMode.DEFAULT_MODE.name
mode_slug = CourseMode.DEFAULT_MODE_SLUG
min_price = 0
suggested_prices = ''
currency = 'usd'
......
......@@ -7,6 +7,7 @@ from mock import patch
from django.conf import settings
from django.core.urlresolvers import reverse
from course_modes.models import CourseMode
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from util.testing import UrlResetMixin
......@@ -41,13 +42,13 @@ class EnrollmentTest(UrlResetMixin, ModuleStoreTestCase):
@ddt.data(
# Default (no course modes in the database)
# Expect that we're redirected to the dashboard
# and automatically enrolled as "honor"
([], '', 'honor'),
# and automatically enrolled
([], '', CourseMode.DEFAULT_MODE_SLUG),
# Audit / Verified / Honor
# We should always go to the "choose your course" page.
# We should also be enrolled as "honor" by default.
(['honor', 'verified', 'audit'], 'course_modes_choose', 'honor'),
# We should also be enrolled as the default mode.
(['honor', 'verified', 'audit'], 'course_modes_choose', CourseMode.DEFAULT_MODE_SLUG),
# Professional ed
# Expect that we're sent to the "choose your track" page
......
......@@ -127,22 +127,21 @@ class TestRecentEnrollments(ModuleStoreTestCase):
self.assertContains(response, "Thank you for enrolling in")
@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),
([('honor', 0)], 'honor', True),
([], 'honor', True),
#Register as an honor in any course modes which has payment option
# Register as honor in any course modes which has payment option
([('honor', 10)], 'honor', False), # This is a paid course
([('audit', 0), ('honor', 0), ('professional', 20)], 'honor', True),
([('audit', 0), ('honor', 0), ('verified', 20)], 'honor', True),
([('audit', 0), ('honor', 0), ('verified', 20), ('professional', 20)], 'honor', True),
([], 'honor', True),
#Register as an audit in any course modes with no payment option
# Register as audit in any course modes with no payment option
([('audit', 0), ('honor', 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),
#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),
([('verified', 20)], 'verified', False),
([('professional', 20), ('verified', 20)], 'verified', False),
......
......@@ -18,6 +18,7 @@ from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.client import Client
from course_modes.models import CourseMode
from student.models import (
anonymous_id_for_user, user_by_anonymous_id, CourseEnrollment,
unique_id_for_user, LinkedInAddToProfileConfiguration
......@@ -321,7 +322,12 @@ class DashboardTest(ModuleStoreTestCase):
course_id=self.course.id
)
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()
......@@ -339,7 +345,6 @@ class DashboardTest(ModuleStoreTestCase):
#now activate the user by enrolling him/her to the course
response = self.client.post(redeem_url)
self.assertEquals(response.status_code, 200)
response = self.client.get(reverse('dashboard'))
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)
......@@ -566,7 +571,7 @@ class EnrollmentEventTestMixin(EventTestMixin):
{
'course_id': course_key.to_deprecated_string(),
'user_id': user.pk,
'mode': 'honor'
'mode': CourseMode.DEFAULT_MODE_SLUG
}
)
self.mock_tracker.reset_mock()
......@@ -578,7 +583,7 @@ class EnrollmentEventTestMixin(EventTestMixin):
{
'course_id': course_key.to_deprecated_string(),
'user_id': user.pk,
'mode': 'honor'
'mode': CourseMode.DEFAULT_MODE_SLUG
}
)
self.mock_tracker.reset_mock()
......@@ -754,18 +759,18 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, TestCase):
user = User.objects.create(username="justin", email="jh@fake.edx.org")
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)
CourseEnrollment.enroll(user, course_id, "audit")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "audit")
CourseEnrollment.enroll(user, course_id, "honor")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "honor")
# 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()
CourseEnrollment.enroll(user, course_id, "honor")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "honor")
CourseEnrollment.enroll(user, course_id, "audit")
self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "audit")
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
......@@ -789,7 +794,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
)
return response
def test_enroll_as_honor(self):
def test_enroll_as_default(self):
"""Tests that a student can successfully enroll through this view"""
response = self._enroll_through_view(self.course)
self.assertEqual(response.status_code, 200)
......@@ -797,7 +802,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id
)
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):
"""
......@@ -810,14 +815,14 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
response = self._enroll_through_view(self.course)
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
accidentally change their enrollment to verified
accidentally change their enrollment mode
"""
CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified')
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)
self.assertEqual(response.status_code, 400)
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
......@@ -826,7 +831,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.assertTrue(is_active)
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
"""
......@@ -847,7 +852,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id
)
self.assertTrue(is_active)
self.assertEqual(enrollment_mode, u'honor')
self.assertEqual(enrollment_mode, CourseMode.DEFAULT_MODE_SLUG)
class AnonymousLookupTable(ModuleStoreTestCase):
......
......@@ -13,6 +13,7 @@ from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from config_models.models import cache
from util.testing import EventTestMixin
......@@ -305,6 +306,7 @@ class GenerateExampleCertificatesTest(TestCase):
def test_generate_example_certs(self):
# Generate certificates for the course
CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug=CourseMode.HONOR)
with self._mock_xqueue() as mock_queue:
certs_api.generate_example_certificates(self.COURSE_KEY)
......
......@@ -197,7 +197,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
with mock_create_basket(response=return_value):
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.
"""
......@@ -207,13 +207,16 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
# Validate the response content
self.assertEqual(response.status_code, 200)
msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode='honor', course_id=self.course.id,
username=self.user.username)
msg = Messages.NO_SKU_ENROLLED.format(
enrollment_mode=enrollment_mode,
course_id=self.course.id,
username=self.user.username
)
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.
"""
# Remove SKU from all course modes
......@@ -223,6 +226,24 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
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)
def test_ecommerce_service_not_configured(self):
"""
......@@ -240,7 +261,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
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()
mode = CourseMode.NO_ID_PROFESSIONAL_MODE
......@@ -252,7 +273,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
# The view should return an error status code
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)
def test_course_with_professional_mode_only(self):
......
......@@ -59,9 +59,9 @@ class BasketsView(APIView):
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. """
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):
"""
......@@ -100,19 +100,28 @@ class BasketsView(APIView):
msg = Messages.ENROLLMENT_EXISTS.format(course_id=course_id, username=user.username)
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
# redirects to track selection.
# If there is no audit or honor course mode, this most likely
# 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)
audit_mode = CourseMode.mode_for_course(course_key, CourseMode.AUDIT)
if not honor_mode:
msg = Messages.NO_HONOR_MODE.format(course_id=course_id)
# Accept either honor or audit as an enrollment mode to
# 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)
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.
msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode=CourseMode.HONOR, course_id=course_id,
username=user.username)
msg = Messages.NO_SKU_ENROLLED.format(
enrollment_mode=default_enrollment_mode.slug,
course_id=course_id,
username=user.username
)
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)
return DetailResponse(msg)
......@@ -131,7 +140,7 @@ class BasketsView(APIView):
# Make the API call
try:
response_data = api.baskets.post({
'products': [{'sku': honor_mode.sku}],
'products': [{'sku': default_enrollment_mode.sku}],
'checkout': True,
})
......@@ -158,7 +167,7 @@ class BasketsView(APIView):
audit_log(
'checkout_requested',
course_id=course_id,
mode=honor_mode.slug,
mode=default_enrollment_mode.slug,
processor_name=None,
user_id=user.id
)
......
......@@ -285,7 +285,7 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
expected_modes = [
CourseMode(
mode_slug=u'honor',
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
min_price=150, currency=u'USD',
sku=u'ABC123'
)
......
......@@ -15,4 +15,5 @@ class Messages(object):
ORDER_COMPLETED = u'Order {order_number} was completed.'
ORDER_INCOMPLETE_ENROLLED = u'Order {order_number} was created, but is not yet complete. User was enrolled.'
NO_HONOR_MODE = u'Course {course_id} does not have an honor mode.'
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}.'
"""
Test helpers for testing course block transformers.
"""
from course_modes.models import CourseMode
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
......@@ -221,7 +222,12 @@ class BlockParentsMapTestCase(ModuleStoreTestCase):
self.password = 'test'
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)
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(
self,
......
......@@ -58,10 +58,12 @@ class AboutTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, EventTrackingT
)
self.purchase_course = CourseFactory.create(org='MITx', number='buyme', display_name='Course To Buy')
self.course_mode = CourseMode(course_id=self.purchase_course.id,
mode_slug="honor",
mode_display_name="honor cert",
min_price=10)
self.course_mode = CourseMode(
course_id=self.purchase_course.id,
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10
)
self.course_mode.save()
def test_anonymous_user(self):
......@@ -248,8 +250,7 @@ class AboutWithCappedEnrollmentsTestCase(LoginEnrollmentTestCase, ModuleStoreTes
self.email = 'foo_second@test.com'
self.password = 'bar'
self.username = 'test_second'
self.create_account(self.username,
self.email, self.password)
self.create_account(self.username, self.email, self.password)
self.activate_user(self.email)
self.login(self.email, self.password)
......@@ -417,8 +418,8 @@ class AboutPurchaseCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
"""
course_mode = CourseMode(
course_id=course.id,
mode_slug="honor",
mode_display_name="honor cert",
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10,
)
course_mode.save()
......
......@@ -201,8 +201,8 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
"""
course_mode = CourseMode(
course_id=self.course_with_visibility.id,
mode_slug="honor",
mode_display_name="honor cert",
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
min_price=10,
)
course_mode.save()
......
......@@ -27,6 +27,7 @@ from xblock.core import XBlock
from xblock.fragment import Fragment
from capa.tests.response_xml_factory import OptionResponseXMLFactory
from course_modes.models import CourseMode
from courseware import module_render as render
from courseware.courses import get_course_with_access, course_image_url, get_course_info_section
from courseware.field_overrides import OverrideFieldData
......@@ -724,9 +725,9 @@ class TestProctoringRendering(ModuleStoreTestCase):
)
@ddt.data(
('honor', False, None, None),
(CourseMode.DEFAULT_MODE_SLUG, False, None, None),
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
'eligible',
{
......@@ -737,7 +738,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
'submitted',
{
......@@ -748,7 +749,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
'error',
{
......@@ -759,7 +760,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
None,
{
......@@ -770,7 +771,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
'declined',
{
......@@ -781,7 +782,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
'submitted',
{
......@@ -792,7 +793,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
'verified',
{
......@@ -803,7 +804,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
'rejected',
{
......@@ -814,7 +815,7 @@ class TestProctoringRendering(ModuleStoreTestCase):
}
),
(
'verified',
CourseMode.VERIFIED,
False,
'error',
{
......@@ -851,56 +852,56 @@ class TestProctoringRendering(ModuleStoreTestCase):
@ddt.data(
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
None,
'Try a proctored exam',
True
),
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
'submitted',
'You have submitted this practice proctored exam',
False
),
(
'honor',
CourseMode.DEFAULT_MODE_SLUG,
True,
'error',
'There was a problem with your practice proctoring session',
True
),
(
'verified',
CourseMode.VERIFIED,
False,
None,
'This exam is proctored',
False
),
(
'verified',
CourseMode.VERIFIED,
False,
'submitted',
'You have submitted this proctored exam for review',
True
),
(
'verified',
CourseMode.VERIFIED,
False,
'verified',
'Your proctoring session was reviewed and passed all requirements',
False
),
(
'verified',
CourseMode.VERIFIED,
False,
'rejected',
'Your proctoring session was reviewed and did not pass requirements',
True
),
(
'verified',
CourseMode.VERIFIED,
False,
'error',
'There was a problem with your proctoring session',
......
......@@ -708,7 +708,7 @@ class ProgressPageTests(ModuleStoreTestCase):
)
# 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)
# Assert that valid 'student_id' returns 200 status
self.assertEqual(resp.status_code, 200)
......
......@@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.utils.translation import override as override_language
from course_modes.models import CourseMode
from student.models import CourseEnrollment, CourseEnrollmentAllowed
from courseware.models import StudentModule
from edxmako.shortcuts import render_to_string
......@@ -110,7 +111,7 @@ def enroll_email(course_id, student_email, auto_enroll=False, email_students=Fal
if previous_state.user:
# if the student is currently unenrolled, don't enroll them in their
# previous mode
course_mode = u"honor"
course_mode = CourseMode.DEFAULT_MODE_SLUG
if previous_state.enrollment:
course_mode = previous_state.mode
......
......@@ -1275,7 +1275,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
create paid course mode.
"""
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)
return paid_course
......@@ -1405,7 +1405,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
def test_unenroll_and_enroll_verified(self):
"""
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(
user=self.enrolled_student, course_id=self.course.id
......@@ -1422,7 +1422,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
course_enrollment = CourseEnrollment.objects.get(
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):
"""
......@@ -2138,7 +2138,11 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
company_contact_email='test@123', recipient_name='R1',
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
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': paid_course_reg_item.id, 'qty': '4'})
self.assertEqual(resp.status_code, 200)
......
"""
Test for the registration code status information.
"""
from course_modes.models import CourseMode
from courseware.tests.factories import InstructorFactory
from xmodule.modulestore.tests.factories import CourseFactory
from django.utils.translation import ugettext as _
......@@ -116,7 +117,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor,
invoice=self.sale_invoice,
invoice_item=self.invoice_item,
mode_slug='honor'
mode_slug=CourseMode.DEFAULT_MODE_SLUG
)
reg_code = CourseRegistrationCode.objects.all()[0]
......@@ -247,7 +248,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor,
invoice=self.sale_invoice,
invoice_item=self.invoice_item,
mode_slug='honor',
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
is_valid=False
)
......@@ -278,7 +279,7 @@ class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
created_by=self.instructor,
invoice=self.sale_invoice,
invoice_item=self.invoice_item,
mode_slug='honor'
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
)
reg_code = CourseRegistrationCode.objects.all()[0]
......
......@@ -56,10 +56,12 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
display_name='<script>alert("XSS")</script>'
)
self.course_mode = CourseMode(course_id=self.course.id,
mode_slug="honor",
mode_display_name="honor cert",
min_price=40)
self.course_mode = CourseMode(
course_id=self.course.id,
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.DEFAULT_MODE.name,
min_price=40
)
self.course_mode.save()
# Create instructor account
self.instructor = AdminFactory.create()
......
......@@ -476,7 +476,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour
created_by=self.instructor,
invoice=self.sale_invoice_1,
invoice_item=self.invoice_item,
mode_slug='honor'
mode_slug=CourseMode.DEFAULT_MODE_SLUG
)
course_registration_code.save()
......@@ -517,7 +517,7 @@ class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCour
created_by=self.instructor,
invoice=self.sale_invoice_1,
invoice_item=self.invoice_item,
mode_slug='honor'
mode_slug=CourseMode.DEFAULT_MODE_SLUG
)
course_registration_code.save()
......
"""
Test utils for Facebook functionality
Test utils for Facebook functionality
"""
import httpretty
......@@ -10,6 +10,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse
from social.apps.django_app.default.models import UserSocialAuth
from course_modes.models import CourseMode
from student.models import CourseEnrollment
from student.views import login_oauth_token
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, set_user_preference
......@@ -182,4 +183,4 @@ class SocialFacebookTestCase(ModuleStoreTestCase, APITestCase):
self.assertTrue(CourseEnrollment.is_enrolled(user, course.id))
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course.id)
self.assertTrue(is_active)
self.assertEqual(course_mode, 'honor')
self.assertEqual(course_mode, CourseMode.DEFAULT_MODE_SLUG)
......@@ -3,6 +3,7 @@
from tempfile import NamedTemporaryFile
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.factories import CourseFactory
from shoppingcart.models import Order, CertificateItem
......@@ -16,6 +17,11 @@ class TestRetireOrder(ModuleStoreTestCase):
course = CourseFactory.create()
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
self.cart, __ = self._create_cart()
......
......@@ -56,7 +56,13 @@ class OrderTest(ModuleStoreTestCase):
self.course_key = course.id
self.other_course_keys = []
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
# Add mock tracker for event testing.
......@@ -64,6 +70,12 @@ class OrderTest(ModuleStoreTestCase):
self.mock_tracker = patcher.start()
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):
# create a cart
cart = Order.get_cart_for_user(user=self.user)
......@@ -479,10 +491,12 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.cost = 40
self.course = CourseFactory.create()
self.course_key = self.course.id
self.course_mode = CourseMode(course_id=self.course_key,
mode_slug="honor",
mode_display_name="honor cert",
min_price=self.cost)
self.course_mode = CourseMode(
course_id=self.course_key,
mode_slug=CourseMode.HONOR,
mode_display_name="honor cert",
min_price=self.cost
)
self.course_mode.save()
self.percentage_discount = 20.0
self.cart = Order.get_cart_for_user(self.user)
......@@ -492,7 +506,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
Test to check the total amount of the
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()
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key=self.course_key)
......@@ -507,7 +521,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.assertEqual(total_amount, 0.00)
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.line_cost, self.cost)
......@@ -545,7 +559,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.cart.order_type = 'business'
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()
registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
self.assertEqual(registration_codes.count(), item.qty)
......@@ -710,14 +724,15 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
def test_add_with_default_mode(self):
"""
Tests add_to_cart where the mode specified in the argument is NOT in the database
and NOT the default "honor". In this case it just adds the user in the CourseMode.DEFAULT_MODE, 0 price
Tests add_to_cart where the mode specified in the argument is NOT
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")
self.assertEqual(reg1.unit_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.status, "cart")
self.assertEqual(self.cart.total_cost, 0)
......@@ -727,7 +742,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.assertEqual(course_reg_code_item.unit_cost, 0)
self.assertEqual(course_reg_code_item.line_cost, 0)
self.assertEqual(course_reg_code_item.mode, "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.status, "cart")
self.assertEqual(self.cart.total_cost, 0)
......
......@@ -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.save()
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.cart.purchase()
self.now = datetime.datetime.now(pytz.UTC)
......
......@@ -339,8 +339,11 @@ def register_code_redemption(request, registration_code):
}
return render_to_response(template_to_render, context)
elif request.method == "POST":
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(registration_code,
request, limiter)
reg_code_is_valid, reg_code_already_redeemed, course_registration = get_reg_code_validity(
registration_code,
request,
limiter
)
course = get_course_by_id(course_registration.course_id, depth=0)
# Restrict the user from enrolling based on country access rules
......
......@@ -17,6 +17,7 @@ from django.test import TestCase
from django.test.utils import override_settings
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 import EMAIL_MAX_LENGTH
from openedx.core.lib.js_utils import escape_json_dumps
......@@ -263,7 +264,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
params = [
('course_id', 'edX/DemoX/Demo_Course'),
('enrollment_action', 'enroll'),
('course_mode', 'honor'),
('course_mode', CourseMode.DEFAULT_MODE_SLUG),
('email_opt_in', 'true'),
('next', '/custom/final/destination')
]
......@@ -294,7 +295,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi
params = [
('course_id', 'course-v1:Org+Course+Run'),
('enrollment_action', 'enroll'),
('course_mode', 'honor'),
('course_mode', CourseMode.DEFAULT_MODE_SLUG),
('email_opt_in', 'true'),
('next', '/custom/final/destination'),
]
......
......@@ -472,6 +472,7 @@ class TestPhotoVerification(ModuleStoreTestCase):
@ddt.unpack
@ddt.data(
{'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': True, 'output': 'ID Verified'},
)
......
......@@ -105,7 +105,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("verified", "professional")
def test_start_flow_not_verified(self, 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)
self._assert_displayed_mode(response, course_mode)
self._assert_steps_displayed(
......@@ -123,8 +123,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("no-id-professional")
def test_start_flow_with_no_id_professional(self, course_mode):
course = self._create_course(course_mode)
# by default enrollment is honor
self._enroll(course.id, "honor")
self._enroll(course.id)
response = self._get_page('verify_student_start_flow', course.id)
self._assert_displayed_mode(response, course_mode)
self._assert_steps_displayed(
......@@ -164,7 +163,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.unpack
def test_start_flow_already_verified(self, course_mode, verification_status):
course = self._create_course(course_mode)
self._enroll(course.id, "honor")
self._enroll(course.id)
self._set_verification_status(verification_status)
response = self._get_page('verify_student_start_flow', course.id)
self._assert_displayed_mode(response, course_mode)
......@@ -323,7 +322,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
)
def test_verify_now_not_paid(self, page_name):
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)
self._assert_redirects_to_upgrade(response, course.id)
......@@ -440,7 +439,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
@ddt.data("verified", "professional")
def test_upgrade(self, 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)
self._assert_displayed_mode(response, course_mode)
......@@ -459,7 +458,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
def test_upgrade_already_verified(self):
course = self._create_course("verified")
self._enroll(course.id, "honor")
self._enroll(course.id)
self._set_verification_status("submitted")
response = self._get_page('verify_student_upgrade_and_verify', course.id)
......@@ -746,7 +745,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
return course
def _enroll(self, course_key, mode):
def _enroll(self, course_key, mode=CourseMode.DEFAULT_MODE_SLUG):
"""Enroll the user in a course. """
CourseEnrollmentFactory.create(
user=self.user,
......@@ -923,8 +922,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
"""Check the course information on the page. """
mode_display_name = u"Introduction à l'astrophysique"
course = CourseFactory.create(display_name=mode_display_name)
for course_mode in ["honor", "verified"]:
min_price = (self.MIN_PRICE if course_mode != "honor" else 0)
for course_mode in [CourseMode.DEFAULT_MODE_SLUG, "verified"]:
min_price = (self.MIN_PRICE if course_mode != CourseMode.DEFAULT_MODE_SLUG else 0)
CourseModeFactory(
course_id=course.id,
mode_slug=course_mode,
......@@ -932,7 +931,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
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))
self.assertEqual(response_dict['course_name'], mode_display_name)
......@@ -948,7 +947,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin):
# setting a nonempty sku on the course will a trigger calls to
# the ecommerce api to get payment processors.
course = self._create_course("verified", sku='nonempty-sku')
self._enroll(course.id, "honor")
self._enroll(course.id)
# mock out the payment processors endpoint
httpretty.register_uri(
......
......@@ -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
// AND specifying a course mode.
setFakeQueryParams({
......@@ -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
// AND specifying a course mode.
setFakeQueryParams({
'?enrollment_action': 'enroll',
'?course_id': COURSE_KEY,
'?course_mode': 'honor'
'?course_mode': 'audit'
});
ajaxSpyAndInitialize(this);
......
......@@ -26,7 +26,7 @@ var edx = edx || {};
hasVisibleReqs: false,
platformName: '',
alreadyVerified: false,
courseModeSlug: 'honor',
courseModeSlug: 'audit',
verificationGoodUntil: ''
};
},
......
......@@ -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(
course_name=course.display_name, date=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
</p>
</section>
......
......@@ -25,6 +25,15 @@ class CreditServiceTests(ModuleStoreTestCase):
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')
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):
"""
Makes sure that get_credit_state returns None if user_id cannot be found
......@@ -46,7 +55,7 @@ class CreditServiceTests(ModuleStoreTestCase):
inactive
"""
enrollment = CourseEnrollment.enroll(self.user, self.course.id)
enrollment = self.enroll()
enrollment.is_active = False
enrollment.save()
......@@ -58,7 +67,7 @@ class CreditServiceTests(ModuleStoreTestCase):
Credit eligible
"""
CourseEnrollment.enroll(self.user, self.course.id)
self.enroll()
self.credit_course.enabled = False
self.credit_course.save()
......@@ -86,7 +95,7 @@ class CreditServiceTests(ModuleStoreTestCase):
self.assertTrue(self.service.is_credit_course(self.course.id))
CourseEnrollment.enroll(self.user, self.course.id)
self.enroll()
# set course requirements
set_credit_requirements(
......@@ -127,7 +136,7 @@ class CreditServiceTests(ModuleStoreTestCase):
"""
self.assertTrue(self.service.is_credit_course(self.course.id))
CourseEnrollment.enroll(self.user, self.course.id)
self.enroll()
# set course requirements
set_credit_requirements(
......@@ -216,7 +225,7 @@ class CreditServiceTests(ModuleStoreTestCase):
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
self.service.remove_credit_requirement_status(
......@@ -237,7 +246,7 @@ class CreditServiceTests(ModuleStoreTestCase):
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
credit_state = self.service.get_credit_state(self.user.id, self.course.id)
......@@ -258,7 +267,7 @@ class CreditServiceTests(ModuleStoreTestCase):
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
self.service.set_credit_requirement_status(
......@@ -308,7 +317,7 @@ class CreditServiceTests(ModuleStoreTestCase):
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_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