diff --git a/lms/djangoapps/courseware/roles.py b/lms/djangoapps/courseware/roles.py index 1643dd5051..110bb9f362 100644 --- a/lms/djangoapps/courseware/roles.py +++ b/lms/djangoapps/courseware/roles.py @@ -187,6 +187,6 @@ class OrgStaffRole(OrgRole): class OrgInstructorRole(OrgRole): - """An organization staff member""" + """An organization instructor""" def __init__(self, *args, **kwargs): - super(OrgInstructorRole, self).__init__('staff', *args, **kwargs) + super(OrgInstructorRole, self).__init__('instructor', *args, **kwargs) diff --git a/lms/djangoapps/courseware/tests/factories.py b/lms/djangoapps/courseware/tests/factories.py index 2163edb55e..38ad365011 100644 --- a/lms/djangoapps/courseware/tests/factories.py +++ b/lms/djangoapps/courseware/tests/factories.py @@ -14,7 +14,14 @@ from student.tests.factories import RegistrationFactory # Imported to re-export from student.tests.factories import UserProfileFactory as StudentUserProfileFactory from courseware.models import StudentModule, XModuleUserStateSummaryField from courseware.models import XModuleStudentInfoField, XModuleStudentPrefsField -from courseware.roles import CourseInstructorRole, CourseStaffRole, CourseBetaTesterRole, GlobalStaff +from courseware.roles import ( + CourseInstructorRole, + CourseStaffRole, + CourseBetaTesterRole, + GlobalStaff, + OrgStaffRole, + OrgInstructorRole, +) from xmodule.modulestore import Location @@ -64,10 +71,38 @@ class BetaTesterFactory(UserFactory): @post_generation def course(self, create, extracted, **kwargs): if extracted is None: - raise ValueError("Must specify a course location for a course staff user") + raise ValueError("Must specify a course location for a beta-tester user") CourseBetaTesterRole(extracted).add_users(self) +class OrgStaffFactory(UserFactory): + """ + Given a course Location, returns a User object with org-staff + permissions for `course`. + """ + last_name = "Org-Staff" + + @post_generation + def course(self, create, extracted, **kwargs): + if extracted is None: + raise ValueError("Must specify a course location for an org-staff user") + OrgStaffRole(extracted).add_users(self) + + +class OrgInstructorFactory(UserFactory): + """ + Given a course Location, returns a User object with org-instructor + permissions for `course`. + """ + last_name = "Org-Instructor" + + @post_generation + def course(self, create, extracted, **kwargs): + if extracted is None: + raise ValueError("Must specify a course location for an org-instructor user") + OrgInstructorRole(extracted).add_users(self) + + class GlobalStaffFactory(UserFactory): """ Returns a User object with global staff access @@ -79,7 +114,6 @@ class GlobalStaffFactory(UserFactory): GlobalStaff().add_users(self) - class StudentModuleFactory(DjangoModelFactory): FACTORY_FOR = StudentModule diff --git a/lms/djangoapps/courseware/tests/test_view_authentication.py b/lms/djangoapps/courseware/tests/test_view_authentication.py index ce035ff9e8..9ed0dea8e5 100644 --- a/lms/djangoapps/courseware/tests/test_view_authentication.py +++ b/lms/djangoapps/courseware/tests/test_view_authentication.py @@ -18,7 +18,14 @@ from student.tests.factories import UserFactory, CourseEnrollmentFactory from courseware.tests.helpers import LoginEnrollmentTestCase, check_for_get_code from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE -from courseware.tests.factories import BetaTesterFactory, StaffFactory, GlobalStaffFactory, InstructorFactory +from courseware.tests.factories import ( + BetaTesterFactory, + StaffFactory, + GlobalStaffFactory, + InstructorFactory, + OrgStaffFactory, + OrgInstructorFactory, +) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @@ -108,12 +115,18 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.courseware_chapter = ItemFactory.create(display_name='courseware') self.test_course = CourseFactory.create(number='666', display_name='Robot_Sub_Course') - self.sub_courseware_chapter = ItemFactory.create(parent_location=self.test_course.location, - display_name='courseware') - self.sub_overview_chapter = ItemFactory.create(parent_location=self.sub_courseware_chapter.location, - display_name='Overview') - self.welcome_section = ItemFactory.create(parent_location=self.overview_chapter.location, - display_name='Welcome') + self.other_org_course = CourseFactory.create(org='Other_Org_Course') + self.sub_courseware_chapter = ItemFactory.create( + parent_location=self.test_course.location, display_name='courseware' + ) + self.sub_overview_chapter = ItemFactory.create( + parent_location=self.sub_courseware_chapter.location, + display_name='Overview' + ) + self.welcome_section = ItemFactory.create( + parent_location=self.overview_chapter.location, + display_name='Welcome' + ) self.unenrolled_user = UserFactory(last_name="Unenrolled") @@ -123,6 +136,8 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.staff_user = StaffFactory(course=self.course.location) self.instructor_user = InstructorFactory(course=self.course.location) + self.org_staff_user = OrgStaffFactory(course=self.course.location) + self.org_instructor_user = OrgInstructorFactory(course=self.course.location) self.global_staff_user = GlobalStaffFactory() def test_redirection_unenrolled(self): @@ -169,7 +184,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): def test_staff_course_access(self): """ - Verify instructor can load the instructor dashboard, the grade views, + Verify staff can load the staff dashboard, the grade views, and student profile pages for their course. """ self.login(self.staff_user) @@ -195,6 +210,36 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id}) check_for_get_code(self, 404, url) + def test_org_staff_access(self): + """ + Verify org staff can load the instructor dashboard, the grade views, + and student profile pages for course in their org. + """ + self.login(self.org_staff_user) + url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id}) + check_for_get_code(self, 200, url) + + url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id}) + check_for_get_code(self, 200, url) + + url = reverse('instructor_dashboard', kwargs={'course_id': self.other_org_course.id}) + check_for_get_code(self, 404, url) + + def test_org_instructor_access(self): + """ + Verify org instructor can load the instructor dashboard, the grade views, + and student profile pages for course in their org. + """ + self.login(self.org_instructor_user) + url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id}) + check_for_get_code(self, 200, url) + + url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id}) + check_for_get_code(self, 200, url) + + url = reverse('instructor_dashboard', kwargs={'course_id': self.other_org_course.id}) + check_for_get_code(self, 404, url) + def test_global_staff_access(self): """ Verify the global staff user can access any course.