Commit e968c0c0 by Calen Pennington

Merge pull request #1743 from cpennington/fix-beta-tester-roles

Fix for [LMS-1528], plus Changelog entry for the related feature
parents 87f19469 24aa0dec
...@@ -9,6 +9,10 @@ LMS: Add feature for providing background grade report generation via Celery ...@@ -9,6 +9,10 @@ LMS: Add feature for providing background grade report generation via Celery
instructor task, with reports uploaded to S3. Feature is visible on the beta instructor task, with reports uploaded to S3. Feature is visible on the beta
instructor dashboard. LMS-58 instructor dashboard. LMS-58
LMS: Beta-tester status is now set on a per-course-run basis, rather than being valid
across all runs with the same course name. Old group membership will still work
across runs, but new beta-testers will only be added to a single course run.
LMS: Add a user-visible alert modal when a forums AJAX request fails. LMS: Add a user-visible alert modal when a forums AJAX request fails.
Blades: Add template for checkboxes response to studio. BLD-193. Blades: Add template for checkboxes response to studio. BLD-193.
......
...@@ -241,7 +241,11 @@ def _has_access_descriptor(user, descriptor, action, course_context=None): ...@@ -241,7 +241,11 @@ def _has_access_descriptor(user, descriptor, action, course_context=None):
# Check start date # Check start date
if descriptor.start is not None: if descriptor.start is not None:
now = datetime.now(UTC()) now = datetime.now(UTC())
effective_start = _adjust_start_date_for_beta_testers(user, descriptor) effective_start = _adjust_start_date_for_beta_testers(
user,
descriptor,
course_context=course_context
)
if now > effective_start: if now > effective_start:
# after start date, everyone can see it # after start date, everyone can see it
debug("Allow: now > effective start date") debug("Allow: now > effective start date")
...@@ -337,7 +341,7 @@ def _dispatch(table, action, user, obj): ...@@ -337,7 +341,7 @@ def _dispatch(table, action, user, obj):
type(obj), action)) type(obj), action))
def _adjust_start_date_for_beta_testers(user, descriptor): def _adjust_start_date_for_beta_testers(user, descriptor, course_context=None):
""" """
If user is in a beta test group, adjust the start date by the appropriate number of If user is in a beta test group, adjust the start date by the appropriate number of
days. days.
...@@ -364,7 +368,7 @@ def _adjust_start_date_for_beta_testers(user, descriptor): ...@@ -364,7 +368,7 @@ def _adjust_start_date_for_beta_testers(user, descriptor):
# bail early if no beta testing is set up # bail early if no beta testing is set up
return descriptor.start return descriptor.start
if CourseBetaTesterRole(descriptor.location).has_user(user): if CourseBetaTesterRole(descriptor.location, course_context=course_context).has_user(user):
debug("Adjust start time: user in beta role for %s", descriptor) debug("Adjust start time: user in beta role for %s", descriptor)
delta = timedelta(descriptor.days_early_for_beta) delta = timedelta(descriptor.days_early_for_beta)
effective = descriptor.start - delta effective = descriptor.start - delta
......
...@@ -187,6 +187,6 @@ class OrgStaffRole(OrgRole): ...@@ -187,6 +187,6 @@ class OrgStaffRole(OrgRole):
class OrgInstructorRole(OrgRole): class OrgInstructorRole(OrgRole):
"""An organization staff member""" """An organization instructor"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(OrgInstructorRole, self).__init__('staff', *args, **kwargs) super(OrgInstructorRole, self).__init__('instructor', *args, **kwargs)
...@@ -14,7 +14,14 @@ from student.tests.factories import RegistrationFactory # Imported to re-export ...@@ -14,7 +14,14 @@ from student.tests.factories import RegistrationFactory # Imported to re-export
from student.tests.factories import UserProfileFactory as StudentUserProfileFactory from student.tests.factories import UserProfileFactory as StudentUserProfileFactory
from courseware.models import StudentModule, XModuleUserStateSummaryField from courseware.models import StudentModule, XModuleUserStateSummaryField
from courseware.models import XModuleStudentInfoField, XModuleStudentPrefsField from courseware.models import XModuleStudentInfoField, XModuleStudentPrefsField
from courseware.roles import CourseInstructorRole, CourseStaffRole from courseware.roles import (
CourseInstructorRole,
CourseStaffRole,
CourseBetaTesterRole,
GlobalStaff,
OrgStaffRole,
OrgInstructorRole,
)
from xmodule.modulestore import Location from xmodule.modulestore import Location
...@@ -54,6 +61,59 @@ class StaffFactory(UserFactory): ...@@ -54,6 +61,59 @@ class StaffFactory(UserFactory):
CourseStaffRole(extracted).add_users(self) 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 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
"""
last_name = "GlobalStaff"
@post_generation
def set_staff(self, create, extracted, **kwargs):
GlobalStaff().add_users(self)
class StudentModuleFactory(DjangoModelFactory): class StudentModuleFactory(DjangoModelFactory):
FACTORY_FOR = StudentModule FACTORY_FOR = StudentModule
......
...@@ -9,14 +9,23 @@ from django.test.utils import override_settings ...@@ -9,14 +9,23 @@ from django.test.utils import override_settings
# Need access to internal func to put users in the right group # Need access to internal func to put users in the right group
from courseware.access import has_access 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.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory 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.helpers import LoginEnrollmentTestCase, check_for_get_code
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
from courseware.tests.factories import (
BetaTesterFactory,
StaffFactory,
GlobalStaffFactory,
InstructorFactory,
OrgStaffFactory,
OrgInstructorFactory,
)
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
...@@ -89,13 +98,16 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -89,13 +98,16 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
# user (the student), and the requesting user (the prof) # user (the student), and the requesting user (the prof)
url = reverse('student_progress', url = reverse('student_progress',
kwargs={'course_id': course.id, 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) check_for_get_code(self, 404, url)
# The courseware url should redirect, not 200 # The courseware url should redirect, not 200
url = self._reverse_urls(['courseware'], course)[0] url = self._reverse_urls(['courseware'], course)[0]
check_for_get_code(self, 302, url) check_for_get_code(self, 302, url)
def login(self, user):
return super(TestViewAuth, self).login(user.email, 'test')
def setUp(self): def setUp(self):
self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course') self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course')
...@@ -103,26 +115,37 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -103,26 +115,37 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.courseware_chapter = ItemFactory.create(display_name='courseware') self.courseware_chapter = ItemFactory.create(display_name='courseware')
self.test_course = CourseFactory.create(number='666', display_name='Robot_Sub_Course') self.test_course = CourseFactory.create(number='666', display_name='Robot_Sub_Course')
self.sub_courseware_chapter = ItemFactory.create(parent_location=self.test_course.location, self.other_org_course = CourseFactory.create(org='Other_Org_Course')
display_name='courseware') self.sub_courseware_chapter = ItemFactory.create(
self.sub_overview_chapter = ItemFactory.create(parent_location=self.sub_courseware_chapter.location, parent_location=self.test_course.location, display_name='courseware'
display_name='Overview') )
self.welcome_section = ItemFactory.create(parent_location=self.overview_chapter.location, self.sub_overview_chapter = ItemFactory.create(
display_name='Welcome') parent_location=self.sub_courseware_chapter.location,
display_name='Overview'
# Create two accounts and activate them. )
for i in range(len(self.ACCOUNT_INFO)): self.welcome_section = ItemFactory.create(
username, email, password = 'u{0}'.format(i), self.ACCOUNT_INFO[i][0], self.ACCOUNT_INFO[i][1] parent_location=self.overview_chapter.location,
self.create_account(username, email, password) display_name='Welcome'
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.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): def test_redirection_unenrolled(self):
""" """
Verify unenrolled student is redirected to the 'about' section of the chapter Verify unenrolled student is redirected to the 'about' section of the chapter
instead of the 'Welcome' section after clicking on the courseware tab. instead of the 'Welcome' section after clicking on the courseware tab.
""" """
email, password = self.ACCOUNT_INFO[0] self.login(self.unenrolled_user)
self.login(email, password)
response = self.client.get(reverse('courseware', response = self.client.get(reverse('courseware',
kwargs={'course_id': self.course.id})) kwargs={'course_id': self.course.id}))
self.assertRedirects(response, self.assertRedirects(response,
...@@ -134,9 +157,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -134,9 +157,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
Verify enrolled student is redirected to the 'Welcome' section of Verify enrolled student is redirected to the 'Welcome' section of
the chapter after clicking on the courseware tab. the chapter after clicking on the courseware tab.
""" """
email, password = self.ACCOUNT_INFO[0] self.login(self.enrolled_user)
self.login(email, password)
self.enroll(self.course)
response = self.client.get(reverse('courseware', response = self.client.get(reverse('courseware',
kwargs={'course_id': self.course.id})) kwargs={'course_id': self.course.id}))
...@@ -152,11 +173,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -152,11 +173,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
Verify non-staff cannot load the instructor Verify non-staff cannot load the instructor
dashboard, the grade views, and student profile pages. dashboard, the grade views, and student profile pages.
""" """
email, password = self.ACCOUNT_INFO[0] self.login(self.enrolled_user)
self.login(email, password)
self.enroll(self.course)
self.enroll(self.test_course)
urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}), urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}),
reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id})] reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id})]
...@@ -165,37 +182,69 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -165,37 +182,69 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
for url in urls: for url in urls:
check_for_get_code(self, 404, url) check_for_get_code(self, 404, url)
def test_staff_course_access(self):
"""
Verify staff can load the staff dashboard, the grade views,
and student profile pages for their course.
"""
self.login(self.staff_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})
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)
def test_instructor_course_access(self): def test_instructor_course_access(self):
""" """
Verify instructor can load the instructor dashboard, the grade views, Verify instructor can load the instructor dashboard, the grade views,
and student profile pages for their course. and student profile pages for their course.
""" """
email, password = self.ACCOUNT_INFO[1] self.login(self.instructor_user)
# Make the instructor staff in self.course # Now should be able to get to self.course, but not self.test_course
CourseInstructorRole(self.course.location).add_users(User.objects.get(email=email)) url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id})
check_for_get_code(self, 200, url)
self.login(email, password) url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id})
check_for_get_code(self, 404, url)
# Now should be able to get to self.course, but not self.test_course 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}) url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id})
check_for_get_code(self, 200, url) check_for_get_code(self, 200, url)
url = reverse('instructor_dashboard', kwargs={'course_id': self.test_course.id}) 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) check_for_get_code(self, 404, url)
def test_instructor_as_staff_access(self): def test_org_instructor_access(self):
""" """
Verify the instructor can load staff pages if he is given Verify org instructor can load the instructor dashboard, the grade views,
staff permissions. and student profile pages for course in their org.
""" """
email, password = self.ACCOUNT_INFO[1] self.login(self.org_instructor_user)
self.login(email, password) 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)
# now make the instructor also staff url = reverse('instructor_dashboard', kwargs={'course_id': self.other_org_course.id})
instructor = User.objects.get(email=email) check_for_get_code(self, 404, url)
instructor.is_staff = True
instructor.save() def test_global_staff_access(self):
"""
Verify the global staff user can access any course.
"""
self.login(self.global_staff_user)
# and now should be able to load both # and now should be able to load both
urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}), urls = [reverse('instructor_dashboard', kwargs={'course_id': self.course.id}),
...@@ -211,8 +260,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -211,8 +260,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
pages. pages.
""" """
student_email, student_password = self.ACCOUNT_INFO[0]
# Make courses start in the future # Make courses start in the future
now = datetime.datetime.now(pytz.UTC) now = datetime.datetime.now(pytz.UTC)
tomorrow = now + datetime.timedelta(days=1) tomorrow = now + datetime.timedelta(days=1)
...@@ -225,9 +272,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -225,9 +272,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertFalse(self.test_course.has_started()) self.assertFalse(self.test_course.has_started())
# First, try with an enrolled student # First, try with an enrolled student
self.login(student_email, student_password) self.login(self.enrolled_user)
self.enroll(self.course, True)
self.enroll(self.test_course, True)
# shouldn't be able to get to anything except the light pages # shouldn't be able to get to anything except the light pages
self._check_non_staff_light(self.course) self._check_non_staff_light(self.course)
...@@ -241,8 +286,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -241,8 +286,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
Make sure that before course start instructors can access the Make sure that before course start instructors can access the
page for their course. page for their course.
""" """
instructor_email, instructor_password = self.ACCOUNT_INFO[1]
now = datetime.datetime.now(pytz.UTC) now = datetime.datetime.now(pytz.UTC)
tomorrow = now + datetime.timedelta(days=1) tomorrow = now + datetime.timedelta(days=1)
course_data = {'start': tomorrow} course_data = {'start': tomorrow}
...@@ -250,11 +293,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -250,11 +293,7 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.course = self.update_course(self.course, course_data) self.course = self.update_course(self.course, course_data)
self.test_course = self.update_course(self.test_course, test_course_data) self.test_course = self.update_course(self.test_course, test_course_data)
# Make the instructor staff in self.course self.login(self.instructor_user)
CourseStaffRole(self.course.location).add_users(User.objects.get(email=instructor_email))
self.logout()
self.login(instructor_email, instructor_password)
# Enroll in the classes---can't see courseware otherwise. # Enroll in the classes---can't see courseware otherwise.
self.enroll(self.course, True) self.enroll(self.course, True)
self.enroll(self.test_course, True) self.enroll(self.test_course, True)
...@@ -265,13 +304,11 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -265,13 +304,11 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self._check_staff(self.course) self._check_staff(self.course)
@patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False}) @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 Make sure that before course start staff can access
course pages. course pages.
""" """
instructor_email, instructor_password = self.ACCOUNT_INFO[1]
now = datetime.datetime.now(pytz.UTC) now = datetime.datetime.now(pytz.UTC)
tomorrow = now + datetime.timedelta(days=1) tomorrow = now + datetime.timedelta(days=1)
course_data = {'start': tomorrow} course_data = {'start': tomorrow}
...@@ -279,15 +316,10 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -279,15 +316,10 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.course = self.update_course(self.course, course_data) self.course = self.update_course(self.course, course_data)
self.test_course = self.update_course(self.test_course, test_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.course, True)
self.enroll(self.test_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 # and now should be able to load both
self._check_staff(self.course) self._check_staff(self.course)
self._check_staff(self.test_course) self._check_staff(self.test_course)
...@@ -297,9 +329,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -297,9 +329,6 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" """
Check that enrollment periods work. 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 # Make courses start in the future
now = datetime.datetime.now(pytz.UTC) now = datetime.datetime.now(pytz.UTC)
tomorrow = now + datetime.timedelta(days=1) tomorrow = now + datetime.timedelta(days=1)
...@@ -315,52 +344,53 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -315,52 +344,53 @@ class TestViewAuth(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.test_course = self.update_course(self.test_course, test_course_data) self.test_course = self.update_course(self.test_course, test_course_data)
# First, try with an enrolled student # First, try with an enrolled student
self.login(student_email, student_password) self.login(self.unenrolled_user)
self.assertFalse(self.enroll(self.course)) self.assertFalse(self.enroll(self.course))
self.assertTrue(self.enroll(self.test_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.logout()
self.login(instructor_email, instructor_password) self.login(self.instructor_user)
self.assertTrue(self.enroll(self.course)) 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 # unenroll and try again
self.unenroll(self.course) self.login(self.global_staff_user)
self.assertTrue(self.enroll(self.course)) 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) now = datetime.datetime.now(pytz.UTC)
tomorrow = now + datetime.timedelta(days=1) tomorrow = now + datetime.timedelta(days=1)
course_data = {'start': tomorrow}
# self.course's hasn't started self.course = CourseFactory(days_early_for_beta=2, start=tomorrow)
self.course = self.update_course(self.course, course_data) self.content = ItemFactory(parent=self.course)
self.assertFalse(self.course.has_started())
self.normal_student = UserFactory()
self.beta_tester = BetaTesterFactory(course=self.course.location)
# but should be accessible for beta testers @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False})
self.course.days_early_for_beta = 2 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 shouldn't see it
student_user = User.objects.get(email=student_email) self.assertFalse(has_access(self.normal_student, self.course, 'load'))
self.assertFalse(has_access(student_user, self.course, 'load'))
# now the student should see it
self.assertTrue(has_access(self.beta_tester, self.course, 'load'))
# now add the student to the beta test group @patch.dict('courseware.access.settings.MITX_FEATURES', {'DISABLE_START_DATES': False})
CourseBetaTesterRole(self.course.location).add_users(student_user) 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', self.course.id))
# now the student should see it # 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', self.course.id))
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