Commit b6b79282 by Christina Roberts Committed by GitHub

Merge pull request #12864 from edx/christina/disable-xblocks

Move disabling of XBlocks to new XBlockConfiguration model
parents c25dd2ee 8980d1ab
...@@ -42,16 +42,6 @@ class XBlockDisableConfig(ConfigurationModel): ...@@ -42,16 +42,6 @@ class XBlockDisableConfig(ConfigurationModel):
return block_type in config.disabled_blocks.split() return block_type in config.disabled_blocks.split()
@classmethod @classmethod
def disabled_block_types(cls):
""" Return list of disabled xblock types. """
config = cls.current()
if not config.enabled:
return ()
return config.disabled_blocks.split()
@classmethod
def disabled_create_block_types(cls): def disabled_create_block_types(cls):
""" Return list of deprecated XBlock types. Merges types in settings file and field. """ """ Return list of deprecated XBlock types. Merges types in settings file and field. """
......
...@@ -19,6 +19,7 @@ from django.conf import settings ...@@ -19,6 +19,7 @@ from django.conf import settings
if not settings.configured: if not settings.configured:
settings.configure() settings.configure()
from django.db.models.signals import post_save
from django.core.cache import caches, InvalidCacheBackendError from django.core.cache import caches, InvalidCacheBackendError
import django.dispatch import django.dispatch
import django.utils import django.utils
...@@ -49,9 +50,11 @@ except ImportError: ...@@ -49,9 +50,11 @@ except ImportError:
HAS_USER_SERVICE = False HAS_USER_SERVICE = False
try: try:
from xblock_django.models import XBlockDisableConfig from xblock_django.api import disabled_xblocks
from xblock_django.models import XBlockConfiguration
except ImportError: except ImportError:
XBlockDisableConfig = None disabled_xblocks = None
XBlockConfiguration = None
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
ASSET_IGNORE_REGEX = getattr(settings, "ASSET_IGNORE_REGEX", r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)") ASSET_IGNORE_REGEX = getattr(settings, "ASSET_IGNORE_REGEX", r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)")
...@@ -188,8 +191,8 @@ def create_modulestore_instance( ...@@ -188,8 +191,8 @@ def create_modulestore_instance(
if 'read_preference' in doc_store_config: if 'read_preference' in doc_store_config:
doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference']) doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference'])
if XBlockDisableConfig and settings.FEATURES.get('ENABLE_DISABLING_XBLOCK_TYPES', False): if disabled_xblocks:
disabled_xblock_types = XBlockDisableConfig.disabled_block_types() disabled_xblock_types = [block.name for block in disabled_xblocks()]
else: else:
disabled_xblock_types = () disabled_xblock_types = ()
...@@ -252,6 +255,17 @@ def clear_existing_modulestores(): ...@@ -252,6 +255,17 @@ def clear_existing_modulestores():
_MIXED_MODULESTORE = None _MIXED_MODULESTORE = None
if XBlockConfiguration and disabled_xblocks:
@django.dispatch.receiver(post_save, sender=XBlockConfiguration)
def reset_disabled_xblocks(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
If XBlockConfiguation and disabled_xblocks are available, register a signal handler
to update disabled_xblocks on model changes.
"""
disabled_xblock_types = [block.name for block in disabled_xblocks()]
modulestore().disabled_xblock_types = disabled_xblock_types
class ModuleI18nService(object): class ModuleI18nService(object):
""" """
Implement the XBlock runtime "i18n" service. Implement the XBlock runtime "i18n" service.
......
...@@ -185,6 +185,25 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase): ...@@ -185,6 +185,25 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
self.mappings[course_key] = store self.mappings[course_key] = store
self.modulestores.append(store) self.modulestores.append(store)
@property
def disabled_xblock_types(self):
"""
Returns the list of disabled xblock types.
"""
return None if not hasattr(self, "_disabled_xblock_types") else self._disabled_xblock_types
@disabled_xblock_types.setter
def disabled_xblock_types(self, value):
"""
Sets the list of disabled xblock types, and propagates down
to child modulestores if available.
"""
self._disabled_xblock_types = value # pylint: disable=attribute-defined-outside-init
if hasattr(self, 'modulestores'):
for store in self.modulestores:
store.disabled_xblock_types = value
def _clean_locator_for_mapping(self, locator): def _clean_locator_for_mapping(self, locator):
""" """
In order for mapping to work, the locator must be minimal--no version, no branch-- In order for mapping to work, the locator must be minimal--no version, no branch--
......
...@@ -59,6 +59,7 @@ from openedx.core.djangoapps.credit.api import ( ...@@ -59,6 +59,7 @@ from openedx.core.djangoapps.credit.api import (
set_credit_requirements, set_credit_requirements,
set_credit_requirement_status set_credit_requirement_status
) )
from xblock_django.models import XBlockConfiguration
from edx_proctoring.api import ( from edx_proctoring.api import (
create_exam, create_exam,
...@@ -2232,7 +2233,22 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase): ...@@ -2232,7 +2233,22 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase):
def test_get_item(self, default_ms): def test_get_item(self, default_ms):
with self.store.default_store(default_ms): with self.store.default_store(default_ms):
course = CourseFactory() course = CourseFactory()
for block_type in ('video',): self._verify_descriptor('video', course, 'RawDescriptorWithMixins')
item = ItemFactory(category=block_type, parent=course)
item = self.store.get_item(item.scope_ids.usage_id) @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
self.assertEqual(item.__class__.__name__, 'RawDescriptorWithMixins') def test_dynamic_updates(self, default_ms):
"""Tests that the list of disabled xblocks can dynamically update."""
with self.store.default_store(default_ms):
course = CourseFactory()
self._verify_descriptor('problem', course, 'CapaDescriptorWithMixins')
XBlockConfiguration(name='problem', enabled=False).save()
self._verify_descriptor('problem', course, 'RawDescriptorWithMixins')
def _verify_descriptor(self, category, course, descriptor):
"""
Helper method that gets an item with the specified category from the
modulestore and verifies that it has the expected descriptor name.
"""
item = ItemFactory(category=category, parent=course)
item = self.store.get_item(item.scope_ids.usage_id)
self.assertEqual(item.__class__.__name__, descriptor)
...@@ -340,9 +340,6 @@ FEATURES = { ...@@ -340,9 +340,6 @@ FEATURES = {
# Enable OpenBadge support. See the BADGR_* settings later in this file. # Enable OpenBadge support. See the BADGR_* settings later in this file.
'ENABLE_OPENBADGES': False, 'ENABLE_OPENBADGES': False,
# The block types to disable need to be specified in "x block disable config" in django admin.
'ENABLE_DISABLING_XBLOCK_TYPES': True,
# Enable LTI Provider feature. # Enable LTI Provider feature.
'ENABLE_LTI_PROVIDER': False, 'ENABLE_LTI_PROVIDER': False,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment