After we merged this PR: https://github.com/openedx/edx-platform/pull/33920 this error began popping up in logs: Unable to load XBlock 'staffgradedxblock' .... ImportError: cannot import name 'get_course_blocks' from partially initialized module 'lms.djangoapps.course_blocks.api' (most likely due to a circular import) ... The root cause was the new imports of `derived_key` and `BlockKey` into xmodule/library_content_block.py. Those new imports come from xmodule/modulestore/store_utilities.py, which runs `XBlock.load_classes()` at the module level, which fails because we are still in the process of loading xmodule/library_content_block. As a solution, we move both `derived_key` and `BlockKey` to xmodule/util/keys.py. We could potentially move that file to opaque-keys eventually, depending on how well we think that those concepts generalize. Also: * We rename the function from derived_key to derive_key, as functions should be verbs. * We combine the first to parameters of derive_key (a source ContextKey and a source BlockKey) into a single parameter (a source UsageKey). In my opinion, this makes the function call easier to understand.
84 lines
2.0 KiB
Python
84 lines
2.0 KiB
Python
"""
|
|
Tests for store_utilities.py
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import Mock
|
|
|
|
import ddt
|
|
|
|
from xmodule.modulestore.store_utilities import draft_node_constructor, get_draft_subtree_roots
|
|
|
|
|
|
@ddt.ddt
|
|
class TestUtils(unittest.TestCase):
|
|
"""
|
|
Tests for store_utilities
|
|
|
|
ASCII trees for ONLY_ROOTS and SOME_TREES:
|
|
|
|
ONLY_ROOTS:
|
|
1)
|
|
vertical (not draft)
|
|
|
|
|
url1
|
|
|
|
2)
|
|
sequential (not draft)
|
|
|
|
|
url2
|
|
|
|
SOME_TREES:
|
|
|
|
1)
|
|
sequential_1 (not draft)
|
|
|
|
|
vertical_1
|
|
/ \
|
|
/ \
|
|
child_1 child_2
|
|
|
|
|
|
2)
|
|
great_grandparent_vertical (not draft)
|
|
|
|
|
grandparent_vertical
|
|
|
|
|
vertical_2
|
|
/ \
|
|
/ \
|
|
child_3 child_4
|
|
"""
|
|
|
|
ONLY_ROOTS = [
|
|
('url1', 'vertical'),
|
|
('url2', 'sequential'),
|
|
]
|
|
ONLY_ROOTS_URLS = ['url1', 'url2']
|
|
|
|
SOME_TREES = [
|
|
('child_1', 'vertical_1'),
|
|
('child_2', 'vertical_1'),
|
|
('vertical_1', 'sequential_1'),
|
|
|
|
('child_3', 'vertical_2'),
|
|
('child_4', 'vertical_2'),
|
|
('vertical_2', 'grandparent_vertical'),
|
|
('grandparent_vertical', 'great_grandparent_vertical'),
|
|
]
|
|
SOME_TREES_ROOTS_URLS = ['vertical_1', 'grandparent_vertical']
|
|
|
|
@ddt.data(
|
|
(ONLY_ROOTS, ONLY_ROOTS_URLS),
|
|
(SOME_TREES, SOME_TREES_ROOTS_URLS),
|
|
)
|
|
@ddt.unpack
|
|
def test_get_draft_subtree_roots(self, node_arguments_list, expected_roots_urls):
|
|
"""tests for get_draft_subtree_roots"""
|
|
block_nodes = []
|
|
for node_args in node_arguments_list:
|
|
block_nodes.append(draft_node_constructor(Mock(), node_args[0], node_args[1]))
|
|
subtree_roots_urls = [root.url for root in get_draft_subtree_roots(block_nodes)]
|
|
# check that we return the expected urls
|
|
assert set(subtree_roots_urls) == set(expected_roots_urls)
|