Move waffle_utils/testutils.py to edx-toggles
This commit is contained in:
@@ -1,68 +0,0 @@
|
||||
"""
|
||||
Tests for waffle utils test utilities.
|
||||
"""
|
||||
|
||||
|
||||
import crum
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from edx_django_utils.cache import RequestCache
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from .. import CourseWaffleFlag, WaffleFlagNamespace
|
||||
from ..testutils import override_waffle_flag
|
||||
|
||||
|
||||
class OverrideWaffleFlagTests(TestCase):
|
||||
"""
|
||||
Tests for the override_waffle_flag decorator/context manager.
|
||||
"""
|
||||
|
||||
NAMESPACE_NAME = "test_namespace"
|
||||
FLAG_NAME = "test_flag"
|
||||
NAMESPACED_FLAG_NAME = NAMESPACE_NAME + "." + FLAG_NAME
|
||||
|
||||
TEST_COURSE_KEY = CourseKey.from_string("edX/DemoX/Demo_Course")
|
||||
TEST_NAMESPACE = WaffleFlagNamespace(NAMESPACE_NAME)
|
||||
TEST_COURSE_FLAG = CourseWaffleFlag(TEST_NAMESPACE, FLAG_NAME, __name__)
|
||||
|
||||
def setUp(self):
|
||||
super(OverrideWaffleFlagTests, self).setUp()
|
||||
request = RequestFactory().request()
|
||||
self.addCleanup(crum.set_current_request, None)
|
||||
crum.set_current_request(request)
|
||||
RequestCache.clear_all_namespaces()
|
||||
|
||||
@override_waffle_flag(TEST_COURSE_FLAG, True)
|
||||
def assert_decorator_activates_flag(self):
|
||||
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
|
||||
def test_override_waffle_flag_pre_cached(self):
|
||||
# checks and caches the is_enabled value
|
||||
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
flag_cache = self.TEST_COURSE_FLAG.waffle_namespace._cached_flags
|
||||
assert self.NAMESPACED_FLAG_NAME in flag_cache
|
||||
|
||||
self.assert_decorator_activates_flag()
|
||||
|
||||
# test cached flag is restored
|
||||
assert self.NAMESPACED_FLAG_NAME in flag_cache
|
||||
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
|
||||
def test_override_waffle_flag_not_pre_cached(self):
|
||||
# check that the flag is not yet cached
|
||||
flag_cache = self.TEST_COURSE_FLAG.waffle_namespace._cached_flags
|
||||
assert self.NAMESPACED_FLAG_NAME not in flag_cache
|
||||
|
||||
self.assert_decorator_activates_flag()
|
||||
|
||||
# test cache is removed when no longer using decorator/context manager
|
||||
assert self.NAMESPACED_FLAG_NAME not in flag_cache
|
||||
|
||||
def test_override_waffle_flag_as_context_manager(self):
|
||||
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
|
||||
with override_waffle_flag(self.TEST_COURSE_FLAG, True):
|
||||
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
|
||||
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
|
||||
@@ -2,66 +2,17 @@
|
||||
Test utilities for waffle utilities.
|
||||
"""
|
||||
|
||||
|
||||
from waffle.testutils import override_flag
|
||||
# Import from edx-toggles to preserve import paths
|
||||
# pylint: disable=unused-import
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
|
||||
# Can be used with FilteredQueryCountMixin.assertNumQueries() to blacklist
|
||||
# waffle tables. For example:
|
||||
# QUERY_COUNT_TABLE_BLACKLIST = WAFFLE_TABLES
|
||||
# with self.assertNumQueries(6, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
WAFFLE_TABLES = ['waffle_utils_waffleflagcourseoverridemodel', 'waffle_flag', 'waffle_switch', 'waffle_sample']
|
||||
|
||||
|
||||
class override_waffle_flag(override_flag):
|
||||
"""
|
||||
override_waffle_flag is a contextmanager for easier testing of flags.
|
||||
|
||||
It accepts two parameters, the flag itself and its intended state. Example
|
||||
usage::
|
||||
|
||||
with override_waffle_flag(SOME_COURSE_FLAG, active=True):
|
||||
...
|
||||
|
||||
If the flag already exists, its value will be changed inside the context
|
||||
block, then restored to the original value. If the flag does not exist
|
||||
before entering the context, it is created, then removed at the end of the
|
||||
block.
|
||||
|
||||
It can also act as a decorator::
|
||||
|
||||
@override_waffle_flag(SOME_COURSE_FLAG, active=True)
|
||||
def test_happy_mode_enabled():
|
||||
...
|
||||
"""
|
||||
_cached_value = None
|
||||
|
||||
def __init__(self, flag, active):
|
||||
"""
|
||||
|
||||
Args:
|
||||
flag (WaffleFlag): The namespaced cached waffle flag.
|
||||
active (Boolean): The value to which the flag will be set.
|
||||
"""
|
||||
self.flag = flag
|
||||
waffle_namespace = flag.waffle_namespace
|
||||
name = waffle_namespace._namespaced_name(flag.flag_name) # pylint: disable=protected-access
|
||||
super(override_waffle_flag, self).__init__(name, active)
|
||||
|
||||
def __enter__(self):
|
||||
super(override_waffle_flag, self).__enter__()
|
||||
|
||||
# pylint: disable=protected-access
|
||||
# Store values that have been cached on the flag
|
||||
self._cached_value = self.flag.waffle_namespace._cached_flags.get(self.name)
|
||||
self.flag.waffle_namespace._cached_flags[self.name] = self.active
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
super(override_waffle_flag, self).__exit__(exc_type, exc_val, exc_tb)
|
||||
|
||||
# pylint: disable=protected-access
|
||||
# Restore the cached values
|
||||
waffle_namespace = self.flag.waffle_namespace
|
||||
waffle_namespace._cached_flags.pop(self.name, None)
|
||||
|
||||
if self._cached_value is not None:
|
||||
waffle_namespace._cached_flags[self.name] = self._cached_value
|
||||
WAFFLE_TABLES = [
|
||||
"waffle_utils_waffleflagcourseoverridemodel",
|
||||
"waffle_flag",
|
||||
"waffle_switch",
|
||||
"waffle_sample",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user