diff --git a/cms/djangoapps/contentstore/course_group_config.py b/cms/djangoapps/contentstore/course_group_config.py index 09036dad1366..569a1f72b372 100644 --- a/cms/djangoapps/contentstore/course_group_config.py +++ b/cms/djangoapps/contentstore/course_group_config.py @@ -114,26 +114,26 @@ def get_user_partition(self): raise GroupConfigurationsValidationError(_("unable to load this type of group configuration")) # lint-amnesty, pylint: disable=raise-missing-from @staticmethod - def _get_usage_dict(course, unit, item, scheme_name=None): + def _get_usage_dict(course, unit, block, scheme_name=None): """ - Get usage info for unit/module. + Get usage info for unit/block. """ - parent_unit = get_parent_unit(item) + parent_unit = get_parent_unit(block) - if unit == parent_unit and not item.has_children: + if unit == parent_unit and not block.has_children: # Display the topmost unit page if # the item is a child of the topmost unit and doesn't have its own children. unit_for_url = unit - elif (not parent_unit and unit.get_parent()) or (unit == parent_unit and item.has_children): + elif (not parent_unit and unit.get_parent()) or (unit == parent_unit and block.has_children): # Display the item's page rather than the unit page if # the item is one level below the topmost unit and has children, or # the item itself *is* the topmost unit (and thus does not have a parent unit, but is not an orphan). - unit_for_url = item + unit_for_url = block else: # If the item is nested deeper than two levels (the topmost unit > vertical > ... > item) # display the page for the nested vertical element. - parent = item.get_parent() - nested_vertical = item + parent = block.get_parent() + nested_vertical = block while parent != parent_unit: nested_vertical = parent parent = parent.get_parent() @@ -144,9 +144,9 @@ def _get_usage_dict(course, unit, item, scheme_name=None): course.location.course_key.make_usage_key(unit_for_url.location.block_type, unit_for_url.location.block_id) ) - usage_dict = {'label': f"{unit.display_name} / {item.display_name}", 'url': unit_url} + usage_dict = {'label': f"{unit.display_name} / {block.display_name}", 'url': unit_url} if scheme_name == RANDOM_SCHEME: - validation_summary = item.general_validation_message() + validation_summary = block.general_validation_message() usage_dict.update({'validation': validation_summary.to_json() if validation_summary else None}) return usage_dict @@ -204,7 +204,7 @@ def _get_content_experiment_usage_info(store, course, split_tests): # pylint: d usage_info[split_test.user_partition_id].append(GroupConfiguration._get_usage_dict( course=course, unit=unit, - item=split_test, + block=split_test, scheme_name=RANDOM_SCHEME, )) return usage_info @@ -233,16 +233,16 @@ def get_partitions_usage_info(store, course): items = store.get_items(course.id, settings={'group_access': {'$exists': True}}, include_orphans=False) usage_info = defaultdict(lambda: defaultdict(list)) - for item, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items): - unit = item.get_parent() + for block, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items): + unit = block.get_parent() if not unit: - log.warning("Unable to find parent for component %s", item.location) + log.warning("Unable to find parent for component %s", block.location) continue usage_info[partition_id][group_id].append(GroupConfiguration._get_usage_dict( course, unit=unit, - item=item, + block=block, )) return usage_info @@ -280,11 +280,11 @@ def _get_content_groups_items_usage_info(course, items): } """ usage_info = defaultdict(lambda: defaultdict(list)) - for item, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items): + for block, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items): usage_info[partition_id][group_id].append(GroupConfiguration._get_usage_dict( course, - unit=item, - item=item, + unit=block, + block=block, )) return usage_info diff --git a/cms/djangoapps/contentstore/courseware_index.py b/cms/djangoapps/contentstore/courseware_index.py index d21f9b8ffc73..dc28774c50f7 100644 --- a/cms/djangoapps/contentstore/courseware_index.py +++ b/cms/djangoapps/contentstore/courseware_index.py @@ -613,7 +613,7 @@ def index_about_information(cls, modulestore, course): 'image_url': course_image_url(course), } - # load data for all of the 'about' modules for this course into a dictionary + # load data for all of the 'about' blocks for this course into a dictionary about_dictionary = { item.location.block_id: item.data for item in modulestore.get_items(course.id, qualifiers={"category": "about"}) diff --git a/cms/djangoapps/contentstore/management/commands/delete_orphans.py b/cms/djangoapps/contentstore/management/commands/delete_orphans.py index a79b362f43bb..267af09a5443 100644 --- a/cms/djangoapps/contentstore/management/commands/delete_orphans.py +++ b/cms/djangoapps/contentstore/management/commands/delete_orphans.py @@ -5,7 +5,7 @@ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from cms.djangoapps.contentstore.views.item import _delete_orphans +from cms.djangoapps.contentstore.views.block import _delete_orphans from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order diff --git a/cms/djangoapps/contentstore/management/commands/import.py b/cms/djangoapps/contentstore/management/commands/import.py index e2a54731c95b..4ff9e7ce8d43 100644 --- a/cms/djangoapps/contentstore/management/commands/import.py +++ b/cms/djangoapps/contentstore/management/commands/import.py @@ -64,7 +64,7 @@ def handle(self, *args, **options): mstore = modulestore() course_items = import_course_from_xml( - mstore, ModuleStoreEnum.UserID.mgmt_command, data_dir, source_dirs, load_error_modules=False, + mstore, ModuleStoreEnum.UserID.mgmt_command, data_dir, source_dirs, load_error_blocks=False, static_content_store=contentstore(), verbose=True, do_import_static=do_import_static, do_import_python_lib=do_import_python_lib, create_if_not_present=True, diff --git a/cms/djangoapps/contentstore/management/commands/import_content_library.py b/cms/djangoapps/contentstore/management/commands/import_content_library.py index 60f33ffdf7b9..782db4988061 100644 --- a/cms/djangoapps/contentstore/management/commands/import_content_library.py +++ b/cms/djangoapps/contentstore/management/commands/import_content_library.py @@ -87,7 +87,7 @@ def handle(self, *args, **options): import_library_from_xml( modulestore(), user.id, settings.GITHUB_REPO_ROOT, [rel_xml_path], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore(), target_id=courselike_key ) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py b/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py index 91a39e7d67e8..75650d41dcb2 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py @@ -42,7 +42,7 @@ def test_delete_orphans_commit(self): call_command('delete_orphans', str(course.id), '--commit') - # make sure this module wasn't deleted + # make sure this block wasn't deleted self.assertTrue(self.store.has_item(course.id.make_usage_key('html', 'multi_parent_html'))) # and make sure that these were diff --git a/cms/djangoapps/contentstore/management/commands/xlint.py b/cms/djangoapps/contentstore/management/commands/xlint.py index 655a2af01ee7..d7e93d44de0a 100644 --- a/cms/djangoapps/contentstore/management/commands/xlint.py +++ b/cms/djangoapps/contentstore/management/commands/xlint.py @@ -31,4 +31,4 @@ def handle(self, *args, **options): data=data_dir, courses=source_dirs)) - perform_xlint(data_dir, source_dirs, load_error_modules=False) + perform_xlint(data_dir, source_dirs, load_error_blocks=False) diff --git a/cms/djangoapps/contentstore/signals/handlers.py b/cms/djangoapps/contentstore/signals/handlers.py index 535169f02135..44c8c8a126dd 100644 --- a/cms/djangoapps/contentstore/signals/handlers.py +++ b/cms/djangoapps/contentstore/signals/handlers.py @@ -23,7 +23,7 @@ LibrarySearchIndexer, ) from common.djangoapps.track.event_transaction_utils import get_event_transaction_id, get_event_transaction_type -from common.djangoapps.util.module_utils import yield_dynamic_descriptor_descendants +from common.djangoapps.util.block_utils import yield_dynamic_descriptor_descendants from lms.djangoapps.grades.api import task_compute_all_grades_for_course from openedx.core.djangoapps.content.learning_sequences.api import key_supports_outlines from openedx.core.djangoapps.discussions.tasks import update_discussions_settings_from_course_task @@ -204,12 +204,12 @@ def handle_item_deleted(**kwargs): # Strip branch info usage_key = usage_key.for_branch(None) course_key = usage_key.course_key - deleted_module = modulestore().get_item(usage_key) - for module in yield_dynamic_descriptor_descendants(deleted_module, kwargs.get('user_id')): + deleted_block = modulestore().get_item(usage_key) + for block in yield_dynamic_descriptor_descendants(deleted_block, kwargs.get('user_id')): # Remove prerequisite milestone data - gating_api.remove_prerequisite(module.location) + gating_api.remove_prerequisite(block.location) # Remove any 'requires' course content milestone relationships - gating_api.set_required_content(course_key, module.location, None, None, None) + gating_api.set_required_content(course_key, block.location, None, None, None) @receiver(GRADING_POLICY_CHANGED) diff --git a/cms/djangoapps/contentstore/tasks.py b/cms/djangoapps/contentstore/tasks.py index af0c6ea9d1af..d08ac886e207 100644 --- a/cms/djangoapps/contentstore/tasks.py +++ b/cms/djangoapps/contentstore/tasks.py @@ -317,13 +317,13 @@ def export_olx(self, user_id, course_key_string, language): return if isinstance(courselike_key, LibraryLocator): - courselike_module = modulestore().get_library(courselike_key) + courselike_block = modulestore().get_library(courselike_key) else: - courselike_module = modulestore().get_course(courselike_key) + courselike_block = modulestore().get_course(courselike_key) try: self.status.set_state('Exporting') - tarball = create_export_tarball(courselike_module, courselike_key, {}, self.status) + tarball = create_export_tarball(courselike_block, courselike_key, {}, self.status) artifact = UserTaskArtifact(status=self.status, name='Output') artifact.file.save(name=os.path.basename(tarball.name), content=File(tarball)) artifact.save() @@ -541,11 +541,11 @@ def get_dir_for_filename(directory, filename): is_course = not is_library if is_library: root_name = LIBRARY_ROOT - courselike_module = modulestore().get_library(courselike_key) + courselike_block = modulestore().get_library(courselike_key) import_func = import_library_from_xml else: root_name = COURSE_ROOT - courselike_module = modulestore().get_course(courselike_key) + courselike_block = modulestore().get_course(courselike_key) import_func = import_course_from_xml # Locate the uploaded OLX archive (and download it from S3 if necessary) @@ -581,7 +581,7 @@ def read_chunk(): # If the course has an entrance exam then remove it and its corresponding milestone. # current course state before import. if is_course: - if courselike_module.entrance_exam_enabled: + if courselike_block.entrance_exam_enabled: fake_request = RequestFactory().get('/') fake_request.user = user from .views.entrance_exam import remove_entrance_exam_milestone_reference @@ -635,7 +635,7 @@ def read_chunk(): courselike_items = import_func( modulestore(), user.id, settings.GITHUB_REPO_ROOT, [dirpath], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore(), target_id=courselike_key, verbose=True, diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index d67b819aa783..be120824a42a 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -400,7 +400,7 @@ def test_empty_data_roundtrip(self): parent = verticals[0] - # Create a module, and ensure that its `data` field is empty + # Create a block, and ensure that its `data` field is empty word_cloud = BlockFactory.create( parent_location=parent.location, category="word_cloud", display_name="untitled") del word_cloud.data @@ -478,7 +478,7 @@ def test_export_course_without_content_store(self): def test_export_course_no_xml_attributes(self): """ - Test that a module without an `xml_attributes` attr will still be + Test that a block without an `xml_attributes` attr will still be exported successfully """ content_store = contentstore() @@ -732,7 +732,7 @@ def test_get_items(self): def test_draft_metadata(self): """ This verifies a bug we had where inherited metadata was getting written to the - module as 'own-metadata' when publishing. Also verifies the metadata inheritance is + block as 'own-metadata' when publishing. Also verifies the metadata inheritance is properly computed """ # refetch course so it has all the children correct @@ -752,7 +752,7 @@ def test_draft_metadata(self): self.assertEqual(problem.graceperiod, course.graceperiod) self.assertNotIn('graceperiod', own_metadata(problem)) - # publish module + # publish block self.store.publish(problem.location, self.user.id) # refetch to check metadata @@ -831,7 +831,7 @@ def test_import_polls(self): def test_module_preview_in_whitelist(self): """ - Tests the ajax callback to render an XModule + Tests the ajax callback to render an XBlock """ with override_settings(COURSES_WITH_UNSAFE_CODE=[str(self.course.id)]): # also try a custom response which will trigger the 'is this course in whitelist' logic @@ -971,7 +971,7 @@ def test_delete_course(self): # delete the course self.store.delete_course(self.course.id, self.user.id) - # assert that there's absolutely no non-draft modules in the course + # assert that there's absolutely no non-draft blocks in the course # this should also include all draft items with self.assertRaises(ItemNotFoundError): self.store.get_items(self.course.id) @@ -992,7 +992,7 @@ def test_course_handouts_rewrites(self): } ) - # get module info (json) + # get block info (json) resp = self.client.get(get_url('xblock_handler', handouts.location)) # make sure we got a successful response @@ -1015,10 +1015,10 @@ def test_prefetch_children(self): course = self.store.get_course(self.course.id, depth=2, lazy=False) # make sure we pre-fetched a known sequential which should be at depth=2 - self.assertIn(BlockKey.from_usage_key(self.seq_loc), course.system.module_data) + self.assertIn(BlockKey.from_usage_key(self.seq_loc), course.runtime.module_data) # make sure we don't have a specific vertical which should be at depth=3 - self.assertNotIn(BlockKey.from_usage_key(self.vert_loc), course.system.module_data) + self.assertNotIn(BlockKey.from_usage_key(self.vert_loc), course.runtime.module_data) # Now, test with the branch set to draft. No extra round trips b/c it doesn't go deep enough to get # beyond direct only categories @@ -1386,7 +1386,7 @@ def test_course_overview_view_with_course(self): html=True ) - def test_create_item(self): + def test_create_block(self): """Test creating a new xblock instance.""" course = CourseFactory.create() @@ -1493,11 +1493,11 @@ def test_import_into_new_course_id(self): import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id) - modules = self.store.get_items(target_id) + blocks = self.store.get_items(target_id) - # we should have a number of modules in there + # we should have a number of blocks in there # we can't specify an exact number since it'll always be changing - self.assertGreater(len(modules), 10) + self.assertGreater(len(blocks), 10) # # test various re-namespacing elements @@ -1602,7 +1602,7 @@ def test_metadata_inheritance(self): self.assertGreater(len(verticals), 0) - # crate a new module and add it as a child to a vertical + # crate a new block and add it as a child to a vertical parent = verticals[0] new_block = self.store.create_child( self.user.id, parent.location, 'html', 'new_component' @@ -1743,13 +1743,13 @@ def test_metadata_not_persistence(self): self.assertNotIn('html5_sources', own_metadata(self.video_descriptor)) self.store.update_item(self.video_descriptor, self.user.id) - module = self.store.get_item(location) + block = self.store.get_item(location) - self.assertNotIn('html5_sources', own_metadata(module)) + self.assertNotIn('html5_sources', own_metadata(block)) def test_metadata_persistence(self): # TODO: create the same test as `test_metadata_not_persistence`, - # but check persistence for some other module. + # but check persistence for some other block. pass diff --git a/cms/djangoapps/contentstore/tests/test_courseware_index.py b/cms/djangoapps/contentstore/tests/test_courseware_index.py index 429b3cd316d9..7d7a0d533b07 100644 --- a/cms/djangoapps/contentstore/tests/test_courseware_index.py +++ b/cms/djangoapps/contentstore/tests/test_courseware_index.py @@ -206,7 +206,7 @@ def _get_default_search(self): def _test_indexing_course(self, store): """ indexing course tests """ - # Only published modules should be in the index + # Only published blocks should be in the index added_to_index = self.reindex_course(store) # This reindex may not be necessary (it may already be indexed) self.assertEqual(added_to_index, 3) response = self.search() @@ -1164,7 +1164,7 @@ def test_content_group_gets_indexed(self): Indexing course with content groups added test. """ - # Only published modules should be in the index + # Only published blocks should be in the index added_to_index = self.reindex_course(self.store) self.assertEqual(added_to_index, 16) response = self.searcher.search(field_dictionary={"course": str(self.course.id)}) diff --git a/cms/djangoapps/contentstore/tests/test_crud.py b/cms/djangoapps/contentstore/tests/test_crud.py index ab3796cc7028..a7d283e466d1 100644 --- a/cms/djangoapps/contentstore/tests/test_crud.py +++ b/cms/djangoapps/contentstore/tests/test_crud.py @@ -90,7 +90,7 @@ def test_temporary_xblocks(self): ) test_chapter = self.store.create_xblock( - test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'}, + test_course.runtime, test_course.id, 'chapter', fields={'display_name': 'chapter n'}, parent_xblock=test_course ) self.assertIsInstance(test_chapter, SequenceBlock) @@ -100,7 +100,7 @@ def test_temporary_xblocks(self): # test w/ a definition (e.g., a problem) test_def_content = 'boo' test_problem = self.store.create_xblock( - test_course.system, test_course.id, 'problem', fields={'data': test_def_content}, + test_course.runtime, test_course.id, 'problem', fields={'data': test_def_content}, parent_xblock=test_chapter ) self.assertIsInstance(test_problem, ProblemBlock) diff --git a/cms/djangoapps/contentstore/tests/test_i18n.py b/cms/djangoapps/contentstore/tests/test_i18n.py index 5bcb10834d5b..ebd5616b9d5e 100644 --- a/cms/djangoapps/contentstore/tests/test_i18n.py +++ b/cms/djangoapps/contentstore/tests/test_i18n.py @@ -1,5 +1,5 @@ """ -Tests for validate Internationalization and Module i18n service. +Tests for validate Internationalization and XBlock i18n service. """ @@ -9,7 +9,7 @@ from django.utils import translation from django.utils.translation import get_language from xblock.core import XBlock -from xmodule.modulestore.django import ModuleI18nService +from xmodule.modulestore.django import XBlockI18nService from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory from xmodule.tests.test_export import PureXBlock @@ -20,7 +20,7 @@ from openedx.core.lib.edx_six import get_gettext -class FakeTranslations(ModuleI18nService): +class FakeTranslations(XBlockI18nService): """A test GNUTranslations class that takes a map of msg -> translations.""" def __init__(self, translations): # pylint: disable=super-init-not-called @@ -57,8 +57,8 @@ def _translation(domain, localedir=None, languages=None): # pylint: disable=unu return _translation -class TestModuleI18nService(ModuleStoreTestCase): - """ Test ModuleI18nService """ +class TestXBlockI18nService(ModuleStoreTestCase): + """ Test XBlockI18nService """ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE @XBlock.register_temp_plugin(PureXBlock, 'pure') @@ -77,13 +77,13 @@ def setUp(self): ) self.addCleanup(translation.deactivate) - def get_module_i18n_service(self, descriptor): + def get_block_i18n_service(self, descriptor): """ - return the module i18n service. + return the block i18n service. """ i18n_service = self.runtime.service(descriptor, 'i18n') self.assertIsNotNone(i18n_service) - self.assertIsInstance(i18n_service, ModuleI18nService) + self.assertIsInstance(i18n_service, XBlockI18nService) return i18n_service def test_django_service_translation_works(self): @@ -113,7 +113,7 @@ def __exit__(self, _type, _value, _traceback): self.module.ugettext = self.old_ugettext self.module.gettext = self.old_ugettext - i18n_service = self.get_module_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.descriptor) # Activate french, so that if the fr files haven't been loaded, they will be loaded now. with translation.override("fr"): @@ -132,7 +132,7 @@ def test_django_translator_in_use_with_empty_block(self): """ Test: Django default translator should in use if we have an empty block """ - i18n_service = ModuleI18nService(None) + i18n_service = XBlockI18nService(None) self.assertEqual(i18n_service.ugettext(self.test_language), 'XYZ-TEST-LANGUAGE') @mock.patch('django.utils.translation.ugettext', mock.Mock(return_value='XYZ-TEST-LANGUAGE')) @@ -150,13 +150,13 @@ def test_message_catalog_translations(self): translation.activate("es") with mock.patch('gettext.translation', return_value=_translator(domain='text', localedir=localedir, languages=[get_language()])): - i18n_service = self.get_module_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.descriptor) self.assertEqual(i18n_service.ugettext('Hello'), 'es-hello-world') translation.activate("ar") with mock.patch('gettext.translation', return_value=_translator(domain='text', localedir=localedir, languages=[get_language()])): - i18n_service = self.get_module_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.descriptor) self.assertEqual(get_gettext(i18n_service)('Hello'), 'Hello') self.assertNotEqual(get_gettext(i18n_service)('Hello'), 'fr-hello-world') self.assertNotEqual(get_gettext(i18n_service)('Hello'), 'es-hello-world') @@ -164,7 +164,7 @@ def test_message_catalog_translations(self): translation.activate("fr") with mock.patch('gettext.translation', return_value=_translator(domain='text', localedir=localedir, languages=[get_language()])): - i18n_service = self.get_module_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.descriptor) self.assertEqual(i18n_service.ugettext('Hello'), 'fr-hello-world') def test_i18n_service_callable(self): diff --git a/cms/djangoapps/contentstore/tests/test_libraries.py b/cms/djangoapps/contentstore/tests/test_libraries.py index 22563ec7533e..3e850e4794d7 100644 --- a/cms/djangoapps/contentstore/tests/test_libraries.py +++ b/cms/djangoapps/contentstore/tests/test_libraries.py @@ -16,8 +16,8 @@ from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, parse_json from cms.djangoapps.contentstore.utils import reverse_library_url, reverse_url, reverse_usage_url -from cms.djangoapps.contentstore.views.item import _duplicate_item -from cms.djangoapps.contentstore.views.preview import _load_preview_module +from cms.djangoapps.contentstore.views.block import _duplicate_block +from cms.djangoapps.contentstore.views.preview import _load_preview_block from cms.djangoapps.contentstore.views.tests.test_library import LIBRARY_REST_URL from cms.djangoapps.course_creators.views import add_user_with_status_granted from common.djangoapps.student import auth @@ -50,7 +50,7 @@ def setUp(self): self.lib_key = self._create_library() self.library = modulestore().get_library(self.lib_key) - self.session_data = {} # Used by _bind_module + self.session_data = {} # Used by _bind_block def _login_as_staff_user(self, logout_first=True): """ Login as a staff user """ @@ -114,7 +114,7 @@ def _refresh_children(self, lib_content_block, status_code_expected=200): self.assertEqual(response.status_code, status_code_expected) return modulestore().get_item(lib_content_block.location) - def _bind_module(self, descriptor, user=None): + def _bind_block(self, descriptor, user=None): """ Helper to use the CMS's module system so we can access student-specific fields. """ @@ -123,9 +123,9 @@ def _bind_module(self, descriptor, user=None): if user not in self.session_data: self.session_data[user] = {} request = Mock(user=user, session=self.session_data[user]) - _load_preview_module(request, descriptor) + _load_preview_block(request, descriptor) - def _update_item(self, usage_key, metadata): + def _update_block(self, usage_key, metadata): """ Helper method: Uses the REST API to update the fields of an XBlock. This will result in the XBlock's editor_saved() method being called. @@ -178,7 +178,7 @@ def test_max_items(self, num_to_create, num_to_select, num_expected): # chosen for a given student. # In order to be able to call get_child_descriptors(), we must first # call bind_for_student: - self._bind_module(lc_block) + self._bind_block(lc_block) self.assertEqual(len(lc_block.children), num_to_create) self.assertEqual(len(lc_block.get_child_descriptors()), num_expected) @@ -209,7 +209,7 @@ def get_child_of_lc_block(block): return children[0] # Check which child a student will see: - self._bind_module(lc_block) + self._bind_block(lc_block) chosen_child = get_child_of_lc_block(lc_block) chosen_child_defn_id = chosen_child.definition_locator.definition_id lc_block.save() @@ -223,7 +223,7 @@ def check(): """ for _ in range(6): # Repeat many times b/c blocks are randomized lc_block = modulestore().get_item(lc_block_key) # Reload block from the database - self._bind_module(lc_block) + self._bind_block(lc_block) current_child = get_child_of_lc_block(lc_block) self.assertEqual(current_child.location, chosen_child.location) self.assertEqual(current_child.data, chosen_child.data) @@ -352,7 +352,7 @@ def test_change_after_first_sync(self): self.assertEqual(len(lc_block.children), 1) # Now, change the block settings to have an invalid library key: - resp = self._update_item( + resp = self._update_block( lc_block.location, {"source_library_id": "library-v1:NOT+FOUND"}, ) @@ -395,7 +395,7 @@ def test_refreshes_children_if_libraries_change(self): self.assertEqual(len(lc_block.children), 1) # Now, change the block settings to have an invalid library key: - resp = self._update_item( + resp = self._update_block( lc_block.location, {"source_library_id": str(library2key)}, ) @@ -436,7 +436,7 @@ def test_refreshes_children_if_capa_type_change(self): lc_block = self._refresh_children(lc_block) self.assertEqual(len(lc_block.children), 2) - resp = self._update_item( + resp = self._update_block( lc_block.location, {"capa_type": 'optionresponse'}, ) @@ -447,7 +447,7 @@ def test_refreshes_children_if_capa_type_change(self): html_block = modulestore().get_item(lc_block.children[0]) self.assertEqual(html_block.display_name, name1) - resp = self._update_item( + resp = self._update_block( lc_block.location, {"capa_type": 'multiplechoiceresponse'}, ) @@ -470,7 +470,7 @@ def test_refresh_fails_for_unknown_library(self): self.assertEqual(len(lc_block.children), 0) # Now, change the block settings to have an invalid library key: - resp = self._update_item( + resp = self._update_block( lc_block.location, {"source_library_id": "library-v1:NOT+FOUND"}, ) @@ -766,7 +766,7 @@ def test_refresh_library_content_permissions(self, library_role, course_role, ex # Try updating our library content block: lc_block = self._add_library_content_block(course, self.lib_key) # We must use the CMS's module system in order to get permissions checks. - self._bind_module(lc_block, user=self.non_staff_user) + self._bind_block(lc_block, user=self.non_staff_user) lc_block = self._refresh_children(lc_block, status_code_expected=200 if expected_result else 403) self.assertEqual(len(lc_block.children), 1 if expected_result else 0) @@ -947,7 +947,7 @@ def test_persistent_overrides(self, duplicate): if duplicate: # Check that this also works when the RCB is duplicated. self.lc_block = modulestore().get_item( - _duplicate_item(self.course.location, self.lc_block.location, self.user) + _duplicate_block(self.course.location, self.lc_block.location, self.user) ) self.problem_in_course = modulestore().get_item(self.lc_block.children[0]) else: @@ -1006,7 +1006,7 @@ def test_duplicated_version(self): # Duplicate self.lc_block: duplicate = store.get_item( - _duplicate_item(self.course.location, self.lc_block.location, self.user) + _duplicate_block(self.course.location, self.lc_block.location, self.user) ) # The duplicate should have identical children to the original: self.assertEqual(len(duplicate.children), 1) diff --git a/cms/djangoapps/contentstore/tests/test_orphan.py b/cms/djangoapps/contentstore/tests/test_orphan.py index 5e5ddbabc0d0..244eecebf9af 100644 --- a/cms/djangoapps/contentstore/tests/test_orphan.py +++ b/cms/djangoapps/contentstore/tests/test_orphan.py @@ -17,11 +17,11 @@ class TestOrphanBase(CourseTestCase): """ - Base class for Studio tests that require orphaned modules + Base class for Studio tests that require orphaned blocks """ def create_course_with_orphans(self, default_store): """ - Creates a course with 3 orphan modules, one of which + Creates a course with 3 orphan blocks, one of which has a child that's also in the course tree. """ course = CourseFactory.create(default_store=default_store) @@ -145,7 +145,7 @@ def test_path_to_location_for_orphan_vertical(self): \ / html """ - # Get a course with orphan modules + # Get a course with orphan blocks course = self.create_course_with_orphans(ModuleStoreEnum.Type.split) # Fetch the required course components. @@ -194,7 +194,7 @@ def test_path_to_location_for_orphan_chapter(self): html """ - # Get a course with orphan modules + # Get a course with orphan blocks course = self.create_course_with_orphans(ModuleStoreEnum.Type.split) orphan_chapter = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'OrphanChapter')) chapter1 = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'Chapter1')) diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 180dc097cf4a..7791bb681238 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -366,7 +366,7 @@ def reverse_usage_url(handler_name, usage_key, kwargs=None): def get_split_group_display_name(xblock, course): """ - Returns group name if an xblock is found in user partition groups that are suitable for the split_test module. + Returns group name if an xblock is found in user partition groups that are suitable for the split_test block. Arguments: xblock (XBlock): The courseware component. diff --git a/cms/djangoapps/contentstore/views/__init__.py b/cms/djangoapps/contentstore/views/__init__.py index 1263976c7bb2..ba87c54d38c0 100644 --- a/cms/djangoapps/contentstore/views/__init__.py +++ b/cms/djangoapps/contentstore/views/__init__.py @@ -9,7 +9,7 @@ from .export_git import * from .helpers import * from .import_export import * -from .item import * +from .block import * from .library import * from .preview import * from .public import * diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/block.py similarity index 97% rename from cms/djangoapps/contentstore/views/item.py rename to cms/djangoapps/contentstore/views/block.py index 244cf52c13b4..439bed09cf59 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/block.py @@ -1,4 +1,4 @@ -"""Views for items (modules).""" +"""Views for blocks.""" import logging from collections import OrderedDict @@ -181,15 +181,15 @@ def xblock_handler(request, usage_key_string=None): if 'application/json' in accept_header: fields = request.GET.get('fields', '').split(',') if 'graderType' in fields: - # right now can't combine output of this w/ output of _get_module_info, but worthy goal + # right now can't combine output of this w/ output of _get_block_info, but worthy goal return JsonResponse(CourseGradingModel.get_section_grader_type(usage_key)) elif 'ancestorInfo' in fields: xblock = _get_xblock(usage_key, request.user) ancestor_info = _create_xblock_ancestor_info(xblock, is_concise=True) return JsonResponse(ancestor_info) - # TODO: pass fields to _get_module_info and only return those + # TODO: pass fields to _get_block_info and only return those with modulestore().bulk_operations(usage_key.course_key): - response = _get_module_info(_get_xblock(usage_key, request.user)) + response = _get_block_info(_get_xblock(usage_key, request.user)) return JsonResponse(response) else: return HttpResponse(status=406) @@ -238,7 +238,7 @@ def xblock_handler(request, usage_key_string=None): status=400 ) - dest_usage_key = _duplicate_item( + dest_usage_key = _duplicate_block( parent_usage_key, duplicate_source_usage_key, request.user, @@ -249,7 +249,7 @@ def xblock_handler(request, usage_key_string=None): 'courseKey': str(dest_usage_key.course_key) }) else: - return _create_item(request) + return _create_block(request) elif request.method == 'PATCH': if 'move_source_locator' in request.json: move_source_usage_key = usage_key_with_run(request.json.get('move_source_locator')) @@ -503,7 +503,7 @@ def xblock_container_handler(request, usage_key_string): response_format = request.GET.get('format', 'html') if response_format == 'json' or 'application/json' in request.META.get('HTTP_ACCEPT', 'application/json'): with modulestore().bulk_operations(usage_key.course_key): - response = _get_module_info( + response = _get_block_info( _get_xblock(usage_key, request.user), include_ancestor_info=True, include_publishing_info=True ) return JsonResponse(response) @@ -701,13 +701,13 @@ def create_item(request): """ Exposes internal helper method without breaking existing bindings/dependencies """ - return _create_item(request) + return _create_block(request) @login_required @expect_json -def _create_item(request): - """View for create items.""" +def _create_block(request): + """View for create blocks.""" parent_locator = request.json['parent_locator'] usage_key = usage_key_with_run(parent_locator) if not has_studio_write_access(request.user, usage_key.course_key): @@ -875,7 +875,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non return JsonResponse(context) -def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_name=None, is_child=False): +def _duplicate_block(parent_usage_key, duplicate_source_usage_key, user, display_name=None, is_child=False): """ Duplicate an existing xblock as a child of the supplied parent_usage_key. """ @@ -917,7 +917,7 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_ if field.scope not in (Scope.settings, Scope.content,): field.delete_from(aside) - dest_module = store.create_item( + dest_block = store.create_item( user.id, dest_usage_key.course_key, dest_usage_key.block_type, @@ -930,22 +930,22 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_ children_handled = False - if hasattr(dest_module, 'studio_post_duplicate'): + if hasattr(dest_block, 'studio_post_duplicate'): # Allow an XBlock to do anything fancy it may need to when duplicated from another block. # These blocks may handle their own children or parenting if needed. Let them return booleans to # let us know if we need to handle these or not. - dest_module.xmodule_runtime = StudioEditModuleRuntime(user) - children_handled = dest_module.studio_post_duplicate(store, source_item) + dest_block.xmodule_runtime = StudioEditModuleRuntime(user) + children_handled = dest_block.studio_post_duplicate(store, source_item) # Children are not automatically copied over (and not all xblocks have a 'children' attribute). # Because DAGs are not fully supported, we need to actually duplicate each child as well. if source_item.has_children and not children_handled: - dest_module.children = dest_module.children or [] + dest_block.children = dest_block.children or [] for child in source_item.children: - dupe = _duplicate_item(dest_module.location, child, user=user, is_child=True) - if dupe not in dest_module.children: # _duplicate_item may add the child for us. - dest_module.children.append(dupe) - store.update_item(dest_module, user.id) + dupe = _duplicate_block(dest_block.location, child, user=user, is_child=True) + if dupe not in dest_block.children: # _duplicate_block may add the child for us. + dest_block.children.append(dupe) + store.update_item(dest_block, user.id) # pylint: disable=protected-access if 'detached' not in source_item.runtime.load_block_type(category)._class_tags: @@ -954,12 +954,12 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_ # Otherwise, add child to end. if source_item.location in parent.children: source_index = parent.children.index(source_item.location) - parent.children.insert(source_index + 1, dest_module.location) + parent.children.insert(source_index + 1, dest_block.location) else: - parent.children.append(dest_module.location) + parent.children.append(dest_block.location) store.update_item(parent, user.id) - return dest_module.location + return dest_block.location @login_required @@ -1024,17 +1024,17 @@ def _delete_orphans(course_usage_key, user_id, commit=False): the orphans. """ store = modulestore() - items = store.get_orphans(course_usage_key) + blocks = store.get_orphans(course_usage_key) branch = course_usage_key.branch if commit: with store.bulk_operations(course_usage_key): - for itemloc in items: + for blockloc in blocks: revision = ModuleStoreEnum.RevisionOption.all # specify branches when deleting orphans if branch == ModuleStoreEnum.BranchName.published: revision = ModuleStoreEnum.RevisionOption.published_only - store.delete_item(itemloc, user_id, revision=revision) - return [str(item) for item in items] + store.delete_item(blockloc, user_id, revision=revision) + return [str(block) for block in blocks] def _get_xblock(usage_key, user): @@ -1061,9 +1061,9 @@ def _get_xblock(usage_key, user): return JsonResponse({"error": "Can't find item by location: " + str(usage_key)}, 404) -def _get_module_info(xblock, rewrite_static_links=True, include_ancestor_info=False, include_publishing_info=False): +def _get_block_info(xblock, rewrite_static_links=True, include_ancestor_info=False, include_publishing_info=False): """ - metadata, data, id representation of a leaf module fetcher. + metadata, data, id representation of a leaf block fetcher. :param usage_key: A UsageKey """ with modulestore().bulk_operations(xblock.location.course_key): diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index 9b86350ed2c4..124c12df785e 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -32,7 +32,7 @@ from ..utils import get_lms_link_for_item, get_sibling_urls, reverse_course_url from .helpers import get_parent_xblock, is_unit, xblock_type_display_name -from .item import StudioEditModuleRuntime, add_container_page_publishing_info, create_xblock_info +from .block import StudioEditModuleRuntime, add_container_page_publishing_info, create_xblock_info __all__ = [ 'container_handler', @@ -546,7 +546,7 @@ def component_handler(request, usage_key_string, handler, suffix=''): """ usage_key = UsageKey.from_string(usage_key_string) - # Let the module handle the AJAX + # Let the block handle the AJAX req = django_to_webob_request(request) try: diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index cd4e9868691f..943dd580608f 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -108,7 +108,7 @@ from .component import ADVANCED_COMPONENT_TYPES from .helpers import is_content_creator from .entrance_exam import create_entrance_exam, delete_entrance_exam, update_entrance_exam -from .item import create_xblock_info +from .block import create_xblock_info from .library import ( LIBRARIES_ENABLED, LIBRARY_AUTHORING_MICROFRONTEND_URL, @@ -254,7 +254,7 @@ def course_handler(request, course_key_string=None): """ The restful handler for course specific requests. It provides the course tree with the necessary information for identifying and labeling the parts. The root - will typically be a 'course' object but may not be especially as we support modules. + will typically be a 'course' object but may not be especially as we support blocks. GET html: return course listing page if not given a course id diff --git a/cms/djangoapps/contentstore/views/entrance_exam.py b/cms/djangoapps/contentstore/views/entrance_exam.py index d47b1274b54d..63917d17f6d5 100644 --- a/cms/djangoapps/contentstore/views/entrance_exam.py +++ b/cms/djangoapps/contentstore/views/entrance_exam.py @@ -1,5 +1,5 @@ """ -Entrance Exams view module -- handles all requests related to entrance exam management via Studio +Entrance Exams view block -- handles all requests related to entrance exam management via Studio Intended to be utilized as an AJAX callback handler, versus a proper view/screen """ @@ -24,7 +24,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order from .helpers import create_xblock, remove_entrance_exam_graders -from .item import delete_item +from .block import delete_item __all__ = ['entrance_exam', ] @@ -64,9 +64,9 @@ def entrance_exam(request, course_key_string): deleting assets, and changing the "locked" state of an asset. GET - Retrieves the entrance exam module (metadata) for the specified course + Retrieves the entrance exam block (metadata) for the specified course POST - Adds an entrance exam module to the specified course. + Adds an entrance exam block to the specified course. DELETE Removes the entrance exam from the course """ @@ -76,7 +76,7 @@ def entrance_exam(request, course_key_string): if not has_course_author_access(request.user, course_key): return HttpResponse(status=403) - # Retrieve the entrance exam module for the specified course (returns 404 if none found) + # Retrieve the entrance exam block for the specified course (returns 404 if none found) if request.method == 'GET': return _get_entrance_exam(request, course_key) @@ -94,7 +94,7 @@ def entrance_exam(request, course_key_string): return create_entrance_exam(request, course_key, entrance_exam_minimum_score_pct) return HttpResponse(status=400) - # Remove the entrance exam module for the specified course (returns 204 regardless of existence) + # Remove the entrance exam block for the specified course (returns 204 regardless of existence) elif request.method == 'DELETE': return delete_entrance_exam(request, course_key) diff --git a/cms/djangoapps/contentstore/views/helpers.py b/cms/djangoapps/contentstore/views/helpers.py index 019f32716b33..398f0f6c6311 100644 --- a/cms/djangoapps/contentstore/views/helpers.py +++ b/cms/djangoapps/contentstore/views/helpers.py @@ -200,7 +200,7 @@ def create_xblock(parent_locator, user, category, display_name, boilerplate=None if display_name is not None: metadata['display_name'] = display_name - # We should use the 'fields' kwarg for newer module settings/values (vs. metadata or data) + # We should use the 'fields' kwarg for newer block settings/values (vs. metadata or data) fields = {} # Entrance Exams: Chapter module positioning diff --git a/cms/djangoapps/contentstore/views/import_export.py b/cms/djangoapps/contentstore/views/import_export.py index b56d19d5950c..f80e0146f581 100644 --- a/cms/djangoapps/contentstore/views/import_export.py +++ b/cms/djangoapps/contentstore/views/import_export.py @@ -76,11 +76,11 @@ def import_handler(request, course_key_string): if library: successful_url = reverse_library_url('library_handler', courselike_key) context_name = 'context_library' - courselike_module = modulestore().get_library(courselike_key) + courselike_block = modulestore().get_library(courselike_key) else: successful_url = reverse_course_url('course_handler', courselike_key) context_name = 'context_course' - courselike_module = modulestore().get_course(courselike_key) + courselike_block = modulestore().get_course(courselike_key) if not has_course_author_access(request.user, courselike_key): raise PermissionDenied() @@ -94,7 +94,7 @@ def import_handler(request, course_key_string): "import_status_handler", courselike_key, kwargs={'filename': "fillerName"} ) return render_to_response('import.html', { - context_name: courselike_module, + context_name: courselike_block, 'successful_import_redirect_url': successful_url, 'import_status_url': status_url, 'library': isinstance(courselike_key, LibraryLocator) @@ -313,18 +313,18 @@ def export_handler(request, course_key_string): raise PermissionDenied() if isinstance(course_key, LibraryLocator): - courselike_module = modulestore().get_library(course_key) + courselike_block = modulestore().get_library(course_key) context = { - 'context_library': courselike_module, + 'context_library': courselike_block, 'courselike_home_url': reverse_library_url("library_handler", course_key), 'library': True } else: - courselike_module = modulestore().get_course(course_key) - if courselike_module is None: + courselike_block = modulestore().get_course(course_key) + if courselike_block is None: raise Http404 context = { - 'context_course': courselike_module, + 'context_course': courselike_block, 'courselike_home_url': reverse_course_url("course_handler", course_key), 'library': False } diff --git a/cms/djangoapps/contentstore/views/library.py b/cms/djangoapps/contentstore/views/library.py index b58ea54cccea..8ec1e79d1932 100644 --- a/cms/djangoapps/contentstore/views/library.py +++ b/cms/djangoapps/contentstore/views/library.py @@ -43,7 +43,7 @@ from ..utils import add_instructor, reverse_library_url from .component import CONTAINER_TEMPLATES, get_component_templates from .helpers import is_content_creator -from .item import create_xblock_info +from .block import create_xblock_info from .user import user_with_role __all__ = ['library_handler', 'manage_library_users'] diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index d972eb4f2227..b3297d86c7f2 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -18,7 +18,7 @@ from xmodule.contentstore.django import contentstore from xmodule.exceptions import NotFoundError, ProcessingError -from xmodule.modulestore.django import ModuleI18nService, modulestore +from xmodule.modulestore.django import XBlockI18nService, modulestore from xmodule.partitions.partitions_service import PartitionService from xmodule.services import SettingsService, TeamsConfigurationService from xmodule.studio_editable import has_author_view @@ -67,7 +67,7 @@ def preview_handler(request, usage_key_string, handler, suffix=''): usage_key = UsageKey.from_string(usage_key_string) descriptor = modulestore().get_item(usage_key) - instance = _load_preview_module(request, descriptor) + instance = _load_preview_block(request, descriptor) # Let the module handle the AJAX req = django_to_webob_request(request) @@ -98,7 +98,7 @@ class PreviewModuleSystem(ModuleSystem): # pylint: disable=abstract-method """ An XModule ModuleSystem for use in Studio previews """ - # xmodules can check for this attribute during rendering to determine if + # xblocks can check for this attribute during rendering to determine if # they are being rendered for preview (i.e. in Studio) is_author_mode = True @@ -154,7 +154,7 @@ def layout_asides(self, block, context, frag, view_name, aside_frag_fns): def _preview_module_system(request, descriptor, field_data): """ Returns a ModuleSystem for the specified descriptor that is specialized for - rendering module previews. + rendering block previews. request: The active django request descriptor: An XModuleDescriptor @@ -166,7 +166,7 @@ def _preview_module_system(request, descriptor, field_data): replace_url_service = ReplaceURLService(course_id=course_id) wrappers = [ - # This wrapper wraps the module in the template specified above + # This wrapper wraps the block in the template specified above partial( wrap_xblock, 'PreviewRuntime', @@ -207,7 +207,7 @@ def _preview_module_system(request, descriptor, field_data): preview_anonymous_user_id = anonymous_id_for_user(request.user, course_id) return PreviewModuleSystem( - get_module=partial(_load_preview_module, request), + get_block=partial(_load_preview_block, request), mixins=settings.XBLOCK_MIXINS, # Set up functions to modify the fragment produced by student_view @@ -217,7 +217,7 @@ def _preview_module_system(request, descriptor, field_data): descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access services={ "field-data": field_data, - "i18n": ModuleI18nService, + "i18n": XBlockI18nService, 'mako': mako_service, "settings": SettingsService(), "user": DjangoXBlockUserService( @@ -247,10 +247,10 @@ def get_user_group_id_for_partition(self, user, user_partition_id): return None -def _load_preview_module(request, descriptor): +def _load_preview_block(request, descriptor): """ - Return a preview XModule instantiated from the supplied descriptor. Will use mutable fields - if XModule supports an author_view. Otherwise, will use immutable fields and student_view. + Return a preview XBlock instantiated from the supplied descriptor. Will use mutable fields + if XBlock supports an author_view. Otherwise, will use immutable fields and student_view. request: The active django request descriptor: An XModuleDescriptor @@ -325,13 +325,13 @@ def get_preview_fragment(request, descriptor, context): Returns the HTML returned by the XModule's student_view or author_view (if available), specified by the descriptor and idx. """ - module = _load_preview_module(request, descriptor) + block = _load_preview_block(request, descriptor) - preview_view = AUTHOR_VIEW if has_author_view(module) else STUDENT_VIEW + preview_view = AUTHOR_VIEW if has_author_view(block) else STUDENT_VIEW try: - fragment = module.render(preview_view, context) + fragment = block.render(preview_view, context) except Exception as exc: # pylint: disable=broad-except - log.warning("Unable to render %s for %r", preview_view, module, exc_info=True) + log.warning("Unable to render %s for %r", preview_view, block, exc_info=True) fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)})) return fragment diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_block.py similarity index 99% rename from cms/djangoapps/contentstore/views/tests/test_item.py rename to cms/djangoapps/contentstore/views/tests/test_block.py index 7b413174638b..9ebc7e554bac 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_block.py @@ -1,4 +1,4 @@ -"""Tests for items views.""" +"""Tests for block views.""" import json @@ -45,7 +45,7 @@ from cms.djangoapps.contentstore.tests.utils import CourseTestCase from cms.djangoapps.contentstore.utils import reverse_course_url, reverse_usage_url -from cms.djangoapps.contentstore.views import item as item_module +from cms.djangoapps.contentstore.views import block as item_module from common.djangoapps.student.tests.factories import StaffFactory, UserFactory from common.djangoapps.xblock_django.models import ( XBlockConfiguration, @@ -57,10 +57,10 @@ from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration from ..component import component_handler, get_component_templates -from ..item import ( +from ..block import ( ALWAYS, VisibilityState, - _get_module_info, + _get_block_info, _get_source_index, _xblock_type_and_display_name, add_container_page_publishing_info, @@ -238,7 +238,7 @@ def test_get_container_nested_container_fragment(self): def test_split_test(self): """ - Test that a split_test module renders all of its children in Studio. + Test that a split_test block renders all of its children in Studio. """ root_usage_key = self._create_vertical() resp = self.create_xblock(category='split_test', parent_usage_key=root_usage_key) @@ -305,7 +305,7 @@ def test_valid_paging(self): """ Tests that valid paging is passed along to underlying block """ - with patch('cms.djangoapps.contentstore.views.item.get_preview_fragment') as patched_get_preview_fragment: + with patch('cms.djangoapps.contentstore.views.block.get_preview_fragment') as patched_get_preview_fragment: retval = Mock() type(retval).content = PropertyMock(return_value="Some content") type(retval).resources = PropertyMock(return_value=[]) @@ -447,7 +447,7 @@ def assert_xblock_info(xblock, xblock_info): xblock = parent_xblock else: self.assertNotIn('ancestors', response) - self.assertEqual(_get_module_info(xblock), response) + self.assertEqual(_get_block_info(xblock), response) @ddt.ddt @@ -510,7 +510,7 @@ def test_create_nicely(self): self.assertEqual(problem.display_name, template['metadata']['display_name']) self.assertEqual(problem.markdown, template['metadata']['markdown']) - def test_create_item_negative(self): + def test_create_block_negative(self): """ Negative tests for create_item """ @@ -1208,7 +1208,7 @@ def test_move_component_nonsensical_access_restriction_validation(self): validation = html.validate() self.assertEqual(len(validation.messages), 0) - @patch('cms.djangoapps.contentstore.views.item.log') + @patch('cms.djangoapps.contentstore.views.block.log') def test_move_logging(self, mock_logger): """ Test logging when an item is successfully moved. @@ -1886,7 +1886,7 @@ def test_editing_view_wrappers(self): class TestEditSplitModule(ItemTest): """ - Tests around editing instances of the split_test module. + Tests around editing instances of the split_test block. """ def setUp(self): @@ -1935,7 +1935,7 @@ def _update_partition_id(self, partition_id): self.client.ajax_post( self.split_test_update_url, # Even though user_partition_id is Scope.content, it will get saved by the Studio editor as - # metadata. The code in item.py will update the field correctly, even though it is not the + # metadata. The code in block.py will update the field correctly, even though it is not the # expected scope. data={'metadata': {'user_partition_id': str(partition_id)}} ) @@ -1956,7 +1956,7 @@ def _assert_children(self, expected_number): def test_create_groups(self): """ Test that verticals are created for the configuration groups when - a spit test module is edited. + a spit test block is edited. """ split_test = self.get_item_from_modulestore(self.split_test_usage_key, verify_is_draft=True) # Initially, no user_partition_id is set, and the split_test has no children. @@ -3052,7 +3052,7 @@ def test_add_xblock(self): def test_no_add_discussion(self): """ - Verify we cannot add a discussion module to a Library. + Verify we cannot add a discussion block to a Library. """ lib = LibraryFactory.create() response = self.create_xblock(parent_usage_key=lib.location, display_name='Test', category='discussion') diff --git a/cms/djangoapps/contentstore/views/tests/test_container_page.py b/cms/djangoapps/contentstore/views/tests/test_container_page.py index 1759a959627b..986d2c4485e9 100644 --- a/cms/djangoapps/contentstore/views/tests/test_container_page.py +++ b/cms/djangoapps/contentstore/views/tests/test_container_page.py @@ -31,25 +31,25 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase): def setUp(self): super().setUp() - self.vertical = self._create_item(self.sequential.location, 'vertical', 'Unit') - self.html = self._create_item(self.vertical.location, "html", "HTML") - self.child_container = self._create_item(self.vertical.location, 'split_test', 'Split Test') - self.child_vertical = self._create_item(self.child_container.location, 'vertical', 'Child Vertical') - self.video = self._create_item(self.child_vertical.location, "video", "My Video") + self.vertical = self._create_block(self.sequential.location, 'vertical', 'Unit') + self.html = self._create_block(self.vertical.location, "html", "HTML") + self.child_container = self._create_block(self.vertical.location, 'split_test', 'Split Test') + self.child_vertical = self._create_block(self.child_container.location, 'vertical', 'Child Vertical') + self.video = self._create_block(self.child_vertical.location, "video", "My Video") self.store = modulestore() past = datetime.datetime(1970, 1, 1, tzinfo=UTC) future = datetime.datetime.now(UTC) + datetime.timedelta(days=1) - self.released_private_vertical = self._create_item( + self.released_private_vertical = self._create_block( parent_location=self.sequential.location, category='vertical', display_name='Released Private Unit', start=past) - self.unreleased_private_vertical = self._create_item( + self.unreleased_private_vertical = self._create_block( parent_location=self.sequential.location, category='vertical', display_name='Unreleased Private Unit', start=future) - self.released_public_vertical = self._create_item( + self.released_public_vertical = self._create_block( parent_location=self.sequential.location, category='vertical', display_name='Released Public Unit', start=past) - self.unreleased_public_vertical = self._create_item( + self.unreleased_public_vertical = self._create_block( parent_location=self.sequential.location, category='vertical', display_name='Unreleased Public Unit', start=future) self.store.publish(self.unreleased_public_vertical.location, self.user.id) @@ -81,8 +81,8 @@ def test_container_on_container_html(self): Create the scenario of an xblock with children (non-vertical) on the container page. This should create a container page that is a child of another container page. """ - draft_container = self._create_item(self.child_container.location, "wrapper", "Wrapper") - self._create_item(draft_container.location, "html", "Child HTML") + draft_container = self._create_block(self.child_container.location, "wrapper", "Wrapper") + self._create_block(draft_container.location, "html", "Child HTML") def test_container_html(xblock): self._test_html_content( @@ -177,9 +177,9 @@ def test_draft_container_preview_html(self): self.validate_preview_html(self.child_container, self.container_view) self.validate_preview_html(self.child_vertical, self.reorderable_child_view) - def _create_item(self, parent_location, category, display_name, **kwargs): + def _create_block(self, parent_location, category, display_name, **kwargs): """ - creates an item in the module store, without publishing it. + creates a block in the module store, without publishing it. """ return BlockFactory.create( parent_location=parent_location, @@ -194,7 +194,7 @@ def test_public_child_container_preview_html(self): """ Verify that a public container rendered as a child of the container page returns the expected HTML. """ - empty_child_container = self._create_item(self.vertical.location, 'split_test', 'Split Test') + empty_child_container = self._create_block(self.vertical.location, 'split_test', 'Split Test') published_empty_child_container = self.store.publish(empty_child_container.location, self.user.id) self.validate_preview_html(published_empty_child_container, self.reorderable_child_view, can_add=False) @@ -202,7 +202,7 @@ def test_draft_child_container_preview_html(self): """ Verify that a draft container rendered as a child of the container page returns the expected HTML. """ - empty_child_container = self._create_item(self.vertical.location, 'split_test', 'Split Test') + empty_child_container = self._create_block(self.vertical.location, 'split_test', 'Split Test') self.validate_preview_html(empty_child_container, self.reorderable_child_view, can_add=False) @patch( diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index 5bff99d6be92..cf9f2a4197ae 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -39,7 +39,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory, LibraryFactory, check_mongo_calls # lint-amnesty, pylint: disable=wrong-import-order from ..course import _deprecated_blocks_info, course_outline_initial_state, reindex_course_and_check_access -from ..item import VisibilityState, create_xblock_info +from ..block import VisibilityState, create_xblock_info class TestCourseIndex(CourseTestCase): diff --git a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py index 57bbc114f7b2..2ac8d56c9579 100644 --- a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py +++ b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py @@ -105,7 +105,7 @@ def test_contentstore_views_entrance_exam_post(self): resp = self.client.get(self.exam_url) self.assertEqual(resp.status_code, 200) - # Reload the test course now that the exam module has been added + # Reload the test course now that the exam block has been added self.course = modulestore().get_course(self.course.id) metadata = CourseMetadata.fetch_all(self.course) self.assertTrue(metadata['entrance_exam_enabled']) @@ -128,10 +128,10 @@ def test_contentstore_views_entrance_exam_post_new_sequential_confirm_grader(sel resp = self.client.get(self.exam_url) self.assertEqual(resp.status_code, 200) - # Reload the test course now that the exam module has been added + # Reload the test course now that the exam block has been added self.course = modulestore().get_course(self.course.id) - # Add a new child sequential to the exam module + # Add a new child sequential to the exam block # Confirm that the grader type is 'Entrance Exam' chapter_locator_string = json.loads(resp.content.decode('utf-8')).get('locator') # chapter_locator = UsageKey.from_string(chapter_locator_string) @@ -194,7 +194,7 @@ def test_contentstore_views_entrance_exam_delete(self): self.assertEqual(len(paths[milestone_key]), 0) # Re-adding an entrance exam to the course should fix the missing link - # It wipes out any old entrance exam artifacts and inserts a new exam course chapter/module + # It wipes out any old entrance exam artifacts and inserts a new exam course chapter/block resp = self.client.post(self.exam_url, {}, http_accept='application/json') self.assertEqual(resp.status_code, 201) resp = self.client.get(self.exam_url) diff --git a/cms/djangoapps/contentstore/views/tests/test_gating.py b/cms/djangoapps/contentstore/views/tests/test_gating.py index 62ab8aacc0de..9f96e57f9356 100644 --- a/cms/djangoapps/contentstore/views/tests/test_gating.py +++ b/cms/djangoapps/contentstore/views/tests/test_gating.py @@ -14,7 +14,7 @@ from cms.djangoapps.contentstore.utils import reverse_usage_url from openedx.core.lib.gating.api import GATING_NAMESPACE_QUALIFIER -from ..item import VisibilityState +from ..block import VisibilityState @ddt.ddt @@ -57,7 +57,7 @@ def setUp(self): ) self.seq2_url = reverse_usage_url('xblock_handler', self.seq2.location) - @patch('cms.djangoapps.contentstore.views.item.gating_api.add_prerequisite') + @patch('cms.djangoapps.contentstore.views.block.gating_api.add_prerequisite') def test_add_prerequisite(self, mock_add_prereq): """ Test adding a subsection as a prerequisite @@ -69,7 +69,7 @@ def test_add_prerequisite(self, mock_add_prereq): ) mock_add_prereq.assert_called_with(self.course.id, self.seq1.location) - @patch('cms.djangoapps.contentstore.views.item.gating_api.remove_prerequisite') + @patch('cms.djangoapps.contentstore.views.block.gating_api.remove_prerequisite') def test_remove_prerequisite(self, mock_remove_prereq): """ Test removing a subsection as a prerequisite @@ -81,7 +81,7 @@ def test_remove_prerequisite(self, mock_remove_prereq): ) mock_remove_prereq.assert_called_with(self.seq1.location) - @patch('cms.djangoapps.contentstore.views.item.gating_api.set_required_content') + @patch('cms.djangoapps.contentstore.views.block.gating_api.set_required_content') def test_add_gate(self, mock_set_required_content): """ Test adding a gated subsection @@ -100,7 +100,7 @@ def test_add_gate(self, mock_set_required_content): '100' ) - @patch('cms.djangoapps.contentstore.views.item.gating_api.set_required_content') + @patch('cms.djangoapps.contentstore.views.block.gating_api.set_required_content') def test_remove_gate(self, mock_set_required_content): """ Test removing a gated subsection @@ -118,9 +118,9 @@ def test_remove_gate(self, mock_set_required_content): '' ) - @patch('cms.djangoapps.contentstore.views.item.gating_api.get_prerequisites') - @patch('cms.djangoapps.contentstore.views.item.gating_api.get_required_content') - @patch('cms.djangoapps.contentstore.views.item.gating_api.is_prerequisite') + @patch('cms.djangoapps.contentstore.views.block.gating_api.get_prerequisites') + @patch('cms.djangoapps.contentstore.views.block.gating_api.get_required_content') + @patch('cms.djangoapps.contentstore.views.block.gating_api.is_prerequisite') @ddt.data( (90, None), (None, 90), diff --git a/cms/djangoapps/contentstore/views/tests/test_import_export.py b/cms/djangoapps/contentstore/views/tests/test_import_export.py index 04d34ee4df39..7b6a68964ee1 100644 --- a/cms/djangoapps/contentstore/views/tests/test_import_export.py +++ b/cms/djangoapps/contentstore/views/tests/test_import_export.py @@ -51,7 +51,7 @@ ErrorReadingFileException, import_course_from_xml, import_library_from_xml, - ModuleFailedToImport, + BlockFailedToImport, ) TASK_LOGGER = 'cms.djangoapps.contentstore.tasks.LOGGER' @@ -124,7 +124,7 @@ def test_import_delete_pre_exiting_entrance_exam(self): resp = self.client.post(exam_url, {'entrance_exam_minimum_score_pct': 0.5}, http_accept='application/json') self.assertEqual(resp.status_code, 201) - # Reload the test course now that the exam module has been added + # Reload the test course now that the exam block has been added self.course = modulestore().get_course(self.course.id) metadata = CourseMetadata.fetch_all(self.course) self.assertTrue(metadata['entrance_exam_enabled']) @@ -460,7 +460,7 @@ def test_library_import(self): self.user.id, settings.GITHUB_REPO_ROOT, [extract_dir_relative / 'library'], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore(), target_id=lib_key ) @@ -505,7 +505,7 @@ def test_library_import_branch_settings(self, branch_setting): self.user.id, settings.GITHUB_REPO_ROOT, [extract_dir_relative / 'library'], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore(), target_id=lib_key ) @@ -540,7 +540,7 @@ def test_library_import_branch_settings_again(self, branch_setting): [extract_dir_relative / 'library'], static_content_store=source_content, target_id=source_library_key, - load_error_modules=False, + load_error_blocks=False, raise_on_failure=True, create_if_not_present=True, ) @@ -639,7 +639,7 @@ def test_import_failed_with_olx_validations(self, mocked_report, mocked_summary, ), (DuplicateCourseError("foo", "foobar"), 'Cannot create course foo, which duplicates foobar'), (ErrorReadingFileException("assets.xml"), "Error while reading assets.xml. Check file for XML errors."), - (ModuleFailedToImport("Unit 1", "foo/bar"), "Failed to import module: Unit 1 at location: foo/bar"), + (BlockFailedToImport("Unit 1", "foo/bar"), "Failed to import block: Unit 1 at location: foo/bar"), ) @ddt.unpack def test_import_failure_is_descriptive_for_known_failures(self, exc, expected_mesg, mocked_import, mocked_log): @@ -840,7 +840,7 @@ def _verify_export_failure(self, expected_text): self.assertNotIn('ExportOutput', result) self.assertIn('ExportError', result) error = result['ExportError'] - self.assertIn('Unable to create xml for module', error['raw_error_msg']) + self.assertIn('Unable to create xml for block', error['raw_error_msg']) self.assertIn(expected_text, error['edit_unit_url']) def test_library_export(self): @@ -1033,7 +1033,7 @@ def test_content_library_export_import(self): ['library_empty_problem'], static_content_store=contentstore(), target_id=source_library1_key, - load_error_modules=False, + load_error_blocks=False, raise_on_failure=True, create_if_not_present=True, ) @@ -1057,7 +1057,7 @@ def test_content_library_export_import(self): ['exported_source_library'], static_content_store=contentstore(), target_id=source_library2_key, - load_error_modules=False, + load_error_blocks=False, raise_on_failure=True, create_if_not_present=True, ) @@ -1184,7 +1184,7 @@ def test_library_content_on_course_export_import(self, publish_item, generate_ve ['exported_source_course'], static_content_store=contentstore(), target_id=dest_course.location.course_key, - load_error_modules=False, + load_error_blocks=False, raise_on_failure=True, create_if_not_present=True, ) @@ -1314,7 +1314,7 @@ def test_problem_content_on_course_export_import(self, problem_data, expected_pr ['exported_source_course'], static_content_store=contentstore(), target_id=dest_course.location.course_key, - load_error_modules=False, + load_error_blocks=False, raise_on_failure=True, create_if_not_present=True, ) diff --git a/cms/djangoapps/contentstore/views/tests/test_transcripts.py b/cms/djangoapps/contentstore/views/tests/test_transcripts.py index 07b5e52705bd..56391560e78c 100644 --- a/cms/djangoapps/contentstore/views/tests/test_transcripts.py +++ b/cms/djangoapps/contentstore/views/tests/test_transcripts.py @@ -102,7 +102,7 @@ def setUp(self): modulestore().update_item(self.item, self.user.id) self.item = modulestore().get_item(self.video_usage_key) - # Remove all transcripts for current module. + # Remove all transcripts for current block. self.clear_subs_content() def _get_usage_key(self, resp): @@ -331,7 +331,7 @@ def test_transcript_upload_unknown_category(self): self.assert_response( response, expected_status_code=400, - expected_message='Transcripts are supported only for "video" modules.' + expected_message='Transcripts are supported only for "video" blocks.' ) def test_transcript_upload_non_existent_item(self): @@ -496,7 +496,7 @@ def test_choose_transcript_fails_on_unknown_category(self): self.assert_response( response, expected_status_code=400, - expected_message='Transcripts are supported only for "video" modules.' + expected_message='Transcripts are supported only for "video" blocks.' ) @@ -618,7 +618,7 @@ def test_rename_transcript_fails_on_unknown_category(self): self.assert_response( response, expected_status_code=400, - expected_message='Transcripts are supported only for "video" modules.' + expected_message='Transcripts are supported only for "video" blocks.' ) @@ -753,7 +753,7 @@ def test_replace_transcript_fails_on_unknown_category(self): self.assert_response( response, expected_status_code=400, - expected_message='Transcripts are supported only for "video" modules.' + expected_message='Transcripts are supported only for "video" blocks.' ) @@ -1077,7 +1077,7 @@ def test_fail_for_non_video_block(self): self.assertEqual(resp.status_code, 400) self.assertEqual( json.loads(resp.content.decode('utf-8')).get('status'), - 'Transcripts are supported only for "video" modules.', + 'Transcripts are supported only for "video" blocks.', ) @patch('xmodule.video_block.transcripts_utils.get_video_transcript_content') diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py index a27ae4a4bf83..9c2042099665 100644 --- a/cms/djangoapps/contentstore/views/transcripts_ajax.py +++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py @@ -2,7 +2,7 @@ Actions manager for transcripts ajax calls. +++++++++++++++++++++++++++++++++++++++++++ -Module do not support rollback (pressing "Cancel" button in Studio) +Blocks do not support rollback (pressing "Cancel" button in Studio) All user changes are saved immediately. """ @@ -143,7 +143,7 @@ def validate_video_block(request, locator): try: item = _get_item(request, {'locator': locator}) if item.category != 'video': - error = _('Transcripts are supported only for "video" modules.') + error = _('Transcripts are supported only for "video" blocks.') except (InvalidKeyError, ItemNotFoundError): error = _('Cannot find item by locator.') @@ -189,7 +189,7 @@ def validate_transcript_upload_data(request): @login_required def upload_transcripts(request): """ - Upload transcripts for current module. + Upload transcripts for current block. returns: response dict:: @@ -455,7 +455,7 @@ def _validate_transcripts_data(request): raise TranscriptsRequestValidationException(_("Can't find item by locator.")) # lint-amnesty, pylint: disable=raise-missing-from if item.category != 'video': - raise TranscriptsRequestValidationException(_('Transcripts are supported only for "video" modules.')) + raise TranscriptsRequestValidationException(_('Transcripts are supported only for "video" blocks.')) # parse data form request.GET.['data']['video'] to useful format videos = {'youtube': '', 'html5': {}} diff --git a/common/djangoapps/util/block_utils.py b/common/djangoapps/util/block_utils.py new file mode 100644 index 000000000000..7c84ace75c7d --- /dev/null +++ b/common/djangoapps/util/block_utils.py @@ -0,0 +1,36 @@ +""" +Utility library containing operations used/shared by multiple CourseBlocks. +""" + + +def yield_dynamic_descriptor_descendants(descriptor, user_id, block_creator=None): + """ + This returns all of the descendants of a descriptor. If the descriptor + has dynamic children, the block will be created using block_creator + and the children (as descriptors) of that module will be returned. + """ + stack = [descriptor] + + while len(stack) > 0: + next_descriptor = stack.pop() + stack.extend(get_dynamic_descriptor_children(next_descriptor, user_id, block_creator)) + yield next_descriptor + + +def get_dynamic_descriptor_children(descriptor, user_id, block_creator=None, usage_key_filter=None): + """ + Returns the children of the given descriptor, while supporting descriptors with dynamic children. + """ + block_children = [] + if descriptor.has_dynamic_children(): + block = None + if descriptor.scope_ids.user_id and user_id == descriptor.scope_ids.user_id: + # do not rebind the block if it's already bound to a user. + block = descriptor + elif block_creator: + block = block_creator(descriptor) + if block: + block_children = block.get_child_descriptors() + else: + block_children = descriptor.get_children(usage_key_filter) + return block_children diff --git a/common/djangoapps/util/module_utils.py b/common/djangoapps/util/module_utils.py deleted file mode 100644 index bb51521a8968..000000000000 --- a/common/djangoapps/util/module_utils.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -Utility library containing operations used/shared by multiple courseware modules -""" - - -def yield_dynamic_descriptor_descendants(descriptor, user_id, module_creator=None): - """ - This returns all of the descendants of a descriptor. If the descriptor - has dynamic children, the module will be created using module_creator - and the children (as descriptors) of that module will be returned. - """ - stack = [descriptor] - - while len(stack) > 0: - next_descriptor = stack.pop() - stack.extend(get_dynamic_descriptor_children(next_descriptor, user_id, module_creator)) - yield next_descriptor - - -def get_dynamic_descriptor_children(descriptor, user_id, module_creator=None, usage_key_filter=None): - """ - Returns the children of the given descriptor, while supporting descriptors with dynamic children. - """ - module_children = [] - if descriptor.has_dynamic_children(): - module = None - if descriptor.scope_ids.user_id and user_id == descriptor.scope_ids.user_id: - # do not rebind the module if it's already bound to a user. - module = descriptor - elif module_creator: - module = module_creator(descriptor) - if module: - module_children = module.get_child_descriptors() - else: - module_children = descriptor.get_children(usage_key_filter) - return module_children diff --git a/common/test/data/conditional/README.md b/common/test/data/conditional/README.md index f44ef84fe8ed..4dd46d70d76e 100644 --- a/common/test/data/conditional/README.md +++ b/common/test/data/conditional/README.md @@ -1,4 +1,4 @@ -Course for testing conditional module. +Course for testing conditional block. Note that 'i4x://edX/different_course/html/for_testing_import_rewrites' in sources is only present for testing that import does NOT rewrite references to @@ -6,4 +6,4 @@ courses that differ from the original course being imported. It is not expected that i4x://edX/different_course/html/for_testing_import_rewrites will render. - + diff --git a/common/test/data/simple/README.md b/common/test/data/simple/README.md index 69ff6b4ed099..e4e63fca56a3 100644 --- a/common/test/data/simple/README.md +++ b/common/test/data/simple/README.md @@ -1,2 +1,2 @@ -This is a simple, but non-trivial, course using multiple module types and some nested structure. - +This is a simple, but non-trivial, course using multiple block types and some nested structure. + diff --git a/common/test/data/simple_with_draft/README.md b/common/test/data/simple_with_draft/README.md index 69ff6b4ed099..e4e63fca56a3 100644 --- a/common/test/data/simple_with_draft/README.md +++ b/common/test/data/simple_with_draft/README.md @@ -1,2 +1,2 @@ -This is a simple, but non-trivial, course using multiple module types and some nested structure. - +This is a simple, but non-trivial, course using multiple block types and some nested structure. + diff --git a/conf/locale/ar/LC_MESSAGES/django.po b/conf/locale/ar/LC_MESSAGES/django.po index d40a7c8d8ce1..77ad9435984f 100644 --- a/conf/locale/ar/LC_MESSAGES/django.po +++ b/conf/locale/ar/LC_MESSAGES/django.po @@ -270,7 +270,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "نصّ" @@ -13127,63 +13127,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "بيانات غير صالحة" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "بيانات غير صالحة ({details}) " -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "لا يمكنك نقل {source_type} إلى {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "العنصر موجود من قبل في الموقع الهدف." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "لا يمكنك نقل عنصر إلى نفسه." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "لا يمكنك نقل عنصر إلى فرعه." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "لا يمكنك نقل عنصر مباشرة إلى تجربة المحتوى." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} غير موجود في {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "لا يمكنك نقل {source_usage_key} في فهرس غير صالح ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "يجب إدخال target_index ({target_index}) كعدد صحيح." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "نسخة مطابقة لـ {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "نسخة مطابقة لـ ’{0}‘" @@ -13191,7 +13191,7 @@ msgstr "نسخة مطابقة لـ ’{0}‘" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13201,11 +13201,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/ca/LC_MESSAGES/django.po b/conf/locale/ca/LC_MESSAGES/django.po index c62089e15852..13bdd02cc7eb 100644 --- a/conf/locale/ca/LC_MESSAGES/django.po +++ b/conf/locale/ca/LC_MESSAGES/django.po @@ -80,7 +80,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11710,64 +11710,64 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Dades invàlides" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Dades no vàlides ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "No podeu moure {source_type} a {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "L'element ja està present a la ubicació d'orientació." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "No podeu moure un element a si mateix." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "No podeu moure un element a un element secundari." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "No podeu moure un element directament a l'experiment de contingut." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} no s'ha trobat a {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" "No podeu moure {source_usage_key} a un índex no vàlid ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Heu de proporcionar target_index ({target_index}) com un enter." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplicat de {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplicat de '{0}'" @@ -11775,7 +11775,7 @@ msgstr "Duplicat de '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11785,11 +11785,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/de_DE/LC_MESSAGES/django.po b/conf/locale/de_DE/LC_MESSAGES/django.po index bc545a2df7d3..8273ad8d693b 100644 --- a/conf/locale/de_DE/LC_MESSAGES/django.po +++ b/conf/locale/de_DE/LC_MESSAGES/django.po @@ -189,7 +189,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Text" @@ -13263,49 +13263,49 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Bibliotheken können nicht mehr als {limit} Komponenten beinhalten." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Ungültige Daten" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Ungültige Daten ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Sie können {source_type} nicht nach {target_parent_type} verschieben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Gegenstand bereits am Zielort vorhanden." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Sie können ein Objekte nicht auf sich selbst verschieben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" "Sie können ein Objekt nicht zu seinem eigenen Unterobjekt verschieben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Sie können ein Objekt nicht direkt in ein Inhaltsexperiment verschieben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} nicht in {parent_usage_key} gefunden." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -13313,17 +13313,17 @@ msgstr "" "Sie können {source_usage_key} nicht zu einem ungültigen index " "({target_index}) verschieben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Sie müssen einen target_index ({target_index}) als integer angeben." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Kopie von '{0}'" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplikat von '{0}'" @@ -13331,7 +13331,7 @@ msgstr "Duplikat von '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13341,11 +13341,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/el/LC_MESSAGES/django.po b/conf/locale/el/LC_MESSAGES/django.po index 5aa75ebf12c0..12f932ec6c7f 100644 --- a/conf/locale/el/LC_MESSAGES/django.po +++ b/conf/locale/el/LC_MESSAGES/django.po @@ -104,7 +104,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11921,63 +11921,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Μη έγκυρα δεδομένα" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -11985,7 +11985,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11993,11 +11993,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/en/LC_MESSAGES/django.po b/conf/locale/en/LC_MESSAGES/django.po index 9e2fa21ed076..b9c91ea3cf63 100644 --- a/conf/locale/en/LC_MESSAGES/django.po +++ b/conf/locale/en/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11706,63 +11706,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -11770,7 +11770,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11778,11 +11778,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/eo/LC_MESSAGES/django.po b/conf/locale/eo/LC_MESSAGES/django.po index 524d0b9f85fa..506f6ba2711b 100644 --- a/conf/locale/eo/LC_MESSAGES/django.po +++ b/conf/locale/eo/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Téxt Ⱡ'σяєм ι#" @@ -15147,61 +15147,61 @@ msgstr "" "Fïlé üplöäd fäïléd. Pléäsé trý ägäïn Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " "¢σηѕє¢тєтυ#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" "Lïßrärïés çännöt hävé möré thän {limit} çömpönénts Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт " "αмєт, ¢σηѕє¢тєтυя α#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Ìnvälïd dätä Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Ìnvälïd dätä ({details}) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" "Ýöü çän nöt mövé {source_type} ïntö {target_parent_type}. Ⱡ'σяєм ιρѕυм ∂σłσя" " ѕιт αмєт, ¢σηѕє¢т#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" "Ìtém ïs älréädý présént ïn tärgét löçätïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " "¢σηѕє¢тєтυя #" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" "Ýöü çän nöt mövé än ïtém ïntö ïtsélf. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " "¢σηѕє¢тєтυ#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" "Ýöü çän nöt mövé än ïtém ïntö ït's çhïld. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " "¢σηѕє¢тєтυя #" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Ýöü çän nöt mövé än ïtém dïréçtlý ïntö çöntént éxpérïmént. Ⱡ'σяєм ιρѕυм " "∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" "{source_usage_key} nöt föünd ïn {parent_usage_key}. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт " "αмєт, #" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -15209,19 +15209,19 @@ msgstr "" "Ýöü çän nöt mövé {source_usage_key} ät än ïnvälïd ïndéx ({target_index}). " "Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" "Ýöü müst prövïdé tärgét_ïndéx ({target_index}) äs än ïntégér. Ⱡ'σяєм ιρѕυм " "∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Düplïçäté öf {0} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Düplïçäté öf '{0}' Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#" @@ -15229,7 +15229,7 @@ msgstr "Düplïçäté öf '{0}' Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -15239,11 +15239,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "% Ⱡ#" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\" Ⱡ'σяєм ιρѕυм ∂σł#" diff --git a/conf/locale/es_419/LC_MESSAGES/django.po b/conf/locale/es_419/LC_MESSAGES/django.po index de937795fd3a..822b27fd76d2 100644 --- a/conf/locale/es_419/LC_MESSAGES/django.po +++ b/conf/locale/es_419/LC_MESSAGES/django.po @@ -287,7 +287,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Texto" @@ -13700,66 +13700,66 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "Error al cargar el archivo. Inténtalo de nuevo" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Las librerías no pueden tener más de {limit} componentes" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Datos inválidos" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Datos inválidos ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "No puedes mover {source_type} dentro de {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Este elemento ya está presente en la ubicación de destino." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "No puedes mover un elemento dentro de él mismo." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "No puedes mover un elemento dentro de un elemento hijo." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "No puedes mover un elemento directamente dentro del experimento de " "contenido." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} no encontrado en {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" "No puedes mover {source_usage_key} en un índice inválido ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Debes proveer target_index ({target_index}) como un entero." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplicado de {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplicado de '{0}'" @@ -13767,7 +13767,7 @@ msgstr "Duplicado de '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13777,11 +13777,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/eu_ES/LC_MESSAGES/django.po b/conf/locale/eu_ES/LC_MESSAGES/django.po index cc2bfa37c315..96d3dc60996a 100644 --- a/conf/locale/eu_ES/LC_MESSAGES/django.po +++ b/conf/locale/eu_ES/LC_MESSAGES/django.po @@ -77,7 +77,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Testua" @@ -11947,63 +11947,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Datu baliogabea" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Datu baliogabea ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -12011,7 +12011,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12019,11 +12019,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr " {section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/fr/LC_MESSAGES/django.po b/conf/locale/fr/LC_MESSAGES/django.po index 9f495f821f57..d518735929f8 100644 --- a/conf/locale/fr/LC_MESSAGES/django.po +++ b/conf/locale/fr/LC_MESSAGES/django.po @@ -329,7 +329,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Texte" @@ -13744,49 +13744,49 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "Le téléchargement du fichier a échoué. Veuillez réessayer" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Les bibliothèques ne peuvent pas avoir plus de {limit} composants" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Donnée invalide" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Donnée invalide ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Vous ne pouvez pas déplacer {target_parent_type} dans {source_type}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Élément déjà présent dans l'emplacement cible." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Vous ne pouvez pas déplacer un élément vers lui-même." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Vous ne pouvez pas déplacer un élément vers un de ses enfants." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Vous ne pouvez pas déplacer un élément vers un contenu expérimental " "directement." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} pas trouvé dans {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -13794,18 +13794,18 @@ msgstr "" "Vous ne pouvez pas déplacer {source_usage_key} vers un index non valable " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" "Vous devez fournir l'index_cible ({target_index}) en un nombre entier." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplication de {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplication de '{0}'" @@ -13813,7 +13813,7 @@ msgstr "Duplication de '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13823,11 +13823,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/he/LC_MESSAGES/django.po b/conf/locale/he/LC_MESSAGES/django.po index def0ef19b192..d29bdaef1f8a 100644 --- a/conf/locale/he/LC_MESSAGES/django.po +++ b/conf/locale/he/LC_MESSAGES/django.po @@ -11842,63 +11842,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "נתונים לא חוקיים" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "נתונים לא חוקיים ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "העתקה של {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "העתקה של '{0}'" @@ -11906,7 +11906,7 @@ msgstr "העתקה של '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11916,11 +11916,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/hi/LC_MESSAGES/django.po b/conf/locale/hi/LC_MESSAGES/django.po index 3fa9fbbf60c1..3ecb5136ab19 100644 --- a/conf/locale/hi/LC_MESSAGES/django.po +++ b/conf/locale/hi/LC_MESSAGES/django.po @@ -11189,63 +11189,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -11253,7 +11253,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11261,11 +11261,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/id/LC_MESSAGES/django.po b/conf/locale/id/LC_MESSAGES/django.po index ffaf96bbf2c2..de623b6ddcfb 100644 --- a/conf/locale/id/LC_MESSAGES/django.po +++ b/conf/locale/id/LC_MESSAGES/django.po @@ -118,7 +118,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Teks" @@ -12486,63 +12486,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Data tidak valid" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Data tidak valid ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplikasi dari {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplikasi '{0}'" @@ -12550,7 +12550,7 @@ msgstr "Duplikasi '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12558,11 +12558,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/it_IT/LC_MESSAGES/django.po b/conf/locale/it_IT/LC_MESSAGES/django.po index b5c4feb877dd..805d56231d18 100644 --- a/conf/locale/it_IT/LC_MESSAGES/django.po +++ b/conf/locale/it_IT/LC_MESSAGES/django.po @@ -140,7 +140,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Testo" @@ -13584,49 +13584,49 @@ msgstr "Alcuni blocchi mancanti nel caricamento del file. Provare di nuovo." msgid "File upload failed. Please try again" msgstr "Caricamento del file non riuscito. Per favore riprova" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Le librerie non possono avere più di {limit} componenti" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Dati non validi" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Dati non validi ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "È possibile spostare {source_type} in {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Elemento già presente nell'ubicazione di destinazione." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Non è possibile spostare un elemento in se stesso." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Non è possibile spostare un elemento nel proprio elemento secondario." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Non è possibile spostare un elemento direttamente nell'esperimento del " "contenuto." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} non trovato in {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -13634,17 +13634,17 @@ msgstr "" "Non è possibile spostare {source_usage_key} in un indice non valido " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "target_index ({target_index}) deve essere un numero intero." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplicato di {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplicato di '{0}'" @@ -13652,7 +13652,7 @@ msgstr "Duplicato di '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13662,11 +13662,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/ja_JP/LC_MESSAGES/django.po b/conf/locale/ja_JP/LC_MESSAGES/django.po index e410f15347aa..d1b9a70e0cfd 100644 --- a/conf/locale/ja_JP/LC_MESSAGES/django.po +++ b/conf/locale/ja_JP/LC_MESSAGES/django.po @@ -127,7 +127,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "テキスト" @@ -11819,63 +11819,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "無効なデータ" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "無効なデータ ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "{source_type}を{target_parent_type}に移動できません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "ご希望のロケーションに既にアイテムがあります。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "アイテムを同じ場所には移動できません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "アイテムを子へ移動することはできません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "コンテンツテストに直接アイテムを移動することはできません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{parent_usage_key}内に{source_usage_key}がありません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "無効な見出し({target_index})のため、{source_usage_key}は移動できません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "target_index ({target_index}) は整数でなければいけません。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "'{0}' の重複" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "'{0}' の重複" @@ -11883,7 +11883,7 @@ msgstr "'{0}' の重複" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11891,11 +11891,11 @@ msgstr "受講者が教材にアクセスするには {score}{pct_sign}以上の #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/ka/LC_MESSAGES/django.po b/conf/locale/ka/LC_MESSAGES/django.po index 68c88e409b34..19c07b38fef8 100644 --- a/conf/locale/ka/LC_MESSAGES/django.po +++ b/conf/locale/ka/LC_MESSAGES/django.po @@ -73,7 +73,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "ტექსტი" @@ -12342,63 +12342,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "არასწორი მონაცემები" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "არასწორი მონაცემები ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "{0}-ის ასლი" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "'{0}'-ის ასლი" @@ -12406,7 +12406,7 @@ msgstr "'{0}'-ის ასლი" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12416,11 +12416,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/lt_LT/LC_MESSAGES/django.po b/conf/locale/lt_LT/LC_MESSAGES/django.po index f4f2a1c14a55..0735865ee24c 100644 --- a/conf/locale/lt_LT/LC_MESSAGES/django.po +++ b/conf/locale/lt_LT/LC_MESSAGES/django.po @@ -85,7 +85,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11659,63 +11659,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Neteisingi duomenys" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Neteisingi duomenys: ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "{0} kopija" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr " '{0}' kopija" @@ -11723,7 +11723,7 @@ msgstr " '{0}' kopija" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11733,11 +11733,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/lv/LC_MESSAGES/django.po b/conf/locale/lv/LC_MESSAGES/django.po index 7f1c1ea56f16..6e70f4588b38 100644 --- a/conf/locale/lv/LC_MESSAGES/django.po +++ b/conf/locale/lv/LC_MESSAGES/django.po @@ -62,7 +62,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Teksts" @@ -12532,63 +12532,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -12596,7 +12596,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12604,11 +12604,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/mn/LC_MESSAGES/django.po b/conf/locale/mn/LC_MESSAGES/django.po index 1f51b93d98a9..9f559ba59892 100644 --- a/conf/locale/mn/LC_MESSAGES/django.po +++ b/conf/locale/mn/LC_MESSAGES/django.po @@ -87,7 +87,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11737,63 +11737,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "" @@ -11801,7 +11801,7 @@ msgstr "" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11809,11 +11809,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "" diff --git a/conf/locale/pl/LC_MESSAGES/django.po b/conf/locale/pl/LC_MESSAGES/django.po index 83298e46ffcc..d805880b8dc1 100644 --- a/conf/locale/pl/LC_MESSAGES/django.po +++ b/conf/locale/pl/LC_MESSAGES/django.po @@ -163,7 +163,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Tekst" @@ -12693,47 +12693,47 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Błędne dane" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Błędne dane ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Nie możesz przenieść {source_type} do {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "element znajduje się już w docelowej lokalizacji." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Nie możesz przenieść elementu do niego samego." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Nie możesz przenieść elementu do wywodzącego się z niego elementu." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Nie możesz przenieść elementu bezpośrednio do eksperymentu z treścią." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} nieodnaleziony w {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -12741,17 +12741,17 @@ msgstr "" "Nie możesz przenieść {source_usage_key} do nieprawidłowego indeksu " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Musisz podać target_index ({target_index}) jako całość." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplikat {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplikat '{0}'" @@ -12759,7 +12759,7 @@ msgstr "Duplikat '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12769,11 +12769,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/pt_BR/LC_MESSAGES/django.po b/conf/locale/pt_BR/LC_MESSAGES/django.po index 682a0676ff90..6d9800d190ea 100644 --- a/conf/locale/pt_BR/LC_MESSAGES/django.po +++ b/conf/locale/pt_BR/LC_MESSAGES/django.po @@ -12160,63 +12160,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Dados inválidos" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Dados inválidos ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplicata de {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplicata de '{0}'" @@ -12224,7 +12224,7 @@ msgstr "Duplicata de '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12234,11 +12234,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/pt_PT/LC_MESSAGES/django.po b/conf/locale/pt_PT/LC_MESSAGES/django.po index 26a6eadc842b..4cb8950ca210 100644 --- a/conf/locale/pt_PT/LC_MESSAGES/django.po +++ b/conf/locale/pt_PT/LC_MESSAGES/django.po @@ -153,7 +153,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Texto" @@ -13332,64 +13332,64 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "O carregamento de ficheiros falhou. Por favor, tente novamente" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "As bibliotecas não podem ter mais do {limit} componentes" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Dados inválidos" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Dados inválidos ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Não pode mover {source_type} para {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "O item já está presente no local de destino." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Não pode mover um item para si mesmo." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Não pode mover um item para um item dependente." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Não pode mover um item diretamente para a experiência de conteúdo." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} não foi encontrado em {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" "Não pode mover {source_usage_key} num índice inválido ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Deve indicar o target_index ({target_index}) como um número inteiro." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplicado de {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplicado de '{0}'" @@ -13397,7 +13397,7 @@ msgstr "Duplicado de '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13407,11 +13407,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/rtl/LC_MESSAGES/django.po b/conf/locale/rtl/LC_MESSAGES/django.po index 3164d7cd56f8..55b5f36c820c 100644 --- a/conf/locale/rtl/LC_MESSAGES/django.po +++ b/conf/locale/rtl/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Ŧǝxʇ" @@ -13030,64 +13030,64 @@ msgstr "Søɯǝ ɔɥnnʞs ɯᴉssǝd dnɹᴉnƃ ɟᴉlǝ ndløɐd. Ᵽlǝɐsǝ msgid "File upload failed. Please try again" msgstr "Fᴉlǝ ndløɐd ɟɐᴉlǝd. Ᵽlǝɐsǝ ʇɹʎ ɐƃɐᴉn" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Łᴉbɹɐɹᴉǝs ɔɐnnøʇ ɥɐʌǝ ɯøɹǝ ʇɥɐn {limit} ɔøɯdønǝnʇs" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Ɨnʌɐlᴉd dɐʇɐ" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Ɨnʌɐlᴉd dɐʇɐ ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Ɏøn ɔɐn nøʇ ɯøʌǝ {source_type} ᴉnʇø {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Ɨʇǝɯ ᴉs ɐlɹǝɐdʎ dɹǝsǝnʇ ᴉn ʇɐɹƃǝʇ løɔɐʇᴉøn." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Ɏøn ɔɐn nøʇ ɯøʌǝ ɐn ᴉʇǝɯ ᴉnʇø ᴉʇsǝlɟ." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Ɏøn ɔɐn nøʇ ɯøʌǝ ɐn ᴉʇǝɯ ᴉnʇø ᴉʇ's ɔɥᴉld." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Ɏøn ɔɐn nøʇ ɯøʌǝ ɐn ᴉʇǝɯ dᴉɹǝɔʇlʎ ᴉnʇø ɔønʇǝnʇ ǝxdǝɹᴉɯǝnʇ." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} nøʇ ɟønnd ᴉn {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" "Ɏøn ɔɐn nøʇ ɯøʌǝ {source_usage_key} ɐʇ ɐn ᴉnʌɐlᴉd ᴉndǝx ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Ɏøn ɯnsʇ dɹøʌᴉdǝ ʇɐɹƃǝʇ_ᴉndǝx ({target_index}) ɐs ɐn ᴉnʇǝƃǝɹ." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Đndlᴉɔɐʇǝ øɟ {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Đndlᴉɔɐʇǝ øɟ '{0}'" @@ -13095,7 +13095,7 @@ msgstr "Đndlᴉɔɐʇǝ øɟ '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13104,11 +13104,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/ru/LC_MESSAGES/django.po b/conf/locale/ru/LC_MESSAGES/django.po index 454c90893727..c14da1dafc82 100644 --- a/conf/locale/ru/LC_MESSAGES/django.po +++ b/conf/locale/ru/LC_MESSAGES/django.po @@ -12758,48 +12758,48 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Неверные данные" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Неверные данные ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Вы не можете переместить {source_type} в {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Элемент уже находится в заданном месте." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Невозможно переместить элемент в самого себя." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Невозможно поместить элемент в его дочерний элемент." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Невозможно переместить элемент в компонент с экспериментальными материалами." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} не найден в {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -12807,17 +12807,17 @@ msgstr "" "Невозможно переместить {source_usage_key} на отсутствующую позицию " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Необходимо указать позицию ({target_index}) в виде целого числа." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Копия {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Копия «{0}»" @@ -12825,7 +12825,7 @@ msgstr "Копия «{0}»" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12835,11 +12835,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} «{display_name}»" diff --git a/conf/locale/sk/LC_MESSAGES/django.po b/conf/locale/sk/LC_MESSAGES/django.po index 971f93d1ac28..30274837ce7d 100644 --- a/conf/locale/sk/LC_MESSAGES/django.po +++ b/conf/locale/sk/LC_MESSAGES/django.po @@ -68,7 +68,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11782,63 +11782,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Neplatné údaje" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Neplatné údaje ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Duplikát {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Duplikát '{0}'" @@ -11846,7 +11846,7 @@ msgstr "Duplikát '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11856,11 +11856,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/sw_KE/LC_MESSAGES/django.po b/conf/locale/sw_KE/LC_MESSAGES/django.po index 88c60abd9dad..7bf1e96a08e0 100644 --- a/conf/locale/sw_KE/LC_MESSAGES/django.po +++ b/conf/locale/sw_KE/LC_MESSAGES/django.po @@ -98,7 +98,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Maandishi" @@ -11906,65 +11906,65 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Taarifa batili" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Taarifa batili ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Huwezi kupeleka {source_type} kwenye {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Kipengele tayari kipo katika eneo linalohitajika." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Huwezi kupeleka kipengele hiki ndani ya chenyewe." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Huwezi kupeleka kipengele kwenye kipengele kidogo zaidi yake." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" "Huwezi kupeleka kipengele hiki moja kwa moja kwenye sehemu ya majaribio." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} hakikupatikana kwenye {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" "Huwezi kupeleka {source_usage_key} katika namba batili ({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Lazima uweke namba sahihi ({target_index}) kama vile namba kamili." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Nakala ya {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Nakala ya '{0}'" @@ -11972,7 +11972,7 @@ msgstr "Nakala ya '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11982,11 +11982,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "% " -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/th/LC_MESSAGES/django.po b/conf/locale/th/LC_MESSAGES/django.po index 48a042a42280..fbad7ebe5a45 100644 --- a/conf/locale/th/LC_MESSAGES/django.po +++ b/conf/locale/th/LC_MESSAGES/django.po @@ -129,7 +129,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11564,63 +11564,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "ข้อมูลไม่ถูกต้อง" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "ข้อมูลไม่ถูกต้อง ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "ค่าซ้ำกันของ {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "ค่าซ้ำกันของ '{0}'" @@ -11628,7 +11628,7 @@ msgstr "ค่าซ้ำกันของ '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11638,11 +11638,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "เปอร์เซนต์" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/tr_TR/LC_MESSAGES/django.po b/conf/locale/tr_TR/LC_MESSAGES/django.po index 52f8d5353b06..b1ce987789c6 100644 --- a/conf/locale/tr_TR/LC_MESSAGES/django.po +++ b/conf/locale/tr_TR/LC_MESSAGES/django.po @@ -145,7 +145,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Metin" @@ -13229,47 +13229,47 @@ msgstr "Dosya yükleme sırasında bazı parçalar kayboldu. Lütfen tekrar dene msgid "File upload failed. Please try again" msgstr "Dosya yükleme başarısız. Lütfen tekrar deneyin" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "Kütüphaneler {limit} bileşenden daha fazlasına sahip olamaz" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Geçersiz veri" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Geçersiz veri ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "{source_type} verisini {target_parent_type} üzerine taşıyamazsınız." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Nesne hedef konumda zaten mevcut." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Bir nesneyi zaten bulunduğu konuma taşıyamazsınız." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Bir nesneyi kendi altına taşıyamazsınız." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Bir nesneyi doğrudan içerik denemesine taşıyamazsınız." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} anahtarı {parent_usage_key} içinde bulunamadı." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -13277,17 +13277,17 @@ msgstr "" "{source_usage_key} anahtarını geçersiz bir ({target_index}) indeksine " "taşıyamazsınız." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "({target_index}) target_index bir tamsayı olarak girilmeli." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "{0}'ın kopyası" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "'{0}'ın tekrarı" @@ -13295,7 +13295,7 @@ msgstr "'{0}'ın tekrarı" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -13305,11 +13305,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/uk/LC_MESSAGES/django.po b/conf/locale/uk/LC_MESSAGES/django.po index a419360766eb..880084b1a190 100644 --- a/conf/locale/uk/LC_MESSAGES/django.po +++ b/conf/locale/uk/LC_MESSAGES/django.po @@ -137,7 +137,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "Текст" @@ -12762,47 +12762,47 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Некоректні дані" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Некоректні дані ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Ви не можете перенести {source_type} у {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Елемент вже присутній у вказаному місці." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Неможливо перемістити у самого себе." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Не можна перемістити елемент безпосередньо до експерименту з вмістом." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} не знайдено у {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -12810,17 +12810,17 @@ msgstr "" "Ви не можете перенести {source_usage_key} у неправильний розділ " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Ви повинні давати target_index ({target_index}) як ціле число." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Копія {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Копіювання '{0}'" @@ -12828,7 +12828,7 @@ msgstr "Копіювання '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12838,11 +12838,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} «{display_name}»" diff --git a/conf/locale/vi/LC_MESSAGES/django.po b/conf/locale/vi/LC_MESSAGES/django.po index 0d5370152bea..03b6b1d21ce0 100644 --- a/conf/locale/vi/LC_MESSAGES/django.po +++ b/conf/locale/vi/LC_MESSAGES/django.po @@ -211,7 +211,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "" @@ -11655,47 +11655,47 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "Dữ liệu không hợp lệ" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "Dữ liệu không hợp lệ ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "Bạn không thể di chuyển {source_type} vào {target_parent_type}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "Mục đã có trong vị trí đích." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "Bạn không thể di chuyển một mục vào chính nó." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "Bạn không thể di chuyển một mục vào mục con của nó." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "Bạn không thể di chuyển một mục trực tiếp vào thử nghiệm nội dung." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "{source_usage_key} không tìm thấy trong {parent_usage_key}." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." @@ -11703,17 +11703,17 @@ msgstr "" "Bạn không thể di chuyển {source_usage_key} tại một chỉ mục không hợp lệ " "({target_index})." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "Bạn phải nhập target_index ({target_index}) là một số nguyên." -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "Sao chép của {0}" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "Sao chép của '{0}'" @@ -11721,7 +11721,7 @@ msgstr "Sao chép của '{0}'" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11731,11 +11731,11 @@ msgstr "" #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/conf/locale/zh_CN/LC_MESSAGES/django.po b/conf/locale/zh_CN/LC_MESSAGES/django.po index f7a181921091..923a8e42481f 100644 --- a/conf/locale/zh_CN/LC_MESSAGES/django.po +++ b/conf/locale/zh_CN/LC_MESSAGES/django.po @@ -410,7 +410,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "文本" @@ -12155,63 +12155,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "无效的数据" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "无效的数据 ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "无法将 {source_type}移进 {target_parent_type}内。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "目标位置已显示该项。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "您无法将项目移动至本身。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "您无法将项移动至子目录下。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "您无法将项直接移动至内容实验中。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "在{parent_usage_key}中未找到{source_usage_key} 。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "无法将{source_usage_key}移动至无效索引中({target_index})。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "您必须提供整数的target_index ({target_index})。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "“{0}”的副本" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "“{0}”的副本" @@ -12219,7 +12219,7 @@ msgstr "“{0}”的副本" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12227,11 +12227,11 @@ msgstr "学生必须获得 {score}{pct_sign} 或者更高的分数才能查看 #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection}“{display_name}”" diff --git a/conf/locale/zh_HANS/LC_MESSAGES/django.po b/conf/locale/zh_HANS/LC_MESSAGES/django.po index f7a181921091..923a8e42481f 100644 --- a/conf/locale/zh_HANS/LC_MESSAGES/django.po +++ b/conf/locale/zh_HANS/LC_MESSAGES/django.po @@ -410,7 +410,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "文本" @@ -12155,63 +12155,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "无效的数据" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "无效的数据 ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "无法将 {source_type}移进 {target_parent_type}内。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "目标位置已显示该项。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "您无法将项目移动至本身。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "您无法将项移动至子目录下。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "您无法将项直接移动至内容实验中。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "在{parent_usage_key}中未找到{source_usage_key} 。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "无法将{source_usage_key}移动至无效索引中({target_index})。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "您必须提供整数的target_index ({target_index})。" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "“{0}”的副本" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "“{0}”的副本" @@ -12219,7 +12219,7 @@ msgstr "“{0}”的副本" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -12227,11 +12227,11 @@ msgstr "学生必须获得 {score}{pct_sign} 或者更高的分数才能查看 #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection}“{display_name}”" diff --git a/conf/locale/zh_TW/LC_MESSAGES/django.po b/conf/locale/zh_TW/LC_MESSAGES/django.po index 8c0adec8f838..54ede518d0fe 100644 --- a/conf/locale/zh_TW/LC_MESSAGES/django.po +++ b/conf/locale/zh_TW/LC_MESSAGES/django.po @@ -190,7 +190,7 @@ msgstr "" #: cms/djangoapps/contentstore/utils.py #: cms/djangoapps/contentstore/views/component.py -#: cms/djangoapps/contentstore/views/item.py xmodule/html_block.py +#: cms/djangoapps/contentstore/views/block.py xmodule/html_block.py msgid "Text" msgstr "文本" @@ -11803,63 +11803,63 @@ msgstr "" msgid "File upload failed. Please try again" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Libraries cannot have more than {limit} components" msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Invalid data" msgstr "無效的資料" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Invalid data ({details})" msgstr "無效資料 ({details})" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You can not move {source_type} into {target_parent_type}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "Item is already present in target location." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into itself." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item into it's child." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "You can not move an item directly into content experiment." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{source_usage_key} not found in {parent_usage_key}." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "You can not move {source_usage_key} at an invalid index ({target_index})." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "You must provide target_index ({target_index}) as an integer." msgstr "" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of {0}" msgstr "與{0}重複" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "Duplicate of '{0}'" msgstr "與'{0}'重複" @@ -11867,7 +11867,7 @@ msgstr "與'{0}'重複" #. Translators: The {pct_sign} here represents the percent sign, i.e., '%' #. in many languages. This is used to avoid Transifex's misinterpreting of #. '% o'. The percent sign is also translatable as a standalone string. -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "" "Students must score {score}{pct_sign} or higher to access course materials." @@ -11875,11 +11875,11 @@ msgstr "學生必須得分 {score}{pct_sign} 或高於此分數以存取課程 #. Translators: This is the percent sign. It will be used to represent #. a percent value out of 100, e.g. "58%" means "58/100". -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py msgid "%" msgstr "%" -#: cms/djangoapps/contentstore/views/item.py +#: cms/djangoapps/contentstore/views/block.py #, python-brace-format msgid "{section_or_subsection} \"{display_name}\"" msgstr "{section_or_subsection} \"{display_name}\"" diff --git a/docs/guides/testing/testing.rst b/docs/guides/testing/testing.rst index 2407b6922681..ee488b4fb295 100644 --- a/docs/guides/testing/testing.rst +++ b/docs/guides/testing/testing.rst @@ -183,7 +183,7 @@ How to output coverage locally These are examples of how to run a single test and get coverage:: pytest cms/djangoapps/contentstore/tests/test_import.py --cov --cov-config=.coveragerc-local # cms example - pytest lms/djangoapps/courseware/tests/test_module_render.py --cov --cov-config=.coveragerc-local # lms example + pytest lms/djangoapps/courseware/tests/test_block_render.py --cov --cov-config=.coveragerc-local # lms example That ``--cov-conifg=.coveragerc-local`` option is important - without it, the coverage tool will look for paths that exist on our jenkins test servers, but not on your local devstack. diff --git a/lms/djangoapps/course_blocks/transformers/library_content.py b/lms/djangoapps/course_blocks/transformers/library_content.py index ae4ad7b2282a..11321196d2e9 100644 --- a/lms/djangoapps/course_blocks/transformers/library_content.py +++ b/lms/djangoapps/course_blocks/transformers/library_content.py @@ -25,7 +25,7 @@ class ContentLibraryTransformer(FilteringTransformerMixin, BlockStructureTransformer): """ A transformer that manipulates the block structure by removing all - blocks within a library_content module to which a user should not + blocks within a library_content block to which a user should not have access. Staff users are not to be exempted from library content pathways. @@ -90,7 +90,7 @@ def transform_block_filters(self, usage_info, block_structure): state_dict = get_student_module_as_dict(usage_info.user, usage_info.course_key, block_key) for selected_block in state_dict.get('selected', []): # Add all selected entries for this user for this - # library module to the selected list. + # library block to the selected list. block_type, block_id = selected_block usage_key = usage_info.course_key.make_usage_key(block_type, block_id) if usage_key in library_children: @@ -184,7 +184,7 @@ def publish_event(event_name, result, **kwargs): class ContentLibraryOrderTransformer(BlockStructureTransformer): """ A transformer that manipulates the block structure by modifying the order of the - selected blocks within a library_content module to match the order of the selections + selected blocks within a library_content block to match the order of the selections made by the ContentLibraryTransformer or the corresponding XBlock. So this transformer requires the selections for the randomized content block to be already made either by the ContentLibraryTransformer or the XBlock. diff --git a/lms/djangoapps/course_blocks/transformers/split_test.py b/lms/djangoapps/course_blocks/transformers/split_test.py index 80b8fba3690a..4de70d8badff 100644 --- a/lms/djangoapps/course_blocks/transformers/split_test.py +++ b/lms/djangoapps/course_blocks/transformers/split_test.py @@ -12,13 +12,13 @@ class SplitTestTransformer(FilteringTransformerMixin, BlockStructureTransformer): """ A nested transformer of the UserPartitionTransformer that honors the - block structure pathways created by split_test modules. + block structure pathways created by split_test blocks. To avoid code duplication, the implementation transforms its block access representation to the representation used by user_partitions. - Namely, the 'group_id_to_child' field on a split_test module is + Namely, the 'group_id_to_child' field on a split_test block is transformed into the, now standard, 'group_access' fields in the - split_test module's children. + split_test block's children. The implementation therefore relies on the UserPartitionTransformer to actually enforce the access using the 'user_partitions' and @@ -61,7 +61,7 @@ def collect(cls, block_structure): continue # Create dict of child location to group_id, using the - # group_id_to_child field on the split_test module. + # group_id_to_child field on the split_test block. child_to_group = { xblock.group_id_to_child.get(str(group.id), None): group.id for group in partition_for_this_block.groups @@ -80,7 +80,7 @@ def transform_block_filters(self, usage_info, block_structure): """ # The UserPartitionTransformer will enforce group access, so - # go ahead and remove all extraneous split_test modules. + # go ahead and remove all extraneous split_test blocks. return [ block_structure.create_removal_filter( lambda block_key: block_key.block_type == 'split_test', diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index 76cad3961fc2..f71f2daec5bb 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -5,7 +5,7 @@ Note: The access control logic in this file does NOT check for enrollment in a course. It is expected that higher layers check for enrollment so we - don't have to hit the enrollments table on every module load. + don't have to hit the enrollments table on every block load. If enrollment is to be checked, use get_course_with_access in courseware.courses. It is a wrapper around has_access that additionally checks for enrollment. @@ -104,8 +104,8 @@ def has_access(user, action, obj, course_key=None): switching based on various settings. Things this module understands: - - start dates for modules - - visible_to_staff_only for modules + - start dates for blocks + - visible_to_staff_only for blocks - DISABLE_START_DATES - different access for instructor, staff, course staff, and students. - mobile_available flag for course blocks @@ -113,7 +113,7 @@ def has_access(user, action, obj, course_key=None): user: a Django user object. May be anonymous. If none is passed, anonymous is assumed - obj: The object to check access for. A module, descriptor, location, or + obj: The object to check access for. A block, descriptor, location, or certain special strings (e.g. 'global') action: A string specifying the action that the client is trying to perform. @@ -557,9 +557,9 @@ def _has_access_descriptor(user, action, descriptor, course_key=None): def can_load(): """ NOTE: This does not check that the student is enrolled in the course - that contains this module. We may or may not want to allow non-enrolled - students to see modules. If not, views should check the course, so we - don't have to hit the enrollments table on every module load. + that contains this block. We may or may not want to allow non-enrolled + students to see blocks. If not, views should check the course, so we + don't have to hit the enrollments table on every block load. """ # If the user (or the role the user is currently masquerading as) does not have # access to this content, then deny access. The problem with calling _has_staff_access_to_descriptor @@ -569,7 +569,7 @@ def can_load(): if not group_access_response: return group_access_response - # If the user has staff access, they can load the module and checks below are not needed. + # If the user has staff access, they can load the block and checks below are not needed. staff_access_response = _has_staff_access_to_descriptor(user, descriptor, course_key) if staff_access_response: return staff_access_response @@ -597,17 +597,6 @@ def can_load(): return _dispatch(checkers, action, user, descriptor) -def _has_access_xmodule(user, action, xmodule, course_key): - """ - Check if user has access to this xmodule. - - Valid actions: - - same as the valid actions for xmodule.descriptor - """ - # Delegate to the descriptor - return has_access(user, action, xmodule.descriptor, course_key) - - def _has_access_location(user, action, location, course_key): """ Check if user has access to this location. diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/block_render.py similarity index 91% rename from lms/djangoapps/courseware/module_render.py rename to lms/djangoapps/courseware/block_render.py index bb52321c41f6..e9cf15678ee2 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/block_render.py @@ -1,5 +1,5 @@ """ -Module rendering +Block rendering """ @@ -46,7 +46,7 @@ from xmodule.contentstore.django import contentstore from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.library_tools import LibraryToolsService -from xmodule.modulestore.django import ModuleI18nService, modulestore +from xmodule.modulestore.django import XBlockI18nService, modulestore from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.partitions.partitions_service import PartitionService from xmodule.util.sandboxing import SandboxService @@ -107,7 +107,7 @@ class LmsModuleRenderError(Exception): """ - An exception class for exceptions thrown by module_render that don't fit well elsewhere + An exception class for exceptions thrown by block_render that don't fit well elsewhere """ pass # lint-amnesty, pylint: disable=unnecessary-pass @@ -155,7 +155,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_ field_data_cache must include data from the course blocks and 2 levels of its descendants ''' with modulestore().bulk_operations(course.id): - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( user, request, course, field_data_cache, course.id, course=course ) if course_block is None: @@ -276,17 +276,16 @@ def _add_timed_exam_info(user, course, section, section_context): }) -def get_module(user, request, usage_key, field_data_cache, - position=None, log_if_not_found=True, wrap_xmodule_display=True, - grade_bucket_type=None, depth=0, - static_asset_path='', course=None, will_recheck_access=False): +def get_block(user, request, usage_key, field_data_cache, position=None, log_if_not_found=True, + wrap_xblock_display=True, grade_bucket_type=None, depth=0, static_asset_path='', course=None, + will_recheck_access=False): """ - Get an instance of the xmodule class identified by location, + Get an instance of the XBlock class identified by location, setting the state based on an existing StudentModule, or creating one if none exists. Arguments: - - user : User for whom we're getting the module + - user : User for whom we're getting the block - request : current django HTTPrequest. Note: request.user isn't used for anything--all auth and such works based on user. - usage_key : A UsageKey object identifying the module to load @@ -294,7 +293,7 @@ def get_module(user, request, usage_key, field_data_cache, - position : extra information from URL for user-specified position within module - log_if_not_found : If this is True, we log a debug message if we cannot find the requested xmodule. - - wrap_xmodule_display : If this is True, wrap the output display in a single div to allow for the + - wrap_xblock_display : If this is True, wrap the output display in a single div to allow for the XModule javascript to be bound correctly - depth : number of levels of descendents to cache when loading this module. None means cache all descendents @@ -306,26 +305,26 @@ def get_module(user, request, usage_key, field_data_cache, before rendering the content in order to display access error messages to the user. - Returns: xmodule instance, or None if the user does not have access to the - module. If there's an error, will try to return an instance of ErrorBlock + Returns: XBlock instance, or None if the user does not have access to the + block. If there's an error, will try to return an instance of ErrorBlock if possible. If not possible, return None. """ try: descriptor = modulestore().get_item(usage_key, depth=depth) - return get_module_for_descriptor(user, request, descriptor, field_data_cache, usage_key.course_key, - position=position, - wrap_xmodule_display=wrap_xmodule_display, - grade_bucket_type=grade_bucket_type, - static_asset_path=static_asset_path, - course=course, will_recheck_access=will_recheck_access) + return get_block_for_descriptor(user, request, descriptor, field_data_cache, usage_key.course_key, + position=position, + wrap_xblock_display=wrap_xblock_display, + grade_bucket_type=grade_bucket_type, + static_asset_path=static_asset_path, + course=course, will_recheck_access=will_recheck_access) except ItemNotFoundError: if log_if_not_found: - log.debug("Error in get_module: ItemNotFoundError") + log.debug("Error in get_block: ItemNotFoundError") return None except: # pylint: disable=W0702 # Something has gone terribly wrong, but still not letting it turn into a 500. - log.exception("Error in get_module") + log.exception("Error in get_block") return None @@ -366,16 +365,16 @@ def display_access_messages(user, block, view, frag, context): # pylint: disabl # pylint: disable=too-many-statements -def get_module_for_descriptor(user, request, descriptor, field_data_cache, course_key, - position=None, wrap_xmodule_display=True, grade_bucket_type=None, - static_asset_path='', disable_staff_debug_info=False, - course=None, will_recheck_access=False): +def get_block_for_descriptor(user, request, descriptor, field_data_cache, course_key, + position=None, wrap_xblock_display=True, grade_bucket_type=None, + static_asset_path='', disable_staff_debug_info=False, + course=None, will_recheck_access=False): """ - Implements get_module, extracting out the request-specific functionality. + Implements get_block, extracting out the request-specific functionality. - disable_staff_debug_info : If this is True, exclude staff debug information in the rendering of the module. + disable_staff_debug_info : If this is True, exclude staff debug information in the rendering of the block. - See get_module() docstring for further details. + See get_block() docstring for further details. """ track_function = make_track_function(request) @@ -386,14 +385,14 @@ def get_module_for_descriptor(user, request, descriptor, field_data_cache, cours student_kvs = MasqueradingKeyValueStore(student_kvs, request.session) student_data = KvsFieldData(student_kvs) - return get_module_for_descriptor_internal( + return get_block_for_descriptor_internal( user=user, descriptor=descriptor, student_data=student_data, course_id=course_key, track_function=track_function, position=position, - wrap_xmodule_display=wrap_xmodule_display, + wrap_xblock_display=wrap_xblock_display, grade_bucket_type=grade_bucket_type, static_asset_path=static_asset_path, user_location=user_location, @@ -413,7 +412,7 @@ def get_module_system_for_user( track_function, request_token, position=None, - wrap_xmodule_display=True, + wrap_xblock_display=True, grade_bucket_type=None, static_asset_path='', user_location=None, @@ -425,16 +424,16 @@ def get_module_system_for_user( Helper function that returns a module system and student_data bound to a user and a descriptor. The purpose of this function is to factor out everywhere a user is implicitly bound when creating a module, - to allow an existing module to be re-bound to a user. Most of the user bindings happen when creating the + to allow an existing block to be re-bound to a user. Most of the user bindings happen when creating the closures that feed the instantiation of ModuleSystem. The arguments fall into two categories: those that have explicit or implicit user binding, which are user and student_data, and those don't and are just present so that ModuleSystem can be instantiated, which - are all the other arguments. Ultimately, this isn't too different than how get_module_for_descriptor_internal + are all the other arguments. Ultimately, this isn't too different than how get_block_for_descriptor_internal was before refactoring. Arguments: - see arguments for get_module() + see arguments for get_block() request_token (str): A token unique to the request use by xblock initialization Returns: @@ -458,7 +457,7 @@ def make_xqueue_callback(dispatch='score_update'): return xqueue_callback_url_prefix + relative_xqueue_callback_url # Default queuename is course-specific and is derived from the course that - # contains the current module. + # contains the current block. # TODO: Queuename should be derived from 'course_settings.json' of each course xqueue_default_queuename = descriptor.location.org + '-' + descriptor.location.course @@ -471,15 +470,15 @@ def make_xqueue_callback(dispatch='score_update'): waittime=settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS, ) - def inner_get_module(descriptor): + def inner_get_block(descriptor): """ - Delegate to get_module_for_descriptor_internal() with all values except `descriptor` set. + Delegate to get_block_for_descriptor_internal() with all values except `descriptor` set. Because it does an access check, it may return None. """ # TODO: fix this so that make_xqueue_callback uses the descriptor passed into - # inner_get_module, not the parent's callback. Add it as an argument.... - return get_module_for_descriptor_internal( + # inner_get_block, not the parent's callback. Add it as an argument.... + return get_block_for_descriptor_internal( user=user, descriptor=descriptor, student_data=student_data, @@ -487,7 +486,7 @@ def inner_get_module(descriptor): track_function=track_function, request_token=request_token, position=position, - wrap_xmodule_display=wrap_xmodule_display, + wrap_xblock_display=wrap_xblock_display, grade_bucket_type=grade_bucket_type, static_asset_path=static_asset_path, user_location=user_location, @@ -522,7 +521,7 @@ def inner_get_module(descriptor): get_module_system_for_user, track_function=track_function, position=position, - wrap_xmodule_display=wrap_xmodule_display, + wrap_xblock_display=wrap_xblock_display, grade_bucket_type=grade_bucket_type, static_asset_path=static_asset_path, user_location=user_location, @@ -541,9 +540,9 @@ def inner_get_module(descriptor): if settings.FEATURES.get("LICENSING", False): block_wrappers.append(partial(wrap_with_license, mako_service=mako_service)) - # Wrap the output display in a single div to allow for the XModule + # Wrap the output display in a single div to allow for the XBlock # javascript to be bound correctly - if wrap_xmodule_display is True: + if wrap_xblock_display is True: block_wrappers.append(partial( wrap_xblock, 'LmsRuntime', @@ -589,7 +588,7 @@ def inner_get_module(descriptor): store = modulestore() system = LmsModuleSystem( - get_module=inner_get_module, + get_block=inner_get_block, # TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington) mixins=descriptor.runtime.mixologist._mixins, # pylint: disable=protected-access wrappers=block_wrappers, @@ -615,7 +614,7 @@ def inner_get_module(descriptor): 'completion': CompletionService(user=user, context_key=course_id) if user and user.is_authenticated else None, - 'i18n': ModuleI18nService, + 'i18n': XBlockI18nService, 'library_tools': LibraryToolsService(store, user_id=user.id if user else None), 'partitions': PartitionService(course_id=course_id, cache=DEFAULT_REQUEST_CACHE.data), 'settings': SettingsService(), @@ -650,15 +649,14 @@ def inner_get_module(descriptor): # TODO: Find all the places that this method is called and figure out how to # get a loaded course passed into it -def get_module_for_descriptor_internal(user, descriptor, student_data, course_id, - track_function, request_token, - position=None, wrap_xmodule_display=True, grade_bucket_type=None, - static_asset_path='', user_location=None, disable_staff_debug_info=False, - course=None, will_recheck_access=False): +def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, track_function, request_token, + position=None, wrap_xblock_display=True, grade_bucket_type=None, + static_asset_path='', user_location=None, disable_staff_debug_info=False, + course=None, will_recheck_access=False): """ - Actually implement get_module, without requiring a request. + Actually implement get_block, without requiring a request. - See get_module() docstring for further details. + See get_block() docstring for further details. Arguments: request_token (str): A unique token for this request, used to isolate xblock rendering @@ -671,7 +669,7 @@ def get_module_for_descriptor_internal(user, descriptor, student_data, course_id course_id=course_id, track_function=track_function, position=position, - wrap_xmodule_display=wrap_xmodule_display, + wrap_xblock_display=wrap_xblock_display, grade_bucket_type=grade_bucket_type, static_asset_path=static_asset_path, user_location=user_location, @@ -729,7 +727,7 @@ def load_single_xblock(request, user_id, course_id, usage_key_string, course=Non modulestore().get_item(usage_key), depth=0, ) - instance = get_module( + instance = get_block( user, request, usage_key, @@ -910,10 +908,10 @@ def _get_descriptor_by_usage_key(usage_key): return descriptor, tracking_context -def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None, - will_recheck_access=False): +def get_block_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None, + will_recheck_access=False): """ - Gets a module instance based on its `usage_id` in a course, for a given request/user + Gets a block instance based on its `usage_id` in a course, for a given request/user Returns (instance, tracking_context) """ @@ -928,7 +926,7 @@ def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_inf descriptor, read_only=CrawlersConfig.is_crawler(request), ) - instance = get_module_for_descriptor( + instance = get_block_for_descriptor( user, request, descriptor, @@ -991,12 +989,12 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course handler_method = getattr(descriptor, handler, False) will_recheck_access = handler_method and getattr(handler_method, 'will_recheck_access', False) - instance, tracking_context = get_module_by_usage_id( + instance, tracking_context = get_block_by_usage_id( request, course_id, str(block_usage_key), course=course, will_recheck_access=will_recheck_access, ) # Name the transaction so that we can view XBlock handlers separately in - # New Relic. The suffix is necessary for XModule handlers because the + # New Relic. The suffix is necessary for XBlock handlers because the # "handler" in those cases is always just "xmodule_handler". nr_tx_name = f"{instance.__class__.__name__}.{handler}" nr_tx_name += f"/{suffix}" if (suffix and handler == "xmodule_handler") else "" @@ -1025,12 +1023,12 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # lint-amnesty, pylint: disable=raise-missing-from - # If we can't find the module, respond with a 404 + # If we can't find the block, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # lint-amnesty, pylint: disable=raise-missing-from - # For XModule-specific errors, we log the error and respond with an error message + # For XBlock-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) @@ -1067,7 +1065,7 @@ def xblock_view(request, course_id, usage_id, view_name): with modulestore().bulk_operations(course_key): course = modulestore().get_course(course_key) - instance, _ = get_module_by_usage_id(request, course_id, usage_id, course=course) + instance, _ = get_block_by_usage_id(request, course_id, usage_id, course=course) try: fragment = instance.render(view_name, context=request.GET) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 1dfb33be5290..676a42bd70e6 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -49,7 +49,7 @@ from lms.djangoapps.courseware.exceptions import CourseAccessRedirect, CourseRunNotFound from lms.djangoapps.courseware.masquerade import check_content_start_date_for_masquerade_user from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module +from lms.djangoapps.courseware.block_render import get_block from lms.djangoapps.survey.utils import SurveyRequiredAccessError, check_survey_required_and_unanswered from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.enrollments.api import get_course_enrollment_details @@ -370,22 +370,22 @@ def get_course_about_section(request, course, section_key): # Use an empty cache field_data_cache = FieldDataCache([], course.id, request.user) - about_module = get_module( + about_block = get_block( request.user, request, loc, field_data_cache, log_if_not_found=False, - wrap_xmodule_display=False, + wrap_xblock_display=False, static_asset_path=course.static_asset_path, course=course ) html = '' - if about_module is not None: + if about_block is not None: try: - html = about_module.render(STUDENT_VIEW).content + html = about_block.render(STUDENT_VIEW).content except Exception: # pylint: disable=broad-except html = render_to_string('courseware/error-message.html', None) log.exception( @@ -406,14 +406,14 @@ def get_course_about_section(request, course, section_key): def get_course_info_usage_key(course, section_key): """ - Returns the usage key for the specified section's course info module. + Returns the usage key for the specified section's course info block. """ return course.id.make_usage_key('course_info', section_key) -def get_course_info_section_module(request, user, course, section_key): +def get_course_info_section_block(request, user, course, section_key): """ - This returns the course info module for a given section_key. + This returns the course info block for a given section_key. Valid keys: - handouts @@ -426,13 +426,13 @@ def get_course_info_section_module(request, user, course, section_key): # Use an empty cache field_data_cache = FieldDataCache([], course.id, user) - return get_module( + return get_block( user, request, usage_key, field_data_cache, log_if_not_found=False, - wrap_xmodule_display=False, + wrap_xblock_display=False, static_asset_path=course.static_asset_path, course=course ) @@ -449,12 +449,12 @@ def get_course_info_section(request, user, course, section_key): - updates - guest_updates """ - info_module = get_course_info_section_module(request, user, course, section_key) + info_block = get_course_info_section_block(request, user, course, section_key) html = '' - if info_module is not None: + if info_block is not None: try: - html = info_module.render(STUDENT_VIEW).content.strip() + html = info_block.render(STUDENT_VIEW).content.strip() except Exception: # pylint: disable=broad-except html = render_to_string('courseware/error-message.html', None) log.exception( @@ -731,7 +731,7 @@ def get_course_syllabus_section(course, section_key): if section_key in ['syllabus', 'guest_syllabus']: try: - filesys = course.system.resources_fs + filesys = course.runtime.resources_fs # first look for a run-specific version dirs = [path("syllabus") / course.url_name, path("syllabus")] filepath = find_file(filesys, dirs, section_key + ".html") @@ -879,10 +879,10 @@ def get_problems_in_section(section): return problem_descriptors -def get_current_child(xmodule, min_depth=None, requested_child=None): +def get_current_child(xblock, min_depth=None, requested_child=None): """ - Get the xmodule.position's display item of an xmodule that has a position and - children. If xmodule has no position or is out of bounds, return the first + Get the xblock.position's display item of an xblock that has a position and + children. If xblock has no position or is out of bounds, return the first child with children of min_depth. For example, if chapter_one has no position set, with two child sections, @@ -905,13 +905,13 @@ def _get_child(children): else: return children[0] - def _get_default_child_module(child_modules): - """Returns the first child of xmodule, subject to min_depth.""" + def _get_default_child_block(child_blocks): + """Returns the first child of xblock, subject to min_depth.""" if min_depth is None or min_depth <= 0: - return _get_child(child_modules) + return _get_child(child_blocks) else: content_children = [ - child for child in child_modules + child for child in child_blocks if child.has_children_at_depth(min_depth - 1) and child.get_children() ] return _get_child(content_children) if content_children else None @@ -921,21 +921,21 @@ def _get_default_child_module(child_modules): try: # In python 3, hasattr() catches AttributeErrors only then returns False. # All other exceptions bubble up the call stack. - has_position = hasattr(xmodule, 'position') # This conditions returns AssertionError from xblock.fields lib. + has_position = hasattr(xblock, 'position') # This conditions returns AssertionError from xblock.fields lib. except AssertionError: return child if has_position: - children = xmodule.get_children() + children = xblock.get_children() if len(children) > 0: - if xmodule.position is not None and not requested_child: - pos = int(xmodule.position) - 1 # position is 1-indexed + if xblock.position is not None and not requested_child: + pos = int(xblock.position) - 1 # position is 1-indexed if 0 <= pos < len(children): child = children[pos] if min_depth is not None and (min_depth > 0 and not child.has_children_at_depth(min_depth - 1)): child = None if child is None: - child = _get_default_child_module(children) + child = _get_default_child_block(children) return child diff --git a/lms/djangoapps/courseware/entrance_exams.py b/lms/djangoapps/courseware/entrance_exams.py index b4358773c533..519174994b10 100644 --- a/lms/djangoapps/courseware/entrance_exams.py +++ b/lms/djangoapps/courseware/entrance_exams.py @@ -58,15 +58,15 @@ def user_has_passed_entrance_exam(user, course): def get_entrance_exam_content(user, course): """ - Get the entrance exam content information (ie, chapter module) + Get the entrance exam content information (ie, chapter block) """ required_content = get_required_content(course.id, user) - exam_module = None + exam_block = None for content in required_content: usage_key = UsageKey.from_string(content).map_into_course(course.id) - module_item = modulestore().get_item(usage_key) - if not module_item.hide_from_toc and module_item.is_entrance_exam: - exam_module = module_item + block = modulestore().get_item(usage_key) + if not block.hide_from_toc and block.is_entrance_exam: + exam_block = block break - return exam_module + return exam_block diff --git a/lms/djangoapps/courseware/field_overrides.py b/lms/djangoapps/courseware/field_overrides.py index cb7ba4d31d9c..60ffcafd25a5 100644 --- a/lms/djangoapps/courseware/field_overrides.py +++ b/lms/djangoapps/courseware/field_overrides.py @@ -9,7 +9,7 @@ extensible, modular architecture allows for overrides being done in ways not envisioned by the authors. -Currently, this module is used in the `module_render` module in this same +Currently, this module is used in the `block_render` module in this same package and is used to wrap the `authored_data` when constructing an `LmsFieldData`. This means overrides will be in effect for all scopes covered by `authored_data`, e.g. course content and settings stored in Mongo. diff --git a/lms/djangoapps/courseware/management/commands/dump_course_structure.py b/lms/djangoapps/courseware/management/commands/dump_course_structure.py index 2f1fd8f8e3b8..a2ef76e88ea4 100644 --- a/lms/djangoapps/courseware/management/commands/dump_course_structure.py +++ b/lms/djangoapps/courseware/management/commands/dump_course_structure.py @@ -1,16 +1,16 @@ """ Dump the structure of a course as a JSON object. -The resulting JSON object has one entry for each module in the course: +The resulting JSON object has one entry for each block in the course: { - "$module_url": { - "category": "$module_category", - "children": [$module_children_urls... ], - "metadata": {$module_metadata} + "$block_url": { + "category": "$block_category", + "children": [$block_children_urls... ], + "metadata": {$block_metadata} }, - "$module_url": .... + "$block_url": .... ... } @@ -73,30 +73,30 @@ def handle(self, *args, **options): # Convert course data to dictionary and dump it as JSON to stdout - info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults']) + info = dump_block(course, inherited=options['inherited'], defaults=options['inherited_defaults']) return json.dumps(info, indent=2, sort_keys=True, default=str) -def dump_module(module, destination=None, inherited=False, defaults=False): +def dump_block(block, destination=None, inherited=False, defaults=False): """ - Add the module and all its children to the destination dictionary in + Add the block and all its children to the destination dictionary in as a flat structure. """ destination = destination if destination else {} - items = own_metadata(module) + items = own_metadata(block) # HACK: add discussion ids to list of items to export (AN-6696) - if isinstance(module, DiscussionXBlock) and 'discussion_id' not in items: - items['discussion_id'] = module.discussion_id + if isinstance(block, DiscussionXBlock) and 'discussion_id' not in items: + items['discussion_id'] = block.discussion_id filtered_metadata = {k: v for k, v in items.items() if k not in FILTER_LIST} - destination[str(module.location)] = { - 'category': module.location.block_type, - 'children': [str(child) for child in getattr(module, 'children', [])], + destination[str(block.location)] = { + 'category': block.location.block_type, + 'children': [str(child) for child in getattr(block, 'children', [])], 'metadata': filtered_metadata, } @@ -116,10 +116,10 @@ def is_inherited(field): else: return field.values != field.default - inherited_metadata = {field.name: field.read_json(module) for field in module.fields.values() if is_inherited(field)} # lint-amnesty, pylint: disable=line-too-long - destination[str(module.location)]['inherited_metadata'] = inherited_metadata + inherited_metadata = {field.name: field.read_json(block) for field in block.fields.values() if is_inherited(field)} # lint-amnesty, pylint: disable=line-too-long + destination[str(block.location)]['inherited_metadata'] = inherited_metadata - for child in module.get_children(): - dump_module(child, destination, inherited, defaults) + for child in block.get_children(): + dump_block(child, destination, inherited, defaults) return destination diff --git a/lms/djangoapps/courseware/management/commands/import.py b/lms/djangoapps/courseware/management/commands/import.py index 92fba632ddf0..7ebb26795112 100644 --- a/lms/djangoapps/courseware/management/commands/import.py +++ b/lms/djangoapps/courseware/management/commands/import.py @@ -64,7 +64,7 @@ def handle(self, *args, **options): mstore = modulestore() course_items = import_course_from_xml( - mstore, ModuleStoreEnum.UserID.mgmt_command, data_dir, source_dirs, load_error_modules=False, + mstore, ModuleStoreEnum.UserID.mgmt_command, data_dir, source_dirs, load_error_blocks=False, static_content_store=contentstore(), verbose=True, do_import_static=do_import_static, do_import_python_lib=do_import_python_lib, create_if_not_present=True, diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py index 85ccceb6fc2b..26578f286c11 100644 --- a/lms/djangoapps/courseware/model_data.py +++ b/lms/djangoapps/courseware/model_data.py @@ -663,13 +663,13 @@ def _cache_key_for_kvs_key(self, key): class FieldDataCache: """ A cache of django model objects needed to supply the data - for a module and its descendants + for a block and its descendants """ def __init__(self, descriptors, course_id, user, asides=None, read_only=False): """ Find any courseware.models objects that are needed by any descriptor in descriptors. Attempts to minimize the number of queries to the database. - Note: Only modules that have store_state = True or have shared + Note: Only blocks that have store_state = True or have shared state will have a StudentModule. Arguments @@ -725,7 +725,7 @@ def add_descriptor_descendents(self, descriptor, depth=None, descriptor_filter=l Arguments: descriptor: An XModuleDescriptor - depth is the number of levels of descendant modules to load StudentModules for, in addition to + depth is the number of levels of descendant blocks to load StudentModules for, in addition to the supplied descriptor. If depth is None, load all descendant StudentModules descriptor_filter is a function that accepts a descriptor and return whether the field data should be cached @@ -749,7 +749,7 @@ def get_child_descriptors(descriptor, depth, descriptor_filter): if depth is None or depth > 0: new_depth = depth - 1 if depth is not None else depth - for child in descriptor.get_children() + descriptor.get_required_module_descriptors(): + for child in descriptor.get_children() + descriptor.get_required_block_descriptors(): descriptors.extend(get_child_descriptors(child, new_depth, descriptor_filter)) return descriptors @@ -767,7 +767,7 @@ def cache_for_descriptor_descendents(cls, course_id, user, descriptor, depth=Non course_id: the course in the context of which we want StudentModules. user: the django user for whom to load modules. descriptor: An XModuleDescriptor - depth is the number of levels of descendant modules to load StudentModules for, in addition to + depth is the number of levels of descendant blocks to load StudentModules for, in addition to the supplied descriptor. If depth is None, load all descendant StudentModules descriptor_filter is a function that accepts a descriptor and return whether the field data should be cached diff --git a/lms/djangoapps/courseware/models.py b/lms/djangoapps/courseware/models.py index a1ec90a06baa..b5cd3839c351 100644 --- a/lms/djangoapps/courseware/models.py +++ b/lms/djangoapps/courseware/models.py @@ -340,14 +340,14 @@ def __str__(self): # lint-amnesty, pylint: disable=invalid-str-returned class XModuleUserStateSummaryField(XBlockFieldBase): # lint-amnesty, pylint: disable=model-no-explicit-unicode """ - Stores data set in the Scope.user_state_summary scope by an xmodule field + Stores data set in the Scope.user_state_summary scope by an xblock field """ class Meta: app_label = "courseware" unique_together = (('usage_id', 'field_name'),) - # The definition id for the module + # The definition id for the block usage_id = UsageKeyField(max_length=255, db_index=True) @@ -360,7 +360,7 @@ class Meta: app_label = "courseware" unique_together = (('student', 'module_type', 'field_name'),) - # The type of the module for these preferences + # The type of the block for these preferences module_type = BlockTypeKeyField(max_length=64, db_index=True) student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE) diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_block_render.py similarity index 92% rename from lms/djangoapps/courseware/tests/test_module_render.py rename to lms/djangoapps/courseware/tests/test_block_render.py index a3e687cb248b..53e10b5c5138 100644 --- a/lms/djangoapps/courseware/tests/test_module_render.py +++ b/lms/djangoapps/courseware/tests/test_block_render.py @@ -1,5 +1,5 @@ """ -Test for lms courseware app, module render unit +Test for lms courseware app, block render unit """ @@ -47,7 +47,7 @@ from xmodule.html_block import AboutBlock, CourseInfoBlock, HtmlBlock, StaticTabBlock from xmodule.lti_block import LTIBlock from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.django import ModuleI18nService, modulestore +from xmodule.modulestore.django import XBlockI18nService, modulestore from xmodule.modulestore.tests.django_utils import ( TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase, @@ -67,14 +67,14 @@ from common.djangoapps.xblock_django.constants import ATTR_KEY_ANONYMOUS_USER_ID from lms.djangoapps.badges.tests.factories import BadgeClassFactory from lms.djangoapps.badges.tests.test_models import get_image -from lms.djangoapps.courseware import module_render as render +from lms.djangoapps.courseware import block_render as render from lms.djangoapps.courseware.access_response import AccessResponse from lms.djangoapps.courseware.courses import get_course_info_section, get_course_with_access from lms.djangoapps.courseware.field_overrides import OverrideFieldData from lms.djangoapps.courseware.masquerade import CourseMasquerade from lms.djangoapps.courseware.model_data import FieldDataCache from lms.djangoapps.courseware.models import StudentModule -from lms.djangoapps.courseware.module_render import get_module_for_descriptor, hash_resource +from lms.djangoapps.courseware.block_render import get_block_for_descriptor, hash_resource from lms.djangoapps.courseware.tests.factories import StudentModuleFactory from lms.djangoapps.courseware.tests.test_submitting_problems import TestSubmittingProblems from lms.djangoapps.courseware.tests.tests import LoginEnrollmentTestCase @@ -193,9 +193,9 @@ def progress(self, json_data, suffix): # pylint: disable=unused-argument @ddt.ddt -class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): +class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): """ - Tests of courseware.module_render + Tests of courseware.block_render """ @classmethod @@ -217,9 +217,9 @@ def setUp(self): self.mock_user.id = 1 self.request_factory = RequestFactoryNoCsrf() - # Construct a mock module for the modulestore to return - self.mock_module = MagicMock() - self.mock_module.id = 1 + # Construct a mock block for the modulestore to return + self.mock_block = MagicMock() + self.mock_block.id = 1 self.dispatch = 'score_update' # Construct a 'standard' xqueue_callback url @@ -228,7 +228,7 @@ def setUp(self): kwargs=dict( course_id=str(self.course_key), userid=str(self.mock_user.id), - mod_id=self.mock_module.id, + mod_id=self.mock_block.id, dispatch=self.dispatch ) ) @@ -237,10 +237,10 @@ def tearDown(self): OverrideFieldData.provider_classes = None super().tearDown() - def test_get_module(self): - assert render.get_module('dummyuser', None, 'invalid location', None) is None + def test_get_block(self): + assert render.get_block('dummyuser', None, 'invalid location', None) is None - def test_module_render_with_jump_to_id(self): + def test_block_render_with_jump_to_id(self): """ This test validates that the /jump_to_id/ shorthand for intracourse linking works assertIn expected. Note there's a HTML element in the 'toy' course with the url_name 'toyjumpto' which @@ -254,7 +254,7 @@ def test_module_render_with_jump_to_id(self): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course_key, self.mock_user, course, depth=2) - module = render.get_module( + block = render.get_block( self.mock_user, mock_request, self.course_key.make_usage_key('html', 'toyjumpto'), @@ -262,7 +262,7 @@ def test_module_render_with_jump_to_id(self): ) # get the rendered HTML output which should have the rewritten link - html = module.render(STUDENT_VIEW).content + html = block.render(STUDENT_VIEW).content # See if the url got rewritten to the target link # note if the URL mapping changes then this assertion will break @@ -279,22 +279,22 @@ def test_xqueue_callback_success(self): 'xqueue_body': 'hello world', } - # Patch getmodule to return our mock module - with patch('lms.djangoapps.courseware.module_render.load_single_xblock', return_value=self.mock_module): + # Patch getmodule to return our mock block + with patch('lms.djangoapps.courseware.block_render.load_single_xblock', return_value=self.mock_block): # call xqueue_callback with our mocked information request = self.request_factory.post(self.callback_url, data) render.xqueue_callback( request, str(self.course_key), self.mock_user.id, - self.mock_module.id, + self.mock_block.id, self.dispatch ) # Verify that handle ajax is called with the correct data request.POST._mutable = True # lint-amnesty, pylint: disable=protected-access request.POST['queuekey'] = fake_key - self.mock_module.handle_ajax.assert_called_once_with(self.dispatch, request.POST) + self.mock_block.handle_ajax.assert_called_once_with(self.dispatch, request.POST) def test_xqueue_callback_missing_header_info(self): data = { @@ -302,7 +302,7 @@ def test_xqueue_callback_missing_header_info(self): 'xqueue_body': 'hello world', } - with patch('lms.djangoapps.courseware.module_render.load_single_xblock', return_value=self.mock_module): + with patch('lms.djangoapps.courseware.block_render.load_single_xblock', return_value=self.mock_block): # Test with missing xqueue data with pytest.raises(Http404): request = self.request_factory.post(self.callback_url, {}) @@ -310,7 +310,7 @@ def test_xqueue_callback_missing_header_info(self): request, str(self.course_key), self.mock_user.id, - self.mock_module.id, + self.mock_block.id, self.dispatch ) @@ -321,7 +321,7 @@ def test_xqueue_callback_missing_header_info(self): request, str(self.course_key), self.mock_user.id, - self.mock_module.id, + self.mock_block.id, self.dispatch ) @@ -413,9 +413,9 @@ def test_rebinding_same_user(self, block_type): course = CourseFactory() descriptor = BlockFactory(category=block_type, parent=course) field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user) - # This is verifying that caching doesn't cause an error during get_module_for_descriptor, which + # This is verifying that caching doesn't cause an error during get_block_for_descriptor, which # is why it calls the method twice identically. - render.get_module_for_descriptor( + render.get_block_for_descriptor( self.mock_user, request, descriptor, @@ -423,7 +423,7 @@ def test_rebinding_same_user(self, block_type): self.toy_course.id, course=self.toy_course ) - render.get_module_for_descriptor( + render.get_block_for_descriptor( self.mock_user, request, descriptor, @@ -478,7 +478,7 @@ def create_aside(item, block_type): # grab what _field_data was originally set to original_field_data = descriptor._field_data # lint-amnesty, pylint: disable=no-member, protected-access - render.get_module_for_descriptor( + render.get_block_for_descriptor( self.mock_user, request, descriptor, field_data_cache, course.id, course=course ) @@ -488,9 +488,9 @@ def create_aside(item, block_type): assert descriptor._unwrapped_field_data is original_field_data # lint-amnesty, pylint: disable=no-member assert descriptor._unwrapped_field_data is not descriptor._field_data # lint-amnesty, pylint: disable=no-member - # now bind this module to a few other students + # now bind this block to a few other students for user in [UserFactory(), UserFactory(), self.mock_user]: - render.get_module_for_descriptor( + render.get_block_for_descriptor( user, request, descriptor, @@ -537,9 +537,9 @@ def setUp(self): self.mock_user = UserFactory.create() self.request_factory = RequestFactoryNoCsrf() - # Construct a mock module for the modulestore to return - self.mock_module = MagicMock() - self.mock_module.id = 1 + # Construct a mock block for the modulestore to return + self.mock_block = MagicMock() + self.mock_block.id = 1 self.dispatch = 'score_update' # Construct a 'standard' xqueue_callback url @@ -547,7 +547,7 @@ def setUp(self): 'xqueue_callback', kwargs={ 'course_id': str(self.course_key), 'userid': str(self.mock_user.id), - 'mod_id': self.mock_module.id, + 'mod_id': self.mock_block.id, 'dispatch': self.dispatch } ) @@ -650,7 +650,7 @@ def test_too_large_file(self): request.user = self.mock_user assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': ('Submission aborted! Your file "%s" is too large (max size: %d MB)' % (inputfile.name, (settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))))}, indent=2) # pylint: disable=line-too-long - def test_xmodule_dispatch(self): + def test_xblock_dispatch(self): request = self.request_factory.post('dummy_url', data={'position': 1}) request.user = self.mock_user response = render.handle_xblock_callback( @@ -686,7 +686,7 @@ def test_bad_location(self): 'goto_position', ) - def test_bad_xmodule_dispatch(self): + def test_bad_xblock_dispatch(self): request = self.request_factory.post('dummy_url') request.user = self.mock_user with pytest.raises(Http404): @@ -803,12 +803,12 @@ def get_usage_key(): ) with patch( - 'lms.djangoapps.courseware.module_render.is_xblock_aside', + 'lms.djangoapps.courseware.block_render.is_xblock_aside', return_value=is_xblock_aside ), patch( - 'lms.djangoapps.courseware.module_render.get_aside_from_xblock' + 'lms.djangoapps.courseware.block_render.get_aside_from_xblock' ) as mocked_get_aside_from_xblock, patch( - 'lms.djangoapps.courseware.module_render.webob_to_django_response' + 'lms.djangoapps.courseware.block_render.webob_to_django_response' ) as mocked_webob_to_django_response: render.handle_xblock_callback( request, @@ -833,7 +833,7 @@ def test_aside_invalid_usage_id(self): request.user = self.mock_user with patch( - 'lms.djangoapps.courseware.module_render.is_xblock_aside', + 'lms.djangoapps.courseware.block_render.is_xblock_aside', return_value=True ), self.assertRaises(Http404): render.handle_xblock_callback( @@ -925,8 +925,8 @@ def test_anonymous_user_not_be_graded(self, mock_score_signal): ('goto_position', False), # does not set it ) @ddt.unpack - @patch('lms.djangoapps.courseware.module_render.get_module_for_descriptor', wraps=get_module_for_descriptor) - def test_will_recheck_access_handler_attribute(self, handler, will_recheck_access, mock_get_module): + @patch('lms.djangoapps.courseware.block_render.get_block_for_descriptor', wraps=get_block_for_descriptor) + def test_will_recheck_access_handler_attribute(self, handler, will_recheck_access, mock_get_block): """Confirm that we pay attention to any 'will_recheck_access' attributes on handler methods""" course = CourseFactory.create() descriptor_kwargs = { @@ -941,8 +941,8 @@ def test_will_recheck_access_handler_attribute(self, handler, will_recheck_acces request.user = self.mock_user render.handle_xblock_callback(request, str(course.id), usage_id, handler) - assert mock_get_module.call_count == 1 - assert mock_get_module.call_args[1]['will_recheck_access'] == will_recheck_access + assert mock_get_block.call_count == 1 + assert mock_get_block.call_args[1]['will_recheck_access'] == will_recheck_access @ddt.ddt @@ -1320,14 +1320,14 @@ def test_render_proctored_exam(self, enrollment_mode, is_practice_exam, 'ICRV1' ) - module = render.get_module( + block = render.get_block( self.request.user, self.request, usage_key, self.field_data_cache, - wrap_xmodule_display=True, + wrap_xblock_display=True, ) - content = module.render(STUDENT_VIEW).content + content = block.render(STUDENT_VIEW).content assert expected in content @@ -1515,49 +1515,49 @@ def setUp(self): self.descriptor ) - def test_xmodule_display_wrapper_enabled(self): - module = render.get_module( + def test_xblock_display_wrapper_enabled(self): + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, - wrap_xmodule_display=True, + wrap_xblock_display=True, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert len(PyQuery(result_fragment.content)('div.xblock.xblock-student_view.xmodule_HtmlBlock')) == 1 def test_xmodule_display_wrapper_disabled(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, - wrap_xmodule_display=False, + wrap_xblock_display=False, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'div class="xblock xblock-student_view xmodule_display xmodule_HtmlBlock"' not in result_fragment.content def test_static_link_rewrite(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) key = self.course.location assert f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block/foo_content' in result_fragment.content def test_static_badlink_rewrite(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) key = self.course.location assert f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block/file.jpg' in result_fragment.content @@ -1568,14 +1568,14 @@ def test_static_asset_path_use(self): static_asset_path is set as an lms kv in course. That should make static paths not be mangled (ie not changed to c4x://). ''' - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, static_asset_path="toy_course_dir", ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'href="/static/toy_course_dir' in result_fragment.content def test_course_image(self): @@ -1606,13 +1606,13 @@ def test_get_course_info_section(self): # at least this makes sure get_course_info_section returns without exception def test_course_link_rewrite(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert f'/courses/{str(self.course.id)}/bar/content' in result_fragment.content @@ -1651,7 +1651,7 @@ def test_json_init_data(self, json_data, json_output): course = CourseFactory() descriptor = BlockFactory(category='withjson', parent=course) field_data_cache = FieldDataCache([course, descriptor], course.id, mock_user) - module = render.get_module_for_descriptor( + block = render.get_block_for_descriptor( mock_user, mock_request, descriptor, @@ -1659,7 +1659,7 @@ def test_json_init_data(self, json_data, json_output): course.id, course=course ) - html = module.render(STUDENT_VIEW).content + html = block.render(STUDENT_VIEW).content assert json_output in html # No matter what data goes in, there should only be one close-script tag. assert html.count('') == 1 @@ -1680,7 +1680,7 @@ def student_view(self, context=None): # pylint: disable=unused-argument @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_DEBUG_INFO_TO_STAFF': True, 'DISPLAY_HISTOGRAMS_TO_STAFF': True}) -@patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True)) +@patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True)) class TestStaffDebugInfo(SharedModuleStoreTestCase): """Tests to verify that Staff Debug Info panel and histograms are displayed to staff.""" MODULESTORE = TEST_DATA_SPLIT_MODULESTORE @@ -1719,23 +1719,23 @@ def setUp(self): @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_DEBUG_INFO_TO_STAFF': False}) def test_staff_debug_info_disabled(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'Staff Debug' not in result_fragment.content def test_staff_debug_info_enabled(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'Staff Debug' in result_fragment.content def test_staff_debug_info_score_for_invalid_dropdown(self): @@ -1761,13 +1761,13 @@ def test_staff_debug_info_score_for_invalid_dropdown(self): category='problem', data=problem_xml ) - module = render.get_module( + block = render.get_block( self.user, self.request, problem_descriptor.location, self.field_data_cache ) - html_fragment = module.render(STUDENT_VIEW) + html_fragment = block.render(STUDENT_VIEW) expected_score_override_html = textwrap.dedent("""
@@ -1790,28 +1790,28 @@ def test_staff_debug_info_disabled_for_detached_blocks(self): self.user, descriptor ) - module = render.get_module( + block = render.get_block( self.user, self.request, descriptor.location, field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'Staff Debug' not in result_fragment.content @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_HISTOGRAMS_TO_STAFF': False}) def test_histogram_disabled(self): - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - result_fragment = module.render(STUDENT_VIEW) + result_fragment = block.render(STUDENT_VIEW) assert 'histrogram' not in result_fragment.content - def test_histogram_enabled_for_unscored_xmodules(self): - """Histograms should not display for xmodules which are not scored.""" + def test_histogram_enabled_for_unscored_xblocks(self): + """Histograms should not display for xblocks which are not scored.""" html_descriptor = BlockFactory.create( category='html', @@ -1824,17 +1824,17 @@ def test_histogram_enabled_for_unscored_xmodules(self): ) with patch('openedx.core.lib.xblock_utils.grade_histogram') as mock_grade_histogram: mock_grade_histogram.return_value = [] - module = render.get_module( + block = render.get_block( self.user, self.request, html_descriptor.location, field_data_cache, ) - module.render(STUDENT_VIEW) + block.render(STUDENT_VIEW) assert not mock_grade_histogram.called - def test_histogram_enabled_for_scored_xmodules(self): - """Histograms should display for xmodules which are scored.""" + def test_histogram_enabled_for_scored_xblocks(self): + """Histograms should display for xblocks which are scored.""" StudentModuleFactory.create( course_id=self.course.id, @@ -1846,13 +1846,13 @@ def test_histogram_enabled_for_scored_xmodules(self): ) with patch('openedx.core.lib.xblock_utils.grade_histogram') as mock_grade_histogram: mock_grade_histogram.return_value = [] - module = render.get_module( + block = render.get_block( self.user, self.request, self.location, self.field_data_cache, ) - module.render(STUDENT_VIEW) + block.render(STUDENT_VIEW) assert mock_grade_histogram.called @@ -1885,7 +1885,7 @@ def setUp(self): super().setUp() self.user = UserFactory() - @patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True)) + @patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True)) def _get_anonymous_id(self, course_id, xblock_class): # lint-amnesty, pylint: disable=missing-function-docstring location = course_id.make_usage_key('dummy_category', 'dummy_name') descriptor = Mock( @@ -1913,7 +1913,7 @@ def _get_anonymous_id(self, course_id, xblock_class): # lint-amnesty, pylint: d if hasattr(xblock_class, 'module_class'): descriptor.module_class = xblock_class.module_class - module = render.get_module_for_descriptor_internal( + block = render.get_block_for_descriptor_internal( user=self.user, descriptor=descriptor, student_data=Mock(spec=FieldData, name='student_data'), @@ -1922,7 +1922,7 @@ def _get_anonymous_id(self, course_id, xblock_class): # lint-amnesty, pylint: d request_token='request_token', course=self.course, ) - current_user = module.xmodule_runtime.service(module, 'user').get_current_user() + current_user = block.xmodule_runtime.service(block, 'user').get_current_user() return current_user.opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID) @ddt.data(*PER_STUDENT_ANONYMIZED_XBLOCKS) @@ -1970,8 +1970,8 @@ def setUp(self): def test_context_contains_display_name(self, mock_tracker): problem_display_name = 'Option Response Problem' - module_info = self.handle_callback_and_get_module_info(mock_tracker, problem_display_name) - assert problem_display_name == module_info['display_name'] + block_info = self.handle_callback_and_get_block_info(mock_tracker, problem_display_name) + assert problem_display_name == block_info['display_name'] @XBlockAside.register_temp_plugin(AsideTestType, 'test_aside') @patch('xmodule.modulestore.mongo.base.CachingDescriptorSystem.applicable_aside_types', @@ -2009,7 +2009,7 @@ def handle_callback_and_get_context_info(self, problem_display_name=None, call_idx=0): """ - Creates a fake module, invokes the callback and extracts the 'context' + Creates a fake block, invokes the callback and extracts the 'context' metadata from the emitted problem_check event. """ @@ -2022,7 +2022,7 @@ def handle_callback_and_get_context_info(self, descriptor = BlockFactory.create(**descriptor_kwargs) mock_tracker_for_context = MagicMock() - with patch('lms.djangoapps.courseware.module_render.tracker', mock_tracker_for_context), patch( + with patch('lms.djangoapps.courseware.block_render.tracker', mock_tracker_for_context), patch( 'xmodule.services.tracker', mock_tracker_for_context ): render.handle_xblock_callback( @@ -2045,9 +2045,9 @@ def handle_callback_and_get_context_info(self, return context - def handle_callback_and_get_module_info(self, mock_tracker, problem_display_name=None): + def handle_callback_and_get_block_info(self, mock_tracker, problem_display_name=None): """ - Creates a fake module, invokes the callback and extracts the 'module' + Creates a fake block, invokes the callback and extracts the 'block' metadata from the emitted problem_check event. """ event = self.handle_callback_and_get_context_info( @@ -2056,7 +2056,7 @@ def handle_callback_and_get_module_info(self, mock_tracker, problem_display_name return event['module'] def test_missing_display_name(self, mock_tracker): - actual_display_name = self.handle_callback_and_get_module_info(mock_tracker)['display_name'] + actual_display_name = self.handle_callback_and_get_block_info(mock_tracker)['display_name'] assert actual_display_name.startswith('problem') def test_library_source_information(self, mock_tracker): @@ -2072,14 +2072,14 @@ def _mock_get_original_usage(_, __): return original_usage_key, original_usage_version with patch('xmodule.modulestore.mixed.MixedModuleStore.get_block_original_usage', _mock_get_original_usage): - module_info = self.handle_callback_and_get_module_info(mock_tracker) - assert 'original_usage_key' in module_info - assert module_info['original_usage_key'] == str(original_usage_key) - assert 'original_usage_version' in module_info - assert module_info['original_usage_version'] == str(original_usage_version) + block_info = self.handle_callback_and_get_block_info(mock_tracker) + assert 'original_usage_key' in block_info + assert block_info['original_usage_key'] == str(original_usage_key) + assert 'original_usage_version' in block_info + assert block_info['original_usage_version'] == str(original_usage_version) -class TestXmoduleRuntimeEvent(TestSubmittingProblems): +class TestXBlockRuntimeEvent(TestSubmittingProblems): """ Inherit from TestSubmittingProblems to get functionality that set up a course and problems structure """ @@ -2091,37 +2091,37 @@ def setUp(self): self.grade_dict = {'value': 0.18, 'max_value': 32} self.delete_dict = {'value': None, 'max_value': None} - def get_module_for_user(self, user): - """Helper function to get useful module at self.location in self.course_id for user""" + def get_block_for_user(self, user): + """Helper function to get useful block at self.location in self.course_id for user""" mock_request = MagicMock() mock_request.user = user field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course.id, user, self.course, depth=2) - return render.get_module( + return render.get_block( user, mock_request, self.problem.location, field_data_cache, ) - def set_module_grade_using_publish(self, grade_dict): + def set_block_grade_using_publish(self, grade_dict): """Publish the user's grade, takes grade_dict as input""" - module = self.get_module_for_user(self.student_user) - module.system.publish(module, 'grade', grade_dict) - return module + block = self.get_block_for_user(self.student_user) + block.runtime.publish(block, 'grade', grade_dict) + return block - def test_xmodule_runtime_publish(self): + def test_xblock_runtime_publish(self): """Tests the publish mechanism""" - self.set_module_grade_using_publish(self.grade_dict) + self.set_block_grade_using_publish(self.grade_dict) student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location) assert student_module.grade == self.grade_dict['value'] assert student_module.max_grade == self.grade_dict['max_value'] - def test_xmodule_runtime_publish_delete(self): + def test_xblock_runtime_publish_delete(self): """Test deleting the grade using the publish mechanism""" - module = self.set_module_grade_using_publish(self.grade_dict) - module.system.publish(module, 'grade', self.delete_dict) + block = self.set_block_grade_using_publish(self.grade_dict) + block.runtime.publish(block, 'grade', self.delete_dict) student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location) assert student_module.grade is None assert student_module.max_grade is None @@ -2130,7 +2130,7 @@ def test_xmodule_runtime_publish_delete(self): def test_score_change_signal(self, send_mock): """Test that a Django signal is generated when a score changes""" with freeze_time(datetime.now().replace(tzinfo=pytz.UTC)): - self.set_module_grade_using_publish(self.grade_dict) + self.set_block_grade_using_publish(self.grade_dict) expected_signal_kwargs = { 'sender': None, 'raw_possible': self.grade_dict['max_value'], @@ -2148,9 +2148,9 @@ def test_score_change_signal(self, send_mock): send_mock.assert_called_with(**expected_signal_kwargs) -class TestRebindModule(TestSubmittingProblems): +class TestRebindBlock(TestSubmittingProblems): """ - Tests to verify the functionality of rebinding a module. + Tests to verify the functionality of rebinding a block. Inherit from TestSubmittingProblems to get functionality that set up a course structure """ @@ -2162,8 +2162,8 @@ def setUp(self): self.user = UserFactory.create() self.anon_user = AnonymousUser() - def get_module_for_user(self, user, item=None): - """Helper function to get useful module at self.location in self.course_id for user""" + def get_block_for_user(self, user, item=None): + """Helper function to get useful block at self.location in self.course_id for user""" mock_request = MagicMock() mock_request.user = user field_data_cache = FieldDataCache.cache_for_descriptor_descendents( @@ -2172,57 +2172,57 @@ def get_module_for_user(self, user, item=None): if item is None: item = self.lti - return render.get_module( + return render.get_block( user, mock_request, item.location, field_data_cache, ) - def test_rebind_module_to_new_users(self): - module = self.get_module_for_user(self.user, self.problem) + def test_rebind_block_to_new_users(self): + block = self.get_block_for_user(self.user, self.problem) - # Bind the module to another student, which will remove "correct_map" - # from the module's _field_data_cache and _dirty_fields. + # Bind the block to another student, which will remove "correct_map" + # from the block's _field_data_cache and _dirty_fields. user2 = UserFactory.create() - module.bind_for_student(module.system, user2.id) + block.bind_for_student(block.runtime, 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 - # doesn't hold, then we get an error trying to bind this module + # doesn't hold, then we get an error trying to bind this block # to a third student, since we've removed "correct_map" from # _field_data cache, but not _dirty_fields, when we bound - # this module to the second student. (TNL-2640) + # this block to the second student. (TNL-2640) user3 = UserFactory.create() - module.bind_for_student(module.system, user3.id) + block.bind_for_student(block.runtime, user3.id) - def test_rebind_noauth_module_to_user_not_anonymous(self): + def test_rebind_noauth_block_to_user_not_anonymous(self): """ - Tests that an exception is thrown when rebind_noauth_module_to_user is run from a - module bound to a real user + Tests that an exception is thrown when rebind_noauth_block_to_user is run from a + block bound to a real user """ - module = self.get_module_for_user(self.user) + block = self.get_block_for_user(self.user) user2 = UserFactory() user2.id = 2 with self.assertRaisesRegex( RebindUserServiceError, "rebind_noauth_module_to_user can only be called from a module bound to an anonymous user" ): - assert module.runtime.service(module, 'rebind_user').rebind_noauth_module_to_user(module, user2) + assert block.runtime.service(block, 'rebind_user').rebind_noauth_module_to_user(block, user2) - def test_rebind_noauth_module_to_user_anonymous(self): + def test_rebind_noauth_block_to_user_anonymous(self): """ - Tests that get_user_module_for_noauth succeeds when rebind_noauth_module_to_user is run from a - module bound to AnonymousUser + Tests that get_user_block_for_noauth succeeds when rebind_noauth_block_to_user is run from a + block bound to AnonymousUser """ - module = self.get_module_for_user(self.anon_user) + block = self.get_block_for_user(self.anon_user) user2 = UserFactory() user2.id = 2 - module.runtime.service(module, 'rebind_user').rebind_noauth_module_to_user(module, user2) - assert module - assert module.system.anonymous_student_id == anonymous_id_for_user(user2, self.course.id) - assert module.scope_ids.user_id == user2.id - assert module.scope_ids.user_id == user2.id + block.runtime.service(block, 'rebind_user').rebind_noauth_module_to_user(block, user2) + assert block + assert block.runtime.anonymous_student_id == anonymous_id_for_user(user2, self.course.id) + assert block.scope_ids.user_id == user2.id + assert block.scope_ids.user_id == user2.id @ddt.ddt @@ -2249,7 +2249,7 @@ def test_event_publishing(self, mock_track_function): course = CourseFactory() descriptor = BlockFactory(category='xblock', parent=course) field_data_cache = FieldDataCache([course, descriptor], course.id, self.mock_user) - block = render.get_module(self.mock_user, request, descriptor.location, field_data_cache) + block = render.get_block(self.mock_user, request, descriptor.location, field_data_cache) event_type = 'event_type' event = {'event': 'data'} @@ -2415,7 +2415,7 @@ def test_get_badge_class(self): class TestI18nService(LMSXBlockServiceMixin): - """ Test ModuleI18nService """ + """ Test XBlockI18nService """ def test_module_i18n_lms_service(self): """ @@ -2423,7 +2423,7 @@ def test_module_i18n_lms_service(self): """ i18n_service = self.runtime.service(self.descriptor, 'i18n') assert i18n_service is not None - assert isinstance(i18n_service, ModuleI18nService) + assert isinstance(i18n_service, XBlockI18nService) def test_no_service_exception_with_none_declaration_(self): """ @@ -2477,7 +2477,7 @@ def setUp(self): self.users = {number: UserFactory() for number in USER_NUMBERS} self._old_has_access = render.has_access - patcher = patch('lms.djangoapps.courseware.module_render.has_access', self._has_access) + patcher = patch('lms.djangoapps.courseware.block_render.has_access', self._has_access) patcher.start() self.addCleanup(patcher.stop) @@ -2497,7 +2497,7 @@ def test_unbound_then_bound_as_descriptor(self, user_number): @ddt.data(*USER_NUMBERS) @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') - def test_unbound_then_bound_as_xmodule(self, user_number): + def test_unbound_then_bound_as_xblock(self, user_number): user = self.users[user_number] block = self._load_block() self.assertUnboundChildren(block) @@ -2514,7 +2514,7 @@ def test_bound_only_as_descriptor(self, user_number): @ddt.data(*USER_NUMBERS) @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') - def test_bound_only_as_xmodule(self, user_number): + def test_bound_only_as_xblock(self, user_number): user = self.users[user_number] block = self._load_block() self._bind_block(block, user) @@ -2546,7 +2546,7 @@ def _bind_block(self, block, user): user, block, ) - return get_module_for_descriptor( + return get_block_for_descriptor( user, Mock(name='request', user=user), block, @@ -2688,7 +2688,7 @@ def test_user_service_attributes(self, attribute, expected_value): """ assert getattr(self.runtime, attribute) == expected_value - @patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True)) + @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( self.user, @@ -2702,7 +2702,7 @@ def test_user_is_staff(self): assert runtime.user_is_staff assert runtime.get_user_role() == 'student' - @patch('lms.djangoapps.courseware.module_render.get_user_role', Mock(return_value='instructor', autospec=True)) + @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( self.user, @@ -2885,5 +2885,5 @@ def test_replace_jump_to_id_urls(self): def test_course_id(self): descriptor = BlockFactory(category="pure", parent=self.course) - block = render.get_module(self.user, Mock(), descriptor.location, None) + block = render.get_block(self.user, Mock(), descriptor.location, None) assert str(block.runtime.course_id) == self.COURSE_ID diff --git a/lms/djangoapps/courseware/tests/test_courses.py b/lms/djangoapps/courseware/tests/test_courses.py index 4067b19d1c02..d4d6c97fbe1d 100644 --- a/lms/djangoapps/courseware/tests/test_courses.py +++ b/lms/djangoapps/courseware/tests/test_courses.py @@ -39,7 +39,7 @@ get_current_child ) from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException from openedx.core.djangolib.testing.utils import get_mock_request from openedx.core.lib.courses import course_image_url @@ -162,21 +162,21 @@ def test_get_courses_with_filter(self): expected_courses, f'testing get_courses with filter_={filter_}' def test_get_current_child(self): - mock_xmodule = mock.MagicMock() - assert get_current_child(mock_xmodule) is None + mock_xblock = mock.MagicMock() + assert get_current_child(mock_xblock) is None - mock_xmodule.position = -1 - mock_xmodule.get_children.return_value = ['one', 'two', 'three'] - assert get_current_child(mock_xmodule) == 'one' + mock_xblock.position = -1 + mock_xblock.get_children.return_value = ['one', 'two', 'three'] + assert get_current_child(mock_xblock) == 'one' - mock_xmodule.position = 2 - assert get_current_child(mock_xmodule) == 'two' - assert get_current_child(mock_xmodule, requested_child='first') == 'one' - assert get_current_child(mock_xmodule, requested_child='last') == 'three' + mock_xblock.position = 2 + assert get_current_child(mock_xblock) == 'two' + assert get_current_child(mock_xblock, requested_child='first') == 'one' + assert get_current_child(mock_xblock, requested_child='last') == 'three' - mock_xmodule.position = 3 - mock_xmodule.get_children.return_value = [] - assert get_current_child(mock_xmodule) is None + mock_xblock.position = 3 + mock_xblock.get_children.return_value = [] + assert get_current_child(mock_xblock) is None class ModuleStoreBranchSettingTest(ModuleStoreTestCase): @@ -287,8 +287,8 @@ def test_get_course_info_section_render(self): "Sample" # Test when render raises an exception - with mock.patch('lms.djangoapps.courseware.courses.get_module') as mock_module_render: - mock_module_render.return_value = mock.MagicMock( + with mock.patch('lms.djangoapps.courseware.courses.get_block') as mock_block_render: + mock_block_render.return_value = mock.MagicMock( render=mock.Mock(side_effect=Exception('Render failed!')) ) course_info = get_course_info_section(self.request, self.request.user, self.course, 'handouts') @@ -301,8 +301,8 @@ def test_get_course_about_section_render(self): assert course_about == 'A course about toys.' # Test when render raises an exception - with mock.patch('lms.djangoapps.courseware.courses.get_module') as mock_module_render: - mock_module_render.return_value = mock.MagicMock( + with mock.patch('lms.djangoapps.courseware.courses.get_block') as mock_block_render: + mock_block_render.return_value = mock.MagicMock( render=mock.Mock(side_effect=Exception('Render failed!')) ) course_about = get_course_about_section(self.request, self.course, 'short_description') @@ -385,7 +385,7 @@ def test_repeated_course_block_instantiation(self, loops, course_depth): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, self.user, course, depth=course_depth ) - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( self.user, fake_request, course, diff --git a/lms/djangoapps/courseware/tests/test_discussion_xblock.py b/lms/djangoapps/courseware/tests/test_discussion_xblock.py index b3519e40cf21..49f76be0f400 100644 --- a/lms/djangoapps/courseware/tests/test_discussion_xblock.py +++ b/lms/djangoapps/courseware/tests/test_discussion_xblock.py @@ -21,7 +21,7 @@ from xmodule.modulestore.tests.factories import BlockFactory, ToyCourseFactory from lms.djangoapps.course_api.blocks.tests.helpers import deserialize_usage_key -from lms.djangoapps.courseware.module_render import get_module_for_descriptor_internal +from lms.djangoapps.courseware.block_render import get_block_for_descriptor_internal from lms.djangoapps.courseware.tests.helpers import XModuleRenderingTestBase from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory @@ -294,7 +294,7 @@ def test_html_with_user(self): """ Test rendered DiscussionXBlock permissions. """ - discussion_xblock = get_module_for_descriptor_internal( + discussion_xblock = get_block_for_descriptor_internal( user=self.user, descriptor=self.discussion, student_data=mock.Mock(name='student_data'), @@ -337,7 +337,7 @@ def test_discussion_render_successfully_with_orphan_parent(self): assert orphan_sequential.location.block_id == root.location.block_id # Get xblock bound to a user and a descriptor. - discussion_xblock = get_module_for_descriptor_internal( + discussion_xblock = get_block_for_descriptor_internal( user=self.user, descriptor=discussion, student_data=mock.Mock(name='student_data'), @@ -387,7 +387,7 @@ def test_discussion_xblock_visibility(self): provider_type=Provider.OPEN_EDX, ) - discussion_xblock = get_module_for_descriptor_internal( + discussion_xblock = get_block_for_descriptor_internal( user=self.user, descriptor=self.discussion, student_data=mock.Mock(name='student_data'), @@ -437,7 +437,7 @@ def test_permissions_query_load(self): num_queries = 6 for discussion in discussions: - discussion_xblock = get_module_for_descriptor_internal( + discussion_xblock = get_block_for_descriptor_internal( user=user, descriptor=discussion, student_data=mock.Mock(name='student_data'), diff --git a/lms/djangoapps/courseware/tests/test_entrance_exam.py b/lms/djangoapps/courseware/tests/test_entrance_exam.py index 1d638e51a002..7024ea5c3c3b 100644 --- a/lms/djangoapps/courseware/tests/test_entrance_exam.py +++ b/lms/djangoapps/courseware/tests/test_entrance_exam.py @@ -17,7 +17,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory from xmodule.capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module, handle_xblock_callback, toc_for_course +from lms.djangoapps.courseware.block_render import get_block, handle_xblock_callback, toc_for_course from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase from openedx.core.djangolib.testing.utils import get_mock_request from common.djangoapps.student.models import CourseEnrollment @@ -378,13 +378,13 @@ def answer_entrance_exam_problem(course, request, problem, user=None, value=1, m course, depth=2 ) - module = get_module( + block = get_block( user, request, problem.scope_ids.usage_id, field_data_cache, ) - module.system.publish(problem, 'grade', grade_dict) + block.runtime.publish(problem, 'grade', grade_dict) def add_entrance_exam_milestone(course, entrance_exam): diff --git a/lms/djangoapps/courseware/tests/test_split_module.py b/lms/djangoapps/courseware/tests/test_split_module.py index fb33874d730b..7e6b88718eac 100644 --- a/lms/djangoapps/courseware/tests/test_split_module.py +++ b/lms/djangoapps/courseware/tests/test_split_module.py @@ -10,7 +10,7 @@ from xmodule.partitions.partitions import Group, UserPartition from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory @@ -314,7 +314,7 @@ def setUp(self): def test_changing_position_works(self): # Make a mock FieldDataCache for this course, so we can get the course block mock_field_data_cache = FieldDataCache([self.course], self.course.id, self.student) - course = get_module_for_descriptor( + course = get_block_for_descriptor( self.student, MagicMock(name='request'), self.course, diff --git a/lms/djangoapps/courseware/tests/test_tabs.py b/lms/djangoapps/courseware/tests/test_tabs.py index f65729961057..db59fa373bc5 100644 --- a/lms/djangoapps/courseware/tests/test_tabs.py +++ b/lms/djangoapps/courseware/tests/test_tabs.py @@ -280,8 +280,8 @@ def test_get_static_tab_fragment(self): assert 'static_tab' in tab_content # Test when render raises an exception - with patch('lms.djangoapps.courseware.views.views.get_module') as mock_module_render: - mock_module_render.return_value = MagicMock( + with patch('lms.djangoapps.courseware.views.views.get_block') as mock_block_render: + mock_block_render.return_value = MagicMock( render=Mock(side_effect=Exception('Render failed!')) ) static_tab_content = get_static_tab_fragment(request, course, tab).content diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py index 7fc2f21ee29c..9f51f06c018d 100644 --- a/lms/djangoapps/courseware/tests/test_video_mongo.py +++ b/lms/djangoapps/courseware/tests/test_video_mongo.py @@ -1188,7 +1188,7 @@ def test_deprecate_youtube_course_waffle_flag(self, data): @ddt.ddt class TestVideoBlockInitialization(BaseTestVideoXBlock): """ - Make sure that module initialization works correctly. + Make sure that block initialization works correctly. """ CATEGORY = "video" DATA = SOURCE_XML @@ -1786,7 +1786,7 @@ def test_import_val_data_internal(self): Test that import val data internal works as expected. """ create_profile('mobile') - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) edx_video_id = 'test_edx_video_id' sub_id = '0CzPOIIdUsA' @@ -1889,7 +1889,7 @@ def test_import_no_video_id(self): """ xml_data = """""" xml_object = etree.fromstring(xml_data) - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) id_generator = Mock() # Verify edx_video_id is empty before. @@ -1926,7 +1926,7 @@ def test_import_val_transcript(self): val_transcript_provider=val_transcript_provider ) xml_object = etree.fromstring(xml_data) - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) id_generator = Mock() # Create static directory in import file system and place transcript files inside it. @@ -2032,7 +2032,7 @@ def test_import_val_transcript_priority(self, sub_id, external_transcripts, val_ edx_video_id = 'test_edx_video_id' language_code = 'en' - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) id_generator = Mock() # Create static directory in import file system and place transcript files inside it. @@ -2101,7 +2101,7 @@ def test_import_val_transcript_priority(self, sub_id, external_transcripts, val_ def test_import_val_data_invalid(self): create_profile('mobile') - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) # Negative file_size is invalid xml_data = """ diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index f7e1b9f6c120..f8456349fd1a 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -70,7 +70,7 @@ from lms.djangoapps.commerce.utils import EcommerceService from lms.djangoapps.courseware.access_utils import check_course_open_for_learner from lms.djangoapps.courseware.model_data import FieldDataCache, set_score -from lms.djangoapps.courseware.module_render import get_module, handle_xblock_callback +from lms.djangoapps.courseware.block_render import get_block, handle_xblock_callback from lms.djangoapps.courseware.tests.factories import StudentModuleFactory from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin, get_expiration_banner_text, set_preview_mode from lms.djangoapps.courseware.testutils import RenderXBlockTestMixin @@ -194,46 +194,46 @@ def test_jump_to_mfe_from_sequence(self): assert response.url == expected_redirect_url @set_preview_mode(True) - def test_jump_to_legacy_from_module(self): + def test_jump_to_legacy_from_block(self): with self.store.default_store(ModuleStoreEnum.Type.split): course = CourseFactory.create() chapter = BlockFactory.create(category='chapter', parent_location=course.location) sequence = BlockFactory.create(category='sequential', parent_location=chapter.location) vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.location) vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.location) - module1 = BlockFactory.create(category='html', parent_location=vertical1.location) - module2 = BlockFactory.create(category='html', parent_location=vertical2.location) + block1 = BlockFactory.create(category='html', parent_location=vertical1.location) + block2 = BlockFactory.create(category='html', parent_location=vertical2.location) - activate_block_id = urlencode({'activate_block_id': str(module1.location)}) + activate_block_id = urlencode({'activate_block_id': str(block1.location)}) expected_redirect_url = ( f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/1?{activate_block_id}' ) - jumpto_url = f'/courses/{course.id}/jump_to/{module1.location}' + jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}' response = self.client.get(jumpto_url) self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302) - activate_block_id = urlencode({'activate_block_id': str(module2.location)}) + activate_block_id = urlencode({'activate_block_id': str(block2.location)}) expected_redirect_url = ( f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/2?{activate_block_id}' ) - jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}' + jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}' response = self.client.get(jumpto_url) self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302) @set_preview_mode(False) - def test_jump_to_mfe_from_module(self): + def test_jump_to_mfe_from_block(self): course = CourseFactory.create() chapter = BlockFactory.create(category='chapter', parent_location=course.location) sequence = BlockFactory.create(category='sequential', parent_location=chapter.location) vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.location) vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.location) - module1 = BlockFactory.create(category='html', parent_location=vertical1.location) - module2 = BlockFactory.create(category='html', parent_location=vertical2.location) + block1 = BlockFactory.create(category='html', parent_location=vertical1.location) + block2 = BlockFactory.create(category='html', parent_location=vertical2.location) expected_redirect_url = ( f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical1.location}' ) - jumpto_url = f'/courses/{course.id}/jump_to/{module1.location}' + jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}' response = self.client.get(jumpto_url) assert response.status_code == 302 assert response.url == expected_redirect_url @@ -241,7 +241,7 @@ def test_jump_to_mfe_from_module(self): expected_redirect_url = ( f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical2.location}' ) - jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}' + jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}' response = self.client.get(jumpto_url) assert response.status_code == 302 assert response.url == expected_redirect_url @@ -249,7 +249,7 @@ def test_jump_to_mfe_from_module(self): # The new courseware experience does not support this sort of course structure; # it assumes a simple course->chapter->sequence->unit->component tree. @set_preview_mode(True) - def test_jump_to_legacy_from_nested_module(self): + def test_jump_to_legacy_from_nested_block(self): with self.store.default_store(ModuleStoreEnum.Type.split): course = CourseFactory.create() chapter = BlockFactory.create(category='chapter', parent_location=course.location) @@ -257,17 +257,17 @@ def test_jump_to_legacy_from_nested_module(self): vertical = BlockFactory.create(category='vertical', parent_location=sequence.location) nested_sequence = BlockFactory.create(category='sequential', parent_location=vertical.location) nested_vertical1 = BlockFactory.create(category='vertical', parent_location=nested_sequence.location) - # put a module into nested_vertical1 for completeness + # put a block into nested_vertical1 for completeness BlockFactory.create(category='html', parent_location=nested_vertical1.location) nested_vertical2 = BlockFactory.create(category='vertical', parent_location=nested_sequence.location) - module2 = BlockFactory.create(category='html', parent_location=nested_vertical2.location) + block2 = BlockFactory.create(category='html', parent_location=nested_vertical2.location) - # internal position of module2 will be 1_2 (2nd item withing 1st item) - activate_block_id = urlencode({'activate_block_id': str(module2.location)}) + # internal position of block2 will be 1_2 (2nd item withing 1st item) + activate_block_id = urlencode({'activate_block_id': str(block2.location)}) expected_redirect_url = ( f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/1?{activate_block_id}' ) - jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}' + jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}' response = self.client.get(jumpto_url) self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302) @@ -1927,7 +1927,7 @@ def answer_problem(self, value=1, max_value=1): """ Submit the given score to the problem on behalf of the user """ - # Get the module for the problem, as viewed by the user + # Get the block for the problem, as viewed by the user field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course.id, self.user, @@ -1935,16 +1935,16 @@ def answer_problem(self, value=1, max_value=1): depth=2 ) self.addCleanup(set_current_request, None) - module = get_module( + block = get_block( self.user, get_mock_request(self.user), self.problem.scope_ids.usage_id, - field_data_cache, + field_data_cache ) # Submit the given score/max_score to the problem xmodule grade_dict = {'value': value, 'max_value': max_value, 'user_id': self.user.id} - module.system.publish(self.problem, 'grade', grade_dict) + block.runtime.publish(self.problem, 'grade', grade_dict) def assert_progress_page_show_grades(self, response, show_correctness, due_date, graded, show_grades, score, max_score, avg): # lint-amnesty, pylint: disable=unused-argument diff --git a/lms/djangoapps/courseware/tests/tests.py b/lms/djangoapps/courseware/tests/tests.py index c815f7eadba9..5a210c6eeb98 100644 --- a/lms/djangoapps/courseware/tests/tests.py +++ b/lms/djangoapps/courseware/tests/tests.py @@ -95,7 +95,7 @@ def _assert_loads(self, django_url, kwargs, descriptor, Assert that the url loads correctly. If expect_redirect, then also check that we were redirected. If check_content, then check that we don't get - an error message about unavailable modules. + an error message about unavailable blocks. """ url = reverse(django_url, kwargs=kwargs) diff --git a/lms/djangoapps/courseware/views/index.py b/lms/djangoapps/courseware/views/index.py index 59a65255deca..adafa4003a0d 100644 --- a/lms/djangoapps/courseware/views/index.py +++ b/lms/djangoapps/courseware/views/index.py @@ -61,7 +61,7 @@ ) from ..masquerade import check_content_start_date_for_masquerade_user, setup_masquerade from ..model_data import FieldDataCache -from ..module_render import get_module_for_descriptor, toc_for_course +from ..block_render import get_block_for_descriptor, toc_for_course from ..permissions import MASQUERADE_AS_STUDENT from ..toggles import ENABLE_OPTIMIZELY_IN_COURSEWARE, courseware_mfe_is_active from .views import CourseTabView @@ -103,7 +103,7 @@ def get(self, request, course_id, chapter=None, section=None, position=None): course_id (unicode): course id chapter (unicode): chapter url_name section (unicode): section url_name - position (unicode): position in module, eg of module + position (unicode): position in block, eg of block """ self.course_key = CourseKey.from_string(course_id) @@ -357,7 +357,7 @@ def _prefetch_and_bind_course(self, request): read_only=CrawlersConfig.is_crawler(request), ) - self.course = get_module_for_descriptor( + self.course = get_block_for_descriptor( self.effective_user, self.request, self.course, @@ -377,7 +377,7 @@ def _prefetch_and_bind_section(self): self.field_data_cache.add_descriptor_descendents(self.section, depth=None) # Bind section to user - self.section = get_module_for_descriptor( + self.section = get_block_for_descriptor( self.effective_user, self.request, self.section, @@ -579,23 +579,23 @@ def save_positions_recursively_up(user, request, field_data_cache, xmodule, cour Recurses up the course tree starting from a leaf Saving the position property based on the previous node as it goes """ - current_module = xmodule + current_block = xmodule - while current_module: - parent_location = modulestore().get_parent_location(current_module.location) + while current_block: + parent_location = modulestore().get_parent_location(current_block.location) parent = None if parent_location: parent_descriptor = modulestore().get_item(parent_location) - parent = get_module_for_descriptor( + parent = get_block_for_descriptor( user, request, parent_descriptor, field_data_cache, - current_module.location.course_key, + current_block.location.course_key, course=course ) if parent and hasattr(parent, 'position'): - save_child_position(parent, current_module.location.block_id) + save_child_position(parent, current_block.location.block_id) - current_module = parent + current_block = parent diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index fa7a88d11818..dee8c854a640 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -129,7 +129,7 @@ from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML from openedx.features.enterprise_support.api import data_sharing_consent_required -from ..module_render import get_module, get_module_by_usage_id, get_module_for_descriptor +from ..block_render import get_block, get_block_by_usage_id, get_block_for_descriptor from ..tabs import _get_dynamic_tabs from ..toggles import COURSEWARE_OPTIMIZED_RENDER_XBLOCK @@ -1258,16 +1258,16 @@ def get_static_tab_fragment(request, course, tab): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, modulestore().get_item(loc), depth=0 ) - tab_module = get_module( + tab_block = get_block( request.user, request, loc, field_data_cache, static_asset_path=course.static_asset_path, course=course ) - logging.debug('course_block = %s', tab_module) + logging.debug('course_block = %s', tab_block) fragment = Fragment() - if tab_module is not None: + if tab_block is not None: try: - fragment = tab_module.render(STUDENT_VIEW, {}) + fragment = tab_block.render(STUDENT_VIEW, {}) except Exception: # pylint: disable=broad-except fragment.content = render_to_string('courseware/error-message.html', None) log.exception( @@ -1301,12 +1301,12 @@ def get_course_lti_endpoints(request, course_id): return HttpResponse(status=404) anonymous_user = AnonymousUser() - anonymous_user.known = False # make these "noauth" requests like module_render.handle_xblock_callback_noauth + anonymous_user.known = False # make these "noauth" requests like block_render.handle_xblock_callback_noauth lti_descriptors = modulestore().get_items(course.id, qualifiers={'category': 'lti'}) lti_descriptors.extend(modulestore().get_items(course.id, qualifiers={'category': 'lti_consumer'})) - lti_noauth_modules = [ - get_module_for_descriptor( + lti_noauth_blocks = [ + get_block_for_descriptor( anonymous_user, request, descriptor, @@ -1323,13 +1323,13 @@ def get_course_lti_endpoints(request, course_id): endpoints = [ { - 'display_name': module.display_name, - 'lti_2_0_result_service_json_endpoint': module.get_outcome_service_url( + 'display_name': block.display_name, + 'lti_2_0_result_service_json_endpoint': block.get_outcome_service_url( service_name='lti_2_0_result_rest_handler') + "/user/{anon_user_id}", - 'lti_1_1_result_service_xml_endpoint': module.get_outcome_service_url( + 'lti_1_1_result_service_xml_endpoint': block.get_outcome_service_url( service_name='grade_handler'), } - for module in lti_noauth_modules + for block in lti_noauth_blocks ] return HttpResponse(json.dumps(endpoints), content_type='application/json') # lint-amnesty, pylint: disable=http-response-with-content-type-json, http-response-with-json-dumps @@ -1539,7 +1539,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True): # get the block, which verifies whether the user has access to the block. recheck_access = request.GET.get('recheck_access') == '1' - block, _ = get_module_by_usage_id( + block, _ = get_block_by_usage_id( request, str(course_key), str(usage_key), disable_staff_debug_info=True, course=course, will_recheck_access=recheck_access ) @@ -1635,7 +1635,7 @@ def render_public_video_xblock(request, usage_key_string): with modulestore().bulk_operations(course_key): course = get_course_by_id(course_key, 0) - block, _ = get_module_by_usage_id( + block, _ = get_block_by_usage_id( request, str(course_key), str(usage_key), diff --git a/lms/djangoapps/discussion/django_comment_client/base/tests.py b/lms/djangoapps/discussion/django_comment_client/base/tests.py index ecff54355e33..01de4f754deb 100644 --- a/lms/djangoapps/discussion/django_comment_client/base/tests.py +++ b/lms/djangoapps/discussion/django_comment_client/base/tests.py @@ -209,9 +209,9 @@ def test_openclose(self, mock_request): class ViewsTestCaseMixin: - def set_up_course(self, module_count=0): + def set_up_course(self, block_count=0): """ - Creates a course, optionally with module_count discussion modules, and + Creates a course, optionally with block_count discussion blocks, and a user with appropriate permissions. """ @@ -223,8 +223,8 @@ def set_up_course(self, module_count=0): ) self.course_id = self.course.id - # add some discussion modules - for i in range(module_count): + # add some discussion blocks + for i in range(block_count): BlockFactory.create( parent_location=self.course.location, category='discussion', @@ -396,9 +396,9 @@ def count_queries(func): # pylint: disable=no-self-argument Decorates test methods to count mongo and SQL calls for a particular modulestore. """ - def inner(self, default_store, module_count, mongo_calls, sql_queries, *args, **kwargs): + def inner(self, default_store, block_count, mongo_calls, sql_queries, *args, **kwargs): with modulestore().default_store(default_store): - self.set_up_course(module_count=module_count) + self.set_up_course(block_count=block_count) self.clear_caches() with self.assertNumQueries(sql_queries, table_ignorelist=QUERY_COUNT_TABLE_IGNORELIST): with check_mongo_calls(mongo_calls): diff --git a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py index 928d82d22a36..c93c63ded1ff 100644 --- a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py +++ b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py @@ -177,7 +177,7 @@ def assertThreadCorrect(thread, discussion, expected_title): # pylint: disable= def test_empty_discussion_subcategory_title(self): """ - Test that for empty subcategory inline discussion modules, + Test that for empty subcategory inline discussion blocks, the divider " / " is not rendered on a post or inline discussion topic label. """ discussion = BlockFactory.create( diff --git a/lms/djangoapps/discussion/rest_api/tests/test_api.py b/lms/djangoapps/discussion/rest_api/tests/test_api.py index ab2b72214f13..be0baf23d58a 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_api.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_api.py @@ -505,8 +505,8 @@ def test_access_control(self): Test that only topics that a user has access to are returned. The ways in which a user may not have access are: - * Module is visible to staff only - * Module is accessible only to a group the user is not in + * Block is visible to staff only + * Block is accessible only to a group the user is not in Also, there is a case that ensures that a category with no accessible subcategories does not appear in the result. diff --git a/lms/djangoapps/discussion/rest_api/tests/test_views.py b/lms/djangoapps/discussion/rest_api/tests/test_views.py index ade937a51e17..e66b386be7b9 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_views.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_views.py @@ -730,7 +730,7 @@ def setUp(self): } self.register_get_course_commentable_counts_response(self.course.id, self.thread_counts_map) - def create_course(self, modules_count, module_store, topics): + def create_course(self, blocks_count, module_store, topics): """ Create a course in a specified module store with discussion xblocks and topics """ @@ -745,7 +745,7 @@ def create_course(self, modules_count, module_store, topics): CourseEnrollmentFactory.create(user=self.user, course_id=course.id) course_url = reverse("course_topics", kwargs={"course_id": str(course.id)}) # add some discussion xblocks - for i in range(modules_count): + for i in range(blocks_count): BlockFactory.create( parent_location=course.location, category='discussion', @@ -804,8 +804,8 @@ def test_basic(self): (10, ModuleStoreEnum.Type.split, 2, {"Test Topic 1": {"id": "test_topic_1"}}), ) @ddt.unpack - def test_bulk_response(self, modules_count, module_store, mongo_calls, topics): - course_url, course_id = self.create_course(modules_count, module_store, topics) + def test_bulk_response(self, blocks_count, module_store, mongo_calls, topics): + course_url, course_id = self.create_course(blocks_count, module_store, topics) self.register_get_course_commentable_counts_response(course_id, {}) with check_mongo_calls(mongo_calls): with modulestore().default_store(module_store): diff --git a/lms/djangoapps/discussion/tests/test_views.py b/lms/djangoapps/discussion/tests/test_views.py index ffb6c5855a36..6b7f2de3ee5f 100644 --- a/lms/djangoapps/discussion/tests/test_views.py +++ b/lms/djangoapps/discussion/tests/test_views.py @@ -793,9 +793,9 @@ def test_group_info_in_ajax_response(self, mock_request): class ForumFormDiscussionContentGroupTestCase(ForumsEnableMixin, ContentGroupTestCase): """ Tests `forum_form_discussion api` works with different content groups. - Discussion modules are setup in ContentGroupTestCase class i.e - alpha_module => alpha_group_discussion => alpha_cohort => alpha_user/community_ta - beta_module => beta_group_discussion => beta_cohort => beta_user + Discussion blocks are setup in ContentGroupTestCase class i.e + alpha_block => alpha_group_discussion => alpha_cohort => alpha_user/community_ta + beta_block => beta_group_discussion => beta_cohort => beta_user """ @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) @@ -803,17 +803,17 @@ def setUp(self): super().setUp() self.thread_list = [ {"thread_id": "test_general_thread_id"}, - {"thread_id": "test_global_group_thread_id", "commentable_id": self.global_module.discussion_id}, - {"thread_id": "test_alpha_group_thread_id", "group_id": self.alpha_module.group_access[0][0], - "commentable_id": self.alpha_module.discussion_id}, - {"thread_id": "test_beta_group_thread_id", "group_id": self.beta_module.group_access[0][0], - "commentable_id": self.beta_module.discussion_id} + {"thread_id": "test_global_group_thread_id", "commentable_id": self.global_block.discussion_id}, + {"thread_id": "test_alpha_group_thread_id", "group_id": self.alpha_block.group_access[0][0], + "commentable_id": self.alpha_block.discussion_id}, + {"thread_id": "test_beta_group_thread_id", "group_id": self.beta_block.group_access[0][0], + "commentable_id": self.beta_block.discussion_id} ] def assert_has_access(self, response, expected_discussion_threads): """ Verify that a users have access to the threads in their assigned - cohorts and non-cohorted modules. + cohorts and non-cohorted blocks. """ discussion_data = json.loads(response.content.decode('utf-8'))['discussion_data'] assert len(discussion_data) == expected_discussion_threads @@ -902,53 +902,53 @@ def call_single_thread(): def test_staff_user(self, mock_request): """ Verify that the staff user can access threads in the alpha, - beta, and global discussion modules. + beta, and global discussion blocks. """ thread_id = "test_thread_id" mock_request.side_effect = make_mock_request_impl(course=self.course, text="dummy content", thread_id=thread_id) - for discussion_xblock in [self.alpha_module, self.beta_module, self.global_module]: + for discussion_xblock in [self.alpha_block, self.beta_block, self.global_block]: self.assert_can_access(self.staff_user, discussion_xblock.discussion_id, thread_id, True) def test_alpha_user(self, mock_request): """ Verify that the alpha user can access threads in the alpha and - global discussion modules. + global discussion blocks. """ thread_id = "test_thread_id" mock_request.side_effect = make_mock_request_impl(course=self.course, text="dummy content", thread_id=thread_id) - for discussion_xblock in [self.alpha_module, self.global_module]: + for discussion_xblock in [self.alpha_block, self.global_block]: self.assert_can_access(self.alpha_user, discussion_xblock.discussion_id, thread_id, True) - self.assert_can_access(self.alpha_user, self.beta_module.discussion_id, thread_id, False) + self.assert_can_access(self.alpha_user, self.beta_block.discussion_id, thread_id, False) def test_beta_user(self, mock_request): """ Verify that the beta user can access threads in the beta and - global discussion modules. + global discussion blocks. """ thread_id = "test_thread_id" mock_request.side_effect = make_mock_request_impl(course=self.course, text="dummy content", thread_id=thread_id) - for discussion_xblock in [self.beta_module, self.global_module]: + for discussion_xblock in [self.beta_block, self.global_block]: self.assert_can_access(self.beta_user, discussion_xblock.discussion_id, thread_id, True) - self.assert_can_access(self.beta_user, self.alpha_module.discussion_id, thread_id, False) + self.assert_can_access(self.beta_user, self.alpha_block.discussion_id, thread_id, False) def test_non_cohorted_user(self, mock_request): """ Verify that the non-cohorted user can access threads in just the - global discussion module. + global discussion blocks. """ thread_id = "test_thread_id" mock_request.side_effect = make_mock_request_impl(course=self.course, text="dummy content", thread_id=thread_id) - self.assert_can_access(self.non_cohorted_user, self.global_module.discussion_id, thread_id, True) + self.assert_can_access(self.non_cohorted_user, self.global_block.discussion_id, thread_id, True) - self.assert_can_access(self.non_cohorted_user, self.alpha_module.discussion_id, thread_id, False) + self.assert_can_access(self.non_cohorted_user, self.alpha_block.discussion_id, thread_id, False) - self.assert_can_access(self.non_cohorted_user, self.beta_module.discussion_id, thread_id, False) + self.assert_can_access(self.non_cohorted_user, self.beta_block.discussion_id, thread_id, False) def test_course_context_respected(self, mock_request): """ @@ -959,30 +959,30 @@ def test_course_context_respected(self, mock_request): course=self.course, text="dummy content", thread_id=thread_id ) - # Beta user does not have access to alpha_module. - self.assert_can_access(self.beta_user, self.alpha_module.discussion_id, thread_id, False) + # Beta user does not have access to alpha_block. + self.assert_can_access(self.beta_user, self.alpha_block.discussion_id, thread_id, False) def test_standalone_context_respected(self, mock_request): """ Verify that standalone threads don't go through discussion_category_id_access method. """ - # For this rather pathological test, we are assigning the alpha module discussion_id (commentable_id) + # For this rather pathological test, we are assigning the alpha block discussion_id (commentable_id) # to a team so that we can verify that standalone threads don't go through discussion_category_id_access. thread_id = "test_thread_id" CourseTeamFactory( name="A team", course_id=self.course.id, topic_id='topic_id', - discussion_topic_id=self.alpha_module.discussion_id + discussion_topic_id=self.alpha_block.discussion_id ) mock_request.side_effect = make_mock_request_impl( course=self.course, text="dummy content", thread_id=thread_id, - commentable_id=self.alpha_module.discussion_id + commentable_id=self.alpha_block.discussion_id ) # If a thread returns context other than "course", the access check is not done, and the beta user - # can see the alpha discussion module. - self.assert_can_access(self.beta_user, self.alpha_module.discussion_id, thread_id, True) + # can see the alpha discussion block. + self.assert_can_access(self.beta_user, self.alpha_block.discussion_id, thread_id, True) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) diff --git a/lms/djangoapps/discussion/views.py b/lms/djangoapps/discussion/views.py index a9ad7dce839b..74a365bcdf8e 100644 --- a/lms/djangoapps/discussion/views.py +++ b/lms/djangoapps/discussion/views.py @@ -421,7 +421,7 @@ def _find_thread(request, course, discussion_id, thread_id): ) except cc.utils.CommentClientRequestError: return None - # Verify that the student has access to this thread if belongs to a course discussion module + # Verify that the student has access to this thread if belongs to a course discussion block thread_context = getattr(thread, "context", "course") if thread_context == "course" and not utils.discussion_category_id_access(course, request.user, discussion_id): return None diff --git a/lms/djangoapps/edxnotes/helpers.py b/lms/djangoapps/edxnotes/helpers.py index 9fe74619d71f..d8e743536d14 100644 --- a/lms/djangoapps/edxnotes/helpers.py +++ b/lms/djangoapps/edxnotes/helpers.py @@ -157,7 +157,7 @@ def preprocess_collection(user, course, collection): convert "updated" to date Raises: - ItemNotFoundError - when appropriate module is not found. + ItemNotFoundError - when appropriate block is not found. """ # pylint: disable=too-many-statements @@ -185,7 +185,7 @@ def preprocess_collection(user, course, collection): try: item = store.get_item(usage_key) except ItemNotFoundError: - log.debug("Module not found: %s", usage_key) + log.debug("Block not found: %s", usage_key) continue if not has_access(user, "load", item, course_key=course.id): @@ -205,7 +205,7 @@ def preprocess_collection(user, course, collection): if section.location in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary usage_context = cache[section.location] usage_context.update({ - "unit": get_module_context(course, unit), + "unit": get_block_context(course, unit), }) model.update(usage_context) cache[usage_id] = cache[unit.location] = usage_context @@ -219,8 +219,8 @@ def preprocess_collection(user, course, collection): if chapter.location in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary usage_context = cache[chapter.location] usage_context.update({ - "unit": get_module_context(course, unit), - "section": get_module_context(course, section), + "unit": get_block_context(course, unit), + "section": get_block_context(course, section), }) model.update(usage_context) cache[usage_id] = cache[unit.location] = cache[section.location] = usage_context @@ -228,9 +228,9 @@ def preprocess_collection(user, course, collection): continue usage_context = { - "unit": get_module_context(course, unit), - "section": get_module_context(course, section) if include_path_info else {}, - "chapter": get_module_context(course, chapter) if include_path_info else {}, + "unit": get_block_context(course, unit), + "section": get_block_context(course, section) if include_path_info else {}, + "chapter": get_block_context(course, chapter) if include_path_info else {}, } model.update(usage_context) if include_path_info: @@ -242,34 +242,34 @@ def preprocess_collection(user, course, collection): return filtered_collection -def get_module_context(course, item): +def get_block_context(course, block): """ - Returns dispay_name and url for the parent module. + Returns dispay_name and url for the parent block. """ - item_dict = { - 'location': str(item.location), - 'display_name': Text(item.display_name_with_default), + block_dict = { + 'location': str(block.location), + 'display_name': Text(block.display_name_with_default), } - if item.category == 'chapter' and item.get_parent(): + if block.category == 'chapter' and block.get_parent(): # course is a locator w/o branch and version # so for uniformity we replace it with one that has them - course = item.get_parent() - item_dict['index'] = get_index(item_dict['location'], course.children) - elif item.category == 'vertical': - section = item.get_parent() + course = block.get_parent() + block_dict['index'] = get_index(block_dict['location'], course.children) + elif block.category == 'vertical': + section = block.get_parent() chapter = section.get_parent() # Position starts from 1, that's why we add 1. - position = get_index(str(item.location), section.children) + 1 - item_dict['url'] = reverse('courseware_position', kwargs={ + position = get_index(str(block.location), section.children) + 1 + block_dict['url'] = reverse('courseware_position', kwargs={ 'course_id': str(course.id), 'chapter': chapter.url_name, 'section': section.url_name, 'position': position, }) - if item.category in ('chapter', 'sequential'): - item_dict['children'] = [str(child) for child in item.children] + if block.category in ('chapter', 'sequential'): + block_dict['children'] = [str(child) for child in block.children] - return item_dict + return block_dict def get_index(usage_key, children): diff --git a/lms/djangoapps/edxnotes/tests.py b/lms/djangoapps/edxnotes/tests.py index a0f90f7ea026..fe138810a06a 100644 --- a/lms/djangoapps/edxnotes/tests.py +++ b/lms/djangoapps/edxnotes/tests.py @@ -23,7 +23,7 @@ from common.djangoapps.edxmako.shortcuts import render_to_string from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, SuperuserFactory, UserFactory from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from lms.djangoapps.courseware.tabs import get_course_tab_list from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory @@ -88,7 +88,7 @@ def __init__(self, course, user=None): def get_html(self): """ - Imitate get_html in module. + Imitate get_html in block. """ return "original_get_html" @@ -547,7 +547,7 @@ def test_delete_all_notes_for_user(self, mock_post, mock_get_id_token, mock_anon def test_preprocess_collection_no_item(self): """ - Tests the result if appropriate module is not found. + Tests the result if appropriate block is not found. """ initial_collection = [ { @@ -590,7 +590,7 @@ def test_preprocess_collection_no_item(self): def test_preprocess_collection_has_access(self): """ - Tests the result if the user does not have access to some of the modules. + Tests the result if the user does not have access to some of the blocks. """ initial_collection = [ { @@ -702,9 +702,9 @@ def test_preprocess_collection_with_disabled_tabs(self, ): } ]) == len(helpers.preprocess_collection(self.user, self.course, initial_collection)) - def test_get_module_context_sequential(self): + def test_get_block_context_sequential(self): """ - Tests `get_module_context` method for the sequential. + Tests `get_block_context` method for the sequential. """ self.assertDictEqual( { @@ -712,24 +712,24 @@ def test_get_module_context_sequential(self): "location": str(self.sequential.location), "children": [str(self.vertical.location), str(self.vertical_with_container.location)], }, - helpers.get_module_context(self.course, self.sequential) + helpers.get_block_context(self.course, self.sequential) ) - def test_get_module_context_html_component(self): + def test_get_block_context_html_component(self): """ - Tests `get_module_context` method for the components. + Tests `get_block_context` method for the components. """ self.assertDictEqual( { "display_name": self.html_block_1.display_name_with_default, "location": str(self.html_block_1.location), }, - helpers.get_module_context(self.course, self.html_block_1) + helpers.get_block_context(self.course, self.html_block_1) ) - def test_get_module_context_chapter(self): + def test_get_block_context_chapter(self): """ - Tests `get_module_context` method for the chapters. + Tests `get_block_context` method for the chapters. """ self.assertDictEqual( { @@ -738,7 +738,7 @@ def test_get_module_context_chapter(self): "location": str(self.chapter.location), "children": [str(self.sequential.location)], }, - helpers.get_module_context(self.course, self.chapter) + helpers.get_block_context(self.course, self.chapter) ) self.assertDictEqual( { @@ -747,7 +747,7 @@ def test_get_module_context_chapter(self): "location": str(self.chapter_2.location), "children": [], }, - helpers.get_module_context(self.course, self.chapter_2) + helpers.get_block_context(self.course, self.chapter_2) ) @override_settings(EDXNOTES_PUBLIC_API="http://example.com") @@ -962,7 +962,7 @@ def _get_course_block(self): Returns the course block. """ field_data_cache = FieldDataCache([self.course], self.course.id, self.user) # lint-amnesty, pylint: disable=no-member - return get_module_for_descriptor( + return get_block_for_descriptor( self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course # lint-amnesty, pylint: disable=no-member ) diff --git a/lms/djangoapps/edxnotes/views.py b/lms/djangoapps/edxnotes/views.py index 7f524fb99300..04c50da08d1e 100644 --- a/lms/djangoapps/edxnotes/views.py +++ b/lms/djangoapps/edxnotes/views.py @@ -21,7 +21,7 @@ from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest from lms.djangoapps.courseware.courses import get_course_with_access from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from lms.djangoapps.edxnotes.exceptions import EdxNotesParseError, EdxNotesServiceUnavailable from lms.djangoapps.edxnotes.helpers import ( DEFAULT_PAGE, @@ -74,7 +74,7 @@ def edxnotes(request, course_id): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2 ) - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( request.user, request, course, field_data_cache, course_key, course=course ) position = get_course_position(course_block) @@ -195,7 +195,7 @@ def edxnotes_visibility(request, course_id): course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) field_data_cache = FieldDataCache([course], course_key, request.user) - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( request.user, request, course, field_data_cache, course_key, course=course ) diff --git a/lms/djangoapps/grades/course_grade.py b/lms/djangoapps/grades/course_grade.py index fa1288547b92..f5639873a809 100644 --- a/lms/djangoapps/grades/course_grade.py +++ b/lms/djangoapps/grades/course_grade.py @@ -158,13 +158,13 @@ def chapter_percentage(self, chapter_key): possible += section.graded_total.possible return compute_percent(earned, possible) - def score_for_module(self, location): + def score_for_block(self, location): """ Calculate the aggregate weighted score for any location in the course. This method returns a tuple containing (earned_score, possible_score). If the location is of 'problem' type, this method will return the possible and earned scores for that problem. If the location refers to a - composite module (a vertical or section ) the scores will be the sums of + composite block (a vertical or section ) the scores will be the sums of all scored problems that are children of the chosen location. """ if location in self.problem_scores: @@ -173,7 +173,7 @@ def score_for_module(self, location): children = self.course_data.structure.get_children(location) earned, possible = 0.0, 0.0 for child in children: - child_earned, child_possible = self.score_for_module(child) + child_earned, child_possible = self.score_for_block(child) earned += child_earned possible += child_possible return earned, possible diff --git a/lms/djangoapps/grades/docs/background.rst b/lms/djangoapps/grades/docs/background.rst index ebe76ca8c894..ef101455380e 100644 --- a/lms/djangoapps/grades/docs/background.rst +++ b/lms/djangoapps/grades/docs/background.rst @@ -15,7 +15,7 @@ Terminology +-------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Term | Definition | +-------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Raw Score | Unweighted (earned, possible) points tuple. For a CapaModule (our most common problem type), each response entry is a point. So a single CapaModule problem with two multiple choice responses has a possible raw score of 2. | +| Raw Score | Unweighted (earned, possible) points tuple. For a CapaBlock (our most common problem type), each response entry is a point. So a single CapaBlock problem with two multiple choice responses has a possible raw score of 2. | +-------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Weighted Score | The result of applying the weight settings-scoped XBlock attribute to the raw score. The weight is an indication of how much the total problem should be worth, so the weighted score tuple looks like ((earned / possible) * weight, weight). So if someone has a raw score of 1/2 and the problem weight is 10, then 5/10 is what will show up on the progress page as the weighted score. Problem weights are attributes that are placed on the XBlock/XModuleDescriptor and can be manipulated via Studio. | +-------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/lms/djangoapps/grades/tests/test_course_grade.py b/lms/djangoapps/grades/tests/test_course_grade.py index 8ac66aad28ab..a4afd554facb 100644 --- a/lms/djangoapps/grades/tests/test_course_grade.py +++ b/lms/djangoapps/grades/tests/test_course_grade.py @@ -106,46 +106,46 @@ def tearDownClass(cls): set_current_request(None) def test_score_chapter(self): - earned, possible = self.course_grade.score_for_module(self.a.location) + earned, possible = self.course_grade.score_for_block(self.a.location) assert earned == 9 assert possible == 24 def test_score_section_many_leaves(self): - earned, possible = self.course_grade.score_for_module(self.b.location) + earned, possible = self.course_grade.score_for_block(self.b.location) assert earned == 6 assert possible == 14 def test_score_section_one_leaf(self): - earned, possible = self.course_grade.score_for_module(self.c.location) + earned, possible = self.course_grade.score_for_block(self.c.location) assert earned == 3 assert possible == 10 def test_score_vertical_two_leaves(self): - earned, possible = self.course_grade.score_for_module(self.d.location) + earned, possible = self.course_grade.score_for_block(self.d.location) assert earned == 5 assert possible == 10 def test_score_vertical_two_leaves_one_unscored(self): - earned, possible = self.course_grade.score_for_module(self.e.location) + earned, possible = self.course_grade.score_for_block(self.e.location) assert earned == 1 assert possible == 4 def test_score_vertical_no_score(self): - earned, possible = self.course_grade.score_for_module(self.f.location) + earned, possible = self.course_grade.score_for_block(self.f.location) assert earned == 0 assert possible == 0 def test_score_vertical_one_leaf(self): - earned, possible = self.course_grade.score_for_module(self.g.location) + earned, possible = self.course_grade.score_for_block(self.g.location) assert earned == 3 assert possible == 10 def test_score_leaf(self): - earned, possible = self.course_grade.score_for_module(self.h.location) + earned, possible = self.course_grade.score_for_block(self.h.location) assert earned == 2 assert possible == 5 def test_score_leaf_no_score(self): - earned, possible = self.course_grade.score_for_module(self.m.location) + earned, possible = self.course_grade.score_for_block(self.m.location) assert earned == 0 assert possible == 0 diff --git a/lms/djangoapps/grades/tests/utils.py b/lms/djangoapps/grades/tests/utils.py index 82edebbc3129..dffe80c3dd63 100644 --- a/lms/djangoapps/grades/tests/utils.py +++ b/lms/djangoapps/grades/tests/utils.py @@ -10,7 +10,7 @@ import pytz from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module +from lms.djangoapps.courseware.block_render import get_block from xmodule.graders import ProblemScore # lint-amnesty, pylint: disable=wrong-import-order @@ -79,10 +79,10 @@ def answer_problem(course, request, problem, score=1, max_value=1): course, depth=2 ) - module = get_module( + block = get_block( user, request, problem.scope_ids.usage_id, field_data_cache, ) - module.system.publish(problem, 'grade', grade_dict) + block.runtime.publish(problem, 'grade', grade_dict) diff --git a/lms/djangoapps/grades/transformer.py b/lms/djangoapps/grades/transformer.py index bfa90ca80405..38fe903ba7d9 100644 --- a/lms/djangoapps/grades/transformer.py +++ b/lms/djangoapps/grades/transformer.py @@ -144,15 +144,15 @@ def _collect_max_scores(cls, block_structure): cls._collect_max_score(block_structure, block) @classmethod - def _collect_max_score(cls, block_structure, module): + def _collect_max_score(cls, block_structure, block): """ - Collect the `max_score` from the given module, storing it as a + Collect the `max_score` from the given block, storing it as a `transformer_block_field` associated with the `GradesTransformer`. """ - max_score = module.max_score() - block_structure.set_transformer_block_field(module.location, cls, 'max_score', max_score) + max_score = block.max_score() + block_structure.set_transformer_block_field(block.location, cls, 'max_score', max_score) if max_score is None: - log.warning(f"GradesTransformer: max_score is None for {module.location}") + log.warning(f"GradesTransformer: max_score is None for {block.location}") @classmethod def _collect_grading_policy_hash(cls, block_structure): @@ -168,18 +168,3 @@ def _collect_grading_policy_hash(cls, block_structure): "grading_policy_hash", cls.grading_policy_hash(course_block), ) - - @staticmethod - def _iter_scorable_xmodules(block_structure): - """ - Loop through all the blocks locators in the block structure, and - retrieve the module (XModule or XBlock) associated with that locator. - - For implementation reasons, we need to pull the max_score from the - XModule, even though the data is not user specific. Here we bind the - data to a SystemUser. - """ - for block_locator in block_structure.post_order_traversal(): - block = block_structure.get_xblock(block_locator) - if getattr(block, 'has_score', False): - yield block diff --git a/lms/djangoapps/instructor/tasks.py b/lms/djangoapps/instructor/tasks.py index 5e29dc608a0d..11f3deafd976 100644 --- a/lms/djangoapps/instructor/tasks.py +++ b/lms/djangoapps/instructor/tasks.py @@ -12,7 +12,7 @@ from common.djangoapps.student.models import get_user_by_username_or_email from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from openedx.core.lib.request_utils import get_request_or_stub from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order @@ -71,11 +71,11 @@ def update_exam_completion_task(user_identifier: str, content_id: str, completio field_data_cache = FieldDataCache.cache_for_descriptor_descendents( root_descriptor.scope_ids.usage_id.context_key, user, root_descriptor, read_only=True, ) - root_module = get_module_for_descriptor( + root_block = get_block_for_descriptor( user, request, root_descriptor, field_data_cache, root_descriptor.scope_ids.usage_id.context_key, ) - if not root_module: - err_msg = err_msg_prefix + 'Module unable to be created from descriptor!' + if not root_block: + err_msg = err_msg_prefix + 'Block unable to be created from descriptor!' log.error(err_msg) return @@ -99,4 +99,4 @@ def _submit_completions(block, user, completion): for child in block_children: _submit_completions(child, user, completion) - _submit_completions(root_module, user, completion) + _submit_completions(root_block, user, completion) diff --git a/lms/djangoapps/instructor/tests/test_services.py b/lms/djangoapps/instructor/tests/test_services.py index e16df1678f6e..488c0d43a600 100644 --- a/lms/djangoapps/instructor/tests/test_services.py +++ b/lms/djangoapps/instructor/tests/test_services.py @@ -233,14 +233,14 @@ def test_complete_student_attempt_nonexisting_item(self, mock_logger): @mock.patch('lms.djangoapps.instructor.tasks.log.error') def test_complete_student_attempt_failed_module(self, mock_logger): """ - Assert complete_student_attempt with failed get_module raises error and returns None + Assert complete_student_attempt with failed get_block raises error and returns None """ username = self.student.username - with mock.patch('lms.djangoapps.instructor.tasks.get_module_for_descriptor', return_value=None): + with mock.patch('lms.djangoapps.instructor.tasks.get_block_for_descriptor', return_value=None): self.service.complete_student_attempt(username, str(self.course.location)) mock_logger.assert_called_once_with( self.complete_error_prefix.format(user=username, content_id=self.course.location) + - 'Module unable to be created from descriptor!' + 'Block unable to be created from descriptor!' ) def test_is_user_staff(self): diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py index f853c2c05fc3..26f1ccd1f306 100644 --- a/lms/djangoapps/instructor/tests/test_tools.py +++ b/lms/djangoapps/instructor/tests/test_tools.py @@ -357,7 +357,7 @@ def test_dump_module_extensions(self): extended) tools.set_due_date_extension(self.course, self.week1, self.user2, extended) - report = tools.dump_module_extensions(self.course, self.week1) + report = tools.dump_block_extensions(self.course, self.week1) assert ( report['title'] == 'Users with due date extensions for ' + self.week1.display_name) diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py deleted file mode 100644 index 54dd8e848b26..000000000000 --- a/lms/djangoapps/instructor/utils.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -Helpers for instructor app. -""" - - -from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module -from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order - - -class DummyRequest: - """Dummy request""" - - META = {} - - def __init__(self): # lint-amnesty, pylint: disable=useless-return - self.session = {} - self.user = None - return - - def get_host(self): - """Return a default host.""" - return 'edx.mit.edu' - - def is_secure(self): - """Always insecure.""" - return False - - -def get_module_for_student(student, usage_key, request=None, course=None): - """Return the module for the (student, location) using a DummyRequest.""" - if request is None: - request = DummyRequest() - request.user = student - - descriptor = modulestore().get_item(usage_key, depth=0) - field_data_cache = FieldDataCache([descriptor], usage_key.course_key, student) - return get_module(student, request, usage_key, field_data_cache, course=course) diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index 8388fffb4fcf..eb0d6aa8a5a7 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -124,7 +124,7 @@ from openedx.core.lib.courses import get_course_by_id from openedx.features.course_experience.url_helpers import get_learning_mfe_home_url from .tools import ( - dump_module_extensions, + dump_block_extensions, dump_student_extensions, find_unit, get_student_from_identifier, @@ -2915,7 +2915,7 @@ def show_unit_extensions(request, course_id): """ course = get_course_by_id(CourseKey.from_string(course_id)) unit = find_unit(course, request.POST.get('url')) - return JsonResponse(dump_module_extensions(course, unit)) + return JsonResponse(dump_block_extensions(course, unit)) @handle_dashboard_error diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py index 7896bee18e28..579b8d035f90 100644 --- a/lms/djangoapps/instructor/views/instructor_dashboard.py +++ b/lms/djangoapps/instructor/views/instructor_dashboard.py @@ -50,7 +50,7 @@ ) from lms.djangoapps.courseware.access import has_access from lms.djangoapps.courseware.courses import get_studio_url -from lms.djangoapps.courseware.module_render import get_module_by_usage_id +from lms.djangoapps.courseware.block_render import get_block_by_usage_id from lms.djangoapps.discussion.django_comment_client.utils import has_forum_access from lms.djangoapps.grades.api import is_writable_gradebook_enabled from lms.djangoapps.instructor.constants import INSTRUCTOR_DASHBOARD_PLUGIN_VIEW_NAME @@ -662,11 +662,11 @@ def _section_send_email(course, access): with patch.object(course.runtime, 'applicable_aside_types', null_applicable_aside_types): # This HtmlBlock is only being used to generate a nice text editor. html_block = HtmlBlock( - course.system, + course.runtime, DictFieldData({'data': ''}), ScopeIds(None, None, None, course_key.make_usage_key('html', 'fake')) ) - fragment = course.system.render(html_block, 'studio_view') + fragment = course.runtime.render(html_block, 'studio_view') fragment = wrap_xblock( 'LmsRuntime', html_block, 'studio_view', fragment, None, extra_data={"course-id": str(course_key)}, @@ -757,7 +757,7 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac }) openassessment_block = openassessment_blocks[0] - block, __ = get_module_by_usage_id( + block, __ = get_block_by_usage_id( request, str(course_key), str(openassessment_block.location), disable_staff_debug_info=True, course=course ) diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py index f6ad49dbc525..b660a544ef78 100644 --- a/lms/djangoapps/instructor/views/tools.py +++ b/lms/djangoapps/instructor/views/tools.py @@ -11,7 +11,6 @@ from django.http import HttpResponseBadRequest from django.utils.translation import gettext as _ from edx_when import api -from opaque_keys.edx.keys import UsageKey from pytz import UTC from common.djangoapps.student.models import CourseEnrollment, get_user_by_username_or_email @@ -96,9 +95,8 @@ def parse_datetime(datestr): def find_unit(course, url): """ - Finds the unit (block, module, whatever the terminology is) with the given - url in the course tree and returns the unit. Raises DashboardError if no - unit is found. + Finds the unit/block with the given url in the course tree and returns the unit. + Raises DashboardError if no unit is found. """ def find(node, url): """ @@ -215,9 +213,9 @@ def visit(node): api.get_dates_for_course(course.id, user=student, use_cached=False) -def dump_module_extensions(course, unit): +def dump_block_extensions(course, unit): """ - Dumps data about students with due date extensions for a particular module, + Dumps data about students with due date extensions for a particular block, specified by 'url', in a particular course. """ header = [_("Username"), _("Full Name"), _("Extended Due Date")] @@ -258,13 +256,3 @@ def dump_student_extensions(course, student): "title": _("Due date extensions for {0} {1} ({2})").format( student.first_name, student.last_name, student.username), "data": data} - - -def add_block_ids(payload): - """ - rather than manually parsing block_ids from module_ids on the client, pass the block_ids explicitly in the payload - """ - if 'data' in payload: - for ele in payload['data']: - if 'module_id' in ele: - ele['block_id'] = UsageKey.from_string(ele['module_id']).block_id diff --git a/lms/djangoapps/instructor_task/api_helper.py b/lms/djangoapps/instructor_task/api_helper.py index b346b9700d44..50718580ae91 100644 --- a/lms/djangoapps/instructor_task/api_helper.py +++ b/lms/djangoapps/instructor_task/api_helper.py @@ -128,9 +128,9 @@ def generate_already_running_error_message(task_type): return message -def _get_xmodule_instance_args(request, task_id): +def _get_xblock_instance_args(request, task_id): """ - Calculate parameters needed for instantiating xmodule instances. + Calculate parameters needed for instantiating xblock instances. The `request_info` will be passed to a tracking log function, to provide information about the source of the task request. @@ -143,10 +143,10 @@ def _get_xmodule_instance_args(request, task_id): 'host': request.META['SERVER_NAME'], } - xmodule_instance_args = {'request_info': request_info, - 'task_id': task_id, - } - return xmodule_instance_args + xblock_instance_args = {'request_info': request_info, + 'task_id': task_id, + } + return xblock_instance_args def _supports_rescore(descriptor): @@ -460,7 +460,7 @@ def submit_task(request, task_type, task_class, course_key, task_input, task_key # make sure all data has been committed before handing off task to celery. task_id = instructor_task.task_id - task_args = [instructor_task.id, _get_xmodule_instance_args(request, task_id)] + task_args = [instructor_task.id, _get_xblock_instance_args(request, task_id)] try: task_class.apply_async(task_args, task_id=task_id) @@ -494,7 +494,7 @@ def schedule_task(request, task_type, course_key, task_input, task_key, schedule instructor_task = InstructorTask.create(course_key, task_type, task_key, task_input, request.user) task_id = instructor_task.task_id - task_args = _get_xmodule_instance_args(request, task_id) + task_args = _get_xblock_instance_args(request, task_id) log.info(f"Creating a task schedule associated with instructor task '{instructor_task.id}' and due after " f"'{schedule}'") InstructorTaskSchedule.objects.create( diff --git a/lms/djangoapps/instructor_task/tasks.py b/lms/djangoapps/instructor_task/tasks.py index 61a933b5a65d..f142b90cc4fa 100644 --- a/lms/djangoapps/instructor_task/tasks.py +++ b/lms/djangoapps/instructor_task/tasks.py @@ -4,12 +4,12 @@ At present, these tasks all operate on StudentModule objects in one way or another, so they share a visitor architecture. Each task defines an "update function" that -takes a module_descriptor, a particular StudentModule object, and xmodule_instance_args. +takes a module_descriptor, a particular StudentModule object, and xblock_instance_args. A task may optionally specify a "filter function" that takes a query for StudentModule objects, and adds additional filter clauses. -A task also passes through "xmodule_instance_args", that are used to provide +A task also passes through "xblock_instance_args", that are used to provide information to our code that instantiates xmodule instances. The task definition then calls the traversal function, passing in the three arguments @@ -56,7 +56,7 @@ @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def rescore_problem(entry_id, xmodule_instance_args): +def rescore_problem(entry_id, xblock_instance_args): """Rescores a problem in a course, for all students or one specific student. `entry_id` is the id value of the InstructorTask entry that corresponds to this task. @@ -71,12 +71,12 @@ def rescore_problem(entry_id, xmodule_instance_args): problem submission should be rescored. If not specified, all problem submissions for the problem will be rescored. - `xmodule_instance_args` provides information needed by _get_module_instance_for_task() - to instantiate an xmodule instance. + `xblock_instance_args` provides information needed by _get_module_instance_for_task() + to instantiate an xblock instance. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('rescored') - update_fcn = partial(rescore_problem_module_state, xmodule_instance_args) + update_fcn = partial(rescore_problem_module_state, xblock_instance_args) visit_fcn = partial(perform_module_state_update, update_fcn, None) return run_main_task(entry_id, visit_fcn, action_name) @@ -84,13 +84,13 @@ def rescore_problem(entry_id, xmodule_instance_args): @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def override_problem_score(entry_id, xmodule_instance_args): +def override_problem_score(entry_id, xblock_instance_args): """ Overrides a specific learner's score on a problem. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('overridden') - update_fcn = partial(override_score_module_state, xmodule_instance_args) + update_fcn = partial(override_score_module_state, xblock_instance_args) visit_fcn = partial(perform_module_state_update, update_fcn, None) return run_main_task(entry_id, visit_fcn, action_name) @@ -98,7 +98,7 @@ def override_problem_score(entry_id, xmodule_instance_args): @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def reset_problem_attempts(entry_id, xmodule_instance_args): +def reset_problem_attempts(entry_id, xblock_instance_args): """Resets problem attempts to zero for a particular problem for all students in a course. `entry_id` is the id value of the InstructorTask entry that corresponds to this task. @@ -109,19 +109,19 @@ def reset_problem_attempts(entry_id, xmodule_instance_args): 'problem_url': the full URL to the problem to be rescored. (required) - `xmodule_instance_args` provides information needed by _get_module_instance_for_task() - to instantiate an xmodule instance. + `xblock_instance_args` provides information needed by _get_module_instance_for_task() + to instantiate an xblock instance. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('reset') - update_fcn = partial(reset_attempts_module_state, xmodule_instance_args) + update_fcn = partial(reset_attempts_module_state, xblock_instance_args) visit_fcn = partial(perform_module_state_update, update_fcn, None) return run_main_task(entry_id, visit_fcn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def delete_problem_state(entry_id, xmodule_instance_args): +def delete_problem_state(entry_id, xblock_instance_args): """Deletes problem state entirely for all students on a particular problem in a course. `entry_id` is the id value of the InstructorTask entry that corresponds to this task. @@ -132,19 +132,19 @@ def delete_problem_state(entry_id, xmodule_instance_args): 'problem_url': the full URL to the problem to be rescored. (required) - `xmodule_instance_args` provides information needed by _get_module_instance_for_task() - to instantiate an xmodule instance. + `xblock_instance_args` provides information needed by _get_module_instance_for_task() + to instantiate an xblock instance. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('deleted') - update_fcn = partial(delete_problem_module_state, xmodule_instance_args) + update_fcn = partial(delete_problem_module_state, xblock_instance_args) visit_fcn = partial(perform_module_state_update, update_fcn, None) return run_main_task(entry_id, visit_fcn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def send_bulk_course_email(entry_id, _xmodule_instance_args): +def send_bulk_course_email(entry_id, _xblock_instance_args): """Sends emails to recipients enrolled in a course. `entry_id` is the id value of the InstructorTask entry that corresponds to this task. @@ -155,8 +155,8 @@ def send_bulk_course_email(entry_id, _xmodule_instance_args): 'email_id': the full URL to the problem to be rescored. (required) - `_xmodule_instance_args` provides information needed by _get_module_instance_for_task() - to instantiate an xmodule instance. This is unused here. + `_xblock_instance_args` provides information needed by _get_module_instance_for_task() + to instantiate an xblock instance. This is unused here. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('emailed') @@ -169,20 +169,20 @@ def send_bulk_course_email(entry_id, _xmodule_instance_args): base=BaseInstructorTask, ) @set_code_owner_attribute -def calculate_problem_responses_csv(entry_id, xmodule_instance_args): +def calculate_problem_responses_csv(entry_id, xblock_instance_args): """ Compute student answers to a given problem and upload the CSV to an S3 bucket for download. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('generated') - task_fn = partial(ProblemResponses.generate, xmodule_instance_args) + task_fn = partial(ProblemResponses.generate, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def calculate_grades_csv(entry_id, xmodule_instance_args): +def calculate_grades_csv(entry_id, xblock_instance_args): """ Grade a course and push the results to an S3 bucket for download. """ @@ -190,16 +190,16 @@ def calculate_grades_csv(entry_id, xmodule_instance_args): action_name = gettext_noop('graded') TASK_LOG.info( "Task: %s, InstructorTask ID: %s, Task type: %s, Preparing for task execution", - xmodule_instance_args.get('task_id'), entry_id, action_name + xblock_instance_args.get('task_id'), entry_id, action_name ) - task_fn = partial(CourseGradeReport.generate, xmodule_instance_args) + task_fn = partial(CourseGradeReport.generate, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def calculate_problem_grade_report(entry_id, xmodule_instance_args): +def calculate_problem_grade_report(entry_id, xblock_instance_args): """ Generate a CSV for a course containing all students' problem grades and push the results to an S3 bucket for download. @@ -208,54 +208,54 @@ def calculate_problem_grade_report(entry_id, xmodule_instance_args): action_name = gettext_noop('problem distribution graded') TASK_LOG.info( "Task: %s, InstructorTask ID: %s, Task type: %s, Preparing for task execution", - xmodule_instance_args.get('task_id'), entry_id, action_name + xblock_instance_args.get('task_id'), entry_id, action_name ) - task_fn = partial(ProblemGradeReport.generate, xmodule_instance_args) + task_fn = partial(ProblemGradeReport.generate, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def calculate_students_features_csv(entry_id, xmodule_instance_args): +def calculate_students_features_csv(entry_id, xblock_instance_args): """ Compute student profile information for a course and upload the CSV to an S3 bucket for download. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('generated') - task_fn = partial(upload_students_csv, xmodule_instance_args) + task_fn = partial(upload_students_csv, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def course_survey_report_csv(entry_id, xmodule_instance_args): +def course_survey_report_csv(entry_id, xblock_instance_args): """ Compute the survey report for a course and upload the generated report to an S3 bucket for download. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('generated') - task_fn = partial(upload_course_survey_report, xmodule_instance_args) + task_fn = partial(upload_course_survey_report, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def proctored_exam_results_csv(entry_id, xmodule_instance_args): +def proctored_exam_results_csv(entry_id, xblock_instance_args): """ Compute proctored exam results report for a course and upload the CSV for download. """ action_name = 'generating_proctored_exam_results_report' - task_fn = partial(upload_proctored_exam_results_report, xmodule_instance_args) + task_fn = partial(upload_proctored_exam_results_report, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def calculate_may_enroll_csv(entry_id, xmodule_instance_args): +def calculate_may_enroll_csv(entry_id, xblock_instance_args): """ Compute information about invited students who have not enrolled in a given course yet and upload the CSV to an S3 bucket for @@ -263,13 +263,13 @@ def calculate_may_enroll_csv(entry_id, xmodule_instance_args): """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. action_name = gettext_noop('generated') - task_fn = partial(upload_may_enroll_csv, xmodule_instance_args) + task_fn = partial(upload_may_enroll_csv, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def generate_certificates(entry_id, xmodule_instance_args): +def generate_certificates(entry_id, xblock_instance_args): """ Grade students and generate certificates. """ @@ -277,68 +277,68 @@ def generate_certificates(entry_id, xmodule_instance_args): action_name = gettext_noop('certificates generated') TASK_LOG.info( "Task: %s, InstructorTask ID: %s, Task type: %s, Preparing for task execution", - xmodule_instance_args.get('task_id'), entry_id, action_name + xblock_instance_args.get('task_id'), entry_id, action_name ) - task_fn = partial(generate_students_certificates, xmodule_instance_args) + task_fn = partial(generate_students_certificates, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def cohort_students(entry_id, xmodule_instance_args): +def cohort_students(entry_id, xblock_instance_args): """ Cohort students in bulk, and upload the results. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. # An example of such a message is: "Progress: {action} {succeeded} of {attempted} so far" action_name = gettext_noop('cohorted') - task_fn = partial(cohort_students_and_upload, xmodule_instance_args) + task_fn = partial(cohort_students_and_upload, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def generate_anonymous_ids_for_course(entry_id, xmodule_instance_args): +def generate_anonymous_ids_for_course(entry_id, xblock_instance_args): """ Generate a CSV of anonymize IDs for enrolled learner for course. """ # Translators: This is a past-tense verb that is inserted into task progress messages as {action}. # An example of such a message is: "Progress: {action} {succeeded} of {attempted} so far" action_name = gettext_noop('generate_anonymized_id') - task_fn = partial(generate_anonymous_ids, xmodule_instance_args) + task_fn = partial(generate_anonymous_ids, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def export_ora2_data(entry_id, xmodule_instance_args): +def export_ora2_data(entry_id, xblock_instance_args): """ Generate a CSV of ora2 responses and push it to S3. """ action_name = gettext_noop('generated') - task_fn = partial(upload_ora2_data, xmodule_instance_args) + task_fn = partial(upload_ora2_data, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def export_ora2_submission_files(entry_id, xmodule_instance_args): +def export_ora2_submission_files(entry_id, xblock_instance_args): """ Download all submission files, generate csv downloads list, put all this into zip archive and push it to S3. """ action_name = gettext_noop('compressed') - task_fn = partial(upload_ora2_submission_files, xmodule_instance_args) + task_fn = partial(upload_ora2_submission_files, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) @shared_task(base=BaseInstructorTask) @set_code_owner_attribute -def export_ora2_summary(entry_id, xmodule_instance_args): +def export_ora2_summary(entry_id, xblock_instance_args): """ Generate a CSV of ora2/student summaries and push it to S3. """ action_name = gettext_noop('generated') - task_fn = partial(upload_ora2_summary, xmodule_instance_args) + task_fn = partial(upload_ora2_summary, xblock_instance_args) return run_main_task(entry_id, task_fn, action_name) diff --git a/lms/djangoapps/instructor_task/tasks_helper/certs.py b/lms/djangoapps/instructor_task/tasks_helper/certs.py index 28f51d06a102..8ea80cce6a9a 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/certs.py +++ b/lms/djangoapps/instructor_task/tasks_helper/certs.py @@ -26,7 +26,7 @@ def generate_students_certificates( - _xmodule_instance_args, _entry_id, course_id, task_input, action_name): + _xblock_instance_args, _entry_id, course_id, task_input, action_name): """ For a given `course_id`, generate certificates for only students present in 'students' key in task_input json column, otherwise generate certificates for all enrolled students. diff --git a/lms/djangoapps/instructor_task/tasks_helper/enrollments.py b/lms/djangoapps/instructor_task/tasks_helper/enrollments.py index ada2bd45ee3b..0309b7883af2 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/enrollments.py +++ b/lms/djangoapps/instructor_task/tasks_helper/enrollments.py @@ -18,7 +18,7 @@ FILTERED_OUT_ROLES = ['staff', 'instructor', 'finance_admin', 'sales_admin'] -def upload_may_enroll_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name): +def upload_may_enroll_csv(_xblock_instance_args, _entry_id, course_id, task_input, action_name): """ For a given `course_id`, generate a CSV file containing information about students who may enroll but have not done so @@ -50,7 +50,7 @@ def upload_may_enroll_csv(_xmodule_instance_args, _entry_id, course_id, task_inp return task_progress.update_task_state(extra_meta=current_step) -def upload_students_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name): +def upload_students_csv(_xblock_instance_args, _entry_id, course_id, task_input, action_name): """ For a given `course_id`, generate a CSV file containing profile information for all students that are enrolled, and store using a diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py index 561bc0873ec3..5358af370897 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/grades.py +++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py @@ -80,14 +80,14 @@ class _CourseGradeReportContext: boundaries. """ - def __init__(self, _xmodule_instance_args, _entry_id, course_id, _task_input, action_name): + def __init__(self, _xblock_instance_args, _entry_id, course_id, _task_input, action_name): self.task_info_string = ( 'Task: {task_id}, ' 'InstructorTask ID: {entry_id}, ' 'Course: {course_id}, ' 'Input: {task_input}' ).format( - task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None, + task_id=_xblock_instance_args.get('task_id') if _xblock_instance_args is not None else None, entry_id=_entry_id, course_id=course_id, task_input=_task_input, @@ -171,8 +171,8 @@ class _ProblemGradeReportContext: boundaries. """ - def __init__(self, _xmodule_instance_args, _entry_id, course_id, _task_input, action_name): - task_id = _xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None + def __init__(self, _xblock_instance_args, _entry_id, course_id, _task_input, action_name): + task_id = _xblock_instance_args.get('task_id') if _xblock_instance_args is not None else None self.task_info_string = ( 'Task: {task_id}, ' 'InstructorTask ID: {entry_id}, ' @@ -513,12 +513,12 @@ class CourseGradeReport(GradeReportBase): USER_BATCH_SIZE = 100 @classmethod - def generate(cls, _xmodule_instance_args, _entry_id, course_id, _task_input, action_name): + def generate(cls, _xblock_instance_args, _entry_id, course_id, _task_input, action_name): """ Public method to generate a grade report. """ with modulestore().bulk_operations(course_id): - context = _CourseGradeReportContext(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name) + context = _CourseGradeReportContext(_xblock_instance_args, _entry_id, course_id, _task_input, action_name) if use_on_disk_grade_reporting(course_id): # AU-926 return TempFileCourseGradeReport(context)._generate() # pylint: disable=protected-access else: @@ -712,12 +712,12 @@ class ProblemGradeReport(GradeReportBase): """ @classmethod - def generate(cls, _xmodule_instance_args, _entry_id, course_id, _task_input, action_name): + def generate(cls, _xblock_instance_args, _entry_id, course_id, _task_input, action_name): """ Public method to generate a grade report. """ with modulestore().bulk_operations(course_id): - context = _ProblemGradeReportContext(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name) + context = _ProblemGradeReportContext(_xblock_instance_args, _entry_id, course_id, _task_input, action_name) if use_on_disk_grade_reporting(course_id): # AU-926 return TempFileProblemGradeReport(context)._generate() # pylint: disable=protected-access else: @@ -960,7 +960,7 @@ def _build_student_data( return student_data, student_data_keys_list @classmethod - def generate(cls, _xmodule_instance_args, _entry_id, course_id, task_input, action_name): + def generate(cls, _xblock_instance_args, _entry_id, course_id, task_input, action_name): """ For a given `course_id`, generate a CSV file containing all student answers to a given problem, and store using a `ReportStore`. diff --git a/lms/djangoapps/instructor_task/tasks_helper/misc.py b/lms/djangoapps/instructor_task/tasks_helper/misc.py index e2d303a9b15d..85a5d4e1361e 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/misc.py +++ b/lms/djangoapps/instructor_task/tasks_helper/misc.py @@ -39,7 +39,7 @@ TASK_LOG = logging.getLogger('edx.celery.task') -def upload_course_survey_report(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name): +def upload_course_survey_report(_xblock_instance_args, _entry_id, course_id, _task_input, action_name): """ For a given `course_id`, generate a html report containing the survey results for a course. """ @@ -97,7 +97,7 @@ def upload_course_survey_report(_xmodule_instance_args, _entry_id, course_id, _t return task_progress.update_task_state(extra_meta=current_step) -def upload_proctored_exam_results_report(_xmodule_instance_args, _entry_id, course_id, _task_input, action_name): +def upload_proctored_exam_results_report(_xblock_instance_args, _entry_id, course_id, _task_input, action_name): """ For a given `course_id`, generate a CSV file containing information about proctored exam results, and store using a `ReportStore`. @@ -165,7 +165,7 @@ def _get_csv_file_content(csv_file): return csv_content -def cohort_students_and_upload(_xmodule_instance_args, _entry_id, course_id, task_input, action_name): # lint-amnesty, pylint: disable=too-many-statements +def cohort_students_and_upload(_xblock_instance_args, _entry_id, course_id, task_input, action_name): # lint-amnesty, pylint: disable=too-many-statements """ Within a given course, cohort students in bulk, then upload the results using a `ReportStore`. @@ -273,33 +273,33 @@ def cohort_students_and_upload(_xmodule_instance_args, _entry_id, course_id, tas def upload_ora2_data( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name + _xblock_instance_args, _entry_id, course_id, _task_input, action_name ): """ Collect ora2 responses and upload them to S3 as a CSV """ return _upload_ora2_data_common( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name, + _xblock_instance_args, _entry_id, course_id, _task_input, action_name, 'data', OraAggregateData.collect_ora2_data ) def upload_ora2_summary( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name + _xblock_instance_args, _entry_id, course_id, _task_input, action_name ): """ Collect ora2/student summaries and upload them to file storage as a CSV """ return _upload_ora2_data_common( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name, + _xblock_instance_args, _entry_id, course_id, _task_input, action_name, 'summary', OraAggregateData.collect_ora2_summary ) def _upload_ora2_data_common( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name, + _xblock_instance_args, _entry_id, course_id, _task_input, action_name, report_name, csv_gen_func ): """ @@ -313,7 +313,7 @@ def _upload_ora2_data_common( fmt = 'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}' task_info_string = fmt.format( - task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None, + task_id=_xblock_instance_args.get('task_id') if _xblock_instance_args is not None else None, entry_id=_entry_id, course_id=course_id, task_input=_task_input @@ -399,7 +399,7 @@ def _step_context_manager(step_description, exception_text, step_error_descripti def upload_ora2_submission_files( - _xmodule_instance_args, _entry_id, course_id, _task_input, action_name + _xblock_instance_args, _entry_id, course_id, _task_input, action_name ): """ Creates zip archive with submission files in three steps: @@ -418,7 +418,7 @@ def upload_ora2_submission_files( fmt = 'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}' task_info_string = fmt.format( - task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None, + task_id=_xblock_instance_args.get('task_id') if _xblock_instance_args is not None else None, entry_id=_entry_id, course_id=course_id, task_input=_task_input @@ -481,7 +481,7 @@ def upload_ora2_submission_files( return UPDATE_STATUS_SUCCEEDED -def generate_anonymous_ids(_xmodule_instance_args, _entry_id, course_id, task_input, action_name): # lint-amnesty, pylint: disable=too-many-statements +def generate_anonymous_ids(_xblock_instance_args, _entry_id, course_id, task_input, action_name): # lint-amnesty, pylint: disable=too-many-statements """ Generate a 2-column CSV output of user-id, anonymized-user-id """ @@ -503,7 +503,7 @@ def _log_and_update_progress(step): task_info_string_format = 'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}' task_info_string = task_info_string_format.format( - task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None, + task_id=_xblock_instance_args.get('task_id') if _xblock_instance_args is not None else None, entry_id=_entry_id, course_id=course_id, task_input=task_input diff --git a/lms/djangoapps/instructor_task/tasks_helper/module_state.py b/lms/djangoapps/instructor_task/tasks_helper/module_state.py index 8095153f00b2..ddec49cf8a03 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/module_state.py +++ b/lms/djangoapps/instructor_task/tasks_helper/module_state.py @@ -20,7 +20,7 @@ from lms.djangoapps.courseware.courses import get_problems_in_section from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache from lms.djangoapps.courseware.models import StudentModule -from lms.djangoapps.courseware.module_render import get_module_for_descriptor_internal +from lms.djangoapps.courseware.block_render import get_block_for_descriptor_internal from lms.djangoapps.grades.api import events as grades_events from openedx.core.lib.courses import get_course_by_id from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order @@ -39,7 +39,7 @@ def perform_module_state_update(update_fcn, filter_fcn, _entry_id, course_id, ta The student modules are fetched for update the `update_fcn` is called on each StudentModule that passes the resulting filtering. It is passed four arguments: the module_descriptor for the module pointed to by the module_state_key, the particular StudentModule to update, the - xmodule_instance_args, and the task_input being passed through. If the value returned by the + xblock_instance_args, and the task_input being passed through. If the value returned by the update function evaluates to a boolean True, the update is successful; False indicates the update on the particular student module failed. A raised exception indicates a fatal condition -- that no other student modules should be considered. @@ -110,7 +110,7 @@ def perform_module_state_update(update_fcn, filter_fcn, _entry_id, course_id, ta @outer_atomic -def rescore_problem_module_state(xmodule_instance_args, module_descriptor, student_module, task_input): +def rescore_problem_module_state(xblock_instance_args, module_descriptor, student_module, task_input): ''' Takes an XModule descriptor and a corresponding StudentModule object, and performs rescoring on the student's problem submission. @@ -136,7 +136,7 @@ def rescore_problem_module_state(xmodule_instance_args, module_descriptor, stude course_id, student, module_descriptor, - xmodule_instance_args, + xblock_instance_args, grade_bucket_type='rescore', course=course ) @@ -208,7 +208,7 @@ def rescore_problem_module_state(xmodule_instance_args, module_descriptor, stude @outer_atomic -def override_score_module_state(xmodule_instance_args, module_descriptor, student_module, task_input): +def override_score_module_state(xblock_instance_args, module_descriptor, student_module, task_input): ''' Takes an XModule descriptor and a corresponding StudentModule object, and performs an override on the student's problem score. @@ -233,7 +233,7 @@ def override_score_module_state(xmodule_instance_args, module_descriptor, studen course_id, student, module_descriptor, - xmodule_instance_args, + xblock_instance_args, course=course ) @@ -288,7 +288,7 @@ def override_score_module_state(xmodule_instance_args, module_descriptor, studen @outer_atomic -def reset_attempts_module_state(xmodule_instance_args, _module_descriptor, student_module, _task_input): +def reset_attempts_module_state(xblock_instance_args, _module_descriptor, student_module, _task_input): """ Resets problem attempts to zero for specified `student_module`. @@ -306,7 +306,7 @@ def reset_attempts_module_state(xmodule_instance_args, _module_descriptor, stude student_module.save() # get request-related tracking information from args passthrough, # and supplement with task-specific information: - track_function = _get_track_function_for_task(student_module.student, xmodule_instance_args) + track_function = _get_track_function_for_task(student_module.student, xblock_instance_args) event_info = {"old_attempts": old_number_of_attempts, "new_attempts": 0} track_function('problem_reset_attempts', event_info) update_status = UPDATE_STATUS_SUCCEEDED @@ -315,7 +315,7 @@ def reset_attempts_module_state(xmodule_instance_args, _module_descriptor, stude @outer_atomic -def delete_problem_module_state(xmodule_instance_args, _module_descriptor, student_module, _task_input): +def delete_problem_module_state(xblock_instance_args, _module_descriptor, student_module, _task_input): """ Delete the StudentModule entry. @@ -324,19 +324,19 @@ def delete_problem_module_state(xmodule_instance_args, _module_descriptor, stude student_module.delete() # get request-related tracking information from args passthrough, # and supplement with task-specific information: - track_function = _get_track_function_for_task(student_module.student, xmodule_instance_args) + track_function = _get_track_function_for_task(student_module.student, xblock_instance_args) track_function('problem_delete_state', {}) return UPDATE_STATUS_SUCCEEDED -def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule_instance_args=None, +def _get_module_instance_for_task(course_id, student, module_descriptor, xblock_instance_args=None, grade_bucket_type=None, course=None): """ Fetches a StudentModule instance for a given `course_id`, `student` object, and `module_descriptor`. - `xmodule_instance_args` is used to provide information for creating a track function and an XQueue callback. - These are passed, along with `grade_bucket_type`, to get_module_for_descriptor_internal, which sidesteps - the need for a Request object when instantiating an xmodule instance. + `xblock_instance_args` is used to provide information for creating a track function and an XQueue callback. + These are passed, along with `grade_bucket_type`, to get_block_for_descriptor_internal, which sidesteps + the need for a Request object when instantiating an xblock instance. """ # reconstitute the problem's corresponding XModule: field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, student, module_descriptor) @@ -344,8 +344,8 @@ def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule # get request-related tracking information from args passthrough, and supplement with task-specific # information: - request_info = xmodule_instance_args.get('request_info', {}) if xmodule_instance_args is not None else {} - task_info = {"student": student.username, "task_id": _get_task_id_from_xmodule_args(xmodule_instance_args)} + request_info = xblock_instance_args.get('request_info', {}) if xblock_instance_args is not None else {} + task_info = {"student": student.username, "task_id": _get_task_id_from_xblock_args(xblock_instance_args)} def make_track_function(): ''' @@ -357,7 +357,7 @@ def make_track_function(): ''' return lambda event_type, event: task_track(request_info, task_info, event_type, event, page='x_module_task') - return get_module_for_descriptor_internal( + return get_block_for_descriptor_internal( user=student, descriptor=module_descriptor, student_data=student_data, @@ -371,7 +371,7 @@ def make_track_function(): ) -def _get_track_function_for_task(student, xmodule_instance_args=None, source_page='x_module_task'): +def _get_track_function_for_task(student, xblock_instance_args=None, source_page='x_module_task'): """ Make a tracking function that logs what happened. @@ -381,18 +381,18 @@ def _get_track_function_for_task(student, xmodule_instance_args=None, source_pag """ # get request-related tracking information from args passthrough, and supplement with task-specific # information: - request_info = xmodule_instance_args.get('request_info', {}) if xmodule_instance_args is not None else {} - task_info = {'student': student.username, 'task_id': _get_task_id_from_xmodule_args(xmodule_instance_args)} + request_info = xblock_instance_args.get('request_info', {}) if xblock_instance_args is not None else {} + task_info = {'student': student.username, 'task_id': _get_task_id_from_xblock_args(xblock_instance_args)} return lambda event_type, event: task_track(request_info, task_info, event_type, event, page=source_page) -def _get_task_id_from_xmodule_args(xmodule_instance_args): - """Gets task_id from `xmodule_instance_args` dict, or returns default value if missing.""" - if xmodule_instance_args is None: +def _get_task_id_from_xblock_args(xblock_instance_args): + """Gets task_id from `xblock_instance_args` dict, or returns default value if missing.""" + if xblock_instance_args is None: return UNKNOWN_TASK_ID else: - return xmodule_instance_args.get('task_id', UNKNOWN_TASK_ID) + return xblock_instance_args.get('task_id', UNKNOWN_TASK_ID) def _get_modules_to_update(course_id, usage_keys, student_identifier, filter_fcn, override_score_task=False): diff --git a/lms/djangoapps/instructor_task/tests/test_api_helper.py b/lms/djangoapps/instructor_task/tests/test_api_helper.py index 45df5a241a05..f1432945013c 100644 --- a/lms/djangoapps/instructor_task/tests/test_api_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_api_helper.py @@ -116,8 +116,8 @@ def test_create_scheduled_instructor_task(self): assert expected_task_args == actual_task_args self._verify_log_messages(expected_messages, log) - @patch("lms.djangoapps.instructor_task.api_helper._get_xmodule_instance_args", side_effect=Exception("boom!")) - def test_create_scheduled_instructor_task_expect_failure(self, mock_get_xmodule_instance_args): + @patch("lms.djangoapps.instructor_task.api_helper._get_xblock_instance_args", side_effect=Exception("boom!")) + def test_create_scheduled_instructor_task_expect_failure(self, mock_get_xblock_instance_args): """ A test to verify that we will mark a task as `FAILED` if a failure occurs during the creation of the task schedule. diff --git a/lms/djangoapps/instructor_task/tests/test_tasks.py b/lms/djangoapps/instructor_task/tests/test_tasks.py index 6c514a596464..4c66f7271c51 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks.py @@ -78,7 +78,7 @@ def _create_input_entry( ) return instructor_task - def _get_xmodule_instance_args(self): + def _get_block_instance_args(self): """ Calculate dummy values for parameters needed for instantiating xmodule instances. """ @@ -97,7 +97,7 @@ def _run_task_with_mock_celery(self, task_class, entry_id, task_id, expected_fai self.current_task.update_state = Mock() if expected_failure_message is not None: self.current_task.update_state.side_effect = TestTaskFailure(expected_failure_message) - task_args = [entry_id, self._get_xmodule_instance_args()] + task_args = [entry_id, self._get_block_instance_args()] with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task') as mock_get_task: mock_get_task.return_value = self.current_task @@ -107,7 +107,7 @@ def _test_missing_current_task(self, task_class): """Check that a task_class fails when celery doesn't provide a current_task.""" task_entry = self._create_input_entry() with pytest.raises(ValueError): - task_class(task_entry.id, self._get_xmodule_instance_args()) + task_class(task_entry.id, self._get_block_instance_args()) def _test_undefined_course(self, task_class): """Run with celery, but with no course defined.""" @@ -292,9 +292,9 @@ def test_overriding_non_scorable(self): mock_instance = MagicMock() del mock_instance.set_score with patch( - 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal' - ) as mock_get_module: - mock_get_module.return_value = mock_instance + 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal' + ) as mock_get_block: + mock_get_block.return_value = mock_instance with pytest.raises(UpdateProblemModuleStateError): self._run_task_with_mock_celery(override_problem_score, task_entry.id, task_entry.task_id) # check values stored in table: @@ -313,7 +313,7 @@ def test_overriding_unaccessable(self): num_students = 1 self._create_students_with_state(num_students, input_state) task_entry = self._create_input_entry(score=0) - with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal', + with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal', return_value=None): self._run_task_with_mock_celery(override_problem_score, task_entry.id, task_entry.task_id) @@ -338,9 +338,9 @@ def test_overriding_success(self): self._create_students_with_state(num_students) task_entry = self._create_input_entry(score=0) with patch( - 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal' - ) as mock_get_module: - mock_get_module.return_value = mock_instance + 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal' + ) as mock_get_block: + mock_get_block.return_value = mock_instance mock_instance.max_score = MagicMock(return_value=99999.0) mock_instance.weight = 99999.0 self._run_task_with_mock_celery(override_problem_score, task_entry.id, task_entry.task_id) @@ -425,8 +425,8 @@ def test_rescoring_unrescorable(self): mock_instance = MagicMock() del mock_instance.rescore_problem del mock_instance.rescore - with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal') as mock_get_module: # lint-amnesty, pylint: disable=line-too-long - mock_get_module.return_value = mock_instance + with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal') as mock_get_block: # lint-amnesty, pylint: disable=line-too-long + mock_get_block.return_value = mock_instance with pytest.raises(UpdateProblemModuleStateError): self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id) # check values stored in table: @@ -448,7 +448,7 @@ def test_rescoring_unaccessable(self): num_students = 1 self._create_students_with_state(num_students, input_state) task_entry = self._create_input_entry() - with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal', return_value=None): # lint-amnesty, pylint: disable=line-too-long + with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal', return_value=None): # lint-amnesty, pylint: disable=line-too-long self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id) self.assert_task_output( @@ -474,9 +474,9 @@ def test_rescoring_success(self): self._create_students_with_state(num_students) task_entry = self._create_input_entry() with patch( - 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal' - ) as mock_get_module: - mock_get_module.return_value = mock_instance + 'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal' + ) as mock_get_block: + mock_get_block.return_value = mock_instance self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id) self.assert_task_output( @@ -671,10 +671,10 @@ def test_ora2_with_short_error_msg(self): def test_ora2_runs_task(self): task_entry = self._create_input_entry() - task_xmodule_args = self._get_xmodule_instance_args() + task_xblock_args = self._get_block_instance_args() with patch('lms.djangoapps.instructor_task.tasks.run_main_task') as mock_main_task: - export_ora2_data(task_entry.id, task_xmodule_args) + export_ora2_data(task_entry.id, task_xblock_args) action_name = gettext_noop('generated') assert mock_main_task.call_count == 1 @@ -701,10 +701,10 @@ def test_ora2_with_short_error_msg(self): def test_ora2_runs_task(self): task_entry = self._create_input_entry() - task_xmodule_args = self._get_xmodule_instance_args() + task_xblock_args = self._get_block_instance_args() with patch('lms.djangoapps.instructor_task.tasks.run_main_task') as mock_main_task: - export_ora2_submission_files(task_entry.id, task_xmodule_args) + export_ora2_submission_files(task_entry.id, task_xblock_args) action_name = gettext_noop('compressed') assert mock_main_task.call_count == 1 @@ -731,10 +731,10 @@ def test_ora2_with_short_error_msg(self): def test_ora2_runs_task(self): task_entry = self._create_input_entry() - task_xmodule_args = self._get_xmodule_instance_args() + task_xblock_args = self._get_block_instance_args() with patch('lms.djangoapps.instructor_task.tasks.run_main_task') as mock_main_task: - export_ora2_summary(task_entry.id, task_xmodule_args) + export_ora2_summary(task_entry.id, task_xblock_args) action_name = gettext_noop('generated') assert mock_main_task.call_count == 1 diff --git a/lms/djangoapps/lms_xblock/apps.py b/lms/djangoapps/lms_xblock/apps.py index 5abbb4b151f4..54cee08cefb2 100644 --- a/lms/djangoapps/lms_xblock/apps.py +++ b/lms/djangoapps/lms_xblock/apps.py @@ -18,7 +18,7 @@ class LMSXBlockConfig(AppConfig): def ready(self): from .runtime import handler_url, local_resource_url - # In order to allow modules to use a handler url, we need to + # In order to allow blocks to use a handler url, we need to # monkey-patch the x_module library. # TODO: Remove this code when Runtimes are no longer created by modulestores # https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes diff --git a/lms/djangoapps/lms_xblock/mixin.py b/lms/djangoapps/lms_xblock/mixin.py index 67c2fd477abd..dbaaa5b1fa5a 100644 --- a/lms/djangoapps/lms_xblock/mixin.py +++ b/lms/djangoapps/lms_xblock/mixin.py @@ -53,13 +53,13 @@ class LmsBlockMixin(XBlockMixin): Mixin that defines fields common to all blocks used in the LMS """ hide_from_toc = Boolean( - help=_("Whether to display this module in the table of contents"), + help=_("Whether to display this block in the table of contents"), default=False, scope=Scope.settings ) format = String( # Translators: "TOC" stands for "Table of Contents" - help=_("What format this module is in (used for deciding which " + help=_("What format this block is in (used for deciding which " "grader to apply, and what to show in the TOC)"), scope=Scope.settings, ) diff --git a/lms/djangoapps/lms_xblock/test/test_runtime.py b/lms/djangoapps/lms_xblock/test/test_runtime.py index eaca83dacbaa..046c2139efd0 100644 --- a/lms/djangoapps/lms_xblock/test/test_runtime.py +++ b/lms/djangoapps/lms_xblock/test/test_runtime.py @@ -51,7 +51,7 @@ def setUp(self): super().setUp() self.block = BlockMock(name='block') self.runtime = LmsModuleSystem( - get_module=Mock(), + get_block=Mock(), descriptor_runtime=Mock(), ) diff --git a/lms/djangoapps/lti_provider/tasks.py b/lms/djangoapps/lti_provider/tasks.py index d65970a77f57..55430b5edf43 100644 --- a/lms/djangoapps/lti_provider/tasks.py +++ b/lms/djangoapps/lti_provider/tasks.py @@ -55,7 +55,7 @@ def send_composite_outcome(user_id, course_id, assignment_id, version): user = User.objects.get(id=user_id) course = modulestore().get_course(course_key, depth=0) course_grade = CourseGradeFactory().read(user, course) - earned, possible = course_grade.score_for_module(mapped_usage_key) + earned, possible = course_grade.score_for_block(mapped_usage_key) if possible == 0: weighted_score = 0 else: diff --git a/lms/djangoapps/lti_provider/tests/test_tasks.py b/lms/djangoapps/lti_provider/tests/test_tasks.py index f8c98cbdffeb..950d2ce0176b 100644 --- a/lms/djangoapps/lti_provider/tests/test_tasks.py +++ b/lms/djangoapps/lti_provider/tests/test_tasks.py @@ -121,7 +121,7 @@ def setUp(self): ) @ddt.unpack def test_outcome_with_score_score(self, earned, possible, expected): - self.course_grade.score_for_module = MagicMock(return_value=(earned, possible)) + self.course_grade.score_for_block = MagicMock(return_value=(earned, possible)) tasks.send_composite_outcome( self.user.id, str(self.course_key), self.assignment.id, 1 ) diff --git a/lms/djangoapps/mobile_api/course_info/views.py b/lms/djangoapps/mobile_api/course_info/views.py index 3d8aff38ec78..cb474a5fd754 100644 --- a/lms/djangoapps/mobile_api/course_info/views.py +++ b/lms/djangoapps/mobile_api/course_info/views.py @@ -12,7 +12,7 @@ from rest_framework.views import APIView from common.djangoapps.static_replace import make_static_urls_absolute -from lms.djangoapps.courseware.courses import get_course_info_section_module +from lms.djangoapps.courseware.courses import get_course_info_section_block from lms.djangoapps.course_goals.models import UserActivity from openedx.core.lib.xblock_utils import get_course_update_items from openedx.features.course_experience import ENABLE_COURSE_GOALS @@ -47,8 +47,8 @@ class CourseUpdatesList(generics.ListAPIView): @mobile_course_access() def list(self, request, course, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ - course_updates_module = get_course_info_section_module(request, request.user, course, 'updates') - update_items = get_course_update_items(course_updates_module) + course_updates_block = get_course_info_section_block(request, request.user, course, 'updates') + update_items = get_course_update_items(course_updates_block) updates_to_show = [ update for update in update_items @@ -56,7 +56,7 @@ def list(self, request, course, *args, **kwargs): # lint-amnesty, pylint: disab ] for item in updates_to_show: - item['content'] = apply_wrappers_to_content(item['content'], course_updates_module, request) + item['content'] = apply_wrappers_to_content(item['content'], course_updates_block, request) return Response(updates_to_show) @@ -82,26 +82,26 @@ class CourseHandoutsList(generics.ListAPIView): @mobile_course_access() def list(self, request, course, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ - course_handouts_module = get_course_info_section_module(request, request.user, course, 'handouts') - if course_handouts_module: - if course_handouts_module.data == "
    ": + course_handouts_block = get_course_info_section_block(request, request.user, course, 'handouts') + if course_handouts_block: + if course_handouts_block.data == "
      ": handouts_html = None else: - handouts_html = apply_wrappers_to_content(course_handouts_module.data, course_handouts_module, request) + handouts_html = apply_wrappers_to_content(course_handouts_block.data, course_handouts_block, request) return Response({'handouts_html': handouts_html}) else: - # course_handouts_module could be None if there are no handouts + # course_handouts_block could be None if there are no handouts return Response({'handouts_html': None}) -def apply_wrappers_to_content(content, module, request): +def apply_wrappers_to_content(content, block, request): """ Updates a piece of html content with the filter functions stored in its module system, then replaces any static urls with absolute urls. Args: content: The html content to which to apply the content wrappers generated for this module system. - module: The module containing a reference to the module system which contains functions to apply to the + block: The block containing a reference to the module system which contains functions to apply to the content. These functions include: * Replacing static url's * Replacing course url's @@ -111,7 +111,7 @@ def apply_wrappers_to_content(content, module, request): Returns: A piece of html content containing the original content updated by each wrapper. """ - content = module.system.service(module, "replace_urls").replace_urls(content) + content = block.runtime.service(block, "replace_urls").replace_urls(content) return make_static_urls_absolute(request, content) diff --git a/lms/djangoapps/mobile_api/users/tests.py b/lms/djangoapps/mobile_api/users/tests.py index f5ce65af6733..9d4752ea7c22 100644 --- a/lms/djangoapps/mobile_api/users/tests.py +++ b/lms/djangoapps/mobile_api/users/tests.py @@ -490,7 +490,7 @@ def test_success_v0(self): response = self.api_response(api_version=API_V05) assert response.data['last_visited_module_id'] == str(self.sub_section.location) - assert response.data['last_visited_module_path'] == [str(module.location) for module in + assert response.data['last_visited_module_path'] == [str(block.location) for block in [self.sub_section, self.section, self.course]] def test_success_v1(self): @@ -558,12 +558,12 @@ def test_success(self): response = self.api_response(data={"last_visited_module_id": str(self.other_unit.location)}) assert response.data['last_visited_module_id'] == str(self.other_sub_section.location) - def test_invalid_module(self): + def test_invalid_block(self): self.login_and_enroll() response = self.api_response(data={"last_visited_module_id": "abc"}, expected_response_code=400) assert response.data == errors.ERROR_INVALID_MODULE_ID - def test_nonexistent_module(self): + def test_nonexistent_block(self): self.login_and_enroll() non_existent_key = self.course.id.make_usage_key('video', 'non-existent') response = self.api_response(data={"last_visited_module_id": non_existent_key}, expected_response_code=400) diff --git a/lms/djangoapps/mobile_api/users/views.py b/lms/djangoapps/mobile_api/users/views.py index cfca1adeb311..0e2cb61d3114 100644 --- a/lms/djangoapps/mobile_api/users/views.py +++ b/lms/djangoapps/mobile_api/users/views.py @@ -25,7 +25,7 @@ from lms.djangoapps.courseware.access_utils import ACCESS_GRANTED from lms.djangoapps.courseware.courses import get_current_child from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module_for_descriptor +from lms.djangoapps.courseware.block_render import get_block_for_descriptor from lms.djangoapps.courseware.views.index import save_positions_recursively_up from lms.djangoapps.mobile_api.models import MobileConfig from lms.djangoapps.mobile_api.utils import API_V1, API_V05, API_V2 @@ -134,16 +134,16 @@ def dispatch(self, request, *args, **kwargs): with transaction.atomic(): return super().dispatch(request, *args, **kwargs) - def _last_visited_module_path(self, request, course): + def _last_visited_block_path(self, request, course): """ - Returns the path from the last module visited by the current user in the given course up to + Returns the path from the last block visited by the current user in the given course up to the course block. If there is no such visit, the first item deep enough down the course tree is used. """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( request.user, request, course, field_data_cache, course.id, course=course ) @@ -162,8 +162,8 @@ def _get_course_info(self, request, course): """ Returns the course status """ - path = self._last_visited_module_path(request, course) - path_ids = [str(module.location) for module in path] + path = self._last_visited_block_path(request, course) + path_ids = [str(block.location) for block in path] return Response({ "last_visited_module_id": path_ids[0], "last_visited_module_path": path_ids, @@ -176,11 +176,11 @@ def _update_last_visited_module_id(self, request, course, module_key, modificati field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) try: - module_descriptor = modulestore().get_item(module_key) + block_descriptor = modulestore().get_item(module_key) except ItemNotFoundError: return Response(errors.ERROR_INVALID_MODULE_ID, status=400) - module = get_module_for_descriptor( - request.user, request, module_descriptor, field_data_cache, course.id, course=course + block = get_block_for_descriptor( + request.user, request, block_descriptor, field_data_cache, course.id, course=course ) if modification_date: @@ -195,7 +195,7 @@ def _update_last_visited_module_id(self, request, course, module_key, modificati # old modification date so skip update return self._get_course_info(request, course) - save_positions_recursively_up(request.user, request, field_data_cache, module, course=course) + save_positions_recursively_up(request.user, request, field_data_cache, block, course=course) return self._get_course_info(request, course) @mobile_course_access(depth=2) diff --git a/lms/djangoapps/ora_staff_grader/utils.py b/lms/djangoapps/ora_staff_grader/utils.py index 355292380831..7812a62a83a3 100644 --- a/lms/djangoapps/ora_staff_grader/utils.py +++ b/lms/djangoapps/ora_staff_grader/utils.py @@ -7,7 +7,7 @@ from opaque_keys.edx.keys import UsageKey from rest_framework.request import clone_request -from lms.djangoapps.courseware.module_render import handle_xblock_callback_noauth +from lms.djangoapps.courseware.block_render import handle_xblock_callback_noauth from lms.djangoapps.ora_staff_grader.errors import MissingParamResponse diff --git a/lms/urls.py b/lms/urls.py index ce5631347e4b..3a4b7d3e02b4 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -17,7 +17,7 @@ from common.djangoapps.util import views as util_views from lms.djangoapps.branding import views as branding_views from lms.djangoapps.courseware.masquerade import MasqueradeView -from lms.djangoapps.courseware.module_render import ( +from lms.djangoapps.courseware.block_render import ( handle_xblock_callback, handle_xblock_callback_noauth, xblock_view, diff --git a/openedx/core/djangoapps/courseware_api/views.py b/openedx/core/djangoapps/courseware_api/views.py index 8232337203eb..2d6060e6edb3 100644 --- a/openedx/core/djangoapps/courseware_api/views.py +++ b/openedx/core/djangoapps/courseware_api/views.py @@ -40,7 +40,7 @@ is_masquerading_as_non_audit_enrollment, ) from lms.djangoapps.courseware.models import LastSeenCoursewareTimezone -from lms.djangoapps.courseware.module_render import get_module_by_usage_id +from lms.djangoapps.courseware.block_render import get_block_by_usage_id from lms.djangoapps.courseware.toggles import course_exit_page_is_active from lms.djangoapps.courseware.views.views import get_cert_data from lms.djangoapps.gating.api import get_entrance_exam_score, get_entrance_exam_usage_key @@ -584,7 +584,7 @@ def get(self, request, usage_key_string, *args, **kwargs): # lint-amnesty, pyli reset_masquerade_data=True, ) - sequence, _ = get_module_by_usage_id( + sequence, _ = get_block_by_usage_id( self.request, str(usage_key.course_key), str(usage_key), diff --git a/openedx/core/djangoapps/olx_rest_api/block_serializer.py b/openedx/core/djangoapps/olx_rest_api/block_serializer.py index 2a2d002f96e7..4e063601aebe 100644 --- a/openedx/core/djangoapps/olx_rest_api/block_serializer.py +++ b/openedx/core/djangoapps/olx_rest_api/block_serializer.py @@ -94,7 +94,7 @@ def serialize_normal_block(self, block): block.add_xml_to_node(olx_node) block.children = children - # Now the block/module may have exported addtional data as files in + # Now the block may have exported addtional data as files in # 'filesystem'. If so, store them: for item in filesystem.walk(): # pylint: disable=not-callable for unit_file in item.files: diff --git a/openedx/core/djangoapps/schedules/content_highlights.py b/openedx/core/djangoapps/schedules/content_highlights.py index 9695c72e3b4d..c50d00484bc6 100644 --- a/openedx/core/djangoapps/schedules/content_highlights.py +++ b/openedx/core/djangoapps/schedules/content_highlights.py @@ -131,7 +131,7 @@ def _get_course_block(course_descriptor, user): # Adding courseware imports here to insulate other apps (e.g. schedules) to # avoid import errors. from lms.djangoapps.courseware.model_data import FieldDataCache - from lms.djangoapps.courseware.module_render import get_module_for_descriptor + from lms.djangoapps.courseware.block_render import get_block_for_descriptor # Fake a request to fool parts of the courseware that want to inspect it. request = get_request_or_stub() @@ -142,7 +142,7 @@ def _get_course_block(course_descriptor, user): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_descriptor.id, user, course_descriptor, depth=1, read_only=True, ) - course_block = get_module_for_descriptor( + course_block = get_block_for_descriptor( user, request, course_descriptor, field_data_cache, course_descriptor.id, course=course_descriptor, ) if not course_block: diff --git a/openedx/core/djangoapps/schedules/tests/test_content_highlights.py b/openedx/core/djangoapps/schedules/tests/test_content_highlights.py index 9a34eaee5d25..ece49fc50f0d 100644 --- a/openedx/core/djangoapps/schedules/tests/test_content_highlights.py +++ b/openedx/core/djangoapps/schedules/tests/test_content_highlights.py @@ -161,9 +161,9 @@ def test_get_next_section_highlights(self, mock_duration): with pytest.raises(CourseUpdateDoesNotExist): get_next_section_highlights(self.user, self.course_key, two_days_ago, six_days.date()) - @patch('lms.djangoapps.courseware.module_render.get_module_for_descriptor') - def test_get_highlights_without_module(self, mock_get_module): - mock_get_module.return_value = None + @patch('lms.djangoapps.courseware.block_render.get_block_for_descriptor') + def test_get_highlights_without_block(self, mock_get_block): + mock_get_block.return_value = None with self.store.bulk_operations(self.course_key): self._create_chapter(highlights=['Test highlight']) diff --git a/openedx/core/djangoapps/util/testing.py b/openedx/core/djangoapps/util/testing.py index f840cad676da..040a2b5af180 100644 --- a/openedx/core/djangoapps/util/testing.py +++ b/openedx/core/djangoapps/util/testing.py @@ -19,8 +19,8 @@ class ContentGroupTestCase(ModuleStoreTestCase): """ - Sets up discussion modules visible to content groups 'Alpha' and - 'Beta', as well as a module visible to all students. Creates a + Sets up discussion blocks visible to content groups 'Alpha' and + 'Beta', as well as a block visible to all students. Creates a staff user, users with access to Alpha/Beta (by way of cohorts), and a non-cohorted user with no special access. """ @@ -99,21 +99,21 @@ def setUp(self): partition_id=self.course.user_partitions[0].id, group_id=self.course.user_partitions[0].groups[1].id ) - self.alpha_module = BlockFactory.create( + self.alpha_block = BlockFactory.create( parent_location=self.course.location, category='discussion', discussion_id='alpha_group_discussion', discussion_target='Visible to Alpha', group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[0].id]} ) - self.beta_module = BlockFactory.create( + self.beta_block = BlockFactory.create( parent_location=self.course.location, category='discussion', discussion_id='beta_group_discussion', discussion_target='Visible to Beta', group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[1].id]} ) - self.global_module = BlockFactory.create( + self.global_block = BlockFactory.create( parent_location=self.course.location, category='discussion', discussion_id='global_group_discussion', diff --git a/openedx/core/djangoapps/xblock/runtime/runtime.py b/openedx/core/djangoapps/xblock/runtime/runtime.py index 3f0fc79d1b3b..cadc7f4e3309 100644 --- a/openedx/core/djangoapps/xblock/runtime/runtime.py +++ b/openedx/core/djangoapps/xblock/runtime/runtime.py @@ -22,7 +22,7 @@ from xmodule.errortracker import make_error_tracker from xmodule.contentstore.django import contentstore -from xmodule.modulestore.django import ModuleI18nService +from xmodule.modulestore.django import XBlockI18nService from xmodule.services import EventPublishingService, RebindUserService from xmodule.util.sandboxing import SandboxService from common.djangoapps.edxmako.services import MakoService @@ -31,7 +31,7 @@ from common.djangoapps.track import views as track_views from common.djangoapps.xblock_django.user_service import DjangoXBlockUserService from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache -from lms.djangoapps.courseware import module_render +from lms.djangoapps.courseware import block_render from lms.djangoapps.grades.api import signals as grades_signals from openedx.core.djangoapps.xblock.apps import get_xblock_app_config from openedx.core.djangoapps.xblock.runtime.blockstore_field_data import BlockstoreChildrenData, BlockstoreFieldData @@ -247,7 +247,7 @@ def service(self, block, service_name): return MakoService(namespace_prefix='lms.') return MakoService() elif service_name == "i18n": - return ModuleI18nService(block=block) + return XBlockI18nService(block=block) elif service_name == 'sandbox': context_key = block.scope_ids.usage_id.context_key return SandboxService(contentstore=contentstore, course_id=context_key) @@ -258,11 +258,11 @@ def service(self, block, service_name): elif service_name == 'rebind_user': # this service should ideally be initialized with all the arguments of get_module_system_for_user # but only the positional arguments are passed here as the other arguments are too - # specific to the lms.module_render module + # specific to the lms.block_render module return RebindUserService( self.user, context_key, - module_render.get_module_system_for_user, + block_render.get_module_system_for_user, track_function=make_track_function(), request_token=request_token(crum.get_current_request()), ) diff --git a/openedx/core/lib/exceptions.py b/openedx/core/lib/exceptions.py index f9e0e36e5559..7a49dd535660 100644 --- a/openedx/core/lib/exceptions.py +++ b/openedx/core/lib/exceptions.py @@ -21,6 +21,6 @@ class PageNotFoundError(ObjectDoesNotExist): class DiscussionNotFoundError(ObjectDoesNotExist): """ - Discussion Module was not found. + Discussion Block was not found. """ pass # lint-amnesty, pylint: disable=unnecessary-pass diff --git a/openedx/core/lib/xblock_utils/__init__.py b/openedx/core/lib/xblock_utils/__init__.py index 1674b2757fc5..f8f8ef92e813 100644 --- a/openedx/core/lib/xblock_utils/__init__.py +++ b/openedx/core/lib/xblock_utils/__init__.py @@ -225,11 +225,11 @@ def wrap_xblock_aside( return wrap_fragment(frag, render_to_string('xblock_wrapper.html', template_context)) -def grade_histogram(module_id): +def grade_histogram(block_id): ''' Print out a histogram of grades on a given problem in staff member debug info. - Warning: If a student has just looked at an xmodule and not attempted + Warning: If a student has just looked at an xblock and not attempted it, their grade is None. Since there will always be at least one such student this function almost always returns []. ''' @@ -242,8 +242,8 @@ def grade_histogram(module_id): FROM courseware_studentmodule WHERE courseware_studentmodule.module_id=%s GROUP BY courseware_studentmodule.grade""" - # Passing module_id this way prevents sql-injection. - cursor.execute(query, [str(module_id)]) + # Passing block_id this way prevents sql-injection. + cursor.execute(query, [str(block_id)]) grades = list(cursor.fetchall()) grades.sort(key=lambda x: x[0]) # Add ORDER BY to sql query? @@ -262,13 +262,13 @@ def sanitize_html_id(html_id): def add_staff_markup(user, disable_staff_debug_info, block, view, frag, context): # pylint: disable=unused-argument """ - Updates the supplied module with a new get_html function that wraps + Updates the supplied block with a new get_html function that wraps the output of the old get_html function with additional information for admin users only, including a histogram of student answers, the - definition of the xmodule, and a link to view the module in Studio + definition of the xblock, and a link to view the block in Studio if it is a Studio edited, mongo stored course. - Does nothing if module is a SequenceBlock. + Does nothing if block is a SequenceBlock. """ if context and context.get('hide_staff_markup', False): # If hide_staff_markup is passed, don't add the markup diff --git a/openedx/features/content_type_gating/tests/test_access.py b/openedx/features/content_type_gating/tests/test_access.py index 8c8da08ef863..cf8e4ca63dc6 100644 --- a/openedx/features/content_type_gating/tests/test_access.py +++ b/openedx/features/content_type_gating/tests/test_access.py @@ -27,7 +27,7 @@ from common.djangoapps.student.tests.factories import OrgInstructorFactory from common.djangoapps.student.tests.factories import OrgStaffFactory from common.djangoapps.student.tests.factories import StaffFactory -from lms.djangoapps.courseware.module_render import load_single_xblock +from lms.djangoapps.courseware.block_render import load_single_xblock from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory from openedx.core.djangoapps.django_comment_common.models import ( diff --git a/openedx/features/course_experience/course_updates.py b/openedx/features/course_experience/course_updates.py index 3539eb9cbab4..f073f69930d4 100644 --- a/openedx/features/course_experience/course_updates.py +++ b/openedx/features/course_experience/course_updates.py @@ -5,7 +5,7 @@ import hashlib from datetime import datetime -from lms.djangoapps.courseware.courses import get_course_info_section_module +from lms.djangoapps.courseware.courses import get_course_info_section_block from openedx.core.djangoapps.user_api.course_tag.api import get_course_tag, set_course_tag STATUS_VISIBLE = 'visible' @@ -59,18 +59,18 @@ def get_ordered_updates(request, course): """ Returns all public course updates in reverse chronological order, including dismissed ones. """ - info_module = get_course_info_section_module(request, request.user, course, 'updates') - if not info_module: + info_block = get_course_info_section_block(request, request.user, course, 'updates') + if not info_block: return [] - info_block = getattr(info_module, '_xmodule', info_module) - ordered_updates = [update for update in info_module.items if update.get('status') == STATUS_VISIBLE] + info_block = getattr(info_block, '_xmodule', info_block) + ordered_updates = [update for update in info_block.items if update.get('status') == STATUS_VISIBLE] ordered_updates.sort( key=lambda item: (_safe_parse_date(item['date']), item['id']), reverse=True ) for update in ordered_updates: - update['content'] = info_block.system.service(info_block, "replace_urls").replace_urls(update['content']) + update['content'] = info_block.runtime.service(info_block, "replace_urls").replace_urls(update['content']) return ordered_updates diff --git a/openedx/features/course_experience/views/course_updates.py b/openedx/features/course_experience/views/course_updates.py index 2e16cbc2508c..6789172f3606 100644 --- a/openedx/features/course_experience/views/course_updates.py +++ b/openedx/features/course_experience/views/course_updates.py @@ -10,7 +10,7 @@ from opaque_keys.edx.keys import CourseKey from web_fragments.fragment import Fragment -from lms.djangoapps.courseware.courses import get_course_info_section_module, get_course_with_access +from lms.djangoapps.courseware.courses import get_course_info_section_block, get_course_with_access from lms.djangoapps.courseware.views.views import CourseTabView from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.features.course_experience import default_course_url @@ -76,8 +76,8 @@ def get_plain_html_updates(self, request, course): # lint-amnesty, pylint: disa for older implementations and a few tests that store a single html object representing all the updates. """ - info_module = get_course_info_section_module(request, request.user, course, 'updates') - info_block = getattr(info_module, '_xmodule', info_module) - return info_block.system.service( + info_block = get_course_info_section_block(request, request.user, course, 'updates') + info_block = getattr(info_block, '_xmodule', info_block) + return info_block.runtime.service( info_block, "replace_urls" - ).replace_urls(info_module.data) if info_module else '' + ).replace_urls(info_block.data) if info_block else '' diff --git a/openedx/features/personalized_learner_schedules/show_answer/tests/test_show_answer_override.py b/openedx/features/personalized_learner_schedules/show_answer/tests/test_show_answer_override.py index 1d6fdf628268..0a0c03725545 100644 --- a/openedx/features/personalized_learner_schedules/show_answer/tests/test_show_answer_override.py +++ b/openedx/features/personalized_learner_schedules/show_answer/tests/test_show_answer_override.py @@ -8,7 +8,7 @@ from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides from lms.djangoapps.courseware.model_data import FieldDataCache -from lms.djangoapps.courseware.module_render import get_module +from lms.djangoapps.courseware.block_render import get_block from openedx.features.course_experience import RELATIVE_DATES_FLAG from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order @@ -33,7 +33,7 @@ def setup_course(self, **course_kwargs): def get_course_block(self, course): request = RequestFactory().request() field_data_cache = FieldDataCache([], course.id, self.user) - return get_module(self.user, request, course.location, field_data_cache, course=course) + return get_block(self.user, request, course.location, field_data_cache, course=course) @ddt.data(True, False) def test_override_enabled_for(self, active): diff --git a/openedx/tests/completion_integration/test_services.py b/openedx/tests/completion_integration/test_services.py index 9761d7bfe34b..d7bc197d952d 100644 --- a/openedx/tests/completion_integration/test_services.py +++ b/openedx/tests/completion_integration/test_services.py @@ -117,24 +117,24 @@ def setUp(self): completion=0.75, ) - def _bind_course_block(self, module): + def _bind_course_block(self, block): """ - Bind a module (part of self.course) so we can access student-specific data. + Bind a block (part of self.course) so we can access student-specific data. """ - module_system = get_test_system(course_id=module.location.course_key) - module_system.descriptor_runtime = module.runtime._descriptor_system # pylint: disable=protected-access + 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 - def get_module(descriptor): - """Mocks module_system get_module function""" - sub_module_system = get_test_system(course_id=module.location.course_key) - sub_module_system.get_module = get_module + 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) return descriptor - module_system.get_module = get_module - module.xmodule_runtime = module_system + module_system.get_block_for_descriptor = get_block + block.xmodule_runtime = module_system def test_completion_service(self): # Only the completions for the user and course specified for the CompletionService diff --git a/requirements/constraints.txt b/requirements/constraints.txt index c796ad340c26..7f844ad17a93 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -77,7 +77,3 @@ pyopenssl==22.0.0 cryptography==38.0.4 # greater version has some issues with openssl. bleach[css]==5.0.1 # greater version has some breaking changes. - -# This constraint can be removed in https://github.com/openedx/edx-platform/pull/31475, which changes the imports used -# by this XBlock. -lti-consumer-xblock<=7.2.3 diff --git a/requirements/edx/base.in b/requirements/edx/base.in index 9468118f7eee..d62171258504 100644 --- a/requirements/edx/base.in +++ b/requirements/edx/base.in @@ -114,7 +114,7 @@ jsonfield # Django model field for validated JSON; use laboratory # Library for testing that code refactors/infrastructure changes produce identical results lxml # XML parser learner-pathway-progress # A plugin for lms to track learners progress in pathays -lti-consumer-xblock>=7.2.2 +lti-consumer-xblock>=7.3.0 mailsnake # Needed for mailchimp (mailing djangoapp) mako # Primary template language used for server-side page rendering Markdown # Convert text markup to HTML; used in capa problems, forums, and course wikis diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 90b965f8fc49..ff51c8f8a629 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -665,10 +665,8 @@ libsass==0.10.0 # ora2 loremipsum==1.0.5 # via ora2 -lti-consumer-xblock==7.2.3 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/base.in +lti-consumer-xblock==7.3.0 + # via -r requirements/edx/base.in lxml==4.9.2 # via # -r requirements/edx/base.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 113f16ef96c1..968249f09759 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -891,10 +891,8 @@ loremipsum==1.0.5 # via # -r requirements/edx/testing.txt # ora2 -lti-consumer-xblock==7.2.3 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/testing.txt +lti-consumer-xblock==7.3.0 + # via -r requirements/edx/testing.txt lxml==4.9.2 # via # -r requirements/edx/testing.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 830993bcbe0e..52f0a5e0c5ec 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -849,10 +849,8 @@ loremipsum==1.0.5 # via # -r requirements/edx/base.txt # ora2 -lti-consumer-xblock==7.2.3 - # via - # -c requirements/edx/../constraints.txt - # -r requirements/edx/base.txt +lti-consumer-xblock==7.3.0 + # via -r requirements/edx/base.txt lxml==4.9.2 # via # -r requirements/edx/base.txt diff --git a/setup.cfg b/setup.cfg index 72a2d296e541..7b1be0be92e8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -66,7 +66,7 @@ ignore_imports = lms.djangoapps.courseware.plugins -> cms.djangoapps.contentstore.utils lms.djangoapps.course_home_api.tests.utils -> cms.djangoapps.contentstore.outlines # cms side imports that we are ignoring for now - cms.djangoapps.contentstore.views.tests.test_item -> lms.djangoapps.lms_xblock.mixin + cms.djangoapps.contentstore.views.tests.test_block -> lms.djangoapps.lms_xblock.mixin cms.envs.common -> lms.envs.common cms.djangoapps.contentstore.signals.handlers -> lms.djangoapps.grades.api cms.djangoapps.contentstore.course_group_config -> lms.lib.utils diff --git a/xmodule/capa/tests/helpers.py b/xmodule/capa/tests/helpers.py index ecb94d6283fc..c464e64e934e 100644 --- a/xmodule/capa/tests/helpers.py +++ b/xmodule/capa/tests/helpers.py @@ -89,7 +89,7 @@ def mock_capa_block(): """ def mock_location_text(self): # lint-amnesty, pylint: disable=unused-argument """ - Mock implementation of __unicode__ or __str__ for the module's location. + Mock implementation of __unicode__ or __str__ for the block's location. """ return 'i4x://Foo/bar/mock/abc' diff --git a/xmodule/capa/util.py b/xmodule/capa/util.py index 163a1c86ea30..66e7b12390ff 100644 --- a/xmodule/capa/util.py +++ b/xmodule/capa/util.py @@ -236,7 +236,7 @@ def get_course_id_from_capa_block(capa_block): capa_block (ProblemBlock|None) Returns: str|None - The stringified course run key of the module. + The stringified course run key of the block. If not available, fall back to None. """ if not capa_block: diff --git a/xmodule/capa_block.py b/xmodule/capa_block.py index 4cf6f80e537c..425e0d1c586a 100644 --- a/xmodule/capa_block.py +++ b/xmodule/capa_block.py @@ -399,7 +399,7 @@ def studio_view(self, _context): def handle_ajax(self, dispatch, data): """ - This is called by courseware.module_render, to handle an AJAX call. + This is called by courseware.block_render, to handle an AJAX call. `data` is request.POST. @@ -1286,7 +1286,7 @@ def get_problem_html(self, encapsulate=True, submit_notification=False): id=self.location.html_id(), ajax_url=self.ajax_url, html=HTML(html) ) - # Now do all the substitutions which the LMS module_render normally does, but + # Now do all the substitutions which the LMS block_render normally does, but # we need to do here explicitly since we can get called for our HTML via AJAX html = self.runtime.service(self, "replace_urls").replace_urls(html) diff --git a/xmodule/conditional_block.py b/xmodule/conditional_block.py index c7e47aeede34..5264db255e53 100644 --- a/xmodule/conditional_block.py +++ b/xmodule/conditional_block.py @@ -60,18 +60,18 @@ class ConditionalBlock( tag attributes: - sources - location id of required modules, separated by ';' + sources - location id of required blocks, separated by ';' - submitted - map to `is_submitted` module method. + submitted - map to `is_submitted` block method. (pressing RESET button makes this function to return False.) - attempted - map to `is_attempted` module method - correct - map to `is_correct` module method - poll_answer - map to `poll_answer` module attribute - voted - map to `voted` module attribute + attempted - map to `is_attempted` block method + correct - map to `is_correct` block method + poll_answer - map to `poll_answer` block attribute + voted - map to `voted` block attribute tag attributes: - sources - location id of required modules, separated by ';' + sources - location id of required blocks, separated by ';' You can add you own rules for tag, like "completed", "attempted" etc. To do that yo must extend @@ -83,7 +83,7 @@ class ConditionalBlock( ... - And my_property/my_method will be called for required modules. + And my_property/my_method will be called for required blocks. """ @@ -170,7 +170,7 @@ class ConditionalBlock( # Map # key: - # value: + # value: conditions_map = { 'poll_answer': 'poll_answer', # poll_question attr @@ -210,20 +210,20 @@ def is_condition_satisfied(self): # lint-amnesty, pylint: disable=missing-funct attr_name = self.conditions_map[self.conditional_attr] if self.conditional_value and self.get_required_blocks: - for module in self.get_required_blocks: - if not hasattr(module, attr_name): + for block in self.get_required_blocks: + if not hasattr(block, attr_name): # We don't throw an exception here because it is possible for - # the descriptor of a required module to have a property but + # the descriptor of a required block to have a property but # for the resulting module to be a (flavor of) ErrorBlock. # So just log and return false. - if module is not None: - # We do not want to log when module is None, and it is when requester - # does not have access to the requested required module. + if block is not None: + # We do not want to log when block is None, and it is when requester + # does not have access to the requested required block. log.warning('Error in conditional block: \ - required module {module} has no {module_attr}'.format(module=module, module_attr=attr_name)) + required module {block} has no {block_attr}'.format(block=block, block_attr=attr_name)) return False - attr = getattr(module, attr_name) + attr = getattr(block, attr_name) if callable(attr): attr = attr() @@ -278,7 +278,7 @@ def studio_view(self, _context): return fragment def handle_ajax(self, _dispatch, _data): - """This is called by courseware.moduleodule_render, to handle + """This is called by courseware.block_render, to handle an AJAX call. """ if not self.is_condition_satisfied(): @@ -317,9 +317,11 @@ def get_required_blocks(self): """ Returns a list of bound XBlocks instances upon which XBlock depends. """ - return [self.system.get_module(descriptor) for descriptor in self.get_required_module_descriptors()] + return [ + self.runtime.get_block_for_descriptor(descriptor) for descriptor in self.get_required_block_descriptors() + ] - def get_required_module_descriptors(self): + def get_required_block_descriptors(self): """ Returns a list of unbound XBlocks instances upon which this XBlock depends. """ @@ -331,7 +333,7 @@ def get_required_module_descriptors(self): except ItemNotFoundError: msg = "Invalid module by location." log.exception(msg) - self.system.error_tracker(msg) + self.runtime.error_tracker(msg) return descriptors diff --git a/xmodule/course_block.py b/xmodule/course_block.py index 668ae59897e6..27b5cabd4464 100644 --- a/xmodule/course_block.py +++ b/xmodule/course_block.py @@ -314,7 +314,7 @@ class CourseFields: # lint-amnesty, pylint: disable=missing-class-docstring enrollment_start = Date(help=_("Date that enrollment for this class is opened"), scope=Scope.settings) enrollment_end = Date(help=_("Date that enrollment for this class is closed"), scope=Scope.settings) start = Date( - help=_("Start time when this module is visible"), + help=_("Start time when this block is visible"), default=DEFAULT_START_DATE, scope=Scope.settings ) @@ -795,7 +795,7 @@ class CourseFields: # lint-amnesty, pylint: disable=missing-class-docstring entrance_exam_id = String( display_name=_("Entrance Exam ID"), - help=_("Content module identifier (location) of entrance exam."), + help=_("Content block identifier (location) of entrance exam."), default=None, scope=Scope.settings, ) @@ -1056,10 +1056,10 @@ def __init__(self, *args, **kwargs): # NOTE (THK): This is a last-minute addition for Fall 2012 launch to dynamically # disable the syllabus content for courses that do not provide a syllabus - if self.system.resources_fs is None: + if self.runtime.resources_fs is None: self.syllabus_present = False else: - self.syllabus_present = self.system.resources_fs.exists(path('syllabus')) + self.syllabus_present = self.runtime.resources_fs.exists(path('syllabus')) self._grading_policy = {} self.set_grading_policy(self.grading_policy) diff --git a/xmodule/error_block.py b/xmodule/error_block.py index d74cb5930448..10a9300bddab 100644 --- a/xmodule/error_block.py +++ b/xmodule/error_block.py @@ -1,6 +1,6 @@ """ -Modules that get shown to the users when an error has occurred while -loading or rendering other modules +Block that get shown to the users when an error has occurred while +loading or rendering other blocks """ @@ -27,11 +27,11 @@ log = logging.getLogger(__name__) # NOTE: This is not the most beautiful design in the world, but there's no good -# way to tell if the module is being used in a staff context or not. Errors that get discovered +# way to tell if the block is being used in a staff context or not. Errors that get discovered # at course load time are turned into ErrorBlock objects, and automatically hidden from students. -# Unfortunately, we can also have errors when loading modules mid-request, and then we need to decide -# what to show, and the logic for that belongs in the LMS (e.g. in get_module), so the error handler -# decides whether to create a staff or not-staff module. +# Unfortunately, we can also have errors when loading blocks mid-request, and then we need to decide +# what to show, and the logic for that belongs in the LMS (e.g. in get_block), so the error handler +# decides whether to create a staff or not-staff block. class ErrorFields: @@ -52,8 +52,8 @@ class ErrorBlock( XModuleMixin, ): # pylint: disable=abstract-method """ - Module that gets shown to staff when there has been an error while - loading or rendering other modules + Block that gets shown to staff when there has been an error while + loading or rendering other blocks """ resources_dir = None @@ -99,7 +99,7 @@ def _construct(cls, system, contents, error_msg, location, for_parent=None): # Pick a unique url_name -- the sha1 hash of the contents. # NOTE: We could try to pull out the url_name of the errored descriptor, # but url_names aren't guaranteed to be unique between descriptor types, - # and ErrorBlock can wrap any type. When the wrapped module is fixed, + # and ErrorBlock can wrap any type. When the wrapped block is fixed, # it will be written out with the original url_name. name=hashlib.sha1(contents.encode('utf8')).hexdigest() ) diff --git a/xmodule/graders.py b/xmodule/graders.py index bd90dab394a1..a587204d682e 100644 --- a/xmodule/graders.py +++ b/xmodule/graders.py @@ -29,10 +29,10 @@ def __init__(self, graded, first_attempted): """ Fields common to all scores include: - :param graded: Whether or not this module is graded + :param graded: Whether or not this block is graded :type graded: bool - :param first_attempted: When the module was first attempted, or None + :param first_attempted: When the block was first attempted, or None :type first_attempted: datetime|None """ self.graded = graded diff --git a/xmodule/html_block.py b/xmodule/html_block.py index 2c3e24d37ed8..e6b42465d364 100644 --- a/xmodule/html_block.py +++ b/xmodule/html_block.py @@ -60,7 +60,7 @@ class HtmlBlockMixin( # lint-amnesty, pylint: disable=abstract-method # use display_name_with_default for those default=_("Text") ) - data = String(help=_("Html contents to display for this module"), default="", scope=Scope.content) + data = String(help=_("Html contents to display for this block"), default="", scope=Scope.content) source_code = String( help=_("Source code for LaTeX documents. This feature is not well-supported."), scope=Scope.settings @@ -389,7 +389,7 @@ class AboutFields: # lint-amnesty, pylint: disable=missing-class-docstring default="overview", ) data = String( - help=_("Html contents to display for this module"), + help=_("Html contents to display for this block"), default="", scope=Scope.content ) @@ -449,7 +449,7 @@ class CourseInfoFields: scope=Scope.content ) data = String( - help=_("Html contents to display for this module"), + help=_("Html contents to display for this block"), default="
        ", scope=Scope.content ) diff --git a/xmodule/library_root_xblock.py b/xmodule/library_root_xblock.py index 97ec88aed600..70fb993ba9e7 100644 --- a/xmodule/library_root_xblock.py +++ b/xmodule/library_root_xblock.py @@ -60,7 +60,7 @@ def author_view(self, context): def render_children(self, context, fragment, can_reorder=False, can_add=False): # pylint: disable=unused-argument """ - Renders the children of the module with HTML appropriate for Studio. Reordering is not supported. + Renders the children of the block with HTML appropriate for Studio. Reordering is not supported. """ contents = [] diff --git a/xmodule/lti_2_util.py b/xmodule/lti_2_util.py index 93faa807c7b5..11eba5ee6de7 100644 --- a/xmodule/lti_2_util.py +++ b/xmodule/lti_2_util.py @@ -220,7 +220,7 @@ def _lti_2_0_result_put_handler(self, request, real_user): self.clear_user_module_score(real_user) return Response(status=200) - # Fall-through record the score and the comment in the module + # Fall-through record the score and the comment in the block self.set_user_module_score(real_user, score, self.max_score(), comment) return Response(status=200) diff --git a/xmodule/lti_block.py b/xmodule/lti_block.py index 795db6c64e97..8bf60f1c4486 100644 --- a/xmodule/lti_block.py +++ b/xmodule/lti_block.py @@ -744,7 +744,7 @@ def oauth_params(self, custom_parameters, client_key, client_secret): @XBlock.handler def grade_handler(self, request, suffix): # lint-amnesty, pylint: disable=unused-argument """ - This is called by courseware.module_render, to handle an AJAX call. + This is called by courseware.block_render, to handle an AJAX call. Used only for grading. Returns XML response. diff --git a/xmodule/mako_block.py b/xmodule/mako_block.py index 83572097fa83..017b277e032c 100644 --- a/xmodule/mako_block.py +++ b/xmodule/mako_block.py @@ -32,7 +32,7 @@ def __init__(self, render_template, **kwargs): class MakoTemplateBlockBase: """ XBlock intended as a mixin that uses a mako template - to specify the module html. + to specify the block html. Expects the descriptor to have the `mako_template` attribute set with the name of the template to render, and it will pass @@ -67,7 +67,7 @@ def studio_view(self, context): # pylint: disable=unused-argument """ # pylint: disable=no-member fragment = Fragment( - self.system.render_template(self.mako_template, self.get_context()) + self.runtime.render_template(self.mako_template, self.get_context()) ) shim_xmodule_js(fragment, self.js_module_name) return fragment diff --git a/xmodule/modulestore/__init__.py b/xmodule/modulestore/__init__.py index 4b2634484a3e..d02d62e1420c 100644 --- a/xmodule/modulestore/__init__.py +++ b/xmodule/modulestore/__init__.py @@ -784,7 +784,7 @@ def get_item(self, usage_key, depth=0, using_descriptor_system=None, **kwargs): usage_key: A :class:`.UsageKey` subclass instance depth (int): An argument that some module stores may use to prefetch - descendents of the queried modules for more efficient results later + descendents of the queried blocks for more efficient results later in the request. The depth is counted in the number of calls to get_children() to cache. None indicates to cache all descendents """ @@ -1283,7 +1283,7 @@ def create_course(self, org, course, run, user_id, fields=None, runtime=None, ** Creates any necessary other things for the course as a side effect and doesn't return anything useful. The real subclass should call this before it returns the course. """ - # clone a default 'about' overview module as well + # clone a default 'about' overview block as well about_location = self.make_course_key(org, course, run).make_usage_key('about', 'overview') about_descriptor = XBlock.load_class('about') diff --git a/xmodule/modulestore/django.py b/xmodule/modulestore/django.py index ead24e6792cb..917aa3d6c93b 100644 --- a/xmodule/modulestore/django.py +++ b/xmodule/modulestore/django.py @@ -308,7 +308,7 @@ def fetch_disabled_xblock_types(): xblock_field_data_wrappers=xblock_field_data_wrappers, disabled_xblock_types=fetch_disabled_xblock_types, doc_store_config=doc_store_config, - i18n_service=i18n_service or ModuleI18nService, + i18n_service=i18n_service or XBlockI18nService, fs_service=fs_service or xblock.reference.plugins.FSService(), user_service=user_service or xb_user_service, signal_handler=signal_handler or SignalHandler(class_), @@ -356,7 +356,7 @@ def clear_existing_modulestores(): _MIXED_MODULESTORE = None -class ModuleI18nService: +class XBlockI18nService: """ Implement the XBlock runtime "i18n" service. diff --git a/xmodule/modulestore/inheritance.py b/xmodule/modulestore/inheritance.py index 315ce6e509dd..e75b9ab083c4 100644 --- a/xmodule/modulestore/inheritance.py +++ b/xmodule/modulestore/inheritance.py @@ -32,12 +32,12 @@ class InheritanceMixin(XBlockMixin): """Field definitions for inheritable fields.""" graded = Boolean( - help="Whether this module contributes to the final course grade", + help="Whether this block contributes to the final course grade", scope=Scope.settings, default=False, ) start = Date( - help="Start time when this module is visible", + help="Start time when this block is visible", default=DEFAULT_START_DATE, scope=Scope.settings ) @@ -220,8 +220,8 @@ class InheritanceMixin(XBlockMixin): ) in_entrance_exam = Boolean( - display_name=_("Tag this module as part of an Entrance Exam section"), - help=_("Enter true or false. If true, answer submissions for problem modules will be " + display_name=_("Tag this block as part of an Entrance Exam section"), + help=_("Enter true or false. If true, answer submissions for problem blocks will be " "considered in the Entrance Exam scoring/gating algorithm."), scope=Scope.settings, default=False @@ -294,7 +294,7 @@ def compute_inherited_metadata(descriptor): def inherit_metadata(descriptor, inherited_data): """ - Updates this module with metadata inherited from a containing module. + Updates this block with metadata inherited from a containing block. Only metadata specified in self.inheritable_metadata will be inherited @@ -307,12 +307,12 @@ def inherit_metadata(descriptor, inherited_data): pass -def own_metadata(module): +def own_metadata(block): """ Return a JSON-friendly dictionary that contains only non-inherited field keys, mapped to their serialized values """ - return module.get_explicitly_set_fields_by_scope(Scope.settings) + return block.get_explicitly_set_fields_by_scope(Scope.settings) class InheritingFieldData(KvsFieldData): diff --git a/xmodule/modulestore/mixed.py b/xmodule/modulestore/mixed.py index 57a36b204dcd..58c58e32f34d 100644 --- a/xmodule/modulestore/mixed.py +++ b/xmodule/modulestore/mixed.py @@ -852,7 +852,7 @@ def _drop_database(self, database=True, collections=True, connections=True): @strip_key def create_xblock(self, runtime, course_key, block_type, block_id=None, fields=None, **kwargs): """ - Create the new xmodule but don't save it. Returns the new module. + Create the new xblock but don't save it. Returns the new block. Args: runtime: :py:class `xblock.runtime` from another xblock in the same course. Providing this diff --git a/xmodule/modulestore/mongo/base.py b/xmodule/modulestore/mongo/base.py index 93e09dda3cbd..39532a82012f 100644 --- a/xmodule/modulestore/mongo/base.py +++ b/xmodule/modulestore/mongo/base.py @@ -167,7 +167,7 @@ def __repr__(self): class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # lint-amnesty, pylint: disable=abstract-method """ - A system that has a cache of module json that it will use to load modules + A system that has a cache of block json that it will use to load blocks from, with a backup of calling to the underlying modulestore for more data """ def __repr__(self): @@ -180,7 +180,7 @@ def __repr__(self): def __init__(self, modulestore, course_key, module_data, default_class, **kwargs): """ - modulestore: the module store that can be used to retrieve additional modules + modulestore: the module store that can be used to retrieve additional blocks course_key: the course for which everything in this runtime will be relative @@ -214,7 +214,7 @@ def __init__(self, modulestore, course_key, module_data, default_class, **kwargs def load_item(self, location, for_parent=None): # lint-amnesty, pylint: disable=method-hidden """ - Return an XModule instance for the specified location + Return an XBlock instance for the specified location """ assert isinstance(location, UsageKey) @@ -227,10 +227,10 @@ def load_item(self, location, for_parent=None): # lint-amnesty, pylint: disable json_data = self.module_data.get(location) if json_data is None: - module = self.modulestore.get_item(location, using_descriptor_system=self) - return module + block = self.modulestore.get_item(location, using_descriptor_system=self) + return block else: - # load the module and apply the inherited metadata + # load the block and apply the inherited metadata try: category = json_data['location']['category'] class_ = self.load_block_type(category) @@ -269,31 +269,31 @@ def load_item(self, location, for_parent=None): # lint-amnesty, pylint: disable field_data = KvsFieldData(kvs) scope_ids = ScopeIds(None, category, location, location) - module = self.construct_xblock_from_class(class_, scope_ids, field_data, for_parent=for_parent) + block = self.construct_xblock_from_class(class_, scope_ids, field_data, for_parent=for_parent) non_draft_loc = as_published(location) metadata_inheritance_tree = self.modulestore._compute_metadata_inheritance_tree(self.course_id) - inherit_metadata(module, metadata_inheritance_tree.get(str(non_draft_loc), {})) + inherit_metadata(block, metadata_inheritance_tree.get(str(non_draft_loc), {})) - module._edit_info = json_data.get('edit_info') + block._edit_info = json_data.get('edit_info') # migrate published_by and published_on if edit_info isn't present - if module._edit_info is None: - module._edit_info = {} + if block._edit_info is None: + block._edit_info = {} raw_metadata = json_data.get('metadata', {}) # published_on was previously stored as a list of time components instead of a datetime if raw_metadata.get('published_date'): - module._edit_info['published_date'] = datetime( + block._edit_info['published_date'] = datetime( *raw_metadata.get('published_date')[0:6] ).replace(tzinfo=UTC) - module._edit_info['published_by'] = raw_metadata.get('published_by') + block._edit_info['published_by'] = raw_metadata.get('published_by') for wrapper in self.modulestore.xblock_field_data_wrappers: - module._field_data = wrapper(module, module._field_data) # pylint: disable=protected-access + block._field_data = wrapper(block, block._field_data) # pylint: disable=protected-access # decache any computed pending field settings - module.save() - return module + block.save() + return block except Exception: # pylint: disable=broad-except log.warning("Failed to load descriptor from %s", json_data, exc_info=True) return ErrorBlock.from_json( @@ -835,7 +835,7 @@ def _load_item(self, course_key, item, data_cache, def _load_items(self, course_key, items, depth=0, using_descriptor_system=None, for_parent=None): """ - Load a list of xmodules from the data in items, with children cached up + Load a list of xblocks from the data in items, with children cached up to specified depth """ course_key = self.fill_in_run(course_key) @@ -1041,21 +1041,21 @@ def get_item(self, usage_key, depth=0, using_descriptor_system=None, for_parent= Arguments: usage_key: a :class:`.UsageKey` instance depth (int): An argument that some module stores may use to prefetch - descendents of the queried modules for more efficient results later + descendents of the queried blocks for more efficient results later in the request. The depth is counted in the number of calls to get_children() to cache. None indicates to cache all descendents. using_descriptor_system (CachingDescriptorSystem): The existing CachingDescriptorSystem to add data to, and to load the XBlocks from. """ item = self._find_one(usage_key) - module = self._load_items( + block = self._load_items( usage_key.course_key, [item], depth, using_descriptor_system=using_descriptor_system, for_parent=for_parent, )[0] - return module + return block @staticmethod def _course_key_to_son(course_id, tag='i4x'): @@ -1144,12 +1144,12 @@ def get_items( # lint-amnesty, pylint: disable=arguments-differ sort=[SORT_REVISION_FAVOR_DRAFT], ) - modules = self._load_items( + blocks = self._load_items( course_id, list(items), using_descriptor_system=using_descriptor_system ) - return modules + return blocks def create_course(self, org, course, run, user_id, fields=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ """ @@ -1199,10 +1199,10 @@ def create_xblock( metadata=None, definition_data=None, **kwargs ): """ - Create the new xblock but don't save it. Returns the new module. + Create the new xblock but don't save it. Returns the new block. :param runtime: if you already have an xblock from the course, the xblock.runtime value - :param fields: a dictionary of field names and values for the new xmodule + :param fields: a dictionary of field names and values for the new xblock """ if metadata is None: metadata = {} @@ -1245,7 +1245,7 @@ def create_xblock( xblock_class = runtime.load_block_type(block_type) location = course_key.make_usage_key(block_type, block_id) dbmodel = self._create_new_field_data(block_type, location, definition_data, metadata) - xmodule = runtime.construct_xblock_from_class( + xblock = runtime.construct_xblock_from_class( xblock_class, # We're loading a descriptor, so student_id is meaningless # We also don't have separate notions of definition and usage ids yet, @@ -1256,10 +1256,10 @@ def create_xblock( ) if fields is not None: for key, value in fields.items(): - setattr(xmodule, key, value) + setattr(xblock, key, value) # decache any pending field settings from init - xmodule.save() - return xmodule + xblock.save() + return xblock def create_item(self, user_id, course_key, block_type, block_id=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ """ @@ -1268,7 +1268,7 @@ def create_item(self, user_id, course_key, block_type, block_id=None, **kwargs): Returns the newly created item. Args: - user_id: ID of the user creating and saving the xmodule + user_id: ID of the user creating and saving the xblock course_key: A :class:`~opaque_keys.edx.CourseKey` identifying which course to create this item in block_type: The typo of block to create @@ -1294,7 +1294,7 @@ def create_child(self, user_id, parent_usage_key, block_type, block_id=None, **k Returns the newly created item. Args: - user_id: ID of the user creating and saving the xmodule + user_id: ID of the user creating and saving the xblock parent_usage_key: a :class:`~opaque_key.edx.UsageKey` identifing the block that this item should be parented under block_type: The typo of block to create @@ -1332,8 +1332,8 @@ def import_xblock(self, user_id, course_key, block_type, block_id, fields=None, def _get_course_for_item(self, location, depth=0): ''' - for a given Xmodule, return the course that it belongs to - Also we have to assert that this module maps to only one course item - it'll throw an + for a given XBlock, return the course that it belongs to + Also we have to assert that this block maps to only one course item - it'll throw an assert if not ''' return self.get_course(location.course_key, depth) @@ -1631,7 +1631,7 @@ def get_courses_for_wiki(self, wiki_slug, **kwargs): def _create_new_field_data(self, _category, _location, definition_data, metadata): """ - To instantiate a new xmodule which will be saved later, set up the dbModel and kvs + To instantiate a new xblock which will be saved later, set up the dbModel and kvs """ kvs = MongoKeyValueStore( definition_data, diff --git a/xmodule/modulestore/mongo/draft.py b/xmodule/modulestore/mongo/draft.py index 2caca673fbf3..60eebdd31bb2 100644 --- a/xmodule/modulestore/mongo/draft.py +++ b/xmodule/modulestore/mongo/draft.py @@ -1,6 +1,6 @@ """ -A ModuleStore that knows about a special version DRAFT. Modules -marked as DRAFT are read in preference to modules without the DRAFT +A ModuleStore that knows about a special version DRAFT. Blocks +marked as DRAFT are read in preference to blocks without the DRAFT version by this ModuleStore (so, access to i4x://org/course/cat/name returns the i4x://org/course/cat/name@draft object if that exists, and otherwise returns i4x://org/course/cat/name). @@ -55,8 +55,8 @@ class DraftModuleStore(MongoModuleStore): Reads are first read with revision DRAFT, and then fall back to the baseline revision only if DRAFT doesn't exist. - This module also includes functionality to promote DRAFT modules (and their children) - to published modules. + This module store also includes functionality to promote DRAFT blocks (and their children) + to published blocks. """ def get_item(self, usage_key, depth=0, revision=None, using_descriptor_system=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ """ @@ -66,7 +66,7 @@ def get_item(self, usage_key, depth=0, revision=None, using_descriptor_system=No usage_key: A :class:`.UsageKey` instance depth (int): An argument that some module stores may use to prefetch - descendants of the queried modules for more efficient results later + descendants of the queried blocks for more efficient results later in the request. The depth is counted in the number of calls to get_children() to cache. None indicates to cache all descendants. @@ -219,42 +219,42 @@ def clone_course(self, source_course_id, dest_course_id, user_id, fields=None, * setattr(new_course, key, value) self.update_item(new_course, user_id) - # Get all modules under this namespace which is (tag, org, course) tuple - modules = self.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.published_only) - self._clone_modules(modules, dest_course_id, user_id) + # Get all blocks under this namespace which is (tag, org, course) tuple + blocks = self.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.published_only) + self._clone_blocks(blocks, dest_course_id, user_id) course_location = dest_course_id.make_usage_key('course', dest_course_id.run) self.publish(course_location, user_id) - modules = self.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.draft_only) - self._clone_modules(modules, dest_course_id, user_id) + blocks = self.get_items(source_course_id, revision=ModuleStoreEnum.RevisionOption.draft_only) + self._clone_blocks(blocks, dest_course_id, user_id) return True - def _clone_modules(self, modules, dest_course_id, user_id): - """Clones each module into the given course""" - for module in modules: - original_loc = module.location - module.location = module.location.map_into_course(dest_course_id) - if module.location.block_type == 'course': - module.location = module.location.replace(name=module.location.run) + def _clone_blocks(self, blocks, dest_course_id, user_id): + """Clones each block into the given course""" + for block in blocks: + original_loc = block.location + block.location = block.location.map_into_course(dest_course_id) + if block.location.block_type == 'course': + block.location = block.location.replace(name=block.location.run) - log.info("Cloning module %s to %s....", original_loc, module.location) + log.info("Cloning block %s to %s....", original_loc, block.location) - if 'data' in module.fields and module.fields['data'].is_set_on(module) and isinstance(module.data, str): # lint-amnesty, pylint: disable=line-too-long - module.data = rewrite_nonportable_content_links( - original_loc.course_key, dest_course_id, module.data + if 'data' in block.fields and block.fields['data'].is_set_on(block) and isinstance(block.data, str): # lint-amnesty, pylint: disable=line-too-long + block.data = rewrite_nonportable_content_links( + original_loc.course_key, dest_course_id, block.data ) # repoint children - if module.has_children: + if block.has_children: new_children = [] - for child_loc in module.children: + for child_loc in block.children: child_loc = child_loc.map_into_course(dest_course_id) new_children.append(child_loc) - module.children = new_children + block.children = new_children - self.update_item(module, user_id, allow_not_found=True) + self.update_item(block, user_id, allow_not_found=True) def _get_raw_parent_locations(self, location, key_revision): """ @@ -321,8 +321,8 @@ def get_parent_location(self, location, revision=None, **kwargs): def create_xblock(self, runtime, course_key, block_type, block_id=None, fields=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ """ - Create the new xmodule but don't save it. Returns the new module with a draft locator if - the category allows drafts. If the category does not allow drafts, just creates a published module. + Create the new xblock but don't save it. Returns the new block with a draft locator if + the category allows drafts. If the category does not allow drafts, just creates a published block. :param location: a Location--must have a category :param definition_data: can be empty. The initial definition_data for the kvs @@ -596,16 +596,16 @@ def _delete_item(current_entry, to_be_deleted): child_loc = UsageKey.from_string(child_loc).map_into_course(course_key) # single parent can have 2 versions: draft and published - # get draft parents only while deleting draft module + # get draft parents only while deleting draft block if draft_only: revision = MongoRevisionKey.draft else: revision = ModuleStoreEnum.RevisionOption.all parents = self._get_raw_parent_locations(child_loc, revision) - # Don't delete modules if one of its parents shouldn't be deleted + # Don't delete blocks if one of its parents shouldn't be deleted # This should only be an issue for courses have ended up in - # a state where modules have multiple parents + # a state where blocks have multiple parents if all(parent.to_deprecated_son() in to_be_deleted for parent in parents): for rev_func in as_functions: current_loc = rev_func(child_loc) diff --git a/xmodule/modulestore/search.py b/xmodule/modulestore/search.py index 136568eadab5..60317039821a 100644 --- a/xmodule/modulestore/search.py +++ b/xmodule/modulestore/search.py @@ -16,7 +16,7 @@ def path_to_location(modulestore, usage_key, request=None, full_path=False): ''' Try to find a course_id/chapter/section[/position] path to location in modulestore. The courseware insists that the first level in the course is - chapter, but any kind of module can be a "section". + chapter, but any kind of block can be a "section". Args: modulestore: which store holds the relevant objects @@ -101,12 +101,12 @@ def find_path_to_course(): # Figure out the position position = None - # This block of code will find the position of a module within a nested tree - # of modules. If a problem is on tab 2 of a sequence that's on tab 3 of a - # sequence, the resulting position is 3_2. However, no positional modules + # This block of code will find the position of a block within a nested tree + # of blocks. If a problem is on tab 2 of a sequence that's on tab 3 of a + # sequence, the resulting position is 3_2. However, no positional blocks # (e.g. sequential) currently deal with this form of representing nested - # positions. This needs to happen before jumping to a module nested in more - # than one positional module will work. + # positions. This needs to happen before jumping to a block nested in more + # than one positional block will work. if n > 3: position_list = [] diff --git a/xmodule/modulestore/split_mongo/caching_descriptor_system.py b/xmodule/modulestore/split_mongo/caching_descriptor_system.py index 55aa112f5b3b..5cb0bb35714f 100644 --- a/xmodule/modulestore/split_mongo/caching_descriptor_system.py +++ b/xmodule/modulestore/split_mongo/caching_descriptor_system.py @@ -28,7 +28,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin): # lint-amnesty, pylint: disable=abstract-method """ - A system that has a cache of a course version's json that it will use to load modules + A system that has a cache of a course version's json that it will use to load blocks from, with a backup of calling to the underlying modulestore for more data. Computes the settings (nee 'metadata') inheritance upon creation. @@ -37,8 +37,7 @@ def __init__(self, modulestore, course_entry, default_class, module_data, lazy, """ Computes the settings inheritance and sets up the cache. - modulestore: the module store that can be used to retrieve additional - modules + modulestore: the module store that can be used to retrieve additional blocks course_entry: the originally fetched enveloped course_structure w/ branch and course id info. Callers to _load_item provide an override but that function ignores the provided structure and @@ -112,9 +111,9 @@ def _load_item(self, usage_key, course_entry_override=None, **kwargs): version_guid = course_key.version_guid # look in cache - cached_module = self.modulestore.get_cached_block(course_key, version_guid, block_key) - if cached_module: - return cached_module + cached_block = self.modulestore.get_cached_block(course_key, version_guid, block_key) + if cached_block: + return cached_block block_data = self.get_module_data(block_key, course_key) @@ -234,7 +233,7 @@ def xblock_from_json(self, class_, course_key, block_key, block_data, course_ent else: field_data = KvsFieldData(kvs) - module = self.construct_xblock_from_class( + block = self.construct_xblock_from_class( class_, ScopeIds(None, block_key.type, definition_id, block_locator), field_data, @@ -253,24 +252,24 @@ def xblock_from_json(self, class_, course_key, block_key, block_data, course_ent ) edit_info = block_data.edit_info - module._edited_by = edit_info.edited_by # pylint: disable=protected-access - module._edited_on = edit_info.edited_on # pylint: disable=protected-access - module.previous_version = edit_info.previous_version - module.update_version = edit_info.update_version - module.source_version = edit_info.source_version - module.definition_locator = DefinitionLocator(block_key.type, definition_id) + block._edited_by = edit_info.edited_by # pylint: disable=protected-access + block._edited_on = edit_info.edited_on # pylint: disable=protected-access + block.previous_version = edit_info.previous_version + block.update_version = edit_info.update_version + block.source_version = edit_info.source_version + block.definition_locator = DefinitionLocator(block_key.type, definition_id) for wrapper in self.modulestore.xblock_field_data_wrappers: - module._field_data = wrapper(module, module._field_data) # pylint: disable=protected-access + block._field_data = wrapper(block, block._field_data) # pylint: disable=protected-access # decache any pending field settings - module.save() + block.save() # If this is an in-memory block, store it in this system if isinstance(block_locator.block_id, LocalId): - self.local_modules[block_locator] = module + self.local_modules[block_locator] = block - return module + return block def get_edited_by(self, xblock): """ diff --git a/xmodule/modulestore/split_mongo/split.py b/xmodule/modulestore/split_mongo/split.py index 4f814986c06c..8e7999ae75bc 100644 --- a/xmodule/modulestore/split_mongo/split.py +++ b/xmodule/modulestore/split_mongo/split.py @@ -1,5 +1,5 @@ """ -Provides full versioning CRUD and representation for collections of xblocks (e.g., courses, modules, etc). +Provides full versioning CRUD and representation for collections of xblocks (e.g., courses, blocks, etc). Representation: * course_index: a dictionary: @@ -140,7 +140,7 @@ def __init__(self): self.index = None self.structures = {} self.structures_in_db = set() - # dict(version_guid, dict(BlockKey, module)) + # dict(version_guid, dict(BlockKey, block)) self.modules = defaultdict(dict) self.definitions = {} self.definitions_in_db = set() @@ -363,7 +363,7 @@ def update_structure(self, course_key, structure): def get_cached_block(self, course_key, version_guid, block_id): """ - If there's an active bulk_operation, see if it's cached this module and just return it + If there's an active bulk_operation, see if it's cached this block and just return it Don't do any extra work to get the ones which are not cached. Make the caller do the work & cache them. """ bulk_write_record = self._get_bulk_ops_record(course_key) @@ -723,13 +723,13 @@ def cache_items(self, system, base_block_ids, course_key, depth=0, lazy=True): lazy: whether to load definitions now or later """ with self.bulk_operations(course_key, emit_signals=False): - new_module_data = {} + new_block_data = {} for block_id in base_block_ids: - new_module_data = self.descendants( + new_block_data = self.descendants( system.course_entry.structure['blocks'], block_id, depth, - new_module_data + new_block_data ) # This method supports lazy loading, where the descendent definitions aren't loaded @@ -740,21 +740,21 @@ def cache_items(self, system, base_block_ids, course_key, depth=0, lazy=True): course_key, [ block.definition - for block in new_module_data.values() + for block in new_block_data.values() ] ) # Turn definitions into a map. definitions = {definition['_id']: definition for definition in descendent_definitions} - for block in new_module_data.values(): + for block in new_block_data.values(): if block.definition in definitions: definition = definitions[block.definition] # convert_fields gets done later in the runtime's xblock_from_json block.fields.update(definition.get('fields')) block.definition_loaded = True - system.module_data.update(new_module_data) + system.module_data.update(new_block_data) return system.module_data def _load_items(self, course_entry, block_keys, depth=0, **kwargs): @@ -1168,7 +1168,7 @@ def has_item(self, usage_key): def get_item(self, usage_key, depth=0, **kwargs): # lint-amnesty, pylint: disable=arguments-differ """ depth (int): An argument that some module stores may use to prefetch - descendants of the queried modules for more efficient results later + descendants of the queried blocks for more efficient results later in the request. The depth is counted in the number of calls to get_children() to cache. None indicates to cache all descendants. @@ -1311,8 +1311,8 @@ def has_path_to_root(self, block_key, course, path_cache=None, parents_cache=Non :param block_key: BlockKey of the component whose path is to be checked :param course: actual db json of course from structures - :param path_cache: a dictionary that records which modules have a path to the root so that we don't have to - double count modules if we're computing this for a list of modules in a course. + :param path_cache: a dictionary that records which blocks have a path to the root so that we don't have to + double count blocks if we're computing this for a list of blocks in a course. :param parents_cache: a dictionary containing mapping of block_key to list of its parents. Optionally, this should be built for course structure to make this method faster. @@ -1700,7 +1700,7 @@ def create_child(self, user_id, parent_usage_key, block_type, block_id=None, fie Returns the newly created item. Args: - user_id: ID of the user creating and saving the xmodule + user_id: ID of the user creating and saving the xblock parent_usage_key: a :class:`~opaque_key.edx.UsageKey` identifying the block that this item should be parented under block_type: The typo of block to create @@ -2080,7 +2080,7 @@ def create_xblock( parent_xblock is used to compute inherited metadata as well as to append the new xblock. json_data: - - 'block_type': the xmodule block_type + - 'block_type': the xblock block_type - 'fields': a dict of locally set fields (not inherited) in json format not pythonic typed format! - 'definition': the object id of the existing definition """ @@ -2191,7 +2191,7 @@ def _persist_subdag(self, course_key, xblock, user_id, structure_blocks, new_id) if xblock.has_children: for child in xblock.children: if isinstance(child.block_id, LocalId): - child_block = xblock.system.get_block(child) + child_block = xblock.runtime.get_block(child) is_updated = self._persist_subdag(course_key, child_block, user_id, structure_blocks, new_id) or is_updated # lint-amnesty, pylint: disable=line-too-long children.append(BlockKey.from_usage_key(child_block.location)) else: diff --git a/xmodule/modulestore/store_utilities.py b/xmodule/modulestore/store_utilities.py index da71999c0104..45082ff43e75 100644 --- a/xmodule/modulestore/store_utilities.py +++ b/xmodule/modulestore/store_utilities.py @@ -79,12 +79,12 @@ def portable_jump_to_link_substitution(match): return text -def draft_node_constructor(module, url, parent_url, location=None, parent_location=None, index=None): +def draft_node_constructor(block, url, parent_url, location=None, parent_location=None, index=None): """ Contructs a draft_node namedtuple with defaults. """ draft_node = namedtuple('draft_node', ['module', 'location', 'url', 'parent_location', 'parent_url', 'index']) - return draft_node(module, location, url, parent_location, parent_url, index) + return draft_node(block, location, url, parent_location, parent_url, index) def get_draft_subtree_roots(draft_nodes): diff --git a/xmodule/modulestore/tests/factories.py b/xmodule/modulestore/tests/factories.py index bc6bf6ad9649..b740b10e053f 100644 --- a/xmodule/modulestore/tests/factories.py +++ b/xmodule/modulestore/tests/factories.py @@ -330,7 +330,7 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum """ Uses ``**kwargs``: - :parent_location: (required): the location of the parent module + :parent_location: (required): the location of the parent block (e.g. the parent course or section) :category: the category of the resulting item. @@ -400,7 +400,7 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum if display_name is not None: metadata['display_name'] = display_name - module = store.create_child( + block = store.create_child( user_id, parent.location, location.block_type, @@ -412,12 +412,12 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum ) if has_score: - module.has_score = has_score + block.has_score = has_score if submission_start: - module.submission_start = submission_start + block.submission_start = submission_start if submission_end: - module.submission_end = submission_end - store.update_item(module, user_id) + block.submission_end = submission_end + store.update_item(block, user_id) # VS[compat] cdodge: This is a hack because static_tabs also have references from the course block, so # if we add one then we need to also add it to the policy information (i.e. metadata) @@ -430,19 +430,19 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum store.update_item(course, user_id) # parent and publish the item, so it can be accessed - if 'detached' not in module._class_tags: # lint-amnesty, pylint: disable=protected-access + if 'detached' not in block._class_tags: # lint-amnesty, pylint: disable=protected-access parent.children.append(location) store.update_item(parent, user_id) if publish_item: published_parent = store.publish(parent.location, user_id) - # module is last child of parent + # block is last child of parent return published_parent.get_children()[-1] else: return store.get_item(location) elif publish_item: return store.publish(location, user_id) else: - return module + return block @contextmanager diff --git a/xmodule/modulestore/tests/test_mixed_modulestore.py b/xmodule/modulestore/tests/test_mixed_modulestore.py index 21c25347ba3d..5d5360d8f0bb 100644 --- a/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -418,8 +418,8 @@ def test_get_items(self, default_ms, num_mysql, max_find, max_send): course_locn = self.course_locations[self.MONGO_COURSEID] with check_mongo_calls(max_find, max_send), self.assertNumQueries(num_mysql): - modules = self.store.get_items(course_locn.course_key, qualifiers={'category': 'problem'}) - assert len(modules) == 6 + blocks = self.store.get_items(course_locn.course_key, qualifiers={'category': 'problem'}) + assert len(blocks) == 6 # verify that an error is raised when the revision is not valid with pytest.raises(UnsupportedRevisionError): @@ -2460,7 +2460,7 @@ def verify_default_store(self, store_type): # verify store used for creating a course course = self.store.create_course("org", "course{}".format(uuid4().hex[:5]), "run", self.user_id) - assert course.system.modulestore.get_modulestore_type() == store_type + assert course.runtime.modulestore.get_modulestore_type() == store_type @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) def test_default_store(self, default_ms): @@ -2676,7 +2676,7 @@ def test_course_publish_signal_import_firing(self, default): # Note: The signal is fired once when the course is created and # a second time after the actual data import. import_course_from_xml( - self.store, self.user_id, DATA_DIR, ['toy'], load_error_modules=False, + self.store, self.user_id, DATA_DIR, ['toy'], load_error_blocks=False, static_content_store=contentstore, create_if_not_present=True, ) @@ -3345,7 +3345,7 @@ def test_aside_crud(self, default_store): dest_course_key = self.store.make_course_key('edX', "aside_test", "2012_Fall") courses = import_course_from_xml( self.store, self.user_id, DATA_DIR, ['aside'], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore, target_id=dest_course_key, create_if_not_present=True, @@ -3421,7 +3421,7 @@ def test_export_course_with_asides(self, default_store): self.user_id, DATA_DIR, ['aside'], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore, target_id=dest_course_key, create_if_not_present=True, @@ -3508,7 +3508,7 @@ def test_export_course_after_creating_new_items_with_asides(self, default_store) self.user_id, DATA_DIR, ['aside'], - load_error_modules=False, + load_error_blocks=False, static_content_store=contentstore, target_id=dest_course_key, create_if_not_present=True, diff --git a/xmodule/modulestore/tests/test_split_modulestore.py b/xmodule/modulestore/tests/test_split_modulestore.py index 56525f907bfd..408d7b3002f6 100644 --- a/xmodule/modulestore/tests/test_split_modulestore.py +++ b/xmodule/modulestore/tests/test_split_modulestore.py @@ -704,7 +704,7 @@ def test_cache(self): locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT) course = modulestore().get_course(locator) block_map = modulestore().cache_items( - course.system, [BlockKey.from_usage_key(child) for child in course.children], course.id, depth=3 + course.runtime, [BlockKey.from_usage_key(child) for child in course.children], course.id, depth=3 ) assert BlockKey('chapter', 'chapter1') in block_map assert BlockKey('problem', 'problem3_2') in block_map @@ -719,14 +719,14 @@ def test_persist_dag(self): master_branch=ModuleStoreEnum.BranchName.draft ) test_chapter = modulestore().create_xblock( - test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'}, + test_course.runtime, test_course.id, 'chapter', fields={'display_name': 'chapter n'}, parent_xblock=test_course ) assert test_chapter.display_name == 'chapter n' test_def_content = 'boo' # create child new_block = modulestore().create_xblock( - test_course.system, test_course.id, + test_course.runtime, test_course.id, 'problem', fields={ 'data': test_def_content, @@ -1013,7 +1013,7 @@ def test_get_items(self): get_items(locator, qualifiers, [branch]) ''' locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT) - # get all modules + # get all blocks matches = modulestore().get_items(locator) assert len(matches) == 8 matches = modulestore().get_items(locator) @@ -1120,28 +1120,28 @@ def test_create_minimal_item(self): premod_history = modulestore().get_course_history_info(locator) # add minimal one w/o a parent category = 'sequential' - new_module = modulestore().create_item( + new_block = modulestore().create_item( 'user123', locator, category, fields={'display_name': 'new sequential'} ) # check that course version changed and course's previous is the other one - assert new_module.location.course == 'GreekHero' - assert new_module.location.version_guid != premod_course.location.version_guid + assert new_block.location.course == 'GreekHero' + assert new_block.location.version_guid != premod_course.location.version_guid assert locator.version_guid is None,\ 'Version inadvertently filled in' # lint-amnesty, pylint: disable=no-member current_course = modulestore().get_course(locator) - assert new_module.location.version_guid == current_course.location.version_guid + assert new_block.location.version_guid == current_course.location.version_guid history_info = modulestore().get_course_history_info(current_course.location.course_key) assert history_info['previous_version'] == premod_course.location.version_guid assert history_info['original_version'] == premod_history['original_version'] assert history_info['edited_by'] == 'user123' # check block's info: category, definition_locator, and display_name - assert new_module.category == 'sequential' - assert new_module.definition_locator is not None - assert new_module.display_name == 'new sequential' + assert new_block.category == 'sequential' + assert new_block.definition_locator is not None + assert new_block.display_name == 'new sequential' # check that block does not exist in previous version - locator = new_module.location.map_into_course( + locator = new_block.location.map_into_course( CourseLocator(version_guid=premod_course.location.version_guid) ) with pytest.raises(ItemNotFoundError): @@ -1162,20 +1162,20 @@ def test_create_parented_item(self): ) premod_course = modulestore().get_course(locator.course_key) category = 'chapter' - new_module = modulestore().create_child( + new_block = modulestore().create_child( 'user123', locator, category, fields={'display_name': 'new chapter'}, definition_locator=original.definition_locator ) # check that course version changed and course's previous is the other one - assert new_module.location.version_guid != premod_course.location.version_guid + assert new_block.location.version_guid != premod_course.location.version_guid parent = modulestore().get_item(locator) - assert new_module.location.version_agnostic() in version_agnostic(parent.children) - assert new_module.definition_locator.definition_id == original.definition_locator.definition_id + assert new_block.location.version_agnostic() in version_agnostic(parent.children) + assert new_block.definition_locator.definition_id == original.definition_locator.definition_id def test_unique_naming(self): """ - Check that 2 modules of same type get unique block_ids. Also check that if creation provides + Check that 2 blocks of same type get unique block_ids. Also check that if creation provides a definition id and new def data that it branches the definition in the db. Actually, this tries to test all create_item features not tested above. """ @@ -1190,29 +1190,29 @@ def test_unique_naming(self): ) category = 'problem' new_payload = "empty" - new_module = modulestore().create_child( + new_block = modulestore().create_child( 'anotheruser', locator, category, fields={'display_name': 'problem 1', 'data': new_payload}, ) another_payload = "not empty" - another_module = modulestore().create_child( + another_block = modulestore().create_child( 'anotheruser', locator, category, fields={'display_name': 'problem 2', 'data': another_payload}, definition_locator=original.definition_locator, ) # check that course version changed and course's previous is the other one parent = modulestore().get_item(locator) - assert new_module.location.block_id != another_module.location.block_id - assert new_module.location.version_agnostic() in version_agnostic(parent.children) - assert another_module.location.version_agnostic() in version_agnostic(parent.children) - assert new_module.data == new_payload - assert another_module.data == another_payload + assert new_block.location.block_id != another_block.location.block_id + assert new_block.location.version_agnostic() in version_agnostic(parent.children) + assert another_block.location.version_agnostic() in version_agnostic(parent.children) + assert new_block.data == new_payload + assert another_block.data == another_payload # check definition histories - new_history = modulestore().get_definition_history_info(new_module.definition_locator) + new_history = modulestore().get_definition_history_info(new_block.definition_locator) assert new_history['previous_version'] is None - assert new_history['original_version'] == new_module.definition_locator.definition_id + assert new_history['original_version'] == new_block.definition_locator.definition_id assert new_history['edited_by'] == 'anotheruser' - another_history = modulestore().get_definition_history_info(another_module.definition_locator) + another_history = modulestore().get_definition_history_info(another_block.definition_locator) assert another_history['previous_version'] == original.definition_locator.definition_id def test_encoded_naming(self): @@ -1228,8 +1228,8 @@ def test_encoded_naming(self): fields={'display_name': 'chapter 99'}, ) # check that course version changed and course's previous is the other one - new_module = modulestore().get_item(chapter_locator) - assert new_module.location.block_id == 'foo.bar_-~:0' + new_block = modulestore().get_item(chapter_locator) + assert new_block.location.block_id == 'foo.bar_-~:0' # hardcode to ensure BUL init didn't change # now try making that a parent of something new_payload = "empty" @@ -1240,8 +1240,8 @@ def test_encoded_naming(self): fields={'display_name': 'chapter 99', 'data': new_payload}, ) # check that course version changed and course's previous is the other one - new_module = modulestore().get_item(problem_locator) - assert new_module.location.block_id == problem_locator.block_id + new_block = modulestore().get_item(problem_locator) + assert new_block.location.block_id == problem_locator.block_id chapter = modulestore().get_item(chapter_locator) assert problem_locator in version_agnostic(chapter.children) @@ -1871,7 +1871,7 @@ def test_publish_safe(self): ] self._check_course(source_course, dest_course, expected, unexpected) # add a child under chapter1 - new_module = modulestore().create_child( + new_block = modulestore().create_child( self.user_id, chapter1, "sequential", fields={'display_name': 'new sequential'}, ) @@ -1879,22 +1879,22 @@ def test_publish_safe(self): expected.remove(BlockKey.from_usage_key(chapter1)) # check that it's not in published course with pytest.raises(ItemNotFoundError): - modulestore().get_item(new_module.location.map_into_course(dest_course)) + modulestore().get_item(new_block.location.map_into_course(dest_course)) # publish it - modulestore().copy(self.user_id, source_course, dest_course, [new_module.location], None) - expected.append(BlockKey.from_usage_key(new_module.location)) + modulestore().copy(self.user_id, source_course, dest_course, [new_block.location], None) + expected.append(BlockKey.from_usage_key(new_block.location)) # check that it is in the published course and that its parent is the chapter - pub_module = modulestore().get_item(new_module.location.map_into_course(dest_course)) - assert modulestore().get_parent_location(pub_module.location).block_id == chapter1.block_id + pub_block = modulestore().get_item(new_block.location.map_into_course(dest_course)) + assert modulestore().get_parent_location(pub_block.location).block_id == chapter1.block_id # ensure intentionally orphaned blocks work (e.g., course_info) - new_module = modulestore().create_item( + new_block = modulestore().create_item( self.user_id, source_course, "course_info", block_id="handouts" ) # publish it - modulestore().copy(self.user_id, source_course, dest_course, [new_module.location], None) - expected.append(BlockKey.from_usage_key(new_module.location)) + modulestore().copy(self.user_id, source_course, dest_course, [new_block.location], None) + expected.append(BlockKey.from_usage_key(new_block.location)) # check that it is in the published course (no error means it worked) - pub_module = modulestore().get_item(new_module.location.map_into_course(dest_course)) + pub_block = modulestore().get_item(new_block.location.map_into_course(dest_course)) self._check_course(source_course, dest_course, expected, unexpected) def test_exceptions(self): diff --git a/xmodule/modulestore/tests/test_store_utilities.py b/xmodule/modulestore/tests/test_store_utilities.py index fdc76655f770..1c1c86f4fcd3 100644 --- a/xmodule/modulestore/tests/test_store_utilities.py +++ b/xmodule/modulestore/tests/test_store_utilities.py @@ -76,9 +76,9 @@ class TestUtils(unittest.TestCase): @ddt.unpack def test_get_draft_subtree_roots(self, node_arguments_list, expected_roots_urls): """tests for get_draft_subtree_roots""" - module_nodes = [] + block_nodes = [] for node_args in node_arguments_list: - module_nodes.append(draft_node_constructor(Mock(), node_args[0], node_args[1])) - subtree_roots_urls = [root.url for root in get_draft_subtree_roots(module_nodes)] + 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) diff --git a/xmodule/modulestore/tests/test_xml.py b/xmodule/modulestore/tests/test_xml.py index b2c10157fc7b..b22e3938b23c 100644 --- a/xmodule/modulestore/tests/test_xml.py +++ b/xmodule/modulestore/tests/test_xml.py @@ -54,7 +54,7 @@ def test_unicode_chars_in_xml_content(self): DATA_DIR, source_dirs=['toy'], xblock_mixins=(XModuleMixin,), - load_error_modules=False) + load_error_blocks=False) # Look up the errors during load. There should be none. errors = modulestore.get_course_errors(CourseKey.from_string("edX/toy/2012_Fall")) @@ -152,10 +152,10 @@ def setUp(self): @patch("xmodule.modulestore.xml.glob.glob", side_effect=glob_tildes_at_end) def test_tilde_files_ignored(self, _fake_glob): - modulestore = XMLModuleStore(DATA_DIR, source_dirs=['course_ignore'], load_error_modules=False) + modulestore = XMLModuleStore(DATA_DIR, source_dirs=['course_ignore'], load_error_blocks=False) about_location = CourseKey.from_string('edX/course_ignore/2014_Fall').make_usage_key( 'about', 'index', ) - about_module = modulestore.get_item(about_location) - assert 'GREEN' in about_module.data - assert 'RED' not in about_module.data + about_block = modulestore.get_item(about_location) + assert 'GREEN' in about_block.data + assert 'RED' not in about_block.data diff --git a/xmodule/modulestore/tests/test_xml_importer.py b/xmodule/modulestore/tests/test_xml_importer.py index 6e0e69dc861b..c59050b319e0 100644 --- a/xmodule/modulestore/tests/test_xml_importer.py +++ b/xmodule/modulestore/tests/test_xml_importer.py @@ -19,7 +19,7 @@ from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM -from xmodule.modulestore.xml_importer import StaticContentImporter, _update_and_import_module, _update_module_location +from xmodule.modulestore.xml_importer import StaticContentImporter, _update_and_import_block, _update_block_location from xmodule.tests import DATA_DIR from xmodule.x_module import XModuleMixin @@ -152,7 +152,7 @@ def test_remap_namespace_native_xblock(self): # Move to different runtime w/ different course id target_location_namespace = CourseKey.from_string("org/course/run") - new_version = _update_and_import_module( + new_version = _update_and_import_block( self.xblock, modulestore(), 999, @@ -183,7 +183,7 @@ def test_remap_namespace_native_xblock_default_values(self): # Remap the namespace target_location_namespace = BlockUsageLocator(CourseLocator("org", "course", "run"), "category", "stubxblock") - new_version = _update_and_import_module( + new_version = _update_and_import_block( self.xblock, modulestore(), 999, @@ -209,7 +209,7 @@ def test_remap_namespace_native_xblock_inherited_values(self): # Remap the namespace target_location_namespace = BlockUsageLocator(CourseLocator("org", "course", "run"), "category", "stubxblock") - new_version = _update_and_import_module( + new_version = _update_and_import_block( self.xblock, modulestore(), 999, @@ -303,8 +303,8 @@ def test_update_locations_native_xblock(self): # Update location target_location = self.xblock.location.replace(revision='draft') - _update_module_location(self.xblock, target_location) - new_version = self.xblock # _update_module_location updates in-place + _update_block_location(self.xblock, target_location) + new_version = self.xblock # _update_block_location updates in-place # Check the XBlock's location assert new_version.location == target_location diff --git a/xmodule/modulestore/xml.py b/xmodule/modulestore/xml.py index 35c5244c130b..497bad1d1137 100644 --- a/xmodule/modulestore/xml.py +++ b/xmodule/modulestore/xml.py @@ -49,12 +49,12 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring def __init__(self, xmlstore, course_id, course_dir, # lint-amnesty, pylint: disable=too-many-statements error_tracker, - load_error_modules=True, target_course_id=None, **kwargs): + load_error_blocks=True, target_course_id=None, **kwargs): """ A class that handles loading from xml. Does some munging to ensure that all elements have unique slugs. - xmlstore: the XMLModuleStore to store the loaded modules in + xmlstore: the XMLModuleStore to store the loaded blocks in """ self.unnamed = defaultdict(int) # category -> num of new url_names for that category self.used_names = defaultdict(set) # category -> set of used url_names @@ -62,7 +62,7 @@ def __init__(self, xmlstore, course_id, course_dir, # lint-amnesty, pylint: dis # Adding the course_id as passed in for later reference rather than # having to recombine the org/course/url_name self.course_id = course_id - self.load_error_modules = load_error_modules + self.load_error_blocks = load_error_blocks self.modulestore = xmlstore def process_xml(xml): # lint-amnesty, pylint: disable=too-many-statements @@ -107,7 +107,7 @@ def looks_like_fallback(url_name): and re.search('[0-9a-fA-F]{12}$', url_name)) def fallback_name(orig_name=None): - """Return the fallback name for this module. This is a function instead of a variable + """Return the fallback name for this block. This is a function instead of a variable because we want it to be lazy.""" if looks_like_fallback(orig_name): # We're about to re-hash, in case something changed, so get rid of the tag_ and hash @@ -125,17 +125,17 @@ def fallback_name(orig_name=None): if tag in need_uniq_names: error_tracker("PROBLEM: no name of any kind specified for {tag}. Student " - "state will not be properly tracked for this module. Problem xml:" + "state will not be properly tracked for this block. Problem xml:" " '{xml}...'".format(tag=tag, xml=xml[:100])) else: # TODO (vshnayder): We may want to enable this once course repos are cleaned up. # (or we may want to give up on the requirement for non-state-relevant issues...) - # error_tracker("WARNING: no name specified for module. xml='{0}...'".format(xml[:100])) + # error_tracker("WARNING: no name specified for block. xml='{0}...'".format(xml[:100])) pass # Make sure everything is unique if url_name in self.used_names[tag]: - # Always complain about modules that store state. If it + # Always complain about blocks that store state. If it # doesn't store state, don't complain about things that are # hashed. if tag in need_uniq_names: @@ -166,7 +166,7 @@ def fallback_name(orig_name=None): id_manager, ) except Exception as err: # pylint: disable=broad-except - if not self.load_error_modules: + if not self.load_error_blocks: raise # Didn't load properly. Fall back on loading as an error @@ -304,7 +304,7 @@ class XMLModuleStore(ModuleStoreReadBase): def __init__( self, data_dir, default_class=None, source_dirs=None, course_ids=None, - load_error_modules=True, i18n_service=None, fs_service=None, user_service=None, + load_error_blocks=True, i18n_service=None, fs_service=None, user_service=None, signal_handler=None, target_course_id=None, **kwargs # pylint: disable=unused-argument ): """ @@ -329,7 +329,7 @@ class to use if none is specified in entry_points if course_ids is not None: course_ids = [CourseKey.from_string(course_id) for course_id in course_ids] - self.load_error_modules = load_error_modules + self.load_error_blocks = load_error_blocks if default_class is None: self.default_class = None @@ -486,7 +486,7 @@ def load_course(self, course_dir, course_ids, tracker, target_course_id=None): # VS[compat] : 'name' is deprecated, but support it for now... if course_data.get('name'): url_name = BlockUsageLocator.clean(course_data.get('name')) - tracker("'name' is deprecated for module xml. Please use " + tracker("'name' is deprecated for block xml. Please use " "display_name and url_name.") else: url_name = None @@ -519,7 +519,7 @@ def get_policy(usage_id): course_id=course_id, course_dir=course_dir, error_tracker=tracker, - load_error_modules=self.load_error_modules, + load_error_blocks=self.load_error_blocks, get_policy=get_policy, mixins=self.xblock_mixins, default_class=self.default_class, @@ -639,12 +639,12 @@ def _load_extra_content(self, system, course_descriptor, category, content_path, else: try: # get and update data field in xblock runtime - module = system.get_block(loc) + block = system.get_block(loc) for key, value in data_content.items(): - setattr(module, key, value) - module.save() + setattr(block, key, value) + block.save() except ItemNotFoundError: - module = None + block = None data_content['location'] = loc data_content['category'] = category else: @@ -653,15 +653,15 @@ def _load_extra_content(self, system, course_descriptor, category, content_path, # html file with html data content html = f.read() try: - module = system.get_block(loc) - module.data = html - module.save() + block = system.get_block(loc) + block.data = html + block.save() except ItemNotFoundError: - module = None + block = None data_content = {'data': html, 'location': loc, 'category': category} - if module is None: - module = system.construct_xblock( + if block is None: + block = system.construct_xblock( category, # We're loading a descriptor, so student_id is meaningless # We also don't have separate notions of definition and usage ids yet, @@ -675,12 +675,12 @@ def _load_extra_content(self, system, course_descriptor, category, content_path, if category == "static_tab": tab = CourseTabList.get_tab_by_slug(tab_list=course_descriptor.tabs, url_slug=slug) if tab: - module.display_name = tab.name - module.course_staff_only = tab.course_staff_only - module.data_dir = course_dir - module.save() + block.display_name = tab.name + block.course_staff_only = tab.course_staff_only + block.data_dir = course_dir + block.save() - self.modules[course_descriptor.id][module.scope_ids.usage_id] = module + self.modules[course_descriptor.id][block.scope_ids.usage_id] = block except Exception as exc: # pylint: disable=broad-except logging.exception("Failed to load %s. Skipping... \ Exception: %s", filepath, str(exc)) @@ -702,7 +702,7 @@ def get_item(self, usage_key, depth=0, **kwargs): # lint-amnesty, pylint: disab If no object is found at that location, raises xmodule.modulestore.exceptions.ItemNotFoundError - usage_key: a UsageKey that matches the module we are looking for. + usage_key: a UsageKey that matches the block we are looking for. """ try: return self.modules[usage_key.course_key][usage_key] @@ -743,24 +743,24 @@ def get_items(self, course_id, settings=None, content=None, revision=None, quali category = qualifiers.pop('category', None) name = qualifiers.pop('name', None) - def _block_matches_all(mod_loc, module): - if category and mod_loc.category != category: + def _block_matches_all(block_loc, block): + if category and block_loc.category != category: return False if name: if isinstance(name, list): # Support for passing a list as the name qualifier - if mod_loc.name not in name: + if block_loc.name not in name: return False - elif mod_loc.name != name: + elif block_loc.name != name: return False return all( - self._block_matches(module, fields or {}) + self._block_matches(block, fields or {}) for fields in [settings, content, qualifiers] ) - for mod_loc, module in self.modules[course_id].items(): - if _block_matches_all(mod_loc, module): - items.append(module) + for block_loc, block in self.modules[course_id].items(): + if _block_matches_all(block_loc, block): + items.append(block) return items diff --git a/xmodule/modulestore/xml_exporter.py b/xmodule/modulestore/xml_exporter.py index 79002f7ede80..144d46e93534 100644 --- a/xmodule/modulestore/xml_exporter.py +++ b/xmodule/modulestore/xml_exporter.py @@ -34,24 +34,24 @@ def _export_drafts(modulestore, course_key, export_fs, xml_centric_course_key): # NOTE: we need to explicitly implement the logic for setting the vertical's parent # and index here since the XML modulestore cannot load draft modules with modulestore.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course_key): - draft_modules = modulestore.get_items( + draft_blocks = modulestore.get_items( course_key, qualifiers={'category': {'$nin': DIRECT_ONLY_CATEGORIES}}, revision=ModuleStoreEnum.RevisionOption.draft_only ) - # Check to see if the returned draft modules have changes w.r.t. the published module. - # Only modules with changes will be exported into the /drafts directory. - draft_modules = [module for module in draft_modules if modulestore.has_changes(module)] - if draft_modules: + # Check to see if the returned draft blocks have changes w.r.t. the published block. + # Only blocks with changes will be exported into the /drafts directory. + draft_blocks = [block for block in draft_blocks if modulestore.has_changes(block)] + if draft_blocks: draft_course_dir = export_fs.makedir(DRAFT_DIR, recreate=True) - # accumulate tuples of draft_modules and their parents in + # accumulate tuples of draft_blocks and their parents in # this list: draft_node_list = [] - for draft_module in draft_modules: + for draft_block in draft_blocks: parent_loc = modulestore.get_parent_location( - draft_module.location, + draft_block.location, revision=ModuleStoreEnum.RevisionOption.draft_preferred ) @@ -61,9 +61,9 @@ def _export_drafts(modulestore, course_key, export_fs, xml_centric_course_key): parent_url = str(parent_loc) draft_node = draft_node_constructor( - draft_module, - location=draft_module.location, - url=str(draft_module.location), + draft_block, + location=draft_block.location, + url=str(draft_block.location), parent_location=parent_loc, parent_url=parent_url, ) @@ -117,9 +117,9 @@ class ExportManager: """ def __init__(self, modulestore, contentstore, courselike_key, root_dir, target_dir): """ - Export all modules from `modulestore` and content from `contentstore` as xml to `root_dir`. + Export all blocks from `modulestore` and content from `contentstore` as xml to `root_dir`. - `modulestore`: A `ModuleStore` object that is the source of the modules to export + `modulestore`: A `ModuleStore` object that is the source of the blocks to export `contentstore`: A `ContentStore` object that is the source of the content to export, can be None `courselike_key`: The Locator of the Descriptor to export `root_dir`: The directory to write the exported xml to @@ -394,14 +394,14 @@ def _export_field_content(xblock_item, item_dir): """ Export all fields related to 'xblock_item' other than 'metadata' and 'data' to json file in provided directory """ - module_data = xblock_item.get_explicitly_set_fields_by_scope(Scope.content) - if isinstance(module_data, dict): - for field_name in module_data: + block_data = xblock_item.get_explicitly_set_fields_by_scope(Scope.content) + if isinstance(block_data, dict): + for field_name in block_data: if field_name not in DEFAULT_CONTENT_FIELDS: # filename format: {dirname}.{field_name}.json with item_dir.open('{}.{}.{}'.format(xblock_item.location.block_id, field_name, 'json'), 'wb') as field_content_file: - field_content_file.write(dumps(module_data.get(field_name, {}), cls=EdxJSONEncoder, + field_content_file.write(dumps(block_data.get(field_name, {}), cls=EdxJSONEncoder, sort_keys=True, indent=4).encode('utf-8')) diff --git a/xmodule/modulestore/xml_importer.py b/xmodule/modulestore/xml_importer.py index 89bb855067d2..2ab68f5d4050 100644 --- a/xmodule/modulestore/xml_importer.py +++ b/xmodule/modulestore/xml_importer.py @@ -82,12 +82,12 @@ def __init__(self, filename, **kwargs): super().__init__(**kwargs) -class ModuleFailedToImport(CourseImportException): +class BlockFailedToImport(CourseImportException): """ - Raised when a module is failed to import. + Raised when a block is failed to import. """ - MESSAGE_TEMPLATE = _('Failed to import module: {} at location: {}') + MESSAGE_TEMPLATE = _('Failed to import block: {} at location: {}') def __init__(self, display_name, location, **kwargs): self.description = self.MESSAGE_TEMPLATE.format(display_name, location) @@ -228,7 +228,7 @@ class ImportManager: source_dirs: If specified, the list of data_dir subdirectories to load. Otherwise, load all dirs - target_id: is the Locator that all modules should be remapped to + target_id: is the Locator that all blocks should be remapped to after import off disk. NOTE: this only makes sense if importing only one courselike. If there are more than one courselike loaded from data_dir/source_dirs & you supply this id, an AssertException will be raised. @@ -254,14 +254,14 @@ class ImportManager: python_lib_filename: The filename of the courselike's python library. Course authors can optionally create this file to implement custom logic in their course. - default_class, load_error_modules: are arguments for constructing the XMLModuleStore (see its doc) + default_class, load_error_blocks: are arguments for constructing the XMLModuleStore (see its doc) """ store_class = XMLModuleStore def __init__( self, store, user_id, data_dir, source_dirs=None, default_class='xmodule.hidden_block.HiddenBlock', - load_error_modules=True, static_content_store=None, + load_error_blocks=True, static_content_store=None, target_id=None, verbose=False, do_import_static=True, do_import_python_lib=True, create_if_not_present=False, raise_on_failure=False, @@ -272,7 +272,7 @@ def __init__( self.user_id = user_id self.data_dir = data_dir self.source_dirs = source_dirs - self.load_error_modules = load_error_modules + self.load_error_blocks = load_error_blocks self.static_content_store = static_content_store self.target_id = target_id self.verbose = verbose @@ -286,7 +286,7 @@ def __init__( data_dir, default_class=default_class, source_dirs=source_dirs, - load_error_modules=load_error_modules, + load_error_blocks=load_error_blocks, xblock_mixins=store.xblock_mixins, xblock_select=store.xblock_select, target_course_id=target_id, @@ -406,10 +406,10 @@ def make_asset_id(course_id, asset_xml): def import_courselike(self, runtime, courselike_key, dest_id, source_courselike): """ - Import the base module/block + Import the base block """ if self.verbose: - log.debug("Scanning %s for courselike module...", courselike_key) + log.debug("Scanning %s for courselike block...", courselike_key) # Quick scan to get course block as we need some info from there. # Also we need to make sure that the course block is committed @@ -427,7 +427,7 @@ def import_courselike(self, runtime, courselike_key, dest_id, source_courselike) log.debug('course data_dir=%s', source_courselike.data_dir) with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, dest_id): - course = _update_and_import_module( + course = _update_and_import_block( source_courselike, self.store, self.user_id, courselike_key, dest_id, @@ -497,10 +497,10 @@ def depth_first(subtree): # ContentStoreTest.test_image_import pass if self.verbose: - log.debug('importing module location %s', child.location) + log.debug('importing block location %s', child.location) try: - _update_and_import_module( + _update_and_import_block( child, self.store, self.user_id, @@ -511,9 +511,9 @@ def depth_first(subtree): ) except Exception: log.exception( - f'Course import {dest_id}: failed to import module location {child.location}' + f'Course import {dest_id}: failed to import block location {child.location}' ) - raise ModuleFailedToImport(child.display_name, child.location) # pylint: disable=raise-missing-from + raise BlockFailedToImport(child.display_name, child.location) # pylint: disable=raise-missing-from depth_first(child) @@ -521,10 +521,10 @@ def depth_first(subtree): for leftover in all_locs: if self.verbose: - log.debug('importing module location %s', leftover) + log.debug('importing block location %s', leftover) try: - _update_and_import_module( + _update_and_import_block( self.xml_module_store.get_item(leftover), self.store, self.user_id, @@ -535,10 +535,10 @@ def depth_first(subtree): ) except Exception: log.exception( - f'Course import {dest_id}: failed to import module location {leftover}' + f'Course import {dest_id}: failed to import block location {leftover}' ) # pylint: disable=raise-missing-from - raise ModuleFailedToImport(leftover.display_name, leftover.location) + raise BlockFailedToImport(leftover.display_name, leftover.location) def run_imports(self): """ @@ -783,19 +783,19 @@ def import_library_from_xml(*args, **kwargs): return list(manager.run_imports()) -def _update_and_import_module( - module, store, user_id, +def _update_and_import_block( + block, store, user_id, source_course_id, dest_course_id, do_import_static=True, runtime=None): """ - Update all the module reference fields to the destination course id, - then import the module into the destination course. + Update all the block reference fields to the destination course id, + then import the block into the destination course. """ - logging.debug('processing import of module %s...', str(module.location)) + logging.debug('processing import of blocks %s...', str(block.location)) - def _update_module_references(module, source_course_id, dest_course_id): + def _update_block_references(block, source_course_id, dest_course_id): """ - Move the module to a new course. + Move the block to a new course. """ def _convert_ref_fields_to_new_namespace(reference): @@ -812,26 +812,26 @@ def _convert_ref_fields_to_new_namespace(reference): return reference fields = {} - for field_name, field in module.fields.items(): - if field.scope != Scope.parent and field.is_set_on(module): + for field_name, field in block.fields.items(): + if field.scope != Scope.parent and field.is_set_on(block): if isinstance(field, Reference): - value = field.read_from(module) + value = field.read_from(block) if value is None: fields[field_name] = None else: - fields[field_name] = _convert_ref_fields_to_new_namespace(field.read_from(module)) + fields[field_name] = _convert_ref_fields_to_new_namespace(field.read_from(block)) elif isinstance(field, ReferenceList): - references = field.read_from(module) + references = field.read_from(block) fields[field_name] = [_convert_ref_fields_to_new_namespace(reference) for reference in references] elif isinstance(field, ReferenceValueDict): - reference_dict = field.read_from(module) + reference_dict = field.read_from(block) fields[field_name] = { key: _convert_ref_fields_to_new_namespace(reference) for key, reference in reference_dict.items() } elif field_name == 'xml_attributes': - value = field.read_from(module) + value = field.read_from(block) # remove any export/import only xml_attributes # which are used to wire together draft imports if 'parent_url' in value: @@ -843,28 +843,28 @@ def _convert_ref_fields_to_new_namespace(reference): del value['index_in_children_list'] fields[field_name] = value else: - fields[field_name] = field.read_from(module) + fields[field_name] = field.read_from(block) return fields - if do_import_static and 'data' in module.fields and isinstance(module.fields['data'], xblock.fields.String): + if do_import_static and 'data' in block.fields and isinstance(block.fields['data'], xblock.fields.String): # we want to convert all 'non-portable' links in the module_data # (if it is a string) to portable strings (e.g. /static/) - module.data = rewrite_nonportable_content_links( + block.data = rewrite_nonportable_content_links( source_course_id, dest_course_id, - module.data + block.data ) - fields = _update_module_references(module, source_course_id, dest_course_id) - asides = module.get_asides() if isinstance(module, XModuleMixin) else None + fields = _update_block_references(block, source_course_id, dest_course_id) + asides = block.get_asides() if isinstance(block, XModuleMixin) else None - if module.location.block_type == 'library_content': + if block.location.block_type == 'library_content': with store.branch_setting(branch_setting=ModuleStoreEnum.Branch.published_only): - lib_content_block_already_published = store.has_item(module.location) + lib_content_block_already_published = store.has_item(block.location) block = store.import_xblock( - user_id, dest_course_id, module.location.block_type, - module.location.block_id, fields, runtime, asides=asides + user_id, dest_course_id, block.location.block_type, + block.location.block_id, fields, runtime, asides=asides ) # TODO: Move this code once the following condition is met. @@ -952,25 +952,25 @@ def _import_course_draft( course_id=source_course_id, course_dir=draft_course_dir, error_tracker=errorlog.tracker, - load_error_modules=False, + load_error_blocks=False, mixins=xml_module_store.xblock_mixins, services={'field-data': KvsFieldData(kvs=DictKeyValueStore())}, target_course_id=target_id, ) - def _import_module(module): - # IMPORTANT: Be sure to update the module location in the NEW namespace - module_location = module.location.map_into_course(target_id) - # Update the module's location to DRAFT revision + def _import_block(block): + # IMPORTANT: Be sure to update the block location in the NEW namespace + block_location = block.location.map_into_course(target_id) + # Update the block's location to DRAFT revision # We need to call this method (instead of updating the location directly) # to ensure that pure XBlock field data is updated correctly. - _update_module_location(module, module_location.replace(revision=MongoRevisionKey.draft)) + _update_block_location(block, block_location.replace(revision=MongoRevisionKey.draft)) - parent_url = get_parent_url(module) - index = index_in_children_list(module) + parent_url = get_parent_url(block) + index = index_in_children_list(block) # make sure our parent has us in its list of children - # this is to make sure private only modules show up + # this is to make sure private only blocks show up # in the list of children since they would have been # filtered out from the non-draft store export. if parent_url is not None and index is not None: @@ -982,19 +982,19 @@ def _import_module(module): parent = store.get_item(parent_location, depth=0) - non_draft_location = module.location.map_into_course(target_id) - if not any(child.block_id == module.location.block_id for child in parent.children): + non_draft_location = block.location.map_into_course(target_id) + if not any(child.block_id == block.location.block_id for child in parent.children): parent.children.insert(index, non_draft_location) store.update_item(parent, user_id) - _update_and_import_module( - module, store, user_id, + _update_and_import_block( + block, store, user_id, source_course_id, target_id, runtime=mongo_runtime, ) - for child in module.get_children(): - _import_module(child) + for child in block.get_children(): + _import_block(child) # Now walk the /drafts directory. # Each file in the directory will be a draft copy of the vertical. @@ -1007,8 +1007,8 @@ def _import_module(module): if filename.startswith('._'): # Skip any OSX quarantine files, prefixed with a '._'. continue - module_path = os.path.join(rootdir, filename) - with open(module_path) as f: + block_path = os.path.join(rootdir, filename) + with open(block_path) as f: try: xml = f.read() @@ -1033,7 +1033,7 @@ def _import_module(module): draft_url = str(descriptor.location) draft = draft_node_constructor( - module=descriptor, url=draft_url, parent_url=parent_url, index=index + block=descriptor, url=draft_url, parent_url=parent_url, index=index ) drafts.append(draft) @@ -1045,7 +1045,7 @@ def _import_module(module): for draft in get_draft_subtree_roots(drafts): try: - _import_module(draft.module) + _import_block(draft.module) except Exception: # pylint: disable=broad-except logging.exception(f'Course import {source_course_id}: while importing draft descriptor {draft.module}') @@ -1059,89 +1059,89 @@ def allowed_metadata_by_category(category): }.get(category, ['*']) -def check_module_metadata_editability(module): +def check_block_metadata_editability(block): """ - Assert that there is no metadata within a particular module that + Assert that there is no metadata within a particular block that we can't support editing. However we always allow 'display_name' and 'xml_attributes' """ - allowed = allowed_metadata_by_category(module.location.block_type) + allowed = allowed_metadata_by_category(block.location.block_type) if '*' in allowed: # everything is allowed return 0 allowed = allowed + ['xml_attributes', 'display_name'] err_cnt = 0 - illegal_keys = set(own_metadata(module).keys()) - set(allowed) + illegal_keys = set(own_metadata(block).keys()) - set(allowed) if len(illegal_keys) > 0: err_cnt = err_cnt + 1 print( ": found non-editable metadata on {url}. " "These metadata keys are not supported = {keys}".format( - url=str(module.location), keys=illegal_keys + url=str(block.location), keys=illegal_keys ) ) return err_cnt -def get_parent_url(module, xml=None): +def get_parent_url(block, xml=None): """ - Get the parent_url, if any, from module using xml as an alternative source. If it finds it in - xml but not on module, it modifies module so that the next call to this w/o the xml will get the parent url + Get the parent_url, if any, from block using xml as an alternative source. If it finds it in + xml but not on block, it modifies block so that the next call to this w/o the xml will get the parent url """ - if hasattr(module, 'xml_attributes'): - return module.xml_attributes.get( + if hasattr(block, 'xml_attributes'): + return block.xml_attributes.get( # handle deprecated old attr - 'parent_url', module.xml_attributes.get('parent_sequential_url') + 'parent_url', block.xml_attributes.get('parent_sequential_url') ) if xml is not None: - create_xml_attributes(module, xml) - return get_parent_url(module) # don't reparse xml b/c don't infinite recurse but retry above lines + create_xml_attributes(block, xml) + return get_parent_url(block) # don't reparse xml b/c don't infinite recurse but retry above lines return None -def index_in_children_list(module, xml=None): +def index_in_children_list(block, xml=None): """ - Get the index_in_children_list, if any, from module using xml - as an alternative source. If it finds it in xml but not on module, - it modifies module so that the next call to this w/o the xml + Get the index_in_children_list, if any, from block using xml + as an alternative source. If it finds it in xml but not on block, + it modifies block so that the next call to this w/o the xml will get the field. """ - if hasattr(module, 'xml_attributes'): - val = module.xml_attributes.get('index_in_children_list') + if hasattr(block, 'xml_attributes'): + val = block.xml_attributes.get('index_in_children_list') if val is not None: return int(val) return None if xml is not None: - create_xml_attributes(module, xml) - return index_in_children_list(module) # don't reparse xml b/c don't infinite recurse but retry above lines + create_xml_attributes(block, xml) + return index_in_children_list(block) # don't reparse xml b/c don't infinite recurse but retry above lines return None -def create_xml_attributes(module, xml): +def create_xml_attributes(block, xml): """ - Make up for modules which don't define xml_attributes by creating them here and populating + Make up for blocks which don't define xml_attributes by creating them here and populating """ xml_attrs = {} for attr, val in xml.attrib.items(): - if attr not in module.fields: + if attr not in block.fields: # translate obsolete attr if attr == 'parent_sequential_url': attr = 'parent_url' xml_attrs[attr] = val - # now cache it on module where it's expected - module.xml_attributes = xml_attrs + # now cache it on block where it's expected + block.xml_attributes = xml_attrs def validate_no_non_editable_metadata(module_store, course_id, category): # lint-amnesty, pylint: disable=missing-function-docstring err_cnt = 0 - for module_loc in module_store.modules[course_id]: - module = module_store.modules[course_id][module_loc] - if module.location.block_type == category: - err_cnt = err_cnt + check_module_metadata_editability(module) + for block_loc in module_store.modules[course_id]: + block = module_store.modules[course_id][block_loc] + if block.location.block_type == category: + err_cnt = err_cnt + check_block_metadata_editability(block) return err_cnt @@ -1151,10 +1151,10 @@ def validate_category_hierarchy( # lint-amnesty, pylint: disable=missing-functi err_cnt = 0 parents = [] - # get all modules of parent_category - for module in module_store.modules[course_id].values(): - if module.location.block_type == parent_category: - parents.append(module) + # get all blocks of parent_category + for block in module_store.modules[course_id].values(): + if block.location.block_type == parent_category: + parents.append(block) for parent in parents: for child_loc in parent.children: @@ -1206,18 +1206,18 @@ def validate_course_policy(module_store, course_id): Does not add to error count as these are just warnings. """ - # is there a reliable way to get the module location just given the course_id? + # is there a reliable way to get the block location just given the course_id? warn_cnt = 0 - for module in module_store.modules[course_id].values(): - if module.location.block_type == 'course': - if not module._field_data.has(module, 'rerandomize'): # lint-amnesty, pylint: disable=protected-access + for block in module_store.modules[course_id].values(): + if block.location.block_type == 'course': + if not block._field_data.has(block, 'rerandomize'): # lint-amnesty, pylint: disable=protected-access warn_cnt += 1 print( 'WARN: course policy does not specify value for ' '"rerandomize" whose default is now "never". ' 'The behavior of your course may change.' ) - if not module._field_data.has(module, 'showanswer'): # lint-amnesty, pylint: disable=protected-access + if not block._field_data.has(block, 'showanswer'): # lint-amnesty, pylint: disable=protected-access warn_cnt += 1 print( 'WARN: course policy does not specify value for ' @@ -1230,7 +1230,7 @@ def validate_course_policy(module_store, course_id): def perform_xlint( # lint-amnesty, pylint: disable=missing-function-docstring data_dir, source_dirs, default_class='xmodule.hidden_block.HiddenBlock', - load_error_modules=True, + load_error_blocks=True, xblock_mixins=(LocationMixin, XModuleMixin)): err_cnt = 0 warn_cnt = 0 @@ -1239,7 +1239,7 @@ def perform_xlint( # lint-amnesty, pylint: disable=missing-function-docstring data_dir, default_class=default_class, source_dirs=source_dirs, - load_error_modules=load_error_modules, + load_error_blocks=load_error_blocks, xblock_mixins=xblock_mixins ) @@ -1329,16 +1329,16 @@ def perform_xlint( # lint-amnesty, pylint: disable=missing-function-docstring return err_cnt -def _update_module_location(module, new_location): +def _update_block_location(block, new_location): """ - Update a module's location. + Update a block's location. - If the module is a pure XBlock (not an XModule), then its field data + If the block is a pure XBlock (not an XModule), then its field data keys will need to be updated to include the new location. Args: - module (XModuleMixin): The module to update. - new_location (Location): The new location of the module. + block (XModuleMixin): The block to update. + new_location (Location): The new location of the block. Returns: None @@ -1347,12 +1347,12 @@ def _update_module_location(module, new_location): # Retrieve the content and settings fields that have been explicitly set # to ensure that they are properly re-keyed in the XBlock field data. rekey_fields = ( - list(module.get_explicitly_set_fields_by_scope(Scope.content).keys()) + - list(module.get_explicitly_set_fields_by_scope(Scope.settings).keys()) + - list(module.get_explicitly_set_fields_by_scope(Scope.children).keys()) + list(block.get_explicitly_set_fields_by_scope(Scope.content).keys()) + + list(block.get_explicitly_set_fields_by_scope(Scope.settings).keys()) + + list(block.get_explicitly_set_fields_by_scope(Scope.children).keys()) ) - module.location = new_location + block.location = new_location # Pure XBlocks store the field data in a key-value store # in which one component of the key is the XBlock's location (equivalent to "scope_ids"). @@ -1361,4 +1361,4 @@ def _update_module_location(module, new_location): # However, since XBlocks only save "dirty" fields, we need to call # XBlock's `force_save_fields_method` if len(rekey_fields) > 0: - module.force_save_fields(rekey_fields) + block.force_save_fields(rekey_fields) diff --git a/xmodule/progress.py b/xmodule/progress.py index 014ce6369f09..dda88ad53eca 100644 --- a/xmodule/progress.py +++ b/xmodule/progress.py @@ -1,5 +1,5 @@ ''' -Progress class for modules. Represents where a student is in a module. +Progress class for blocks. Represents where a student is in a block. For most subclassing needs, you should only need to reimplement frac() and __str__(). @@ -15,8 +15,8 @@ class Progress: a and b must be numeric, but not necessarily integer, with 0 <= a <= b and b > 0. - Progress can only represent Progress for modules where that makes sense. Other - modules (e.g. html) should return None from get_progress(). + Progress can only represent Progress for blocks where that makes sense. Other + blocks (e.g. html) should return None from get_progress(). TODO: add tag for module type? Would allow for smarter merging. ''' diff --git a/xmodule/randomize_block.py b/xmodule/randomize_block.py index a9c6a706df41..6c17804b11bc 100644 --- a/xmodule/randomize_block.py +++ b/xmodule/randomize_block.py @@ -42,14 +42,14 @@ class RandomizeBlock( User notes: - - If you're randomizing amongst graded modules, each of them MUST be worth the same + - If you're randomizing amongst graded blocks, each of them MUST be worth the same number of points. Otherwise, the earth will be overrun by monsters from the deeps. You have been warned. Technical notes: - There is more dark magic in this code than I'd like. The whole varying-children + grading interaction is a tangle between super and subclasses of descriptors and - modules. + blocks. """ choice = Integer(help="Which random child was chosen", scope=Scope.user_state) @@ -71,8 +71,8 @@ def child(self): if self.choice is None: # choose one based on the system seed, or randomly if that's not available if num_choices > 0: - if self.system.seed is not None: - self.choice = self.system.seed % num_choices + if self.runtime.seed is not None: + self.choice = self.runtime.seed % num_choices else: self.choice = random.randrange(0, num_choices) @@ -120,6 +120,6 @@ def definition_to_xml(self, resource_fs): def has_dynamic_children(self): """ Grading needs to know that only one of the children is actually "real". This - makes it use module.get_child_descriptors(). + makes it use block.get_child_descriptors(). """ return True diff --git a/xmodule/raw_block.py b/xmodule/raw_block.py index 06668e3d460e..2b88e4a3a266 100644 --- a/xmodule/raw_block.py +++ b/xmodule/raw_block.py @@ -18,7 +18,7 @@ class RawMixin: """ resources_dir = None - data = String(help="XML data for the module", default="", scope=Scope.content) + data = String(help="XML data for the block", default="", scope=Scope.content) @classmethod def definition_from_xml(cls, xml_object, system): # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument @@ -52,7 +52,7 @@ def definition_to_xml(self, resource_fs): # lint-amnesty, pylint: disable=unuse lines = self.data.split('\n') line, offset = err.position msg = ( - "Unable to create xml for module {loc}. " + "Unable to create xml for block {loc}. " "Context: '{context}'" ).format( context=lines[line - 1][offset - 40:offset + 40], diff --git a/xmodule/seq_block.py b/xmodule/seq_block.py index 8e97a3e85953..242dbedfa490 100644 --- a/xmodule/seq_block.py +++ b/xmodule/seq_block.py @@ -1,5 +1,5 @@ """ -xModule implementation of a learning sequence +XBlock implementation of a learning sequence """ # pylint: disable=abstract-method @@ -39,7 +39,7 @@ from .fields import Date from .mako_block import MakoTemplateBlockBase from .progress import Progress -from .x_module import AUTHOR_VIEW, PUBLIC_VIEW, STUDENT_VIEW +from .x_module import AUTHOR_VIEW, PUBLIC_VIEW from .xml_block import XmlMixin @@ -306,10 +306,10 @@ def bind_for_student(self, xmodule_runtime, user_id, wrappers=None): # and needs to be read here after the ModuleSystem has been set on the XBlock. super().bind_for_student(xmodule_runtime, user_id, wrappers) # If position is specified in system, then use that instead. - position = getattr(self.system, 'position', None) + position = getattr(self.runtime, 'position', None) if position is not None: assert isinstance(position, int) - self.position = self.system.position + self.position = self.runtime.position def get_progress(self): ''' Return the total progress, adding total done and total available. diff --git a/xmodule/services.py b/xmodule/services.py index a12730d06bc6..5418ea4f196f 100644 --- a/xmodule/services.py +++ b/xmodule/services.py @@ -147,7 +147,7 @@ class RebindUserService(Service): """ An XBlock Service that allows modules to get rebound to real users if it was previously bound to an AnonymousUser. - This used to be a local function inside the `lms.djangoapps.courseware.module_render.get_module_system_for_user` + This used to be a local function inside the `lms.djangoapps.courseware.block_render.get_module_system_for_user` method, and was passed as a constructor argument to x_module.ModuleSystem. This has been refactored out into a service to simplify the ModuleSystem and lives in this module temporarily. @@ -160,7 +160,7 @@ class RebindUserService(Service): course (Course) - Course Object get_module_system_for_user (function) - The helper function that will be called to create a module system for a specfic user. This is the parent function from which this service was reactored out. - `lms.djangoapps.courseware.module_render.get_module_system_for_user` + `lms.djangoapps.courseware.block_render.get_module_system_for_user` kwargs (dict) - all the keyword arguments that need to be passed to the `get_module_system_for_user` function when it is called during rebinding """ diff --git a/xmodule/split_test_block.py b/xmodule/split_test_block.py index 1979009ca18f..c60d72c863ed 100644 --- a/xmodule/split_test_block.py +++ b/xmodule/split_test_block.py @@ -1,5 +1,5 @@ """ -Module for running content split tests +Block for running content split tests """ @@ -107,7 +107,7 @@ class SplitTestFields: # Block. (expected invariant that we'll need to test, and handle # authoring tools that mess this up) group_id_to_child = ReferenceValueDict( - help=_("Which child module students in a particular group_id should see"), + help=_("Which child block students in a particular group_id should see"), scope=Scope.content ) @@ -115,7 +115,7 @@ class SplitTestFields: def get_split_user_partitions(user_partitions): """ Helper method that filters a list of user_partitions and returns just the - ones that are suitable for the split_test module. + ones that are suitable for the split_test block. """ return [user_partition for user_partition in user_partitions if user_partition.scheme.name == "random"] @@ -148,7 +148,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method Technical notes: - There is more dark magic in this code than I'd like. The whole varying-children + grading interaction is a tangle between super and subclasses of descriptors and - modules. + blocks. """ resources_dir = 'assets/split_test' @@ -192,7 +192,7 @@ def child(self): Return the user bound child block for the partition or None. """ if self.child_descriptor is not None: - return self.system.get_module(self.child_descriptor) + return self.runtime.get_block_for_descriptor(self.child_descriptor) else: return None @@ -272,7 +272,7 @@ def _staff_view(self, context): for child_location in self.children: # pylint: disable=no-member child_descriptor = self.get_child_descriptor_by_location(child_location) - child = self.system.get_module(child_descriptor) + child = self.runtime.get_block_for_descriptor(child_descriptor) rendered_child = child.render(STUDENT_VIEW, context) fragment.add_fragment_resources(rendered_child) group_name, updated_group_id = self.get_data_for_vertical(child) @@ -347,7 +347,7 @@ def studio_render_children(self, fragment, children, context): """ html = "" for active_child_descriptor in children: - active_child = self.system.get_module(active_child_descriptor) + active_child = self.runtime.get_block_for_descriptor(active_child_descriptor) rendered_child = active_child.render(StudioEditableBlock.get_preview_view_name(active_child), context) if active_child.category == 'vertical': group_name, group_id = self.get_data_for_vertical(active_child) @@ -381,7 +381,7 @@ def student_view(self, context): # raise error instead? In fact, could complain on descriptor load... return Fragment(content="
        Nothing here. Move along.
        ") - if self.system.user_is_staff: + if self.runtime.user_is_staff: return self._staff_view(context) else: child_fragment = self.child.render(STUDENT_VIEW, context) @@ -467,7 +467,7 @@ def definition_from_xml(cls, xml_object, system): descriptor = system.process_xml(etree.tostring(child)) children.append(descriptor.scope_ids.usage_id) except Exception: # lint-amnesty, pylint: disable=broad-except - msg = "Unable to load child when parsing split_test module." + msg = "Unable to load child when parsing split_test block." log.exception(msg) system.error_tracker(msg) @@ -486,7 +486,7 @@ def get_context(self): def has_dynamic_children(self): """ Grading needs to know that only one of the children is actually "real". This - makes it use module.get_child_descriptors(). + makes it use block.get_child_descriptors(). """ return True @@ -540,7 +540,7 @@ def non_editable_metadata_fields(self): def get_selected_partition(self): """ - Returns the partition that this split module is currently using, or None + Returns the partition that this split block is currently using, or None if the currently selected partition ID does not match any of the defined partitions. """ for user_partition in self.user_partitions: # lint-amnesty, pylint: disable=not-an-iterable @@ -637,7 +637,7 @@ def validate_split_test(self): ) ) else: - # If the user_partition selected is not valid for the split_test module, error. + # If the user_partition selected is not valid for the split_test block, error. # This can only happen via XML and import/export. if not get_split_user_partitions([user_partition]): split_validation.add( @@ -704,15 +704,15 @@ def add_missing_groups(self, request, suffix=''): # lint-amnesty, pylint: disab if changed: # user.id - to be fixed by Publishing team - self.system.modulestore.update_item(self, None) + self.runtime.modulestore.update_item(self, None) return Response() @property def group_configuration_url(self): # lint-amnesty, pylint: disable=missing-function-docstring - assert hasattr(self.system, 'modulestore') and hasattr(self.system.modulestore, 'get_course'), \ + assert hasattr(self.runtime, 'modulestore') and hasattr(self.runtime.modulestore, 'get_course'), \ "modulestore has to be available" - course_block = self.system.modulestore.get_course(self.location.course_key) + course_block = self.runtime.modulestore.get_course(self.location.course_key) group_configuration_url = None if 'split_test' in course_block.advanced_modules: user_partition = self.get_selected_partition() @@ -732,9 +732,9 @@ def _create_vertical_for_group(self, group, user_id): A mutable modulestore is needed to call this method (will need to update after mixed modulestore work, currently relies on mongo's create_item method). """ - assert hasattr(self.system, 'modulestore') and hasattr(self.system.modulestore, 'create_item'), \ + assert hasattr(self.runtime, 'modulestore') and hasattr(self.runtime.modulestore, 'create_item'), \ "editor_saved should only be called when a mutable modulestore is available" - modulestore = self.system.modulestore + modulestore = self.runtime.modulestore dest_usage_key = self.location.replace(category="vertical", name=uuid4().hex) metadata = {'display_name': DEFAULT_GROUP_NAME.format(group_id=group.id)} modulestore.create_item( @@ -744,7 +744,7 @@ def _create_vertical_for_group(self, group, user_id): block_id=dest_usage_key.block_id, definition_data=None, metadata=metadata, - runtime=self.system, + runtime=self.runtime, ) self.children.append(dest_usage_key) # pylint: disable=no-member self.group_id_to_child[str(group.id)] = dest_usage_key diff --git a/xmodule/studio_editable.py b/xmodule/studio_editable.py index 287d72bab783..69d3126338cf 100644 --- a/xmodule/studio_editable.py +++ b/xmodule/studio_editable.py @@ -16,7 +16,7 @@ class StudioEditableBlock(XBlockMixin): def render_children(self, context, fragment, can_reorder=False, can_add=False): """ - Renders the children of the module with HTML appropriate for Studio. If can_reorder is True, + Renders the children of the block with HTML appropriate for Studio. If can_reorder is True, then the children will be rendered to support drag and drop. """ contents = [] @@ -43,7 +43,7 @@ def render_children(self, context, fragment, can_reorder=False, can_add=False): @staticmethod def get_preview_view_name(block): """ - Helper method for getting preview view name (student_view or author_view) for a given module. + Helper method for getting preview view name (student_view or author_view) for a given block. """ return AUTHOR_VIEW if has_author_view(block) else STUDENT_VIEW diff --git a/xmodule/template_block.py b/xmodule/template_block.py index 2c542ba4fcdd..70bafca7753e 100644 --- a/xmodule/template_block.py +++ b/xmodule/template_block.py @@ -42,7 +42,7 @@ class CustomTagTemplateBlock( # pylint: disable=abstract-method @XBlock.needs('mako') class CustomTagBlock(CustomTagTemplateBlock): # pylint: disable=abstract-method """ - This module supports tags of the form + This block supports tags of the form In this case, $tagname should refer to a file in data/custom_tags, which @@ -118,7 +118,7 @@ def render_template(self, system, xml_data): @property def rendered_html(self): - return self.render_template(self.system, self.data) + return self.render_template(self.runtime, self.data) def student_view(self, _context): """ diff --git a/xmodule/tests/__init__.py b/xmodule/tests/__init__.py index 4bdb43c9bba0..7770988f64c5 100644 --- a/xmodule/tests/__init__.py +++ b/xmodule/tests/__init__.py @@ -121,8 +121,8 @@ def get_test_system( id_manager = CourseLocationManager(course_id) - def get_module(descriptor): - """Mocks module_system get_module function""" + def get_block(descriptor): + """Mocks module_system get_block function""" # Unlike XBlock Runtimes or DescriptorSystems, # each XModule is provided with a new ModuleSystem. @@ -138,7 +138,7 @@ def get_module(descriptor): return descriptor return TestModuleSystem( - get_module=get_module, + get_block=get_block, services={ 'user': user_service, 'mako': mako_service, diff --git a/xmodule/tests/helpers.py b/xmodule/tests/helpers.py index 8c960a2b5717..2f7a399ab07c 100644 --- a/xmodule/tests/helpers.py +++ b/xmodule/tests/helpers.py @@ -42,7 +42,7 @@ def mock_render_template(*args, **kwargs): class StubMakoService: """ - Stub MakoService for testing modules that use mako templates. + Stub MakoService for testing blocks that use mako templates. """ def __init__(self, render_template=None): @@ -57,7 +57,7 @@ def render_template(self, *args, **kwargs): class StubUserService(UserService): """ - Stub UserService for testing the sequence module. + Stub UserService for testing the sequence block. """ def __init__(self, @@ -101,7 +101,7 @@ def get_user_by_anonymous_id(self, uid=None): # pylint: disable=unused-argument class StubReplaceURLService: """ - Stub ReplaceURLService for testing modules. + Stub ReplaceURLService for testing blocks. """ def replace_urls(self, text, static_replace_only=False): diff --git a/xmodule/tests/test_annotatable_block.py b/xmodule/tests/test_annotatable_block.py index b83be2248e6e..b9f419ee3a0f 100644 --- a/xmodule/tests/test_annotatable_block.py +++ b/xmodule/tests/test_annotatable_block.py @@ -1,4 +1,4 @@ -"""Module annotatable tests""" +"""Annotatable block tests""" import unittest diff --git a/xmodule/tests/test_capa_block.py b/xmodule/tests/test_capa_block.py index ac9726a0bcfe..2e14b2b1c9e6 100644 --- a/xmodule/tests/test_capa_block.py +++ b/xmodule/tests/test_capa_block.py @@ -42,7 +42,7 @@ class CapaFactory: """ - A helper class to create problem modules with various parameters for testing. + A helper class to create problem blocks with various parameters for testing. """ sample_problem_xml = textwrap.dedent("""\ @@ -93,8 +93,7 @@ def create(cls, attempts=None, problem_state=None, correct=False, xml=None, over force_save_button: rerandomize: all strings, as specified in the policy for the problem - problem_state: a dict to to be serialized into the instance_state of the - module. + problem_state: a dict to be serialized into the instance_state of the block. attempts: also added to instance state. Will be converted to an int. @@ -122,23 +121,23 @@ def create(cls, attempts=None, problem_state=None, correct=False, xml=None, over user_is_staff=kwargs.get('user_is_staff', False), render_template=render_template or Mock(return_value="
        Test Template HTML
        "), ) - module = ProblemBlock( + block = ProblemBlock( system, DictFieldData(field_data), ScopeIds(None, 'problem', location, location), ) - assert module.lcp + assert block.lcp if override_get_score: if correct: # TODO: probably better to actually set the internal state properly, but... - module.score = Score(raw_earned=1, raw_possible=1) + block.score = Score(raw_earned=1, raw_possible=1) else: - module.score = Score(raw_earned=0, raw_possible=1) + block.score = Score(raw_earned=0, raw_possible=1) - module.graded = 'False' - module.weight = 1 - return module + block.graded = 'False' + block.weight = 1 + return block class CapaFactoryWithFiles(CapaFactory): @@ -198,22 +197,22 @@ def setUp(self): self.two_day_delta_str = "2 days" def test_import(self): - module = CapaFactory.create() - assert module.get_score().raw_earned == 0 + block = CapaFactory.create() + assert block.get_score().raw_earned == 0 - other_module = CapaFactory.create() - assert module.get_score().raw_earned == 0 - assert module.url_name != other_module.url_name, 'Factory should be creating unique names for each problem' + other_block = CapaFactory.create() + assert block.get_score().raw_earned == 0 + assert block.url_name != other_block.url_name, 'Factory should be creating unique names for each problem' def test_correct(self): """ Check that the factory creates correct and incorrect problems properly. """ - module = CapaFactory.create() - assert module.get_score().raw_earned == 0 + block = CapaFactory.create() + assert block.get_score().raw_earned == 0 - other_module = CapaFactory.create(correct=True) - assert other_module.get_score().raw_earned == 1 + other_block = CapaFactory.create(correct=True) + assert other_block.get_score().raw_earned == 1 def test_get_score(self): """ @@ -223,20 +222,20 @@ def test_get_score(self): """ student_answers = {'1_2_1': 'abcd'} correct_map = CorrectMap(answer_id='1_2_1', correctness="correct", npoints=0.9) - module = CapaFactory.create(correct=True, override_get_score=False) - module.lcp.correct_map = correct_map - module.lcp.student_answers = student_answers - assert module.get_score().raw_earned == 0.0 - module.set_score(module.score_from_lcp(module.lcp)) - assert module.get_score().raw_earned == 0.9 + block = CapaFactory.create(correct=True, override_get_score=False) + block.lcp.correct_map = correct_map + block.lcp.student_answers = student_answers + assert block.get_score().raw_earned == 0.0 + block.set_score(block.score_from_lcp(block.lcp)) + assert block.get_score().raw_earned == 0.9 other_correct_map = CorrectMap(answer_id='1_2_1', correctness="incorrect", npoints=0.1) - other_module = CapaFactory.create(correct=False, override_get_score=False) - other_module.lcp.correct_map = other_correct_map - other_module.lcp.student_answers = student_answers - assert other_module.get_score().raw_earned == 0.0 - other_module.set_score(other_module.score_from_lcp(other_module.lcp)) - assert other_module.get_score().raw_earned == 0.1 + other_block = CapaFactory.create(correct=False, override_get_score=False) + other_block.lcp.correct_map = other_correct_map + other_block.lcp.student_answers = student_answers + assert other_block.get_score().raw_earned == 0.0 + other_block.set_score(other_block.score_from_lcp(other_block.lcp)) + assert other_block.get_score().raw_earned == 0.1 def test_showanswer_default(self): """ @@ -625,29 +624,29 @@ def test_show_correctness_past_due(self, problem_data, expected_result): def test_closed(self): # Attempts < Max attempts --> NOT closed - module = CapaFactory.create(max_attempts="1", attempts="0") - assert not module.closed() + block = CapaFactory.create(max_attempts="1", attempts="0") + assert not block.closed() # Attempts < Max attempts --> NOT closed - module = CapaFactory.create(max_attempts="2", attempts="1") - assert not module.closed() + block = CapaFactory.create(max_attempts="2", attempts="1") + assert not block.closed() # Attempts = Max attempts --> closed - module = CapaFactory.create(max_attempts="1", attempts="1") - assert module.closed() + block = CapaFactory.create(max_attempts="1", attempts="1") + assert block.closed() # Attempts > Max attempts --> closed - module = CapaFactory.create(max_attempts="1", attempts="2") - assert module.closed() + block = CapaFactory.create(max_attempts="1", attempts="2") + assert block.closed() # Max attempts = 0 --> closed - module = CapaFactory.create(max_attempts="0", attempts="2") - assert module.closed() + block = CapaFactory.create(max_attempts="0", attempts="2") + assert block.closed() # Past due --> closed - module = CapaFactory.create(max_attempts="1", attempts="0", - due=self.yesterday_str) - assert module.closed() + block = CapaFactory.create(max_attempts="1", attempts="0", + due=self.yesterday_str) + assert block.closed() def test_parse_get_params(self): @@ -699,7 +698,7 @@ def test_parse_get_params(self): def test_submit_problem_correct(self): - module = CapaFactory.create(attempts=1) + block = CapaFactory.create(attempts=1) # Simulate that all answers are marked correct, no matter # what the input is, by patching CorrectMap.is_correct() @@ -711,7 +710,7 @@ def test_submit_problem_correct(self): # Check the problem get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect that the problem is marked correct assert result['success'] == 'correct' @@ -720,13 +719,13 @@ def test_submit_problem_correct(self): assert result['contents'] == 'Test HTML' # Expect that the number of attempts is incremented by 1 - assert module.attempts == 2 + assert block.attempts == 2 # and that this was considered attempt number 2 for grading purposes - assert module.lcp.context['attempt'] == 2 + assert block.lcp.context['attempt'] == 2 def test_submit_problem_incorrect(self): - module = CapaFactory.create(attempts=0) + block = CapaFactory.create(attempts=0) # Simulate marking the input incorrect with patch('xmodule.capa.correctmap.CorrectMap.is_correct') as mock_is_correct: @@ -734,18 +733,18 @@ def test_submit_problem_incorrect(self): # Check the problem get_request_dict = {CapaFactory.input_key(): '0'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect that the problem is marked correct assert result['success'] == 'incorrect' # Expect that the number of attempts is incremented by 1 - assert module.attempts == 1 + assert block.attempts == 1 # and that this is considered the first attempt - assert module.lcp.context['attempt'] == 1 + assert block.lcp.context['attempt'] == 1 def test_submit_problem_closed(self): - module = CapaFactory.create(attempts=3) + block = CapaFactory.create(attempts=3) # Problem closed -- cannot submit # Simulate that ProblemBlock.closed() always returns True @@ -753,10 +752,10 @@ def test_submit_problem_closed(self): mock_closed.return_value = True with pytest.raises(xmodule.exceptions.NotFoundError): get_request_dict = {CapaFactory.input_key(): '3.14'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # Expect that number of attempts NOT incremented - assert module.attempts == 3 + assert block.attempts == 3 @ddt.data( RANDOMIZATION.ALWAYS, @@ -764,18 +763,18 @@ def test_submit_problem_closed(self): ) def test_submit_problem_resubmitted_with_randomize(self, rerandomize): # Randomize turned on - module = CapaFactory.create(rerandomize=rerandomize, attempts=0) + block = CapaFactory.create(rerandomize=rerandomize, attempts=0) # Simulate that the problem is completed - module.done = True + block.done = True # Expect that we cannot submit with pytest.raises(xmodule.exceptions.NotFoundError): get_request_dict = {CapaFactory.input_key(): '3.14'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # Expect that number of attempts NOT incremented - assert module.attempts == 0 + assert block.attempts == 0 @ddt.data( RANDOMIZATION.NEVER, @@ -784,20 +783,20 @@ def test_submit_problem_resubmitted_with_randomize(self, rerandomize): ) def test_submit_problem_resubmitted_no_randomize(self, rerandomize): # Randomize turned off - module = CapaFactory.create(rerandomize=rerandomize, attempts=0, done=True) + block = CapaFactory.create(rerandomize=rerandomize, attempts=0, done=True) # Expect that we can submit successfully get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) assert result['success'] == 'correct' # Expect that number of attempts IS incremented, still same attempt - assert module.attempts == 1 - assert module.lcp.context['attempt'] == 1 + assert block.attempts == 1 + assert block.lcp.context['attempt'] == 1 def test_submit_problem_queued(self): - module = CapaFactory.create(attempts=1) + block = CapaFactory.create(attempts=1) # Simulate that the problem is queued multipatch = patch.multiple( @@ -810,13 +809,13 @@ def test_submit_problem_queued(self): values['get_recentmost_queuetime'].return_value = datetime.datetime.now(UTC) get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' assert 'You must wait' in result['success'] # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 @patch.object(XQueueInterface, '_http_post') def test_submit_problem_with_files(self, mock_xqueue_post): @@ -830,7 +829,7 @@ def test_submit_problem_with_files(self, mock_xqueue_post): for fileobj in fileobjs: self.addCleanup(fileobj.close) - module = CapaFactoryWithFiles.create() + block = CapaFactoryWithFiles.create() # Mock the XQueueInterface post method mock_xqueue_post.return_value = (0, "ok") @@ -841,7 +840,7 @@ def test_submit_problem_with_files(self, mock_xqueue_post): CapaFactoryWithFiles.input_key(response_num=3): 'None', } - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # pylint: disable=line-too-long # _http_post is called like this: @@ -880,7 +879,7 @@ def test_submit_problem_with_files_as_xblock(self, mock_xqueue_post): for fileobj in fileobjs: self.addCleanup(fileobj.close) - module = CapaFactoryWithFiles.create() + block = CapaFactoryWithFiles.create() # Mock the XQueueInterface post method mock_xqueue_post.return_value = (0, "ok") @@ -892,7 +891,7 @@ def test_submit_problem_with_files_as_xblock(self, mock_xqueue_post): post_data.append((CapaFactoryWithFiles.input_key(response_num=3), 'None')) request = webob.Request.blank("/some/fake/url", POST=post_data, content_type='multipart/form-data') - module.handle('xmodule_handler', request, 'problem_check') + block.handle('xmodule_handler', request, 'problem_check') assert mock_xqueue_post.call_count == 1 _, kwargs = mock_xqueue_post.call_args @@ -907,15 +906,15 @@ def test_submit_problem_error(self): LoncapaProblemError, ResponseError] for exception_class in exception_classes: - # Create the module - module = CapaFactory.create(attempts=1, user_is_staff=False) + # Create the block + block = CapaFactory.create(attempts=1, user_is_staff=False) # Simulate answering a problem that raises the exception with patch('xmodule.capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = exception_class('test error') get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' expected_msg = 'test error' @@ -923,9 +922,9 @@ def test_submit_problem_error(self): assert expected_msg == result['success'] # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 # but that this was considered attempt number 2 for grading purposes - assert module.lcp.context['attempt'] == 2 + assert block.lcp.context['attempt'] == 2 def test_submit_problem_error_with_codejail_exception(self): @@ -935,8 +934,8 @@ def test_submit_problem_error_with_codejail_exception(self): ResponseError] for exception_class in exception_classes: - # Create the module - module = CapaFactory.create(attempts=1, user_is_staff=False) + # Create the block + block = CapaFactory.create(attempts=1, user_is_staff=False) # Simulate a codejail exception "Exception: Couldn't execute jailed code" with patch('xmodule.capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: @@ -951,16 +950,16 @@ def test_submit_problem_error_with_codejail_exception(self): except ResponseError as err: mock_grade.side_effect = exception_class(str(err)) get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' without the text of the stack trace expected_msg = 'Couldn\'t execute jailed code' assert expected_msg == result['success'] # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 # but that this was considered the second attempt for grading purposes - assert module.lcp.context['attempt'] == 2 + assert block.lcp.context['attempt'] == 2 @override_settings(DEBUG=True) def test_submit_problem_other_errors(self): @@ -969,8 +968,8 @@ def test_submit_problem_other_errors(self): See also `test_submit_problem_error` for the "expected kinds" or errors. """ - # Create the module - module = CapaFactory.create(attempts=1, user_is_staff=False) + # Create the block + block = CapaFactory.create(attempts=1, user_is_staff=False) # Simulate answering a problem that raises the exception with patch('xmodule.capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: @@ -978,7 +977,7 @@ def test_submit_problem_other_errors(self): mock_grade.side_effect = Exception(error_msg) get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' assert error_msg in result['success'] @@ -987,15 +986,15 @@ def test_submit_problem_zero_max_grade(self): """ Test that a capa problem with a max grade of zero doesn't generate an error. """ - # Create the module - module = CapaFactory.create(attempts=1) + # Create the block + block = CapaFactory.create(attempts=1) # Override the problem score to have a total of zero. - module.lcp.get_score = lambda: {'score': 0, 'total': 0} + block.lcp.get_score = lambda: {'score': 0, 'total': 0} # Check the problem get_request_dict = {CapaFactory.input_key(): '3.14'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) def test_submit_problem_error_nonascii(self): @@ -1004,15 +1003,15 @@ def test_submit_problem_error_nonascii(self): LoncapaProblemError, ResponseError] for exception_class in exception_classes: - # Create the module - module = CapaFactory.create(attempts=1, user_is_staff=False) + # Create the block + block = CapaFactory.create(attempts=1, user_is_staff=False) # Simulate answering a problem that raises the exception with patch('xmodule.capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = exception_class("ȧƈƈḗƞŧḗḓ ŧḗẋŧ ƒǿř ŧḗşŧīƞɠ") get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' expected_msg = 'ȧƈƈḗƞŧḗḓ ŧḗẋŧ ƒǿř ŧḗşŧīƞɠ' @@ -1020,9 +1019,9 @@ def test_submit_problem_error_nonascii(self): assert expected_msg == result['success'] # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 # but that this was considered the second attempt for grading purposes - assert module.lcp.context['attempt'] == 2 + assert block.lcp.context['attempt'] == 2 def test_submit_problem_error_with_staff_user(self): @@ -1030,15 +1029,15 @@ def test_submit_problem_error_with_staff_user(self): for exception_class in [StudentInputError, LoncapaProblemError, ResponseError]: - # Create the module - module = CapaFactory.create(attempts=1, user_is_staff=True) + # Create the block + block = CapaFactory.create(attempts=1, user_is_staff=True) # Simulate answering a problem that raises an exception with patch('xmodule.capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: mock_grade.side_effect = exception_class('test error') get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect an AJAX alert message in 'success' assert 'test error' in result['success'] @@ -1047,9 +1046,9 @@ def test_submit_problem_error_with_staff_user(self): assert 'Traceback' in result['success'] # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 # but that it was considered the second attempt for grading purposes - assert module.lcp.context['attempt'] == 2 + assert block.lcp.context['attempt'] == 2 @ddt.data( ("never", True, None, 'submitted'), @@ -1061,9 +1060,9 @@ def test_submit_problem_error_with_staff_user(self): ) @ddt.unpack def test_handle_ajax_show_correctness(self, show_correctness, is_correct, expected_score, expected_success): - module = CapaFactory.create(show_correctness=show_correctness, - due=self.tomorrow_str, - correct=is_correct) + block = CapaFactory.create(show_correctness=show_correctness, + due=self.tomorrow_str, + correct=is_correct) # Simulate marking the input correct/incorrect with patch('xmodule.capa.correctmap.CorrectMap.is_correct') as mock_is_correct: @@ -1071,7 +1070,7 @@ def test_handle_ajax_show_correctness(self, show_correctness, is_correct, expect # Check the problem get_request_dict = {CapaFactory.input_key(): '0'} - json_result = module.handle_ajax('problem_check', get_request_dict) + json_result = block.handle_ajax('problem_check', get_request_dict) result = json.loads(json_result) # Expect that the AJAX result withholds correctness and score @@ -1079,13 +1078,13 @@ def test_handle_ajax_show_correctness(self, show_correctness, is_correct, expect assert result['success'] == expected_success # Expect that the number of attempts is incremented by 1 - assert module.attempts == 1 - assert module.lcp.context['attempt'] == 1 + assert block.attempts == 1 + assert block.lcp.context['attempt'] == 1 def test_reset_problem(self): - module = CapaFactory.create(done=True) - module.new_lcp = Mock(wraps=module.new_lcp) - module.choose_new_seed = Mock(wraps=module.choose_new_seed) + block = CapaFactory.create(done=True) + block.new_lcp = Mock(wraps=block.new_lcp) + block.choose_new_seed = Mock(wraps=block.choose_new_seed) # Stub out HTML rendering with patch('xmodule.capa_block.ProblemBlock.get_problem_html') as mock_html: @@ -1093,7 +1092,7 @@ def test_reset_problem(self): # Reset the problem get_request_dict = {} - result = module.reset_problem(get_request_dict) + result = block.reset_problem(get_request_dict) # Expect that the request was successful assert (('success' in result) and result['success']) @@ -1103,11 +1102,11 @@ def test_reset_problem(self): assert result['html'] == '
        Test HTML
        ' # Expect that the problem was reset - module.new_lcp.assert_called_once_with(None) + block.new_lcp.assert_called_once_with(None) def test_reset_problem_closed(self): # pre studio default - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS) + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS) # Simulate that the problem is closed with patch('xmodule.capa_block.ProblemBlock.closed') as mock_closed: @@ -1115,25 +1114,25 @@ def test_reset_problem_closed(self): # Try to reset the problem get_request_dict = {} - result = module.reset_problem(get_request_dict) + result = block.reset_problem(get_request_dict) # Expect that the problem was NOT reset assert (('success' in result) and (not result['success'])) def test_reset_problem_not_done(self): # Simulate that the problem is NOT done - module = CapaFactory.create(done=False) + block = CapaFactory.create(done=False) # Try to reset the problem get_request_dict = {} - result = module.reset_problem(get_request_dict) + result = block.reset_problem(get_request_dict) # Expect that the problem was NOT reset assert (('success' in result) and (not result['success'])) def test_rescore_problem_correct(self): - module = CapaFactory.create(attempts=0, done=True) + block = CapaFactory.create(attempts=0, done=True) # Simulate that all answers are marked correct, no matter # what the input is, by patching LoncapaResponse.evaluate_answers() @@ -1148,91 +1147,91 @@ def test_rescore_problem_correct(self): # Check the problem get_request_dict = {CapaFactory.input_key(): '1'} - module.submit_problem(get_request_dict) - module.rescore(only_if_higher=False) + block.submit_problem(get_request_dict) + block.rescore(only_if_higher=False) # Expect that the problem is marked correct - assert module.is_correct() is True + assert block.is_correct() is True # Expect that the number of attempts is not incremented - assert module.attempts == 1 + assert block.attempts == 1 # and that this was considered attempt number 1 for grading purposes - assert module.lcp.context['attempt'] == 1 + assert block.lcp.context['attempt'] == 1 def test_rescore_problem_additional_correct(self): # make sure it also works when new correct answer has been added - module = CapaFactory.create(attempts=0) + block = CapaFactory.create(attempts=0) answer_id = CapaFactory.answer_key() # Check the problem get_request_dict = {CapaFactory.input_key(): '1'} - result = module.submit_problem(get_request_dict) + result = block.submit_problem(get_request_dict) # Expect that the problem is marked incorrect and user didn't earn score assert result['success'] == 'incorrect' - assert module.get_score() == (0, 1) - assert module.correct_map[answer_id]['correctness'] == 'incorrect' + assert block.get_score() == (0, 1) + assert block.correct_map[answer_id]['correctness'] == 'incorrect' # Expect that the number of attempts has incremented to 1 - assert module.attempts == 1 - assert module.lcp.context['attempt'] == 1 + assert block.attempts == 1 + assert block.lcp.context['attempt'] == 1 # Simulate that after making an incorrect answer to the correct answer # the new calculated score is (1,1) # by patching CorrectMap.is_correct() and NumericalResponse.get_staff_ans() - # In case of rescore with only_if_higher=True it should update score of module + # In case of rescore with only_if_higher=True it should update score of block # if previous score was lower with patch('xmodule.capa.correctmap.CorrectMap.is_correct') as mock_is_correct: mock_is_correct.return_value = True - module.set_score(module.score_from_lcp(module.lcp)) + block.set_score(block.score_from_lcp(block.lcp)) with patch('xmodule.capa.responsetypes.NumericalResponse.get_staff_ans') as get_staff_ans: get_staff_ans.return_value = 1 + 0j - module.rescore(only_if_higher=True) + block.rescore(only_if_higher=True) # Expect that the problem is marked correct and user earned the score - assert module.get_score() == (1, 1) - assert module.correct_map[answer_id]['correctness'] == 'correct' + assert block.get_score() == (1, 1) + assert block.correct_map[answer_id]['correctness'] == 'correct' # Expect that the number of attempts is not incremented - assert module.attempts == 1 + assert block.attempts == 1 # and hence that this was still considered the first attempt for grading purposes - assert module.lcp.context['attempt'] == 1 + assert block.lcp.context['attempt'] == 1 def test_rescore_problem_incorrect(self): # make sure it also works when attempts have been reset, # so add this to the test: - module = CapaFactory.create(attempts=0, done=True) + block = CapaFactory.create(attempts=0, done=True) # Simulate that all answers are marked incorrect, no matter # what the input is, by patching LoncapaResponse.evaluate_answers() with patch('xmodule.capa.responsetypes.LoncapaResponse.evaluate_answers') as mock_evaluate_answers: mock_evaluate_answers.return_value = CorrectMap(CapaFactory.answer_key(), 'incorrect') - module.rescore(only_if_higher=False) + block.rescore(only_if_higher=False) # Expect that the problem is marked incorrect - assert module.is_correct() is False + assert block.is_correct() is False # Expect that the number of attempts is not incremented - assert module.attempts == 0 + assert block.attempts == 0 # and that this is treated as the first attempt for grading purposes - assert module.lcp.context['attempt'] == 1 + assert block.lcp.context['attempt'] == 1 def test_rescore_problem_not_done(self): # Simulate that the problem is NOT done - module = CapaFactory.create(done=False) + block = CapaFactory.create(done=False) # Try to rescore the problem, and get exception with pytest.raises(xmodule.exceptions.NotFoundError): - module.rescore(only_if_higher=False) + block.rescore(only_if_higher=False) def test_rescore_problem_not_supported(self): - module = CapaFactory.create(done=True) + block = CapaFactory.create(done=True) # Try to rescore the problem, and get exception with patch('xmodule.capa.capa_problem.LoncapaProblem.supports_rescoring') as mock_supports_rescoring: mock_supports_rescoring.return_value = False with pytest.raises(NotImplementedError): - module.rescore(only_if_higher=False) + block.rescore(only_if_higher=False) def capa_factory_for_problem_xml(self, xml): # lint-amnesty, pylint: disable=missing-function-docstring class CustomCapaFactory(CapaFactory): @@ -1261,19 +1260,19 @@ def test_codejail_error_upon_problem_creation(self): def _rescore_problem_error_helper(self, exception_class): """Helper to allow testing all errors that rescoring might return.""" - # Create the module - module = CapaFactory.create(attempts=1, done=True) + # Create the block + block = CapaFactory.create(attempts=1, done=True) # Simulate answering a problem that raises the exception with patch('xmodule.capa.capa_problem.LoncapaProblem.get_grade_from_current_answers') as mock_rescore: mock_rescore.side_effect = exception_class('test error \u03a9') with pytest.raises(exception_class): - module.rescore(only_if_higher=False) + block.rescore(only_if_higher=False) # Expect that the number of attempts is NOT incremented - assert module.attempts == 1 + assert block.attempts == 1 # and that this was considered the first attempt for grading purposes - assert module.lcp.context['attempt'] == 1 + assert block.lcp.context['attempt'] == 1 def test_rescore_problem_student_input_error(self): self._rescore_problem_error_helper(StudentInputError) @@ -1285,21 +1284,21 @@ def test_rescore_problem_response_error(self): self._rescore_problem_error_helper(ResponseError) def test_save_problem(self): - module = CapaFactory.create(done=False) + block = CapaFactory.create(done=False) # Save the problem get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.save_problem(get_request_dict) + result = block.save_problem(get_request_dict) # Expect that answers are saved to the problem expected_answers = {CapaFactory.answer_key(): '3.14'} - assert module.lcp.student_answers == expected_answers + assert block.lcp.student_answers == expected_answers # Expect that the result is success assert (('success' in result) and result['success']) def test_save_problem_closed(self): - module = CapaFactory.create(done=False) + block = CapaFactory.create(done=False) # Simulate that the problem is closed with patch('xmodule.capa_block.ProblemBlock.closed') as mock_closed: @@ -1307,7 +1306,7 @@ def test_save_problem_closed(self): # Try to save the problem get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.save_problem(get_request_dict) + result = block.save_problem(get_request_dict) # Expect that the result is failure assert (('success' in result) and (not result['success'])) @@ -1318,11 +1317,11 @@ def test_save_problem_closed(self): ) def test_save_problem_submitted_with_randomize(self, rerandomize): # Capa XModule treats 'always' and 'true' equivalently - module = CapaFactory.create(rerandomize=rerandomize, done=True) + block = CapaFactory.create(rerandomize=rerandomize, done=True) # Try to save get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.save_problem(get_request_dict) + result = block.save_problem(get_request_dict) # Expect that we cannot save assert (('success' in result) and (not result['success'])) @@ -1333,198 +1332,198 @@ def test_save_problem_submitted_with_randomize(self, rerandomize): RANDOMIZATION.PER_STUDENT ) def test_save_problem_submitted_no_randomize(self, rerandomize): - # Capa XModule treats 'false' and 'per_student' equivalently - module = CapaFactory.create(rerandomize=rerandomize, done=True) + # Capa XBlock treats 'false' and 'per_student' equivalently + block = CapaFactory.create(rerandomize=rerandomize, done=True) # Try to save get_request_dict = {CapaFactory.input_key(): '3.14'} - result = module.save_problem(get_request_dict) + result = block.save_problem(get_request_dict) # Expect that we succeed assert (('success' in result) and result['success']) def test_submit_button_name(self): - module = CapaFactory.create(attempts=0) - assert module.submit_button_name() == 'Submit' + block = CapaFactory.create(attempts=0) + assert block.submit_button_name() == 'Submit' def test_submit_button_submitting_name(self): - module = CapaFactory.create(attempts=1, max_attempts=10) - assert module.submit_button_submitting_name() == 'Submitting' + block = CapaFactory.create(attempts=1, max_attempts=10) + assert block.submit_button_submitting_name() == 'Submitting' def test_should_enable_submit_button(self): attempts = random.randint(1, 10) # If we're after the deadline, disable the submit button - module = CapaFactory.create(due=self.yesterday_str) - assert not module.should_enable_submit_button() + block = CapaFactory.create(due=self.yesterday_str) + assert not block.should_enable_submit_button() # If user is out of attempts, disable the submit button - module = CapaFactory.create(attempts=attempts, max_attempts=attempts) - assert not module.should_enable_submit_button() + block = CapaFactory.create(attempts=attempts, max_attempts=attempts) + assert not block.should_enable_submit_button() # If survey question (max_attempts = 0), disable the submit button - module = CapaFactory.create(max_attempts=0) - assert not module.should_enable_submit_button() + block = CapaFactory.create(max_attempts=0) + assert not block.should_enable_submit_button() # If user submitted a problem but hasn't reset, # disable the submit button # Note: we can only reset when rerandomize="always" or "true" - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) - assert not module.should_enable_submit_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) + assert not block.should_enable_submit_button() - module = CapaFactory.create(rerandomize="true", done=True) - assert not module.should_enable_submit_button() + block = CapaFactory.create(rerandomize="true", done=True) + assert not block.should_enable_submit_button() # Otherwise, enable the submit button - module = CapaFactory.create() - assert module.should_enable_submit_button() + block = CapaFactory.create() + assert block.should_enable_submit_button() # If the user has submitted the problem # and we do NOT have a reset button, then we can enable the submit button # Setting rerandomize to "never" or "false" ensures that the reset button # is not shown - module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, done=True) - assert module.should_enable_submit_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, done=True) + assert block.should_enable_submit_button() - module = CapaFactory.create(rerandomize="false", done=True) - assert module.should_enable_submit_button() + block = CapaFactory.create(rerandomize="false", done=True) + assert block.should_enable_submit_button() - module = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, done=True) - assert module.should_enable_submit_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, done=True) + assert block.should_enable_submit_button() def test_should_show_reset_button(self): attempts = random.randint(1, 10) # If we're after the deadline, do NOT show the reset button - module = CapaFactory.create(due=self.yesterday_str, done=True) - assert not module.should_show_reset_button() + block = CapaFactory.create(due=self.yesterday_str, done=True) + assert not block.should_show_reset_button() # If the user is out of attempts, do NOT show the reset button - module = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True) - assert not module.should_show_reset_button() + block = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True) + assert not block.should_show_reset_button() # pre studio default value, DO show the reset button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) - assert module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) + assert block.should_show_reset_button() # If survey question for capa (max_attempts = 0), # DO show the reset button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True) - assert module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True) + assert block.should_show_reset_button() # If the question is not correct # DO show the reset button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=False) - assert module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=False) + assert block.should_show_reset_button() # If the question is correct and randomization is never # DO not show the reset button - module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=0, done=True, correct=True) - assert not module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=0, done=True, correct=True) + assert not block.should_show_reset_button() # If the question is correct and randomization is always # Show the reset button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=True) - assert module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=True) + assert block.should_show_reset_button() # Don't show reset button if randomization is turned on and the question is not done - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=False) - assert not module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=False) + assert not block.should_show_reset_button() # Show reset button if randomization is turned on and the problem is done - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=True) - assert module.should_show_reset_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=True) + assert block.should_show_reset_button() def test_should_show_save_button(self): attempts = random.randint(1, 10) # If we're after the deadline, do NOT show the save button - module = CapaFactory.create(due=self.yesterday_str, done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(due=self.yesterday_str, done=True) + assert not block.should_show_save_button() # If the user is out of attempts, do NOT show the save button - module = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True) + assert not block.should_show_save_button() # If user submitted a problem but hasn't reset, do NOT show the save button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True) + assert not block.should_show_save_button() - module = CapaFactory.create(rerandomize="true", done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(rerandomize="true", done=True) + assert not block.should_show_save_button() # If the user has unlimited attempts and we are not randomizing, # then do NOT show a save button # because they can keep using "Check" - module = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.NEVER, done=False) - assert not module.should_show_save_button() + block = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.NEVER, done=False) + assert not block.should_show_save_button() - module = CapaFactory.create(max_attempts=None, rerandomize="false", done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(max_attempts=None, rerandomize="false", done=True) + assert not block.should_show_save_button() - module = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.PER_STUDENT, done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.PER_STUDENT, done=True) + assert not block.should_show_save_button() # pre-studio default, DO show the save button - module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=False) - assert module.should_show_save_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=False) + assert block.should_show_save_button() # If we're not randomizing and we have limited attempts, then we can save - module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=2, done=True) - assert module.should_show_save_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=2, done=True) + assert block.should_show_save_button() - module = CapaFactory.create(rerandomize="false", max_attempts=2, done=True) - assert module.should_show_save_button() + block = CapaFactory.create(rerandomize="false", max_attempts=2, done=True) + assert block.should_show_save_button() - module = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, max_attempts=2, done=True) - assert module.should_show_save_button() + block = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, max_attempts=2, done=True) + assert block.should_show_save_button() # If survey question for capa (max_attempts = 0), # DO show the save button - module = CapaFactory.create(max_attempts=0, done=False) - assert module.should_show_save_button() + block = CapaFactory.create(max_attempts=0, done=False) + assert block.should_show_save_button() def test_should_show_save_button_force_save_button(self): # If we're after the deadline, do NOT show the save button # even though we're forcing a save - module = CapaFactory.create(due=self.yesterday_str, - force_save_button="true", - done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(due=self.yesterday_str, + force_save_button="true", + done=True) + assert not block.should_show_save_button() # If the user is out of attempts, do NOT show the save button attempts = random.randint(1, 10) - module = CapaFactory.create(attempts=attempts, - max_attempts=attempts, - force_save_button="true", - done=True) - assert not module.should_show_save_button() + block = CapaFactory.create(attempts=attempts, + max_attempts=attempts, + force_save_button="true", + done=True) + assert not block.should_show_save_button() # Otherwise, if we force the save button, # then show it even if we would ordinarily # require a reset first - module = CapaFactory.create(force_save_button="true", - rerandomize=RANDOMIZATION.ALWAYS, - done=True) - assert module.should_show_save_button() + block = CapaFactory.create(force_save_button="true", + rerandomize=RANDOMIZATION.ALWAYS, + done=True) + assert block.should_show_save_button() - module = CapaFactory.create(force_save_button="true", - rerandomize="true", - done=True) - assert module.should_show_save_button() + block = CapaFactory.create(force_save_button="true", + rerandomize="true", + done=True) + assert block.should_show_save_button() def test_no_max_attempts(self): - module = CapaFactory.create(max_attempts='') - html = module.get_problem_html() + block = CapaFactory.create(max_attempts='') + html = block.get_problem_html() assert html is not None # assert that we got here without exploding def test_get_problem_html(self): render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(render_template=render_template) + block = CapaFactory.create(render_template=render_template) # We've tested the show/hide button logic in other tests, # so here we hard-wire the values @@ -1532,19 +1531,19 @@ def test_get_problem_html(self): show_reset_button = bool(random.randint(0, 1) % 2) show_save_button = bool(random.randint(0, 1) % 2) - module.should_enable_submit_button = Mock(return_value=enable_submit_button) - module.should_show_reset_button = Mock(return_value=show_reset_button) - module.should_show_save_button = Mock(return_value=show_save_button) + block.should_enable_submit_button = Mock(return_value=enable_submit_button) + block.should_show_reset_button = Mock(return_value=show_reset_button) + block.should_show_save_button = Mock(return_value=show_save_button) # Patch the capa problem's HTML rendering with patch('xmodule.capa.capa_problem.LoncapaProblem.get_html') as mock_html: mock_html.return_value = "
        Test Problem HTML
        " # Render the problem HTML - html = module.get_problem_html(encapsulate=False) + html = block.get_problem_html(encapsulate=False) # Also render the problem encapsulated in a
        - html_encapsulated = module.get_problem_html(encapsulate=True) + html_encapsulated = block.get_problem_html(encapsulate=True) # Expect that we get the rendered template back assert html == '
        Test Template HTML
        ' @@ -1586,22 +1585,22 @@ def test_demand_hint(self): # HTML generation is mocked out to be meaningless here, so instead we check # the context dict passed into HTML generation. render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(xml=self.demand_xml, render_template=render_template) - module.get_problem_html() # ignoring html result + block = CapaFactory.create(xml=self.demand_xml, render_template=render_template) + block.get_problem_html() # ignoring html result context = render_template.call_args[0][1] assert context['demand_hint_possible'] assert context['should_enable_next_hint'] # Check the AJAX call that gets the hint by index - result = module.get_demand_hint(0) + result = block.get_demand_hint(0) assert result['hint_index'] == 0 assert result['should_enable_next_hint'] - result = module.get_demand_hint(1) + result = block.get_demand_hint(1) assert result['hint_index'] == 1 assert not result['should_enable_next_hint'] - result = module.get_demand_hint(2) # here the server wraps around to index 0 + result = block.get_demand_hint(2) # here the server wraps around to index 0 assert result['hint_index'] == 0 assert result['should_enable_next_hint'] @@ -1624,14 +1623,14 @@ def test_single_demand_hint(self): """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(xml=test_xml, render_template=render_template) - module.get_problem_html() # ignoring html result + block = CapaFactory.create(xml=test_xml, render_template=render_template) + block.get_problem_html() # ignoring html result context = render_template.call_args[0][1] assert context['demand_hint_possible'] assert context['should_enable_next_hint'] # Check the AJAX call that gets the hint by index - result = module.get_demand_hint(0) + result = block.get_demand_hint(0) assert result['hint_index'] == 0 assert not result['should_enable_next_hint'] @@ -1656,14 +1655,14 @@ def test_image_hint(self): """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(xml=test_xml, render_template=render_template) - module.get_problem_html() # ignoring html result + block = CapaFactory.create(xml=test_xml, render_template=render_template) + block.get_problem_html() # ignoring html result context = render_template.call_args[0][1] assert context['demand_hint_possible'] assert context['should_enable_next_hint'] # Check the AJAX call that gets the hint by index - result = module.get_demand_hint(0) + result = block.get_demand_hint(0) assert result['hint_index'] == 0 assert not result['should_enable_next_hint'] @@ -1671,27 +1670,27 @@ def test_demand_hint_logging(self): """ Test calling get_demand_hunt() results in an event being published. """ - module = CapaFactory.create(xml=self.demand_xml) - with patch.object(module.runtime, 'publish') as mock_publish: - module.get_problem_html() - module.get_demand_hint(0) + block = CapaFactory.create(xml=self.demand_xml) + with patch.object(block.runtime, 'publish') as mock_publish: + block.get_problem_html() + block.get_demand_hint(0) mock_publish.assert_called_with( - module, 'edx.problem.hint.demandhint_displayed', - {'hint_index': 0, 'module_id': str(module.location), + block, 'edx.problem.hint.demandhint_displayed', + {'hint_index': 0, 'module_id': str(block.location), 'hint_text': 'Demand 1', 'hint_len': 2} ) def test_input_state_consistency(self): - module1 = CapaFactory.create() - module2 = CapaFactory.create() + block1 = CapaFactory.create() + block2 = CapaFactory.create() # check to make sure that the input_state and the keys have the same values - module1.set_state_from_lcp() - assert list(module1.lcp.inputs.keys()) == list(module1.input_state.keys()) + block1.set_state_from_lcp() + assert list(block1.lcp.inputs.keys()) == list(block1.input_state.keys()) - module2.set_state_from_lcp() + block2.set_state_from_lcp() - intersection = set(module2.input_state.keys()).intersection(set(module1.input_state.keys())) + intersection = set(block2.input_state.keys()).intersection(set(block1.input_state.keys())) assert len(intersection) == 0 def test_get_problem_html_error(self): @@ -1701,17 +1700,17 @@ def test_get_problem_html_error(self): message to display to the user. """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(render_template=render_template) + block = CapaFactory.create(render_template=render_template) # Save the original problem so we can compare it later - original_problem = module.lcp + original_problem = block.lcp # Simulate throwing an exception when the capa problem # is asked to render itself as HTML - module.lcp.get_html = Mock(side_effect=Exception("Test")) + block.lcp.get_html = Mock(side_effect=Exception("Test")) - # Try to render the module with DEBUG turned off - html = module.get_problem_html() + # Try to render the block with DEBUG turned off + html = block.get_problem_html() assert html is not None @@ -1720,25 +1719,25 @@ def test_get_problem_html_error(self): context = render_args[1] assert 'error' in context['problem']['html'] - # Expect that the module has created a new dummy problem with the error - assert original_problem != module.lcp + # Expect that the block has created a new dummy problem with the error + assert original_problem != block.lcp def test_get_problem_html_error_preview(self): """ Test the html response when an error occurs with DEBUG off in Studio. """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(render_template=render_template) + block = CapaFactory.create(render_template=render_template) # Simulate throwing an exception when the capa problem # is asked to render itself as HTML error_msg = "Superterrible error happened: ☠" - module.lcp.get_html = Mock(side_effect=Exception(error_msg)) + block.lcp.get_html = Mock(side_effect=Exception(error_msg)) - module.system.is_author_mode = True + block.runtime.is_author_mode = True - # Try to render the module with the author mode turned on - html = module.get_problem_html() + # Try to render the block with the author mode turned on + html = block.get_problem_html() assert html is not None @@ -1753,15 +1752,15 @@ def test_get_problem_html_error_w_debug(self): Test the html response when an error occurs with DEBUG on """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(render_template=render_template) + block = CapaFactory.create(render_template=render_template) # Simulate throwing an exception when the capa problem # is asked to render itself as HTML error_msg = "Superterrible error happened: ☠" - module.lcp.get_html = Mock(side_effect=Exception(error_msg)) + block.lcp.get_html = Mock(side_effect=Exception(error_msg)) - # Try to render the module with DEBUG turned on - html = module.get_problem_html() + # Try to render the block with DEBUG turned on + html = block.get_problem_html() assert html is not None @@ -1782,11 +1781,11 @@ def test_random_seed_no_change(self, rerandomize): # Run the test for each possible rerandomize value - module = CapaFactory.create(rerandomize=rerandomize) + block = CapaFactory.create(rerandomize=rerandomize) # Get the seed - # By this point, the module should have persisted the seed - seed = module.seed + # By this point, the block should have persisted the seed + seed = block.seed assert seed is not None # If we're not rerandomizing, the seed is always set @@ -1796,16 +1795,16 @@ def test_random_seed_no_change(self, rerandomize): # Check the problem get_request_dict = {CapaFactory.input_key(): '3.14'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # Expect that the seed is the same - assert seed == module.seed + assert seed == block.seed # Save the problem - module.save_problem(get_request_dict) + block.save_problem(get_request_dict) # Expect that the seed is the same - assert seed == module.seed + assert seed == block.seed @ddt.data( 'false', @@ -1820,22 +1819,22 @@ def test_random_seed_with_reset(self, rerandomize): Run the test for each possible rerandomize value """ - def _reset_and_get_seed(module): + def _reset_and_get_seed(block): """ - Reset the XModule and return the module's seed + Reset the XBlock and return the block's seed """ # Simulate submitting an attempt # We need to do this, or reset_problem() will # fail because it won't re-randomize until the problem has been submitted # the problem yet. - module.done = True + block.done = True # Reset the problem - module.reset_problem({}) + block.reset_problem({}) # Return the seed - return module.seed + return block.seed def _retry_and_check(num_tries, test_func): ''' @@ -1852,11 +1851,11 @@ def _retry_and_check(num_tries, test_func): break return success - module = CapaFactory.create(rerandomize=rerandomize, done=True) + block = CapaFactory.create(rerandomize=rerandomize, done=True) # Get the seed - # By this point, the module should have persisted the seed - seed = module.seed + # By this point, the block should have persisted the seed + seed = block.seed assert seed is not None # We do NOT want the seed to reset if rerandomize @@ -1866,7 +1865,7 @@ def _retry_and_check(num_tries, test_func): if rerandomize in [RANDOMIZATION.NEVER, 'false', RANDOMIZATION.PER_STUDENT]: - assert seed == _reset_and_get_seed(module) + assert seed == _reset_and_get_seed(block) # Otherwise, we expect the seed to change # to another valid seed @@ -1875,9 +1874,9 @@ def _retry_and_check(num_tries, test_func): # Since there's a small chance (expected) we might get the # same seed again, give it 10 chances # to generate a different seed - success = _retry_and_check(10, lambda: _reset_and_get_seed(module) != seed) + success = _retry_and_check(10, lambda: _reset_and_get_seed(block) != seed) - assert module.seed is not None + assert block.seed is not None msg = 'Could not get a new seed from reset after 10 tries' assert success, msg @@ -1894,27 +1893,27 @@ def test_random_seed_with_reset_question_unsubmitted(self, rerandomize): Run the test for each possible rerandomize value """ - def _reset_and_get_seed(module): + def _reset_and_get_seed(block): """ - Reset the XModule and return the module's seed + Reset the XBlock and return the block's seed """ # Reset the problem # By default, the problem is instantiated as unsubmitted - module.reset_problem({}) + block.reset_problem({}) # Return the seed - return module.seed + return block.seed - module = CapaFactory.create(rerandomize=rerandomize, done=False) + block = CapaFactory.create(rerandomize=rerandomize, done=False) # Get the seed - # By this point, the module should have persisted the seed - seed = module.seed + # By this point, the block should have persisted the seed + seed = block.seed assert seed is not None # the seed should never change because the student hasn't finished the problem - assert seed == _reset_and_get_seed(module) + assert seed == _reset_and_get_seed(block) @ddt.data( RANDOMIZATION.ALWAYS, @@ -1927,8 +1926,8 @@ def test_random_seed_bins(self, rerandomize): # Get a bunch of seeds, they should all be in 0-999. i = 200 while i > 0: - module = CapaFactory.create(rerandomize=rerandomize) - assert 0 <= module.seed < 1000 + block = CapaFactory.create(rerandomize=rerandomize) + assert 0 <= block.seed < 1000 i -= 1 @patch('xmodule.capa_block.log') @@ -1940,8 +1939,8 @@ def test_get_progress_error(self, mock_progress, mock_log): error_types = [TypeError, ValueError] for error_type in error_types: mock_progress.side_effect = error_type - module = CapaFactory.create() - assert module.get_progress() is None + block = CapaFactory.create() + assert block.get_progress() is None mock_log.exception.assert_called_once_with('Got bad progress') mock_log.reset_mock() @@ -1951,9 +1950,9 @@ def test_get_progress_no_error_if_weight_zero(self, mock_progress): Check that if the weight is 0 get_progress does not try to create a Progress object. """ mock_progress.return_value = True - module = CapaFactory.create() - module.weight = 0 - progress = module.get_progress() + block = CapaFactory.create() + block.weight = 0 + progress = block.get_progress() assert progress is None assert not mock_progress.called @@ -1962,14 +1961,14 @@ def test_get_progress_calculate_progress_fraction(self, mock_progress): """ Check that score and total are calculated correctly for the progress fraction. """ - module = CapaFactory.create() - module.weight = 1 - module.get_progress() + block = CapaFactory.create() + block.weight = 1 + block.get_progress() mock_progress.assert_called_with(0, 1) - other_module = CapaFactory.create(correct=True) - other_module.weight = 1 - other_module.get_progress() + other_block = CapaFactory.create(correct=True) + other_block.weight = 1 + other_block.get_progress() mock_progress.assert_called_with(1, 1) @ddt.data( @@ -1985,11 +1984,11 @@ def test_get_display_progress_show_correctness(self, show_correctness, is_correc """ Check that score and total are calculated correctly for the progress fraction. """ - module = CapaFactory.create(correct=is_correct, - show_correctness=show_correctness, - due=self.tomorrow_str) - module.weight = 1 - score, total = module.get_display_progress() + block = CapaFactory.create(correct=is_correct, + show_correctness=show_correctness, + due=self.tomorrow_str) + block.weight = 1 + score, total = block.get_display_progress() assert score == expected_score assert total == 1 @@ -1997,17 +1996,17 @@ def test_get_html(self): """ Check that get_html() calls get_progress() with no arguments. """ - module = CapaFactory.create() - module.get_progress = Mock(wraps=module.get_progress) - module.get_html() - module.get_progress.assert_called_with() + block = CapaFactory.create() + block.get_progress = Mock(wraps=block.get_progress) + block.get_html() + block.get_progress.assert_called_with() def test_get_problem(self): """ Check that get_problem() returns the expected dictionary. """ - module = CapaFactory.create() - assert module.get_problem('data') == {'html': module.get_problem_html(encapsulate=False)} + block = CapaFactory.create() + assert block.get_problem('data') == {'html': block.get_problem_html(encapsulate=False)} # Standard question with shuffle="true" used by a few tests common_shuffle_xml = textwrap.dedent(""" @@ -2028,10 +2027,10 @@ def test_check_unmask(self): Check that shuffle unmasking is plumbed through: when submit_problem is called, unmasked names should appear in the publish event_info. """ - module = CapaFactory.create(xml=self.common_shuffle_xml) - with patch.object(module.runtime, 'publish') as mock_publish: + block = CapaFactory.create(xml=self.common_shuffle_xml) + with patch.object(block.runtime, 'publish') as mock_publish: get_request_dict = {CapaFactory.input_key(): 'choice_3'} # the correct choice - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) mock_call = mock_publish.mock_calls[1] event_info = mock_call[1][2] assert event_info['answers'][CapaFactory.answer_key()] == 'choice_3' @@ -2043,10 +2042,10 @@ def test_check_unmask(self): @unittest.skip("masking temporarily disabled") def test_save_unmask(self): """On problem save, unmasked data should appear on publish.""" - module = CapaFactory.create(xml=self.common_shuffle_xml) - with patch.object(module.runtime, 'publish') as mock_publish: + block = CapaFactory.create(xml=self.common_shuffle_xml) + with patch.object(block.runtime, 'publish') as mock_publish: get_request_dict = {CapaFactory.input_key(): 'mask_0'} - module.save_problem(get_request_dict) + block.save_problem(get_request_dict) mock_call = mock_publish.mock_calls[0] event_info = mock_call[1][1] assert event_info['answers'][CapaFactory.answer_key()] == 'choice_2' @@ -2055,12 +2054,12 @@ def test_save_unmask(self): @unittest.skip("masking temporarily disabled") def test_reset_unmask(self): """On problem reset, unmask names should appear publish.""" - module = CapaFactory.create(xml=self.common_shuffle_xml) + block = CapaFactory.create(xml=self.common_shuffle_xml) get_request_dict = {CapaFactory.input_key(): 'mask_0'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # On reset, 'old_state' should use unmasked names - with patch.object(module.runtime, 'publish') as mock_publish: - module.reset_problem(None) + with patch.object(block.runtime, 'publish') as mock_publish: + block.reset_problem(None) mock_call = mock_publish.mock_calls[0] event_info = mock_call[1][1] assert mock_call[1][0] == 'reset_problem' @@ -2070,12 +2069,12 @@ def test_reset_unmask(self): @unittest.skip("masking temporarily disabled") def test_rescore_unmask(self): """On problem rescore, unmasked names should appear on publish.""" - module = CapaFactory.create(xml=self.common_shuffle_xml) + block = CapaFactory.create(xml=self.common_shuffle_xml) get_request_dict = {CapaFactory.input_key(): 'mask_0'} - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) # On rescore, state/student_answers should use unmasked names - with patch.object(module.runtime, 'publish') as mock_publish: - module.rescore_problem(only_if_higher=False) # lint-amnesty, pylint: disable=no-member + with patch.object(block.runtime, 'publish') as mock_publish: + block.rescore_problem(only_if_higher=False) # lint-amnesty, pylint: disable=no-member mock_call = mock_publish.mock_calls[0] event_info = mock_call[1][1] assert mock_call[1][0] == 'problem_rescore' @@ -2096,10 +2095,10 @@ def test_check_unmask_answerpool(self): """) - module = CapaFactory.create(xml=xml) - with patch.object(module.runtime, 'publish') as mock_publish: + block = CapaFactory.create(xml=xml) + with patch.object(block.runtime, 'publish') as mock_publish: get_request_dict = {CapaFactory.input_key(): 'choice_2'} # mask_X form when masking enabled - module.submit_problem(get_request_dict) + block.submit_problem(get_request_dict) mock_call = mock_publish.mock_calls[1] event_info = mock_call[1][2] assert event_info['answers'][CapaFactory.answer_key()] == 'choice_2' @@ -2119,8 +2118,8 @@ def test_problem_display_name_with_default(self, display_name, expected_display_ """ Verify that display_name_with_default works as expected. """ - module = CapaFactory.create(display_name=display_name) - assert module.display_name_with_default == expected_display_name + block = CapaFactory.create(display_name=display_name) + assert block.display_name_with_default == expected_display_name @ddt.data( '', @@ -2131,11 +2130,11 @@ def test_problem_no_display_name(self, display_name): Verify that if problem display name is not provided then a default name is used. """ render_template = Mock(return_value="
        Test Template HTML
        ") - module = CapaFactory.create(display_name=display_name, render_template=render_template) - module.get_problem_html() + block = CapaFactory.create(display_name=display_name, render_template=render_template) + block.get_problem_html() render_args, _ = render_template.call_args context = render_args[1] - assert context['problem']['name'] == module.location.block_type + assert context['problem']['name'] == block.location.block_type @ddt.ddt @@ -2941,14 +2940,14 @@ def test_choice_answer_text(self): # Whitespace screws up comparisons xml = ''.join(line.strip() for line in xml.split('\n')) factory = self.capa_factory_for_problem_xml(xml) - module = factory.create() + block = factory.create() answer_input_dict = { factory.input_key(2): 'blue', factory.input_key(3): 'choice_0', factory.input_key(4): ['choice_0', 'choice_1'], } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2): {'question': 'What color is the open ocean on a sunny day?', @@ -2981,9 +2980,9 @@ class CustomCapaFactory(CapaFactory): return CustomCapaFactory - def get_event_for_answers(self, module, answer_input_dict): # lint-amnesty, pylint: disable=missing-function-docstring - with patch.object(module.runtime, 'publish') as mock_publish: - module.submit_problem(answer_input_dict) + def get_event_for_answers(self, block, answer_input_dict): # lint-amnesty, pylint: disable=missing-function-docstring + with patch.object(block.runtime, 'publish') as mock_publish: + block.submit_problem(answer_input_dict) assert len(mock_publish.mock_calls) >= 2 # There are potentially 2 track logs: answers and hint. [-1]=answers. @@ -2994,13 +2993,13 @@ def get_event_for_answers(self, module, answer_input_dict): # lint-amnesty, pyl def test_numerical_textline(self): factory = CapaFactory - module = factory.create() + block = factory.create() answer_input_dict = { factory.input_key(2): '3.14' } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2): {'question': '', 'answer': '3.14', 'response_type': 'numericalresponse', @@ -3022,13 +3021,13 @@ def test_multiple_inputs(self): """.format(group_label, input1_label, input2_label)) - module = factory.create() + block = factory.create() answer_input_dict = { factory.input_key(2, 1): 'blue', factory.input_key(2, 2): 'yellow', } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2, 1): {'group_label': group_label, 'question': input1_label, @@ -3084,14 +3083,14 @@ def test_optioninput_extended_xml(self): """.format(group_label, input1_label, input2_label)) - module = factory.create() + block = factory.create() answer_input_dict = { factory.input_key(2, 1): 'apple', factory.input_key(2, 2): 'cucumber', } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2, 1): {'group_label': group_label, 'question': input1_label, @@ -3108,13 +3107,13 @@ def test_optioninput_extended_xml(self): def test_rerandomized_inputs(self): factory = CapaFactory - module = factory.create(rerandomize=RANDOMIZATION.ALWAYS) + block = factory.create(rerandomize=RANDOMIZATION.ALWAYS) answer_input_dict = { factory.input_key(2): '3.14' } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2): {'question': '', 'answer': '3.14', @@ -3122,7 +3121,7 @@ def test_rerandomized_inputs(self): 'input_type': 'textline', 'correct': True, 'group_label': '', - 'variant': module.seed}} + 'variant': block.seed}} @patch.object(XQueueInterface, '_http_post') def test_file_inputs(self, mock_xqueue_post): @@ -3133,7 +3132,7 @@ def test_file_inputs(self, mock_xqueue_post): self.addCleanup(fileobj.close) factory = CapaFactoryWithFiles - module = factory.create() + block = factory.create() # Mock the XQueueInterface post method mock_xqueue_post.return_value = (0, "ok") @@ -3143,7 +3142,7 @@ def test_file_inputs(self, mock_xqueue_post): CapaFactoryWithFiles.input_key(response_num=3): 'None', } - event = self.get_event_for_answers(module, answer_input_dict) + event = self.get_event_for_answers(block, answer_input_dict) assert event['submission'] ==\ {factory.answer_key(2): {'question': '', 'answer': fpaths, diff --git a/xmodule/tests/test_conditional.py b/xmodule/tests/test_conditional.py index 8f63150a9262..b36ae92b63a7 100644 --- a/xmodule/tests/test_conditional.py +++ b/xmodule/tests/test_conditional.py @@ -29,16 +29,16 @@ class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring @patch('xmodule.modulestore.xml.OSFS', lambda directory: MemoryFS()) - def __init__(self, load_error_modules): + def __init__(self, load_error_blocks): - xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) + xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_blocks=load_error_blocks) super().__init__( xmlstore=xmlstore, course_id=CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])), course_dir='test_dir', error_tracker=Mock(), - load_error_modules=load_error_modules, + load_error_blocks=load_error_blocks, ) def render_template(self, template, context): # lint-amnesty, pylint: disable=method-hidden @@ -58,20 +58,20 @@ class ConditionalFactory: to allow for testing. """ @staticmethod - def create(system, source_is_error_module=False, source_visible_to_staff_only=False): + def create(system, source_is_error_block=False, source_visible_to_staff_only=False): """ - return a dict of modules: the conditional with a single source and a single child. - Keys are 'cond_module', 'source_module', and 'child_module'. + return a dict of blocks: the conditional with a single source and a single child. + Keys are 'cond_block', 'source_block', and 'child_block'. - if the source_is_error_module flag is set, create a real ErrorBlock for the source. + 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), "problem", "SampleProblem", deprecated=True) - if source_is_error_module: - # Make an error descriptor and module + if source_is_error_block: + # Make an error descriptor and block source_descriptor = ErrorBlock.from_xml( 'some random xml data', system, @@ -130,15 +130,15 @@ def load_item(usage_id, for_parent=None): # pylint: disable=unused-argument ScopeIds(None, None, cond_location, cond_location) ) cond_descriptor.xmodule_runtime = system - system.get_module = lambda desc: desc if visible_to_nonstaff_users(desc) else None + system.get_block_for_descriptor = lambda desc: desc if visible_to_nonstaff_users(desc) else None cond_descriptor.get_required_blocks = [ - system.get_module(source_descriptor), + system.get_block_for_descriptor(source_descriptor), ] # return dict: - return {'cond_module': cond_descriptor, - 'source_module': source_descriptor, - 'child_module': child_descriptor} + return {'cond_block': cond_descriptor, + 'source_block': source_descriptor, + 'child_block': child_descriptor} class ConditionalBlockBasicTest(unittest.TestCase): @@ -153,38 +153,38 @@ def setUp(self): def test_icon_class(self): '''verify that get_icon_class works independent of condition satisfaction''' - modules = ConditionalFactory.create(self.test_system) + blocks = ConditionalFactory.create(self.test_system) for attempted in ["false", "true"]: for icon_class in ['other', 'problem', 'video']: - modules['source_module'].is_attempted = attempted - modules['child_module'].get_icon_class = lambda: icon_class # lint-amnesty, pylint: disable=cell-var-from-loop - assert modules['cond_module'].get_icon_class() == icon_class + blocks['source_block'].is_attempted = attempted + blocks['child_block'].get_icon_class = lambda: icon_class # lint-amnesty, pylint: disable=cell-var-from-loop + assert blocks['cond_block'].get_icon_class() == icon_class def test_get_html(self): - modules = ConditionalFactory.create(self.test_system) + blocks = ConditionalFactory.create(self.test_system) # because get_test_system returns the repr of the context dict passed to render_template, # we reverse it here - html = modules['cond_module'].render(STUDENT_VIEW).content - mako_service = modules['cond_module'].xmodule_runtime.service(modules['cond_module'], 'mako') + html = blocks['cond_block'].render(STUDENT_VIEW).content + mako_service = blocks['cond_block'].xmodule_runtime.service(blocks['cond_block'], 'mako') expected = mako_service.render_template('conditional_ajax.html', { - 'ajax_url': modules['cond_module'].ajax_url, + 'ajax_url': blocks['cond_block'].ajax_url, 'element_id': 'i4x-edX-conditional_test-conditional-SampleConditional', 'depends': 'i4x-edX-conditional_test-problem-SampleProblem', }) assert expected == html def test_handle_ajax(self): - modules = ConditionalFactory.create(self.test_system) - modules['cond_module'].save() - modules['source_module'].is_attempted = "false" - ajax = json.loads(modules['cond_module'].handle_ajax('', '')) + blocks = ConditionalFactory.create(self.test_system) + blocks['cond_block'].save() + blocks['source_block'].is_attempted = "false" + ajax = json.loads(blocks['cond_block'].handle_ajax('', '')) fragments = ajax['fragments'] assert not any(('This is a secret' in item['content']) for item in fragments) # now change state of the capa problem to make it completed - modules['source_module'].is_attempted = "true" - ajax = json.loads(modules['cond_module'].handle_ajax('', '')) - modules['cond_module'].save() + blocks['source_block'].is_attempted = "true" + ajax = json.loads(blocks['cond_block'].handle_ajax('', '')) + blocks['cond_block'].save() fragments = ajax['fragments'] assert any(('This is a secret' in item['content']) for item in fragments) @@ -193,24 +193,24 @@ def test_error_as_source(self): Check that handle_ajax works properly if the source is really an ErrorBlock, and that the condition is not satisfied. ''' - modules = ConditionalFactory.create(self.test_system, source_is_error_module=True) - modules['cond_module'].save() - ajax = json.loads(modules['cond_module'].handle_ajax('', '')) + blocks = ConditionalFactory.create(self.test_system, source_is_error_block=True) + blocks['cond_block'].save() + ajax = json.loads(blocks['cond_block'].handle_ajax('', '')) fragments = ajax['fragments'] assert not any(('This is a secret' in item['content']) for item in fragments) @patch('xmodule.conditional_block.log') - def test_conditional_with_staff_only_source_module(self, mock_log): - modules = ConditionalFactory.create( + def test_conditional_with_staff_only_source_block(self, mock_log): + blocks = ConditionalFactory.create( self.test_system, source_visible_to_staff_only=True, ) - cond_module = modules['cond_module'] - cond_module.save() - cond_module.is_attempted = "false" - cond_module.handle_ajax('', '') + cond_block = blocks['cond_block'] + cond_block.save() + cond_block.is_attempted = "false" + cond_block.handle_ajax('', '') assert not mock_log.warn.called - assert None in cond_module.get_required_blocks + assert None in cond_block.get_required_blocks class ConditionalBlockXmlTest(unittest.TestCase): @@ -226,9 +226,9 @@ def setUp(self): assert len(courses) == 1 self.course = courses[0] - def get_module_for_location(self, location): + def get_block_for_location(self, location): descriptor = self.modulestore.get_item(location, depth=None) - return self.test_system.get_module(descriptor) + return self.test_system.get_block_for_descriptor(descriptor) @patch('xmodule.x_module.descriptor_global_local_resource_url') @patch.dict(settings.FEATURES, {'ENABLE_EDXNOTES': False}) @@ -239,9 +239,9 @@ def test_conditional_block(self, _): location = BlockUsageLocator(CourseLocator("HarvardX", "ER22x", "2013_Spring", deprecated=True), "conditional", "condone", deprecated=True) - module = self.get_module_for_location(location) - html = module.render(STUDENT_VIEW).content - mako_service = module.xmodule_runtime.service(module, 'mako') + block = self.get_block_for_location(location) + html = block.render(STUDENT_VIEW).content + mako_service = block.xmodule_runtime.service(block, 'mako') html_expect = mako_service.render_template( 'conditional_ajax.html', { @@ -253,17 +253,17 @@ def test_conditional_block(self, _): ) assert html == html_expect - ajax = json.loads(module.handle_ajax('', '')) + ajax = json.loads(block.handle_ajax('', '')) fragments = ajax['fragments'] assert not any(('This is a secret' in item['content']) for item in fragments) # Now change state of the capa problem to make it completed - inner_module = self.get_module_for_location(location.replace(category="problem", name='choiceprob')) - inner_module.attempts = 1 + inner_block = self.get_block_for_location(location.replace(category="problem", name='choiceprob')) + inner_block.attempts = 1 # Save our modifications to the underlying KeyValueStore so they can be persisted - inner_module.save() + inner_block.save() - ajax = json.loads(module.handle_ajax('', '')) + ajax = json.loads(block.handle_ajax('', '')) fragments = ajax['fragments'] assert any(('This is a secret' in item['content']) for item in fragments) @@ -323,15 +323,15 @@ def test_conditional_block_parse_attr_values(self): assert definition == expected_definition def test_presence_attributes_in_xml_attributes(self): - modules = ConditionalFactory.create(self.test_system) - modules['cond_module'].save() - modules['cond_module'].definition_to_xml(Mock()) + blocks = ConditionalFactory.create(self.test_system) + blocks['cond_block'].save() + blocks['cond_block'].definition_to_xml(Mock()) expected_xml_attributes = { 'attempted': 'true', 'message': 'You must complete {link} before you can access this unit.', 'sources': '' } - self.assertDictEqual(modules['cond_module'].xml_attributes, expected_xml_attributes) + self.assertDictEqual(blocks['cond_block'].xml_attributes, expected_xml_attributes) class ConditionalBlockStudioTest(XModuleXmlImportTest): diff --git a/xmodule/tests/test_course_block.py b/xmodule/tests/test_course_block.py index 8c032dc0bbbf..183a4f9c069e 100644 --- a/xmodule/tests/test_course_block.py +++ b/xmodule/tests/test_course_block.py @@ -40,10 +40,10 @@ def test_default_start_date(self): class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring @patch('xmodule.modulestore.xml.OSFS', lambda dir: MemoryFS()) - def __init__(self, load_error_modules, course_id=None): + def __init__(self, load_error_blocks, course_id=None): xmlstore = XMLModuleStore("data_dir", source_dirs=[], - load_error_modules=load_error_modules) + load_error_blocks=load_error_blocks) if course_id is None: course_id = CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])) course_dir = "test_dir" @@ -54,7 +54,7 @@ def __init__(self, load_error_modules, course_id=None): course_id=course_id, course_dir=course_dir, error_tracker=error_tracker, - load_error_modules=load_error_modules, + load_error_blocks=load_error_blocks, services={'field-data': KvsFieldData(DictKeyValueStore())}, ) @@ -69,7 +69,7 @@ def get_dummy_course( ): """Get a dummy course""" - system = DummySystem(load_error_modules=True) + system = DummySystem(load_error_blocks=True) def to_attrb(n, v): return '' if v is None else f'{n}="{v}"'.lower() @@ -112,7 +112,7 @@ class HasEndedMayCertifyTestCase(unittest.TestCase): def setUp(self): super().setUp() - system = DummySystem(load_error_modules=True) # lint-amnesty, pylint: disable=unused-variable + system = DummySystem(load_error_blocks=True) # lint-amnesty, pylint: disable=unused-variable past_end = (datetime.now() - timedelta(days=12)).strftime("%Y-%m-%dT%H:%M:00") future_end = (datetime.now() + timedelta(days=12)).strftime("%Y-%m-%dT%H:%M:00") diff --git a/xmodule/tests/test_delay_between_attempts.py b/xmodule/tests/test_delay_between_attempts.py index 871156665a42..9b1c58d8aaf3 100644 --- a/xmodule/tests/test_delay_between_attempts.py +++ b/xmodule/tests/test_delay_between_attempts.py @@ -28,7 +28,7 @@ class CapaFactoryWithDelay: """ - Create problem modules class, specialized for delay_between_attempts + Create problem blocks class, specialized for delay_between_attempts test cases. This factory seems different enough from the one in test_capa_block that unifying them is unattractive. Removed the unused optional arguments. @@ -104,7 +104,7 @@ def create( field_data['attempts'] = int(attempts) system = get_test_system(render_template=Mock(return_value="
        Test Template HTML
        ")) - module = ProblemBlock( + block = ProblemBlock( system, DictFieldData(field_data), ScopeIds(None, None, location, location), @@ -112,11 +112,11 @@ def create( if correct: # Could set the internal state formally, but here we just jam in the score. - module.score = Score(raw_earned=1, raw_possible=1) + block.score = Score(raw_earned=1, raw_possible=1) else: - module.score = Score(raw_earned=0, raw_possible=1) + block.score = Score(raw_earned=0, raw_possible=1) - return module + return block class XModuleQuizAttemptsDelayTest(unittest.TestCase): @@ -131,37 +131,37 @@ def create_and_check(self, considered_now=None, skip_submit_problem=False): """Unified create and check code for the tests here.""" - module = CapaFactoryWithDelay.create( + block = CapaFactoryWithDelay.create( attempts=num_attempts, max_attempts=99, last_submission_time=last_submission_time, submission_wait_seconds=submission_wait_seconds ) - module.done = False + block.done = False get_request_dict = {CapaFactoryWithDelay.input_key(): "3.14"} if skip_submit_problem: - return (module, None) + return (block, None) if considered_now is not None: - result = module.submit_problem(get_request_dict, considered_now) + result = block.submit_problem(get_request_dict, considered_now) else: - result = module.submit_problem(get_request_dict) - return (module, result) + result = block.submit_problem(get_request_dict) + return (block, result) def test_first_submission(self): # Not attempted yet num_attempts = 0 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=None ) # Successfully submitted and answered # Also, the number of attempts should increment by 1 assert result['success'] == 'correct' - assert module.attempts == (num_attempts + 1) + assert block.attempts == (num_attempts + 1) def test_no_wait_time(self): num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime.now(UTC), submission_wait_seconds=0 @@ -169,12 +169,12 @@ def test_no_wait_time(self): # Successfully submitted and answered # Also, the number of attempts should increment by 1 assert result['success'] == 'correct' - assert module.attempts == (num_attempts + 1) + assert block.attempts == (num_attempts + 1) def test_submit_quiz_in_rapid_succession(self): # Already attempted once (just now) and thus has a submitted time num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime.now(UTC), submission_wait_seconds=123 @@ -182,12 +182,12 @@ def test_submit_quiz_in_rapid_succession(self): # You should get a dialog that tells you to wait # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least.*") - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_too_soon(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -196,12 +196,12 @@ def test_submit_quiz_too_soon(self): # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least 3 minutes between submissions. 2 minutes remaining\..*") # lint-amnesty, pylint: disable=line-too-long - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_1_second_too_soon(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -210,12 +210,12 @@ def test_submit_quiz_1_second_too_soon(self): # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least 3 minutes between submissions. 1 second remaining\..*") # lint-amnesty, pylint: disable=line-too-long - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_as_soon_as_allowed(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -224,12 +224,12 @@ def test_submit_quiz_as_soon_as_allowed(self): # Successfully submitted and answered # Also, the number of attempts should increment by 1 assert result['success'] == 'correct' - assert module.attempts == (num_attempts + 1) + assert block.attempts == (num_attempts + 1) def test_submit_quiz_after_delay_expired(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -238,14 +238,14 @@ def test_submit_quiz_after_delay_expired(self): # Successfully submitted and answered # Also, the number of attempts should increment by 1 assert result['success'] == 'correct' - assert module.attempts == (num_attempts + 1) + assert block.attempts == (num_attempts + 1) def test_still_cannot_submit_after_max_attempts(self): # Already attempted once (just now) and thus has a submitted time num_attempts = 99 # Regular create_and_check should fail with pytest.raises(xmodule.exceptions.NotFoundError): - (module, unused_result) = self.create_and_check( + (block, unused_result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -253,7 +253,7 @@ def test_still_cannot_submit_after_max_attempts(self): ) # Now try it without the submit_problem - (module, unused_result) = self.create_and_check( + (block, unused_result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=180, @@ -261,12 +261,12 @@ def test_still_cannot_submit_after_max_attempts(self): skip_submit_problem=True ) # Expect that number of attempts NOT incremented - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_with_long_delay(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60 * 60 * 2, @@ -275,12 +275,12 @@ def test_submit_quiz_with_long_delay(self): # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least 2 hours between submissions. 2 minutes 1 second remaining\..*") # lint-amnesty, pylint: disable=line-too-long - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_with_involved_pretty_print(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60 * 60 * 2 + 63, @@ -289,12 +289,12 @@ def test_submit_quiz_with_involved_pretty_print(self): # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least 2 hours 1 minute 3 seconds between submissions. 1 hour 2 minutes 59 seconds remaining\..*") # lint-amnesty, pylint: disable=line-too-long - assert module.attempts == num_attempts + assert block.attempts == num_attempts def test_submit_quiz_with_nonplural_pretty_print(self): # Already attempted once (just now) num_attempts = 1 - (module, result) = self.create_and_check( + (block, result) = self.create_and_check( num_attempts=num_attempts, last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC), submission_wait_seconds=60, @@ -303,4 +303,4 @@ def test_submit_quiz_with_nonplural_pretty_print(self): # You should get a dialog that tells you to wait 2 minutes # Also, the number of attempts should not be incremented self.assertRegex(result['success'], r"You must wait at least 1 minute between submissions. 1 minute remaining\..*") # lint-amnesty, pylint: disable=line-too-long - assert module.attempts == num_attempts + assert block.attempts == num_attempts diff --git a/xmodule/tests/test_export.py b/xmodule/tests/test_export.py index 56c00d0dc566..0e6469db70af 100644 --- a/xmodule/tests/test_export.py +++ b/xmodule/tests/test_export.py @@ -140,7 +140,7 @@ def test_export_roundtrip(self, course_dir, mock_get): list(second_import.modules[course_id].keys()) ) - print("Checking module equality") + print("Checking block equality") for location in initial_import.modules[course_id].keys(): print(("Checking", location)) assert blocks_are_equivalent(initial_import.modules[course_id][location], diff --git a/xmodule/tests/test_html_block.py b/xmodule/tests/test_html_block.py index 50968e54d7ae..df8c803b5235 100644 --- a/xmodule/tests/test_html_block.py +++ b/xmodule/tests/test_html_block.py @@ -48,10 +48,10 @@ def test_disabled(self, settings): """ field_data = DictFieldData({'data': '

        Some HTML

        '}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) + block = HtmlBlock(module_system, field_data, Mock()) with override_settings(**settings): - assert module.student_view_data() ==\ + assert block.student_view_data() ==\ dict(enabled=False, message='To enable, set FEATURES["ENABLE_HTML_XBLOCK_STUDENT_VIEW_DATA"]') @ddt.data( @@ -76,8 +76,8 @@ def test_common_values(self, html): """ field_data = DictFieldData({'data': html}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) - assert module.student_view_data() == dict(enabled=True, html=html) + block = HtmlBlock(module_system, field_data, Mock()) + assert block.student_view_data() == dict(enabled=True, html=html) @ddt.data( STUDENT_VIEW, @@ -90,8 +90,8 @@ def test_student_preview_view(self, view): html = '

        This is a test

        ' field_data = DictFieldData({'data': html}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) - rendered = module_system.render(module, view, {}).content + block = HtmlBlock(module_system, field_data, Mock()) + rendered = module_system.render(block, view, {}).content assert html in rendered @@ -101,14 +101,14 @@ def test_substitution_user_id(self): sample_xml = '''%%USER_ID%%''' field_data = DictFieldData({'data': sample_xml}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) - assert module.get_html() == str(module_system.anonymous_student_id) + block = HtmlBlock(module_system, field_data, Mock()) + assert block.get_html() == str(module_system.anonymous_student_id) def test_substitution_course_id(self): sample_xml = '''%%COURSE_ID%%''' field_data = DictFieldData({'data': sample_xml}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) + block = HtmlBlock(module_system, field_data, Mock()) course_key = CourseLocator( org='some_org', course='some_course', @@ -119,8 +119,8 @@ def test_substitution_course_id(self): block_type='problem', block_id='block_id' ) - module.scope_ids.usage_id = usage_key - assert module.get_html() == str(course_key) + block.scope_ids.usage_id = usage_key + assert block.get_html() == str(course_key) def test_substitution_without_magic_string(self): sample_xml = ''' @@ -130,15 +130,15 @@ def test_substitution_without_magic_string(self): ''' field_data = DictFieldData({'data': sample_xml}) module_system = get_test_system() - module = HtmlBlock(module_system, field_data, Mock()) - assert module.get_html() == sample_xml + block = HtmlBlock(module_system, field_data, Mock()) + assert block.get_html() == sample_xml def test_substitution_without_anonymous_student_id(self): sample_xml = '''%%USER_ID%%''' field_data = DictFieldData({'data': sample_xml}) module_system = get_test_system(user=AnonymousUser()) - module = HtmlBlock(module_system, field_data, Mock()) - assert module.get_html() == sample_xml + block = HtmlBlock(module_system, field_data, Mock()) + assert block.get_html() == sample_xml class HtmlBlockIndexingTestCase(unittest.TestCase): @@ -229,7 +229,7 @@ class CourseInfoBlockTestCase(unittest.TestCase): def test_updates_render(self): """ - Tests that a course info module will render its updates, even if they are malformed. + Tests that a course info block will render its updates, even if they are malformed. """ sample_update_data = [ { @@ -246,7 +246,7 @@ def test_updates_render(self): ] ) ] - info_module = CourseInfoBlock( + info_block = CourseInfoBlock( get_test_system(), DictFieldData({'items': sample_update_data, 'data': ""}), Mock() @@ -254,13 +254,13 @@ def test_updates_render(self): # Prior to TNL-4115, an exception would be raised when trying to parse invalid dates in this method try: - info_module.get_html() + info_block.get_html() except ValueError: self.fail("CourseInfoBlock could not parse an invalid date!") def test_updates_order(self): """ - Tests that a course info module will render its updates in the correct order. + Tests that a course info block will render its updates in the correct order. """ sample_update_data = [ { @@ -282,7 +282,7 @@ def test_updates_order(self): "status": CourseInfoBlock.STATUS_VISIBLE, } ] - info_module = CourseInfoBlock( + info_block = CourseInfoBlock( Mock(), DictFieldData({'items': sample_update_data, 'data': ""}), Mock() @@ -312,10 +312,10 @@ def test_updates_order(self): ], 'hidden_updates': [], } - template_name = f"{info_module.TEMPLATE_DIR}/course_updates.html" - info_module.get_html() + template_name = f"{info_block.TEMPLATE_DIR}/course_updates.html" + info_block.get_html() # Assertion to validate that render function is called with the expected context - info_module.runtime.service(info_module, 'mako').render_template.assert_called_once_with( + info_block.runtime.service(info_block, 'mako').render_template.assert_called_once_with( template_name, expected_context ) diff --git a/xmodule/tests/test_import.py b/xmodule/tests/test_import.py index ece5dcab51f0..570b484ef04a 100644 --- a/xmodule/tests/test_import.py +++ b/xmodule/tests/test_import.py @@ -32,12 +32,12 @@ class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring @patch('xmodule.modulestore.xml.OSFS', lambda dir: OSFS(mkdtemp())) - def __init__(self, load_error_modules, library=False): + def __init__(self, load_error_blocks, library=False): if library: - xmlstore = LibraryXMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) + xmlstore = LibraryXMLModuleStore("data_dir", source_dirs=[], load_error_blocks=load_error_blocks) else: - xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) + xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_blocks=load_error_blocks) course_id = CourseKey.from_string('/'.join([ORG, COURSE, RUN])) course_dir = "test_dir" error_tracker = Mock() @@ -47,7 +47,7 @@ def __init__(self, load_error_modules, library=False): course_id=course_id, course_dir=course_dir, error_tracker=error_tracker, - load_error_modules=load_error_modules, + load_error_blocks=load_error_blocks, mixins=(InheritanceMixin, XModuleMixin), services={'field-data': KvsFieldData(DictKeyValueStore())}, ) @@ -57,12 +57,12 @@ def render_template(self, _template, _context): # lint-amnesty, pylint: disable class BaseCourseTestCase(TestCase): - '''Make sure module imports work properly, including for malformed inputs''' + '''Make sure block imports work properly, including for malformed inputs''' @staticmethod - def get_system(load_error_modules=True, library=False): + def get_system(load_error_blocks=True, library=False): '''Get a dummy system''' - return DummySystem(load_error_modules, library=library) + return DummySystem(load_error_blocks, library=library) def get_course(self, name): """Get a test course by directory name. If there's more than one, error.""" @@ -110,7 +110,7 @@ def assert_xblocks_are_good(self, block): ) @patch('xmodule.x_module.XModuleMixin.location') def test_parsing_pure_xblock(self, xml, mock_location): - system = self.get_system(load_error_modules=False) + system = self.get_system(load_error_blocks=False) descriptor = system.process_xml(xml) assert isinstance(descriptor, GenericXBlock) self.assert_xblocks_are_good(descriptor) @@ -488,7 +488,7 @@ def test_static_tabs_import(self): def test_definition_loading(self): """When two courses share the same org and course name and - both have a module with the same url_name, the definitions shouldn't clash. + both have a block with the same url_name, the definitions shouldn't clash. TODO (vshnayder): once we have a CMS, this shouldn't happen--locations should uniquely name definitions. But in @@ -592,20 +592,20 @@ def test_poll_and_conditional_import(self): assert len(sections) == 1 conditional_location = course.id.make_usage_key('conditional', 'condone') - module = modulestore.get_item(conditional_location) - assert len(module.children) == 1 + block = modulestore.get_item(conditional_location) + assert len(block.children) == 1 poll_location = course.id.make_usage_key('poll_question', 'first_poll') - module = modulestore.get_item(poll_location) - assert len(module.get_children()) == 0 - assert module.voted is False - assert module.poll_answer == '' - assert module.poll_answers == {} - assert module.answers ==\ + block = modulestore.get_item(poll_location) + assert len(block.get_children()) == 0 + assert block.voted is False + assert block.poll_answer == '' + assert block.poll_answers == {} + assert block.answers ==\ [{'text': 'Yes', 'id': 'Yes'}, {'text': 'No', 'id': 'No'}, {'text': "Don't know", 'id': 'Dont_know'}] def test_error_on_import(self): - '''Check that when load_error_module is false, an exception is raised, rather than returning an ErrorBlock''' + '''Check that when load_error_block is false, an exception is raised, rather than returning an ErrorBlock''' bad_xml = '''''' system = self.get_system(False) @@ -623,10 +623,10 @@ def test_word_cloud_import(self): assert len(sections) == 1 location = course.id.make_usage_key('word_cloud', 'cloud1') - module = modulestore.get_item(location) - assert len(module.get_children()) == 0 - assert module.num_inputs == 5 - assert module.num_top_words == 250 + block = modulestore.get_item(location) + assert len(block.get_children()) == 0 + assert block.num_inputs == 5 + assert block.num_top_words == 250 def test_cohort_config(self): """ diff --git a/xmodule/tests/test_library_content.py b/xmodule/tests/test_library_content.py index 5316f626836b..30bbfdb11708 100644 --- a/xmodule/tests/test_library_content.py +++ b/xmodule/tests/test_library_content.py @@ -54,24 +54,24 @@ def setUp(self): source_library_id=str(self.library.location.library_key) ) - def _bind_course_block(self, module): + def _bind_course_block(self, block): """ - Bind a module (part of self.course) so we can access student-specific data. + Bind a block (part of self.course) so we can access student-specific data. """ - module_system = get_test_system(course_id=module.location.course_key) - module_system.descriptor_runtime = module.runtime._descriptor_system # pylint: disable=protected-access + 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 - def get_module(descriptor): - """Mocks module_system get_module function""" - sub_module_system = get_test_system(course_id=module.location.course_key) - sub_module_system.get_module = get_module + 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) return descriptor - module_system.get_module = get_module - module.xmodule_runtime = module_system + module_system.get_block_for_descriptor = get_block + block.xmodule_runtime = module_system class TestLibraryContentExportImport(LibraryContentTest): @@ -102,7 +102,7 @@ def setUp(self): self.lc_block.runtime._descriptor_system.export_fs = self.export_fs # pylint: disable=protected-access # Prepare runtime for the import. - self.runtime = TestImportSystem(load_error_modules=True, course_id=self.lc_block.location.course_key) + self.runtime = TestImportSystem(load_error_blocks=True, course_id=self.lc_block.location.course_key) self.runtime.resources_fs = self.export_fs self.id_generator = Mock() @@ -207,7 +207,7 @@ def test_lib_content_block(self): # Normally the children get added when the "source_libraries" setting # is updated, but the way we do it through a factory doesn't do that. assert len(self.lc_block.children) == 0 - # Update the LibraryContent module: + # Update the LibraryContent block: self.lc_block.refresh_children() self.lc_block = self.store.get_item(self.lc_block.location) # Check that all blocks from the library are now children of the block: diff --git a/xmodule/tests/test_lti20_unit.py b/xmodule/tests/test_lti20_unit.py index 001c76965ce8..8923f4b474c0 100644 --- a/xmodule/tests/test_lti20_unit.py +++ b/xmodule/tests/test_lti20_unit.py @@ -29,10 +29,10 @@ def setUp(self): self.runtime.publish = Mock() self.runtime._services['rebind_user'] = Mock() # pylint: disable=protected-access - self.xmodule = LTIBlock(self.runtime, DictFieldData({}), Mock()) - self.lti_id = self.xmodule.lti_id - self.xmodule.due = None - self.xmodule.graceperiod = None + self.xblock = LTIBlock(self.runtime, DictFieldData({}), Mock()) + self.lti_id = self.xblock.lti_id + self.xblock.due = None + self.xblock.graceperiod = None def test_sanitize_get_context(self): """Tests that the get_context function does basic sanitization""" @@ -40,8 +40,8 @@ def test_sanitize_get_context(self): mocked_course = Mock(name='mocked_course', lti_passports=['lti_id:test_client:test_secret']) modulestore = Mock(name='modulestore') modulestore.get_course.return_value = mocked_course - self.xmodule.runtime.modulestore = modulestore - self.xmodule.lti_id = "lti_id" + self.xblock.runtime.modulestore = modulestore + self.xblock.lti_id = "lti_id" test_cases = ( # (before sanitize, after sanitize) ("plaintext", "plaintext"), @@ -49,8 +49,8 @@ def test_sanitize_get_context(self): ("bold 包", "bold 包"), # unicode, and tags pass through ) for case in test_cases: - self.xmodule.score_comment = case[0] - assert case[1] == self.xmodule.get_context()['comment'] + self.xblock.score_comment = case[0] + assert case[1] == self.xblock.get_context()['comment'] def test_lti20_rest_bad_contenttype(self): """ @@ -58,28 +58,28 @@ def test_lti20_rest_bad_contenttype(self): """ with self.assertRaisesRegex(LTIError, "Content-Type must be"): request = Mock(headers={'Content-Type': 'Non-existent'}) - self.xmodule.verify_lti_2_0_result_rest_headers(request) + self.xblock.verify_lti_2_0_result_rest_headers(request) def test_lti20_rest_failed_oauth_body_verify(self): """ Input with bad oauth body hash verification """ err_msg = "OAuth body verification failed" - self.xmodule.verify_oauth_body_sign = Mock(side_effect=LTIError(err_msg)) + self.xblock.verify_oauth_body_sign = Mock(side_effect=LTIError(err_msg)) with self.assertRaisesRegex(LTIError, err_msg): request = Mock(headers={'Content-Type': 'application/vnd.ims.lis.v2.result+json'}) - self.xmodule.verify_lti_2_0_result_rest_headers(request) + self.xblock.verify_lti_2_0_result_rest_headers(request) def test_lti20_rest_good_headers(self): """ Input with good oauth body hash verification """ - self.xmodule.verify_oauth_body_sign = Mock(return_value=True) + self.xblock.verify_oauth_body_sign = Mock(return_value=True) request = Mock(headers={'Content-Type': 'application/vnd.ims.lis.v2.result+json'}) - self.xmodule.verify_lti_2_0_result_rest_headers(request) + self.xblock.verify_lti_2_0_result_rest_headers(request) # We just want the above call to complete without exceptions, and to have called verify_oauth_body_sign - assert self.xmodule.verify_oauth_body_sign.called + assert self.xblock.verify_oauth_body_sign.called BAD_DISPATCH_INPUTS = [ None, @@ -100,7 +100,7 @@ def test_lti20_rest_bad_dispatch(self): """ for einput in self.BAD_DISPATCH_INPUTS: with self.assertRaisesRegex(LTIError, "No valid user id found in endpoint URL"): - self.xmodule.parse_lti_2_0_handler_suffix(einput) + self.xblock.parse_lti_2_0_handler_suffix(einput) GOOD_DISPATCH_INPUTS = [ ("user/abcd3", "abcd3"), @@ -113,7 +113,7 @@ def test_lti20_rest_good_dispatch(self): fit the form user/ """ for ginput, expected in self.GOOD_DISPATCH_INPUTS: - assert self.xmodule.parse_lti_2_0_handler_suffix(ginput) == expected + assert self.xblock.parse_lti_2_0_handler_suffix(ginput) == expected BAD_JSON_INPUTS = [ # (bad inputs, error message expected) @@ -161,7 +161,7 @@ def test_lti20_bad_json(self): for error_inputs, error_message in self.BAD_JSON_INPUTS: for einput in error_inputs: with self.assertRaisesRegex(LTIError, error_message): - self.xmodule.parse_lti_2_0_result_json(einput) + self.xblock.parse_lti_2_0_result_json(einput) GOOD_JSON_INPUTS = [ (''' @@ -185,7 +185,7 @@ def test_lti20_good_json(self): Test the parsing of good comments """ for json_str, expected_comment in self.GOOD_JSON_INPUTS: - score, comment = self.xmodule.parse_lti_2_0_result_json(json_str) + score, comment = self.xblock.parse_lti_2_0_result_json(json_str) assert score == 0.1 assert comment == expected_comment @@ -226,30 +226,30 @@ def get_signed_lti20_mock_request(self, body, method='PUT'): mock_request.body = body return mock_request - def setup_system_xmodule_mocks_for_lti20_request_test(self): + def setup_system_xblock_mocks_for_lti20_request_test(self): """ Helper fn to set up mocking for lti 2.0 request test """ - self.xmodule.max_score = Mock(return_value=1.0) - self.xmodule.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) - self.xmodule.verify_oauth_body_sign = Mock() + self.xblock.max_score = Mock(return_value=1.0) + self.xblock.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) + self.xblock.verify_oauth_body_sign = Mock() def test_lti20_put_like_delete_success(self): """ The happy path for LTI 2.0 PUT that acts like a delete """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() SCORE = 0.55 # pylint: disable=invalid-name COMMENT = "ಠ益ಠ" # pylint: disable=invalid-name - self.xmodule.module_score = SCORE - self.xmodule.score_comment = COMMENT + self.xblock.module_score = SCORE + self.xblock.score_comment = COMMENT mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT_LIKE_DELETE) # Now call the handler - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") # Now assert there's no score assert response.status_code == 200 - assert self.xmodule.module_score is None - assert self.xmodule.score_comment == '' + assert self.xblock.module_score is None + assert self.xblock.score_comment == '' (_, evt_type, called_grade_obj), _ = self.runtime.publish.call_args # pylint: disable=unpacking-non-sequence assert called_grade_obj ==\ {'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True} @@ -259,18 +259,18 @@ def test_lti20_delete_success(self): """ The happy path for LTI 2.0 DELETE """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() SCORE = 0.55 # pylint: disable=invalid-name COMMENT = "ಠ益ಠ" # pylint: disable=invalid-name - self.xmodule.module_score = SCORE - self.xmodule.score_comment = COMMENT + self.xblock.module_score = SCORE + self.xblock.score_comment = COMMENT mock_request = self.get_signed_lti20_mock_request(b"", method='DELETE') # Now call the handler - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") # Now assert there's no score assert response.status_code == 200 - assert self.xmodule.module_score is None - assert self.xmodule.score_comment == '' + assert self.xblock.module_score is None + assert self.xblock.score_comment == '' (_, evt_type, called_grade_obj), _ = self.runtime.publish.call_args # pylint: disable=unpacking-non-sequence assert called_grade_obj ==\ {'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True} @@ -280,14 +280,14 @@ def test_lti20_put_set_score_success(self): """ The happy path for LTI 2.0 PUT that sets a score """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) # Now call the handler - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") # Now assert assert response.status_code == 200 - assert self.xmodule.module_score == 0.1 - assert self.xmodule.score_comment == 'ಠ益ಠ' + assert self.xblock.module_score == 0.1 + assert self.xblock.score_comment == 'ಠ益ಠ' (_, evt_type, called_grade_obj), _ = self.runtime.publish.call_args # pylint: disable=unpacking-non-sequence assert evt_type == 'grade' assert called_grade_obj ==\ @@ -297,10 +297,10 @@ def test_lti20_get_no_score_success(self): """ The happy path for LTI 2.0 GET when there's no score """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() mock_request = self.get_signed_lti20_mock_request(b"", method='GET') # Now call the handler - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") # Now assert assert response.status_code == 200 assert response.json == {'@context': 'http://purl.imsglobal.org/ctx/lis/v2/Result', '@type': 'Result'} @@ -309,14 +309,14 @@ def test_lti20_get_with_score_success(self): """ The happy path for LTI 2.0 GET when there is a score """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() SCORE = 0.55 # pylint: disable=invalid-name COMMENT = "ಠ益ಠ" # pylint: disable=invalid-name - self.xmodule.module_score = SCORE - self.xmodule.score_comment = COMMENT + self.xblock.module_score = SCORE + self.xblock.score_comment = COMMENT mock_request = self.get_signed_lti20_mock_request(b"", method='GET') # Now call the handler - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") # Now assert assert response.status_code == 200 assert response.json ==\ @@ -329,59 +329,59 @@ def test_lti20_unsupported_method_error(self): """ Test we get a 404 when we don't GET or PUT """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) for bad_method in self.UNSUPPORTED_HTTP_METHODS: mock_request.method = bad_method - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") assert response.status_code == 404 def test_lti20_request_handler_bad_headers(self): """ Test that we get a 401 when header verification fails """ - self.setup_system_xmodule_mocks_for_lti20_request_test() - self.xmodule.verify_lti_2_0_result_rest_headers = Mock(side_effect=LTIError()) + self.setup_system_xblock_mocks_for_lti20_request_test() + self.xblock.verify_lti_2_0_result_rest_headers = Mock(side_effect=LTIError()) mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") assert response.status_code == 401 def test_lti20_request_handler_bad_dispatch_user(self): """ Test that we get a 404 when there's no (or badly formatted) user specified in the url """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, None) + response = self.xblock.lti_2_0_result_rest_handler(mock_request, None) assert response.status_code == 404 def test_lti20_request_handler_bad_json(self): """ Test that we get a 404 when json verification fails """ - self.setup_system_xmodule_mocks_for_lti20_request_test() - self.xmodule.parse_lti_2_0_result_json = Mock(side_effect=LTIError()) + self.setup_system_xblock_mocks_for_lti20_request_test() + self.xblock.parse_lti_2_0_result_json = Mock(side_effect=LTIError()) mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") assert response.status_code == 404 def test_lti20_request_handler_bad_user(self): """ Test that we get a 404 when the supplied user does not exist """ - self.setup_system_xmodule_mocks_for_lti20_request_test() + self.setup_system_xblock_mocks_for_lti20_request_test() self.runtime._services['user'] = StubUserService(user=None) # pylint: disable=protected-access mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") assert response.status_code == 404 def test_lti20_request_handler_grade_past_due(self): """ Test that we get a 404 when accept_grades_past_due is False and it is past due """ - self.setup_system_xmodule_mocks_for_lti20_request_test() - self.xmodule.due = datetime.datetime.now(UTC) - self.xmodule.accept_grades_past_due = False + self.setup_system_xblock_mocks_for_lti20_request_test() + self.xblock.due = datetime.datetime.now(UTC) + self.xblock.accept_grades_past_due = False mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT) - response = self.xmodule.lti_2_0_result_rest_handler(mock_request, "user/abcd") + response = self.xblock.lti_2_0_result_rest_handler(mock_request, "user/abcd") assert response.status_code == 404 diff --git a/xmodule/tests/test_lti_unit.py b/xmodule/tests/test_lti_unit.py index 8bd0db9db839..47d480d5bfc9 100644 --- a/xmodule/tests/test_lti_unit.py +++ b/xmodule/tests/test_lti_unit.py @@ -67,14 +67,14 @@ def setUp(self): self.system.publish = Mock() self.system._services['rebind_user'] = Mock() # pylint: disable=protected-access - self.xmodule = LTIBlock( + self.xblock = LTIBlock( self.system, DictFieldData({}), ScopeIds(None, None, None, BlockUsageLocator(self.course_id, 'lti', 'name')) ) - current_user = self.system.service(self.xmodule, 'user').get_current_user() + current_user = self.system.service(self.xblock, 'user').get_current_user() self.user_id = current_user.opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID) - self.lti_id = self.xmodule.lti_id + self.lti_id = self.xblock.lti_id self.unquoted_resource_link_id = '{}-i4x-2-3-lti-31de800015cf4afb973356dbe81496df'.format( settings.LMS_BASE @@ -90,8 +90,8 @@ def setUp(self): 'messageIdentifier': '528243ba5241b', } - self.xmodule.due = None - self.xmodule.graceperiod = None + self.xblock.due = None + self.xblock.graceperiod = None def get_request_body(self, params=None): """Fetches the body of a request specified by params""" @@ -138,7 +138,7 @@ def test_authorization_header_not_present(self, _get_key_secret): """ request = Request(self.environ) request.body = self.get_request_body() - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -163,7 +163,7 @@ def test_authorization_header_empty(self, _get_key_secret): request = Request(self.environ) request.authorization = "bad authorization header" request.body = self.get_request_body() - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -179,11 +179,11 @@ def test_real_user_is_none(self): If we have no real user, we should send back failure response. """ self.system._services['user'] = StubUserService(user=None) # pylint: disable=protected-access - self.xmodule.verify_oauth_body_sign = Mock() - self.xmodule.has_score = True + self.xblock.verify_oauth_body_sign = Mock() + self.xblock.has_score = True request = Request(self.environ) request.body = self.get_request_body() - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -198,12 +198,12 @@ def test_grade_past_due(self): """ Should fail if we do not accept past due grades, and it is past due. """ - self.xmodule.accept_grades_past_due = False - self.xmodule.due = datetime.datetime.now(UTC) - self.xmodule.graceperiod = Timedelta().from_json("0 seconds") + self.xblock.accept_grades_past_due = False + self.xblock.due = datetime.datetime.now(UTC) + self.xblock.graceperiod = Timedelta().from_json("0 seconds") request = Request(self.environ) request.body = self.get_request_body() - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -218,10 +218,10 @@ def test_grade_not_in_range(self): """ Grade returned from Tool Provider is outside the range 0.0-1.0. """ - self.xmodule.verify_oauth_body_sign = Mock() + self.xblock.verify_oauth_body_sign = Mock() request = Request(self.environ) request.body = self.get_request_body(params={'grade': '10'}) - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -236,10 +236,10 @@ def test_bad_grade_decimal(self): """ Grade returned from Tool Provider doesn't use a period as the decimal point. """ - self.xmodule.verify_oauth_body_sign = Mock() + self.xblock.verify_oauth_body_sign = Mock() request = Request(self.environ) request.body = self.get_request_body(params={'grade': '0,5'}) - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) msg = "could not convert string to float: '0,5'" expected_response = { @@ -256,10 +256,10 @@ def test_unsupported_action(self): Action returned from Tool Provider isn't supported. `replaceResultRequest` is supported only. """ - self.xmodule.verify_oauth_body_sign = Mock() + self.xblock.verify_oauth_body_sign = Mock() request = Request(self.environ) request.body = self.get_request_body({'action': 'wrongAction'}) - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') real_response = self.get_response_values(response) expected_response = { 'action': None, @@ -274,11 +274,11 @@ def test_good_request(self): """ Response from Tool Provider is correct. """ - self.xmodule.verify_oauth_body_sign = Mock() - self.xmodule.has_score = True + self.xblock.verify_oauth_body_sign = Mock() + self.xblock.has_score = True request = Request(self.environ) request.body = self.get_request_body() - response = self.xmodule.grade_handler(request, '') + response = self.xblock.grade_handler(request, '') description_expected = 'Score for {sourcedId} is now {score}'.format( sourcedId=self.defaults['sourcedId'], score=self.defaults['grade'], @@ -293,11 +293,11 @@ def test_good_request(self): assert response.status_code == 200 self.assertDictEqual(expected_response, real_response) - assert self.xmodule.module_score == float(self.defaults['grade']) + assert self.xblock.module_score == float(self.defaults['grade']) def test_user_id(self): - expected_user_id = str(parse.quote(self.xmodule.runtime.anonymous_student_id)) - real_user_id = self.xmodule.get_user_id() + expected_user_id = str(parse.quote(self.xblock.runtime.anonymous_student_id)) + real_user_id = self.xblock.get_user_id() assert real_user_id == expected_user_id def test_outcome_service_url(self): @@ -308,24 +308,24 @@ def mock_handler_url(block, handler_name, **kwargs): # pylint: disable=unused-a """Mock function for returning fully-qualified handler urls""" return mock_url_prefix + handler_name - self.xmodule.runtime.handler_url = Mock(side_effect=mock_handler_url) - real_outcome_service_url = self.xmodule.get_outcome_service_url(service_name=test_service_name) + self.xblock.runtime.handler_url = Mock(side_effect=mock_handler_url) + real_outcome_service_url = self.xblock.get_outcome_service_url(service_name=test_service_name) assert real_outcome_service_url == (mock_url_prefix + test_service_name) def test_resource_link_id(self): with patch('xmodule.lti_block.LTIBlock.location', new_callable=PropertyMock): - self.xmodule.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df' + self.xblock.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df' expected_resource_link_id = str(parse.quote(self.unquoted_resource_link_id)) - real_resource_link_id = self.xmodule.get_resource_link_id() + real_resource_link_id = self.xblock.get_resource_link_id() assert real_resource_link_id == expected_resource_link_id def test_lis_result_sourcedid(self): expected_sourced_id = ':'.join(parse.quote(i) for i in ( str(self.course_id), - self.xmodule.get_resource_link_id(), + self.xblock.get_resource_link_id(), self.user_id )) - real_lis_result_sourcedid = self.xmodule.get_lis_result_sourcedid() + real_lis_result_sourcedid = self.xblock.get_lis_result_sourcedid() assert real_lis_result_sourcedid == expected_sourced_id def test_client_key_secret(self): @@ -337,9 +337,9 @@ def test_client_key_secret(self): modulestore = Mock() modulestore.get_course.return_value = mocked_course runtime = Mock(modulestore=modulestore) - self.xmodule.runtime = runtime - self.xmodule.lti_id = "lti_id" - key, secret = self.xmodule.get_client_key_secret() + self.xblock.runtime = runtime + self.xblock.lti_id = "lti_id" + key, secret = self.xblock.get_client_key_secret() expected = ('test_client', 'test_secret') assert expected == (key, secret) @@ -355,10 +355,10 @@ def test_client_key_secret_not_provided(self): modulestore = Mock() modulestore.get_course.return_value = mocked_course runtime = Mock(modulestore=modulestore) - self.xmodule.runtime = runtime + self.xblock.runtime = runtime # set another lti_id - self.xmodule.lti_id = "another_lti_id" - key_secret = self.xmodule.get_client_key_secret() + self.xblock.lti_id = "another_lti_id" + key_secret = self.xblock.get_client_key_secret() expected = ('', '') assert expected == key_secret @@ -373,10 +373,10 @@ def test_bad_client_key_secret(self): modulestore = Mock() modulestore.get_course.return_value = mocked_course runtime = Mock(modulestore=modulestore) - self.xmodule.runtime = runtime - self.xmodule.lti_id = 'lti_id' + self.xblock.runtime = runtime + self.xblock.lti_id = 'lti_id' with pytest.raises(LTIError): - self.xmodule.get_client_key_secret() + self.xblock.get_client_key_secret() @patch('xmodule.lti_block.signature.verify_hmac_sha1', Mock(return_value=True)) @patch( @@ -387,7 +387,7 @@ def test_successful_verify_oauth_body_sign(self): """ Test if OAuth signing was successful. """ - self.xmodule.verify_oauth_body_sign(self.get_signed_grade_mock_request()) + self.xblock.verify_oauth_body_sign(self.get_signed_grade_mock_request()) @patch('xmodule.lti_block.LTIBlock.get_outcome_service_url', Mock(return_value='https://testurl/')) @patch('xmodule.lti_block.LTIBlock.get_client_key_secret', @@ -397,12 +397,12 @@ def test_failed_verify_oauth_body_sign_proxy_mangle_url(self): Oauth signing verify fail. """ request = self.get_signed_grade_mock_request_with_correct_signature() - self.xmodule.verify_oauth_body_sign(request) + self.xblock.verify_oauth_body_sign(request) # we should verify against get_outcome_service_url not # request url proxy and load balancer along the way may # change url presented to the method request.url = 'http://testurl/' - self.xmodule.verify_oauth_body_sign(request) + self.xblock.verify_oauth_body_sign(request) def get_signed_grade_mock_request_with_correct_signature(self): """ @@ -445,7 +445,7 @@ def test_wrong_xml_namespace(self): """ with pytest.raises(IndexError): mocked_request = self.get_signed_grade_mock_request(namespace_lti_v1p1=False) - self.xmodule.parse_grade_xml_body(mocked_request.body) + self.xblock.parse_grade_xml_body(mocked_request.body) def test_parse_grade_xml_body(self): """ @@ -454,7 +454,7 @@ def test_parse_grade_xml_body(self): Tests that xml body was parsed successfully. """ mocked_request = self.get_signed_grade_mock_request() - message_identifier, sourced_id, grade, action = self.xmodule.parse_grade_xml_body(mocked_request.body) + message_identifier, sourced_id, grade, action = self.xblock.parse_grade_xml_body(mocked_request.body) assert self.defaults['messageIdentifier'] == message_identifier assert self.defaults['sourcedId'] == sourced_id assert self.defaults['grade'] == grade @@ -471,7 +471,7 @@ def test_failed_verify_oauth_body_sign(self): """ with pytest.raises(LTIError): req = self.get_signed_grade_mock_request() - self.xmodule.verify_oauth_body_sign(req) + self.xblock.verify_oauth_body_sign(req) def get_signed_grade_mock_request(self, namespace_lti_v1p1=True): """ @@ -507,11 +507,11 @@ def test_good_custom_params(self): """ Custom parameters are presented in right format. """ - self.xmodule.custom_parameters = ['test_custom_params=test_custom_param_value'] - self.xmodule.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) - self.xmodule.oauth_params = Mock() - self.xmodule.get_input_fields() - self.xmodule.oauth_params.assert_called_with( + self.xblock.custom_parameters = ['test_custom_params=test_custom_param_value'] + self.xblock.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) + self.xblock.oauth_params = Mock() + self.xblock.get_input_fields() + self.xblock.oauth_params.assert_called_with( {'custom_test_custom_params': 'test_custom_param_value'}, 'test_client_key', 'test_client_secret' ) @@ -521,24 +521,24 @@ def test_bad_custom_params(self): Custom parameters are presented in wrong format. """ bad_custom_params = ['test_custom_params: test_custom_param_value'] - self.xmodule.custom_parameters = bad_custom_params - self.xmodule.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) - self.xmodule.oauth_params = Mock() + self.xblock.custom_parameters = bad_custom_params + self.xblock.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret')) + self.xblock.oauth_params = Mock() with pytest.raises(LTIError): - self.xmodule.get_input_fields() + self.xblock.get_input_fields() def test_max_score(self): - self.xmodule.weight = 100.0 + self.xblock.weight = 100.0 - assert not self.xmodule.has_score - assert self.xmodule.max_score() is None + assert not self.xblock.has_score + assert self.xblock.max_score() is None - self.xmodule.has_score = True + self.xblock.has_score = True - assert self.xmodule.max_score() == 100.0 + assert self.xblock.max_score() == 100.0 def test_context_id(self): """ Tests that LTI parameter context_id is equal to course_id. """ - assert str(self.course_id) == self.xmodule.context_id + assert str(self.course_id) == self.xblock.context_id diff --git a/xmodule/tests/test_poll.py b/xmodule/tests/test_poll.py index f1a820d6c5c7..6fdf3f4592ce 100644 --- a/xmodule/tests/test_poll.py +++ b/xmodule/tests/test_poll.py @@ -30,13 +30,13 @@ def setUp(self): usage_key = course_key.make_usage_key(PollBlock.category, 'test_loc') # ScopeIds has 4 fields: user_id, block_type, def_id, usage_id self.scope_ids = ScopeIds(1, PollBlock.category, usage_key, usage_key) - self.xmodule = PollBlock( + self.xblock = PollBlock( self.system, DictFieldData(self.raw_field_data), self.scope_ids ) def ajax_request(self, dispatch, data): """Call Xmodule.handle_ajax.""" - return json.loads(self.xmodule.handle_ajax(dispatch, data)) + return json.loads(self.xblock.handle_ajax(dispatch, data)) def test_bad_ajax_request(self): # Make sure that answer for incorrect request is error json. @@ -54,16 +54,16 @@ def test_good_ajax_request(self): self.assertDictEqual(poll_answers, {'Yes': 1, 'Dont_know': 0, 'No': 1}) assert total == 2 self.assertDictEqual(callback, {'objectName': 'Conditional'}) - assert self.xmodule.poll_answer == 'No' + assert self.xblock.poll_answer == 'No' def test_poll_export_with_unescaped_characters_xml(self): """ Make sure that poll_block will export fine if its xml contains unescaped characters. """ - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) id_generator = Mock() - id_generator.target_course_id = self.xmodule.course_id + id_generator.target_course_id = self.xblock.course_id sample_poll_xml = '''

        How old are you?

        diff --git a/xmodule/tests/test_randomize_block.py b/xmodule/tests/test_randomize_block.py index bfbf78fbb9ef..8848c4dded9d 100644 --- a/xmodule/tests/test_randomize_block.py +++ b/xmodule/tests/test_randomize_block.py @@ -80,7 +80,7 @@ def test_xml_export_import_cycle(self): # And compare. assert exported_olx == expected_olx - runtime = TestImportSystem(load_error_modules=True, course_id=randomize_block.location.course_key) + runtime = TestImportSystem(load_error_blocks=True, course_id=randomize_block.location.course_key) runtime.resources_fs = export_fs # Now import it. diff --git a/xmodule/tests/test_sequence.py b/xmodule/tests/test_sequence.py index 1fb744635c52..4447bb2aeded 100644 --- a/xmodule/tests/test_sequence.py +++ b/xmodule/tests/test_sequence.py @@ -1,5 +1,5 @@ """ -Tests for sequence module. +Tests for sequence block. """ # pylint: disable=no-member @@ -34,7 +34,7 @@ @ddt.ddt class SequenceBlockTestCase(XModuleXmlImportTest): """ - Base class for tests of Sequence Module. + Base class for tests of Sequence Block. """ def setUp(self): @@ -88,7 +88,7 @@ def _set_up_course_xml(): def _set_up_block(self, parent, index_in_parent): """ - Sets up the stub sequence module for testing. + Sets up the stub sequence block for testing. """ block = parent.get_children()[index_in_parent] diff --git a/xmodule/tests/test_split_test_block.py b/xmodule/tests/test_split_test_block.py index e5fb15c41a79..61ddd6f8c273 100644 --- a/xmodule/tests/test_split_test_block.py +++ b/xmodule/tests/test_split_test_block.py @@ -1,5 +1,5 @@ """ -Tests for the Split Testing Module +Tests for the Split Testing Block """ import json from unittest.mock import Mock, patch @@ -35,7 +35,7 @@ class SplitTestBlockFactory(xml.XmlImportFactory): class SplitTestUtilitiesTest(PartitionTestCase): """ - Tests for utility methods related to split_test module. + Tests for utility methods related to split_test block. """ def test_split_user_partitions(self): @@ -124,7 +124,7 @@ def setUp(self): # view, since mock services exist and the rendering code will not short-circuit. mocked_modulestore = Mock() mocked_modulestore.get_course.return_value = self.course - self.split_test_block.system.modulestore = mocked_modulestore + self.split_test_block.runtime.modulestore = mocked_modulestore @ddt.ddt @@ -239,7 +239,7 @@ def test_group_configuration_url(self): mocked_course = Mock(advanced_modules=['split_test']) mocked_modulestore = Mock() mocked_modulestore.get_course.return_value = mocked_course - self.split_test_block.system.modulestore = mocked_modulestore + self.split_test_block.runtime.modulestore = mocked_modulestore self.split_test_block.user_partitions = [ UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("1", 'beta')]) @@ -585,7 +585,7 @@ def test_xml_export_import_cycle(self): # And compare. assert exported_olx == expected_olx - runtime = TestImportSystem(load_error_modules=True, course_id=split_test_block.location.course_key) + runtime = TestImportSystem(load_error_blocks=True, course_id=split_test_block.location.course_key) runtime.resources_fs = export_fs # Now import it. diff --git a/xmodule/tests/test_transcripts_utils.py b/xmodule/tests/test_transcripts_utils.py index 925a4cea2072..0675dff2cf2f 100644 --- a/xmodule/tests/test_transcripts_utils.py +++ b/xmodule/tests/test_transcripts_utils.py @@ -104,7 +104,7 @@ def __init__(self, youtube_html): class TranscriptsUtilsTest(TestCase): """ - Tests utility fucntions for transcripts (in video_module) + Tests utility fucntions for transcripts (in video_block) """ @mock.patch('requests.get') diff --git a/xmodule/tests/test_vertical.py b/xmodule/tests/test_vertical.py index 22b06d3548f3..a7f993808fad 100644 --- a/xmodule/tests/test_vertical.py +++ b/xmodule/tests/test_vertical.py @@ -1,5 +1,5 @@ """ -Tests for vertical module. +Tests for vertical block. """ # pylint: disable=protected-access @@ -89,7 +89,7 @@ class BaseVerticalBlockTest(XModuleXmlImportTest): def setUp(self): super().setUp() - # construct module: course/sequence/vertical - problems + # construct block: course/sequence/vertical - problems # \_ nested_vertical / problems course = xml.CourseFactory.build() sequence = xml.SequenceFactory.build(parent=course) diff --git a/xmodule/tests/test_video.py b/xmodule/tests/test_video.py index c21be47b568d..b2bc1b41f0f5 100644 --- a/xmodule/tests/test_video.py +++ b/xmodule/tests/test_video.py @@ -1,5 +1,5 @@ # pylint: disable=protected-access -"""Test for Video Xmodule functional logic. +"""Test for Video XBlock functional logic. These test data read from xml, not from mongo. We have a ModuleStoreTestCase class defined in @@ -282,7 +282,7 @@ def test_constructor(self): }) def test_parse_xml(self): - module_system = DummySystem(load_error_modules=True) + module_system = DummySystem(load_error_blocks=True) xml_data = '''