refactor: migrated FEATURES dict settings to top-level in core files and fixed related test files. (#37389)

* refactor: moved remaining feature dicts settings into top-level settings.

* refactor: moved remaining feature dicts settings into top-level settings.

* fix: fixed the test files

* fix: fixed tehe pylint errors

* fix: fixation of the cms ci failure

* fix: fixed remaining feature settings for cms

* fix: added fix for requirements

* fix: added fix for lms tests

* fix: resolved the test views issue

* fix: configured views file and test_views

* fix: fixed lint errors and assertion issues

* fix: added fix for base url issue in test view

* fix: added fix for base_url and assertion issue

* fix: added configurations for base utl fix

* fix: handled none issue for mfe config

* fix: corrected override settings in test views

* fix: added getattr defensive technique for view settings

* fix: reverted views and test_views file

* fix: added settings in views file

* fix: added with patch within functions in test view

* fix: rearranged the features in default_legacy_config

* fix: fixing the tests  with clearing cache

* fix: reverted test views to verify the CI check

* fix: added cache clear in mfe config test

* fix: fixed the patch toggles to override settings

* fix: fixed the lint errors

* fix: changed patch toggle to override settings
This commit is contained in:
Akanshu Aich
2026-01-20 22:25:26 +05:30
committed by GitHub
parent 7ecb6cb79b
commit 2d82d90279
23 changed files with 88 additions and 84 deletions

View File

@@ -388,15 +388,15 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin):
(True, True, True), (True, True, True),
) )
@override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True) @override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True)
@override_settings(MILESTONES_APP=False)
def test_visibility_of_entrance_exam_section(self, feature_flags): def test_visibility_of_entrance_exam_section(self, feature_flags):
""" """
Tests entrance exam section is available if ENTRANCE_EXAMS feature is enabled no matter any other Tests entrance exam section is available if ENTRANCE_EXAMS feature is enabled no matter any other
feature is enabled or disabled i.e ENABLE_PUBLISHER. feature is enabled or disabled i.e ENABLE_PUBLISHER.
""" """
with patch.dict("django.conf.settings.FEATURES", { with patch.dict("django.conf.settings.FEATURES", {
'ENTRANCE_EXAMS': feature_flags[0],
'ENABLE_PUBLISHER': feature_flags[1] 'ENABLE_PUBLISHER': feature_flags[1]
}): }), override_settings(ENTRANCE_EXAMS=feature_flags[0]):
course_details_url = get_url(self.course.id) course_details_url = get_url(self.course.id)
resp = self.client.get_html(course_details_url) resp = self.client.get_html(course_details_url)
self.assertEqual( self.assertEqual(
@@ -405,14 +405,15 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin):
) )
@override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True) @override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True)
@override_settings(MILESTONES_APP=False)
@override_settings(ENTRANCE_EXAMS=False)
def test_marketing_site_fetch(self): def test_marketing_site_fetch(self):
settings_details_url = get_url(self.course.id) settings_details_url = get_url(self.course.id)
with mock.patch.dict('django.conf.settings.FEATURES', { with mock.patch.dict('django.conf.settings.FEATURES', {
'ENABLE_PUBLISHER': True, 'ENABLE_PUBLISHER': True,
'ENABLE_MKTG_SITE': True, 'ENABLE_MKTG_SITE': True,
'ENTRANCE_EXAMS': False, 'ENABLE_PREREQUISITE_COURSES': False,
'ENABLE_PREREQUISITE_COURSES': False
}): }):
response = self.client.get_html(settings_details_url) response = self.client.get_html(settings_details_url)
self.assertNotContains(response, "Course Summary Page") self.assertNotContains(response, "Course Summary Page")
@@ -1128,7 +1129,7 @@ class CourseMetadataEditingTest(CourseTestCase):
self.assertIn('showanswer', test_model, 'showanswer field ') self.assertIn('showanswer', test_model, 'showanswer field ')
self.assertIn('xqa_key', test_model, 'xqa_key field ') self.assertIn('xqa_key', test_model, 'xqa_key field ')
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': True}) @override_settings(ENABLE_EXPORT_GIT=True)
def test_fetch_giturl_present(self): def test_fetch_giturl_present(self):
""" """
If feature flag ENABLE_EXPORT_GIT is on, show the setting as a non-deprecated Advanced Setting. If feature flag ENABLE_EXPORT_GIT is on, show the setting as a non-deprecated Advanced Setting.
@@ -1136,7 +1137,7 @@ class CourseMetadataEditingTest(CourseTestCase):
test_model = CourseMetadata.fetch(self.fullcourse) test_model = CourseMetadata.fetch(self.fullcourse)
self.assertIn('giturl', test_model) self.assertIn('giturl', test_model)
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': False}) @override_settings(ENABLE_EXPORT_GIT=False)
def test_fetch_giturl_not_present(self): def test_fetch_giturl_not_present(self):
""" """
If feature flag ENABLE_EXPORT_GIT is off, don't show the setting at all on the Advanced Settings page. If feature flag ENABLE_EXPORT_GIT is off, don't show the setting at all on the Advanced Settings page.
@@ -1172,7 +1173,7 @@ class CourseMetadataEditingTest(CourseTestCase):
test_model = CourseMetadata.fetch(self.fullcourse) test_model = CourseMetadata.fetch(self.fullcourse)
self.assertNotIn('proctoring_escalation_email', test_model) self.assertNotIn('proctoring_escalation_email', test_model)
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': False}) @override_settings(ENABLE_EXPORT_GIT=False)
def test_validate_update_filtered_off(self): def test_validate_update_filtered_off(self):
""" """
If feature flag is off, then giturl must be filtered. If feature flag is off, then giturl must be filtered.
@@ -1187,7 +1188,7 @@ class CourseMetadataEditingTest(CourseTestCase):
) )
self.assertNotIn('giturl', test_model) self.assertNotIn('giturl', test_model)
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': True}) @override_settings(ENABLE_EXPORT_GIT=True)
def test_validate_update_filtered_on(self): def test_validate_update_filtered_on(self):
""" """
If feature flag is on, then giturl must not be filtered. If feature flag is on, then giturl must not be filtered.
@@ -1202,7 +1203,7 @@ class CourseMetadataEditingTest(CourseTestCase):
) )
self.assertIn('giturl', test_model) self.assertIn('giturl', test_model)
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': True}) @override_settings(ENABLE_EXPORT_GIT=True)
def test_update_from_json_filtered_on(self): def test_update_from_json_filtered_on(self):
""" """
If feature flag is on, then giturl must be updated. If feature flag is on, then giturl must be updated.
@@ -1216,7 +1217,7 @@ class CourseMetadataEditingTest(CourseTestCase):
) )
self.assertIn('giturl', test_model) self.assertIn('giturl', test_model)
@patch.dict(settings.FEATURES, {'ENABLE_EXPORT_GIT': False}) @override_settings(ENABLE_EXPORT_GIT=False)
def test_update_from_json_filtered_off(self): def test_update_from_json_filtered_off(self):
""" """
If feature flag is on, then giturl must not be updated. If feature flag is on, then giturl must not be updated.

View File

@@ -892,8 +892,8 @@ class UpdateCourseDetailsTests(ModuleStoreTestCase):
@patch.dict("django.conf.settings.FEATURES", { @patch.dict("django.conf.settings.FEATURES", {
"ENABLE_PREREQUISITE_COURSES": False, "ENABLE_PREREQUISITE_COURSES": False,
"ENTRANCE_EXAMS": False,
}) })
@override_settings(ENTRANCE_EXAMS=False)
@patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json") @patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json")
def test_update_course_details_self_paced(self, mock_update): def test_update_course_details_self_paced(self, mock_update):
""" """
@@ -918,8 +918,8 @@ class UpdateCourseDetailsTests(ModuleStoreTestCase):
@patch.dict("django.conf.settings.FEATURES", { @patch.dict("django.conf.settings.FEATURES", {
"ENABLE_PREREQUISITE_COURSES": False, "ENABLE_PREREQUISITE_COURSES": False,
"ENTRANCE_EXAMS": False,
}) })
@override_settings(ENTRANCE_EXAMS=False)
@patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json") @patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json")
def test_update_course_details_instructor_paced(self, mock_update): def test_update_course_details_instructor_paced(self, mock_update):
""" """

View File

@@ -1,13 +1,13 @@
""" """
CMS feature toggles. CMS feature toggles.
""" """
from edx_toggles.toggles import SettingDictToggle, WaffleFlag from edx_toggles.toggles import SettingToggle, WaffleFlag
from openedx.core.djangoapps.content.search import api as search_api from openedx.core.djangoapps.content.search import api as search_api
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
# .. toggle_name: FEATURES['ENABLE_EXPORT_GIT'] # .. toggle_name: ENABLE_EXPORT_GIT
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: When enabled, a "Export to Git" menu item is added to the course studio for courses that have a # .. 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 # valid "giturl" attribute. Exporting a course to git causes the course to be exported in the directory indicated by
@@ -17,8 +17,8 @@ from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
# existing directory. # existing directory.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2014-02-13 # .. toggle_creation_date: 2014-02-13
EXPORT_GIT = SettingDictToggle( EXPORT_GIT = SettingToggle(
"FEATURES", "ENABLE_EXPORT_GIT", default=False, module_name=__name__ "ENABLE_EXPORT_GIT", default=False, module_name=__name__
) )
# Namespace for studio dashboard waffle flags. # Namespace for studio dashboard waffle flags.
@@ -406,8 +406,8 @@ def default_enable_flexible_peer_openassessments(course_key):
return DEFAULT_ENABLE_FLEXIBLE_PEER_OPENASSESSMENTS.is_enabled(course_key) return DEFAULT_ENABLE_FLEXIBLE_PEER_OPENASSESSMENTS.is_enabled(course_key)
# .. toggle_name: FEATURES['ENABLE_CONTENT_LIBRARIES'] # .. toggle_name: ENABLE_CONTENT_LIBRARIES
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: True # .. toggle_default: True
# .. toggle_description: Enables use of the legacy and v2 libraries waffle flags. # .. toggle_description: Enables use of the legacy and v2 libraries waffle flags.
# Note that legacy content libraries are only supported in courses using split mongo. # Note that legacy content libraries are only supported in courses using split mongo.
@@ -416,8 +416,8 @@ def default_enable_flexible_peer_openassessments(course_key):
# .. toggle_target_removal_date: 2025-04-09 # .. toggle_target_removal_date: 2025-04-09
# .. toggle_warning: This flag is deprecated in Sumac, and will be removed in favor of the disable_legacy_libraries and # .. toggle_warning: This flag is deprecated in Sumac, and will be removed in favor of the disable_legacy_libraries and
# disable_new_libraries waffle flags. # disable_new_libraries waffle flags.
ENABLE_CONTENT_LIBRARIES = SettingDictToggle( ENABLE_CONTENT_LIBRARIES = SettingToggle(
"FEATURES", "ENABLE_CONTENT_LIBRARIES", default=True, module_name=__name__ "ENABLE_CONTENT_LIBRARIES", default=True, module_name=__name__
) )
# .. toggle_name: contentstore.new_studio_mfe.disable_legacy_libraries # .. toggle_name: contentstore.new_studio_mfe.disable_legacy_libraries

View File

@@ -4,9 +4,9 @@ Test module for Entrance Exams AJAX callback handler workflows
import json import json
from unittest.mock import patch
from django.conf import settings from django.conf import settings
from django.test import override_settings
from django.test.client import RequestFactory from django.test.client import RequestFactory
from milestones.tests.utils import MilestonesTestCaseMixin from milestones.tests.utils import MilestonesTestCaseMixin
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey
@@ -30,7 +30,7 @@ from cms.djangoapps.contentstore.helpers import GRADER_TYPES
from cms.djangoapps.contentstore.xblock_storage_handlers.create_xblock import create_xblock from cms.djangoapps.contentstore.xblock_storage_handlers.create_xblock import create_xblock
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
class EntranceExamHandlerTests(CourseTestCase, MilestonesTestCaseMixin): class EntranceExamHandlerTests(CourseTestCase, MilestonesTestCaseMixin):
""" """
Base test class for create, save, and delete Base test class for create, save, and delete
@@ -319,7 +319,7 @@ class EntranceExamHandlerTests(CourseTestCase, MilestonesTestCaseMixin):
resp = create_entrance_exam(request, self.course.id, None) resp = create_entrance_exam(request, self.course.id, None)
self.assertEqual(resp.status_code, 201) self.assertEqual(resp.status_code, 201)
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': False}) @override_settings(ENTRANCE_EXAMS=False)
def test_entrance_exam_feature_flag_gating(self): def test_entrance_exam_feature_flag_gating(self):
user = UserFactory() user = UserFactory()
user.is_staff = True user.is_staff = True

View File

@@ -161,7 +161,7 @@ class UnitTestLibraries(CourseTestCase):
self.assertEqual(get_response.status_code, 200) self.assertEqual(get_response.status_code, 200)
self.assertEqual(post_response.status_code, 403) self.assertEqual(post_response.status_code, 403)
@mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_CONTENT_LIBRARIES': False}) @override_settings(ENABLE_CONTENT_LIBRARIES=False)
def test_with_libraries_disabled(self): def test_with_libraries_disabled(self):
""" """
The library URLs should return 404 if libraries are disabled. The library URLs should return 404 if libraries are disabled.

View File

@@ -3,7 +3,7 @@ Utility library for working with the edx-milestones app
""" """
from django.conf import settings from django.conf import settings
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from edx_toggles.toggles import SettingDictToggle from edx_toggles.toggles import SettingToggle
from milestones import api as milestones_api from milestones import api as milestones_api
from milestones.exceptions import InvalidMilestoneRelationshipTypeException, InvalidUserException from milestones.exceptions import InvalidMilestoneRelationshipTypeException, InvalidUserException
from milestones.models import MilestoneRelationshipType from milestones.models import MilestoneRelationshipType
@@ -23,15 +23,15 @@ NAMESPACE_CHOICES = {
REQUEST_CACHE_NAME = "milestones" REQUEST_CACHE_NAME = "milestones"
# TODO this should be moved to edx/edx-milestones # TODO this should be moved to edx/edx-milestones
# .. toggle_name: FEATURES['MILESTONES_APP'] # .. toggle_name: MILESTONES_APP
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: Enable the milestones application, which manages significant Course and/or Student events in # .. toggle_description: Enable the milestones application, which manages significant Course and/or Student events in
# the Open edX platform. (see https://github.com/openedx/edx-milestones) Note that this feature is required to enable # the Open edX platform. (see https://github.com/openedx/edx-milestones) Note that this feature is required to enable
# course pre-requisites. # course pre-requisites.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2014-11-21 # .. toggle_creation_date: 2014-11-21
ENABLE_MILESTONES_APP = SettingDictToggle("FEATURES", "MILESTONES_APP", default=False, module_name=__name__) ENABLE_MILESTONES_APP = SettingToggle("MILESTONES_APP", default=False, module_name=__name__)
def get_namespace_choices(): def get_namespace_choices():

View File

@@ -5,8 +5,8 @@ from unittest.mock import patch
import ddt import ddt
import pytest import pytest
from django.conf import settings
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.test import override_settings
from milestones import api as milestones_api from milestones import api as milestones_api
from milestones.exceptions import InvalidCourseKeyException, InvalidUserException from milestones.exceptions import InvalidCourseKeyException, InvalidUserException
from milestones.models import MilestoneRelationshipType from milestones.models import MilestoneRelationshipType
@@ -16,7 +16,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-a
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
@patch.dict(settings.FEATURES, {'MILESTONES_APP': False}) @override_settings(MILESTONES_APP=False)
@ddt.ddt @ddt.ddt
class MilestonesHelpersTestCase(ModuleStoreTestCase): class MilestonesHelpersTestCase(ModuleStoreTestCase):
""" """
@@ -61,8 +61,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
with patch.dict("django.conf.settings.FEATURES", { with patch.dict("django.conf.settings.FEATURES", {
'ENABLE_PREREQUISITE_COURSES': feature_flags[0], 'ENABLE_PREREQUISITE_COURSES': feature_flags[0],
'MILESTONES_APP': feature_flags[1] }), override_settings(MILESTONES_APP=feature_flags[1]):
}):
assert feature_flags[2] == milestones_helpers.is_prerequisite_courses_enabled() assert feature_flags[2] == milestones_helpers.is_prerequisite_courses_enabled()
def test_add_milestone_returns_none_when_app_disabled(self): def test_add_milestone_returns_none_when_app_disabled(self):
@@ -123,7 +122,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
response = milestones_helpers.get_service() response = milestones_helpers.get_service()
assert response is None assert response is None
@patch.dict(settings.FEATURES, {'MILESTONES_APP': True}) @override_settings(MILESTONES_APP=True)
def test_any_unfulfilled_milestones(self): def test_any_unfulfilled_milestones(self):
""" """
Tests any_unfulfilled_milestones for invalid arguments with the app enabled. Tests any_unfulfilled_milestones for invalid arguments with the app enabled.
@@ -137,7 +136,7 @@ class MilestonesHelpersTestCase(ModuleStoreTestCase):
with pytest.raises(InvalidUserException): with pytest.raises(InvalidUserException):
milestones_helpers.any_unfulfilled_milestones(self.course.id, None) milestones_helpers.any_unfulfilled_milestones(self.course.id, None)
@patch.dict(settings.FEATURES, {'MILESTONES_APP': True}) @override_settings(MILESTONES_APP=True)
def test_get_required_content_with_anonymous_user(self): def test_get_required_content_with_anonymous_user(self):
course = CourseFactory() course = CourseFactory()

View File

@@ -681,7 +681,8 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes
assert access._has_access_course(staff, 'see_in_catalog', course) assert access._has_access_course(staff, 'see_in_catalog', course)
assert access._has_access_course(staff, 'see_about_page', course) assert access._has_access_course(staff, 'see_about_page', course)
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True}) @patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True})
@override_settings(MILESTONES_APP=True)
def test_access_on_course_with_pre_requisites(self): def test_access_on_course_with_pre_requisites(self):
""" """
Test course access when a course has pre-requisite course yet to be completed Test course access when a course has pre-requisite course yet to be completed

View File

@@ -5,6 +5,7 @@ Tests use cases related to LMS Entrance Exam behavior, such as gated content acc
from unittest.mock import patch from unittest.mock import patch
from crum import set_current_request from crum import set_current_request
from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from milestones.tests.utils import MilestonesTestCaseMixin from milestones.tests.utils import MilestonesTestCaseMixin
from lms.djangoapps.courseware.entrance_exams import ( from lms.djangoapps.courseware.entrance_exams import (
@@ -36,7 +37,7 @@ from common.djangoapps.util.milestones_helpers import (
) )
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTestCaseMixin): class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTestCaseMixin):
""" """
Check that content is properly gated. Check that content is properly gated.
@@ -44,7 +45,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
Creates a test course from scratch. The tests below are designed to execute Creates a test course from scratch. The tests below are designed to execute
workflows regardless of the feature flag settings. workflows regardless of the feature flag settings.
""" """
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
def setUp(self): def setUp(self):
""" """
Test case scaffolding Test case scaffolding

View File

@@ -8,6 +8,7 @@ import pytest
from crum import set_current_request from crum import set_current_request
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.http import Http404 from django.http import Http404
from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag from edx_toggles.toggles.testutils import override_waffle_flag
from milestones.tests.utils import MilestonesTestCaseMixin from milestones.tests.utils import MilestonesTestCaseMixin
@@ -333,12 +334,12 @@ class StaticTabDateTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
self.assertContains(resp, self.xml_data) self.assertContains(resp, self.xml_data)
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTestCaseMixin): class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTestCaseMixin):
""" """
Validate tab behavior when dealing with Entrance Exams Validate tab behavior when dealing with Entrance Exams
""" """
@patch.dict('django.conf.settings.FEATURES', {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
def setUp(self): def setUp(self):
""" """
Test case scaffolding Test case scaffolding

View File

@@ -3368,7 +3368,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
assert response.status_code == 200 assert response.status_code == 200
assert act.called assert act.called
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
def test_course_has_entrance_exam_in_student_attempts_reset(self): def test_course_has_entrance_exam_in_student_attempts_reset(self):
""" Test course has entrance exam id set while resetting attempts""" """ Test course has entrance exam id set while resetting attempts"""
url = reverse('reset_student_attempts_for_entrance_exam', url = reverse('reset_student_attempts_for_entrance_exam',
@@ -3379,7 +3379,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
}) })
assert response.status_code == 400 assert response.status_code == 400
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
def test_rescore_entrance_exam_with_invalid_exam(self): def test_rescore_entrance_exam_with_invalid_exam(self):
""" Test course has entrance exam id set while re-scoring. """ """ Test course has entrance exam id set while re-scoring. """
url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)}) url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
@@ -3389,7 +3389,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
assert response.status_code == 400 assert response.status_code == 400
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True}) @override_settings(ENTRANCE_EXAMS=True)
@ddt.ddt @ddt.ddt
class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTestCase): class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
""" """

View File

@@ -5,6 +5,7 @@ Test the use cases of the views of the mfe api.
from unittest.mock import call, patch from unittest.mock import call, patch
import ddt import ddt
from django.core.cache import cache
from django.conf import settings from django.conf import settings
from django.test import override_settings from django.test import override_settings
from django.urls import reverse from django.urls import reverse
@@ -30,6 +31,7 @@ class MFEConfigTestCase(APITestCase):
def setUp(self): def setUp(self):
self.mfe_config_api_url = reverse("mfe_config_api:config") self.mfe_config_api_url = reverse("mfe_config_api:config")
cache.clear()
return super().setUp() return super().setUp()
@patch("lms.djangoapps.mfe_config_api.views.configuration_helpers") @patch("lms.djangoapps.mfe_config_api.views.configuration_helpers")

View File

@@ -7,6 +7,7 @@ from unittest.mock import patch
from crum import set_current_request from crum import set_current_request
from django.conf import settings from django.conf import settings
from django.test import override_settings
from common.djangoapps.util.milestones_helpers import add_prerequisite_course, fulfill_course_milestone from common.djangoapps.util.milestones_helpers import add_prerequisite_course, fulfill_course_milestone
from lms.djangoapps.courseware.access_response import MilestoneAccessError from lms.djangoapps.courseware.access_response import MilestoneAccessError
@@ -56,7 +57,8 @@ class MobileAPIMilestonesMixin:
self.init_course_access() self.init_course_access()
self.api_response() self.api_response()
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True, 'ENABLE_MKTG_SITE': True}) @override_settings(ENTRANCE_EXAMS=True)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_unpassed_entrance_exam(self): def test_unpassed_entrance_exam(self):
""" """
Tests the case where the user has not passed the entrance exam Tests the case where the user has not passed the entrance exam
@@ -65,7 +67,8 @@ class MobileAPIMilestonesMixin:
self.init_course_access() self.init_course_access()
self._verify_unfulfilled_milestone_response() self._verify_unfulfilled_milestone_response()
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True, 'ENABLE_MKTG_SITE': True}) @override_settings(ENTRANCE_EXAMS=True)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_unpassed_entrance_exam_for_staff(self): def test_unpassed_entrance_exam_for_staff(self):
self._add_entrance_exam() self._add_entrance_exam()
self.user.is_staff = True self.user.is_staff = True
@@ -73,7 +76,8 @@ class MobileAPIMilestonesMixin:
self.init_course_access() self.init_course_access()
self.api_response() self.api_response()
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True, 'ENABLE_MKTG_SITE': True}) @override_settings(ENTRANCE_EXAMS=True)
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_passed_entrance_exam(self): def test_passed_entrance_exam(self):
""" """
Tests access when user has passed the entrance exam Tests access when user has passed the entrance exam

View File

@@ -16,6 +16,7 @@ from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from django.utils import translation from django.utils import translation
from elasticsearch.exceptions import ConnectionError # lint-amnesty, pylint: disable=redefined-builtin from elasticsearch.exceptions import ConnectionError # lint-amnesty, pylint: disable=redefined-builtin
@@ -1673,7 +1674,7 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
assert team['name'] == 'foo' assert team['name'] == 'foo'
@patch.dict(settings.FEATURES, {'ENABLE_ORA_TEAM_SUBMISSIONS': True}) @override_settings(ENABLE_ORA_TEAM_SUBMISSIONS=True)
@ddt.ddt @ddt.ddt
class TestTeamAssignmentsView(TeamAPITestCase): class TestTeamAssignmentsView(TeamAPITestCase):
""" Tests for the TeamAssignmentsView """ """ Tests for the TeamAssignmentsView """
@@ -1756,7 +1757,7 @@ class TestTeamAssignmentsView(TeamAPITestCase):
expected_status = 404 expected_status = 404
self.get_team_assignments(team_id, expected_status, user=user) self.get_team_assignments(team_id, expected_status, user=user)
@patch.dict(settings.FEATURES, {'ENABLE_ORA_TEAM_SUBMISSIONS': False}) @override_settings(ENABLE_ORA_TEAM_SUBMISSIONS=False)
def test_get_assignments_feature_not_enabled(self): def test_get_assignments_feature_not_enabled(self):
# Given the team submissions feature is not enabled # Given the team submissions feature is not enabled
user = 'student_enrolled' user = 'student_enrolled'

View File

@@ -1,7 +1,7 @@
""" """
Togglable settings for Teams behavior Togglable settings for Teams behavior
""" """
from edx_toggles.toggles import SettingDictToggle from edx_toggles.toggles import SettingToggle
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
@@ -9,8 +9,8 @@ from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
WAFFLE_NAMESPACE = "openresponseassessment" WAFFLE_NAMESPACE = "openresponseassessment"
TEAM_SUBMISSIONS_FLAG = "team_submissions" TEAM_SUBMISSIONS_FLAG = "team_submissions"
# .. toggle_name: FEATURES['ENABLE_ORA_TEAM_SUBMISSIONS'] # .. toggle_name: ENABLE_ORA_TEAM_SUBMISSIONS
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: Set to True to enable team-based ORA submissions. # .. toggle_description: Set to True to enable team-based ORA submissions.
# .. toggle_use_cases: temporary # .. toggle_use_cases: temporary
@@ -20,8 +20,8 @@ TEAM_SUBMISSIONS_FLAG = "team_submissions"
# .. toggle_warning: This temporary feature toggle does not have a target removal date. This can be overridden by a # .. toggle_warning: 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. # course waffle flags or a waffle switch with identical name.
# TODO: this should be moved to edx/edx-ora2 # TODO: this should be moved to edx/edx-ora2
TEAM_SUBMISSIONS_FEATURE = SettingDictToggle( TEAM_SUBMISSIONS_FEATURE = SettingToggle(
"FEATURES", "ENABLE_ORA_TEAM_SUBMISSIONS", default=False, module_name=__name__ "ENABLE_ORA_TEAM_SUBMISSIONS", default=False, module_name=__name__
) )

View File

@@ -2,12 +2,12 @@
Helpers for the credentials service. Helpers for the credentials service.
""" """
from edx_toggles.toggles import SettingDictToggle from edx_toggles.toggles import SettingToggle
from openedx.core.djangoapps.site_configuration import helpers as config_helpers from openedx.core.djangoapps.site_configuration import helpers as config_helpers
# .. toggle_name: FEATURES['ENABLE_LEARNER_RECORDS'] # .. toggle_name: ENABLE_LEARNER_RECORDS
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: True # .. toggle_default: True
# .. toggle_description: Enable learner records for the whole platform. This setting may be overridden by site- and # .. 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. # org-specific site configurations with the same name.
@@ -15,8 +15,8 @@ from openedx.core.djangoapps.site_configuration import helpers as config_helpers
# setting. # setting.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2020-10-01 # .. toggle_creation_date: 2020-10-01
ENABLE_LEARNER_RECORDS = SettingDictToggle( ENABLE_LEARNER_RECORDS = SettingToggle(
"FEATURES", "ENABLE_LEARNER_RECORDS", default=True, module_name=__name__ "ENABLE_LEARNER_RECORDS", default=True, module_name=__name__
) )

View File

@@ -549,7 +549,7 @@ class TestSendGradeIfInteresting(TestCase):
_mock_is_learner_issuance_enabled _mock_is_learner_issuance_enabled
): ):
assert is_learner_records_enabled() assert is_learner_records_enabled()
with override_settings(FEATURES={"ENABLE_LEARNER_RECORDS": False}): with override_settings(ENABLE_LEARNER_RECORDS=False):
assert not is_learner_records_enabled() assert not is_learner_records_enabled()
tasks.send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None) tasks.send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None)
assert not mock_send_grade_to_credentials.delay.called assert not mock_send_grade_to_credentials.delay.called

View File

@@ -9,7 +9,6 @@ import pytest
import ddt import ddt
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
from django.conf import settings
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from xmodule.data import CertificatesDisplayBehaviors from xmodule.data import CertificatesDisplayBehaviors
from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase
@@ -33,10 +32,7 @@ class CourseDetailsTestCase(ModuleStoreTestCase):
@ddt.data(True, False) @ddt.data(True, False)
def test_virgin_fetch(self, should_have_default_enroll_start): def test_virgin_fetch(self, should_have_default_enroll_start):
features = settings.FEATURES.copy() with override_settings(CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE=should_have_default_enroll_start):
features['CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE'] = should_have_default_enroll_start
with override_settings(FEATURES=features):
course = CourseFactory.create(default_enrollment_start=should_have_default_enroll_start) course = CourseFactory.create(default_enrollment_start=should_have_default_enroll_start)
details = CourseDetails.fetch(course.id) details = CourseDetails.fetch(course.id)
wrong_enrollment_start_msg = ( wrong_enrollment_start_msg = (

View File

@@ -25,13 +25,13 @@ class ToggleStateViewTests(TestCase): # lint-amnesty, pylint: disable=missing-c
response = get_toggle_state_response(is_staff=False) response = get_toggle_state_response(is_staff=False)
assert response.status_code == 403 assert response.status_code == 403
def test_response_with_existing_setting_dict_toggle(self): def test_response_with_existing_setting_toggle(self):
response = get_toggle_state_response() response = get_toggle_state_response()
assert { assert {
"name": "FEATURES['MILESTONES_APP']", "name": "MILESTONES_APP",
"is_active": True, "is_active": True,
"module": "common.djangoapps.util.milestones_helpers", "module": "common.djangoapps.util.milestones_helpers",
"class": "SettingDictToggle", "class": "SettingToggle",
} in response.data["django_settings"] } in response.data["django_settings"]
def test_response_with_course_override(self): def test_response_with_course_override(self):

View File

@@ -2,16 +2,16 @@
Feature toggles used across the platform. Toggles should only be added to this module if we don't have a better place 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. for them. Generally speaking, they should be added to the most appropriate app or repo.
""" """
from edx_toggles.toggles import SettingDictToggle from edx_toggles.toggles import SettingToggle
# .. toggle_name: FEATURES['ENTRANCE_EXAMS'] # .. toggle_name: ENTRANCE_EXAMS
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: Enable entrance exams feature. When enabled, students see an exam xblock as the first unit # .. toggle_description: Enable entrance exams feature. When enabled, students see an exam xblock as the first unit
# of the course. # of the course.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2015-12-01 # .. toggle_creation_date: 2015-12-01
# .. toggle_tickets: https://openedx.atlassian.net/browse/SOL-40 # .. toggle_tickets: https://openedx.atlassian.net/browse/SOL-40
ENTRANCE_EXAMS = SettingDictToggle( ENTRANCE_EXAMS = SettingToggle(
"FEATURES", "ENTRANCE_EXAMS", default=False, module_name=__name__ "ENTRANCE_EXAMS", default=False, module_name=__name__
) )

View File

@@ -12,7 +12,7 @@ import dateutil.parser
import requests import requests
from django.conf import settings from django.conf import settings
from django.core.validators import validate_email from django.core.validators import validate_email
from edx_toggles.toggles import SettingDictToggle from edx_toggles.toggles import SettingToggle
from lazy import lazy from lazy import lazy
from lxml import etree from lxml import etree
from path import Path as path from path import Path as path
@@ -59,8 +59,8 @@ COURSE_VISIBILITY_PRIVATE = 'private'
COURSE_VISIBILITY_PUBLIC_OUTLINE = 'public_outline' COURSE_VISIBILITY_PUBLIC_OUTLINE = 'public_outline'
COURSE_VISIBILITY_PUBLIC = 'public' COURSE_VISIBILITY_PUBLIC = 'public'
# .. toggle_name: FEATURES['CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE'] # .. toggle_name: CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: The default behavior, when this is disabled, is that a newly created course has no # .. toggle_description: The default behavior, when this is disabled, is that a newly created course has no
# enrollment_start date set. When the feature is enabled - the newly created courses will have the # enrollment_start date set. When the feature is enabled - the newly created courses will have the
@@ -71,8 +71,8 @@ COURSE_VISIBILITY_PUBLIC = 'public'
# the newly created (empty) course from appearing in the course listing. # the newly created (empty) course from appearing in the course listing.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2023-06-22 # .. toggle_creation_date: 2023-06-22
CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE = SettingDictToggle( CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE = SettingToggle(
"FEATURES", "CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE", default=False, module_name=__name__ "CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE", default=False, module_name=__name__
) )

View File

@@ -23,7 +23,7 @@ from xblock.exceptions import NoSuchServiceError
from xblock.fields import Boolean, Date, Integer, List, Scope, String from xblock.fields import Boolean, Date, Integer, List, Scope, String
from xblock.progress import Progress from xblock.progress import Progress
from edx_toggles.toggles import WaffleFlag, SettingDictToggle from edx_toggles.toggles import WaffleFlag, SettingToggle
from xmodule.util.builtin_assets import add_webpack_js_to_fragment, add_css_to_fragment from xmodule.util.builtin_assets import add_webpack_js_to_fragment, add_css_to_fragment
from xmodule.x_module import ( from xmodule.x_module import (
ResourceTemplates, ResourceTemplates,
@@ -54,14 +54,14 @@ TIMED_EXAM_GATING_WAFFLE_FLAG = WaffleFlag( # lint-amnesty, pylint: disable=tog
'xmodule.rev_1377_rollout', __name__ 'xmodule.rev_1377_rollout', __name__
) )
# .. toggle_name: FEATURES['SHOW_PROGRESS_BAR'] # .. toggle_name: SHOW_PROGRESS_BAR
# .. toggle_implementation: SettingDictToggle # .. toggle_implementation: SettingToggle
# .. toggle_default: False # .. toggle_default: False
# .. toggle_description: Set to True to show progress bar. # .. toggle_description: Set to True to show progress bar.
# .. toggle_use_cases: open_edx # .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2022-02-09 # .. toggle_creation_date: 2022-02-09
# .. toggle_target_removal_date: None # .. toggle_target_removal_date: None
SHOW_PROGRESS_BAR = SettingDictToggle("FEATURES", "SHOW_PROGRESS_BAR", default=False, module_name=__name__) SHOW_PROGRESS_BAR = SettingToggle("SHOW_PROGRESS_BAR", default=False, module_name=__name__)
class SequenceFields: # lint-amnesty, pylint: disable=missing-class-docstring class SequenceFields: # lint-amnesty, pylint: disable=missing-class-docstring

View File

@@ -42,9 +42,7 @@ class CourseFieldsTestCase(unittest.TestCase): # lint-amnesty, pylint: disable=
@ddt.data(True, False) @ddt.data(True, False)
def test_default_enrollment_start_date(self, should_have_default_enroll_start): def test_default_enrollment_start_date(self, should_have_default_enroll_start):
features = settings.FEATURES.copy() with override_settings(CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE=should_have_default_enroll_start):
features['CREATE_COURSE_WITH_DEFAULT_ENROLLMENT_START_DATE'] = should_have_default_enroll_start
with override_settings(FEATURES=features):
# reimport, so settings override could take effect # reimport, so settings override could take effect
del sys.modules['xmodule.course_block'] del sys.modules['xmodule.course_block']
import xmodule.course_block # lint-amnesty, pylint: disable=redefined-outer-name, reimported import xmodule.course_block # lint-amnesty, pylint: disable=redefined-outer-name, reimported