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