Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 49 additions & 114 deletions cms/djangoapps/contentstore/tests/test_course_create_rerun.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,25 @@


import datetime
from unittest import mock

import ddt
import six
from django.contrib.admin.sites import AdminSite
from django.http import HttpRequest
from django.test import override_settings
from django.test.client import RequestFactory
from django.urls import reverse
from mock import patch
from opaque_keys.edx.keys import CourseKey
from organizations.api import add_organization, get_course_organizations, get_organization_by_short_name
from organizations.models import Organization

from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, parse_json
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.models import CourseAccessRole
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.util.organizations_helpers import add_organization, get_course_organizations
from xmodule.course_module import CourseFields
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory

from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, parse_json
from cms.djangoapps.course_creators.admin import CourseCreatorAdmin
from cms.djangoapps.course_creators.models import CourseCreator
from common.djangoapps.student.auth import update_org_role
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, OrgContentCreatorRole
from common.djangoapps.student.tests.factories import AdminFactory, UserFactory


def mock_render_to_string(template_name, context):
"""Return a string that encodes template_name and context"""
return str((template_name, context))


@ddt.ddt
class TestCourseListing(ModuleStoreTestCase):
Expand All @@ -47,10 +35,12 @@ def setUp(self):
"""
super(TestCourseListing, self).setUp()
# create and log in a staff user.
self.admin_user = UserFactory(is_staff=True)
self.admin_client = AjaxEnabledTestClient()
self.admin_client.login(username=self.admin_user.username, password='test')
# create and log in a non-staff user
self.user = UserFactory()
self.factory = RequestFactory()
self.global_admin = AdminFactory()
self.client = AjaxEnabledTestClient()
self.client.login(username=self.user.username, password='test')
self.course_create_rerun_url = reverse('course_handler')
Expand All @@ -70,12 +60,6 @@ def setUp(self):
)
self.source_course_key = source_course.id

self.course_creator_entry = CourseCreator(user=self.user)
self.course_creator_entry.save()
self.request = HttpRequest()
self.request.user = self.global_admin
self.creator_admin = CourseCreatorAdmin(self.course_creator_entry, AdminSite())

for role in [CourseInstructorRole, CourseStaffRole]:
role(self.source_course_key).add_users(self.user)

Expand All @@ -84,6 +68,7 @@ def tearDown(self):
Reverse the setup
"""
self.client.logout()
self.admin_client.logout()
ModuleStoreTestCase.tearDown(self)

@patch.dict('django.conf.settings.FEATURES', {'ORGANIZATIONS_APP': True})
Expand Down Expand Up @@ -197,11 +182,11 @@ def test_course_creation_with_org_in_system(self, store):
self.assertEqual(len(course_orgs), 1)
self.assertEqual(course_orgs[0]['short_name'], 'orgX')

@override_settings(FEATURES={'ENABLE_CREATOR_GROUP': True})
@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_course_creation_when_user_not_in_org(self, store):
"""
Tests course creation when user doesn't have the required role.
Tests course creation with restriction and user not registered in CourseAccessRole.
"""
with modulestore().default_store(store):
response = self.client.ajax_post(self.course_create_rerun_url, {
Expand All @@ -210,117 +195,67 @@ def test_course_creation_when_user_not_in_org(self, store):
'display_name': 'Course with web certs enabled',
'run': '2021_T1'
})
self.assertEqual(response.status_code, 403)
self.assertEqual(response.status_code, 400)
data = parse_json(response)
self.assertEqual(
data["error"],
'User does not have the permission to create courses in this organization'
)

@override_settings(FEATURES={'ENABLE_CREATOR_GROUP': True})
@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_course_creation_when_user_in_org_with_creator_role(self, store):
def test_course_creation_when_user_in_org(self, store):
"""
Tests course creation with user having the organization content creation role.
Tests course creation with restriction and user registered as staff.
"""
add_organization({
'name': 'Test Organization',
'short_name': self.source_course_key.org,
'description': 'Testing Organization Description',
})
update_org_role(self.global_admin, OrgContentCreatorRole, self.user, [self.source_course_key.org])
staff_role = 'staff'
CourseAccessRole.objects.create(
org='TestorgX', role=staff_role, user=self.user
)
with modulestore().default_store(store):
response = self.client.ajax_post(self.course_create_rerun_url, {
'org': self.source_course_key.org,
'org': 'TestorgX',
'number': 'CS101',
'display_name': 'Course with web certs enabled',
'run': '2021_T1'
})
self.assertEqual(response.status_code, 200)

@override_settings(FEATURES={'ENABLE_CREATOR_GROUP': True})
@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@mock.patch(
'cms.djangoapps.course_creators.admin.render_to_string',
mock.Mock(side_effect=mock_render_to_string, autospec=True)
)
def test_course_creation_with_all_org_checked(self, store):
def test_course_creation_when_user_in_org_with_non_access_role(self, store):
"""
Tests course creation with user having permission to create course for all organization.
Tests course creation with restriction and user registered as role who doesn't have the access.
"""
add_organization({
'name': 'Test Organization',
'short_name': self.source_course_key.org,
'description': 'Testing Organization Description',
})
self.course_creator_entry.all_organizations = True
self.course_creator_entry.state = CourseCreator.GRANTED
self.creator_admin.save_model(self.request, self.course_creator_entry, None, True)
staff_role = 'finance_admin'
CourseAccessRole.objects.create(
org='Stark', role=staff_role, user=self.user
)
with modulestore().default_store(store):
response = self.client.ajax_post(self.course_create_rerun_url, {
'org': self.source_course_key.org,
'number': 'CS101',
'display_name': 'Course with web certs enabled',
'org': 'Stark',
'number': 'AV101',
'display_name': 'Build Iron Man Suit',
'run': '2021_T1'
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.status_code, 400)
data = parse_json(response)
self.assertEqual(
data["error"],
'User does not have the permission to create courses in this organization'
)

@override_settings(FEATURES={'ENABLE_CREATOR_GROUP': True})
@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@mock.patch(
'cms.djangoapps.course_creators.admin.render_to_string',
mock.Mock(side_effect=mock_render_to_string, autospec=True)
)
def test_course_creation_with_permission_for_specific_organization(self, store):
def test_course_creation_when_user_is_global_staff(self, store):
"""
Tests course creation with user having permission to create course for specific organization.
Tests course creation with restriction and user is global staff.
"""
add_organization({
'name': 'Test Organization',
'short_name': self.source_course_key.org,
'description': 'Testing Organization Description',
})
self.course_creator_entry.all_organizations = False
self.course_creator_entry.state = CourseCreator.GRANTED
self.creator_admin.save_model(self.request, self.course_creator_entry, None, True)
dc_org_object = Organization.objects.get(name='Test Organization')
self.course_creator_entry.organizations.add(dc_org_object)
with modulestore().default_store(store):
response = self.client.ajax_post(self.course_create_rerun_url, {
'org': self.source_course_key.org,
'number': 'CS101',
'display_name': 'Course with web certs enabled',
response = self.admin_client.ajax_post(self.course_create_rerun_url, {
'org': 'Oscorp',
'number': 'SP101',
'display_name': 'Making better web',
'run': '2021_T1'
})
self.assertEqual(response.status_code, 200)

@override_settings(FEATURES={'ENABLE_CREATOR_GROUP': True})
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@mock.patch(
'cms.djangoapps.course_creators.admin.render_to_string',
mock.Mock(side_effect=mock_render_to_string, autospec=True)
)
def test_course_creation_without_permission_for_specific_organization(self, store):
"""
Tests course creation with user not having permission to create course for specific organization.
"""
add_organization({
'name': 'Test Organization',
'short_name': self.source_course_key.org,
'description': 'Testing Organization Description',
})
add_organization({
'name': 'DC',
'short_name': 'DC',
'description': 'DC Comics',
})
self.course_creator_entry.all_organizations = False
self.course_creator_entry.state = CourseCreator.GRANTED
self.creator_admin.save_model(self.request, self.course_creator_entry, None, True)
# User has been given the permission to create course under `DC` organization.
# When the user tries to create course under `Test Organization` it throws a 403.
dc_org_object = Organization.objects.get(name='DC')
self.course_creator_entry.organizations.add(dc_org_object)
with modulestore().default_store(store):
response = self.client.ajax_post(self.course_create_rerun_url, {
'org': self.source_course_key.org,
'number': 'CS101',
'display_name': 'Course with web certs enabled',
'run': '2021_T1'
})
self.assertEqual(response.status_code, 403)
72 changes: 72 additions & 0 deletions cms/djangoapps/contentstore/tests/test_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
OrgLibraryUserRole,
OrgStaffRole
)
from common.djangoapps.student.models import CourseAccessRole
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.xblock_django.user_service import DjangoXBlockUserService
from xmodule.modulestore import ModuleStoreEnum
Expand Down Expand Up @@ -829,6 +830,77 @@ def _get_settings_html():
self.assertNotIn('admin_lib_2', non_staff_settings_html)


@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
def test_library_creation_when_user_is_global_staff(self):
"""
Tests course creation with restriction and user is global staff.
"""
self._login_as_staff_user()
response = self.client.ajax_post(LIBRARY_REST_URL, {
'org': 'Oscorp',
'library': 'CentralLibrary',
'display_name': 'Making better web',
})
self.assertEqual(response.status_code, 200)

@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
def test_library_creation_with_normaL_user_with_no_role(self):
"""
Tests course creation with restriction and user is not a global staff.
"""
self._login_as_non_staff_user()
response = self.client.ajax_post(LIBRARY_REST_URL, {
'org': 'Stark',
'library': 'AvengerLibrary',
'display_name': 'Alien Science',
})
self.assertEqual(response.status_code, 400)
data = parse_json(response)
self.assertEqual(
data["ErrMsg"],
"User does not have the permission to create library in this organization"
)

@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
def test_library_creation_with_normaL_user_with_non_access_role(self):
"""
Tests course creation with restriction and user doesn't have access role for org.
"""
staff_role = "finance_admin"
self._login_as_non_staff_user()
CourseAccessRole.objects.create(
org='Stark', role=staff_role, user=self.non_staff_user
)
response = self.client.ajax_post(LIBRARY_REST_URL, {
'org': 'Stark',
'library': 'AvengerLibrary',
'display_name': 'Alien Science',
})
self.assertEqual(response.status_code, 400)
data = parse_json(response)
self.assertEqual(
data["ErrMsg"],
"User does not have the permission to create library in this organization"
)

@patch.dict('django.conf.settings.FEATURES', {'RESTRICT_COURSE_CREATION_TO_ORG_ROLES': True})
def test_library_creation_with_normaL_user_with_role(self):
"""
Tests course creation with restriction and user has role access.
"""
staff_role = "instructor"
self._login_as_non_staff_user()
CourseAccessRole.objects.create(
org='Stark', role=staff_role, user=self.non_staff_user
)
response = self.client.ajax_post(LIBRARY_REST_URL, {
'org': 'Stark',
'library': 'AvengerLibrary',
'display_name': 'Alien Science',
})
self.assertEqual(response.status_code, 200)


@ddt.ddt
@override_settings(SEARCH_ENGINE=None)
class TestOverrides(LibraryTestCase):
Expand Down
Loading