Commit ab46de59 by Awais Qureshi

Merge pull request #8407 from edx/awais786/ECOM-1644-course-access-roles

ECOM-1644 Implementing course-access roles.
parents c4175c7d 956e4134
......@@ -3,6 +3,7 @@ django admin pages for courseware model
'''
from django import forms
from config_models.admin import ConfigurationModelAdmin
from django.contrib.auth.models import User
from student.models import UserProfile, UserTestGroup, CourseEnrollmentAllowed, DashboardConfiguration
from student.models import (
......@@ -11,23 +12,112 @@ from student.models import (
from ratelimitbackend import admin
from student.roles import REGISTERED_ACCESS_ROLES
from xmodule.modulestore.django import modulestore
from opaque_keys.edx.keys import CourseKey
from opaque_keys import InvalidKeyError
class CourseAccessRoleForm(forms.ModelForm):
"""Form for adding new Course Access Roles view the Django Admin Panel."""
class Meta:
model = CourseAccessRole
email = forms.EmailField(required=True)
COURSE_ACCESS_ROLES = [(role_name, role_name) for role_name in REGISTERED_ACCESS_ROLES.keys()]
role = forms.ChoiceField(choices=COURSE_ACCESS_ROLES)
def clean_course_id(self):
"""
Checking course-id format and course exists in module store.
This field can be null.
"""
if self.cleaned_data['course_id']:
course_id = self.cleaned_data['course_id']
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
raise forms.ValidationError(u"Cannot make a valid CourseKey from id {}!".format(course_id))
if not modulestore().has_course(course_key):
raise forms.ValidationError(u"Cannot find course with id {} in the modulestore".format(course_id))
return course_key
return None
def clean_org(self):
"""If org and course-id exists then Check organization name
against the given course.
"""
if self.cleaned_data.get('course_id') and self.cleaned_data['org']:
org = self.cleaned_data['org']
org_name = self.cleaned_data.get('course_id').org
if org.lower() != org_name.lower():
raise forms.ValidationError(
u"Org name {} is not valid. Valid name is {}.".format(
org, org_name
)
)
return self.cleaned_data['org']
def clean_email(self):
"""
Checking user object against given email id.
"""
email = self.cleaned_data['email']
try:
user = User.objects.get(email=email)
except Exception:
raise forms.ValidationError(
u"Email not exists. Could not find user by email address {email}.".format(
email=email
)
)
return user
def clean(self):
"""
Checking the course already exists in db.
"""
cleaned_data = super(CourseAccessRoleForm, self).clean()
if not self.errors:
if CourseAccessRole.objects.filter(
user=cleaned_data.get("email"),
org=cleaned_data.get("org"),
course_id=cleaned_data.get("course_id"),
role=cleaned_data.get("role")
).exists():
raise forms.ValidationError("Duplicate Record.")
return cleaned_data
class CourseAccessRoleAdmin(admin.ModelAdmin):
"""Admin panel for the Course Access Role. """
form = CourseAccessRoleForm
raw_id_fields = ("user",)
exclude = ("user",)
fieldsets = (
(None, {
'fields': ('email', 'course_id', 'org', 'role',)
}),
)
list_display = (
'id', 'user', 'org', 'course_id', 'role'
'id', 'user', 'org', 'course_id', 'role',
)
search_fields = (
'id', 'user__username', 'user__email', 'org', 'course_id', 'role',
)
def save_model(self, request, obj, form, change):
obj.user = form.cleaned_data['email']
super(CourseAccessRoleAdmin, self).save_model(request, obj, form, change)
class LinkedInAddToProfileConfigurationAdmin(admin.ModelAdmin):
......
"""
Tests student admin.py
"""
from django.core.urlresolvers import reverse
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import UserFactory
class AdminCourseRolesPageTest(ModuleStoreTestCase):
"""Test the django admin course roles form saving data in db.
"""
def setUp(self):
super(AdminCourseRolesPageTest, self).setUp()
self.user = UserFactory.create(is_staff=True, is_superuser=True)
self.user.save()
self.course = CourseFactory.create(org='edx')
def test_save_valid_data(self):
data = {
'course_id': unicode(self.course.id),
'role': 'finance_admin',
'org': 'edx',
'email': self.user.email
}
self.client.login(username=self.user.username, password='test')
# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertRedirects(response, reverse('admin:student_courseaccessrole_changelist'))
response = self.client.get(reverse('admin:student_courseaccessrole_changelist'))
self.assertContains(response, 'Select course access role to change')
self.assertContains(response, 'Add course access role')
self.assertContains(response, 'finance_admin')
self.assertContains(response, unicode(self.course.id))
self.assertContains(response, '1 course access role')
#try adding with same information raise error.
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertContains(response, 'Duplicate')
def test_save_without_org_and_course_data(self):
data = {
'role': 'staff',
'email': self.user.email,
'course_id': unicode(self.course.id)
}
self.client.login(username=self.user.username, password='test')
# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertRedirects(response, reverse('admin:student_courseaccessrole_changelist'))
response = self.client.get(reverse('admin:student_courseaccessrole_changelist'))
self.assertContains(response, 'staff')
self.assertContains(response, '1 course access role')
def test_save_with_course_only(self):
data = {
'role': 'beta_testers',
'email': self.user.email,
}
self.client.login(username=self.user.username, password='test')
# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertRedirects(response, reverse('admin:student_courseaccessrole_changelist'))
response = self.client.get(reverse('admin:student_courseaccessrole_changelist'))
self.assertContains(response, 'beta_testers')
self.assertContains(response, '1 course access role')
def test_save_with_org_only(self):
data = {
'role': 'beta_testers',
'email': self.user.email,
'org': 'myorg'
}
self.client.login(username=self.user.username, password='test')
# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertRedirects(response, reverse('admin:student_courseaccessrole_changelist'))
response = self.client.get(reverse('admin:student_courseaccessrole_changelist'))
self.assertContains(response, 'myorg')
self.assertContains(response, '1 course access role')
def test_save_with_invalid_course(self):
course = unicode('no/edx/course')
email = "invalid@email.com"
data = {
'course_id': course,
'role': 'finance_admin',
'org': 'edx',
'email': email
}
self.client.login(username=self.user.username, password='test')
# Adding new role with invalid data
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertContains(
response,
'Cannot find course with id {} in the modulestore'.format(
course
)
)
self.assertContains(
response,
"Email not exists. Could not find user by email address {}".format(
email
)
)
def test_save_valid_course_invalid_org(self):
data = {
'course_id': unicode(self.course.id),
'role': 'finance_admin',
'org': 'edxxx',
'email': self.user.email
}
self.client.login(username=self.user.username, password='test')
# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
self.assertContains(
response,
'Org name {} is not valid. Valid name is {}.'.format(
'edxxx', 'edx'
)
)
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