diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_details.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_details.py index 6d3fe7e69239..fe9549a29c16 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_details.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_details.py @@ -2,9 +2,10 @@ Unit tests for course details views. """ import json -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock import ddt +from django.test.utils import override_settings from django.urls import reverse from openedx_authz.constants.roles import COURSE_EDITOR, COURSE_STAFF from rest_framework import status @@ -57,7 +58,7 @@ def test_put_permissions_unauthorized(self): self.assertEqual(error, "You do not have permission to perform this action.") # noqa: PT009 self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # noqa: PT009 - @patch.dict("django.conf.settings.FEATURES", {"ENABLE_PREREQUISITE_COURSES": True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_put_invalid_pre_requisite_course(self): pre_requisite_course_keys = [str(self.course.id), "invalid_key"] request_data = {"pre_requisite_courses": pre_requisite_course_keys} @@ -619,7 +620,7 @@ def test_put_user_without_role_then_added_can_update(self): ) self.assertEqual(response.status_code, status.HTTP_200_OK) # noqa: PT009 - @patch.dict("django.conf.settings.FEATURES", {"ENABLE_PREREQUISITE_COURSES": True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_put_invalid_pre_requisite_course_with_authz(self): """ Ensure validation still applies under AuthZ. diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_settings.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_settings.py index 83ee03294790..380edafd1c73 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_settings.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_settings.py @@ -5,6 +5,7 @@ import ddt from django.conf import settings +from django.test import override_settings from django.urls import reverse from openedx_authz.constants.roles import COURSE_EDITOR from rest_framework import status @@ -73,13 +74,7 @@ def test_credit_eligibility_setting(self): self.assertIn("credit_requirements", response.data) # noqa: PT009 self.assertTrue(response.data["is_credit_course"]) # noqa: PT009 - @patch.dict( - "django.conf.settings.FEATURES", - { - "ENABLE_PREREQUISITE_COURSES": True, - "MILESTONES_APP": True, - }, - ) + @override_settings(ENABLE_PREREQUISITE_COURSES=True, MILESTONES_APP=True) def test_prerequisite_courses_enabled_setting(self): """ Make sure if the feature flags are enabled we have updated the dict keys in response. diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index d5b596504c12..ca8f82842791 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -288,7 +288,7 @@ def compare_date_fields(self, details, encoded, context, field): elif field in encoded and encoded[field] is not None: self.fail(field + " included in encoding but missing from details at " + context) - @mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_pre_requisite_course_update_and_fetch(self): self.assertFalse(milestones_helpers.any_unfulfilled_milestones(self.course.id, self.user.id), # noqa: PT009 msg='The initial empty state should be: no prerequisite courses') @@ -324,7 +324,7 @@ def test_pre_requisite_course_update_and_fetch(self): self.assertFalse(milestones_helpers.any_unfulfilled_milestones(self.course.id, self.user.id), # noqa: PT009 msg='Should not have prerequisite courses anymore') - @mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_invalid_pre_requisite_course(self): url = get_url(self.course.id) resp = self.client.get_json(url) @@ -436,7 +436,7 @@ def test_entrance_exam_store_default_min_score(self): self.assertEqual(course.entrance_exam_minimum_score_pct, .5) # noqa: PT009 @unittest.skipUnless(settings.ENTRANCE_EXAMS, True) - @mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_entrance_after_changing_other_setting(self): """ Test entrance exam is not deactivated when prerequisites removed. diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index dc402c2eb605..7d467e57033e 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -884,10 +884,7 @@ def setUp(self): super().setUp() self.course = CourseFactory.create() - @patch.dict("django.conf.settings.FEATURES", { - "ENABLE_PREREQUISITE_COURSES": False, - }) - @override_settings(ENTRANCE_EXAMS=False) + @override_settings(ENABLE_PREREQUISITE_COURSES=False, ENTRANCE_EXAMS=False) @patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json") def test_update_course_details_self_paced(self, mock_update): """ @@ -910,10 +907,7 @@ def test_update_course_details_self_paced(self, mock_update): utils.update_course_details(mock_request, self.course.id, payload, None) mock_update.assert_called_once_with(self.course.id, expected_payload, mock_request.user) - @patch.dict("django.conf.settings.FEATURES", { - "ENABLE_PREREQUISITE_COURSES": False, - }) - @override_settings(ENTRANCE_EXAMS=False) + @override_settings(ENABLE_PREREQUISITE_COURSES=False, ENTRANCE_EXAMS=False) @patch("cms.djangoapps.contentstore.utils.CourseDetails.update_from_json") def test_update_course_details_instructor_paced(self, mock_update): """ diff --git a/cms/lib/xblock/test/test_authoring_mixin.py b/cms/lib/xblock/test/test_authoring_mixin.py index 47971ae6ef1e..a0653e64a0bc 100644 --- a/cms/lib/xblock/test/test_authoring_mixin.py +++ b/cms/lib/xblock/test/test_authoring_mixin.py @@ -3,7 +3,6 @@ """ -from django.conf import settings from django.test.utils import override_settings from xblock.core import XBlock @@ -32,9 +31,6 @@ class AuthoringMixinTestCase(ModuleStoreTestCase): ENROLLMENT_GROUPS_TITLE = "Enrollment Track Groups" STAFF_LOCKED = 'The unit that contains this component is hidden from learners' - FEATURES_WITH_ENROLLMENT_TRACK_DISABLED = settings.FEATURES.copy() - FEATURES_WITH_ENROLLMENT_TRACK_DISABLED['ENABLE_ENROLLMENT_TRACK_USER_PARTITION'] = False - @XBlock.register_temp_plugin(PureXBlock, 'pure') def setUp(self): """ @@ -170,7 +166,7 @@ def test_html_false_content_group(self): [self.STAFF_LOCKED] ) - @override_settings(FEATURES=FEATURES_WITH_ENROLLMENT_TRACK_DISABLED) + @override_settings(ENABLE_ENROLLMENT_TRACK_USER_PARTITION=False) def test_enrollment_tracks_disabled(self): """ Test that the "no groups" messages doesn't reference enrollment tracks if diff --git a/common/djangoapps/student/tests/test_course_listing.py b/common/djangoapps/student/tests/test_course_listing.py index df25f44cfa8e..4cbe4417d8a8 100644 --- a/common/djangoapps/student/tests/test_course_listing.py +++ b/common/djangoapps/student/tests/test_course_listing.py @@ -7,6 +7,7 @@ from django.conf import settings from django.test.client import Client +from django.test.utils import override_settings from milestones.tests.utils import MilestonesTestCaseMixin from common.djangoapps.student.models import CourseEnrollment # pylint: disable=unused-import @@ -139,7 +140,7 @@ def test_course_listing_errored_deleted_courses(self): assert len(courses_list) == 1, courses_list assert courses_list[0].course_id == good_location - @mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_course_listing_has_pre_requisite_courses(self): """ Creates four courses. Enroll test user in all courses diff --git a/common/djangoapps/student/tests/test_views.py b/common/djangoapps/student/tests/test_views.py index ac724d6f847b..2c51538c7529 100644 --- a/common/djangoapps/student/tests/test_views.py +++ b/common/djangoapps/student/tests/test_views.py @@ -319,7 +319,7 @@ def test_sharing_icons_for_future_course(self, set_marketing, set_social_sharing assert ('Share on Twitter' in response.content.decode('utf-8')) == (set_marketing or set_social_sharing) assert ('Share on Facebook' in response.content.decode('utf-8')) == (set_marketing or set_social_sharing) - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_pre_requisites_appear_on_dashboard(self): """ When a course has a prerequisite, the dashboard should display the prerequisite. diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py index 20819b6b8859..6179a95fbb63 100644 --- a/common/djangoapps/student/tests/tests.py +++ b/common/djangoapps/student/tests/tests.py @@ -365,7 +365,7 @@ def _check_verification_status_on(self, mode, value): self.assertContains(response, f'class="course {mode}"') self.assertContains(response, value) - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': True}) + @override_settings(ENABLE_VERIFIED_CERTIFICATES=True) def test_verification_status_visible(self): """ Test that the certificate verification status for courses is visible on the dashboard. @@ -402,7 +402,7 @@ def _check_verification_status_off(self, mode, value): self.assertNotContains(response, f"class=\"course {mode}\"") self.assertNotContains(response, value) - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': False}) + @override_settings(ENABLE_VERIFIED_CERTIFICATES=False) def test_verification_status_invisible(self): """ Test that the certificate verification status for courses is not visible on the dashboard @@ -621,7 +621,7 @@ def setUp(self): cache.clear() @skip_unless_lms - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': False}) + @override_settings(ENABLE_VERIFIED_CERTIFICATES=False) @ddt.data( ('testserver1.com', {'ENABLE_VERIFIED_CERTIFICATES': True}), ('testserver2.com', {'ENABLE_VERIFIED_CERTIFICATES': True, 'DISPLAY_COURSE_MODES_ON_DASHBOARD': True}), @@ -642,7 +642,7 @@ def test_course_mode_visible(self, site_domain, site_configuration_values): self.assertContains(response, 'class="course professional"') @skip_unless_lms - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': False}) + @override_settings(ENABLE_VERIFIED_CERTIFICATES=False) @ddt.data( ('testserver3.com', {'ENABLE_VERIFIED_CERTIFICATES': False}), ('testserver4.com', {'DISPLAY_COURSE_MODES_ON_DASHBOARD': False}), diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py index d3e1311fe720..6d350dddf88b 100644 --- a/common/djangoapps/student/views/dashboard.py +++ b/common/djangoapps/student/views/dashboard.py @@ -534,11 +534,11 @@ def student_dashboard(request): # pylint: disable=too-many-statements enable_verified_certificates = configuration_helpers.get_value( 'ENABLE_VERIFIED_CERTIFICATES', - settings.FEATURES.get('ENABLE_VERIFIED_CERTIFICATES') + getattr(settings, 'ENABLE_VERIFIED_CERTIFICATES', False) ) display_course_modes_on_dashboard = configuration_helpers.get_value( 'DISPLAY_COURSE_MODES_ON_DASHBOARD', - settings.FEATURES.get('DISPLAY_COURSE_MODES_ON_DASHBOARD', True) + settings.DISPLAY_COURSE_MODES_ON_DASHBOARD ) activation_email_support_link = configuration_helpers.get_value( 'ACTIVATION_EMAIL_SUPPORT_LINK', settings.ACTIVATION_EMAIL_SUPPORT_LINK diff --git a/common/djangoapps/third_party_auth/management/commands/remove_social_auth_users.py b/common/djangoapps/third_party_auth/management/commands/remove_social_auth_users.py index 251e6836e659..d4cc0cd48e25 100644 --- a/common/djangoapps/third_party_auth/management/commands/remove_social_auth_users.py +++ b/common/djangoapps/third_party_auth/management/commands/remove_social_auth_users.py @@ -38,7 +38,7 @@ def add_arguments(self, parser): def handle(self, *args, **options): slug = options['IDP'] - if not settings.FEATURES.get('ENABLE_ENROLLMENT_RESET'): + if not settings.ENABLE_ENROLLMENT_RESET: raise CommandError('ENABLE_ENROLLMENT_RESET feature not enabled on this enviroment') try: diff --git a/common/djangoapps/third_party_auth/management/commands/tests/test_remove_social_auth_users.py b/common/djangoapps/third_party_auth/management/commands/tests/test_remove_social_auth_users.py index f019db807480..780debce5d19 100644 --- a/common/djangoapps/third_party_auth/management/commands/tests/test_remove_social_auth_users.py +++ b/common/djangoapps/third_party_auth/management/commands/tests/test_remove_social_auth_users.py @@ -7,7 +7,6 @@ from uuid import uuid4 import pytest -from django.conf import settings from django.core.management import call_command from django.core.management.base import CommandError from django.test import TestCase, override_settings @@ -20,9 +19,6 @@ from common.djangoapps.third_party_auth.tests.factories import SAMLProviderConfigFactory from openedx.core.djangolib.testing.utils import skip_unless_lms -FEATURES_WITH_ENABLED = settings.FEATURES.copy() -FEATURES_WITH_ENABLED['ENABLE_ENROLLMENT_RESET'] = True - @skip_unless_lms class TestRemoveSocialAuthUsersCommand(TestCase): @@ -64,7 +60,7 @@ def create_social_auth_entry(self, user, provider): def find_user_social_auth_entry(self, username): UserSocialAuth.objects.get(user__username=username) - @override_settings(FEATURES=FEATURES_WITH_ENABLED) + @override_settings(ENABLE_ENROLLMENT_RESET=True) def test_remove_users(self): call_command(self.command, self.provider_hogwarts.slug, force=True) @@ -83,14 +79,14 @@ def test_remove_users(self): # other social auth intact self.find_user_social_auth_entry(self.user_viktor.username) - @override_settings(FEATURES=FEATURES_WITH_ENABLED) + @override_settings(ENABLE_ENROLLMENT_RESET=True) def test_invalid_idp(self): invalid_slug = 'jedi-academy' err_string = f'No SAML provider found for slug {invalid_slug}' with self.assertRaisesRegex(CommandError, err_string): # noqa: PT027 call_command(self.command, invalid_slug) - @override_settings(FEATURES=FEATURES_WITH_ENABLED) + @override_settings(ENABLE_ENROLLMENT_RESET=True) def test_confirmation_required(self): """ By default this command will require user input to confirm """ with self._replace_stdin('confirm'): @@ -101,7 +97,7 @@ def test_confirmation_required(self): with pytest.raises(UserSocialAuth.DoesNotExist): self.find_user_social_auth_entry('harry') - @override_settings(FEATURES=FEATURES_WITH_ENABLED) + @override_settings(ENABLE_ENROLLMENT_RESET=True) def test_confirmation_failure(self): err_string = 'User confirmation required. No records have been modified' with self.assertRaisesRegex(CommandError, err_string): # noqa: PT027 diff --git a/common/djangoapps/util/milestones_helpers.py b/common/djangoapps/util/milestones_helpers.py index 81954ede7f16..846f1b9e009b 100644 --- a/common/djangoapps/util/milestones_helpers.py +++ b/common/djangoapps/util/milestones_helpers.py @@ -44,7 +44,7 @@ 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() + return settings.ENABLE_PREREQUISITE_COURSES and ENABLE_MILESTONES_APP.is_enabled() def add_prerequisite_course(course_key, prerequisite_course_key): diff --git a/common/djangoapps/util/tests/test_milestones_helpers.py b/common/djangoapps/util/tests/test_milestones_helpers.py index 3808760659e7..7ee3d4a7474d 100644 --- a/common/djangoapps/util/tests/test_milestones_helpers.py +++ b/common/djangoapps/util/tests/test_milestones_helpers.py @@ -1,7 +1,6 @@ """ Tests for the milestones helpers library, which is the integration point for the edx_milestones API """ -from unittest.mock import patch import ddt import pytest @@ -61,9 +60,10 @@ def test_pre_requisite_courses_enabled(self, feature_flags): ENABLE_PREREQUISITE_COURSES and MILESTONES_APP feature flags. """ - with patch.dict("django.conf.settings.FEATURES", { - 'ENABLE_PREREQUISITE_COURSES': feature_flags[0], - }), override_settings(MILESTONES_APP=feature_flags[1]): + with override_settings( + ENABLE_PREREQUISITE_COURSES=feature_flags[0], + MILESTONES_APP=feature_flags[1], + ): assert feature_flags[2] == milestones_helpers.is_prerequisite_courses_enabled() def test_add_milestone_returns_none_when_app_disabled(self): diff --git a/lms/djangoapps/branding/tests/test_page.py b/lms/djangoapps/branding/tests/test_page.py index 509d0509ddeb..c31e7fb6a650 100644 --- a/lms/djangoapps/branding/tests/test_page.py +++ b/lms/djangoapps/branding/tests/test_page.py @@ -133,7 +133,7 @@ class PreRequisiteCourseCatalog(ModuleStoreTestCase, LoginEnrollmentTestCase, Mi """ ENABLED_SIGNALS = ['course_published'] - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_course_with_prereq(self): """ Simulate having a course which has closed enrollments that has diff --git a/lms/djangoapps/certificates/tests/tests.py b/lms/djangoapps/certificates/tests/tests.py index 682f9f09bacb..cf00a1d0b689 100644 --- a/lms/djangoapps/certificates/tests/tests.py +++ b/lms/djangoapps/certificates/tests/tests.py @@ -4,10 +4,9 @@ from datetime import datetime, timedelta -from unittest.mock import patch from ddt import data, ddt, unpack -from django.conf import settings +from django.test.utils import override_settings from milestones.tests.utils import MilestonesTestCaseMixin from pytz import UTC @@ -181,7 +180,7 @@ def test_course_ids_with_certs_for_user(self): {course_1.id, course_2.id} ) - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_course_milestone_collected(self): student = UserFactory() course = CourseFactory.create(org='edx', number='998', display_name='Test Course') diff --git a/lms/djangoapps/courseware/tests/test_about.py b/lms/djangoapps/courseware/tests/test_about.py index b34c29a7cb45..4aa7a945aa60 100644 --- a/lms/djangoapps/courseware/tests/test_about.py +++ b/lms/djangoapps/courseware/tests/test_about.py @@ -122,7 +122,7 @@ def test_logged_in_marketing(self): resp = self.client.get(url) self.assertRedirects(resp, course_home_url(self.course.id), fetch_redirect_response=False) - @patch.dict(settings.FEATURES, {'ENABLE_COURSE_HOME_REDIRECT': False}) + @override_settings(ENABLE_COURSE_HOME_REDIRECT=False) @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True}) def test_logged_in_marketing_without_course_home_redirect(self): """ @@ -135,7 +135,7 @@ def test_logged_in_marketing_without_course_home_redirect(self): # should not be redirected self.assertContains(resp, "OOGIE BLOOGIE") - @patch.dict(settings.FEATURES, {'ENABLE_COURSE_HOME_REDIRECT': True}) + @override_settings(ENABLE_COURSE_HOME_REDIRECT=True) @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': False}) def test_logged_in_marketing_without_mktg_site(self): """ @@ -148,7 +148,7 @@ def test_logged_in_marketing_without_mktg_site(self): # should not be redirected self.assertContains(resp, "OOGIE BLOOGIE") - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_pre_requisite_course(self): pre_requisite_course = CourseFactory.create(org='edX', course='900', display_name='pre requisite course') course = CourseFactory.create(pre_requisite_courses=[str(pre_requisite_course.id)]) @@ -163,7 +163,7 @@ def test_pre_requisite_course(self): f'{pre_requisite_courses[0]["display"]} before you begin this course.' ) in resp.content.decode(resp.charset).strip('\n') - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) def test_about_page_unfulfilled_prereqs(self): pre_requisite_course = CourseFactory.create( org='edX', diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py index bd75d4723933..f18825560571 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -722,8 +722,7 @@ def test__catalog_visibility_returns_typed_error(self): assert isinstance(see_in_catalog_response, access_response.CatalogVisibilityError) assert access._has_access_course(user, 'see_about_page', course_about) - @patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True}) - @override_settings(MILESTONES_APP=True) + @override_settings(ENABLE_PREREQUISITE_COURSES=True, MILESTONES_APP=True) def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed diff --git a/lms/djangoapps/courseware/tests/test_masquerade.py b/lms/djangoapps/courseware/tests/test_masquerade.py index b7c12df30aab..2a3d3be67615 100644 --- a/lms/djangoapps/courseware/tests/test_masquerade.py +++ b/lms/djangoapps/courseware/tests/test_masquerade.py @@ -200,8 +200,7 @@ def test_masquerade_options_for_learner(self, partitions_enabled): """ If there are partitions, then the View as Learner should NOT be available """ - with patch.dict('django.conf.settings.FEATURES', - {'ENABLE_ENROLLMENT_TRACK_USER_PARTITION': partitions_enabled}): + with override_settings(ENABLE_ENROLLMENT_TRACK_USER_PARTITION=partitions_enabled): response = self.get_available_masquerade_identities() is_learner_available = 'Learner' in map(itemgetter('name'), response.json()['available']) assert partitions_enabled != is_learner_available diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 8ae58850920d..208806fdce12 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -1221,7 +1221,7 @@ def _course_home_redirect_enabled(): if configuration_helpers.get_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False) ) and configuration_helpers.get_value( - 'ENABLE_COURSE_HOME_REDIRECT', settings.FEATURES.get('ENABLE_COURSE_HOME_REDIRECT', True) + 'ENABLE_COURSE_HOME_REDIRECT', settings.ENABLE_COURSE_HOME_REDIRECT ): return True diff --git a/lms/djangoapps/mobile_api/tests/test_milestones.py b/lms/djangoapps/mobile_api/tests/test_milestones.py index 622f86f507ca..30624e3e6d0f 100644 --- a/lms/djangoapps/mobile_api/tests/test_milestones.py +++ b/lms/djangoapps/mobile_api/tests/test_milestones.py @@ -31,17 +31,16 @@ class MobileAPIMilestonesMixin: ALLOW_ACCESS_TO_MILESTONE_COURSE = False - @patch.dict(settings.FEATURES, { - 'ENABLE_PREREQUISITE_COURSES': True, - 'ENABLE_MKTG_SITE': True, - }) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) + @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True}) def test_unfulfilled_prerequisite_course(self): """ Tests the case for an unfulfilled pre-requisite course """ self._add_prerequisite_course() self.init_course_access() self._verify_unfulfilled_milestone_response() - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True, 'ENABLE_MKTG_SITE': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) + @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True}) def test_unfulfilled_prerequisite_course_for_staff(self): self._add_prerequisite_course() self.user.is_staff = True @@ -49,7 +48,8 @@ def test_unfulfilled_prerequisite_course_for_staff(self): self.init_course_access() self.api_response() - @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True, 'ENABLE_MKTG_SITE': True}) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) + @patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True}) def test_fulfilled_prerequisite_course(self): """ Tests the case when a user fulfills existing pre-requisite course diff --git a/lms/djangoapps/mobile_api/users/tests.py b/lms/djangoapps/mobile_api/users/tests.py index 1599cf1007e2..df88c7a6236c 100644 --- a/lms/djangoapps/mobile_api/users/tests.py +++ b/lms/djangoapps/mobile_api/users/tests.py @@ -168,8 +168,8 @@ def test_sort_order(self, api_version): str(courses[((num_courses - course_index) - 1)].id) @ddt.data(API_V05, API_V1, API_V2) + @override_settings(ENABLE_PREREQUISITE_COURSES=True) @patch.dict(settings.FEATURES, { - 'ENABLE_PREREQUISITE_COURSES': True, 'DISABLE_START_DATES': False, 'ENABLE_MKTG_SITE': True, }) diff --git a/lms/djangoapps/verify_student/management/commands/tests/test_retry_failed_photo_verifications.py b/lms/djangoapps/verify_student/management/commands/tests/test_retry_failed_photo_verifications.py index b921789c899b..3b0d871b8105 100644 --- a/lms/djangoapps/verify_student/management/commands/tests/test_retry_failed_photo_verifications.py +++ b/lms/djangoapps/verify_student/management/commands/tests/test_retry_failed_photo_verifications.py @@ -97,8 +97,7 @@ def test_args_from_database(self): ) -@override_settings(VERIFY_STUDENT=FAKE_SETTINGS) -@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True}) +@override_settings(VERIFY_STUDENT=FAKE_SETTINGS, AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING=True) class TestRetryFailedPhotoVerificationsBetweenDates(MockS3Boto3Mixin, TestVerificationBase): """ Tests that the command selects specific objects within a date range diff --git a/lms/djangoapps/verify_student/management/commands/tests/test_trigger_softwaresecurephotoverifications_post_save_signal.py b/lms/djangoapps/verify_student/management/commands/tests/test_trigger_softwaresecurephotoverifications_post_save_signal.py index 1960fa9ff2d4..4b5cb511b75b 100644 --- a/lms/djangoapps/verify_student/management/commands/tests/test_trigger_softwaresecurephotoverifications_post_save_signal.py +++ b/lms/djangoapps/verify_student/management/commands/tests/test_trigger_softwaresecurephotoverifications_post_save_signal.py @@ -17,7 +17,6 @@ # Lots of patching to stub in our own settings, and HTTP posting @patch.dict(settings.VERIFY_STUDENT, FAKE_SETTINGS) -@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True}) @patch('lms.djangoapps.verify_student.models.requests.post', new=mock_software_secure_post) class TestTriggerSoftwareSecurePhotoVerificationsPostSaveSignal(MockS3Boto3Mixin, TestVerificationBase): """ diff --git a/lms/djangoapps/verify_student/tests/test_models.py b/lms/djangoapps/verify_student/tests/test_models.py index 959751ad062f..5fa1b9f3fee5 100644 --- a/lms/djangoapps/verify_student/tests/test_models.py +++ b/lms/djangoapps/verify_student/tests/test_models.py @@ -2,7 +2,6 @@ import base64 from datetime import datetime, timedelta -from unittest import mock from unittest.mock import patch import ddt @@ -10,6 +9,7 @@ import requests.exceptions import simplejson as json from django.conf import settings +from django.test.utils import override_settings from django.utils.timezone import now from freezegun import freeze_time @@ -219,7 +219,7 @@ def test_submissions(self): attempt = self.create_upload_and_submit_attempt_for_user() assert attempt.status == PhotoVerification.STATUS.must_retry - @mock.patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True}) + @override_settings(AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING=True) def test_submission_while_testing_flag_is_true(self): """ Test that a fake value is set for field 'photo_id_key' of user's initial verification when the feature flag 'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING' diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index 9b8d6306d22e..330481ee694f 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -1230,7 +1230,7 @@ def test_create_basket(self): @ddt.ddt -@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True}) +@override_settings(AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING=True) class TestSubmitPhotosForVerification(MockS3Boto3Mixin, TestVerificationBase): """ Tests for submitting photos for verification. @@ -1289,7 +1289,7 @@ def test_submit_photos_error_does_not_send_email(self): # Disable auto-auth since we will be intercepting POST requests # to the verification service ourselves in this test. - @patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': False}) + @override_settings(AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING=False) @override_settings(VERIFY_STUDENT={ "SOFTWARE_SECURE": { "API_URL": "https://verify.example.com/submit/", diff --git a/lms/djangoapps/verify_student/utils.py b/lms/djangoapps/verify_student/utils.py index 3dcde96d929f..64d47dbff81a 100644 --- a/lms/djangoapps/verify_student/utils.py +++ b/lms/djangoapps/verify_student/utils.py @@ -136,7 +136,7 @@ def auto_verify_for_testing_enabled(override=None): """ if override is not None: return override - return settings.FEATURES.get('AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING') + return settings.AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING def can_verify_now(verification_status, expiration_datetime): diff --git a/lms/urls.py b/lms/urls.py index f8885ca94fa5..91ab791918f4 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -853,7 +853,7 @@ path('status/', include('openedx.core.djangoapps.service_status.urls')), ] -if settings.FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'): +if settings.ENABLE_INSTRUCTOR_BACKGROUND_TASKS: urlpatterns += [ path( 'instructor_task_status/', diff --git a/openedx/core/djangoapps/safe_sessions/tests/test_middleware.py b/openedx/core/djangoapps/safe_sessions/tests/test_middleware.py index 4a9432af0d28..0f0e3ad1ddd3 100644 --- a/openedx/core/djangoapps/safe_sessions/tests/test_middleware.py +++ b/openedx/core/djangoapps/safe_sessions/tests/test_middleware.py @@ -1029,7 +1029,7 @@ def test_process_response_no_email_in_session(self): # Verify that email is set in the session self.assertEqual(self.request.session.get('email'), self.user.email) # noqa: PT009 - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_user_remain_authenticated_on_email_change_in_other_browser_with_toggle_disabled(self): """ Integration Test: test that a user remains authenticated upon email change @@ -1061,7 +1061,7 @@ def test_user_remain_authenticated_on_email_change_in_other_browser_with_toggle_ response = self.client.get(self.dashboard_url) assert response.status_code == 200 - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=True) def test_cookies_are_updated_with_new_email_on_email_change_with_toggle_enabled(self): """ @@ -1114,7 +1114,7 @@ def test_cookies_are_updated_with_new_email_on_email_change_with_toggle_enabled( email_change_response.cookies[jwt_cookies.jwt_cookie_signature_name()].value ) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=False) def test_cookies_are_updated_with_new_email_on_email_change_with_toggle_disabled(self): """ @@ -1167,7 +1167,7 @@ def test_cookies_are_updated_with_new_email_on_email_change_with_toggle_disabled email_change_response.cookies[jwt_cookies.jwt_cookie_signature_name()].value ) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=True) def test_logged_in_user_unauthenticated_on_email_change_in_other_browser(self): """ @@ -1201,7 +1201,7 @@ def test_logged_in_user_unauthenticated_on_email_change_in_other_browser(self): assert response.status_code == 302 self._assert_logged_in_cookies_not_present(response) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=True) def test_logged_in_user_remains_authenticated_on_email_change_in_same_browser(self): """ @@ -1248,7 +1248,7 @@ def test_logged_in_user_remains_authenticated_on_email_change_in_same_browser(se response = self.client.get(self.dashboard_url) assert response.status_code == 200 - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=True) def test_registered_user_unauthenticated_on_email_change_in_other_browser(self): """ @@ -1286,7 +1286,7 @@ def test_registered_user_unauthenticated_on_email_change_in_other_browser(self): assert response.status_code == 302 self._assert_logged_in_cookies_not_present(response) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @override_settings(ENFORCE_SESSION_EMAIL_MATCH=True) def test_registered_user_remain_authenticated_on_email_change_in_same_browser(self): """ diff --git a/openedx/core/djangoapps/user_authn/cookies.py b/openedx/core/djangoapps/user_authn/cookies.py index d41faf0cb5aa..ec0755372ac5 100644 --- a/openedx/core/djangoapps/user_authn/cookies.py +++ b/openedx/core/djangoapps/user_authn/cookies.py @@ -56,7 +56,7 @@ def are_logged_in_cookies_set(request): """ Check whether the request has logged in cookies set. """ - if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False): + if getattr(settings, 'DISABLE_SET_JWT_COOKIES_FOR_TESTS', False): cookies_that_should_exist = DEPRECATED_LOGGED_IN_COOKIE_NAMES else: cookies_that_should_exist = ALL_LOGGED_IN_COOKIE_NAMES @@ -294,7 +294,7 @@ def _create_and_set_jwt_cookies(response, request, cookie_settings, user=None): # a login oauth client cannot be found in the database in ``_get_login_oauth_client``. # This solution is not ideal, but see https://github.com/openedx/edx-platform/pull/19180#issue-226706355 # for a discussion of alternative solutions that did not work or were halted. - if settings.FEATURES.get('DISABLE_SET_JWT_COOKIES_FOR_TESTS', False): + if getattr(settings, 'DISABLE_SET_JWT_COOKIES_FOR_TESTS', False): return expires_in = settings.JWT_AUTH['JWT_IN_COOKIE_EXPIRATION'] diff --git a/openedx/core/djangoapps/user_authn/tests/test_cookies.py b/openedx/core/djangoapps/user_authn/tests/test_cookies.py index 56ebae7756aa..608c79862677 100644 --- a/openedx/core/djangoapps/user_authn/tests/test_cookies.py +++ b/openedx/core/djangoapps/user_authn/tests/test_cookies.py @@ -125,7 +125,7 @@ def test_set_logged_in_deprecated_cookies(self): self._assert_consistent_expires(response) self._assert_recreate_jwt_from_cookies(response, can_recreate=False) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_set_logged_in_jwt_cookies(self): setup_login_oauth_client() response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user) @@ -133,7 +133,7 @@ def test_set_logged_in_jwt_cookies(self): self._assert_consistent_expires(response, num_of_unique_expires=2) self._assert_recreate_jwt_from_cookies(response, can_recreate=True) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_delete_and_are_logged_in_cookies_set(self): setup_login_oauth_client() response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user) @@ -144,7 +144,7 @@ def test_delete_and_are_logged_in_cookies_set(self): self._copy_cookies_to_request(response, self.request) assert not cookies_api.are_logged_in_cookies_set(self.request) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_refresh_jwt_cookies(self): setup_login_oauth_client() response = cookies_api.get_response_with_refreshed_jwt_cookies(self.request, self.user) diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py index 98db117aca20..09f5cea3327f 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py @@ -610,7 +610,7 @@ def test_excessive_login_attempts_by_ip(self): response, _audit_log = self._login_response(self.user_email, 'wrong_password') self._assert_response(response, success=False, value='Too many failed login attempts') - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_login_refresh(self): def _assert_jwt_cookie_present(response): assert response.status_code == 200 @@ -623,7 +623,7 @@ def _assert_jwt_cookie_present(response): response = self.client.post(reverse('login_refresh')) _assert_jwt_cookie_present(response) - @patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) def test_login_refresh_anonymous_user(self): response = self.client.post(reverse('login_refresh')) assert response.status_code == 401 diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_logistration.py b/openedx/core/djangoapps/user_authn/views/tests/test_logistration.py index 711a71a1298a..3bd716b3780e 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_logistration.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_logistration.py @@ -114,7 +114,7 @@ def test_login_and_registration_form(self, url_name, initial_mode): expected_data = f'"initial_mode": "{initial_mode}"' self.assertContains(response, expected_data) - @mock.patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False}) + @override_settings(DISABLE_SET_JWT_COOKIES_FOR_TESTS=False) @ddt.data("signin_user", "register_user") def test_login_and_registration_form_already_authenticated(self, url_name): setup_login_oauth_client() diff --git a/openedx/envs/common.py b/openedx/envs/common.py index f0b53db8a5a6..c761f4b0ca44 100644 --- a/openedx/envs/common.py +++ b/openedx/envs/common.py @@ -1049,6 +1049,14 @@ def add_optional_apps(optional_apps, installed_apps): # auto-advance. ENABLE_AUTOADVANCE_VIDEOS = False +# .. toggle_name: DISPLAY_COURSE_MODES_ON_DASHBOARD +# .. toggle_implementation: DjangoSetting +# .. toggle_default: True +# .. toggle_description: When True, course modes (verified, honor, etc.) are shown as pills on the learner dashboard. +# .. toggle_use_cases: open_edx +# .. toggle_creation_date: 2017-09-13 +DISPLAY_COURSE_MODES_ON_DASHBOARD = True + # .. toggle_name: CUSTOM_COURSES_EDX # .. toggle_implementation: DjangoSetting # .. toggle_default: False diff --git a/xmodule/discussion_block.py b/xmodule/discussion_block.py index fbbe3298803a..a1fe42c41bef 100644 --- a/xmodule/discussion_block.py +++ b/xmodule/discussion_block.py @@ -218,7 +218,7 @@ def student_view(self, context=None): 'can_create_subcomment': self.has_permission("create_sub_comment"), 'login_msg': login_msg, 'PLATFORM_NAME': settings.PLATFORM_NAME, - 'enable_discussion_home_panel': settings.FEATURES.get("ENABLE_DISCUSSION_HOME_PANEL", False), + 'enable_discussion_home_panel': settings.ENABLE_DISCUSSION_HOME_PANEL, } fragment.add_content( render_to_string('discussion/_discussion_inline.html', context) diff --git a/xmodule/partitions/enrollment_track_partition_generator.py b/xmodule/partitions/enrollment_track_partition_generator.py index 2eece8d1121e..2176a9713ce0 100644 --- a/xmodule/partitions/enrollment_track_partition_generator.py +++ b/xmodule/partitions/enrollment_track_partition_generator.py @@ -16,15 +16,12 @@ log = logging.getLogger(__name__) -FEATURES = getattr(settings, 'FEATURES', {}) - - def create_enrollment_track_partition_with_course_id(course_id): """ Create and return the dynamic enrollment track user partition based only on course_id. If it cannot be created, None is returned. """ - if not FEATURES.get('ENABLE_ENROLLMENT_TRACK_USER_PARTITION'): + if not settings.ENABLE_ENROLLMENT_TRACK_USER_PARTITION: return None try: diff --git a/xmodule/partitions/tests/test_partitions.py b/xmodule/partitions/tests/test_partitions.py index 0a7bc9ec2e81..d035409261f8 100644 --- a/xmodule/partitions/tests/test_partitions.py +++ b/xmodule/partitions/tests/test_partitions.py @@ -8,7 +8,7 @@ from unittest.mock import Mock import pytest -from django.test import TestCase +from django.test import TestCase, override_settings from opaque_keys.edx.locator import CourseLocator from stevedore.extension import Extension, ExtensionManager @@ -20,7 +20,7 @@ UserPartition, UserPartitionError, ) -from xmodule.partitions.partitions_service import FEATURES, PartitionService, get_all_partitions_for_course +from xmodule.partitions.partitions_service import PartitionService, get_all_partitions_for_course class TestGroup(TestCase): @@ -520,22 +520,12 @@ def test_get_group(self): assert group2 == groups[1] +@override_settings(ENABLE_ENROLLMENT_TRACK_USER_PARTITION=True) class TestGetCourseUserPartitions(PartitionServiceBaseClass): """ Test the helper method get_all_partitions_for_course. """ - def setUp(self): - super().setUp() - TestGetCourseUserPartitions._enable_enrollment_track_partition(True) - - @staticmethod - def _enable_enrollment_track_partition(enable): - """ - Enable or disable the feature flag for the enrollment track user partition. - """ - FEATURES['ENABLE_ENROLLMENT_TRACK_USER_PARTITION'] = enable - def test_filter_inactive_user_partitions(self): """ Tests supplying the `active_only` parameter.