Merge pull request #17343 from edx/aj/validate-course-team-user

Course team Validation
This commit is contained in:
Awais Jibran
2018-02-02 14:32:39 +05:00
committed by GitHub
2 changed files with 62 additions and 28 deletions

View File

@@ -1,6 +1,7 @@
import six
from django.contrib.auth import get_user_model
from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.fields import empty
@@ -34,6 +35,15 @@ class CourseRunScheduleSerializer(serializers.Serializer):
class CourseRunTeamSerializer(serializers.Serializer):
def to_internal_value(self, data):
"""Overriding this to support deserialization, for write operations."""
for member in data:
try:
User.objects.get(username=member['user'])
except User.DoesNotExist:
raise serializers.ValidationError(
_('Course team user does not exist')
)
return CourseAccessRoleSerializer(data=data, many=True).to_internal_value(data)
def to_representation(self, instance):

View File

@@ -6,6 +6,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.urlresolvers import reverse
from django.test import RequestFactory
from opaque_keys.edx.keys import CourseKey
from openedx.core.lib.courses import course_image_url
from rest_framework.test import APIClient
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore
@@ -14,7 +15,6 @@ from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ToyCourseFactory
from openedx.core.lib.courses import course_image_url
from student.models import CourseAccessRole
from student.tests.factories import AdminFactory, TEST_PASSWORD, UserFactory
from ..utils import serialize_datetime
@@ -23,6 +23,9 @@ from ...serializers.course_runs import CourseRunSerializer
@ddt.ddt
class CourseRunViewSetTests(ModuleStoreTestCase):
"""
Tests for creating course runs
"""
list_url = reverse('api:v1:course_run-list')
def setUp(self):
@@ -31,6 +34,27 @@ class CourseRunViewSetTests(ModuleStoreTestCase):
user = AdminFactory()
self.client.login(username=user.username, password=TEST_PASSWORD)
def get_course_run_data(self, user, start, end, enrollment_start, enrollment_end, pacing_type, role='instructor'):
return {
'title': 'Testing 101',
'org': 'TestingX',
'number': 'Testing101x',
'run': '3T2017',
'schedule': {
'start': serialize_datetime(start),
'end': serialize_datetime(end),
'enrollment_start': serialize_datetime(enrollment_start),
'enrollment_end': serialize_datetime(enrollment_end),
},
'team': [
{
'user': user.username,
'role': role,
}
],
'pacing_type': pacing_type,
}
def assert_course_run_schedule(self, course_run, start, end, enrollment_start, enrollment_end):
assert course_run.start == start
assert course_run.end == end
@@ -137,7 +161,7 @@ class CourseRunViewSetTests(ModuleStoreTestCase):
}
response = self.client.put(url, data, format='json')
assert response.status_code == 400
assert response.data == {'team': [{'user': ['Object with username=test-user does not exist.']}]}
assert response.data == {'team': ['Course team user does not exist']}
def test_update_with_pacing_type(self):
"""
@@ -231,45 +255,45 @@ class CourseRunViewSetTests(ModuleStoreTestCase):
)
@ddt.unpack
def test_create(self, pacing_type, expected_self_paced_value):
"""Tests successful course run creation"""
user = UserFactory()
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
enrollment_start = start - datetime.timedelta(days=7)
enrollment_end = end - datetime.timedelta(days=14)
user = UserFactory()
role = 'staff'
data = {
'title': 'Testing 101',
'org': 'TestingX',
'number': 'Testing101x',
'run': '3T2017',
'schedule': {
'start': serialize_datetime(start),
'end': serialize_datetime(end),
'enrollment_start': serialize_datetime(enrollment_start),
'enrollment_end': serialize_datetime(enrollment_end),
},
'team': [
{
'user': user.username,
'role': role,
}
],
'pacing_type': pacing_type,
}
data = self.get_course_run_data(user, start, end, enrollment_start, enrollment_end, pacing_type, role)
response = self.client.post(self.list_url, data, format='json')
assert response.status_code == 201
self.assertEqual(response.status_code, 201)
course_run_key = CourseKey.from_string(response.data['id'])
course_run = modulestore().get_course(course_run_key)
assert course_run.display_name == data['title']
assert course_run.id.org == data['org']
assert course_run.id.course == data['number']
assert course_run.id.run == data['run']
assert course_run.self_paced is expected_self_paced_value
self.assertEqual(course_run.display_name, data['title'])
self.assertEqual(course_run.id.org, data['org'])
self.assertEqual(course_run.id.course, data['number'])
self.assertEqual(course_run.id.run, data['run'])
self.assertEqual(course_run.self_paced, expected_self_paced_value)
self.assert_course_run_schedule(course_run, start, end, enrollment_start, enrollment_end)
self.assert_access_role(course_run, user, role)
self.assert_course_access_role_count(course_run, 1)
def test_create_with_invalid_course_team(self):
"""
Tests that if the course team user is invalid, it returns bad request status
with expected validation message
"""
user = UserFactory()
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
end = start + datetime.timedelta(days=30)
enrollment_start = start - datetime.timedelta(days=7)
enrollment_end = end - datetime.timedelta(days=14)
data = self.get_course_run_data(user, start, end, enrollment_start, enrollment_end, 'self-paced')
data['team'] = [{'user': 'invalid-username'}]
response = self.client.post(self.list_url, data, format='json')
self.assertEqual(response.status_code, 400)
self.assertDictContainsSubset({'team': ['Course team user does not exist']}, response.data)
def test_images_upload(self):
# http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser
course_run = CourseFactory()