test: fix test cases and lint issues

This commit is contained in:
Kaustav Banerjee
2023-02-05 12:00:29 +05:30
committed by Agrendalath
parent 20ed3d64ec
commit d0fa2d65e3
30 changed files with 442 additions and 313 deletions

View File

@@ -70,7 +70,7 @@ class TestXBlockI18nService(ModuleStoreTestCase):
self.course = CourseFactory.create()
self.field_data = mock.Mock()
self.descriptor = BlockFactory(category="pure", parent=self.course)
self.runtime = _preview_module_system(
_preview_module_system(
self.request,
self.descriptor,
self.field_data,
@@ -81,7 +81,7 @@ class TestXBlockI18nService(ModuleStoreTestCase):
"""
return the block i18n service.
"""
i18n_service = self.runtime.service(descriptor, 'i18n')
i18n_service = self.descriptor.runtime.service(descriptor, 'i18n')
self.assertIsNotNone(i18n_service)
self.assertIsInstance(i18n_service, XBlockI18nService)
return i18n_service
@@ -171,7 +171,7 @@ class TestXBlockI18nService(ModuleStoreTestCase):
"""
Test: i18n service should be callable in studio.
"""
self.assertTrue(callable(self.runtime._services.get('i18n'))) # pylint: disable=protected-access
self.assertTrue(callable(self.descriptor.runtime._services.get('i18n'))) # pylint: disable=protected-access
class InternationalizationTest(ModuleStoreTestCase):

View File

@@ -299,7 +299,7 @@ def load_services_for_studio(runtime, user):
(i.e. whenever we're not loading preview module system.) This is required to make information
about the current user (especially permissions) available via services as needed.
"""
services={
services = {
"user": DjangoXBlockUserService(user),
"studio_user_permissions": StudioPermissionsService(user),
"mako": MakoService(),
@@ -309,7 +309,7 @@ def load_services_for_studio(runtime, user):
"library_tools": LibraryToolsService(modulestore(), user.id)
}
runtime._services.update(services)
runtime._services.update(services) # lint-amnesty, pylint: disable=protected-access
@require_http_methods("GET")

View File

@@ -93,7 +93,7 @@ def preview_handler(request, usage_key_string, handler, suffix=''):
return webob_to_django_response(resp)
def handler_url(block, handler_name, suffix='', query='', thirdparty=False):
def handler_url(block, handler_name, suffix='', query='', thirdparty=False): # lint-amnesty, pylint: disable=unused-argument
"""
Handler URL function for Preview
"""
@@ -120,14 +120,17 @@ def preview_applicable_aside_types(block, applicable_aside_types=None):
]
def render_child_placeholder(block, view_name, context, wrap_xblock=None):
def render_child_placeholder(block, view_name, context, wrap_block=None):
"""
Renders a placeholder XBlock.
"""
return wrap_xblock(block, view_name, Fragment(), context)
return wrap_block(block, view_name, Fragment(), context)
def preview_layout_asides(block, context, frag, view_name, aside_frag_fns, wrap_aside=None):
"""
Custom layout of asides for preview
"""
position_for_asides = '<!-- footer for xblock_aside -->'
result = Fragment()
result.add_fragment_resources(frag)
@@ -200,7 +203,7 @@ def _preview_module_system(request, descriptor, field_data):
else:
preview_anonymous_user_id = anonymous_id_for_user(request.user, course_id)
services={
services = {
"field-data": field_data,
"i18n": XBlockI18nService,
'mako': mako_service,
@@ -217,7 +220,7 @@ def _preview_module_system(request, descriptor, field_data):
'replace_urls': replace_url_service
}
descriptor.runtime.get_block_for_descriptor = partial(_load_preview_block, request),
descriptor.runtime.get_block_for_descriptor = partial(_load_preview_block, request)
descriptor.runtime.mixins = settings.XBLOCK_MIXINS
# Set up functions to modify the fragment produced by student_view
@@ -232,11 +235,11 @@ def _preview_module_system(request, descriptor, field_data):
descriptor.runtime.applicable_aside_types_override = preview_applicable_aside_types
descriptor.runtime.render_child_placeholder = partial(
render_child_placeholder,
wrap_xblock = descriptor.runtime.wrap_xblock
wrap_block=descriptor.runtime.wrap_xblock
)
descriptor.runtime.layout_asides_override = partial(
preview_layout_asides,
wrap_aside = descriptor.runtime.wrap_aside
wrap_aside=descriptor.runtime.wrap_aside
)

View File

@@ -214,12 +214,12 @@ class StudioXBlockServiceBindingTest(ModuleStoreTestCase):
Tests that the 'user' and 'i18n' services are provided by the Studio runtime.
"""
descriptor = BlockFactory(category="pure", parent=self.course)
runtime = _preview_module_system(
_preview_module_system(
self.request,
descriptor,
self.field_data,
)
service = runtime.service(descriptor, expected_service)
service = descriptor.runtime.service(descriptor, expected_service)
self.assertIsNotNone(service)
@@ -245,15 +245,16 @@ class CmsModuleSystemShimTest(ModuleStoreTestCase):
self.descriptor = BlockFactory(category="video", parent=course)
self.field_data = mock.Mock()
self.contentstore = contentstore()
self.runtime = _preview_module_system(
self.descriptor = BlockFactory(category="problem", parent=course)
_preview_module_system(
self.request,
descriptor=BlockFactory(category="problem", parent=course),
descriptor=self.descriptor,
field_data=mock.Mock(),
)
self.course = self.store.get_item(course.location)
def test_get_user_role(self):
assert self.runtime.get_user_role() == 'staff'
assert self.descriptor.runtime.get_user_role() == 'staff'
@XBlock.register_temp_plugin(PureXBlock, identifier='pure')
def test_render_template(self):
@@ -263,10 +264,10 @@ class CmsModuleSystemShimTest(ModuleStoreTestCase):
@override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+LmsModuleShimTest\+2021_Fall'])
def test_can_execute_unsafe_code(self):
assert self.runtime.can_execute_unsafe_code()
assert self.descriptor.runtime.can_execute_unsafe_code()
def test_cannot_execute_unsafe_code(self):
assert not self.runtime.can_execute_unsafe_code()
assert not self.descriptor.runtime.can_execute_unsafe_code()
@override_settings(PYTHON_LIB_FILENAME=PYTHON_LIB_FILENAME)
def test_get_python_lib_zip(self):
@@ -276,7 +277,7 @@ class CmsModuleSystemShimTest(ModuleStoreTestCase):
source_file=self.PYTHON_LIB_SOURCE_FILE,
target_filename=self.PYTHON_LIB_FILENAME,
)
assert self.runtime.get_python_lib_zip() == zipfile
assert self.descriptor.runtime.get_python_lib_zip() == zipfile
def test_no_get_python_lib_zip(self):
zipfile = upload_file_to_course(
@@ -285,38 +286,40 @@ class CmsModuleSystemShimTest(ModuleStoreTestCase):
source_file=self.PYTHON_LIB_SOURCE_FILE,
target_filename=self.PYTHON_LIB_FILENAME,
)
assert self.runtime.get_python_lib_zip() is None
assert self.descriptor.runtime.get_python_lib_zip() is None
def test_cache(self):
assert hasattr(self.runtime.cache, 'get')
assert hasattr(self.runtime.cache, 'set')
assert hasattr(self.descriptor.runtime.cache, 'get')
assert hasattr(self.descriptor.runtime.cache, 'set')
def test_replace_urls(self):
html = '<a href="/static/id">'
assert self.runtime.replace_urls(html) == \
assert self.descriptor.runtime.replace_urls(html) == \
static_replace.replace_static_urls(html, course_id=self.course.id)
def test_anonymous_user_id_preview(self):
assert self.runtime.anonymous_student_id == 'student'
assert self.descriptor.runtime.anonymous_student_id == 'student'
@override_waffle_flag(INDIVIDUALIZE_ANONYMOUS_USER_ID, active=True)
def test_anonymous_user_id_individual_per_student(self):
"""Test anonymous_user_id on a block which uses per-student anonymous IDs"""
# Create the runtime with the flag turned on.
runtime = _preview_module_system(
descriptor = BlockFactory(category="problem", parent=self.course)
_preview_module_system(
self.request,
descriptor=BlockFactory(category="problem", parent=self.course),
descriptor=descriptor,
field_data=mock.Mock(),
)
assert runtime.anonymous_student_id == '26262401c528d7c4a6bbeabe0455ec46'
assert descriptor.runtime.anonymous_student_id == '26262401c528d7c4a6bbeabe0455ec46'
@override_waffle_flag(INDIVIDUALIZE_ANONYMOUS_USER_ID, active=True)
def test_anonymous_user_id_individual_per_course(self):
"""Test anonymous_user_id on a block which uses per-course anonymous IDs"""
# Create the runtime with the flag turned on.
runtime = _preview_module_system(
descriptor = BlockFactory(category="lti", parent=self.course)
_preview_module_system(
self.request,
descriptor=BlockFactory(category="lti", parent=self.course),
descriptor=descriptor,
field_data=mock.Mock(),
)
assert runtime.anonymous_student_id == 'ad503f629b55c531fed2e45aa17a3368'
assert descriptor.runtime.anonymous_student_id == 'ad503f629b55c531fed2e45aa17a3368'

View File

@@ -587,7 +587,7 @@ def get_module_system_for_user(
store = modulestore()
services={
services = {
'fs': FSService(),
'field-data': field_data,
'mako': mako_service,
@@ -624,12 +624,10 @@ def get_module_system_for_user(
descriptor.runtime.get_block_for_descriptor = inner_get_block
# TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington)
descriptor.runtime.mixins = descriptor.runtime.mixologist._mixins
descriptor.runtime.mixins = descriptor.runtime.mixologist._mixins # lint-amnesty, pylint: disable=protected-access
descriptor.runtime.wrappers = block_wrappers
descriptor.runtime._runtime_services.update(services) # lint-amnesty, pylint: disable=protected-access
descriptor.runtime.request_token = request_token
descriptor.runtime.wrap_asides_override = lms_wrappers_aside
descriptor.runtime.applicable_aside_types_override = lms_applicable_aside_types

View File

@@ -33,7 +33,7 @@ from common.djangoapps.util.date_utils import strftime_localized_html
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_MODULESTORE, ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.tests import get_test_descriptor_system, get_test_system # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.tests import get_test_descriptor_system, get_test_system, prepare_block_runtime # lint-amnesty, pylint: disable=wrong-import-order
class BaseTestXmodule(ModuleStoreTestCase):
@@ -66,10 +66,12 @@ class BaseTestXmodule(ModuleStoreTestCase):
METADATA = {}
MODEL_DATA = {'data': '<some_module></some_module>'}
def new_module_runtime(self, **kwargs):
def new_module_runtime(self, runtime=None, **kwargs):
"""
Generate a new ModuleSystem that is minimally set up for testing
"""
if runtime:
return prepare_block_runtime(runtime, course_id=self.course.id, **kwargs)
return get_test_system(course_id=self.course.id, **kwargs)
def new_descriptor_runtime(self, **kwargs):
@@ -94,7 +96,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
if runtime_kwargs is None:
runtime_kwargs = {}
self.item_descriptor.xmodule_runtime = self.new_module_runtime(**runtime_kwargs)
self.new_module_runtime(runtime=self.item_descriptor.runtime, **runtime_kwargs)
self.item_url = str(self.item_descriptor.location)
@@ -148,6 +150,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
class XModuleRenderingTestBase(BaseTestXmodule): # lint-amnesty, pylint: disable=missing-class-docstring
# lint-amnesty, pylint: disable=arguments-differ
def new_module_runtime(self, **kwargs):
"""
Create a runtime that actually does html rendering

View File

@@ -37,7 +37,7 @@ from xblock.core import XBlock, XBlockAside # lint-amnesty, pylint: disable=wro
from xblock.exceptions import NoSuchServiceError
from xblock.field_data import FieldData # lint-amnesty, pylint: disable=wrong-import-order
from xblock.fields import ScopeIds # lint-amnesty, pylint: disable=wrong-import-order
from xblock.runtime import DictKeyValueStore, KvsFieldData, Runtime # lint-amnesty, pylint: disable=wrong-import-order
from xblock.runtime import DictKeyValueStore, KvsFieldData # lint-amnesty, pylint: disable=wrong-import-order
from xblock.test.tools import TestRuntime # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.capa.tests.response_xml_factory import OptionResponseXMLFactory # lint-amnesty, pylint: disable=reimported
@@ -58,7 +58,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory, Toy
from xmodule.modulestore.tests.test_asides import AsideTestType # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.services import RebindUserServiceError
from xmodule.video_block import VideoBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.x_module import STUDENT_VIEW, CombinedSystem # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.x_module import STUDENT_VIEW, DescriptorSystem # lint-amnesty, pylint: disable=wrong-import-order
from common.djangoapps import static_replace
from common.djangoapps.course_modes.models import CourseMode # lint-amnesty, pylint: disable=reimported
from common.djangoapps.student.tests.factories import GlobalStaffFactory
@@ -1894,9 +1894,10 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
location=location,
static_asset_path=None,
_runtime=Mock(
spec=Runtime,
spec=DescriptorSystem,
resources_fs=None,
mixologist=Mock(_mixins=(), name='mixologist'),
_services={},
name='runtime',
),
scope_ids=Mock(spec=ScopeIds),
@@ -1906,7 +1907,7 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
fields={},
days_early_for_beta=None,
)
descriptor.runtime = CombinedSystem(descriptor._runtime, None) # pylint: disable=protected-access
descriptor.runtime = DescriptorSystem(None, None, None)
# Use the xblock_class's bind_for_student method
descriptor.bind_for_student = partial(xblock_class.bind_for_student, descriptor)
@@ -1922,7 +1923,7 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
request_token='request_token',
course=self.course,
)
current_user = block.xmodule_runtime.service(block, 'user').get_current_user()
current_user = block.runtime.service(block, 'user').get_current_user()
return current_user.opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID)
@ddt.data(*PER_STUDENT_ANONYMIZED_XBLOCKS)
@@ -1976,7 +1977,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
@patch('xmodule.modulestore.mongo.base.CachingDescriptorSystem.applicable_aside_types',
lambda self, block: ['test_aside'])
@patch('lms.djangoapps.lms_xblock.runtime.LmsModuleSystem.applicable_aside_types',
@patch('xmodule.x_module.DescriptorSystem.applicable_aside_types',
lambda self, block: ['test_aside'])
def test_context_contains_aside_info(self, mock_tracker):
"""
@@ -2185,7 +2186,7 @@ class TestRebindBlock(TestSubmittingProblems):
# Bind the block to another student, which will remove "correct_map"
# from the block's _field_data_cache and _dirty_fields.
user2 = UserFactory.create()
block.bind_for_student(block.runtime, user2.id)
block.bind_for_student(user2.id)
# XBlock's save method assumes that if a field is in _dirty_fields,
# then it's also in _field_data_cache. If this assumption
@@ -2194,7 +2195,7 @@ class TestRebindBlock(TestSubmittingProblems):
# _field_data cache, but not _dirty_fields, when we bound
# this block to the second student. (TNL-2640)
user3 = UserFactory.create()
block.bind_for_student(block.runtime, user3.id)
block.bind_for_student(user3.id)
def test_rebind_noauth_block_to_user_not_anonymous(self):
"""
@@ -2263,13 +2264,13 @@ class TestEventPublishing(ModuleStoreTestCase, LoginEnrollmentTestCase):
class LMSXBlockServiceMixin(SharedModuleStoreTestCase):
"""
Helper class that initializes the LmsModuleSystem.
Helper class that initializes the runtime.
"""
def _prepare_runtime(self):
"""
Instantiate the LmsModuleSystem.
Instantiate the runtem.
"""
self.runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2333,7 +2334,7 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin):
"""
Tests that the 'user', 'i18n', and 'fs' services are provided by the LMS runtime.
"""
service = self.runtime.service(self.descriptor, expected_service)
service = self.descriptor.runtime.service(self.descriptor, expected_service)
assert service is not None
def test_beta_tester_fields_added(self):
@@ -2344,8 +2345,8 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin):
self._prepare_runtime()
# pylint: disable=no-member
assert not self.runtime.user_is_beta_tester
assert self.runtime.days_early_for_beta == 5
assert not self.descriptor.runtime.user_is_beta_tester
assert self.descriptor.runtime.days_early_for_beta == 5
def test_get_set_tag(self):
"""
@@ -2355,23 +2356,23 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin):
key = 'key1'
# test for when we haven't set the tag yet
tag = self.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key)
tag = self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key)
assert tag is None
# set the tag
set_value = 'value'
self.runtime.service(self.descriptor, 'user_tags').set_tag(scope, key, set_value)
tag = self.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key)
self.descriptor.runtime.service(self.descriptor, 'user_tags').set_tag(scope, key, set_value)
tag = self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key)
assert tag == set_value
# Try to set tag in wrong scope
with pytest.raises(ValueError):
self.runtime.service(self.descriptor, 'user_tags').set_tag('fake_scope', key, set_value)
self.descriptor.runtime.service(self.descriptor, 'user_tags').set_tag('fake_scope', key, set_value)
# Try to get tag in wrong scope
with pytest.raises(ValueError):
self.runtime.service(self.descriptor, 'user_tags').get_tag('fake_scope', key)
self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag('fake_scope', key)
@ddt.ddt
@@ -2381,23 +2382,23 @@ class TestBadgingService(LMSXBlockServiceMixin):
@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
def test_service_rendered(self):
self._prepare_runtime()
assert self.runtime.service(self.descriptor, 'badging')
assert self.descriptor.runtime.service(self.descriptor, 'badging')
def test_no_service_rendered(self):
with pytest.raises(NoSuchServiceError):
self.runtime.service(self.descriptor, 'badging')
self.descriptor.runtime.service(self.descriptor, 'badging')
@ddt.data(True, False)
@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
def test_course_badges_toggle(self, toggle):
self.course = CourseFactory.create(metadata={'issue_badges': toggle})
self._prepare_runtime()
assert self.runtime.service(self.descriptor, 'badging').course_badges_enabled is toggle
assert self.descriptor.runtime.service(self.descriptor, 'badging').course_badges_enabled is toggle
@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
def test_get_badge_class(self):
self._prepare_runtime()
badge_service = self.runtime.service(self.descriptor, 'badging')
badge_service = self.descriptor.runtime.service(self.descriptor, 'badging')
premade_badge_class = BadgeClassFactory.create()
# Ignore additional parameters. This class already exists.
# We should get back the first class we created, rather than a new one.
@@ -2421,7 +2422,7 @@ class TestI18nService(LMSXBlockServiceMixin):
"""
Test: module i18n service in LMS
"""
i18n_service = self.runtime.service(self.descriptor, 'i18n')
i18n_service = self.descriptor.runtime.service(self.descriptor, 'i18n')
assert i18n_service is not None
assert isinstance(i18n_service, XBlockI18nService)
@@ -2431,27 +2432,30 @@ class TestI18nService(LMSXBlockServiceMixin):
"""
self.descriptor.service_declaration = Mock(return_value=None)
with pytest.raises(NoSuchServiceError):
self.runtime.service(self.descriptor, 'i18n')
self.descriptor.runtime.service(self.descriptor, 'i18n')
def test_no_service_exception_(self):
"""
Test: NoSuchServiceError should be raised if i18n service is none.
"""
self.runtime._services['i18n'] = None # pylint: disable=protected-access
i18nService = self.descriptor.runtime._services['i18n'] # pylint: disable=protected-access
self.descriptor.runtime._runtime_services['i18n'] = None # pylint: disable=protected-access
self.descriptor.runtime._services['i18n'] = None # pylint: disable=protected-access
with pytest.raises(NoSuchServiceError):
self.runtime.service(self.descriptor, 'i18n')
self.descriptor.runtime.service(self.descriptor, 'i18n')
self.descriptor.runtime._services['i18n'] = i18nService # pylint: disable=protected-access
def test_i18n_service_callable(self):
"""
Test: _services dict should contain the callable i18n service in LMS.
"""
assert callable(self.runtime._services.get('i18n')) # pylint: disable=protected-access
assert callable(self.descriptor.runtime._services.get('i18n')) # pylint: disable=protected-access
def test_i18n_service_not_callable(self):
"""
Test: i18n service should not be callable in LMS after initialization.
"""
assert not callable(self.runtime.service(self.descriptor, 'i18n'))
assert not callable(self.descriptor.runtime.service(self.descriptor, 'i18n'))
class PureXBlockWithChildren(PureXBlock):
@@ -2666,7 +2670,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
self.track_function = Mock()
self.request_token = Mock()
self.contentstore = contentstore()
self.runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2686,11 +2690,11 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
"""
Tests that the deprecated attributes provided by the user service match expected values.
"""
assert getattr(self.runtime, attribute) == expected_value
assert getattr(self.descriptor.runtime, attribute) == expected_value
@patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True))
def test_user_is_staff(self):
runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2699,12 +2703,12 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
self.request_token,
course=self.course,
)
assert runtime.user_is_staff
assert runtime.get_user_role() == 'student'
assert self.descriptor.runtime.user_is_staff
assert self.descriptor.runtime.get_user_role() == 'student'
@patch('lms.djangoapps.courseware.block_render.get_user_role', Mock(return_value='instructor', autospec=True))
def test_get_user_role(self):
runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2713,17 +2717,17 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
self.request_token,
course=self.course,
)
assert runtime.get_user_role() == 'instructor'
assert self.descriptor.runtime.get_user_role() == 'instructor'
def test_anonymous_student_id(self):
assert self.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id)
assert self.descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id)
def test_anonymous_student_id_bug(self):
"""
Verifies that subsequent calls to get_module_system_for_user have no effect on each block runtime's
anonymous_student_id value.
"""
problem_runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.problem_descriptor,
@@ -2733,9 +2737,9 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
course=self.course,
)
# Ensure the problem block returns a per-user anonymous id
assert problem_runtime.anonymous_student_id == anonymous_id_for_user(self.user, None)
assert self.problem_descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None)
vertical_runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2745,13 +2749,13 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
course=self.course,
)
# Ensure the vertical block returns a per-course+user anonymous id
assert vertical_runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id)
assert self.descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id)
# Ensure the problem runtime's anonymous student ID is unchanged after the above call.
assert problem_runtime.anonymous_student_id == anonymous_id_for_user(self.user, None)
assert self.problem_descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None)
def test_user_service_with_anonymous_user(self):
runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
AnonymousUser(),
self.student_data,
self.descriptor,
@@ -2760,14 +2764,14 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
self.request_token,
course=self.course,
)
assert runtime.anonymous_student_id is None
assert runtime.seed == 0
assert runtime.user_id is None
assert not runtime.user_is_staff
assert not runtime.get_user_role()
assert self.descriptor.runtime.anonymous_student_id is None
assert self.descriptor.runtime.seed == 0
assert self.descriptor.runtime.user_id is None
assert not self.descriptor.runtime.user_is_staff
assert not self.descriptor.runtime.get_user_role()
def test_get_real_user(self):
runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2777,20 +2781,20 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
course=self.course,
)
course_anonymous_student_id = anonymous_id_for_user(self.user, self.course.id)
assert runtime.get_real_user(course_anonymous_student_id) == self.user # pylint: disable=not-callable
assert self.descriptor.runtime.get_real_user(course_anonymous_student_id) == self.user # pylint: disable=not-callable
no_course_anonymous_student_id = anonymous_id_for_user(self.user, None)
assert runtime.get_real_user(no_course_anonymous_student_id) == self.user # pylint: disable=not-callable
assert self.descriptor.runtime.get_real_user(no_course_anonymous_student_id) == self.user # pylint: disable=not-callable
# Tests that the default is to use the user service's anonymous_student_id
assert runtime.get_real_user() == self.user # pylint: disable=not-callable
assert self.descriptor.runtime.get_real_user() == self.user # pylint: disable=not-callable
def test_render_template(self):
rendered = self.runtime.render_template('templates/edxmako.html', {'element_id': 'hi'}) # pylint: disable=not-callable
rendered = self.descriptor.runtime.render_template('templates/edxmako.html', {'element_id': 'hi'}) # pylint: disable=not-callable
assert rendered == '<div id="hi" ns="main">Testing the MakoService</div>\n'
def test_xqueue(self):
xqueue = self.runtime.xqueue
xqueue = self.descriptor.runtime.xqueue
assert isinstance(xqueue['interface'], XQueueInterface)
assert xqueue['interface'].url == 'http://sandbox-xqueue.edx.org'
assert xqueue['default_queuename'] == 'edX-LmsModuleShimTest'
@@ -2812,7 +2816,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
XQUEUE_WAITTIME_BETWEEN_REQUESTS=15,
)
def test_xqueue_settings(self):
runtime, _ = render.get_module_system_for_user(
_ = render.get_module_system_for_user(
self.user,
self.student_data,
self.descriptor,
@@ -2821,7 +2825,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
self.request_token,
course=self.course,
)
xqueue = runtime.xqueue
xqueue = self.descriptor.runtime.xqueue
assert isinstance(xqueue['interface'], XQueueInterface)
assert xqueue['interface'].url == 'http://xqueue.url'
assert xqueue['default_queuename'] == 'edX-LmsModuleShimTest'
@@ -2832,14 +2836,14 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
@override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+LmsModuleShimTest\+2021_Fall'])
def test_can_execute_unsafe_code_when_allowed(self):
assert self.runtime.can_execute_unsafe_code()
assert self.descriptor.runtime.can_execute_unsafe_code()
@override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+full\+2021_Fall'])
def test_cannot_execute_unsafe_code_when_disallowed(self):
assert not self.runtime.can_execute_unsafe_code()
assert not self.descriptor.runtime.can_execute_unsafe_code()
def test_cannot_execute_unsafe_code(self):
assert not self.runtime.can_execute_unsafe_code()
assert not self.descriptor.runtime.can_execute_unsafe_code()
@override_settings(PYTHON_LIB_FILENAME=PYTHON_LIB_FILENAME)
def test_get_python_lib_zip(self):
@@ -2849,7 +2853,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
source_file=self.PYTHON_LIB_SOURCE_FILE,
target_filename=self.PYTHON_LIB_FILENAME,
)
assert self.runtime.get_python_lib_zip() == zipfile
assert self.descriptor.runtime.get_python_lib_zip() == zipfile
def test_no_get_python_lib_zip(self):
zipfile = upload_file_to_course(
@@ -2858,26 +2862,26 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
source_file=self.PYTHON_LIB_SOURCE_FILE,
target_filename=self.PYTHON_LIB_FILENAME,
)
assert self.runtime.get_python_lib_zip() is None
assert self.descriptor.runtime.get_python_lib_zip() is None
def test_cache(self):
assert hasattr(self.runtime.cache, 'get')
assert hasattr(self.runtime.cache, 'set')
assert hasattr(self.descriptor.runtime.cache, 'get')
assert hasattr(self.descriptor.runtime.cache, 'set')
def test_replace_urls(self):
html = '<a href="/static/id">'
assert self.runtime.replace_urls(html) == \
assert self.descriptor.runtime.replace_urls(html) == \
static_replace.replace_static_urls(html, course_id=self.course.id)
def test_replace_course_urls(self):
html = '<a href="/course/id">'
assert self.runtime.replace_course_urls(html) == \
assert self.descriptor.runtime.replace_course_urls(html) == \
static_replace.replace_course_urls(html, course_key=self.course.id)
def test_replace_jump_to_id_urls(self):
html = '<a href="/jump_to_id/id">'
jump_to_id_base_url = reverse('jump_to_id', kwargs={'course_id': str(self.course.id), 'module_id': ''})
assert self.runtime.replace_jump_to_id_urls(html) == \
assert self.descriptor.runtime.replace_jump_to_id_urls(html) == \
static_replace.replace_jump_to_id_urls(html, self.course.id, jump_to_id_base_url)
@XBlock.register_temp_plugin(PureXBlock, 'pure')

View File

@@ -55,7 +55,6 @@ class TestDiscussionXBlock(XModuleRenderingTestBase):
field_data=self.data,
scope_ids=scope_ids
)
self.block.xmodule_runtime = mock.Mock()
if self.PATCH_DJANGO_USER:
self.django_user_canary = UserFactory()

View File

@@ -41,7 +41,7 @@ class TestLTI(BaseTestXmodule):
# Note: this course_id is actually a course_key
context_id = str(self.item_descriptor.course_id)
user_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'user')
user_service = self.item_descriptor.runtime.service(self.item_descriptor, 'user')
user_id = str(user_service.get_current_user().opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID))
hostname = settings.LMS_BASE
resource_link_id = str(urllib.parse.quote(f'{hostname}-{self.item_descriptor.location.html_id()}'))
@@ -81,8 +81,10 @@ class TestLTI(BaseTestXmodule):
'element_id': self.item_descriptor.location.html_id(),
'launch_url': 'http://www.example.com', # default value
'open_in_a_new_page': True,
'form_url': self.item_descriptor.xmodule_runtime.handler_url(self.item_descriptor,
'preview_handler').rstrip('/?'),
'form_url': self.item_descriptor.runtime.handler_url(
self.item_descriptor,
'preview_handler'
).rstrip('/?'),
'hide_launch': False,
'has_score': False,
'module_score': None,

View File

@@ -22,6 +22,8 @@ from xmodule.contentstore.django import contentstore # lint-amnesty, pylint: di
from xmodule.exceptions import NotFoundError # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
# noinspection PyUnresolvedReferences
from xmodule.tests.helpers import override_descriptor_system # pylint: disable=unused-import
from xmodule.video_block import VideoBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.video_block.transcripts_utils import ( # lint-amnesty, pylint: disable=wrong-import-order
Transcript,
@@ -29,7 +31,7 @@ from xmodule.video_block.transcripts_utils import ( # lint-amnesty, pylint: dis
get_transcript,
subs_filename,
)
from xmodule.x_module import STUDENT_VIEW # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.x_module import STUDENT_VIEW
from .helpers import BaseTestXmodule
from .test_video_xml import SOURCE_XML
@@ -131,6 +133,7 @@ def attach_bumper_transcript(item, filename, lang="en"):
item.video_bumper["transcripts"][lang] = filename
@pytest.mark.usefixtures("override_descriptor_system")
class BaseTestVideoXBlock(BaseTestXmodule):
"""Base class for VideoXBlock tests."""
@@ -232,7 +235,7 @@ class TestVideo(BaseTestVideoXBlock):
"""
Return the URL for the specified handler on self.item_descriptor.
"""
return self.item_descriptor.xmodule_runtime.handler_url(
return self.item_descriptor.runtime.handler_url(
self.item_descriptor, handler, suffix
).rstrip('/?')

View File

@@ -39,6 +39,8 @@ from xmodule.exceptions import NotFoundError
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE
# noinspection PyUnresolvedReferences
from xmodule.tests.helpers import override_descriptor_system # pylint: disable=unused-import
from xmodule.tests.test_import import DummySystem
from xmodule.tests.test_video import VideoBlockTestBase
from xmodule.video_block import VideoBlock, bumper_utils, video_utils
@@ -136,7 +138,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
'public_video_url': None,
}
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -220,7 +222,7 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
'public_video_url': None,
}
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
expected_result = get_context_dict_from_string(
mako_service.render_template('video.html', expected_context)
)
@@ -305,7 +307,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
Return the URL for the specified handler on the block represented by
self.item_descriptor.
"""
return self.item_descriptor.xmodule_runtime.handler_url(
return self.item_descriptor.runtime.handler_url(
self.item_descriptor, handler, suffix
).rstrip('/?')
@@ -422,7 +424,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
'metadata': json.dumps(metadata)
})
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -533,7 +535,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
'metadata': json.dumps(expected_context['metadata'])
})
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -676,7 +678,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
'metadata': json.dumps(expected_context['metadata'])
})
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -704,7 +706,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
# context returned by get_html when provided with above data
# expected_context, a dict to assert with context
context, expected_context = self.helper_get_html_with_edx_video_id(data)
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -735,7 +737,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
# expected_context, a dict to assert with context
context, expected_context = self.helper_get_html_with_edx_video_id(data)
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -936,7 +938,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
self.initialize_block(data=DATA, runtime_kwargs={
'user_location': 'CN',
})
user_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'user')
user_service = self.item_descriptor.runtime.service(self.item_descriptor, 'user')
user_location = user_service.get_current_user().opt_attrs[ATTR_KEY_REQUEST_COUNTRY_CODE]
assert user_location == 'CN'
context = self.item_descriptor.render('student_view').content
@@ -954,7 +956,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
'metadata': json.dumps(expected_context['metadata'])
})
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -1059,7 +1061,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
'metadata': json.dumps(expected_context['metadata'])
})
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
assert get_context_dict_from_string(context) ==\
get_context_dict_from_string(mako_service.render_template('video.html', expected_context))
@@ -2312,7 +2314,7 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
}))
}
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
expected_content = mako_service.render_template('video.html', expected_context)
assert get_context_dict_from_string(content) == get_context_dict_from_string(expected_content)
@@ -2368,10 +2370,10 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
'ytTestTimeout': 1500,
'ytApiUrl': 'https://www.youtube.com/iframe_api',
'lmsRootURL': settings.LMS_ROOT_URL,
'transcriptTranslationUrl': self.item_descriptor.xmodule_runtime.handler_url(
'transcriptTranslationUrl': self.item_descriptor.runtime.handler_url(
self.item_descriptor, 'transcript', 'translation/__lang__'
).rstrip('/?'),
'transcriptAvailableTranslationsUrl': self.item_descriptor.xmodule_runtime.handler_url(
'transcriptAvailableTranslationsUrl': self.item_descriptor.runtime.handler_url(
self.item_descriptor, 'transcript', 'available_translations'
).rstrip('/?'),
'autohideHtml5': False,
@@ -2407,7 +2409,7 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
autoadvance_flag=autoadvance_must_be,
)
mako_service = self.item_descriptor.xmodule_runtime.service(self.item_descriptor, 'mako')
mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako')
with override_settings(FEATURES=self.FEATURES):
expected_content = mako_service.render_template('video.html', expected_context)

View File

@@ -1,14 +1,19 @@
"""Word cloud integration tests using mongo modulestore."""
import pytest
import json
from operator import itemgetter
# noinspection PyUnresolvedReferences
from xmodule.tests.helpers import override_descriptor_system # pylint: disable=unused-import
from xmodule.x_module import STUDENT_VIEW
from .helpers import BaseTestXmodule
@pytest.mark.usefixtures("override_descriptor_system")
class TestWordCloud(BaseTestXmodule):
"""Integration test for Word Cloud Block."""
CATEGORY = "word_cloud"

View File

@@ -16,6 +16,7 @@ from datetime import datetime, timedelta
from unittest.mock import ANY, MagicMock, Mock, patch
import ddt
import pytest
import unicodecsv
from django.conf import settings
from django.test.utils import override_settings
@@ -70,6 +71,8 @@ from openedx.core.lib.teams_config import TeamsConfig
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory, check_mongo_calls # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.partitions.partitions import Group, UserPartition # lint-amnesty, pylint: disable=wrong-import-order
# noinspection PyUnresolvedReferences
from xmodule.tests.helpers import override_descriptor_system # pylint: disable=unused-import
from ..models import ReportStore
from ..tasks_helper.utils import UPDATE_STATUS_FAILED, UPDATE_STATUS_SUCCEEDED
@@ -1080,6 +1083,7 @@ class TestProblemReportSplitTestContent(TestReportMixin, TestConditionalContent,
@ddt.ddt
@pytest.mark.usefixtures("override_descriptor_system")
class TestProblemReportCohortedContent(TestReportMixin, ContentGroupTestCase, InstructorTaskModuleTestCase):
"""
Test the problem report on a course that has cohorted content.
@@ -1729,6 +1733,7 @@ class TestCohortStudents(TestReportMixin, InstructorTaskCourseTestCase):
@ddt.ddt
@patch('lms.djangoapps.instructor_task.tasks_helper.misc.DefaultStorage', new=MockDefaultStorage)
@pytest.mark.usefixtures("override_descriptor_system")
class TestGradeReport(TestReportMixin, InstructorTaskModuleTestCase):
"""
Test that grade report has correct grade values.

View File

@@ -11,7 +11,8 @@ from django.test import TestCase
from opaque_keys.edx.locations import BlockUsageLocator, CourseLocator
from xblock.fields import ScopeIds
from lms.djangoapps.lms_xblock.runtime import LmsModuleSystem
from xmodule.x_module import DescriptorSystem
from lms.djangoapps.lms_xblock.runtime import handler_url
class BlockMock(Mock):
@@ -50,10 +51,13 @@ class TestHandlerUrl(TestCase):
def setUp(self):
super().setUp()
self.block = BlockMock(name='block')
self.runtime = LmsModuleSystem(
get_block=Mock(),
descriptor_runtime=Mock(),
self.runtime = DescriptorSystem(
load_item=Mock(name='get_test_descriptor_system.load_item'),
resources_fs=Mock(name='get_test_descriptor_system.resources_fs'),
error_tracker=Mock(name='get_test_descriptor_system.error_tracker')
)
self.runtime.get_block_for_descriptor = Mock()
self.runtime.handler_url_override = handler_url
def test_trailing_characters(self):
assert not self.runtime.handler_url(self.block, 'handler').endswith('?')

View File

@@ -13,7 +13,7 @@ from opaque_keys.edx.keys import CourseKey
from xmodule.library_tools import LibraryToolsService
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory, LibraryFactory
from xmodule.tests import get_test_system
from xmodule.tests import prepare_block_runtime
from openedx.core.djangolib.testing.utils import skip_unless_lms
from common.djangoapps.student.tests.factories import UserFactory
@@ -121,20 +121,17 @@ class CompletionServiceTestCase(CompletionWaffleTestMixin, SharedModuleStoreTest
"""
Bind a block (part of self.course) so we can access student-specific data.
"""
module_system = get_test_system(course_id=block.location.course_key)
module_system.descriptor_runtime = block.runtime._descriptor_system # pylint: disable=protected-access
module_system._services['library_tools'] = LibraryToolsService(self.store, self.user.id) # pylint: disable=protected-access
prepare_block_runtime(block.runtime, course_id=block.location.course_key)
block.runtime._services.update({'library_tools': LibraryToolsService(self.store, self.user.id)}) # lint-amnesty, pylint: disable=protected-access
def get_block(descriptor):
"""Mocks module_system get_block_for_descriptor function"""
sub_module_system = get_test_system(course_id=block.location.course_key)
sub_module_system.get_block_for_descriptor = get_block
sub_module_system.descriptor_runtime = descriptor._runtime # pylint: disable=protected-access
descriptor.bind_for_student(sub_module_system, self.user.id)
prepare_block_runtime(descriptor.runtime, course_id=block.location.course_key)
descriptor.runtime.get_block_for_descriptor = get_block
descriptor.bind_for_student(self.user.id)
return descriptor
module_system.get_block_for_descriptor = get_block
block.xmodule_runtime = module_system
block.runtime.get_block_for_descriptor = get_block
def test_completion_service(self):
# Only the completions for the user and course specified for the CompletionService

View File

@@ -36,7 +36,7 @@ from xmodule.modulestore.inheritance import InheritanceMixin
from xmodule.modulestore.xml import CourseLocationManager
from xmodule.tests.helpers import StubReplaceURLService, mock_render_template, StubMakoService, StubUserService
from xmodule.util.sandboxing import SandboxService
from xmodule.x_module import DoNothingCache, ModuleSystem, XModuleMixin
from xmodule.x_module import DoNothingCache, XModuleMixin
from openedx.core.lib.cache_utils import CacheService
@@ -46,9 +46,35 @@ MODULE_DIR = path(__file__).dirname()
DATA_DIR = MODULE_DIR.parent.parent / "common" / "test" / "data"
class TestModuleSystem(ModuleSystem): # pylint: disable=abstract-method
def handler_url(block, handler, suffix='', query='', thirdparty=False): # lint-amnesty, pylint: disable=arguments-differ
return '{usage_id}/{handler}{suffix}?{query}'.format(
usage_id=str(block.scope_ids.usage_id),
handler=handler,
suffix=suffix,
query=query,
)
def local_resource_url(block, uri):
return 'resource/{usage_id}/{uri}'.format(
usage_id=str(block.scope_ids.usage_id),
uri=uri,
)
# Disable XBlockAsides in most tests
def get_asides(block):
return []
@property
def resources_fs():
return Mock(name='TestDescriptorSystem.resources_fs', root_path='.')
class TestDescriptorSystem(MakoDescriptorSystem): # pylint: disable=abstract-method
"""
ModuleSystem for testing
DescriptorSystem for testing
"""
def handler_url(self, block, handler, suffix='', query='', thirdparty=False): # lint-amnesty, pylint: disable=arguments-differ
return '{usage_id}/{handler}{suffix}?{query}'.format(
@@ -68,9 +94,8 @@ class TestModuleSystem(ModuleSystem): # pylint: disable=abstract-method
def get_asides(self, block):
return []
@property
def resources_fs(self):
return Mock(name='TestModuleSystem.resources_fs', root_path='.')
def resources_fs(self): # lint-amnesty, pylint: disable=method-hidden
return Mock(name='TestDescriptorSystem.resources_fs', root_path='.')
def __repr__(self):
"""
@@ -94,13 +119,19 @@ def get_test_system(
user_is_staff=False,
user_location=None,
render_template=None,
add_get_block_overrides=False
):
"""
Construct a test ModuleSystem instance.
Construct a test DescriptorSystem instance.
By default, the descriptor system's render_template() method simply returns the repr of the
context it is passed. You can override this by passing in a different render_template argument.
"""
id_manager = CourseLocationManager(course_id)
descriptor_system = get_test_descriptor_system(id_reader=id_manager, id_generator=id_manager)
if not user:
user = Mock(name='get_test_system.user', is_staff=False)
if not user_location:
@@ -117,63 +148,128 @@ def get_test_system(
replace_url_service = StubReplaceURLService()
descriptor_system = get_test_descriptor_system()
id_manager = CourseLocationManager(course_id)
def get_block(descriptor):
def get_block(block):
"""Mocks module_system get_block function"""
# Unlike XBlock Runtimes or DescriptorSystems,
# each XModule is provided with a new ModuleSystem.
# Construct one for the new XModule.
module_system = get_test_system()
prepare_block_runtime(block.runtime, add_overrides=add_get_block_overrides)
block.runtime.get_block_for_descriptor = get_block
block.bind_for_student(user.id)
# Descriptors can all share a single DescriptorSystem.
# So, bind to the same one as the current descriptor.
module_system.descriptor_runtime = descriptor._runtime # pylint: disable=protected-access
return block
descriptor.bind_for_student(module_system, user.id)
services = {
'user': user_service,
'mako': mako_service,
'xqueue': XQueueService(
url='http://xqueue.url',
django_auth={},
basic_auth=[],
default_queuename='testqueue',
waittime=10,
construct_callback=Mock(name='get_test_system.xqueue.construct_callback', side_effect="/"),
),
'replace_urls': replace_url_service,
'cache': CacheService(DoNothingCache()),
'field-data': DictFieldData({}),
'sandbox': SandboxService(contentstore, course_id),
}
return descriptor
descriptor_system.get_block_for_descriptor = get_block # lint-amnesty, pylint: disable=attribute-defined-outside-init
descriptor_system._services.update(services) # lint-amnesty, pylint: disable=protected-access
return TestModuleSystem(
get_block=get_block,
services={
'user': user_service,
'mako': mako_service,
'xqueue': XQueueService(
url='http://xqueue.url',
django_auth={},
basic_auth=[],
default_queuename='testqueue',
waittime=10,
construct_callback=Mock(name='get_test_system.xqueue.construct_callback', side_effect="/"),
),
'replace_urls': replace_url_service,
'cache': CacheService(DoNothingCache()),
'field-data': DictFieldData({}),
'sandbox': SandboxService(contentstore, course_id),
},
descriptor_runtime=descriptor_system,
id_reader=id_manager,
id_generator=id_manager,
return descriptor_system
def prepare_block_runtime(
runtime,
course_id=CourseKey.from_string('/'.join(['org', 'course', 'run'])),
user=None,
user_is_staff=False,
user_location=None,
render_template=None,
add_overrides=False,
add_get_block=False,
):
"""
Sets properties in the runtime of the specified descriptor that is
required for tests.
"""
if not user:
user = Mock(name='get_test_system.user', is_staff=False)
if not user_location:
user_location = Mock(name='get_test_system.user_location')
user_service = StubUserService(
user=user,
anonymous_user_id='student',
user_is_staff=user_is_staff,
user_role='student',
request_country_code=user_location,
)
mako_service = StubMakoService(render_template=render_template)
def get_test_descriptor_system(render_template=None):
replace_url_service = StubReplaceURLService()
def get_block(block):
"""Mocks module_system get_block function"""
prepare_block_runtime(block.runtime)
block.bind_for_student(user.id)
return block
services = {
'user': user_service,
'mako': mako_service,
'xqueue': XQueueService(
url='http://xqueue.url',
django_auth={},
basic_auth=[],
default_queuename='testqueue',
waittime=10,
construct_callback=Mock(name='get_test_system.xqueue.construct_callback', side_effect="/"),
),
'replace_urls': replace_url_service,
'cache': CacheService(DoNothingCache()),
'field-data': DictFieldData({}),
'sandbox': SandboxService(contentstore, course_id),
}
if add_overrides:
runtime.handler_url_override = handler_url
runtime.local_resource_url = local_resource_url
runtime.get_asides = get_asides
runtime.resources_fs = resources_fs
if add_get_block:
runtime.get_block_for_descriptor = get_block
runtime._services.update(services) # lint-amnesty, pylint: disable=protected-access
# runtime.load_item=Mock(name='get_test_descriptor_system.load_item')
# runtime.resources_fs=Mock(name='get_test_descriptor_system.resources_fs')
# runtime.error_tracker=Mock(name='get_test_descriptor_system.error_tracker')
# runtime.render_template=render_template or mock_render_template,
# runtime.mixins=(InheritanceMixin, XModuleMixin)
return runtime
def get_test_descriptor_system(render_template=None, **kwargs):
"""
Construct a test DescriptorSystem instance.
"""
field_data = DictFieldData({})
descriptor_system = MakoDescriptorSystem(
descriptor_system = TestDescriptorSystem(
load_item=Mock(name='get_test_descriptor_system.load_item'),
resources_fs=Mock(name='get_test_descriptor_system.resources_fs'),
error_tracker=Mock(name='get_test_descriptor_system.error_tracker'),
render_template=render_template or mock_render_template,
mixins=(InheritanceMixin, XModuleMixin),
services={'field-data': field_data},
**kwargs
)
descriptor_system.get_asides = lambda block: []
return descriptor_system

View File

@@ -6,8 +6,10 @@ Utility methods for unit tests.
import filecmp
import pprint
import pytest
from path import Path as path
from xblock.reference.user_service import UserService, XBlockUser
from xmodule.x_module import DescriptorSystem
def directories_equal(directory1, directory2):
@@ -72,6 +74,7 @@ class StubUserService(UserService):
self.user_role = user_role
self.anonymous_user_id = anonymous_user_id
self.request_country_code = request_country_code
self._django_user = user
super().__init__(**kwargs)
def get_current_user(self):
@@ -109,3 +112,17 @@ class StubReplaceURLService:
Invokes the configured render_template method.
"""
return text
@pytest.fixture
def override_descriptor_system(monkeypatch):
"""
Fixture to override get_block method of DescriptorSystem
"""
def get_block(self, usage_id, for_parent=None):
"""See documentation for `xblock.runtime:Runtime.get_block`"""
block = self.load_item(usage_id, for_parent=for_parent)
return block
monkeypatch.setattr(DescriptorSystem, "get_block", get_block)

View File

@@ -16,7 +16,7 @@ from xblock.fields import ScopeIds
from xmodule.conditional_block import ConditionalBlock
from xmodule.error_block import ErrorBlock
from xmodule.modulestore.xml import CourseLocationManager, ImportSystem, XMLModuleStore
from xmodule.tests import DATA_DIR, get_test_descriptor_system, get_test_system
from xmodule.tests import DATA_DIR, get_test_system, prepare_block_runtime
from xmodule.tests.xml import XModuleXmlImportTest
from xmodule.tests.xml import factories as xml
from xmodule.validation import StudioValidationMessage
@@ -41,7 +41,8 @@ class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-metho
load_error_blocks=load_error_blocks,
)
def render_template(self, template, context): # lint-amnesty, pylint: disable=method-hidden
@property
def render_template(self): # lint-amnesty, pylint: disable=method-hidden
raise Exception("Shouldn't be called")
@@ -65,7 +66,6 @@ class ConditionalFactory:
if the source_is_error_block flag is set, create a real ErrorBlock for the source.
"""
descriptor_system = get_test_descriptor_system()
# construct source descriptor and module:
source_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run", deprecated=True),
@@ -83,17 +83,16 @@ class ConditionalFactory:
source_descriptor.location = source_location
source_descriptor.visible_to_staff_only = source_visible_to_staff_only
source_descriptor.runtime = descriptor_system
source_descriptor.render = lambda view, context=None: descriptor_system.render(source_descriptor, view, context)
source_descriptor.runtime = system
source_descriptor.render = lambda view, context=None: system.render(source_descriptor, view, context)
# construct other descriptors:
child_descriptor = Mock(name='child_descriptor')
child_descriptor.visible_to_staff_only = False
child_descriptor._xmodule.student_view.return_value = Fragment(content='<p>This is a secret</p>') # lint-amnesty, pylint: disable=protected-access
child_descriptor.student_view = child_descriptor._xmodule.student_view # lint-amnesty, pylint: disable=protected-access
child_descriptor.runtime = descriptor_system
child_descriptor.xmodule_runtime = get_test_system()
child_descriptor.render = lambda view, context=None: descriptor_system.render(child_descriptor, view, context)
child_descriptor.runtime = system
child_descriptor.render = lambda view, context=None: system.render(child_descriptor, view, context)
child_descriptor.location = source_location.replace(category='html', name='child')
def visible_to_nonstaff_users(desc):
@@ -109,9 +108,7 @@ class ConditionalFactory:
source_location: source_descriptor
}.get(usage_id)
descriptor_system.load_item = load_item
system.descriptor_runtime = descriptor_system
system.load_item = load_item
# construct conditional block:
cond_location = BlockUsageLocator(CourseLocator("edX", "conditional_test", "test_run", deprecated=True),
@@ -125,11 +122,10 @@ class ConditionalFactory:
})
cond_descriptor = ConditionalBlock(
descriptor_system,
system,
field_data,
ScopeIds(None, None, cond_location, cond_location)
)
cond_descriptor.xmodule_runtime = system
system.get_block_for_descriptor = lambda desc: desc if visible_to_nonstaff_users(desc) else None
cond_descriptor.get_required_blocks = [
system.get_block_for_descriptor(source_descriptor),
@@ -165,7 +161,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
# because get_test_system returns the repr of the context dict passed to render_template,
# we reverse it here
html = blocks['cond_block'].render(STUDENT_VIEW).content
mako_service = blocks['cond_block'].xmodule_runtime.service(blocks['cond_block'], 'mako')
mako_service = blocks['cond_block'].runtime.service(blocks['cond_block'], 'mako')
expected = mako_service.render_template('conditional_ajax.html', {
'ajax_url': blocks['cond_block'].ajax_url,
'element_id': 'i4x-edX-conditional_test-conditional-SampleConditional',
@@ -220,7 +216,12 @@ class ConditionalBlockXmlTest(unittest.TestCase):
def setUp(self):
super().setUp()
self.test_system = get_test_system()
def add_block_as_child_node(block, node):
child = etree.SubElement(node, "unknown")
block.add_xml_to_node(child)
self.test_system = get_test_system(add_get_block_overrides=True)
self.test_system.add_block_as_child_node = add_block_as_child_node
self.modulestore = XMLModuleStore(DATA_DIR, source_dirs=['conditional_and_poll'])
courses = self.modulestore.get_courses()
assert len(courses) == 1
@@ -241,7 +242,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
block = self.get_block_for_location(location)
html = block.render(STUDENT_VIEW).content
mako_service = block.xmodule_runtime.service(block, 'mako')
mako_service = block.runtime.service(block, 'mako')
html_expect = mako_service.render_template(
'conditional_ajax.html',
{
@@ -355,12 +356,9 @@ class ConditionalBlockStudioTest(XModuleXmlImportTest):
self.sequence = self.course.get_children()[0]
self.conditional = self.sequence.get_children()[0]
self.module_system = get_test_system()
self.module_system.descriptor_runtime = self.course._runtime # pylint: disable=protected-access
user = Mock(username='ma', email='ma@edx.org', is_staff=False, is_active=True)
self.conditional.runtime = prepare_block_runtime(self.course.runtime)
self.conditional.bind_for_student(
self.module_system,
user.id
)
@@ -380,11 +378,11 @@ class ConditionalBlockStudioTest(XModuleXmlImportTest):
}
context = create_studio_context(self.conditional, False)
html = self.module_system.render(self.conditional, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.conditional, AUTHOR_VIEW, context).content
assert 'This is a secret HTML' in html
context = create_studio_context(self.sequence, True)
html = self.module_system.render(self.conditional, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.conditional, AUTHOR_VIEW, context).content
assert 'This is a secret HTML' not in html
def test_non_editable_settings(self):

View File

@@ -38,7 +38,7 @@ class TestErrorBlock(SetupTestErrorBlock):
self.error_msg
)
assert isinstance(descriptor, ErrorBlock)
descriptor.xmodule_runtime = self.system
descriptor.runtime = self.system
context_repr = self.system.render(descriptor, STUDENT_VIEW).content
assert self.error_msg in context_repr
assert repr(self.valid_xml) in context_repr

View File

@@ -52,9 +52,6 @@ class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-metho
services={'field-data': KvsFieldData(DictKeyValueStore())},
)
def render_template(self, _template, _context): # lint-amnesty, pylint: disable=method-hidden
raise Exception("Shouldn't be called")
class BaseCourseTestCase(TestCase):
'''Make sure block imports work properly, including for malformed inputs'''

View File

@@ -19,7 +19,7 @@ from xmodule.library_tools import LibraryToolsService
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.factories import CourseFactory, LibraryFactory
from xmodule.modulestore.tests.utils import MixedSplitTestCase
from xmodule.tests import get_test_system
from xmodule.tests import prepare_block_runtime
from xmodule.validation import StudioValidationMessage
from xmodule.x_module import AUTHOR_VIEW
from xmodule.capa_block import ProblemBlock
@@ -58,20 +58,17 @@ class LibraryContentTest(MixedSplitTestCase):
"""
Bind a block (part of self.course) so we can access student-specific data.
"""
module_system = get_test_system(course_id=block.location.course_key)
module_system.descriptor_runtime = block.runtime._descriptor_system # pylint: disable=protected-access
module_system._services['library_tools'] = self.tools # pylint: disable=protected-access
prepare_block_runtime(block.runtime, course_id=block.location.course_key)
block.runtime._runtime_services.update({'library_tools': self.tools}) # lint-amnesty, pylint: disable=protected-access
def get_block(descriptor):
"""Mocks module_system get_block function"""
sub_module_system = get_test_system(course_id=block.location.course_key)
sub_module_system.get_block_for_descriptor = get_block
sub_module_system.descriptor_runtime = descriptor._runtime # pylint: disable=protected-access
descriptor.bind_for_student(sub_module_system, self.user_id)
prepare_block_runtime(descriptor.runtime, course_id=block.location.course_key)
descriptor.runtime.get_block_for_descriptor = get_block
descriptor.bind_for_student(self.user_id)
return descriptor
module_system.get_block_for_descriptor = get_block
block.xmodule_runtime = module_system
block.runtime.get_block_for_descriptor = get_block
class TestLibraryContentExportImport(LibraryContentTest):
@@ -99,7 +96,7 @@ class TestLibraryContentExportImport(LibraryContentTest):
# Set the virtual FS to export the olx to.
self.export_fs = MemoryFS()
self.lc_block.runtime._descriptor_system.export_fs = self.export_fs # pylint: disable=protected-access
self.lc_block.runtime.export_fs = self.export_fs # pylint: disable=protected-access
# Prepare runtime for the import.
self.runtime = TestImportSystem(load_error_blocks=True, course_id=self.lc_block.location.course_key)
@@ -517,7 +514,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
self.lc_block.refresh_children()
self.lc_block = self.store.get_item(self.lc_block.location)
self._bind_course_block(self.lc_block)
self.lc_block.xmodule_runtime.publish = self.publisher
self.lc_block.runtime.publish = self.publisher
def _assert_event_was_published(self, event_type):
"""
@@ -571,7 +568,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.lc_block = self.store.get_item(self.lc_block.location)
self._bind_course_block(self.lc_block)
self.lc_block.xmodule_runtime.publish = self.publisher
self.lc_block.runtime.publish = self.publisher
self.test_assigned_event()
def test_assigned_descendants(self):
@@ -590,7 +587,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
# Reload lc_block and set it up for a student:
self.lc_block = self.store.get_item(self.lc_block.location)
self._bind_course_block(self.lc_block)
self.lc_block.xmodule_runtime.publish = self.publisher
self.lc_block.runtime.publish = self.publisher
# Get the keys of each of our blocks, as they appear in the course:
course_usage_main_vertical = self.lc_block.children[0]

View File

@@ -6,7 +6,7 @@ from openedx.core.djangoapps.content_libraries.tests.base import ContentLibrarie
from common.djangoapps.student.roles import CourseInstructorRole
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory
from xmodule.tests import get_test_system
from xmodule.tests import prepare_block_runtime
from xmodule.x_module import STUDENT_VIEW # lint-amnesty, pylint: disable=unused-import
@@ -66,7 +66,6 @@ class LibrarySourcedBlockTestCase(ContentLibrariesRestApiTest):
"""
context = context or {}
block = self.store.get_item(block.location)
module_system = get_test_system(block)
module_system.descriptor_runtime = block._runtime # pylint: disable=protected-access
block.bind_for_student(module_system, self.user.id)
return module_system.render(block, view, context).content
prepare_block_runtime(block.runtime)
block.bind_for_student(self.user.id)
return block.runtime.render(block, view, context).content

View File

@@ -370,7 +370,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
Test that we get a 404 when the supplied user does not exist
"""
self.setup_system_xblock_mocks_for_lti20_request_test()
self.runtime._services['user'] = StubUserService(user=None) # pylint: disable=protected-access
self.runtime._runtime_services['user'] = StubUserService(user=None) # pylint: disable=protected-access
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd")
assert response.status_code == 404

View File

@@ -65,7 +65,7 @@ class LTIBlockTest(TestCase):
self.course_id = CourseKey.from_string('org/course/run')
self.system = get_test_system(self.course_id)
self.system.publish = Mock()
self.system._services['rebind_user'] = Mock() # pylint: disable=protected-access
self.system._runtime_services['rebind_user'] = Mock() # pylint: disable=protected-access
self.xblock = LTIBlock(
self.system,
@@ -178,7 +178,7 @@ class LTIBlockTest(TestCase):
"""
If we have no real user, we should send back failure response.
"""
self.system._services['user'] = StubUserService(user=None) # pylint: disable=protected-access
self.system._runtime_services['user'] = StubUserService(user=None) # pylint: disable=protected-access
self.xblock.verify_oauth_body_sign = Mock()
self.xblock.has_score = True
request = Request(self.environ)

View File

@@ -9,7 +9,7 @@ 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 get_test_system
from xmodule.tests import prepare_block_runtime
from .test_course_block import DummySystem as TestImportSystem
@@ -42,9 +42,7 @@ class RandomizeBlockTest(MixedSplitTestCase):
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)
module_system = get_test_system(course_id=block.location.course_key, user=user)
module_system.descriptor_runtime = block.runtime._descriptor_system # pylint: disable=protected-access
block.xmodule_runtime = module_system
prepare_block_runtime(block.runtime, course_id=block.location.course_key, user=user)
def test_xml_export_import_cycle(self):
"""
@@ -64,7 +62,7 @@ class RandomizeBlockTest(MixedSplitTestCase):
export_fs = MemoryFS()
# Set the virtual FS to export the olx to.
randomize_block.runtime._descriptor_system.export_fs = export_fs # pylint: disable=protected-access
randomize_block.runtime.export_fs = export_fs # pylint: disable=protected-access
# Export the olx.
node = etree.Element("unknown_root")

View File

@@ -19,7 +19,7 @@ from web_fragments.fragment import Fragment
from edx_toggles.toggles.testutils import override_waffle_flag
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
from xmodule.seq_block import TIMED_EXAM_GATING_WAFFLE_FLAG, SequenceBlock
from xmodule.tests import get_test_system
from xmodule.tests import get_test_system, prepare_block_runtime
from xmodule.tests.helpers import StubUserService
from xmodule.tests.xml import XModuleXmlImportTest
from xmodule.tests.xml import factories as xml
@@ -94,11 +94,8 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self._set_up_module_system(block)
block.xmodule_runtime._services['bookmarks'] = Mock() # pylint: disable=protected-access
block.xmodule_runtime._services['completion'] = Mock( # pylint: disable=protected-access
return_value=Mock(vertical_is_complete=Mock(return_value=True))
)
block.xmodule_runtime._services['user'] = StubUserService(user=Mock()) # pylint: disable=protected-access
block.runtime._runtime_services['bookmarks'] = Mock() # pylint: disable=protected-access
block.runtime._runtime_services['user'] = StubUserService(user=Mock()) # pylint: disable=protected-access
block.parent = parent.location
return block
@@ -106,14 +103,12 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
"""
Sets up the test module system for the given block.
"""
module_system = get_test_system()
module_system.descriptor_runtime = block._runtime # pylint: disable=protected-access
block.xmodule_runtime = module_system
prepare_block_runtime(block.runtime)
# The render operation will ask modulestore for the current course to get some data. As these tests were
# originally not written to be compatible with a real modulestore, we've mocked out the relevant return values.
module_system.modulestore = Mock()
module_system.modulestore.get_course.return_value = self.course
block.runtime.modulestore = Mock()
block.runtime.modulestore.get_course.return_value = self.course
def _get_rendered_view(self,
sequence,
@@ -130,7 +125,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
context.update(extra_context)
self.course.self_paced = self_paced
return sequence.xmodule_runtime.render(sequence, view, context).content
return sequence.runtime.render(sequence, view, context).content
def _assert_view_at_position(self, rendered_html, expected_position):
"""
@@ -139,10 +134,10 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
assert f"'position': {expected_position}" in rendered_html
def test_student_view_init(self):
module_system = get_test_system()
module_system.position = 2
seq_block = SequenceBlock(runtime=module_system, scope_ids=Mock())
seq_block.bind_for_student(module_system, 34)
runtime = get_test_system()
runtime.position = 2
seq_block = SequenceBlock(runtime=runtime, scope_ids=Mock())
seq_block.bind_for_student(34)
assert seq_block.position == 2
# matches position set in the runtime
@@ -335,7 +330,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
False,
{'url': 'PrereqUrl', 'display_name': 'PrereqSectionName', 'id': 'mockId'}
]
self.sequence_1_2.xmodule_runtime._services['gating'] = gating_mock_1_2 # pylint: disable=protected-access
self.sequence_1_2.runtime._services['gating'] = gating_mock_1_2 # pylint: disable=protected-access
self.sequence_1_2.display_name = 'sequence_1_2'
html = self._get_rendered_view(
@@ -373,6 +368,9 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
def test_xblock_handler_get_completion_success(self):
"""Test that the completion data is returned successfully on targeted vertical through ajax call"""
self.sequence_3_1.runtime._runtime_services['completion'] = Mock( # pylint: disable=protected-access
return_value=Mock(vertical_is_complete=Mock(return_value=True))
)
for child in self.sequence_3_1.get_children():
usage_key = str(child.location)
request = RequestFactory().post(
@@ -382,6 +380,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
)
completion_return = self.sequence_3_1.handle('get_completion', request)
assert completion_return.json == {'complete': True}
self.sequence_3_1.runtime._runtime_services['completion'] = None # pylint: disable=protected-access
def test_xblock_handler_get_completion_bad_key(self):
"""Test that the completion data is returned as False when usage key is None through ajax call"""
@@ -395,10 +394,14 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
def test_handle_ajax_get_completion_success(self):
"""Test that the old-style ajax handler for completion still works"""
self.sequence_3_1.runtime._runtime_services['completion'] = Mock( # pylint: disable=protected-access
return_value=Mock(vertical_is_complete=Mock(return_value=True))
)
for child in self.sequence_3_1.get_children():
usage_key = str(child.location)
completion_return = self.sequence_3_1.handle_ajax('get_completion', {'usage_key': usage_key})
assert json.loads(completion_return) == {'complete': True}
self.sequence_3_1.runtime._runtime_services['completion'] = None # pylint: disable=protected-access
def test_xblock_handler_goto_position_success(self):
"""Test that we can set position through ajax call"""
@@ -434,7 +437,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
"""Test that the sequence metadata is returned correctly"""
# rather than dealing with json serialization of the Mock object,
# let's just disable the bookmarks service
self.sequence_3_1.xmodule_runtime._services['bookmarks'] = None # lint-amnesty, pylint: disable=protected-access
self.sequence_3_1.runtime._services['bookmarks'] = None # lint-amnesty, pylint: disable=protected-access
metadata = self.sequence_3_1.get_metadata()
assert len(metadata['items']) == 3
assert metadata['tag'] == 'sequential'
@@ -445,7 +448,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
))
def test_get_metadata_content_type_gated_content(self):
"""The contains_content_type_gated_content field tells whether the item contains content type gated content"""
self.sequence_5_1.xmodule_runtime._services['bookmarks'] = None # pylint: disable=protected-access
self.sequence_5_1.runtime._services['bookmarks'] = None # pylint: disable=protected-access
ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
metadata = self.sequence_5_1.get_metadata()
assert metadata['items'][0]['contains_content_type_gated_content'] is False

View File

@@ -18,7 +18,7 @@ from xmodule.split_test_block import (
get_split_user_partitions,
user_partition_values,
)
from xmodule.tests import get_test_system
from xmodule.tests import prepare_block_runtime
from xmodule.tests.test_course_block import DummySystem as TestImportSystem
from xmodule.tests.xml import XModuleXmlImportTest
from xmodule.tests.xml import factories as xml
@@ -85,9 +85,9 @@ class SplitTestBlockTest(XModuleXmlImportTest, PartitionTestCase):
self.course = self.process_xml(course)
self.course_sequence = self.course.get_children()[0]
self.module_system = get_test_system()
user = Mock(username='ma', email='ma@edx.org', is_staff=False, is_active=True)
prepare_block_runtime(self.course.runtime, user=user, add_get_block=True)
self.module_system.descriptor_runtime = self.course._runtime # pylint: disable=protected-access
self.course.runtime.export_fs = MemoryFS()
# Create mock partition service, as these tests are running with XML in-memory system.
@@ -106,19 +106,15 @@ class SplitTestBlockTest(XModuleXmlImportTest, PartitionTestCase):
self.course,
course_id=self.course.id,
)
self.module_system._services['partitions'] = partitions_service # pylint: disable=protected-access
self.course.runtime._runtime_services['partitions'] = partitions_service # pylint: disable=protected-access
# Mock user_service user
user_service = Mock()
user = Mock(username='ma', email='ma@edx.org', is_staff=False, is_active=True)
user_service._django_user = user # lint-amnesty, pylint: disable=protected-access
self.module_system._services['user'] = user_service # pylint: disable=protected-access
self.split_test_block = self.course_sequence.get_children()[0]
self.split_test_block.bind_for_student(
self.module_system,
user.id
)
self.split_test_block.runtime = self.course.runtime
self.split_test_block.bind_for_student(user.id)
# Create mock modulestore for getting the course. Needed for rendering the HTML
# view, since mock services exist and the rendering code will not short-circuit.
@@ -152,7 +148,7 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
@ddt.unpack
def test_get_html(self, user_tag, child_content):
self.user_partition.scheme.current_group = self.user_partition.groups[user_tag]
assert child_content in self.module_system.render(self.split_test_block, STUDENT_VIEW).content
assert child_content in self.course.runtime.render(self.split_test_block, STUDENT_VIEW).content
@ddt.data(0, 1)
def test_child_missing_tag_value(self, _user_tag):
@@ -175,7 +171,7 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
# Mock out the process_xml
# Expect it to return a child descriptor for the SplitTestDescriptor when called.
self.module_system.process_xml = Mock()
self.course.runtime.process_xml = Mock()
# Write out the xml.
xml_obj = self.split_test_block.definition_to_xml(MemoryFS())
@@ -184,7 +180,7 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
assert xml_obj.get('group_id_to_child') is not None
# Read the xml back in.
fields, children = SplitTestBlock.definition_from_xml(xml_obj, self.module_system)
fields, children = SplitTestBlock.definition_from_xml(xml_obj, self.course.runtime)
assert fields.get('user_partition_id') == '0'
assert fields.get('group_id_to_child') is not None
assert len(children) == 2
@@ -212,13 +208,13 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
# The split_test block should render both its groups when it is the root
context = create_studio_context(self.split_test_block)
html = self.module_system.render(self.split_test_block, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.split_test_block, AUTHOR_VIEW, context).content
assert 'HTML FOR GROUP 0' in html
assert 'HTML FOR GROUP 1' in html
# When rendering as a child, it shouldn't render either of its groups
context = create_studio_context(self.course_sequence)
html = self.module_system.render(self.split_test_block, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.split_test_block, AUTHOR_VIEW, context).content
assert 'HTML FOR GROUP 0' not in html
assert 'HTML FOR GROUP 1' not in html
@@ -228,7 +224,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
UserPartition(0, 'first_partition', 'First Partition',
[Group("0", 'alpha'), Group("1", 'beta'), Group("2", 'gamma')])
]
html = self.module_system.render(self.split_test_block, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.split_test_block, AUTHOR_VIEW, context).content
assert 'HTML FOR GROUP 0' in html
assert 'HTML FOR GROUP 1' in html
@@ -569,7 +565,7 @@ class SplitTestBlockExportImportTest(MixedSplitTestCase):
)
export_fs = MemoryFS()
# Set the virtual FS to export the olx to.
split_test_block.runtime._descriptor_system.export_fs = export_fs # pylint: disable=protected-access
split_test_block.runtime.export_fs = export_fs # pylint: disable=protected-access
# Export the olx.
node = lxml.etree.Element("unknown_root")

View File

@@ -24,6 +24,6 @@ class StudioEditableBlockTestCase(BaseVerticalBlockTest):
}
# Both children of the vertical should be rendered as reorderable
self.module_system.render(self.vertical, AUTHOR_VIEW, context).content # pylint: disable=expression-not-assigned
self.course.runtime.render(self.vertical, AUTHOR_VIEW, context).content # pylint: disable=expression-not-assigned
assert self.vertical.get_children()[0].location in reorderable_items
assert self.vertical.get_children()[1].location in reorderable_items

View File

@@ -18,7 +18,7 @@ from django.test import override_settings
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import VerticalBlockChildRenderStarted, VerticalBlockRenderCompleted
from . import get_test_system
from . import prepare_block_runtime
from .helpers import StubUserService
from .xml import XModuleXmlImportTest
from .xml import factories as xml
@@ -164,13 +164,12 @@ class BaseVerticalBlockTest(XModuleXmlImportTest):
self.course = self.process_xml(course)
course_seq = self.course.get_children()[0]
self.module_system = get_test_system()
prepare_block_runtime(self.course.runtime)
self.module_system.descriptor_runtime = self.course._runtime
self.course.runtime.export_fs = MemoryFS()
self.vertical = course_seq.get_children()[0]
self.vertical.xmodule_runtime = self.module_system
self.vertical.runtime = self.course.runtime
self.html_block = self.vertical.get_children()[0]
self.problem_block = self.vertical.get_children()[1]
@@ -213,17 +212,19 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test the rendering of the student and public view.
"""
self.module_system._services['bookmarks'] = Mock()
self.course.runtime._runtime_services['bookmarks'] = Mock()
now = datetime.now(pytz.UTC)
self.vertical.due = now + timedelta(days=days)
if view == STUDENT_VIEW:
self.module_system._services['user'] = StubUserService(user=Mock(username=self.username))
self.module_system._services['completion'] = StubCompletionService(enabled=True,
completion_value=completion_value)
self.course.runtime._runtime_services['user'] = StubUserService(user=Mock(username=self.username))
self.course.runtime._runtime_services['completion'] = StubCompletionService(
enabled=True,
completion_value=completion_value
)
elif view == PUBLIC_VIEW:
self.module_system._services['user'] = StubUserService(user=AnonymousUser())
self.course.runtime._runtime_services['user'] = StubUserService(user=AnonymousUser())
html = self.module_system.render(
html = self.course.runtime.render(
self.vertical, view, self.default_context if context is None else context
).content
assert self.test_html in html
@@ -248,15 +249,15 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test the rendering of the student and public view.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
now = datetime.now(pytz.UTC)
self.vertical.due = now + timedelta(days=-1)
self.problem_block.has_score = has_score
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context).content
if has_score:
assert "'has_assignments': True" in html
assert "'completed': False" in html
@@ -270,14 +271,14 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
@ddt.unpack
def test_render_access_denied_blocks(self, node_has_access_error, child_has_access_error):
""" Tests access denied blocks are not rendered when hide_access_error_blocks is True """
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.vertical.due = datetime.now(pytz.UTC) + timedelta(days=-1)
self.problem_block.has_access_error = node_has_access_error
self.nested_problem_block.has_access_error = child_has_access_error
context = {'username': self.username, 'hide_access_error_blocks': True}
html = self.module_system.render(self.vertical, STUDENT_VIEW, context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, context).content
if node_has_access_error and child_has_access_error:
assert self.test_problem not in html
@@ -316,11 +317,11 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
Test that mark-completed-on-view-after-delay is only set for relevant child Xblocks.
"""
with patch.object(self.html_block, 'render') as mock_student_view:
self.module_system._services['completion'] = StubCompletionService(
self.course.runtime._services['completion'] = StubCompletionService(
enabled=completion_enabled,
completion_value=completion_value,
)
self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context)
self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context)
if mark_completed_enabled:
assert mock_student_view.call_args[0][1]['wrap_xblock_data']['mark-completed-on-view-after-delay'] ==\
9876
@@ -335,7 +336,7 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
context = {
'is_unit_page': True
}
html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.vertical, AUTHOR_VIEW, context).content
assert self.test_html not in html
assert self.test_problem not in html
@@ -345,7 +346,7 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
'is_unit_page': False,
'reorderable_items': reorderable_items,
}
html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
html = self.course.runtime.render(self.vertical, AUTHOR_VIEW, context).content
assert self.test_html in html
assert self.test_problem in html
@@ -363,11 +364,11 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test the VerticalBlockChildRenderStarted filter's effects on student view.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context).content
assert TestVerticalBlockChildRenderStep.filter_content in html
@@ -385,11 +386,11 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test VerticalBlockChildRenderStarted filter can be used to skip child blocks.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context).content
assert self.test_html not in html
assert self.test_html_nested not in html
@@ -408,11 +409,11 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test the VerticalBlockRenderCompleted filter's execution.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context).content
assert TestVerticalBlockRenderCompletedStep.filter_content in html
@@ -430,10 +431,10 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
"""
Test VerticalBlockRenderCompleted filter can be used to prevent vertical block from rendering.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
self.course.runtime._services['bookmarks'] = Mock()
self.course.runtime._services['user'] = StubUserService(user=Mock())
self.course.runtime._services['completion'] = StubCompletionService(enabled=True, completion_value=0)
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
html = self.course.runtime.render(self.vertical, STUDENT_VIEW, self.default_context).content
assert TestPreventVerticalBlockRenderStep.filter_content == html

View File

@@ -1408,8 +1408,7 @@ class ModuleSystemShim:
DeprecationWarning, stacklevel=3,
)
if hasattr(self, '_deprecated_course_id'):
return self._deprecated_course_id
return self.descriptor_runtime.course_id.for_branch(None)
return self._deprecated_course_id.for_branch(None)
@course_id.setter
def course_id(self, course_id):
@@ -1479,7 +1478,7 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
def get_block(self, usage_id, for_parent=None):
"""See documentation for `xblock.runtime:Runtime.get_block`"""
block = self.load_item(usage_id, for_parent=for_parent)
if self.get_block_for_descriptor:
if getattr(self, 'get_block_for_descriptor', None):
return self.get_block_for_descriptor(block)
return block