def test_setting_overridden_by_setting_toggle(self): _toggle2 = SettingToggle("MYSETTING2", module_name="module1") _toggle3 = SettingDictToggle("MYDICT", "MYSETTING3", module_name="module1") with override_settings(MYSETTING1=True, MYSETTING2=False, MYDICT={"MYSETTING3": False}): # Need to pre-load settings, otherwise they are not picked up by the view self.assertTrue(settings.MYSETTING1) report = ToggleStateReport().as_dict() setting_dict = { toggle["name"]: toggle for toggle in report["django_settings"] } # Check that Django settings for which a SettingToggle exists have both the correct is_active and class values self.assertTrue(setting_dict["MYSETTING1"]["is_active"]) self.assertNotIn("class", setting_dict["MYSETTING1"]) self.assertFalse(setting_dict["MYSETTING2"]["is_active"]) self.assertEqual("SettingToggle", setting_dict["MYSETTING2"]["class"]) self.assertFalse(setting_dict["MYDICT['MYSETTING3']"]["is_active"]) self.assertEqual("SettingDictToggle", setting_dict["MYDICT['MYSETTING3']"]["class"])
def test_setting_overridden_by_setting_toggle(self): _toggle2 = SettingToggle("MYSETTING2", module_name="module1") _toggle3 = SettingDictToggle("MYDICT", "MYSETTING3", module_name="module1") with override_settings(MYSETTING1=True, MYSETTING2=False, MYDICT={"MYSETTING3": False}): # Need to pre-load settings, otherwise they are not picked up by the view assert settings.MYSETTING1 response = self._get_toggle_state_response() setting_dict = { toggle["name"]: toggle for toggle in response.data["django_settings"] } # Check that Django settings for which a SettingToggle exists have both the correct is_active and class values assert setting_dict['MYSETTING1']['is_active'] assert 'class' not in setting_dict['MYSETTING1'] assert not setting_dict['MYSETTING2']['is_active'] assert 'SettingToggle' == setting_dict['MYSETTING2']['class'] assert not setting_dict["MYDICT['MYSETTING3']"]['is_active'] assert 'SettingDictToggle' == setting_dict["MYDICT['MYSETTING3']"][ 'class']
def _add_setting_dict_toggles(settings_dict): """ Fill the `settings_dict` with values from the list of SettingDictToggle instances. """ for toggle in SettingDictToggle.get_instances(): name = setting_dict_name(toggle.name, toggle.key) toggle_response = get_or_create_toggle_response(settings_dict, name) toggle_response["is_active"] = toggle.is_enabled() _add_toggle_instance_details(toggle_response, toggle)
def test_response_with_existing_setting_dict_toggle(self): _toggle = SettingDictToggle("FEATURES", "MYFEATURE", default=True, module_name="module1") report = ToggleStateReport().as_dict() self.assertIn( { "name": "FEATURES['MYFEATURE']", "is_active": True, "module": "module1", "class": "SettingDictToggle", }, report["django_settings"], )
def test_no_duplicate_setting_toggle(self): _toggle1 = SettingToggle( "MYSETTING1", module_name="module1" ) _toggle2 = SettingDictToggle( "MYDICT", "MYSETTING2", module_name="module1" ) with override_settings(MYSETTING1=True, MYDICT={"MYSETTING2": False}): response = self._get_toggle_state_response() # Check there are no duplicate setting/toggle response_toggles_1 = [toggle for toggle in response.data["django_settings"] if toggle["name"] == "MYSETTING1"] response_toggles_2 = [ toggle for toggle in response.data["django_settings"] if toggle["name"] == "MYDICT['MYSETTING2']" ] self.assertEqual(1, len(response_toggles_1)) self.assertEqual(1, len(response_toggles_2))
def test_response_with_new_setting_dict_toggle(self): _toggle = SettingDictToggle( "CUSTOM_FEATURES", "MYSETTING", default=False, module_name="module1" ) with override_settings(CUSTOM_FEATURES={"MYSETTING": True}): response = self._get_toggle_state_response() setting_dict = {toggle["name"]: toggle for toggle in response.data["django_settings"]} self.assertEqual( { "name": "CUSTOM_FEATURES['MYSETTING']", "is_active": True, "module": "module1", "class": "SettingDictToggle", }, setting_dict["CUSTOM_FEATURES['MYSETTING']"], )
def test_response_with_new_setting_dict_toggle(self): _toggle = SettingDictToggle("CUSTOM_FEATURES", "MYSETTING", default=False, module_name="module1") with override_settings(CUSTOM_FEATURES={"MYSETTING": True}): response = self._get_toggle_state_response() setting_dict = { toggle["name"]: toggle for toggle in response.data["django_settings"] } assert { 'name': "CUSTOM_FEATURES['MYSETTING']", 'is_active': True, 'module': 'module1', 'class': 'SettingDictToggle' } == setting_dict["CUSTOM_FEATURES['MYSETTING']"]
} REQUEST_CACHE_NAME = "milestones" # TODO this should be moved to edx/edx-milestones # .. toggle_name: FEATURES['ENABLE_MILESTONES_APP'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: Enable the milestones application, which manages significant Course and/or Student events in # the Open edX platform. (see https://github.com/edx/edx-milestones) # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2014-11-21 # .. toggle_target_removal_date: None # .. toggle_warnings: None # .. toggle_tickets: None ENABLE_MILESTONES_APP = SettingDictToggle("FEATURES", "MILESTONES_APP", default=False, module_name=__name__) def get_namespace_choices(): """ Return the enum to the caller """ return NAMESPACE_CHOICES def is_prerequisite_courses_enabled(): """ Returns boolean indicating prerequisite courses enabled system wide or not. """ return settings.FEATURES.get('ENABLE_PREREQUISITE_COURSES') and ENABLE_MILESTONES_APP.is_enabled()
from edx_toggles.toggles import SettingDictToggle, WaffleFlag from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag # .. toggle_name: FEATURES['ENABLE_EXPORT_GIT'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: When enabled, a "Export to Git" menu item is added to the course studio for courses that have a # valid "giturl" attribute. Exporting a course to git causes the course to be exported in the directory indicated by # the GIT_REPO_EXPORT_DIR setting. Note that when this feature is disabled, courses can still be exported to git with # the git_export management command. # .. toggle_warnings: To enable this feature, the GIT_REPO_EXPORT_DIR setting must be properly defined and point to an # existing directory. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2014-02-13 EXPORT_GIT = SettingDictToggle("FEATURES", "ENABLE_EXPORT_GIT", default=False, module_name=__name__) # Namespace for studio dashboard waffle flags. CONTENTSTORE_NAMESPACE = 'contentstore' CONTENTSTORE_LOG_PREFIX = 'Contentstore: ' # .. toggle_name: contentstore.split_library_on_studio_dashboard # .. toggle_implementation: WaffleFlag # .. toggle_default: False # .. toggle_description: Enables data new view for library on studio dashboard. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2020-07-8 # .. toggle_tickets: TNL-7536 SPLIT_LIBRARY_ON_DASHBOARD = WaffleFlag( f'{CONTENTSTORE_NAMESPACE}.split_library_on_studio_dashboard',
""" from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace, SettingDictToggle # .. toggle_name: FEATURES['ENABLE_EXPORT_GIT'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: When enabled, a "Export to Git" menu item is added to the course studio for courses that have a # valid "giturl" attribute. Exporting a course to git causes the course to be exported in the directory indicated by # the GIT_REPO_EXPORT_DIR setting. Note that when this feature is disabled, courses can still be exported to git with # the git_export management command. # .. toggle_warnings: To enable this feature, the GIT_REPO_EXPORT_DIR setting must be properly defined and point to an # existing directory. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2014-02-13 EXPORT_GIT = SettingDictToggle("FEATURES", "ENABLE_EXPORT_GIT", default=False, module_name=__name__) # Namespace for studio dashboard waffle flags. WAFFLE_NAMESPACE = 'contentstore' WAFFLE_FLAG_NAMESPACE = LegacyWaffleFlagNamespace(name=WAFFLE_NAMESPACE, log_prefix='Contentstore: ') # Waffle flag to split library to new view. # .. toggle_name: split_library_on_studio_dashboard # .. toggle_implementation: WaffleFlag # .. toggle_default: False # .. toggle_description: Studio dashboard # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2020-07-8 # .. toggle_target_removal_date: None
TIMED_EXAM_GATING_WAFFLE_FLAG = LegacyWaffleFlag( # lint-amnesty, pylint: disable=toggle-missing-annotation waffle_namespace="xmodule", flag_name='rev_1377_rollout', module_name=__name__, ) # .. toggle_name: FEATURES['SHOW_PROGRESS_BAR'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: Set to True to show progress bar. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2022-02-09 # .. toggle_target_removal_date: None SHOW_PROGRESS_BAR = SettingDictToggle("FEATURES", "SHOW_PROGRESS_BAR", default=False, module_name=__name__) class SequenceFields: # lint-amnesty, pylint: disable=missing-class-docstring has_children = True completion_mode = XBlockCompletionMode.AGGREGATOR # NOTE: Position is 1-indexed. This is silly, but there are now student # positions saved on prod, so it's not easy to fix. position = Integer(help="Last tab viewed in this sequence", scope=Scope.user_state) due = Date( display_name=_("Due Date"), help=_("Enter the date by which problems are due."),
WAFFLE_NAMESPACE = "openresponseassessment" TEAM_SUBMISSIONS_FLAG = "team_submissions" # .. toggle_name: FEATURES['ENABLE_ORA_TEAM_SUBMISSIONS'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: Set to True to enable team-based ORA submissions. # .. toggle_use_cases: temporary # .. toggle_creation_date: 2020-03-03 # .. toggle_target_removal_date: None # .. toggle_tickets: https://openedx.atlassian.net/browse/EDUCATOR-4951 # .. toggle_warnings: This temporary feature toggle does not have a target removal date. This can be overridden by a # course waffle flags or a waffle switch with identical name. # TODO: this should be moved to edx/edx-ora2 TEAM_SUBMISSIONS_FEATURE = SettingDictToggle("FEATURES", "ENABLE_ORA_TEAM_SUBMISSIONS", default=False, module_name=__name__) def are_team_submissions_enabled(course_key): """ Checks to see if the CourseWaffleFlag or Django setting for team submissions is enabled """ if CourseWaffleFlag(f'{WAFFLE_NAMESPACE}.{TEAM_SUBMISSIONS_FLAG}', __name__).is_enabled(course_key): return True # TODO: this behaviour differs from edx-ora2, where the WaffleSwitch overrides the setting. # https://github.com/edx/edx-ora2/blob/ac502d8301cb987c9885aaefbaeddaf456c13fb9/openassessment/xblock/config_mixin.py#L96 if TEAM_SUBMISSIONS_FEATURE.is_enabled():
""" Feature toggles used across the platform. Toggles should only be added to this module if we don't have a better place for them. Generally speaking, they should be added to the most appropriate app or repo. """ from edx_toggles.toggles import SettingDictToggle # .. toggle_name: FEATURES['ENTRANCE_EXAMS'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: False # .. toggle_description: Enable entrance exams feature. When enabled, students see an exam xblock as the first unit # of the course. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2015-12-01 # .. toggle_target_removal_date: None # .. toggle_warnings: None # .. toggle_tickets: https://openedx.atlassian.net/browse/SOL-40 ENTRANCE_EXAMS = SettingDictToggle("FEATURES", "ENTRANCE_EXAMS", default=False, module_name=__name__)
Helpers for the credentials service. """ from edx_toggles.toggles import SettingDictToggle from openedx.core.djangoapps.site_configuration import helpers as config_helpers # .. toggle_name: FEATURES['ENABLE_LEARNER_RECORDS'] # .. toggle_implementation: SettingDictToggle # .. toggle_default: True # .. toggle_description: Enable learner records for the whole platform. This setting may be overridden by site- and # org-specific site configurations with the same name. # .. toggle_warnings: Enabling this feature requires that the definition of the ``CREDENTIALS_PUBLIC_SERVICE_URL`` # setting. # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2020-10-01 ENABLE_LEARNER_RECORDS = SettingDictToggle("FEATURES", "ENABLE_LEARNER_RECORDS", default=True, module_name=__name__) def is_learner_records_enabled(): return config_helpers.get_value("ENABLE_LEARNER_RECORDS", ENABLE_LEARNER_RECORDS.is_enabled()) def is_learner_records_enabled_for_org(org): return config_helpers.get_value_for_org( org, "ENABLE_LEARNER_RECORDS", ENABLE_LEARNER_RECORDS.is_enabled())