Fix issues with overrides on duplicated RCBs.
This commit is contained in:
@@ -3,6 +3,7 @@ Content library unit tests that require the CMS runtime.
|
||||
"""
|
||||
from contentstore.tests.utils import AjaxEnabledTestClient, parse_json
|
||||
from contentstore.utils import reverse_url, reverse_usage_url, reverse_library_url
|
||||
from contentstore.views.item import _duplicate_item
|
||||
from contentstore.views.preview import _load_preview_module
|
||||
from contentstore.views.tests.test_library import LIBRARY_REST_URL
|
||||
import ddt
|
||||
@@ -726,6 +727,7 @@ class TestLibraryAccess(SignalDisconnectTestMixin, LibraryTestCase):
|
||||
self.assertEqual(len(lc_block.children), 1 if expected_result else 0)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestOverrides(LibraryTestCase):
|
||||
"""
|
||||
Test that overriding block Scope.settings fields from a library in a specific course works
|
||||
@@ -822,7 +824,8 @@ class TestOverrides(LibraryTestCase):
|
||||
self.assertEqual(self.problem.definition_locator.definition_id, definition_id)
|
||||
self.assertEqual(self.problem_in_course.definition_locator.definition_id, definition_id)
|
||||
|
||||
def test_persistent_overrides(self):
|
||||
@ddt.data(False, True)
|
||||
def test_persistent_overrides(self, duplicate):
|
||||
"""
|
||||
Test that when we override Scope.settings values in a course,
|
||||
the override values persist even when the block is refreshed
|
||||
@@ -834,7 +837,14 @@ class TestOverrides(LibraryTestCase):
|
||||
self.problem_in_course.weight = new_weight
|
||||
|
||||
modulestore().update_item(self.problem_in_course, self.user.id)
|
||||
self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
|
||||
if duplicate:
|
||||
# Check that this also works when the RCB is duplicated.
|
||||
self.lc_block = modulestore().get_item(
|
||||
_duplicate_item(self.course.location, self.lc_block.location, self.user)
|
||||
)
|
||||
self.problem_in_course = modulestore().get_item(self.lc_block.children[0])
|
||||
else:
|
||||
self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
|
||||
self.assertEqual(self.problem_in_course.display_name, new_display_name)
|
||||
self.assertEqual(self.problem_in_course.weight, new_weight)
|
||||
|
||||
|
||||
@@ -593,17 +593,27 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_
|
||||
runtime=source_item.runtime,
|
||||
)
|
||||
|
||||
handle_children = True
|
||||
handle_parenting = True
|
||||
|
||||
if hasattr(dest_module, 'studio_post_duplicate'):
|
||||
# Allow an XBlock to do anything fancy it may need to when duplicated from another block.
|
||||
# These blocks may handle their own children or parenting if needed. Let them return booleans to
|
||||
# let us know if we need to handle these or not.
|
||||
handle_children, handle_parenting = dest_module.studio_post_duplicate(store, parent_usage_key, source_item)
|
||||
|
||||
# Children are not automatically copied over (and not all xblocks have a 'children' attribute).
|
||||
# Because DAGs are not fully supported, we need to actually duplicate each child as well.
|
||||
if source_item.has_children:
|
||||
dest_module.children = []
|
||||
if source_item.has_children and handle_children:
|
||||
dest_module.children = dest_module.children or []
|
||||
for child in source_item.children:
|
||||
dupe = _duplicate_item(dest_module.location, child, user=user)
|
||||
if dupe not in dest_module.children: # _duplicate_item may add the child for us.
|
||||
dest_module.children.append(dupe)
|
||||
store.update_item(dest_module, user.id)
|
||||
|
||||
if 'detached' not in source_item.runtime.load_block_type(category)._class_tags:
|
||||
# pylint: disable=protected-access
|
||||
if ('detached' not in source_item.runtime.load_block_type(category)._class_tags) and handle_parenting:
|
||||
parent = store.get_item(parent_usage_key)
|
||||
# If source was already a child of the parent, add duplicate immediately afterward.
|
||||
# Otherwise, add child to end.
|
||||
|
||||
Reference in New Issue
Block a user