Disallow free verified course modes
The verification workflow assumes that all verified courses will have a price. Free verified course modes cause a 404 when the user attempts to enroll or upgrade.
This commit is contained in:
committed by
Braden MacDonald
parent
a2c686cf6f
commit
6fc4b38ea0
@@ -17,6 +17,7 @@ import pytz
|
||||
|
||||
from course_modes.helpers import enrollment_mode_display
|
||||
from course_modes.models import CourseMode, Mode
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -74,9 +75,9 @@ class CourseModeModelTest(TestCase):
|
||||
Find the modes for a course with only one mode
|
||||
"""
|
||||
|
||||
self.create_mode('verified', 'Verified Certificate')
|
||||
self.create_mode('verified', 'Verified Certificate', 10)
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
mode = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None, None, None)
|
||||
mode = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None)
|
||||
self.assertEqual([mode], modes)
|
||||
|
||||
modes_dict = CourseMode.modes_for_course_dict(self.course_key)
|
||||
@@ -89,7 +90,7 @@ class CourseModeModelTest(TestCase):
|
||||
Finding the modes when there's multiple modes
|
||||
"""
|
||||
mode1 = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', None, None, None)
|
||||
mode2 = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', None, None, None)
|
||||
set_modes = [mode1, mode2]
|
||||
for mode in set_modes:
|
||||
self.create_mode(mode.slug, mode.name, mode.min_price, mode.suggested_prices)
|
||||
@@ -119,7 +120,7 @@ class CourseModeModelTest(TestCase):
|
||||
self.assertEqual(80, CourseMode.min_course_price_for_currency(self.course_key, 'cny'))
|
||||
|
||||
def test_modes_for_course_expired(self):
|
||||
expired_mode, _status = self.create_mode('verified', 'Verified Certificate')
|
||||
expired_mode, _status = self.create_mode('verified', 'Verified Certificate', 10)
|
||||
expired_mode.expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=-1)
|
||||
expired_mode.save()
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
@@ -133,7 +134,7 @@ class CourseModeModelTest(TestCase):
|
||||
expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
expired_mode.expiration_datetime = expiration_datetime
|
||||
expired_mode.save()
|
||||
expired_mode_value = Mode(u'verified', u'Verified Certificate', 0, '', 'usd', expiration_datetime, None, None)
|
||||
expired_mode_value = Mode(u'verified', u'Verified Certificate', 10, '', 'usd', expiration_datetime, None, None)
|
||||
modes = CourseMode.modes_for_course(self.course_key)
|
||||
self.assertEqual([expired_mode_value, mode1], modes)
|
||||
|
||||
@@ -141,14 +142,14 @@ class CourseModeModelTest(TestCase):
|
||||
self.assertEqual([CourseMode.DEFAULT_MODE], modes)
|
||||
|
||||
def test_verified_mode_for_course(self):
|
||||
self.create_mode('verified', 'Verified Certificate')
|
||||
self.create_mode('verified', 'Verified Certificate', 10)
|
||||
|
||||
mode = CourseMode.verified_mode_for_course(self.course_key)
|
||||
|
||||
self.assertEqual(mode.slug, 'verified')
|
||||
|
||||
# verify that the professional mode is preferred
|
||||
self.create_mode('professional', 'Professional Education Verified Certificate')
|
||||
self.create_mode('professional', 'Professional Education Verified Certificate', 10)
|
||||
|
||||
mode = CourseMode.verified_mode_for_course(self.course_key)
|
||||
|
||||
@@ -163,9 +164,8 @@ class CourseModeModelTest(TestCase):
|
||||
verified, _ = self.create_mode('verified', 'Verified', min_price=5)
|
||||
self.assertTrue(CourseMode.has_payment_options(self.course_key))
|
||||
|
||||
# Unset verified's minimum price.
|
||||
verified.min_price = 0
|
||||
verified.save()
|
||||
# Remove the verified option.
|
||||
verified.delete()
|
||||
self.assertFalse(CourseMode.has_payment_options(self.course_key))
|
||||
|
||||
# Finally, give the honor mode payment options
|
||||
@@ -215,7 +215,7 @@ class CourseModeModelTest(TestCase):
|
||||
past = now - timedelta(days=1)
|
||||
|
||||
# Unexpired, no expiration date
|
||||
CourseMode.objects.create(
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course_key,
|
||||
mode_display_name="Honor No Expiration",
|
||||
mode_slug="honor_no_expiration",
|
||||
@@ -223,7 +223,7 @@ class CourseModeModelTest(TestCase):
|
||||
)
|
||||
|
||||
# Unexpired, expiration date in future
|
||||
CourseMode.objects.create(
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course_key,
|
||||
mode_display_name="Honor Not Expired",
|
||||
mode_slug="honor_not_expired",
|
||||
@@ -231,7 +231,7 @@ class CourseModeModelTest(TestCase):
|
||||
)
|
||||
|
||||
# Expired
|
||||
CourseMode.objects.create(
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course_key,
|
||||
mode_display_name="Verified Expired",
|
||||
mode_slug="verified_expired",
|
||||
@@ -306,9 +306,9 @@ class CourseModeModelTest(TestCase):
|
||||
def test_invalid_mode_expiration(self, mode_slug, exp_dt):
|
||||
is_error_expected = CourseMode.is_professional_slug(mode_slug) and exp_dt is not None
|
||||
try:
|
||||
self.create_mode(mode_slug=mode_slug, mode_name=mode_slug.title(), expiration_datetime=exp_dt)
|
||||
self.create_mode(mode_slug=mode_slug, mode_name=mode_slug.title(), expiration_datetime=exp_dt, min_price=10)
|
||||
self.assertFalse(is_error_expected, "Expected a ValidationError to be thrown.")
|
||||
except ValidationError, exc:
|
||||
except ValidationError as exc:
|
||||
self.assertTrue(is_error_expected, "Did not expect a ValidationError to be thrown.")
|
||||
self.assertEqual(
|
||||
exc.messages,
|
||||
@@ -367,7 +367,7 @@ class CourseModeModelTest(TestCase):
|
||||
def test_hide_credit_modes(self, available_modes, expected_selectable_modes):
|
||||
# Create the course modes
|
||||
for mode in available_modes:
|
||||
CourseMode.objects.create(
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course_key,
|
||||
mode_display_name=mode,
|
||||
mode_slug=mode,
|
||||
@@ -406,7 +406,7 @@ class CourseModeModelTest(TestCase):
|
||||
|
||||
def test_expiration_datetime_explicitly_set(self):
|
||||
""" Verify that setting the expiration_date property sets the explicit flag. """
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate')
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate', 10)
|
||||
now = datetime.now()
|
||||
verified_mode.expiration_datetime = now
|
||||
|
||||
@@ -415,7 +415,7 @@ class CourseModeModelTest(TestCase):
|
||||
|
||||
def test_expiration_datetime_not_explicitly_set(self):
|
||||
""" Verify that setting the _expiration_date property does not set the explicit flag. """
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate')
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate', 10)
|
||||
now = datetime.now()
|
||||
verified_mode._expiration_datetime = now # pylint: disable=protected-access
|
||||
|
||||
@@ -424,7 +424,7 @@ class CourseModeModelTest(TestCase):
|
||||
|
||||
def test_expiration_datetime_explicitly_set_to_none(self):
|
||||
""" Verify that setting the _expiration_date property does not set the explicit flag. """
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate')
|
||||
verified_mode, __ = self.create_mode('verified', 'Verified Certificate', 10)
|
||||
self.assertFalse(verified_mode.expiration_datetime_is_explicit)
|
||||
|
||||
verified_mode.expiration_datetime = None
|
||||
@@ -443,3 +443,21 @@ class CourseModeModelTest(TestCase):
|
||||
def test_eligible_for_cert(self, mode_slug, expected_eligibility):
|
||||
"""Verify that non-audit modes are eligible for a cert."""
|
||||
self.assertEqual(CourseMode.is_eligible_for_certificate(mode_slug), expected_eligibility)
|
||||
|
||||
@ddt.data(
|
||||
(CourseMode.AUDIT, False),
|
||||
(CourseMode.HONOR, False),
|
||||
(CourseMode.VERIFIED, True),
|
||||
(CourseMode.CREDIT_MODE, False),
|
||||
(CourseMode.PROFESSIONAL, True),
|
||||
(CourseMode.NO_ID_PROFESSIONAL_MODE, False),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_verified_min_price(self, mode_slug, is_error_expected):
|
||||
"""Verify that verified modes have a price."""
|
||||
try:
|
||||
self.create_mode(mode_slug=mode_slug, mode_name=mode_slug.title(), min_price=0)
|
||||
except ValidationError:
|
||||
self.assertTrue(is_error_expected, "Did not expect a ValidationError to be thrown.")
|
||||
else:
|
||||
self.assertFalse(is_error_expected, "Expected a ValidationError to be thrown.")
|
||||
|
||||
Reference in New Issue
Block a user