Merge pull request #19301 from edx/bessiesteinberg/REVE-23-beta-testers
REVE-101: Fix Beta Tester Experience and Test
This commit is contained in:
@@ -24,6 +24,7 @@ from lms.djangoapps.courseware.masquerade import (
|
||||
from xmodule.partitions.partitions import Group, UserPartition, UserPartitionError
|
||||
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from student.roles import CourseBetaTesterRole
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -157,6 +158,10 @@ class ContentTypeGatingPartitionScheme(object):
|
||||
if not course_mode.has_verified_mode(modes_dict):
|
||||
return cls.FULL_ACCESS
|
||||
|
||||
# If the user is a beta tester for this course they are granted FULL_ACCESS
|
||||
if CourseBetaTesterRole(course_key).has_user(user):
|
||||
return cls.FULL_ACCESS
|
||||
|
||||
course_enrollment = apps.get_model('student.CourseEnrollment')
|
||||
|
||||
mode_slug, is_active = course_enrollment.enrollment_mode_for_user(user, course_key)
|
||||
|
||||
@@ -16,7 +16,7 @@ from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||
from openedx.core.lib.url_utils import quote_slashes
|
||||
from openedx.features.content_type_gating.partitions import CONTENT_GATING_PARTITION_ID
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from student.roles import CourseBetaTesterRole, CourseInstructorRole, CourseStaffRole
|
||||
from student.tests.factories import (
|
||||
AdminFactory,
|
||||
CourseAccessRoleFactory,
|
||||
@@ -384,13 +384,21 @@ class TestProblemTypeAccess(SharedModuleStoreTestCase):
|
||||
# There are two types of course team members: instructor and staff
|
||||
# they have different privileges, but for the purpose of this test the important thing is that they should both
|
||||
# have access to all graded content
|
||||
course_team = []
|
||||
instructor = UserFactory.create()
|
||||
CourseInstructorRole(self.course.id).add_users(instructor)
|
||||
course_team.append(instructor)
|
||||
|
||||
staff = UserFactory.create()
|
||||
CourseStaffRole(self.course.id).add_users(staff)
|
||||
course_team.append(staff)
|
||||
|
||||
beta_tester = UserFactory.create()
|
||||
CourseBetaTesterRole(self.course.id).add_users(beta_tester)
|
||||
course_team.append(beta_tester)
|
||||
|
||||
# assert that all course team members have access to graded content
|
||||
for course_team_member in [instructor, staff]:
|
||||
for course_team_member in course_team:
|
||||
self._assert_block_is_gated(
|
||||
block=self.blocks_dict['problem'],
|
||||
user_id=course_team_member.id,
|
||||
|
||||
@@ -18,6 +18,7 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
|
||||
from openedx.core.djangoapps.util.user_messages import PageLevelMessages
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from student.roles import CourseBetaTesterRole
|
||||
|
||||
MIN_DURATION = timedelta(weeks=4)
|
||||
MAX_DURATION = timedelta(weeks=12)
|
||||
@@ -64,6 +65,10 @@ def get_user_course_expiration_date(user, course):
|
||||
if enrollment is None or enrollment.mode != 'audit':
|
||||
return None
|
||||
|
||||
# if the user is a beta tester their access should not expire
|
||||
if CourseBetaTesterRole(course.id).has_user(user):
|
||||
return None
|
||||
|
||||
try:
|
||||
# Content availability date is equivalent to max(enrollment date, course start date)
|
||||
# for most people. Using the schedule date will provide flexibility to deal with
|
||||
|
||||
@@ -32,7 +32,7 @@ from openedx.features.course_experience import (
|
||||
UNIFIED_COURSE_TAB_FLAG
|
||||
)
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from student.roles import CourseBetaTesterRole, CourseInstructorRole, CourseStaffRole
|
||||
from student.tests.factories import UserFactory
|
||||
from util.date_utils import strftime_localized
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
@@ -339,35 +339,51 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
|
||||
|
||||
# create a list of those users who should not lose their access,
|
||||
# then assert that their access persists past the 'expiration date'
|
||||
users_no_expired_access = []
|
||||
users = []
|
||||
|
||||
verified_user = UserFactory(password=self.TEST_PASSWORD)
|
||||
verified_enrollment = CourseEnrollment.enroll(verified_user, course.id, mode=CourseMode.VERIFIED)
|
||||
ScheduleFactory(start=THREE_YEARS_AGO, enrollment=verified_enrollment)
|
||||
users_no_expired_access.append((verified_user, 'Verified Learner'))
|
||||
users.append({
|
||||
'user': verified_user,
|
||||
'description': 'Verified Learner'
|
||||
})
|
||||
|
||||
# There are two types of course team members: instructor and staff
|
||||
# they have different privileges, but for the purpose of this test the important thing is that they should
|
||||
# retain their access to the course after the access would expire for a normal audit learner
|
||||
instructor = UserFactory.create(password=self.TEST_PASSWORD)
|
||||
enrollment = CourseEnrollment.enroll(instructor, course.id, mode=CourseMode.AUDIT)
|
||||
CourseInstructorRole(course.id).add_users(instructor)
|
||||
ScheduleFactory(start=THREE_YEARS_AGO, enrollment=enrollment)
|
||||
users_no_expired_access.append((instructor, 'Course Instructor'))
|
||||
# There are a number of roles that make up the 'course team' and none of them should lose
|
||||
# access to the course
|
||||
course_team = [
|
||||
{
|
||||
'description': 'Course Instructor',
|
||||
'course_role': CourseInstructorRole,
|
||||
},
|
||||
{
|
||||
'description': 'Course Staff',
|
||||
'course_role': CourseStaffRole,
|
||||
},
|
||||
{
|
||||
'description': 'Beta Tester',
|
||||
'course_role': CourseBetaTesterRole,
|
||||
}
|
||||
]
|
||||
|
||||
staff = UserFactory.create(password=self.TEST_PASSWORD)
|
||||
enrollment = CourseEnrollment.enroll(staff, course.id, mode=CourseMode.AUDIT)
|
||||
CourseStaffRole(course.id).add_users(staff)
|
||||
ScheduleFactory(start=THREE_YEARS_AGO, enrollment=enrollment)
|
||||
users_no_expired_access.append((staff, 'Course Staff'))
|
||||
for course_team_member in course_team:
|
||||
user = UserFactory.create(password=self.TEST_PASSWORD)
|
||||
enrollment = CourseEnrollment.enroll(user, course.id, mode=CourseMode.AUDIT)
|
||||
course_team_member['course_role'](course.id).add_users(user)
|
||||
ScheduleFactory(start=THREE_YEARS_AGO, enrollment=enrollment)
|
||||
users.append({
|
||||
'user': user,
|
||||
'description': course_team_member['description'],
|
||||
})
|
||||
|
||||
for user, user_description in users_no_expired_access:
|
||||
self.client.login(username=user.username, password=self.TEST_PASSWORD)
|
||||
# ensure that all users who should have access indefinitely do
|
||||
for user in users:
|
||||
self.client.login(username=user['user'].username, password=self.TEST_PASSWORD)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
200,
|
||||
"Should not expire access for user [{}]".format(user_description)
|
||||
"Should not expire access for user [{}]".format(user['description'])
|
||||
)
|
||||
|
||||
@mock.patch.dict(settings.FEATURES, {'DISABLE_START_DATES': False})
|
||||
|
||||
Reference in New Issue
Block a user