feat: feature setting to gate courseware search to verified enrollments (#34606)
Adds a Django setting that limits courseware search to users in a verified enrollment track.
This commit is contained in:
@@ -3748,6 +3748,8 @@ class TestPublicVideoXBlockEmbedView(TestBasePublicVideoXBlock):
|
||||
assert context['course'] == self.course
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@override_waffle_flag(COURSEWARE_MICROFRONTEND_SEARCH_ENABLED, active=True)
|
||||
class TestCoursewareMFESearchAPI(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Tests the endpoint to fetch the Courseware Search waffle flag enabled status.
|
||||
@@ -3761,12 +3763,36 @@ class TestCoursewareMFESearchAPI(SharedModuleStoreTestCase):
|
||||
self.client = APIClient()
|
||||
self.apiUrl = reverse('courseware_search_enabled_view', kwargs={'course_id': str(self.course.id)})
|
||||
|
||||
@override_waffle_flag(COURSEWARE_MICROFRONTEND_SEARCH_ENABLED, active=True)
|
||||
def test_courseware_mfe_search_enabled(self):
|
||||
@ddt.data(
|
||||
(CourseMode.AUDIT, False),
|
||||
(CourseMode.VERIFIED, True),
|
||||
(CourseMode.MASTERS, True),
|
||||
)
|
||||
@ddt.unpack
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_COURSEWARE_SEARCH_VERIFIED_ENROLLMENT_REQUIRED': True})
|
||||
def test_courseware_mfe_search_verified_only(self, mode, expected_enabled):
|
||||
"""
|
||||
Getter to check if user is allowed to use Courseware Search.
|
||||
Only verified enrollees may use Courseware Search if ENABLE_COURSEWARE_SEARCH_VERIFIED_ENROLLMENT_REQUIRED
|
||||
is enabled.
|
||||
"""
|
||||
user = UserFactory()
|
||||
CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode=mode)
|
||||
|
||||
self.client.login(username=user.username, password=TEST_PASSWORD)
|
||||
response = self.client.get(self.apiUrl, content_type='application/json')
|
||||
body = json.loads(response.content.decode('utf-8'))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(body, {'enabled': expected_enabled})
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_COURSEWARE_SEARCH_VERIFIED_ENROLLMENT_REQUIRED': True})
|
||||
def test_courseware_mfe_search_staff_access(self):
|
||||
"""
|
||||
Staff users may use Courseware Search regardless of their enrollment status.
|
||||
"""
|
||||
user_staff = UserFactory(is_staff=True) # not enrolled
|
||||
|
||||
self.client.login(username=user_staff.username, password=TEST_PASSWORD)
|
||||
response = self.client.get(self.apiUrl, content_type='application/json')
|
||||
body = json.loads(response.content.decode('utf-8'))
|
||||
|
||||
@@ -3774,11 +3800,13 @@ class TestCoursewareMFESearchAPI(SharedModuleStoreTestCase):
|
||||
self.assertEqual(body, {'enabled': True})
|
||||
|
||||
@override_waffle_flag(COURSEWARE_MICROFRONTEND_SEARCH_ENABLED, active=False)
|
||||
def test_is_mfe_search_disabled(self):
|
||||
def test_is_mfe_search_waffle_disabled(self):
|
||||
"""
|
||||
Getter to check if user is allowed to use Courseware Search.
|
||||
Courseware search is only available when the waffle flag is enabled.
|
||||
"""
|
||||
|
||||
user_admin = UserFactory(is_staff=True, is_superuser=True)
|
||||
CourseEnrollmentFactory.create(user=user_admin, course_id=self.course.id, mode=CourseMode.VERIFIED)
|
||||
self.client.login(username=user_admin.username, password=TEST_PASSWORD)
|
||||
response = self.client.get(self.apiUrl, content_type='application/json')
|
||||
body = json.loads(response.content.decode('utf-8'))
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ from xmodule.x_module import STUDENT_VIEW
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode, get_course_prices
|
||||
from common.djangoapps.edxmako.shortcuts import marketing_link, render_to_response, render_to_string
|
||||
from common.djangoapps.student import auth
|
||||
from common.djangoapps.student.roles import CourseStaffRole
|
||||
from common.djangoapps.student.models import CourseEnrollment, UserTestGroup
|
||||
from common.djangoapps.util.cache import cache, cache_if_anonymous
|
||||
from common.djangoapps.util.course import course_location_from_key
|
||||
@@ -2261,10 +2263,22 @@ def get_learner_username(learner_identifier):
|
||||
@api_view(['GET'])
|
||||
def courseware_mfe_search_enabled(request, course_id=None):
|
||||
"""
|
||||
Simple GET endpoint to expose whether the course may use Courseware Search.
|
||||
Simple GET endpoint to expose whether the user may use Courseware Search
|
||||
for a given course.
|
||||
"""
|
||||
|
||||
enabled = False
|
||||
course_key = CourseKey.from_string(course_id) if course_id else None
|
||||
user = request.user
|
||||
|
||||
payload = {"enabled": courseware_mfe_search_is_enabled(course_key)}
|
||||
if settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH_VERIFIED_ENROLLMENT_REQUIRED'):
|
||||
enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user(user, course_key)
|
||||
if (
|
||||
auth.user_has_role(user, CourseStaffRole(CourseKey.from_string(course_id)))
|
||||
or (enrollment_mode in CourseMode.VERIFIED_MODES)
|
||||
):
|
||||
enabled = True
|
||||
else:
|
||||
enabled = True
|
||||
|
||||
payload = {"enabled": courseware_mfe_search_is_enabled(course_key) if enabled else False}
|
||||
return JsonResponse(payload)
|
||||
|
||||
@@ -1060,6 +1060,15 @@ FEATURES = {
|
||||
# .. toggle_tickets: https://github.com/openedx/edx-platform/pull/33911
|
||||
'ENABLE_GRADING_METHOD_IN_PROBLEMS': False,
|
||||
|
||||
# .. toggle_name: FEATURES['ENABLE_COURSEWARE_SEARCH_VERIFIED_REQUIRED']
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: When enabled, the courseware search feature will only be enabled
|
||||
# for users in a verified enrollment track.
|
||||
# .. toggle_use_cases: open_edx
|
||||
# .. toggle_creation_date: 2024-04-24
|
||||
'ENABLE_COURSEWARE_SEARCH_VERIFIED_ENROLLMENT_REQUIRED': False,
|
||||
|
||||
# .. toggle_name: FEATURES['ENABLE_BLAKE2B_HASHING']
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
|
||||
Reference in New Issue
Block a user