Files
edx-platform/xmodule/tests/test_util_keys.py
Kyle D. McCormick e8b60aef60 fix: move BlockKey and derived_key to avoid cyclical import
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.
2024-01-16 09:37:40 -05:00

46 lines
1.2 KiB
Python

"""
Tests for xmodule/util/keys.py
"""
import ddt
from unittest import TestCase
from unittest.mock import Mock
from opaque_keys.edx.locator import BlockUsageLocator
from opaque_keys.edx.keys import CourseKey
from xmodule.util.keys import BlockKey, derive_key
mock_block = Mock()
mock_block.id = CourseKey.from_string('course-v1:Beeper+B33P+BOOP')
derived_key_scenarios = [
{
'source': BlockUsageLocator.from_string(
'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations'
),
'parent': mock_block,
'expected': BlockKey('chapter', '5793ec64e25ed870a7dd'),
},
{
'source': BlockUsageLocator.from_string(
'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations'
),
'parent': BlockKey('chapter', 'thingy'),
'expected': BlockKey('chapter', '599792a5622d85aa41e6'),
}
]
@ddt.ddt
class TestDeriveKey(TestCase):
"""
Test reproducible block ID generation.
"""
@ddt.data(*derived_key_scenarios)
@ddt.unpack
def test_derive_key(self, source, parent, expected):
"""
Test that derive_key returns the expected value.
"""
assert derive_key(source, parent) == expected