Commit 830a695f by Awais Qureshi

Merge pull request #9461 from edx/awais786/XCOM-538-otto-admin-restrict-nonexisting-course

adding validator to make sure course exists in db before creating in …
parents 94e11e1e cdfc9da4
......@@ -2,11 +2,17 @@
from datetime import datetime
import pytz
from django.utils.translation import ugettext as _
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from rest_framework import serializers
from commerce.api.v1.models import Course
from course_modes.models import CourseMode
from xmodule.modulestore.django import modulestore
class CourseModeSerializer(serializers.ModelSerializer):
""" CourseMode serializer. """
......@@ -25,9 +31,30 @@ class CourseModeSerializer(serializers.ModelSerializer):
fields = ('name', 'currency', 'price', 'sku', 'expires')
def validate_course_id(course_id):
"""
Check that course id is valid and exists in modulestore.
"""
try:
course_key = CourseKey.from_string(unicode(course_id))
except InvalidKeyError:
raise serializers.ValidationError(
_("{course_id} is not a valid course key.").format(
course_id=course_id
)
)
if not modulestore().has_course(course_key):
raise serializers.ValidationError(
_('Course {course_id} does not exist.').format(
course_id=course_id
)
)
class CourseSerializer(serializers.Serializer):
""" Course serializer. """
id = serializers.CharField() # pylint: disable=invalid-name
id = serializers.CharField(validators=[validate_course_id]) # pylint: disable=invalid-name
name = serializers.CharField(read_only=True)
verification_deadline = serializers.DateTimeField(blank=True)
modes = CourseModeSerializer(many=True, allow_add_remove=True)
......
""" Commerce API v1 serializer tests. """
from django.test import TestCase
from commerce.api.v1.serializers import serializers, validate_course_id
class CourseValidatorTests(TestCase):
""" Tests for Course Validator method. """
def test_validate_course_id_with_non_existent_course(self):
""" Verify a validator checking non-existent courses."""
course_key = 'non/existing/keyone'
error_msg = u"Course {} does not exist.".format(course_key)
with self.assertRaisesRegexp(serializers.ValidationError, error_msg):
validate_course_id(course_key)
def test_validate_course_id_with_invalid_key(self):
""" Verify a validator checking invalid course keys."""
course_key = 'invalidkey'
error_msg = u"{} is not a valid course key.".format(course_key)
with self.assertRaisesRegexp(serializers.ValidationError, error_msg):
validate_course_id(course_key)
......@@ -267,3 +267,41 @@ class CourseRetrieveUpdateViewTests(CourseApiViewTestMixin, ModuleStoreTestCase)
""" Verify the view supports creating a course when authenticated with the API header key. """
self.client.logout()
self.assert_can_create_course(HTTP_X_EDX_API_KEY=settings.EDX_API_KEY)
def test_create_with_non_existent_course(self):
""" Verify the API does not allow data to be created for courses that do not exist. """
permissions = Permission.objects.filter(name__in=('Can add course mode', 'Can change course mode'))
for permission in permissions:
self.user.user_permissions.add(permission)
expected_modes = [
CourseMode(
mode_slug=u'honor',
min_price=150, currency=u'USD',
sku=u'ABC123'
)
]
course_key = 'non/existing/key'
course_dict = {
u'id': unicode(course_key),
u'name': unicode('Non Existing Course'),
u'verification_deadline': None,
u'modes': [self._serialize_course_mode(mode) for mode in expected_modes]
}
path = reverse('commerce_api:v1:courses:retrieve_update', args=[unicode(course_key)])
response = self.client.put(path, json.dumps(course_dict), content_type=JSON_CONTENT_TYPE)
self.assertEqual(response.status_code, 400)
expected_dict = {
'id': [
u'Course {} does not exist.'.format(
course_key
)
]
}
self.assertDictEqual(expected_dict, json.loads(response.content))
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