From 820e7711716924d328114c42f39c30d158ef8504 Mon Sep 17 00:00:00 2001 From: Calen Pennington <cale@edx.org> Date: Thu, 21 Nov 2013 10:58:27 -0500 Subject: [PATCH] Add failing test for [LMS-1528] Also cleans up test_view_authentication to use user factories for various user classes --- lms/djangoapps/courseware/tests/factories.py | 28 ++- .../tests/test_view_authentication.py | 159 ++++++++---------- 2 files changed, 100 insertions(+), 87 deletions(-) diff --git a/lms/djangoapps/courseware/tests/factories.py b/lms/djangoapps/courseware/tests/factories.py index 91f91f26174..2163edb55e4 100644 --- a/lms/djangoapps/courseware/tests/factories.py +++ b/lms/djangoapps/courseware/tests/factories.py @@ -14,7 +14,7 @@ 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 +from courseware.roles import CourseInstructorRole, CourseStaffRole, CourseBetaTesterRole, GlobalStaff from xmodule.modulestore import Location @@ -54,6 +54,32 @@ class StaffFactory(UserFactory): CourseStaffRole(extracted).add_users(self) +class BetaTesterFactory(UserFactory): + """ + Given a course Location, returns a User object with beta-tester + permissions for `course`. + """ + last_name = "Beta-Tester" + + @post_generation + def course(self, create, extracted, **kwargs): + if extracted is None: + raise ValueError("Must specify a course location for a course staff user") + CourseBetaTesterRole(extracted).add_users(self) + + +class GlobalStaffFactory(UserFactory): + """ + Returns a User object with global staff access + """ + last_name = "GlobalStaff" + + @post_generation + def set_staff(self, create, extracted, **kwargs): + 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 3639d07afaf..df848034476 100644 --- a/lms/djangoapps/courseware/tests/test_view_authentication.py +++ b/lms/djangoapps/courseware/tests/test_view_authentication.py @@ -1,5 +1,6 @@ import datetime import pytz +import unittest from mock import patch @@ -9,14 +10,16 @@ from django.test.utils import override_settings # Need access to internal func to put users in the right group from courseware.access import has_access -from courseware.roles import CourseBetaTesterRole, CourseInstructorRole, CourseStaffRole, GlobalStaff from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory +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 @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @@ -89,13 +92,16 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): # user (the student), and the requesting user (the prof) url = reverse('student_progress', kwargs={'course_id': course.id, - 'student_id': User.objects.get(email=self.ACCOUNT_INFO[0][0]).id}) + 'student_id': self.enrolled_user.id}) check_for_get_code(self, 404, url) # The courseware url should redirect, not 200 url = self._reverse_urls(['courseware'], course)[0] check_for_get_code(self, 302, url) + def login(self, user): + return super(TestViewAuth, self).login(user.email, 'test') + def setUp(self): self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course') @@ -110,19 +116,22 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.welcome_section = ItemFactory.create(parent_location=self.overview_chapter.location, display_name='Welcome') - # Create two accounts and activate them. - for i in range(len(self.ACCOUNT_INFO)): - username, email, password = 'u{0}'.format(i), self.ACCOUNT_INFO[i][0], self.ACCOUNT_INFO[i][1] - self.create_account(username, email, password) - self.activate_user(email) + self.unenrolled_user = UserFactory(last_name="Unenrolled") + + self.enrolled_user = UserFactory(last_name="Enrolled") + CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.course.id) + CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.test_course.id) + + self.staff_user = StaffFactory(course=self.course.location) + self.instructor_user = InstructorFactory(course=self.course.location) + self.global_staff_user = GlobalStaffFactory() def test_redirection_unenrolled(self): """ Verify unenrolled student is redirected to the 'about' section of the chapter instead of the 'Welcome' section after clicking on the courseware tab. """ - email, password = self.ACCOUNT_INFO[0] - self.login(email, password) + self.login(self.unenrolled_user) response = self.client.get(reverse('courseware', kwargs={'course_id': self.course.id})) self.assertRedirects(response, @@ -134,9 +143,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): Verify enrolled student is redirected to the 'Welcome' section of the chapter after clicking on the courseware tab. """ - email, password = self.ACCOUNT_INFO[0] - self.login(email, password) - self.enroll(self.course) + self.login(self.enrolled_user) response = self.client.get(reverse('courseware', kwargs={'course_id': self.course.id})) @@ -152,11 +159,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): Verify non-staff cannot load the instructor dashboard, the grade views, and student profile pages. """ - email, password = self.ACCOUNT_INFO[0] - self.login(email, password) - - self.enroll(self.course) - self.enroll(self.test_course) + self.login(self.enrolled_user) urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}), reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id})] @@ -165,17 +168,26 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): for url in urls: check_for_get_code(self, 404, url) - def test_instructor_course_access(self): + def test_staff_course_access(self): """ Verify instructor can load the instructor dashboard, the grade views, and student profile pages for their course. """ - email, password = self.ACCOUNT_INFO[1] + self.login(self.staff_user) - # Make the instructor staff in self.course - CourseInstructorRole(self.course.location).add_users(User.objects.get(email=email)) + # Now should be able to get to self.course, but not self.test_course + 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, 404, url) - self.login(email, password) + def test_instructor_course_access(self): + """ + Verify instructor can load the instructor dashboard, the grade views, + and student profile pages for their course. + """ + self.login(self.instructor_user) # Now should be able to get to self.course, but not self.test_course url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id}) @@ -184,18 +196,11 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id}) check_for_get_code(self, 404, url) - def test_instructor_as_staff_access(self): + def test_global_staff_access(self): """ - Verify the instructor can load staff pages if he is given - staff permissions. + Verify the global staff user can access any course. """ - email, password = self.ACCOUNT_INFO[1] - self.login(email, password) - - # now make the instructor also staff - instructor = User.objects.get(email=email) - instructor.is_staff = True - instructor.save() + self.login(self.global_staff_user) # and now should be able to load both urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}), @@ -211,8 +216,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): pages. """ - student_email, student_password = self.ACCOUNT_INFO[0] - # Make courses start in the future now = datetime.datetime.now(pytz.UTC) tomorrow = now + datetime.timedelta(days=1) @@ -225,9 +228,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.assertFalse(self.test_course.has_started()) # First, try with an enrolled student - self.login(student_email, student_password) - self.enroll(self.course, True) - self.enroll(self.test_course, True) + self.login(self.enrolled_user) # shouldn't be able to get to anything except the light pages self._check_non_staff_light(self.course) @@ -241,8 +242,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): Make sure that before course start instructors can access the page for their course. """ - instructor_email, instructor_password = self.ACCOUNT_INFO[1] - now = datetime.datetime.now(pytz.UTC) tomorrow = now + datetime.timedelta(days=1) course_data = {'start': tomorrow} @@ -250,11 +249,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.course = self.update_course(self.course, course_data) self.test_course = self.update_course(self.test_course, test_course_data) - # Make the instructor staff in self.course - CourseStaffRole(self.course.location).add_users(User.objects.get(email=instructor_email)) - - self.logout() - self.login(instructor_email, instructor_password) + self.login(self.instructor_user) # Enroll in the classes---can't see courseware otherwise. self.enroll(self.course, True) self.enroll(self.test_course, True) @@ -265,13 +260,11 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self._check_staff(self.course) @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False}) - def test_dark_launch_staff(self): + def test_dark_launch_global_staff(self): """ Make sure that before course start staff can access course pages. """ - instructor_email, instructor_password = self.ACCOUNT_INFO[1] - now = datetime.datetime.now(pytz.UTC) tomorrow = now + datetime.timedelta(days=1) course_data = {'start': tomorrow} @@ -279,15 +272,10 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.course = self.update_course(self.course, course_data) self.test_course = self.update_course(self.test_course, test_course_data) - self.login(instructor_email, instructor_password) + self.login(self.global_staff_user) self.enroll(self.course, True) self.enroll(self.test_course, True) - # now also make the instructor staff - instructor = User.objects.get(email=instructor_email) - instructor.is_staff = True - instructor.save() - # and now should be able to load both self._check_staff(self.course) self._check_staff(self.test_course) @@ -297,9 +285,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): """ Check that enrollment periods work. """ - student_email, student_password = self.ACCOUNT_INFO[0] - instructor_email, instructor_password = self.ACCOUNT_INFO[1] - # Make courses start in the future now = datetime.datetime.now(pytz.UTC) tomorrow = now + datetime.timedelta(days=1) @@ -315,52 +300,54 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): self.test_course = self.update_course(self.test_course, test_course_data) # First, try with an enrolled student - self.login(student_email, student_password) + self.login(self.unenrolled_user) self.assertFalse(self.enroll(self.course)) self.assertTrue(self.enroll(self.test_course)) - # Make the instructor staff in the self.course - instructor_role = CourseInstructorRole(self.course.location) - instructor_role.add_users(User.objects.get(email=instructor_email)) - self.logout() - self.login(instructor_email, instructor_password) + self.login(self.instructor_user) self.assertTrue(self.enroll(self.course)) - # now make the instructor global staff, but not in the instructor group - instructor_role.remove_users(User.objects.get(email=instructor_email)) - GlobalStaff().add_users(User.objects.get(email=instructor_email)) - # unenroll and try again - self.unenroll(self.course) + self.login(self.global_staff_user) self.assertTrue(self.enroll(self.course)) - @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False}) - def test_beta_period(self): - """ - Check that beta-test access works. - """ - student_email, student_password = self.ACCOUNT_INFO[0] - instructor_email, instructor_password = self.ACCOUNT_INFO[1] - # Make courses start in the future +@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) +class TestBetatesterAccess(ModuleStoreTestCase): + + def setUp(self): + now = datetime.datetime.now(pytz.UTC) tomorrow = now + datetime.timedelta(days=1) - course_data = {'start': tomorrow} - # self.course's hasn't started - self.course = self.update_course(self.course, course_data) - self.assertFalse(self.course.has_started()) + self.course = CourseFactory(days_early_for_beta=2, start=tomorrow) + self.content = ItemFactory(parent=self.course) + + self.normal_student = UserFactory() + self.beta_tester = BetaTesterFactory(course=self.course.location) - # but should be accessible for beta testers - self.course.days_early_for_beta = 2 + @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False}) + def test_course_beta_period(self): + """ + Check that beta-test access works for courses. + """ + self.assertFalse(self.course.has_started()) # student user shouldn't see it - student_user = User.objects.get(email=student_email) - self.assertFalse(has_access(student_user, self.course, 'load')) + self.assertFalse(has_access(self.normal_student, self.course, 'load')) - # now add the student to the beta test group - CourseBetaTesterRole(self.course.location).add_users(student_user) + # now the student should see it + self.assertTrue(has_access(self.beta_tester, self.course, 'load')) + + @unittest.expectedFailure + @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False}) + def test_content_beta_period(self): + """ + Check that beta-test access works for content. + """ + # student user shouldn't see it + self.assertFalse(has_access(self.normal_student, self.content, 'load')) # now the student should see it - self.assertTrue(has_access(student_user, self.course, 'load')) + self.assertTrue(has_access(self.beta_tester, self.content, 'load')) -- GitLab