diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index d8a706fc4f..ac45a98629 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -17,7 +17,10 @@ from django_comment_common.models import assign_default_role from django_comment_common.utils import seed_permissions_roles from openedx.core.djangoapps.site_configuration.models import SiteConfiguration from openedx.features.content_type_gating.models import ContentTypeGatingConfig -from openedx.features.course_duration_limits.config import CONTENT_TYPE_GATING_FLAG +from openedx.features.course_duration_limits.config import ( + CONTENT_TYPE_GATING_FLAG, + FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG +) from student import auth from student.models import CourseEnrollment from student.roles import CourseInstructorRole, CourseStaffRole @@ -460,7 +463,7 @@ def get_visibility_partition_info(xblock, course=None): if len(partition["groups"]) > 1 or any(group["selected"] for group in partition["groups"]): selectable_partitions.append(partition) - flag_enabled = CONTENT_TYPE_GATING_FLAG.is_enabled() + flag_enabled = CONTENT_TYPE_GATING_FLAG.is_enabled() and not FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled() course_key = xblock.scope_ids.usage_id.course_key is_library = isinstance(course_key, LibraryLocator) if not is_library and ( diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py index ad257a06a9..5ca188635c 100644 --- a/lms/djangoapps/grades/tests/test_course_grade_factory.py +++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py @@ -311,7 +311,7 @@ class TestGradeIteration(SharedModuleStoreTestCase): else mock_course_grade.return_value for student in self.students ] - with self.assertNumQueries(8): + with self.assertNumQueries(9): all_course_grades, all_errors = self._course_grades_and_errors_for(self.course, self.students) self.assertEqual( {student: text_type(all_errors[student]) for student in all_errors}, diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 11f16658a5..858ed24245 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -413,7 +413,7 @@ class TestInstructorGradeReport(InstructorGradeReportTestCase): RequestCache.clear_all_namespaces() - expected_query_count = 49 + expected_query_count = 50 with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): with check_mongo_calls(mongo_count): with self.assertNumQueries(expected_query_count): diff --git a/openedx/features/content_type_gating/models.py b/openedx/features/content_type_gating/models.py index 84a6cfe820..f1e36e3c95 100644 --- a/openedx/features/content_type_gating/models.py +++ b/openedx/features/content_type_gating/models.py @@ -17,6 +17,7 @@ from openedx.core.djangoapps.config_model_utils.models import StackedConfigurati from openedx.features.content_type_gating.helpers import has_staff_roles from openedx.features.course_duration_limits.config import ( CONTENT_TYPE_GATING_FLAG, + FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG, EXPERIMENT_ID, EXPERIMENT_DATA_HOLDBACK_KEY ) @@ -68,6 +69,9 @@ class ContentTypeGatingConfig(StackedConfigurationModel): user: The user being queried. course_key: The CourseKey of the course being queried. """ + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return False + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True @@ -141,6 +145,10 @@ class ContentTypeGatingConfig(StackedConfigurationModel): course_key: The CourseKey of the course being queried. target_datetime: The datetime to checked enablement as of. Defaults to the current date and time. """ + + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return False + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True @@ -161,6 +169,10 @@ class ContentTypeGatingConfig(StackedConfigurationModel): Arguments: target_datetime (:class:`datetime.datetime`): The datetime that ``enabled_as_of`` must be equal to or before """ + + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return False + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True diff --git a/openedx/features/content_type_gating/tests/test_models.py b/openedx/features/content_type_gating/tests/test_models.py index ec8f202f4e..c1fee5517d 100644 --- a/openedx/features/content_type_gating/tests/test_models.py +++ b/openedx/features/content_type_gating/tests/test_models.py @@ -73,12 +73,9 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase): user = self.user course_key = self.course_overview.id - if already_enrolled and pass_enrollment: - query_count = 7 - elif not pass_enrollment and already_enrolled: - query_count = 8 - else: - query_count = 7 + query_count = 8 + if not pass_enrollment and already_enrolled: + query_count = 9 with self.assertNumQueries(query_count): enabled = ContentTypeGatingConfig.enabled_for_enrollment( diff --git a/openedx/features/course_duration_limits/config.py b/openedx/features/course_duration_limits/config.py index 71e1ed1b2b..31bb9a06fa 100644 --- a/openedx/features/course_duration_limits/config.py +++ b/openedx/features/course_duration_limits/config.py @@ -19,6 +19,12 @@ CONTENT_TYPE_GATING_FLAG = WaffleFlag( flag_undefined_default=False ) +FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG = WaffleFlag( + waffle_namespace=WAFFLE_FLAG_NAMESPACE, + flag_name=u'global_kill_switch', + flag_undefined_default=False +) + EXPERIMENT_ID = 11 EXPERIMENT_DATA_HOLDBACK_KEY = 'holdback' diff --git a/openedx/features/course_duration_limits/models.py b/openedx/features/course_duration_limits/models.py index 4be9d6a0b3..c3f602b780 100644 --- a/openedx/features/course_duration_limits/models.py +++ b/openedx/features/course_duration_limits/models.py @@ -24,6 +24,7 @@ from openedx.features.content_type_gating.helpers import has_staff_roles from openedx.features.content_type_gating.partitions import CONTENT_GATING_PARTITION_ID, CONTENT_TYPE_GATE_GROUP_IDS from openedx.features.course_duration_limits.config import ( CONTENT_TYPE_GATING_FLAG, + FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG, EXPERIMENT_ID, EXPERIMENT_DATA_HOLDBACK_KEY ) @@ -95,6 +96,10 @@ class CourseDurationLimitConfig(StackedConfigurationModel): user: The user being queried. course_key: The CourseKey of the course being queried. """ + + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return False + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True @@ -163,6 +168,10 @@ class CourseDurationLimitConfig(StackedConfigurationModel): course_key: The CourseKey of the course being queried. target_datetime: The datetime to checked enablement as of. Defaults to the current date and time. """ + + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return False + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True @@ -183,6 +192,10 @@ class CourseDurationLimitConfig(StackedConfigurationModel): Arguments: target_datetime (:class:`datetime.datetime`): The datetime that ``enabled_as_of`` must be equal to or before """ + + if FEATURE_BASED_ENROLLMENT_GLOBAL_KILL_FLAG.is_enabled(): + return True + if CONTENT_TYPE_GATING_FLAG.is_enabled(): return True diff --git a/openedx/features/course_duration_limits/tests/test_models.py b/openedx/features/course_duration_limits/tests/test_models.py index 0bc4595482..cb7a9ab62c 100644 --- a/openedx/features/course_duration_limits/tests/test_models.py +++ b/openedx/features/course_duration_limits/tests/test_models.py @@ -80,9 +80,9 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase): user = self.user course_key = self.course_overview.id - query_count = 7 + query_count = 8 if not pass_enrollment and already_enrolled: - query_count = 8 + query_count = 9 with self.assertNumQueries(query_count): enabled = CourseDurationLimitConfig.enabled_for_enrollment(