Deprecate WaffleSwitch.override* methods

This allows us to get rid of the custom WaffleSwitch and
WaffleSwitchNamespace classes from waffle_utils in favour of
edx_toggles.toggles classes.
This commit is contained in:
Régis Behmo
2020-10-23 13:06:12 +02:00
parent 2307dff4c9
commit 3b127f8c92
26 changed files with 159 additions and 203 deletions

View File

@@ -35,6 +35,7 @@ from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.utils import reverse_course_url, reverse_usage_url
from cms.djangoapps.contentstore.views import item as item_module
from lms_xblock.mixin import NONSENSICAL_ACCESS_RESTRICTION
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.tests.factories import UserFactory
from xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag
from xblock_django.user_service import DjangoXBlockUserService
@@ -2666,7 +2667,7 @@ class TestXBlockInfo(ItemTest):
self.course.highlights_enabled_for_messaging = True
self.store.update_item(self.course, None)
chapter = self.store.get_item(self.chapter.location)
with highlights_setting.override():
with override_waffle_switch(highlights_setting, active=True):
chapter_xblock_info = create_xblock_info(chapter)
course_xblock_info = create_xblock_info(self.course)
self.assertTrue(chapter_xblock_info['highlights_enabled'])

View File

@@ -41,7 +41,9 @@ from openedx.core.djangoapps.video_pipeline.config.waffle import (
waffle_flags
)
from openedx.core.djangoapps.video_pipeline.models import VEMPipelineIntegration
from openedx.core.djangoapps.waffle_utils import WaffleSwitch
from openedx.core.djangoapps.waffle_utils.models import WaffleFlagCourseOverrideModel
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from xmodule.modulestore.tests.factories import CourseFactory
from ..videos import (
@@ -56,23 +58,7 @@ from ..videos import (
convert_video_status
)
def override_switch(switch, active):
"""
Overrides the given waffle switch to `active` boolean.
Arguments:
switch(str): switch name
active(bool): A boolean representing (to be overridden) value
"""
def decorate(function):
@wraps(function)
def inner(*args, **kwargs):
with WAFFLE_SWITCHES.override(switch, active=active):
function(*args, **kwargs)
return inner
return decorate
VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH = WaffleSwitch(WAFFLE_SWITCHES, VIDEO_IMAGE_UPLOAD_ENABLED)
class VideoUploadTestBase(object):
@@ -908,7 +894,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
self.assertIn('error', response)
self.assertEqual(response['error'], error_message)
@override_switch(VIDEO_IMAGE_UPLOAD_ENABLED, False)
@override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH, False)
def test_video_image_upload_disabled(self):
"""
Tests the video image upload when the feature is disabled.
@@ -917,7 +903,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
response = self.client.post(video_image_upload_url, {'file': 'dummy_file'}, format='multipart')
self.assertEqual(response.status_code, 404)
@override_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
@override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH, True)
def test_video_image(self):
"""
Test video image is saved.
@@ -939,7 +925,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
self.assertNotEqual(image_url1, image_url2)
@override_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
@override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH, True)
def test_video_image_no_file(self):
"""
Test that an error error message is returned if upload request is incorrect.
@@ -948,7 +934,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
response = self.client.post(video_image_upload_url, {})
self.verify_error_message(response, 'An image file is required.')
@override_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
@override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH, True)
def test_no_video_image(self):
"""
Test image url is set to None if no video image.
@@ -1130,7 +1116,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
)
)
@ddt.unpack
@override_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
@override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED_SWITCH, True)
def test_video_image_validation_message(self, image_data, error_message):
"""
Test video image validation gives proper error message.

View File

@@ -18,13 +18,14 @@ from django.utils.timezone import now
from mock import Mock
from pytz import UTC
from student.admin import AllowedAuthUserForm, COURSE_ENROLLMENT_ADMIN_SWITCH, UserAdmin, CourseEnrollmentForm
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.admin import COURSE_ENROLLMENT_ADMIN_SWITCH, AllowedAuthUserForm, CourseEnrollmentForm, UserAdmin
from student.models import AllowedAuthUser, CourseEnrollment, LoginFailures
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
@@ -243,7 +244,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
"""
Ensure CourseEnrollmentAdmin views can be enabled with the waffle switch.
"""
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
response = getattr(self.client, method)(url)
self.assertEqual(response.status_code, 200)
@@ -257,7 +258,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
course_id=self.course.id, # pylint: disable=no-member
)
search_url = '{}?q={}'.format(reverse('admin:student_courseenrollment_changelist'), self.user.username)
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
response = self.client.get(search_url)
self.assertEqual(response.status_code, 200)
@@ -283,7 +284,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
'mode': self.course_enrollment.mode,
}
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
response = self.client.post(
reverse('admin:student_courseenrollment_change', args=(self.course_enrollment.id, )),
data=data,
@@ -304,7 +305,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
'mode': self.course_enrollment.mode,
}
with COURSE_ENROLLMENT_ADMIN_SWITCH.override(active=True):
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
with self.assertRaises(ValidationError):
self.client.post(
reverse('admin:student_courseenrollment_change', args=(self.course_enrollment.id, )),

View File

@@ -20,10 +20,14 @@ from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory
from lms.djangoapps.grades.tests.utils import mock_passing_grade
from lms.djangoapps.verify_student.models import IDVerificationAttempt, SoftwareSecurePhotoVerification
from openedx.core.djangoapps.certificates.config import waffle
from openedx.core.djangoapps.waffle_utils import WaffleSwitch
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
AUTO_CERTIFICATE_GENERATION_SWITCH = WaffleSwitch(waffle.waffle(), waffle.AUTO_CERTIFICATE_GENERATION)
class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
"""
@@ -84,13 +88,13 @@ class WhitelistGeneratedCertificatesTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=False):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=False):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.course.id
)
mock_generate_certificate_apply_async.assert_not_called()
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.course.id
@@ -112,13 +116,13 @@ class WhitelistGeneratedCertificatesTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=False):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=False):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.ip_course.id
)
mock_generate_certificate_apply_async.assert_not_called()
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.ip_course.id
@@ -167,7 +171,7 @@ class PassingGradeCertsTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
grade_factory = CourseGradeFactory()
# Not passing
grade_factory.update(self.user, self.course)
@@ -188,7 +192,7 @@ class PassingGradeCertsTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
grade_factory = CourseGradeFactory()
# Not passing
grade_factory.update(self.user, self.ip_course)
@@ -312,7 +316,7 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
mock_generate_certificate_apply_async.assert_not_called()
attempt = SoftwareSecurePhotoVerification.objects.create(
user=self.user_one,
@@ -333,7 +337,7 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
mock_generate_certificate_apply_async.assert_not_called()
attempt = SoftwareSecurePhotoVerification.objects.create(
user=self.user_two,
@@ -386,7 +390,7 @@ class CertificateGenerationTaskTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
fire_ungenerated_certificate_task(self.user, self.course.id)
task_created = mock_generate_certificate_apply_async.called
self.assertEqual(task_created, should_create)

View File

@@ -14,8 +14,10 @@ from django.test.client import Client, RequestFactory
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from urllib.parse import urlencode
from course_modes.models import CourseMode
from edx_toggles.toggles.testutils import override_waffle_switch
from lms.djangoapps.badges.events.course_complete import get_completion_badge
from lms.djangoapps.badges.tests.factories import (
BadgeAssertionFactory,
@@ -44,6 +46,7 @@ from openedx.core.djangoapps.site_configuration.tests.test_util import (
with_site_configuration,
with_site_configuration_context
)
from openedx.core.djangoapps.waffle_utils import WaffleSwitch
from openedx.core.djangolib.js_utils import js_escaped_string
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from openedx.core.lib.tests.assertions.events import assert_event_matches
@@ -55,6 +58,7 @@ from util.date_utils import strftime_localized
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
AUTO_CERTIFICATE_GENERATION_SWITCH = WaffleSwitch(waffle.waffle(), waffle.AUTO_CERTIFICATE_GENERATION)
FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
FEATURES_WITH_BADGES_ENABLED = FEATURES_WITH_CERTS_ENABLED.copy()
@@ -937,7 +941,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase, CacheIsolationTestCase)
expected_date = today
else:
expected_date = self.course.certificate_available_date
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
with override_waffle_switch(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True):
response = self.client.get(test_url)
date = u'{month} {day}, {year}'.format(
month=strftime_localized(expected_date, "%B"),

View File

@@ -11,7 +11,8 @@ from django.test.client import RequestFactory
from mock import patch
from openedx.core.djangoapps.content.block_structure.api import clear_course_from_cache
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE, waffle
from openedx.core.djangoapps.content.block_structure.config import STORAGE_BACKING_FOR_CACHE, waffle_switch
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.tests.factories import UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@@ -229,7 +230,7 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
)
@ddt.unpack
def test_query_counts_cached(self, store_type, with_storage_backing):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
course = self._create_course(store_type)
self._get_blocks(
course,
@@ -246,7 +247,7 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
@ddt.unpack
def test_query_counts_uncached(self, store_type_tuple, with_storage_backing):
store_type, expected_mongo_queries = store_type_tuple
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
course = self._create_course(store_type)
clear_course_from_cache(course.id)

View File

@@ -48,21 +48,26 @@ from course_modes.models import CourseMode
from lms.djangoapps.courseware import module_render as render
from lms.djangoapps.courseware.access_response import AccessResponse
from lms.djangoapps.courseware.courses import get_course_info_section, get_course_with_access
from lms.djangoapps.courseware.field_overrides import OverrideFieldData
from lms.djangoapps.courseware.masquerade import CourseMasquerade
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.courseware.module_render import get_module_for_descriptor, hash_resource
from lms.djangoapps.courseware.tests.factories import (
GlobalStaffFactory, RequestFactoryNoCsrf, StudentModuleFactory, UserFactory,
GlobalStaffFactory,
RequestFactoryNoCsrf,
StudentModuleFactory,
UserFactory
)
from lms.djangoapps.courseware.tests.test_submitting_problems import TestSubmittingProblems
from lms.djangoapps.courseware.tests.tests import LoginEnrollmentTestCase
from lms.djangoapps.courseware.field_overrides import OverrideFieldData
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
from openedx.core.djangoapps.credit.api import set_credit_requirement_status, set_credit_requirements
from openedx.core.djangoapps.credit.models import CreditCourse
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory, AccessTokenFactory
from openedx.core.djangoapps.oauth_dispatch.tests.factories import AccessTokenFactory, ApplicationFactory
from openedx.core.djangoapps.waffle_utils import WaffleSwitch
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from openedx.core.lib.courses import course_image_url
from openedx.core.lib.gating import api as gating_api
from openedx.core.lib.url_utils import quote_slashes
@@ -86,6 +91,10 @@ from xmodule.x_module import STUDENT_VIEW, CombinedSystem, XModule, XModuleDescr
TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
ENABLE_COMPLETION_TRACKING_SWITCH = WaffleSwitch(
completion_waffle.waffle(), completion_waffle.ENABLE_COMPLETION_TRACKING, __name__
)
@XBlock.needs("field-data")
@XBlock.needs("i18n")
@@ -760,7 +769,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
@ddt.unpack
@XBlock.register_temp_plugin(StubCompletableXBlock, identifier='comp')
def test_completion_events_with_completion_disabled(self, signal, data):
with completion_waffle.waffle().override(completion_waffle.ENABLE_COMPLETION_TRACKING, False):
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, False):
course = CourseFactory.create()
block = ItemFactory.create(category='comp', parent=course)
request = self.request_factory.post(
@@ -782,7 +791,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
@XBlock.register_temp_plugin(StubCompletableXBlock, identifier='comp')
def test_completion_signal_for_completable_xblock(self):
with completion_waffle.waffle().override(completion_waffle.ENABLE_COMPLETION_TRACKING, True):
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
course = CourseFactory.create()
block = ItemFactory.create(category='comp', parent=course)
@@ -862,7 +871,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
@XBlock.register_temp_plugin(StubCompletableXBlock, identifier='comp')
def test_progress_signal_ignored_for_completable_xblock(self):
with completion_waffle.waffle().override(completion_waffle.ENABLE_COMPLETION_TRACKING, True):
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
course = CourseFactory.create()
block = ItemFactory.create(category='comp', parent=course)
@@ -875,7 +884,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
@XBlock.register_temp_plugin(XBlockWithoutCompletionAPI, identifier='no_comp')
def test_progress_signal_processed_for_xblock_without_completion_api(self):
with completion_waffle.waffle().override(completion_waffle.ENABLE_COMPLETION_TRACKING, True):
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
course = CourseFactory.create()
block = ItemFactory.create(category='no_comp', parent=course)
@@ -889,7 +898,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
@XBlock.register_temp_plugin(StubCompletableXBlock, identifier='comp')
def test_skip_handlers_for_masquerading_staff(self):
with completion_waffle.waffle().override(completion_waffle.ENABLE_COMPLETION_TRACKING, True):
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
course = CourseFactory.create()
block = ItemFactory.create(category='comp', parent=course)
request = self.request_factory.post(

View File

@@ -65,7 +65,7 @@ from lms.djangoapps.courseware.user_state_client import DjangoXBlockUserStateCli
from lms.djangoapps.courseware.views.index import show_courseware_mfe_link
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
from lms.djangoapps.grades.config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT
from lms.djangoapps.grades.config.waffle import waffle as grades_waffle
from lms.djangoapps.grades.config.waffle import waffle_switch as grades_waffle_switch
from lms.djangoapps.verify_student.models import VerificationDeadline
from lms.djangoapps.verify_student.services import IDVerificationService
from openedx.core.djangoapps.catalog.tests.factories import CourseFactory as CatalogCourseFactory
@@ -74,7 +74,7 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
from openedx.core.djangoapps.crawlers.models import CrawlersConfig
from openedx.core.djangoapps.credit.api import set_credit_requirements
from openedx.core.djangoapps.credit.models import CreditCourse, CreditProvider
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES, override_waffle_switch
from openedx.core.djangolib.testing.utils import get_mock_request
from openedx.core.lib.gating import api as gating_api
from openedx.core.lib.url_utils import quote_slashes
@@ -1446,7 +1446,7 @@ class ProgressPageTests(ProgressPageBaseTests):
def test_progress_queries(self, enable_waffle, initial, subsequent):
ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
self.setup_course()
with grades_waffle().override(ASSUME_ZERO_GRADE_IF_ABSENT, active=enable_waffle):
with override_waffle_switch(grades_waffle_switch(ASSUME_ZERO_GRADE_IF_ABSENT), active=enable_waffle):
with self.assertNumQueries(
initial, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST
), check_mongo_calls(1):

View File

@@ -7,6 +7,7 @@ import datetime
import logging
import ddt
import six
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.contrib.sites.models import Site
@@ -17,16 +18,8 @@ from mock import ANY, Mock, patch
from opaque_keys.edx.keys import CourseKey
from sailthru.sailthru_error import SailthruClientError
from sailthru.sailthru_response import SailthruResponse
import six
from testfixtures import LogCapture
from ..models import EmailMarketingConfiguration
from ..signals import (
add_email_marketing_cookies,
email_marketing_register_user,
email_marketing_user_field_changed,
update_sailthru
)
from lms.djangoapps.email_marketing.tasks import (
_create_user_list,
_get_list_from_email_marketing_provider,
@@ -41,6 +34,14 @@ from student.models import Registration
from student.tests.factories import CourseEnrollmentFactory, UserFactory, UserProfileFactory
from util.json_request import JsonResponse
from ..models import EmailMarketingConfiguration
from ..signals import (
add_email_marketing_cookies,
email_marketing_register_user,
email_marketing_user_field_changed,
update_sailthru
)
log = logging.getLogger(__name__)
LOGGER_NAME = "lms.djangoapps.email_marketing.signals"
@@ -620,7 +621,7 @@ class SailthruTests(TestCase):
@patch('sailthru.sailthru_client.SailthruClient.purchase')
@patch('sailthru.sailthru_client.SailthruClient.api_get')
@patch('sailthru.sailthru_client.SailthruClient.api_post')
@patch('openedx.core.djangoapps.waffle_utils.WaffleSwitchNamespace.is_enabled')
@patch('edx_toggles.toggles.WaffleSwitchNamespace.is_enabled')
def test_update_course_enrollment_whitelabel(
self,
switch,
@@ -645,7 +646,7 @@ class SailthruTests(TestCase):
update_sailthru(None, self.user, 'verified', self.course_id)
self.assertFalse(mock_sailthru_purchase.called)
@patch('openedx.core.djangoapps.waffle_utils.WaffleSwitchNamespace.is_enabled')
@patch('edx_toggles.toggles.WaffleSwitchNamespace.is_enabled')
@patch('sailthru.sailthru_client.SailthruClient.purchase')
def test_purchase_is_not_invoked(self, mock_sailthru_purchase, switch):
"""Make sure purchase is not called in the following condition:
@@ -655,7 +656,7 @@ class SailthruTests(TestCase):
update_sailthru(None, self.user, 'verified', self.course_id)
self.assertFalse(mock_sailthru_purchase.called)
@patch('openedx.core.djangoapps.waffle_utils.WaffleSwitchNamespace.is_enabled')
@patch('edx_toggles.toggles.WaffleSwitchNamespace.is_enabled')
@patch('sailthru.sailthru_client.SailthruClient.purchase')
def test_encoding_is_working_for_email_contains_unicode(self, mock_sailthru_purchase, switch):
"""Make sure encoding is working for emails contains unicode characters

View File

@@ -4,7 +4,12 @@ waffle switches for the Grades app.
"""
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag, WaffleFlagNamespace, WaffleSwitchNamespace
from openedx.core.djangoapps.waffle_utils import (
CourseWaffleFlag,
WaffleFlagNamespace,
WaffleSwitch,
WaffleSwitchNamespace
)
# Namespace
WAFFLE_NAMESPACE = u'grades'
@@ -81,6 +86,16 @@ def waffle():
return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Grades: ')
def waffle_switch(name):
"""
Return the corresponding namespaced waffle switch.
WARNING: do not replicate this pattern. Instead of declaring waffle switch names as strings, you should create
WaffleSwitch objects as top-level constants.
"""
return WaffleSwitch(waffle(), name, module_name=__name__)
def waffle_flags():
"""
Returns the namespaced, cached, audited Waffle flags dictionary for Grades.

View File

@@ -4,13 +4,14 @@ from crum import set_current_request
from django.conf import settings
from mock import patch
from edx_toggles.toggles.testutils import override_waffle_switch
from openedx.core.djangolib.testing.utils import get_mock_request
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from ..config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT, waffle
from ..config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT, waffle_switch
from ..course_data import CourseData
from ..course_grade import ZeroCourseGrade
from ..course_grade_factory import CourseGradeFactory
@@ -31,7 +32,7 @@ class ZeroGradeTest(GradeTestBase):
"""
Creates a ZeroCourseGrade and ensures it's empty.
"""
with waffle().override(ASSUME_ZERO_GRADE_IF_ABSENT, active=assume_zero_enabled):
with override_waffle_switch(waffle_switch(ASSUME_ZERO_GRADE_IF_ABSENT), active=assume_zero_enabled):
course_data = CourseData(self.request.user, structure=self.course_structure)
chapter_grades = ZeroCourseGrade(self.request.user, course_data).chapter_grades
for chapter in chapter_grades:
@@ -46,7 +47,7 @@ class ZeroGradeTest(GradeTestBase):
"""
Creates a zero course grade and ensures that null scores aren't included in the section problem scores.
"""
with waffle().override(ASSUME_ZERO_GRADE_IF_ABSENT, active=assume_zero_enabled):
with override_waffle_switch(waffle_switch(ASSUME_ZERO_GRADE_IF_ABSENT), active=assume_zero_enabled):
with patch('lms.djangoapps.grades.subsection_grade.get_score', return_value=None):
course_data = CourseData(self.request.user, structure=self.course_structure)
chapter_grades = ZeroCourseGrade(self.request.user, course_data).chapter_grades

View File

@@ -9,7 +9,7 @@ import ddt
from django.conf import settings
from mock import patch
from six import text_type
from edx_toggles.toggles.testutils import override_waffle_switch
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.grades.config.tests.utils import persistent_grades_feature_flags
from openedx.core.djangoapps.content.block_structure.factory import BlockStructureFactory
@@ -17,7 +17,7 @@ from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from ..config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT, waffle
from ..config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT, waffle_switch
from ..course_grade import CourseGrade, ZeroCourseGrade
from ..course_grade_factory import CourseGradeFactory
from ..subsection_grade import ReadSubsectionGrade, ZeroSubsectionGrade
@@ -132,7 +132,7 @@ class TestCourseGradeFactory(GradeTestBase):
@ddt.data(*itertools.product((True, False), (True, False)))
@ddt.unpack
def test_read_zero(self, assume_zero_enabled, create_if_needed):
with waffle().override(ASSUME_ZERO_GRADE_IF_ABSENT, active=assume_zero_enabled):
with override_waffle_switch(waffle_switch(ASSUME_ZERO_GRADE_IF_ABSENT), active=assume_zero_enabled):
grade_factory = CourseGradeFactory()
course_grade = grade_factory.read(self.request.user, self.course, create_if_needed=create_if_needed)
if create_if_needed or assume_zero_enabled:

View File

@@ -13,6 +13,8 @@ from course_modes.models import CourseMode
from openedx.core.djangoapps.certificates import api
from openedx.core.djangoapps.certificates.config import waffle as certs_waffle
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.waffle_utils import WaffleSwitch
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.tests.factories import CourseEnrollmentFactory, UserFactory
@@ -66,8 +68,8 @@ class MockGeneratedCertificate(object):
@contextmanager
def configure_waffle_namespace(feature_enabled):
namespace = certs_waffle.waffle()
with namespace.override(certs_waffle.AUTO_CERTIFICATE_GENERATION, active=feature_enabled):
auto_certificate_generation_switch = WaffleSwitch(namespace, certs_waffle.AUTO_CERTIFICATE_GENERATION)
with override_waffle_switch(auto_certificate_generation_switch, active=feature_enabled):
yield

View File

@@ -4,7 +4,7 @@ waffle switches for the Block Structure framework.
"""
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
from openedx.core.djangoapps.waffle_utils import WaffleSwitch, WaffleSwitchNamespace
from openedx.core.lib.cache_utils import request_cached
from .models import BlockStructureConfiguration
@@ -25,6 +25,16 @@ def waffle():
return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'BlockStructure: ')
def waffle_switch(name):
"""
Return the waffle switch associated to this namespace.
WARNING: do not replicate this pattern. Instead of declaring waffle switch names as strings, you should create
WaffleSwitch objects as top-level constants.
"""
return WaffleSwitch(waffle(), name, module_name=__name__)
@request_cached()
def num_versions_to_keep():
"""

View File

@@ -133,7 +133,7 @@ class Command(BaseCommand):
Generates course blocks for the given course_keys per the given options.
"""
if options.get('with_storage'):
waffle().override_for_request(STORAGE_BACKING_FOR_CACHE)
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
for course_key in course_keys:
try:

View File

@@ -60,7 +60,7 @@ def _update_course_in_cache(self, **kwargs):
Updates the course blocks (mongo -> BlockStructure) for the specified course.
"""
if kwargs.get('with_storage'):
waffle().override_for_request(STORAGE_BACKING_FOR_CACHE)
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
_call_and_retry_if_needed(self, api.update_course_in_cache, **kwargs)
@@ -89,7 +89,7 @@ def _get_course_in_cache(self, **kwargs):
Gets the course blocks for the specified course, updating the cache if needed.
"""
if kwargs.get('with_storage'):
waffle().override_for_request(STORAGE_BACKING_FOR_CACHE)
waffle().set_request_cache_with_short_name(STORAGE_BACKING_FOR_CACHE, True)
_call_and_retry_if_needed(self, api.get_course_in_cache, **kwargs)

View File

@@ -7,8 +7,10 @@ import ddt
import six
from django.test import TestCase
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from ..block_structure import BlockStructureBlockData
from ..config import RAISE_ERROR_WHEN_NOT_FOUND, STORAGE_BACKING_FOR_CACHE, waffle
from ..config import RAISE_ERROR_WHEN_NOT_FOUND, STORAGE_BACKING_FOR_CACHE, waffle_switch
from ..exceptions import BlockStructureNotFound, UsageKeyNotInBlockStructure
from ..manager import BlockStructureManager
from ..transformers import BlockStructureTransformers
@@ -178,14 +180,14 @@ class TestBlockStructureManager(UsageKeyFactoryMixin, ChildrenMapTestMixin, Test
assert TestTransformer1.collect_call_count == 1
def test_get_collected_error_raised(self):
with waffle().override(RAISE_ERROR_WHEN_NOT_FOUND, active=True):
with override_waffle_switch(waffle_switch(RAISE_ERROR_WHEN_NOT_FOUND), active=True):
with mock_registered_transformers(self.registered_transformers):
with self.assertRaises(BlockStructureNotFound):
self.bs_manager.get_collected()
@ddt.data(True, False)
def test_update_collected_if_needed(self, with_storage_backing):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
with mock_registered_transformers(self.registered_transformers):
assert TestTransformer1.collect_call_count == 0

View File

@@ -7,12 +7,13 @@ import ddt
from mock import patch
from opaque_keys.edx.locator import CourseLocator, LibraryLocator
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from ..api import get_block_structure_manager
from ..config import INVALIDATE_CACHE_ON_PUBLISH, waffle
from ..config import INVALIDATE_CACHE_ON_PUBLISH, waffle_switch
from ..signals import update_block_structure_on_course_publish
from .helpers import is_course_in_block_structure_cache
@@ -56,7 +57,7 @@ class CourseBlocksSignalTest(ModuleStoreTestCase):
def test_cache_invalidation(self, invalidate_cache_enabled, mock_bs_manager_clear):
test_display_name = "Jedi 101"
with waffle().override(INVALIDATE_CACHE_ON_PUBLISH, active=invalidate_cache_enabled):
with override_waffle_switch(waffle_switch(INVALIDATE_CACHE_ON_PUBLISH), active=invalidate_cache_enabled):
self.course.display_name = test_display_name
self.store.update_item(self.course, self.user.id)

View File

@@ -5,9 +5,10 @@ Tests for block_structure/cache.py
import ddt
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from ..config import STORAGE_BACKING_FOR_CACHE, waffle
from ..config import STORAGE_BACKING_FOR_CACHE, waffle_switch
from ..config.models import BlockStructureConfiguration
from ..exceptions import BlockStructureNotFound
from ..store import BlockStructureStore
@@ -47,13 +48,13 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
@ddt.data(True, False)
def test_get_none(self, with_storage_backing):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
with self.assertRaises(BlockStructureNotFound):
self.store.get(self.block_structure.root_block_usage_key)
@ddt.data(True, False)
def test_add_and_get(self, with_storage_backing):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
self.store.add(self.block_structure)
stored_value = self.store.get(self.block_structure.root_block_usage_key)
self.assertIsNotNone(stored_value)
@@ -61,7 +62,7 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
@ddt.data(True, False)
def test_delete(self, with_storage_backing):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=with_storage_backing):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=with_storage_backing):
self.store.add(self.block_structure)
self.store.delete(self.block_structure.root_block_usage_key)
with self.assertRaises(BlockStructureNotFound):
@@ -74,7 +75,7 @@ class TestBlockStructureStore(UsageKeyFactoryMixin, ChildrenMapTestMixin, CacheI
self.store.get(self.block_structure.root_block_usage_key)
def test_uncached_with_storage(self):
with waffle().override(STORAGE_BACKING_FOR_CACHE, active=True):
with override_waffle_switch(waffle_switch(STORAGE_BACKING_FOR_CACHE), active=True):
self.store.add(self.block_structure)
self.mock_cache.map.clear()
stored_value = self.store.get(self.block_structure.root_block_usage_key)

View File

@@ -10,30 +10,23 @@ import ddt
import mock
import six
from django.core.management import call_command
import openedx.core.djangoapps.content.block_structure.config as block_structure_config
from openedx.core.djangoapps.content.block_structure.signals import update_block_structure_on_course_publish
from openedx.core.djangoapps.coursegraph.management.commands.dump_to_neo4j import ModuleStoreSerializer
from openedx.core.djangoapps.coursegraph.management.commands.tests.utils import MockGraph, MockNodeSelector
from openedx.core.djangoapps.coursegraph.tasks import (
coerce_types,
serialize_course,
serialize_item,
should_dump_course,
strip_branch_and_version
)
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from openedx.core.djangolib.testing.utils import skip_unless_lms
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from openedx.core.djangolib.testing.utils import skip_unless_lms
from openedx.core.djangoapps.coursegraph.management.commands.dump_to_neo4j import (
ModuleStoreSerializer
)
from openedx.core.djangoapps.coursegraph.management.commands.tests.utils import (
MockGraph,
MockNodeSelector,
)
from openedx.core.djangoapps.coursegraph.tasks import (
serialize_item,
serialize_course,
coerce_types,
should_dump_course,
strip_branch_and_version,
)
from openedx.core.djangoapps.content.block_structure.signals import (
update_block_structure_on_course_publish
)
import openedx.core.djangoapps.content.block_structure.config as block_structure_config
class TestDumpToNeo4jCommandBase(SharedModuleStoreTestCase):
"""
@@ -507,7 +500,9 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase):
self.assertEqual(len(submitted), len(self.course_strings))
# simulate one of the courses being published
with block_structure_config.waffle().override(block_structure_config.STORAGE_BACKING_FOR_CACHE):
with override_waffle_switch(
block_structure_config.waffle_switch(block_structure_config.STORAGE_BACKING_FOR_CACHE), True
):
update_block_structure_on_course_publish(None, self.course.id)
# make sure only the published course was dumped

View File

@@ -32,6 +32,7 @@ from openedx.core.djangoapps.user_authn.views.login import (
AllowedAuthUser,
_check_user_auth_flow
)
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
from openedx.core.lib.api.test_utils import ApiTestCase
@@ -725,7 +726,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
'THIRD_PARTY_AUTH_ONLY_HINT': provider_tpa_hint,
}
with ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY.override(switch_enabled):
with override_waffle_switch(ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY, switch_enabled):
if not is_third_party_authenticated:
site = self.set_up_site(allowed_domain, default_site_configuration_values)
@@ -778,7 +779,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
'THIRD_PARTY_AUTH_ONLY_HINT': provider_tpa_hint,
}
with ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY.override(True):
with override_waffle_switch(ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY, True):
site = self.set_up_site(allowed_domain, default_site_configuration_values)
with self.assertLogs(level='WARN') as log:

View File

@@ -3,97 +3,15 @@ Extra utilities for waffle: most classes are defined in edx_toggles.toggles (htt
we keep here some extra classes for usage within edx-platform. These classes cover course override use cases.
"""
import logging
from contextlib import contextmanager
from opaque_keys.edx.keys import CourseKey
from edx_toggles.toggles import WaffleFlag, WaffleFlagNamespace
from edx_toggles.toggles import WaffleSwitch as BaseWaffleSwitch
from edx_toggles.toggles import WaffleSwitchNamespace as BaseWaffleSwitchNamespace
# pylint: disable=unused-import
from edx_toggles.toggles import WaffleFlag, WaffleFlagNamespace, WaffleSwitch, WaffleSwitchNamespace
log = logging.getLogger(__name__)
class WaffleSwitchNamespace(BaseWaffleSwitchNamespace):
"""
Waffle switch namespace that implements custom overriding methods. We should eventually get rid of this class.
To test WaffleSwitchNamespace, use the provided context managers. For example:
with WAFFLE_SWITCHES.override(waffle.ESTIMATE_FIRST_ATTEMPTED, active=True):
...
Note: this should eventually be deprecated in favour of a dedicated `override_waffle_switch` context manager.
"""
@contextmanager
def override(self, switch_name, active=True):
"""
Overrides the active value for the given switch for the duration of this
contextmanager.
Note: The value is overridden in the request cache AND in the model.
"""
previous_active = self.is_enabled(switch_name)
try:
self.override_for_request(switch_name, active)
with self.override_in_model(switch_name, active):
yield
finally:
self.override_for_request(switch_name, previous_active)
def override_for_request(self, switch_name, active=True):
"""
Overrides the active value for the given switch for the remainder of
this request (as this is not a context manager).
Note: The value is overridden in the request cache, not in the model.
"""
namespaced_switch_name = self._namespaced_name(switch_name)
self._cached_switches[namespaced_switch_name] = active
log.info(
"%sSwitch '%s' set to %s for request.",
self.log_prefix,
namespaced_switch_name,
active,
)
@contextmanager
def override_in_model(self, switch_name, active=True):
"""
Overrides the active value for the given switch for the duration of this
contextmanager.
Note: The value is overridden in the model, not the request cache.
Note: This should probably be moved to a test class.
"""
# Import is placed here to avoid model import at project startup.
# pylint: disable=import-outside-toplevel
from waffle.testutils import override_switch as waffle_override_switch
namespaced_switch_name = self._namespaced_name(switch_name)
with waffle_override_switch(namespaced_switch_name, active):
log.info(
"%sSwitch '%s' set to %s in model.",
self.log_prefix,
namespaced_switch_name,
active,
)
yield
class WaffleSwitch(BaseWaffleSwitch):
"""
This class should be removed in favour of edx_toggles.toggles.WaffleSwitch once we get rid of the
WaffleSwitchNamespace class.
"""
NAMESPACE_CLASS = WaffleSwitchNamespace
@contextmanager
def override(self, active=True):
with self.waffle_namespace.override(self.switch_name, active):
yield
class CourseWaffleFlag(WaffleFlag):
"""
Represents a single waffle flag that can be forced on/off for a course. This class should be used instead of

View File

@@ -7,7 +7,8 @@ import ddt
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
# Note that we really shouldn't import from edx_toggles' internal API
# TODO: we really shouldn't import from edx_toggles' internal API, but that's currently the only way to mock the
# monitoring functions.
import edx_toggles.toggles.internal.waffle
from edx_django_utils.cache import RequestCache
from mock import call, patch

View File

@@ -5,7 +5,7 @@ Test utilities for waffle utilities.
# Import from edx-toggles to preserve import paths
# TODO: Deprecate and remove
# pylint: disable=unused-import
from edx_toggles.toggles.testutils import override_waffle_flag
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
# Can be used with FilteredQueryCountMixin.assertNumQueries() to blacklist
# waffle tables. For example:

View File

@@ -4,10 +4,12 @@ Tests that verify that the admin view loads.
This is not inside a django app because it is a global property of the system.
"""
from django.test import TestCase, Client
from django.test import Client, TestCase
from django.urls import reverse
from student.tests.factories import UserFactory, TEST_PASSWORD
from openedx.core.djangoapps.user_authn.views.login import ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_switch
from student.tests.factories import TEST_PASSWORD, UserFactory
class TestAdminView(TestCase):
@@ -37,10 +39,10 @@ class TestAdminView(TestCase):
assert response.status_code == 302
def test_admin_login_redirect(self):
with ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY.override(True):
with override_waffle_switch(ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY, True):
response = self.client.get(reverse('admin:login'))
assert response.url == '/login?next=/admin'
assert response.status_code == 302
with ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY.override(False):
with override_waffle_switch(ENABLE_LOGIN_USING_THIRDPARTY_AUTH_ONLY, False):
response = self.client.get(reverse('admin:login'))
assert response.template_name == ['admin/login.html']

View File

@@ -5,11 +5,11 @@ Test models, managers, and validators.
import ddt
import six
from completion import waffle
from completion.test_utils import CompletionWaffleTestMixin
from django.urls import reverse
from rest_framework.test import APIClient
import six
from openedx.core.djangolib.testing.utils import skip_unless_lms
from student.tests.factories import CourseEnrollmentFactory, UserFactory