Make course ids and usage ids opaque to LMS and Studio [partial commit]
This commit updates common/djangoapps. These keys are now objects with a limited interface, and the particular internal representation is managed by the data storage layer (the modulestore). For the LMS, there should be no outward-facing changes to the system. The keys are, for now, a change to internal representation only. For Studio, the new serialized form of the keys is used in urls, to allow for further migration in the future. Co-Author: Andy Armstrong <andya@edx.org> Co-Author: Christina Roberts <christina@edx.org> Co-Author: David Baumgold <db@edx.org> Co-Author: Diana Huang <dkh@edx.org> Co-Author: Don Mitchell <dmitchell@edx.org> Co-Author: Julia Hansbrough <julia@edx.org> Co-Author: Nimisha Asthagiri <nasthagiri@edx.org> Co-Author: Sarina Canelake <sarina@edx.org> [LMS-2370]
This commit is contained in:
@@ -5,12 +5,12 @@ import mock
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from xmodule.modulestore import Location
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole
|
||||
from student.tests.factories import AdminFactory
|
||||
from student.auth import has_access, add_users, remove_users
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class CreatorGroupTest(TestCase):
|
||||
@@ -137,54 +137,54 @@ class CourseGroupTest(TestCase):
|
||||
self.global_admin = AdminFactory()
|
||||
self.creator = User.objects.create_user('testcreator', 'testcreator+courses@edx.org', 'foo')
|
||||
self.staff = User.objects.create_user('teststaff', 'teststaff+courses@edx.org', 'foo')
|
||||
self.location = Location('i4x', 'mitX', '101', 'course', 'test')
|
||||
self.course_key = SlashSeparatedCourseKey('mitX', '101', 'test')
|
||||
|
||||
def test_add_user_to_course_group(self):
|
||||
"""
|
||||
Tests adding user to course group (happy path).
|
||||
"""
|
||||
# Create groups for a new course (and assign instructor role to the creator).
|
||||
self.assertFalse(has_access(self.creator, CourseInstructorRole(self.location)))
|
||||
add_users(self.global_admin, CourseInstructorRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.location), self.creator)
|
||||
self.assertTrue(has_access(self.creator, CourseInstructorRole(self.location)))
|
||||
self.assertFalse(has_access(self.creator, CourseInstructorRole(self.course_key)))
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
self.assertTrue(has_access(self.creator, CourseInstructorRole(self.course_key)))
|
||||
|
||||
# Add another user to the staff role.
|
||||
self.assertFalse(has_access(self.staff, CourseStaffRole(self.location)))
|
||||
add_users(self.creator, CourseStaffRole(self.location), self.staff)
|
||||
self.assertTrue(has_access(self.staff, CourseStaffRole(self.location)))
|
||||
self.assertFalse(has_access(self.staff, CourseStaffRole(self.course_key)))
|
||||
add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertTrue(has_access(self.staff, CourseStaffRole(self.course_key)))
|
||||
|
||||
def test_add_user_to_course_group_permission_denied(self):
|
||||
"""
|
||||
Verifies PermissionDenied if caller of add_user_to_course_group is not instructor role.
|
||||
"""
|
||||
add_users(self.global_admin, CourseInstructorRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
with self.assertRaises(PermissionDenied):
|
||||
add_users(self.staff, CourseStaffRole(self.location), self.staff)
|
||||
add_users(self.staff, CourseStaffRole(self.course_key), self.staff)
|
||||
|
||||
def test_remove_user_from_course_group(self):
|
||||
"""
|
||||
Tests removing user from course group (happy path).
|
||||
"""
|
||||
add_users(self.global_admin, CourseInstructorRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
|
||||
add_users(self.creator, CourseStaffRole(self.location), self.staff)
|
||||
self.assertTrue(has_access(self.staff, CourseStaffRole(self.location)))
|
||||
add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertTrue(has_access(self.staff, CourseStaffRole(self.course_key)))
|
||||
|
||||
remove_users(self.creator, CourseStaffRole(self.location), self.staff)
|
||||
self.assertFalse(has_access(self.staff, CourseStaffRole(self.location)))
|
||||
remove_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertFalse(has_access(self.staff, CourseStaffRole(self.course_key)))
|
||||
|
||||
remove_users(self.creator, CourseInstructorRole(self.location), self.creator)
|
||||
self.assertFalse(has_access(self.creator, CourseInstructorRole(self.location)))
|
||||
remove_users(self.creator, CourseInstructorRole(self.course_key), self.creator)
|
||||
self.assertFalse(has_access(self.creator, CourseInstructorRole(self.course_key)))
|
||||
|
||||
def test_remove_user_from_course_group_permission_denied(self):
|
||||
"""
|
||||
Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role.
|
||||
"""
|
||||
add_users(self.global_admin, CourseInstructorRole(self.location), self.creator)
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
another_staff = User.objects.create_user('another', 'teststaff+anothercourses@edx.org', 'foo')
|
||||
add_users(self.global_admin, CourseStaffRole(self.location), self.creator, self.staff, another_staff)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator, self.staff, another_staff)
|
||||
with self.assertRaises(PermissionDenied):
|
||||
remove_users(self.staff, CourseStaffRole(self.location), another_staff)
|
||||
remove_users(self.staff, CourseStaffRole(self.course_key), another_staff)
|
||||
|
||||
@@ -6,6 +6,7 @@ from django_comment_common.models import (
|
||||
from django_comment_common.utils import seed_permissions_roles
|
||||
from student.models import CourseEnrollment, UserProfile
|
||||
from util.testing import UrlResetMixin
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
from mock import patch
|
||||
|
||||
|
||||
@@ -23,6 +24,8 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
|
||||
super(AutoAuthEnabledTestCase, self).setUp()
|
||||
self.url = '/auto_auth'
|
||||
self.client = Client()
|
||||
self.course_id = 'edX/Test101/2014_Spring'
|
||||
self.course_key = SlashSeparatedCourseKey.from_deprecated_string(self.course_id)
|
||||
|
||||
def test_create_user(self):
|
||||
"""
|
||||
@@ -83,43 +86,39 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
|
||||
def test_course_enrollment(self):
|
||||
|
||||
# Create a user and enroll in a course
|
||||
course_id = "edX/Test101/2014_Spring"
|
||||
self._auto_auth(username='test', course_id=course_id)
|
||||
self._auto_auth(username='test', course_id=self.course_id)
|
||||
|
||||
# Check that a course enrollment was created for the user
|
||||
self.assertEqual(CourseEnrollment.objects.count(), 1)
|
||||
enrollment = CourseEnrollment.objects.get(course_id=course_id)
|
||||
enrollment = CourseEnrollment.objects.get(course_id=self.course_key)
|
||||
self.assertEqual(enrollment.user.username, "test")
|
||||
|
||||
def test_double_enrollment(self):
|
||||
|
||||
# Create a user and enroll in a course
|
||||
course_id = "edX/Test101/2014_Spring"
|
||||
self._auto_auth(username='test', course_id=course_id)
|
||||
self._auto_auth(username='test', course_id=self.course_id)
|
||||
|
||||
# Make the same call again, re-enrolling the student in the same course
|
||||
self._auto_auth(username='test', course_id=course_id)
|
||||
self._auto_auth(username='test', course_id=self.course_id)
|
||||
|
||||
# Check that only one course enrollment was created for the user
|
||||
self.assertEqual(CourseEnrollment.objects.count(), 1)
|
||||
enrollment = CourseEnrollment.objects.get(course_id=course_id)
|
||||
enrollment = CourseEnrollment.objects.get(course_id=self.course_key)
|
||||
self.assertEqual(enrollment.user.username, "test")
|
||||
|
||||
def test_set_roles(self):
|
||||
|
||||
course_id = "edX/Test101/2014_Spring"
|
||||
seed_permissions_roles(course_id)
|
||||
course_roles = dict((r.name, r) for r in Role.objects.filter(course_id=course_id))
|
||||
seed_permissions_roles(self.course_key)
|
||||
course_roles = dict((r.name, r) for r in Role.objects.filter(course_id=self.course_key))
|
||||
self.assertEqual(len(course_roles), 4) # sanity check
|
||||
|
||||
# Student role is assigned by default on course enrollment.
|
||||
self._auto_auth(username='a_student', course_id=course_id)
|
||||
self._auto_auth(username='a_student', course_id=self.course_id)
|
||||
user = User.objects.get(username='a_student')
|
||||
user_roles = user.roles.all()
|
||||
self.assertEqual(len(user_roles), 1)
|
||||
self.assertEqual(user_roles[0], course_roles[FORUM_ROLE_STUDENT])
|
||||
|
||||
self._auto_auth(username='a_moderator', course_id=course_id, roles='Moderator')
|
||||
self._auto_auth(username='a_moderator', course_id=self.course_id, roles='Moderator')
|
||||
user = User.objects.get(username='a_moderator')
|
||||
user_roles = user.roles.all()
|
||||
self.assertEqual(
|
||||
@@ -128,7 +127,7 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
|
||||
course_roles[FORUM_ROLE_MODERATOR]]))
|
||||
|
||||
# check multiple roles work.
|
||||
self._auto_auth(username='an_admin', course_id=course_id,
|
||||
self._auto_auth(username='an_admin', course_id=self.course_id,
|
||||
roles='{},{}'.format(FORUM_ROLE_MODERATOR, FORUM_ROLE_ADMINISTRATOR))
|
||||
user = User.objects.get(username='an_admin')
|
||||
user_roles = user.roles.all()
|
||||
|
||||
@@ -15,6 +15,7 @@ from student.tests.factories import UserFactory, CourseEnrollmentFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
|
||||
from bulk_email.models import CourseAuthorization
|
||||
|
||||
@@ -100,7 +101,10 @@ class TestStudentDashboardEmailViewXMLBacked(ModuleStoreTestCase):
|
||||
|
||||
# Create student account
|
||||
student = UserFactory.create()
|
||||
CourseEnrollmentFactory.create(user=student, course_id=self.course_name)
|
||||
CourseEnrollmentFactory.create(
|
||||
user=student,
|
||||
course_id=SlashSeparatedCourseKey.from_deprecated_string(self.course_name)
|
||||
)
|
||||
self.client.login(username=student.username, password="test")
|
||||
|
||||
try:
|
||||
|
||||
@@ -20,6 +20,7 @@ from xmodule.modulestore.inheritance import own_metadata
|
||||
from xmodule.modulestore.django import editable_modulestore
|
||||
|
||||
from external_auth.models import ExternalAuthMap
|
||||
from xmodule.modulestore.locations import SlashSeparatedCourseKey
|
||||
|
||||
TEST_DATA_MIXED_MODULESTORE = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {})
|
||||
|
||||
@@ -275,7 +276,10 @@ class UtilFnTest(TestCase):
|
||||
COURSE_ID = u'org/num/run' # pylint: disable=C0103
|
||||
COURSE_URL = u'/courses/{}/otherstuff'.format(COURSE_ID) # pylint: disable=C0103
|
||||
NON_COURSE_URL = u'/blahblah' # pylint: disable=C0103
|
||||
self.assertEqual(_parse_course_id_from_string(COURSE_URL), COURSE_ID)
|
||||
self.assertEqual(
|
||||
_parse_course_id_from_string(COURSE_URL),
|
||||
SlashSeparatedCourseKey.from_deprecated_string(COURSE_ID)
|
||||
)
|
||||
self.assertIsNone(_parse_course_id_from_string(NON_COURSE_URL))
|
||||
|
||||
|
||||
@@ -320,7 +324,7 @@ class ExternalAuthShibTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests the _get_course_enrollment_domain utility function
|
||||
"""
|
||||
self.assertIsNone(_get_course_enrollment_domain("I/DONT/EXIST"))
|
||||
self.assertIsNone(_get_course_enrollment_domain(SlashSeparatedCourseKey("I", "DONT", "EXIST")))
|
||||
self.assertIsNone(_get_course_enrollment_domain(self.course.id))
|
||||
self.assertEqual(self.shib_course.enrollment_domain, _get_course_enrollment_domain(self.shib_course.id))
|
||||
|
||||
@@ -340,7 +344,7 @@ class ExternalAuthShibTest(ModuleStoreTestCase):
|
||||
Tests the redirects when visiting course-specific URL with @login_required.
|
||||
Should vary by course depending on its enrollment_domain
|
||||
"""
|
||||
TARGET_URL = reverse('courseware', args=[self.course.id]) # pylint: disable=C0103
|
||||
TARGET_URL = reverse('courseware', args=[self.course.id.to_deprecated_string()]) # pylint: disable=C0103
|
||||
noshib_response = self.client.get(TARGET_URL, follow=True)
|
||||
self.assertEqual(noshib_response.redirect_chain[-1],
|
||||
('http://testserver/accounts/login?next={url}'.format(url=TARGET_URL), 302))
|
||||
@@ -348,7 +352,7 @@ class ExternalAuthShibTest(ModuleStoreTestCase):
|
||||
.format(platform_name=settings.PLATFORM_NAME)))
|
||||
self.assertEqual(noshib_response.status_code, 200)
|
||||
|
||||
TARGET_URL_SHIB = reverse('courseware', args=[self.shib_course.id]) # pylint: disable=C0103
|
||||
TARGET_URL_SHIB = reverse('courseware', args=[self.shib_course.id.to_deprecated_string()]) # pylint: disable=C0103
|
||||
shib_response = self.client.get(**{'path': TARGET_URL_SHIB,
|
||||
'follow': True,
|
||||
'REMOTE_USER': self.extauth.external_id,
|
||||
|
||||
@@ -53,7 +53,7 @@ class UserStandingTest(TestCase):
|
||||
try:
|
||||
self.some_url = reverse('dashboard')
|
||||
except NoReverseMatch:
|
||||
self.some_url = '/course'
|
||||
self.some_url = '/course/'
|
||||
|
||||
# since it's only possible to disable accounts from lms, we're going
|
||||
# to skip tests for cms
|
||||
|
||||
Reference in New Issue
Block a user