commerce/api: Don’t allow setting expiration of prof modes.

XCOM-497
This commit is contained in:
jsa
2015-07-27 12:15:43 -04:00
committed by Clinton Blackburn
parent 7d8fb73934
commit 849ad8df94
3 changed files with 80 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ Add and create new modes for running courses on this particular LMS
import pytz
from datetime import datetime
from django.core.exceptions import ValidationError
from django.db import models
from collections import namedtuple, defaultdict
from django.utils.translation import ugettext_lazy as _
@@ -106,8 +107,19 @@ class CourseMode(models.Model):
""" meta attributes of this model """
unique_together = ('course_id', 'mode_slug', 'currency')
def clean(self):
"""
Object-level validation - implemented in this method so DRF serializers
catch errors in advance of a save() attempt.
"""
if self.is_professional_slug(self.mode_slug) and self.expiration_datetime is not None:
raise ValidationError(
_(u"Professional education modes are not allowed to have expiration_datetime set.")
)
def save(self, force_insert=False, force_update=False, using=None):
# Ensure currency is always lowercase.
self.clean() # ensure object-level validation is performed before we save.
self.currency = self.currency.lower()
super(CourseMode, self).save(force_insert, force_update, using)

View File

@@ -6,12 +6,15 @@ Replace this with more appropriate tests for your application.
"""
from datetime import datetime, timedelta
import pytz
import ddt
import itertools
import ddt
from django.core.exceptions import ValidationError
from django.test import TestCase
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from opaque_keys.edx.locator import CourseLocator
from django.test import TestCase
import pytz
from course_modes.models import CourseMode, Mode
@@ -26,7 +29,15 @@ class CourseModeModelTest(TestCase):
self.course_key = SlashSeparatedCourseKey('Test', 'TestCourse', 'TestCourseRun')
CourseMode.objects.all().delete()
def create_mode(self, mode_slug, mode_name, min_price=0, suggested_prices='', currency='usd'):
def create_mode(
self,
mode_slug,
mode_name,
min_price=0,
suggested_prices='',
currency='usd',
expiration_datetime=None,
):
"""
Create a new course mode
"""
@@ -37,6 +48,7 @@ class CourseModeModelTest(TestCase):
min_price=min_price,
suggested_prices=suggested_prices,
currency=currency,
expiration_datetime=expiration_datetime,
)
def test_save(self):
@@ -264,6 +276,29 @@ class CourseModeModelTest(TestCase):
else:
self.assertFalse(CourseMode.is_verified_slug(mode_slug))
@ddt.data(*itertools.product(
(
CourseMode.HONOR,
CourseMode.AUDIT,
CourseMode.VERIFIED,
CourseMode.PROFESSIONAL,
CourseMode.NO_ID_PROFESSIONAL_MODE
),
(datetime.now(), None),
))
@ddt.unpack
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.assertFalse(is_error_expected, "Expected a ValidationError to be thrown.")
except ValidationError, exc:
self.assertTrue(is_error_expected, "Did not expect a ValidationError to be thrown.")
self.assertEqual(
exc.messages,
[u"Professional education modes are not allowed to have expiration_datetime set."],
)
@ddt.data(
("verified", "verify_need_to_verify"),
("verified", "verify_submitted"),