Files
edx-platform/xmodule/tests/test_randomize_block.py
Kyle McCormick 834cb9482d refactor: rename ModuleStore runtimes now that XModules are gone (#35523)
* Consolidates and renames the runtime used as a base for all the others:
  * Before: `xmodule.x_module:DescriptorSystem` and
            `xmodule.mako_block:MakoDescriptorSystem`.
  * After:  `xmodule.x_module:ModuleStoreRuntime`.

* Co-locates and renames the runtimes for importing course OLX:
  * Before: `xmodule.x_module:XMLParsingSystem` and
            `xmodule.modulestore.xml:ImportSystem`.
  * After:  `xmodule.modulestore.xml:XMLParsingModuleStoreRuntime` and
            `xmodule.modulestore.xml:XMLImportingModuleStoreRuntime`.
  * Note: I would have liked to consolidate these, but it would have
          involved nontrivial test refactoring.

* Renames the stub Old Mongo runtime:
  * Before: `xmodule.modulestore.mongo.base:CachingDescriptorSystem`.
  * After: `xmodule.modulestore.mongo.base:OldModuleStoreRuntime`.

* Renames the Split Mongo runtime, the which is what runs courses in LMS and CMS:
  * Before: `xmodule.modulestore.split_mongo.caching_descriptor_system:CachingDescriptorSystem`.
  * After: `xmodule.modulestore.split_mongo.runtime:SplitModuleStoreRuntime`.

* Renames some of the dummy runtimes used only in unit tests.
2025-10-29 15:46:07 -04:00

116 lines
4.5 KiB
Python

"""
Test cases covering workflows and behaviors for the Randomize XModule
"""
from unittest.mock import Mock
from fs.memoryfs import MemoryFS
from lxml import etree
from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.utils import MixedSplitTestCase
from xmodule.randomize_block import RandomizeBlock
from xmodule.tests import prepare_block_runtime
from .test_course_block import DummyModuleStoreRuntime
class RandomizeBlockTest(MixedSplitTestCase):
"""
Base class for tests of RandomizeBlock (randomize_block.py)
"""
maxDiff = None
def setUp(self):
super().setUp()
self.course = CourseFactory.create(modulestore=self.store)
self.chapter = self.make_block("chapter", self.course)
self.sequential = self.make_block("sequential", self.chapter)
self.vertical = self.make_block("vertical", self.sequential)
self.randomize_block = self.make_block(
"randomize",
self.vertical,
display_name="Hello Randomize",
)
self.child_blocks = [
self.make_block("html", self.randomize_block, display_name=f"Hello HTML {i}")
for i in range(1, 4)
]
def _bind_module_system(self, block, user_id):
"""
Bind module system to block so we can access student-specific data.
"""
user = Mock(name='get_test_system.user', id=user_id, is_staff=False)
prepare_block_runtime(block.runtime, course_id=block.location.course_key, user=user)
def test_xml_export_import_cycle(self):
"""
Test the export-import cycle.
"""
randomize_block = self.store.get_item(self.randomize_block.location)
expected_olx = (
'<randomize display_name="{block.display_name}">\n'
' <html url_name="{block.children[0].block_id}"/>\n'
' <html url_name="{block.children[1].block_id}"/>\n'
' <html url_name="{block.children[2].block_id}"/>\n'
'</randomize>\n'
).format(
block=randomize_block,
)
export_fs = MemoryFS()
# Set the virtual FS to export the olx to.
randomize_block.runtime.export_fs = export_fs # pylint: disable=protected-access
# Export the olx.
node = etree.Element("unknown_root")
randomize_block.add_xml_to_node(node)
# Read it back
with export_fs.open('{dir}/{file_name}.xml'.format(
dir=randomize_block.scope_ids.usage_id.block_type,
file_name=randomize_block.scope_ids.usage_id.block_id
)) as f:
exported_olx = f.read()
# And compare.
assert exported_olx == expected_olx
runtime = DummyModuleStoreRuntime(load_error_blocks=True, course_id=randomize_block.location.course_key)
runtime.resources_fs = export_fs
# Now import it.
olx_element = etree.fromstring(exported_olx)
imported_randomize_block = RandomizeBlock.parse_xml(olx_element, runtime, None)
# Check the new XBlock has the same properties as the old one.
assert imported_randomize_block.display_name == randomize_block.display_name
assert len(imported_randomize_block.children) == 3
assert imported_randomize_block.children == randomize_block.children
def test_children_seen_by_a_user(self):
"""
Test that each student sees only one block as a child of the LibraryContent block.
"""
randomize_block = self.store.get_item(self.randomize_block.location)
self._bind_module_system(randomize_block, 3)
# Make sure the runtime knows that the block's children vary per-user:
assert randomize_block.has_dynamic_children()
assert len(randomize_block.children) == 3
# Check how many children each user will see:
assert len(randomize_block.get_child_blocks()) == 1
assert randomize_block.get_child_blocks()[0].display_name == 'Hello HTML 1'
# Check that get_content_titles() doesn't return titles for hidden/unused children
# get_content_titles() is not overridden in RandomizeBlock so titles of the 3 children are returned.
assert len(randomize_block.get_content_titles()) == 3
# Bind to another user and check a different child block is displayed to user.
randomize_block = self.store.get_item(self.randomize_block.location)
self._bind_module_system(randomize_block, 1)
assert randomize_block.get_child_blocks()[0].display_name == 'Hello HTML 2'