refactor: delete now unused FutureCourseWaffleFlag (#30367)

Remove temporary FutureCourseWaffleFlag class;
Update ora2 and edx-toggles to versions cleaned from the
LegacyWaffle* classes;
Replace `override_flag`s with `override_waffle_flag`;
Replace `override_switch`s with `override_waffle_switch` (where it's possible).
This commit is contained in:
Eugene Dyudyunov
2022-05-13 15:48:42 +03:00
committed by GitHub
parent 0d2ea3c2e2
commit 52dd883a3c
16 changed files with 93 additions and 143 deletions

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.test import TestCase
from django.test.utils import override_settings
from edx_toggles.toggles.testutils import override_waffle_switch
from edxval.api import create_video, get_videos_for_course
from fs.osfs import OSFS
from lxml import etree
@@ -23,7 +24,21 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import AssetKey, CourseKey, UsageKey
from opaque_keys.edx.locations import CourseLocator
from path import Path as path
from waffle.testutils import override_switch
from xmodule.capa_module import ProblemBlock
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore
from xmodule.contentstore.utils import empty_asset_trashcan, restore_asset_from_trashcan
from xmodule.course_module import CourseBlock, Textbook
from xmodule.exceptions import InvalidVersionError
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from xmodule.modulestore.xml_exporter import export_course_to_xml
from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint
from xmodule.seq_module import SequenceBlock
from xmodule.video_module import VideoBlock
from cms.djangoapps.contentstore.config import waffle
from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, CourseTestCase, get_url, parse_json
@@ -36,21 +51,6 @@ from common.djangoapps.student.models import CourseEnrollment
from common.djangoapps.student.roles import CourseCreatorRole, CourseInstructorRole
from openedx.core.djangoapps.django_comment_common.utils import are_permissions_roles_seeded
from openedx.core.lib.tempdir import mkdtemp_clean
from xmodule.capa_module import ProblemBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.contentstore.content import StaticContent # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.contentstore.django import contentstore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.contentstore.utils import empty_asset_trashcan, restore_asset_from_trashcan # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.course_module import CourseBlock, Textbook # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.exceptions import InvalidVersionError # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.inheritance import own_metadata # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.xml_exporter import export_course_to_xml # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.seq_module import SequenceBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.video_module import VideoBlock # lint-amnesty, pylint: disable=wrong-import-order
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
@@ -1055,7 +1055,7 @@ class MiscCourseTests(ContentStoreTestCase):
resp = self.client.get_html('/c4x/InvalidOrg/InvalidCourse/asset/invalid.png')
self.assertEqual(resp.status_code, 404)
@override_switch(waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE.name, active=False)
@override_waffle_switch(waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE, active=False)
def test_disabled_accessibility_page(self):
"""
Test that accessibility page returns 404 when waffle switch is disabled
@@ -2189,7 +2189,7 @@ class EntryPageTestCase(TestCase):
# Logout redirects.
self._test_page("/logout", 200)
@override_switch(waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE.name, active=True)
@override_waffle_switch(waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE, active=True)
def test_accessibility(self):
self._test_page('/accessibility')

View File

@@ -26,7 +26,6 @@ from edxval.api import (
get_transcript_preferences,
get_video_info
)
from waffle.testutils import override_flag
from cms.djangoapps.contentstore.models import VideoUploadConfig
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
@@ -541,7 +540,7 @@ class VideosHandlerTestCase(VideoUploadTestMixin, VideoUploadPostTestsMixin, Cou
@override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret', AWS_SECURITY_TOKEN='token')
@patch('boto.s3.key.Key')
@patch('boto.s3.connection.S3Connection')
@override_flag(ENABLE_DEVSTACK_VIDEO_UPLOADS.name, active=True)
@override_waffle_flag(ENABLE_DEVSTACK_VIDEO_UPLOADS, active=True)
def test_devstack_upload_connection(self, mock_conn, mock_key):
files = [{'file_name': 'first.mp4', 'content_type': 'video/mp4'}]
mock_key_instances = [
@@ -647,7 +646,7 @@ class VideosHandlerTestCase(VideoUploadTestMixin, VideoUploadPostTestsMixin, Cou
expected_args = ('course_video_upload_token', self.test_token)
with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=data['course_override']):
with override_flag(DEPRECATE_YOUTUBE.name, active=data['global_waffle']):
with override_waffle_flag(DEPRECATE_YOUTUBE, active=data['global_waffle']):
response = self.client.post(
self.url,
json.dumps({'files': [file_data]}),

View File

@@ -74,6 +74,9 @@ class EcommerceServiceTests(TestCase):
is_not_enabled = EcommerceService().is_enabled(self.user)
assert not is_not_enabled
# TODO: replace override_switch with override_waffle_switch when the
# DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH will be defined as actual WaffleSwitch. Now
# we have only switch name defined in the settings
@override_switch(settings.DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH, active=True)
def test_is_enabled_activation_requirement_disabled(self):
"""Verify that is_enabled() returns True when ecomm checkout is enabled. """

View File

@@ -5,19 +5,20 @@ Tests for Course API views.
from datetime import datetime
from hashlib import md5
from unittest import TestCase
import pytest
import ddt
import pytest
from django.core.exceptions import ImproperlyConfigured
from django.test import RequestFactory
from django.test.utils import override_settings
from django.urls import reverse
from edx_django_utils.cache import RequestCache
from edx_toggles.toggles.testutils import override_waffle_switch
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import LibraryLocator
from search.tests.test_course_discovery import DemoCourse
from search.tests.tests import TEST_INDEX_NAME
from search.tests.utils import SearcherMixin
from waffle.testutils import override_switch
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -26,6 +27,7 @@ from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from common.djangoapps.student.auth import add_users
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.tests.factories import AdminFactory
from lms.djangoapps.course_api import USE_RATE_LIMIT_2_FOR_COURSE_LIST_API, USE_RATE_LIMIT_10_FOR_COURSE_LIST_API
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES
from openedx.core.lib.api.view_utils import LazySequence
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
@@ -138,14 +140,14 @@ class CourseListViewTestCase(CourseApiTestViewMixin, SharedModuleStoreTestCase):
@ddt.data(('staff', False, 10), ('user', False, 2), ('unknown', True, None))
@ddt.unpack
@override_switch('course_list_api_rate_limit.rate_limit_2', active=True)
@override_waffle_switch(USE_RATE_LIMIT_2_FOR_COURSE_LIST_API, active=True)
def test_throttle_rate_2(self, user_scope, throws_exception, expected_rate):
""" Make sure throttle rate 2 is set correctly for different user scopes. """
self.assert_throttle_configured_correctly(user_scope, throws_exception, expected_rate)
@ddt.data(('staff', False, 20), ('user', False, 10), ('unknown', True, None))
@ddt.unpack
@override_switch('course_list_api_rate_limit.rate_limit_10', active=True)
@override_waffle_switch(USE_RATE_LIMIT_10_FOR_COURSE_LIST_API, active=True)
def test_throttle_rate_20(self, user_scope, throws_exception, expected_rate):
""" Make sure throttle rate 20 is set correctly for different user scopes. """
self.assert_throttle_configured_correctly(user_scope, throws_exception, expected_rate)

View File

@@ -4,23 +4,22 @@ Test the about xblock
import datetime
from unittest import mock
from unittest.mock import patch
import ddt
import pytz
from django.conf import settings
from django.test.utils import override_settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
from milestones.tests.utils import MilestonesTestCaseMixin
from waffle.testutils import override_switch
from xmodule.course_module import (
CATALOG_VISIBILITY_ABOUT,
CATALOG_VISIBILITY_NONE,
COURSE_VISIBILITY_PRIVATE,
COURSE_VISIBILITY_PUBLIC,
COURSE_VISIBILITY_PUBLIC_OUTLINE
COURSE_VISIBILITY_PUBLIC_OUTLINE,
)
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -28,12 +27,12 @@ from xmodule.modulestore.tests.utils import TEST_DATA_DIR
from xmodule.modulestore.xml_importer import import_course_from_xml
from common.djangoapps.course_modes.models import CourseMode
from openedx.core.djangoapps.models.course_details import CourseDetails
from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, course_home_url
from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML
from common.djangoapps.student.tests.factories import CourseEnrollmentAllowedFactory, UserFactory
from common.djangoapps.track.tests import EventTrackingTestCase
from common.djangoapps.util.milestones_helpers import get_prerequisite_courses_display, set_prerequisite_courses
from openedx.core.djangoapps.models.course_details import CourseDetails
from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, course_home_url
from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML
from .helpers import LoginEnrollmentTestCase
@@ -396,7 +395,7 @@ class AboutSidebarHTMLTestCase(SharedModuleStoreTestCase):
)
@ddt.unpack
def test_html_sidebar_enabled(self, itemfactory_display_name, itemfactory_data, waffle_switch_value):
with override_switch(ENABLE_COURSE_ABOUT_SIDEBAR_HTML.name, active=waffle_switch_value):
with override_waffle_switch(ENABLE_COURSE_ABOUT_SIDEBAR_HTML, active=waffle_switch_value):
if itemfactory_display_name:
ItemFactory.create(
category="about",

View File

@@ -7,11 +7,10 @@ from unittest.mock import patch
import crum
import ddt
import waffle # lint-amnesty, pylint: disable=invalid-django-waffle-import
from django.conf import settings
from django.test import RequestFactory
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
from freezegun import freeze_time
from pytz import utc
from xmodule.modulestore import ModuleStoreEnum
@@ -20,6 +19,8 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from common.djangoapps.student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory
from lms.djangoapps.certificates.config import AUTO_CERTIFICATE_GENERATION
from lms.djangoapps.commerce.models import CommerceConfiguration
from lms.djangoapps.courseware.courses import get_course_date_blocks
from lms.djangoapps.courseware.date_summary import (
@@ -30,12 +31,12 @@ from lms.djangoapps.courseware.date_summary import (
CourseStartDate,
TodaysDate,
VerificationDeadlineDate,
VerifiedUpgradeDeadlineDate
VerifiedUpgradeDeadlineDate,
)
from lms.djangoapps.courseware.models import (
CourseDynamicUpgradeDeadlineConfiguration,
DynamicUpgradeDeadlineConfiguration,
OrgDynamicUpgradeDeadlineConfiguration
OrgDynamicUpgradeDeadlineConfiguration,
)
from lms.djangoapps.verify_student.models import VerificationDeadline
from lms.djangoapps.verify_student.services import IDVerificationService
@@ -45,7 +46,6 @@ from openedx.core.djangoapps.content.course_overviews.tests.factories import Cou
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from common.djangoapps.student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory
@ddt.ddt
@@ -477,7 +477,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
assert block.link == f'{configuration.basket_checkout_page}?sku={sku}'
## CertificateAvailableDate
@waffle.testutils.override_switch('certificates.auto_certificate_generation', True)
@override_waffle_switch(AUTO_CERTIFICATE_GENERATION, True)
def test_no_certificate_available_date(self):
course = create_course_run(days_till_start=-1)
user = create_user()
@@ -487,7 +487,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
assert not block.is_allowed
## CertificateAvailableDate
@waffle.testutils.override_switch('certificates.auto_certificate_generation', True)
@override_waffle_switch(AUTO_CERTIFICATE_GENERATION, True)
def test_no_certificate_available_date_for_self_paced(self):
course = create_self_paced_course_run()
verified_user = create_user()
@@ -521,7 +521,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
assert not block.is_allowed
assert block.date is not None
@waffle.testutils.override_switch('certificates.auto_certificate_generation', True)
@override_waffle_switch(AUTO_CERTIFICATE_GENERATION, True)
def test_certificate_available_date_defined(self):
course = create_course_run()
audit_user = create_user()

View File

@@ -7,15 +7,17 @@ import json
import shutil
from collections import OrderedDict
from tempfile import mkdtemp
from uuid import uuid4
from unittest.mock import MagicMock, Mock, patch
import pytest
from uuid import uuid4
import ddt
import pytest
from django.conf import settings
from django.core.files import File
from django.core.files.base import ContentFile
from django.test import TestCase
from django.test.utils import override_settings
from edx_toggles.toggles.testutils import override_waffle_flag
from edxval.api import (
ValCannotCreateError,
ValVideoNotFoundError,
@@ -25,31 +27,30 @@ from edxval.api import (
create_video_transcript,
get_video_info,
get_video_transcript,
get_video_transcript_data
get_video_transcript_data,
)
from edxval.utils import create_file_in_fs
from fs.osfs import OSFS
from fs.path import combine
from lxml import etree
from path import Path as path
from waffle.testutils import override_flag
from xmodule.contentstore.content import StaticContent
from xmodule.exceptions import NotFoundError
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE
from xmodule.tests.test_import import DummySystem
from xmodule.tests.test_video import VideoBlockTestBase
from xmodule.video_module import VideoBlock, bumper_utils, video_utils
from xmodule.video_module.transcripts_utils import Transcript, save_to_store, subs_filename
from xmodule.video_module.video_module import EXPORT_IMPORT_COURSE_DIR, EXPORT_IMPORT_STATIC_DIR
from xmodule.x_module import PUBLIC_VIEW, STUDENT_VIEW
from common.djangoapps.xblock_django.constants import ATTR_KEY_REQUEST_COUNTRY_CODE
from lms.djangoapps.courseware.tests.helpers import get_context_dict_from_string
from openedx.core.djangoapps.video_pipeline.config.waffle import DEPRECATE_YOUTUBE
from openedx.core.djangoapps.waffle_utils.models import WaffleFlagCourseOverrideModel
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from xmodule.contentstore.content import StaticContent # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.exceptions import NotFoundError # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.inheritance import own_metadata # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.tests.test_import import DummySystem # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.tests.test_video import VideoBlockTestBase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.video_module import VideoBlock, bumper_utils, video_utils # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.video_module.transcripts_utils import Transcript, save_to_store, subs_filename # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.video_module.video_module import EXPORT_IMPORT_COURSE_DIR, EXPORT_IMPORT_STATIC_DIR # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.x_module import PUBLIC_VIEW, STUDENT_VIEW # lint-amnesty, pylint: disable=wrong-import-order
from .test_video_handlers import BaseTestVideoXBlock, TestVideo
from .test_video_xml import SOURCE_XML
@@ -1178,7 +1179,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
data['youtube']
)
with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=data['course_override']):
with override_flag(DEPRECATE_YOUTUBE.name, active=data['waffle_enabled']):
with override_waffle_flag(DEPRECATE_YOUTUBE, active=data['waffle_enabled']):
self.initialize_block(data=video_xml, metadata=metadata)
context = self.item_descriptor.render(STUDENT_VIEW).content
assert '"prioritizeHls": {}'.format(data['result']) in context

View File

@@ -34,7 +34,7 @@ def are_team_submissions_enabled(course_key):
):
return True
# TODO: this behaviour differs from edx-ora2, where the LegacyWaffleSwitch overrides the setting.
# TODO: this behaviour differs from edx-ora2, where the WaffleSwitch overrides the setting.
# https://github.com/edx/edx-ora2/blob/ac502d8301cb987c9885aaefbaeddaf456c13fb9/openassessment/xblock/config_mixin.py#L96
if TEAM_SUBMISSIONS_FEATURE.is_enabled():

View File

@@ -624,6 +624,9 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin, Tes
PayAndVerifyView.WEBCAM_REQ,
])
# TODO: replace override_switch with override_waffle_switch when the
# DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH will be defined as actual WaffleSwitch. Now
# we have only switch name defined in the settings
@override_switch(settings.DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH, active=True)
@ddt.data("verify_student_start_flow", "verify_student_begin_flow")
def test_disable_account_activation_requirement_flag_active(self, payment_flow):

View File

@@ -12,26 +12,29 @@ import pytz
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from edx_toggles.toggles.testutils import override_waffle_switch
from testfixtures import LogCapture
from waffle.testutils import override_switch
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from common.djangoapps.student.models import CourseEnrollment
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.schedules.config import _EXTERNAL_COURSE_UPDATES_FLAG
from openedx.core.djangoapps.schedules.config import (
_EXTERNAL_COURSE_UPDATES_FLAG,
COURSE_UPDATE_SHOW_UNSUBSCRIBE_WAFFLE_SWITCH,
)
from openedx.core.djangoapps.schedules.models import Schedule
from openedx.core.djangoapps.schedules.resolvers import (
LOG,
BinnedSchedulesBaseResolver,
CourseNextSectionUpdate,
CourseUpdateResolver
CourseUpdateResolver,
)
from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory
from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory, SiteFactory
from openedx.core.djangolib.testing.utils import CacheIsolationMixin, skip_unless_lms
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory # lint-amnesty, pylint: disable=wrong-import-order
class SchedulesResolverTestMixin(CacheIsolationMixin):
@@ -183,7 +186,7 @@ class TestCourseUpdateResolver(SchedulesResolverTestMixin, ModuleStoreTestCase):
}
assert schedules == [(self.user, None, expected_context)]
@override_switch('schedules.course_update_show_unsubscribe', True)
@override_waffle_switch(COURSE_UPDATE_SHOW_UNSUBSCRIBE_WAFFLE_SWITCH, True)
def test_schedule_context_show_unsubscribe(self):
resolver = self.create_resolver()
schedules = list(resolver.schedules_for_bin())
@@ -274,7 +277,7 @@ class TestCourseNextSectionUpdateResolver(SchedulesResolverTestMixin, ModuleStor
}
assert schedules == [(self.user, None, expected_context)]
@override_switch('schedules.course_update_show_unsubscribe', True)
@override_waffle_switch(COURSE_UPDATE_SHOW_UNSUBSCRIBE_WAFFLE_SWITCH, True)
def test_schedule_context_show_unsubscribe(self):
resolver = self.create_resolver()
schedules = list(resolver.get_schedules())

View File

@@ -1,18 +0,0 @@
"""
Temporary module to switch from the LegacyWaffle* classes.
"""
from edx_django_utils.monitoring import set_custom_attribute
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
class FutureCourseWaffleFlag(CourseWaffleFlag):
"""
Temporary class to support ORA transition to the modern CourseWaffleFlag.
"""
def __init__(self, name, module_name, log_prefix=""):
super().__init__(name, module_name=module_name, log_prefix=log_prefix)
set_custom_attribute(
"deprecated_legacy_waffle_class",
f"{self.__class__.__module__}.{self.__class__.__name__}[{self.name}]"
)

View File

@@ -9,11 +9,10 @@ import crum
import ddt
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache
from edx_toggles.toggles.testutils import override_waffle_flag
from opaque_keys.edx.keys import CourseKey
from waffle.testutils import override_flag
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
from openedx.core.djangoapps.waffle_utils.__future__ import FutureCourseWaffleFlag
from openedx.core.djangoapps.waffle_utils.models import WaffleFlagCourseOverrideModel, WaffleFlagOrgOverrideModel
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
@@ -54,8 +53,8 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
"""
Tests various combinations of a flag being set in waffle and overridden for a course.
"""
with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=course_override):
with override_flag(self.NAMESPACED_FLAG_NAME, active=waffle_enabled):
with override_waffle_flag(self.TEST_COURSE_FLAG, active=waffle_enabled):
with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=course_override):
# check twice to test that the result is properly cached
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY) == result
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY) == result
@@ -65,52 +64,11 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
self.NAMESPACED_FLAG_NAME,
self.TEST_COURSE_KEY
)
# check flag for a second course
if course_override == WaffleFlagCourseOverrideModel.ALL_CHOICES.unset:
# When course override wasn't set for the first course, the second course will get the same
# cached value from waffle.
# Check flag for a second course.
# This should be the same cached value as for overriden flag.
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_2_KEY) == waffle_enabled
else:
# When course override was set for the first course, it should not apply to the second
# course which should get the default value of False.
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_2_KEY) is False
@ddt.data(
(False, WaffleFlagCourseOverrideModel.ALL_CHOICES.on, True),
(True, WaffleFlagCourseOverrideModel.ALL_CHOICES.off, False),
(True, WaffleFlagCourseOverrideModel.ALL_CHOICES.unset, True),
(False, WaffleFlagCourseOverrideModel.ALL_CHOICES.unset, False),
)
@ddt.unpack
def test_future_course_waffle_flag(self, waffle_enabled, course_override, result):
"""
Tests various combinations of a __future__ flag being set in waffle and overridden for a course.
"""
test_future_course_flag = FutureCourseWaffleFlag(
self.NAMESPACED_FLAG_NAME, __name__
)
with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=course_override):
with override_flag(self.NAMESPACED_FLAG_NAME, active=waffle_enabled):
# check twice to test that the result is properly cached
assert test_future_course_flag.is_enabled(self.TEST_COURSE_KEY) == result
assert test_future_course_flag.is_enabled(self.TEST_COURSE_KEY) == result
# result is cached, so override check should happen only once
# pylint: disable=no-member
WaffleFlagCourseOverrideModel.override_value.assert_called_once_with(
self.NAMESPACED_FLAG_NAME,
self.TEST_COURSE_KEY
)
# check flag for a second course
if course_override == WaffleFlagCourseOverrideModel.ALL_CHOICES.unset:
# When course override wasn't set for the first course, the second course will get the same
# cached value from waffle.
assert test_future_course_flag.is_enabled(self.TEST_COURSE_2_KEY) == waffle_enabled
else:
# When course override was set for the first course, it should not apply to the second
# course which should get the default value of False.
assert test_future_course_flag.is_enabled(self.TEST_COURSE_2_KEY) is False
# Check the default value for the second course after the cache was restored
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_2_KEY) is False
@ddt.data(
(False, WaffleFlagOrgOverrideModel.ALL_CHOICES.unset, False),
@@ -140,7 +98,7 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
enabled=True
)
# Both course keys should match the org-level override.
with override_flag(self.NAMESPACED_FLAG_NAME, active=waffle_enabled):
with override_waffle_flag(self.TEST_COURSE_FLAG, active=waffle_enabled):
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY) == is_enabled
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_2_KEY) == is_enabled
@@ -170,7 +128,7 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
enabled=True
)
# Org doesn't match the course key, so should never be enabled.
with override_flag(self.NAMESPACED_FLAG_NAME, active=waffle_enabled):
with override_waffle_flag(self.TEST_COURSE_FLAG, active=waffle_enabled):
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_3_KEY) == is_enabled
@ddt.data(
@@ -226,7 +184,7 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
note='',
enabled=True
)
with override_flag(self.NAMESPACED_FLAG_NAME, active=waffle_enabled):
with override_waffle_flag(self.TEST_COURSE_FLAG, active=waffle_enabled):
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY) == is_enabled
def test_undefined_waffle_flag(self):
@@ -265,5 +223,5 @@ class TestCourseWaffleFlag(CacheIsolationTestCase):
crum.set_current_request(None)
test_course_flag = CourseWaffleFlag(self.NAMESPACED_FLAG_NAME, __name__)
with override_flag(self.NAMESPACED_FLAG_NAME, active=True):
with override_waffle_flag(self.TEST_COURSE_FLAG, active=True):
assert test_course_flag.is_enabled(self.TEST_COURSE_KEY) is True

View File

@@ -121,7 +121,7 @@ oauthlib # OAuth specification support for authentica
openedx-calc # Library supporting mathematical calculations for Open edX
openedx-events # Open edX Events from Hooks Extension Framework (OEP-50)
openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50)
ora2>=4.3.0
ora2>=4.4.0
piexif # Exif image metadata manipulation, used in the profile_images app
Pillow # Image manipulation library; used for course assets, profile images, invoice PDFs, etc.
py2neo # Driver for converting Python modulestore structures to Neo4j's schema (for Coursegraph).

View File

@@ -523,7 +523,7 @@ edx-submissions==3.5.1
# ora2
edx-tincan-py35==1.0.0
# via edx-enterprise
edx-toggles==4.3.1
edx-toggles==5.0.0
# via
# -r requirements/edx/base.in
# edx-completion
@@ -737,7 +737,7 @@ openedx-filters==0.6.2
# via
# -r requirements/edx/base.in
# lti-consumer-xblock
ora2==4.3.0
ora2==4.4.0
# via -r requirements/edx/base.in
packaging==21.3
# via

View File

@@ -646,7 +646,7 @@ edx-tincan-py35==1.0.0
# via
# -r requirements/edx/testing.txt
# edx-enterprise
edx-toggles==4.3.1
edx-toggles==5.0.0
# via
# -r requirements/edx/testing.txt
# edx-completion
@@ -966,7 +966,7 @@ openedx-filters==0.6.2
# via
# -r requirements/edx/testing.txt
# lti-consumer-xblock
ora2==4.3.0
ora2==4.4.0
# via -r requirements/edx/testing.txt
packaging==21.3
# via

View File

@@ -628,7 +628,7 @@ edx-tincan-py35==1.0.0
# via
# -r requirements/edx/base.txt
# edx-enterprise
edx-toggles==4.3.1
edx-toggles==5.0.0
# via
# -r requirements/edx/base.txt
# edx-completion
@@ -917,7 +917,7 @@ openedx-filters==0.6.2
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
ora2==4.3.0
ora2==4.4.0
# via -r requirements/edx/base.txt
packaging==21.3
# via