diff --git a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py index 0381d638d8a0..529d2f881e2f 100644 --- a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py +++ b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py @@ -25,7 +25,7 @@ def print_course(course): print('num type name') for index, item in enumerate(course.tabs): print(index + 1, '"' + item.get('type') + '"', '"' + item.get('name', '') + '"') - # If a course is bad we will get an error descriptor here, dump it and die instead of + # If a course is bad we will get an error here, dump it and die instead of # just sending up the error that .id doesn't exist. except AttributeError: print(course) diff --git a/cms/djangoapps/contentstore/signals/handlers.py b/cms/djangoapps/contentstore/signals/handlers.py index badb7334ef1c..3c0742adb0d3 100644 --- a/cms/djangoapps/contentstore/signals/handlers.py +++ b/cms/djangoapps/contentstore/signals/handlers.py @@ -28,7 +28,7 @@ LibrarySearchIndexer, ) from common.djangoapps.track.event_transaction_utils import get_event_transaction_id, get_event_transaction_type -from common.djangoapps.util.block_utils import yield_dynamic_descriptor_descendants +from common.djangoapps.util.block_utils import yield_dynamic_block_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 @@ -252,7 +252,7 @@ def handle_item_deleted(**kwargs): usage_key = usage_key.for_branch(None) course_key = usage_key.course_key deleted_block = modulestore().get_item(usage_key) - for block in yield_dynamic_descriptor_descendants(deleted_block, kwargs.get('user_id')): + for block in yield_dynamic_block_descendants(deleted_block, kwargs.get('user_id')): # Remove prerequisite milestone data gating_api.remove_prerequisite(block.location) # Remove any 'requires' course content milestone relationships diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index be120824a42a..f7046cc01ab7 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1713,17 +1713,17 @@ def setUp(self): """ video_data = VideoBlock.parse_video_xml(video_sample_xml) video_data.pop('source') - self.video_descriptor = BlockFactory.create( + self.video_block = BlockFactory.create( parent_location=course.location, category='video', **video_data ) def test_metadata_not_persistence(self): """ - Test that descriptors which set metadata fields in their + Test that blocks which set metadata fields in their constructor are correctly deleted. """ - self.assertIn('html5_sources', own_metadata(self.video_descriptor)) + self.assertIn('html5_sources', own_metadata(self.video_block)) attrs_to_strip = { 'show_captions', 'youtube_id_1_0', @@ -1736,13 +1736,13 @@ def test_metadata_not_persistence(self): 'track' } - location = self.video_descriptor.location + location = self.video_block.location for field_name in attrs_to_strip: - delattr(self.video_descriptor, field_name) + delattr(self.video_block, field_name) - self.assertNotIn('html5_sources', own_metadata(self.video_descriptor)) - self.store.update_item(self.video_descriptor, self.user.id) + self.assertNotIn('html5_sources', own_metadata(self.video_block)) + self.store.update_item(self.video_block, self.user.id) block = self.store.get_item(location) self.assertNotIn('html5_sources', own_metadata(block)) @@ -2047,12 +2047,12 @@ def test_course_license_export(self): def test_video_license_export(self): content_store = contentstore() root_dir = path(mkdtemp_clean()) - video_descriptor = BlockFactory.create( + video_block = BlockFactory.create( parent_location=self.course.location, category='video', license="all-rights-reserved" ) export_course_to_xml(self.store, content_store, self.course.id, root_dir, 'test_license') - fname = f"{video_descriptor.scope_ids.usage_id.block_id}.xml" + fname = f"{video_block.scope_ids.usage_id.block_id}.xml" video_file_path = root_dir / "test_license" / "video" / fname with video_file_path.open() as f: video_xml = etree.parse(f) diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index a135faf06712..6a1977f375fe 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -885,33 +885,33 @@ def test_delete_grace_period(self): @mock.patch('cms.djangoapps.contentstore.signals.signals.GRADING_POLICY_CHANGED.send') def test_update_section_grader_type(self, send_signal, tracker, uuid): uuid.return_value = 'mockUUID' - # Get the descriptor and the section_grader_type and assert they are the default values - descriptor = modulestore().get_item(self.course.location) + # Get the block and the section_grader_type and assert they are the default values + block = modulestore().get_item(self.course.location) section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location) self.assertEqual('notgraded', section_grader_type['graderType']) - self.assertEqual(None, descriptor.format) - self.assertEqual(False, descriptor.graded) + self.assertEqual(None, block.format) + self.assertEqual(False, block.graded) # Change the default grader type to Homework, which should also mark the section as graded CourseGradingModel.update_section_grader_type(self.course, 'Homework', self.user) - descriptor = modulestore().get_item(self.course.location) + block = modulestore().get_item(self.course.location) section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location) grading_policy_1 = self._grading_policy_hash_for_course() self.assertEqual('Homework', section_grader_type['graderType']) - self.assertEqual('Homework', descriptor.format) - self.assertEqual(True, descriptor.graded) + self.assertEqual('Homework', block.format) + self.assertEqual(True, block.graded) # Change the grader type back to notgraded, which should also unmark the section as graded CourseGradingModel.update_section_grader_type(self.course, 'notgraded', self.user) - descriptor = modulestore().get_item(self.course.location) + block = modulestore().get_item(self.course.location) section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location) grading_policy_2 = self._grading_policy_hash_for_course() self.assertEqual('notgraded', section_grader_type['graderType']) - self.assertEqual(None, descriptor.format) - self.assertEqual(False, descriptor.graded) + self.assertEqual(None, block.format) + self.assertEqual(False, block.graded) # one for each call to update_section_grader_type() send_signal.assert_has_calls([ diff --git a/cms/djangoapps/contentstore/tests/test_i18n.py b/cms/djangoapps/contentstore/tests/test_i18n.py index e38094a2d3c5..db5746f893e1 100644 --- a/cms/djangoapps/contentstore/tests/test_i18n.py +++ b/cms/djangoapps/contentstore/tests/test_i18n.py @@ -69,19 +69,19 @@ def setUp(self): self.request = mock.Mock() self.course = CourseFactory.create() self.field_data = mock.Mock() - self.descriptor = BlockFactory(category="pure", parent=self.course) + self.block = BlockFactory(category="pure", parent=self.course) _prepare_runtime_for_preview( self.request, - self.descriptor, + self.block, self.field_data, ) self.addCleanup(translation.deactivate) - def get_block_i18n_service(self, descriptor): + def get_block_i18n_service(self, block): """ return the block i18n service. """ - i18n_service = self.descriptor.runtime.service(descriptor, 'i18n') + i18n_service = self.block.runtime.service(block, 'i18n') self.assertIsNotNone(i18n_service) self.assertIsInstance(i18n_service, XBlockI18nService) return i18n_service @@ -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_block_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.block) # Activate french, so that if the fr files haven't been loaded, they will be loaded now. with translation.override("fr"): @@ -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_block_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.block) 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_block_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.block) 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,14 +164,14 @@ 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_block_i18n_service(self.descriptor) + i18n_service = self.get_block_i18n_service(self.block) self.assertEqual(i18n_service.ugettext('Hello'), 'fr-hello-world') def test_i18n_service_callable(self): """ Test: i18n service should be callable in studio. """ - self.assertTrue(callable(self.descriptor.runtime._services.get('i18n'))) # pylint: disable=protected-access + self.assertTrue(callable(self.block.runtime._services.get('i18n'))) # pylint: disable=protected-access class InternationalizationTest(ModuleStoreTestCase): diff --git a/cms/djangoapps/contentstore/tests/test_libraries.py b/cms/djangoapps/contentstore/tests/test_libraries.py index 3e850e4794d7..019f67a594d9 100644 --- a/cms/djangoapps/contentstore/tests/test_libraries.py +++ b/cms/djangoapps/contentstore/tests/test_libraries.py @@ -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_block(self, descriptor, user=None): + def _bind_block(self, block, user=None): """ Helper to use the CMS's module system so we can access student-specific fields. """ @@ -123,7 +123,7 @@ def _bind_block(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_block(request, descriptor) + _load_preview_block(request, block) def _update_block(self, usage_key, metadata): """ @@ -174,13 +174,13 @@ def test_max_items(self, num_to_create, num_to_select, num_expected): lc_block = self._refresh_children(lc_block) # Now, we want to make sure that .children has the total # of potential - # children, and that get_child_descriptors() returns the actual children + # children, and that get_child_blocks() returns the actual children # chosen for a given student. - # In order to be able to call get_child_descriptors(), we must first + # In order to be able to call get_child_blocks(), we must first # call bind_for_student: self._bind_block(lc_block) self.assertEqual(len(lc_block.children), num_to_create) - self.assertEqual(len(lc_block.get_child_descriptors()), num_expected) + self.assertEqual(len(lc_block.get_child_blocks()), num_expected) def test_consistent_children(self): """ @@ -204,7 +204,7 @@ def get_child_of_lc_block(block): """ Fetch the child shown to the current user. """ - children = block.get_child_descriptors() + children = block.get_child_blocks() self.assertEqual(len(children), 1) return children[0] diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index 5b4f4338b2b6..4b6dc100db61 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -620,7 +620,7 @@ def test_exclude_partitions_with_no_groups(self): self.assertEqual(partitions[0]["scheme"], "random") def _set_partitions(self, partitions): - """Set the user partitions of the course descriptor. """ + """Set the user partitions of the course block. """ self.course.user_partitions = partitions self.course = self.store.update_item(self.course, ModuleStoreEnum.UserID.test) diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py index b58ec17502b8..4c2b5b5adf14 100644 --- a/cms/djangoapps/contentstore/tests/utils.py +++ b/cms/djangoapps/contentstore/tests/utils.py @@ -191,8 +191,8 @@ def check_verticals(self, items): """ Test getting the editing HTML for each vertical. """ # assert is here to make sure that the course being tested actually has verticals (units) to check. self.assertGreater(len(items), 0, "Course has no verticals (units) to check") - for descriptor in items: - resp = self.client.get_html(get_url('container_handler', descriptor.location)) + for block in items: + resp = self.client.get_html(get_url('container_handler', block.location)) self.assertEqual(resp.status_code, 200) def assertAssetsEqual(self, asset_son, course1_id, course2_id): diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 22a07d3ccd4a..0c4141b5d26a 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -372,7 +372,7 @@ def get_split_group_display_name(xblock, course): Arguments: xblock (XBlock): The courseware component. - course (XBlock): The course descriptor. + course (XBlock): The course block. Returns: group name (String): Group name of the matching group xblock. @@ -399,14 +399,14 @@ def get_user_partition_info(xblock, schemes=None, course=None): schemes (iterable of str): If provided, filter partitions to include only schemes with the provided names. - course (XBlock): The course descriptor. If provided, uses this to look up the user partitions + course (XBlock): The course block. If provided, uses this to look up the user partitions instead of loading the course. This is useful if we're calling this function multiple times for the same course want to minimize queries to the modulestore. Returns: list Example Usage: - >>> get_user_partition_info(block, schemes=["cohort", "verification"]) + >>> get_user_partition_info(xblock, schemes=["cohort", "verification"]) [ { "id": 12345, @@ -509,7 +509,7 @@ def get_visibility_partition_info(xblock, course=None): Arguments: xblock (XBlock): The component being edited. - course (XBlock): The course descriptor. If provided, uses this to look up the user partitions + course (XBlock): The course block. If provided, uses this to look up the user partitions instead of loading the course. This is useful if we're calling this function multiple times for the same course want to minimize queries to the modulestore. @@ -569,8 +569,8 @@ def get_xblock_aside_instance(usage_key): :param usage_key: Usage key of aside xblock """ try: - descriptor = modulestore().get_item(usage_key.usage_key) - for aside in descriptor.runtime.get_asides(descriptor): + xblock = modulestore().get_item(usage_key.usage_key) + for aside in xblock.runtime.get_asides(xblock): if aside.scope_ids.block_type == usage_key.aside_type: return aside except ItemNotFoundError: diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py index 6535e0a85718..3c43ab1065ad 100644 --- a/cms/djangoapps/contentstore/views/certificates.py +++ b/cms/djangoapps/contentstore/views/certificates.py @@ -128,7 +128,7 @@ class CertificateValidationError(CertificateException): class CertificateManager: """ The CertificateManager is responsible for storage, retrieval, and manipulation of Certificates - Certificates are not stored in the Django ORM, they are a field/setting on the course descriptor + Certificates are not stored in the Django ORM, they are a field/setting on the course block """ @staticmethod def parse(json_string): diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index 7f774ab161d2..d58f601abcdc 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -552,18 +552,18 @@ def component_handler(request, usage_key_string, handler, suffix=''): try: if is_xblock_aside(usage_key): - # Get the descriptor for the block being wrapped by the aside (not the aside itself) - descriptor = modulestore().get_item(usage_key.usage_key) - handler_descriptor = get_aside_from_xblock(descriptor, usage_key.aside_type) - asides = [handler_descriptor] + # Get the block being wrapped by the aside (not the aside itself) + block = modulestore().get_item(usage_key.usage_key) + handler_block = get_aside_from_xblock(block, usage_key.aside_type) + asides = [handler_block] else: - descriptor = modulestore().get_item(usage_key) - handler_descriptor = descriptor + block = modulestore().get_item(usage_key) + handler_block = block asides = [] - load_services_for_studio(handler_descriptor.runtime, request.user) - resp = handler_descriptor.handle(handler, req, suffix) + load_services_for_studio(handler_block.runtime, request.user) + resp = handler_block.handle(handler, req, suffix) except NoSuchHandlerError: - log.info("XBlock %s attempted to access missing handler %r", handler_descriptor, handler, exc_info=True) + log.info("XBlock %s attempted to access missing handler %r", handler_block, handler, exc_info=True) raise Http404 # lint-amnesty, pylint: disable=raise-missing-from # unintentional update to handle any side effects of handle call @@ -572,7 +572,7 @@ def component_handler(request, usage_key_string, handler, suffix=''): # TNL 101-62 studio write permission is also checked for editing content. if has_course_author_access(request.user, usage_key.course_key): - modulestore().update_item(descriptor, request.user.id, asides=asides) + modulestore().update_item(block, request.user.id, asides=asides) else: #fail quietly if user is not course author. log.warning( diff --git a/cms/djangoapps/contentstore/views/entrance_exam.py b/cms/djangoapps/contentstore/views/entrance_exam.py index 63917d17f6d5..ced3ed531b37 100644 --- a/cms/djangoapps/contentstore/views/entrance_exam.py +++ b/cms/djangoapps/contentstore/views/entrance_exam.py @@ -176,9 +176,9 @@ def _get_entrance_exam(request, course_key): except InvalidKeyError: return HttpResponse(status=404) try: - exam_descriptor = modulestore().get_item(exam_key) + exam_block = modulestore().get_item(exam_key) return HttpResponse( # lint-amnesty, pylint: disable=http-response-with-content-type-json - dump_js_escaped_json({'locator': str(exam_descriptor.location)}), + dump_js_escaped_json({'locator': str(exam_block.location)}), status=200, content_type='application/json') except ItemNotFoundError: return HttpResponse(status=404) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 12b00d16e6ad..1b28e65a4c5a 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -11,6 +11,7 @@ from django.utils.translation import gettext as _ from django.views.decorators.clickjacking import xframe_options_exempt from opaque_keys.edx.keys import UsageKey +from rest_framework.request import Request from web_fragments.fragment import Fragment from xblock.django.request import django_to_webob_request, webob_to_django_response from xblock.exceptions import NoSuchHandlerError @@ -24,7 +25,7 @@ from xmodule.studio_editable import has_author_view from xmodule.util.sandboxing import SandboxService from xmodule.util.xmodule_django import add_webpack_to_fragment -from xmodule.x_module import AUTHOR_VIEW, PREVIEW_VIEWS, STUDENT_VIEW +from xmodule.x_module import AUTHOR_VIEW, PREVIEW_VIEWS, STUDENT_VIEW, XModuleMixin from cms.djangoapps.xblock_config.models import StudioConfig from cms.djangoapps.contentstore.toggles import individualize_anonymous_user_id, ENABLE_COPY_PASTE_FEATURE from cms.lib.xblock.field_data import CmsFieldData @@ -65,8 +66,8 @@ 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_block(request, descriptor) + block = modulestore().get_item(usage_key) + instance = _load_preview_block(request, block) # Let the module handle the AJAX req = django_to_webob_request(request) @@ -154,6 +155,7 @@ def _prepare_runtime_for_preview(request, block, field_data): required for rendering block previews. request: The active django request + block: An XBlock field_data: Wrapped field data for previews """ @@ -256,29 +258,29 @@ def get_user_group_id_for_partition(self, user, user_partition_id): return None -def _load_preview_block(request, descriptor): +def _load_preview_block(request: Request, block: XModuleMixin): """ - Return a preview XBlock instantiated from the supplied descriptor. Will use mutable fields + Return a preview XBlock instantiated from the supplied block. 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 + block: An XModuleMixin """ student_data = KvsFieldData(SessionKeyValueStore(request)) - if has_author_view(descriptor): + if has_author_view(block): wrapper = partial(CmsFieldData, student_data=student_data) else: wrapper = partial(LmsFieldData, student_data=student_data) # wrap the _field_data upfront to pass to _prepare_runtime_for_preview - wrapped_field_data = wrapper(descriptor._field_data) # pylint: disable=protected-access - _prepare_runtime_for_preview(request, descriptor, wrapped_field_data) + wrapped_field_data = wrapper(block._field_data) # pylint: disable=protected-access + _prepare_runtime_for_preview(request, block, wrapped_field_data) - descriptor.bind_for_student( + block.bind_for_student( request.user.id, [wrapper] ) - return descriptor + return block def _is_xblock_reorderable(xblock, context): @@ -332,12 +334,12 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False): return frag -def get_preview_fragment(request, descriptor, context): +def get_preview_fragment(request, block, context): """ Returns the HTML returned by the XModule's student_view or author_view (if available), - specified by the descriptor and idx. + specified by the block and idx. """ - block = _load_preview_block(request, descriptor) + block = _load_preview_block(request, block) preview_view = AUTHOR_VIEW if has_author_view(block) else STUDENT_VIEW diff --git a/cms/djangoapps/contentstore/views/tests/test_block.py b/cms/djangoapps/contentstore/views/tests/test_block.py index 863da2e02f5d..d2345abe26df 100644 --- a/cms/djangoapps/contentstore/views/tests/test_block.py +++ b/cms/djangoapps/contentstore/views/tests/test_block.py @@ -2159,10 +2159,10 @@ def setUp(self): self.modulestore = patcher.start() self.addCleanup(patcher.stop) - # component_handler calls modulestore.get_item to get the descriptor of the requested xBlock. + # component_handler calls modulestore.get_item to get the requested xBlock. # Here, we mock the return value of modulestore.get_item so it can be used to mock the handler - # of the xBlock descriptor. - self.descriptor = self.modulestore.return_value.get_item.return_value + # of the xBlock. + self.block = self.modulestore.return_value.get_item.return_value self.usage_key = BlockUsageLocator( CourseLocator('dummy_org', 'dummy_course', 'dummy_run'), 'dummy_category', 'dummy_name' @@ -2173,7 +2173,7 @@ def setUp(self): self.request.user = self.user def test_invalid_handler(self): - self.descriptor.handle.side_effect = NoSuchHandlerError + self.block.handle.side_effect = NoSuchHandlerError with self.assertRaises(Http404): component_handler(self.request, self.usage_key_string, 'invalid_handler') @@ -2185,7 +2185,7 @@ def check_handler(handler, request, suffix): # lint-amnesty, pylint: disable=un self.assertEqual(request.method, method) return Response() - self.descriptor.handle = check_handler + self.block.handle = check_handler # Have to use the right method to create the request to get the HTTP method that we want req_factory_method = getattr(self.request_factory, method.lower()) @@ -2198,7 +2198,7 @@ def test_response_code(self, status_code): def create_response(handler, request, suffix): # lint-amnesty, pylint: disable=unused-argument return Response(status_code=status_code) - self.descriptor.handle = create_response + self.block.handle = create_response self.assertEqual(component_handler(self.request, self.usage_key_string, 'dummy_handler').status_code, status_code) @@ -2219,7 +2219,7 @@ def create_response(handler, request, suffix): # lint-amnesty, pylint: disable= self.request.user = UserFactory() mock_handler = 'dummy_handler' - self.descriptor.handle = create_response + self.block.handle = create_response with patch( 'cms.djangoapps.contentstore.views.component.is_xblock_aside', @@ -2253,7 +2253,7 @@ def get_usage_key(): else self.usage_key_string ) - self.descriptor.handle = create_response + self.block.handle = create_response with patch( 'cms.djangoapps.contentstore.views.component.is_xblock_aside', diff --git a/cms/djangoapps/contentstore/views/tests/test_preview.py b/cms/djangoapps/contentstore/views/tests/test_preview.py index c8d126685387..7e407c966d3d 100644 --- a/cms/djangoapps/contentstore/views/tests/test_preview.py +++ b/cms/djangoapps/contentstore/views/tests/test_preview.py @@ -213,13 +213,13 @@ def test_expected_services_exist(self, expected_service): """ Tests that the 'user' and 'i18n' services are provided by the Studio runtime. """ - descriptor = BlockFactory(category="pure", parent=self.course) + block = BlockFactory(category="pure", parent=self.course) _prepare_runtime_for_preview( self.request, - descriptor, + block, self.field_data, ) - service = descriptor.runtime.service(descriptor, expected_service) + service = block.runtime.service(block, expected_service) self.assertIsNotNone(service) @@ -242,32 +242,31 @@ def setUp(self): self.request = RequestFactory().get('/dummy-url') self.request.user = self.user self.request.session = {} - self.descriptor = BlockFactory(category="video", parent=course) self.field_data = mock.Mock() self.contentstore = contentstore() - self.descriptor = BlockFactory(category="problem", parent=course) + self.block = BlockFactory(category="problem", parent=course) _prepare_runtime_for_preview( self.request, - block=self.descriptor, + block=self.block, field_data=mock.Mock(), ) self.course = self.store.get_item(course.location) def test_get_user_role(self): - assert self.descriptor.runtime.get_user_role() == 'staff' + assert self.block.runtime.get_user_role() == 'staff' @XBlock.register_temp_plugin(PureXBlock, identifier='pure') def test_render_template(self): - descriptor = BlockFactory(category="pure", parent=self.course) - html = get_preview_fragment(self.request, descriptor, {'element_id': 142}).content + block = BlockFactory(category="pure", parent=self.course) + html = get_preview_fragment(self.request, block, {'element_id': 142}).content assert '
Testing the MakoService
' in html @override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+LmsModuleShimTest\+2021_Fall']) def test_can_execute_unsafe_code(self): - assert self.descriptor.runtime.can_execute_unsafe_code() + assert self.block.runtime.can_execute_unsafe_code() def test_cannot_execute_unsafe_code(self): - assert not self.descriptor.runtime.can_execute_unsafe_code() + assert not self.block.runtime.can_execute_unsafe_code() @override_settings(PYTHON_LIB_FILENAME=PYTHON_LIB_FILENAME) def test_get_python_lib_zip(self): @@ -277,7 +276,7 @@ def test_get_python_lib_zip(self): source_file=self.PYTHON_LIB_SOURCE_FILE, target_filename=self.PYTHON_LIB_FILENAME, ) - assert self.descriptor.runtime.get_python_lib_zip() == zipfile + assert self.block.runtime.get_python_lib_zip() == zipfile def test_no_get_python_lib_zip(self): zipfile = upload_file_to_course( @@ -286,40 +285,40 @@ def test_no_get_python_lib_zip(self): source_file=self.PYTHON_LIB_SOURCE_FILE, target_filename=self.PYTHON_LIB_FILENAME, ) - assert self.descriptor.runtime.get_python_lib_zip() is None + assert self.block.runtime.get_python_lib_zip() is None def test_cache(self): - assert hasattr(self.descriptor.runtime.cache, 'get') - assert hasattr(self.descriptor.runtime.cache, 'set') + assert hasattr(self.block.runtime.cache, 'get') + assert hasattr(self.block.runtime.cache, 'set') def test_replace_urls(self): html = '' - assert self.descriptor.runtime.replace_urls(html) == \ + assert self.block.runtime.replace_urls(html) == \ static_replace.replace_static_urls(html, course_id=self.course.id) def test_anonymous_user_id_preview(self): - assert self.descriptor.runtime.anonymous_student_id == 'student' + assert self.block.runtime.anonymous_student_id == 'student' @override_waffle_flag(INDIVIDUALIZE_ANONYMOUS_USER_ID, active=True) def test_anonymous_user_id_individual_per_student(self): """Test anonymous_user_id on a block which uses per-student anonymous IDs""" # Create the runtime with the flag turned on. - descriptor = BlockFactory(category="problem", parent=self.course) + block = BlockFactory(category="problem", parent=self.course) _prepare_runtime_for_preview( self.request, - block=descriptor, + block=block, field_data=mock.Mock(), ) - assert descriptor.runtime.anonymous_student_id == '26262401c528d7c4a6bbeabe0455ec46' + assert block.runtime.anonymous_student_id == '26262401c528d7c4a6bbeabe0455ec46' @override_waffle_flag(INDIVIDUALIZE_ANONYMOUS_USER_ID, active=True) def test_anonymous_user_id_individual_per_course(self): """Test anonymous_user_id on a block which uses per-course anonymous IDs""" # Create the runtime with the flag turned on. - descriptor = BlockFactory(category="lti", parent=self.course) + block = BlockFactory(category="lti", parent=self.course) _prepare_runtime_for_preview( self.request, - block=descriptor, + block=block, field_data=mock.Mock(), ) - assert descriptor.runtime.anonymous_student_id == 'ad503f629b55c531fed2e45aa17a3368' + assert block.runtime.anonymous_student_id == 'ad503f629b55c531fed2e45aa17a3368' diff --git a/cms/djangoapps/contentstore/views/tests/test_transcripts.py b/cms/djangoapps/contentstore/views/tests/test_transcripts.py index 56391560e78c..5d18c76cad1a 100644 --- a/cms/djangoapps/contentstore/views/tests/test_transcripts.py +++ b/cms/djangoapps/contentstore/views/tests/test_transcripts.py @@ -364,7 +364,7 @@ def test_transcript_upload_without_edx_video_id(self): def test_transcript_upload_with_non_existant_edx_video_id(self): """ Test that transcript upload works as expected if `edx_video_id` set on - video descriptor is different from `edx_video_id` received in POST request. + video block is different from `edx_video_id` received in POST request. """ non_existant_edx_video_id = '1111-2222-3333-4444' diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py index 9c2042099665..d8a091848f62 100644 --- a/cms/djangoapps/contentstore/views/transcripts_ajax.py +++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py @@ -71,7 +71,7 @@ def link_video_to_component(video_component, user): Links a VAL video to the video component. Arguments: - video_component: video descriptor item. + video_component: video block. user: A requesting user. Returns: @@ -134,7 +134,7 @@ def validate_video_block(request, locator): locator: video locator. Returns: - A tuple containing error(or None) and video descriptor(i.e. if validation succeeds). + A tuple containing error(or None) and video block(i.e. if validation succeeds). Raises: PermissionDenied: if requesting user does not have access to author the video component. diff --git a/cms/djangoapps/models/settings/course_grading.py b/cms/djangoapps/models/settings/course_grading.py index 6c72f3b9a6ec..e6a0e3690c5c 100644 --- a/cms/djangoapps/models/settings/course_grading.py +++ b/cms/djangoapps/models/settings/course_grading.py @@ -25,21 +25,21 @@ class CourseGradingModel: """ # Within this class, allow access to protected members of client classes. # This comes up when accessing kvs data and caches during kvs saves and modulestore writes. - def __init__(self, course_descriptor): + def __init__(self, course): self.graders = [ - CourseGradingModel.jsonize_grader(i, grader) for i, grader in enumerate(course_descriptor.raw_grader) + CourseGradingModel.jsonize_grader(i, grader) for i, grader in enumerate(course.raw_grader) ] # weights transformed to ints [0..100] - self.grade_cutoffs = course_descriptor.grade_cutoffs - self.grace_period = CourseGradingModel.convert_set_grace_period(course_descriptor) - self.minimum_grade_credit = course_descriptor.minimum_grade_credit + self.grade_cutoffs = course.grade_cutoffs + self.grace_period = CourseGradingModel.convert_set_grace_period(course) + self.minimum_grade_credit = course.minimum_grade_credit @classmethod def fetch(cls, course_key): """ Fetch the course grading policy for the given course from persistence and return a CourseGradingModel. """ - descriptor = modulestore().get_course(course_key) - model = cls(descriptor) + course = modulestore().get_course(course_key) + model = cls(course) return model @staticmethod @@ -48,10 +48,10 @@ def fetch_grader(course_key, index): Fetch the course's nth grader Returns an empty dict if there's no such grader. """ - descriptor = modulestore().get_course(course_key) + course = modulestore().get_course(course_key) index = int(index) - if len(descriptor.raw_grader) > index: - return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index]) + if len(course.raw_grader) > index: + return CourseGradingModel.jsonize_grader(index, course.raw_grader[index]) # return empty model else: @@ -69,27 +69,27 @@ def update_from_json(course_key, jsondict, user): Decode the json into CourseGradingModel and save any changes. Returns the modified model. Probably not the usual path for updates as it's too coarse grained. """ - descriptor = modulestore().get_course(course_key) - previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) + course = modulestore().get_course(course_key) + previous_grading_policy_hash = str(hash_grading_policy(course.grading_policy)) graders_parsed = [CourseGradingModel.parse_grader(jsonele) for jsonele in jsondict['graders']] fire_signal = CourseGradingModel.must_fire_grading_event_and_signal( course_key, graders_parsed, - descriptor, + course, jsondict ) - descriptor.raw_grader = graders_parsed - descriptor.grade_cutoffs = jsondict['grade_cutoffs'] + course.raw_grader = graders_parsed + course.grade_cutoffs = jsondict['grade_cutoffs'] - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) CourseGradingModel.update_grace_period_from_json(course_key, jsondict['grace_period'], user) CourseGradingModel.update_minimum_grade_credit_from_json(course_key, jsondict['minimum_grade_credit'], user) - descriptor = modulestore().get_course(course_key) - new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) + course = modulestore().get_course(course_key) + new_grading_policy_hash = str(hash_grading_policy(course.grading_policy)) log.info( "Updated course grading policy for course %s from %s to %s. fire_signal = %s", str(course_key), @@ -153,28 +153,28 @@ def update_grader_from_json(course_key, grader, user): Create or update the grader of the given type (string key) for the given course. Returns the modified grader which is a full model on the client but not on the server (just a dict) """ - descriptor = modulestore().get_course(course_key) - previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) + course = modulestore().get_course(course_key) + previous_grading_policy_hash = str(hash_grading_policy(course.grading_policy)) # parse removes the id; so, grab it before parse - index = int(grader.get('id', len(descriptor.raw_grader))) + index = int(grader.get('id', len(course.raw_grader))) grader = CourseGradingModel.parse_grader(grader) fire_signal = True - if index < len(descriptor.raw_grader): + if index < len(course.raw_grader): fire_signal = CourseGradingModel.must_fire_grading_event_and_signal_single_grader( course_key, grader, - descriptor.raw_grader[index] + course.raw_grader[index] ) - descriptor.raw_grader[index] = grader + course.raw_grader[index] = grader else: - descriptor.raw_grader.append(grader) + course.raw_grader.append(grader) - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) - descriptor = modulestore().get_course(course_key) - new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy)) + course = modulestore().get_course(course_key) + new_grading_policy_hash = str(hash_grading_policy(course.grading_policy)) log.info( "Updated grader for course %s. Grading policy has changed from %s to %s. fire_signal = %s", str(course_key), @@ -185,7 +185,7 @@ def update_grader_from_json(course_key, grader, user): if fire_signal: _grading_event_and_signal(course_key, user.id) - return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index]) + return CourseGradingModel.jsonize_grader(index, course.raw_grader[index]) @staticmethod def update_cutoffs_from_json(course_key, cutoffs, user): @@ -193,10 +193,10 @@ def update_cutoffs_from_json(course_key, cutoffs, user): Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra db fetch). """ - descriptor = modulestore().get_course(course_key) - descriptor.grade_cutoffs = cutoffs + course = modulestore().get_course(course_key) + course.grade_cutoffs = cutoffs - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) _grading_event_and_signal(course_key, user.id) return cutoffs @@ -207,7 +207,7 @@ def update_grace_period_from_json(course_key, graceperiodjson, user): grace_period entry in an enclosing dict. It is also safe to call this method with a value of None for graceperiodjson. """ - descriptor = modulestore().get_course(course_key) + course = modulestore().get_course(course_key) # Before a graceperiod has ever been created, it will be None (once it has been # created, it cannot be set back to None). @@ -216,9 +216,9 @@ def update_grace_period_from_json(course_key, graceperiodjson, user): graceperiodjson = graceperiodjson['grace_period'] grace_timedelta = timedelta(**graceperiodjson) - descriptor.graceperiod = grace_timedelta + course.graceperiod = grace_timedelta - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) @staticmethod def update_minimum_grade_credit_from_json(course_key, minimum_grade_credit, user): @@ -230,29 +230,29 @@ def update_minimum_grade_credit_from_json(course_key, minimum_grade_credit, user user(User): The user object """ - descriptor = modulestore().get_course(course_key) + course = modulestore().get_course(course_key) # 'minimum_grade_credit' cannot be set to None if minimum_grade_credit is not None: minimum_grade_credit = minimum_grade_credit # lint-amnesty, pylint: disable=self-assigning-variable - descriptor.minimum_grade_credit = minimum_grade_credit - modulestore().update_item(descriptor, user.id) + course.minimum_grade_credit = minimum_grade_credit + modulestore().update_item(course, user.id) @staticmethod def delete_grader(course_key, index, user): """ Delete the grader of the given type from the given course. """ - descriptor = modulestore().get_course(course_key) + course = modulestore().get_course(course_key) index = int(index) - if index < len(descriptor.raw_grader): - del descriptor.raw_grader[index] + if index < len(course.raw_grader): + del course.raw_grader[index] # force propagation to definition - descriptor.raw_grader = descriptor.raw_grader + course.raw_grader = course.raw_grader - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) _grading_event_and_signal(course_key, user.id) @staticmethod @@ -260,37 +260,37 @@ def delete_grace_period(course_key, user): """ Delete the course's grace period. """ - descriptor = modulestore().get_course(course_key) + course = modulestore().get_course(course_key) - del descriptor.graceperiod + del course.graceperiod - modulestore().update_item(descriptor, user.id) + modulestore().update_item(course, user.id) @staticmethod def get_section_grader_type(location): - descriptor = modulestore().get_item(location) + block = modulestore().get_item(location) return { - "graderType": descriptor.format if descriptor.format is not None else 'notgraded', + "graderType": block.format if block.format is not None else 'notgraded', "location": str(location), } @staticmethod - def update_section_grader_type(descriptor, grader_type, user): # lint-amnesty, pylint: disable=missing-function-docstring + def update_section_grader_type(block, grader_type, user): # lint-amnesty, pylint: disable=missing-function-docstring if grader_type is not None and grader_type != 'notgraded': - descriptor.format = grader_type - descriptor.graded = True + block.format = grader_type + block.graded = True else: - del descriptor.format - del descriptor.graded + del block.format + del block.graded - modulestore().update_item(descriptor, user.id) - _grading_event_and_signal(descriptor.location.course_key, user.id) + modulestore().update_item(block, user.id) + _grading_event_and_signal(block.location.course_key, user.id) return {'graderType': grader_type} @staticmethod - def convert_set_grace_period(descriptor): # lint-amnesty, pylint: disable=missing-function-docstring + def convert_set_grace_period(course): # lint-amnesty, pylint: disable=missing-function-docstring # 5 hours 59 minutes 59 seconds => converted to iso format - rawgrace = descriptor.graceperiod + rawgrace = course.graceperiod if rawgrace: hours_from_days = rawgrace.days * 24 seconds = rawgrace.seconds diff --git a/cms/djangoapps/models/settings/course_metadata.py b/cms/djangoapps/models/settings/course_metadata.py index c072a4ae552b..f45130d9fa76 100644 --- a/cms/djangoapps/models/settings/course_metadata.py +++ b/cms/djangoapps/models/settings/course_metadata.py @@ -155,14 +155,14 @@ def get_exclude_list_of_fields(cls, course_key): return exclude_list @classmethod - def fetch(cls, descriptor, filter_fields=None): + def fetch(cls, block, filter_fields=None): """ Fetch the key:value editable course details for the given course from persistence and return a CourseMetadata model. """ result = {} - metadata = cls.fetch_all(descriptor, filter_fields=filter_fields) - exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id) + metadata = cls.fetch_all(block, filter_fields=filter_fields) + exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id) for key, value in metadata.items(): if key in exclude_list_of_fields: @@ -171,12 +171,12 @@ def fetch(cls, descriptor, filter_fields=None): return result @classmethod - def fetch_all(cls, descriptor, filter_fields=None): + def fetch_all(cls, block, filter_fields=None): """ Fetches all key:value pairs from persistence and returns a CourseMetadata model. """ result = {} - for field in descriptor.fields.values(): + for field in block.fields.values(): if field.scope != Scope.settings: continue @@ -189,7 +189,7 @@ def fetch_all(cls, descriptor, filter_fields=None): field_help = field_help.format(**help_args) result[field.name] = { - 'value': field.read_json(descriptor), + 'value': field.read_json(block), 'display_name': _(field.display_name), # lint-amnesty, pylint: disable=translation-of-non-string 'help': field_help, 'deprecated': field.runtime_options.get('deprecated', False), @@ -198,13 +198,13 @@ def fetch_all(cls, descriptor, filter_fields=None): return result @classmethod - def update_from_json(cls, descriptor, jsondict, user, filter_tabs=True): + def update_from_json(cls, block, jsondict, user, filter_tabs=True): """ Decode the json into CourseMetadata and save any changed attrs to the db. Ensures none of the fields are in the exclude list. """ - exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id) + exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id) # Don't filter on the tab attribute if filter_tabs is False. if not filter_tabs: exclude_list_of_fields.remove("tabs") @@ -218,16 +218,16 @@ def update_from_json(cls, descriptor, jsondict, user, filter_tabs=True): continue try: val = model['value'] - if hasattr(descriptor, key) and getattr(descriptor, key) != val: - key_values[key] = descriptor.fields[key].from_json(val) + if hasattr(block, key) and getattr(block, key) != val: + key_values[key] = block.fields[key].from_json(val) except (TypeError, ValueError) as err: raise ValueError(_("Incorrect format for field '{name}'. {detailed_message}").format( # lint-amnesty, pylint: disable=raise-missing-from name=model['display_name'], detailed_message=str(err))) - return cls.update_from_dict(key_values, descriptor, user) + return cls.update_from_dict(key_values, block, user) @classmethod - def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=True): + def validate_and_update_from_json(cls, block, jsondict, user, filter_tabs=True): """ Validate the values in the json dict (validated by xblock fields from_json method) @@ -240,7 +240,7 @@ def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=T errors: list of error objects result: the updated course metadata or None if error """ - exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id) + exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id) if not filter_tabs: exclude_list_of_fields.remove("tabs") @@ -254,8 +254,8 @@ def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=T for key, model in filtered_dict.items(): try: val = model['value'] - if hasattr(descriptor, key) and getattr(descriptor, key) != val: - key_values[key] = descriptor.fields[key].from_json(val) + if hasattr(block, key) and getattr(block, key) != val: + key_values[key] = block.fields[key].from_json(val) except (TypeError, ValueError, ValidationError) as err: did_validate = False errors.append({'key': key, 'message': str(err), 'model': model}) @@ -264,7 +264,7 @@ def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=T # Because we cannot pass course context to the exception, we need to check if the LTI provider # should actually be available to the course err_message = str(err) - if not exams_ida_enabled(descriptor.id): + if not exams_ida_enabled(block.id): available_providers = get_available_providers() available_providers.remove('lti_external') err_message = str(InvalidProctoringProvider(val, available_providers)) @@ -277,29 +277,29 @@ def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=T errors = errors + team_setting_errors did_validate = False - proctoring_errors = cls.validate_proctoring_settings(descriptor, filtered_dict, user) + proctoring_errors = cls.validate_proctoring_settings(block, filtered_dict, user) if proctoring_errors: errors = errors + proctoring_errors did_validate = False # If did validate, go ahead and update the metadata if did_validate: - updated_data = cls.update_from_dict(key_values, descriptor, user, save=False) + updated_data = cls.update_from_dict(key_values, block, user, save=False) return did_validate, errors, updated_data @classmethod - def update_from_dict(cls, key_values, descriptor, user, save=True): + def update_from_dict(cls, key_values, block, user, save=True): """ - Update metadata descriptor from key_values. Saves to modulestore if save is true. + Update metadata from key_values. Saves to modulestore if save is true. """ for key, value in key_values.items(): - setattr(descriptor, key, value) + setattr(block, key, value) if save and key_values: - modulestore().update_item(descriptor, user.id) + modulestore().update_item(block, user.id) - return cls.fetch(descriptor) + return cls.fetch(block) @classmethod def validate_team_settings(cls, settings_dict): @@ -397,7 +397,7 @@ def validate_single_topic(cls, topic_settings): return None @classmethod - def validate_proctoring_settings(cls, descriptor, settings_dict, user): + def validate_proctoring_settings(cls, block, settings_dict, user): """ Verify proctoring settings @@ -412,9 +412,9 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): if ( not user.is_staff and cls._has_requested_proctoring_provider_changed( - descriptor.proctoring_provider, proctoring_provider_model.get('value') + block.proctoring_provider, proctoring_provider_model.get('value') ) and - datetime.now(pytz.UTC) > descriptor.start + datetime.now(pytz.UTC) > block.start ): message = ( 'The proctoring provider cannot be modified after a course has started.' @@ -426,7 +426,7 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): # should only be allowed if the exams IDA is enabled for a course available_providers = get_available_providers() updated_provider = settings_dict.get('proctoring_provider', {}).get('value') - if updated_provider == 'lti_external' and not exams_ida_enabled(descriptor.id): + if updated_provider == 'lti_external' and not exams_ida_enabled(block.id): available_providers.remove('lti_external') error = InvalidProctoringProvider('lti_external', available_providers) errors.append({'key': 'proctoring_provider', 'message': str(error), 'model': proctoring_provider_model}) @@ -435,7 +435,7 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): if enable_proctoring_model: enable_proctoring = enable_proctoring_model.get('value') else: - enable_proctoring = descriptor.enable_proctored_exams + enable_proctoring = block.enable_proctored_exams if enable_proctoring: # Require a valid escalation email if Proctortrack is chosen as the proctoring provider @@ -443,12 +443,12 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): if escalation_email_model: escalation_email = escalation_email_model.get('value') else: - escalation_email = descriptor.proctoring_escalation_email + escalation_email = block.proctoring_escalation_email if proctoring_provider_model: proctoring_provider = proctoring_provider_model.get('value') else: - proctoring_provider = descriptor.proctoring_provider + proctoring_provider = block.proctoring_provider missing_escalation_email_msg = 'Provider \'{provider}\' requires an exam escalation contact.' if proctoring_provider_model and proctoring_provider == 'proctortrack': @@ -477,7 +477,7 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): if zendesk_ticket_model: create_zendesk_tickets = zendesk_ticket_model.get('value') else: - create_zendesk_tickets = descriptor.create_zendesk_tickets + create_zendesk_tickets = block.create_zendesk_tickets if ( (proctoring_provider == 'proctortrack' and create_zendesk_tickets) @@ -489,7 +489,7 @@ def validate_proctoring_settings(cls, descriptor, settings_dict, user): 'should be updated for this course.'.format( ticket_value=create_zendesk_tickets, provider=proctoring_provider, - course_id=descriptor.id + course_id=block.id ) ) diff --git a/cms/djangoapps/xblock_config/apps.py b/cms/djangoapps/xblock_config/apps.py index 92271608f684..ae04e3f54793 100644 --- a/cms/djangoapps/xblock_config/apps.py +++ b/cms/djangoapps/xblock_config/apps.py @@ -19,9 +19,9 @@ class XBlockConfig(AppConfig): def ready(self): from openedx.core.lib.xblock_utils import xblock_local_resource_url - # In order to allow descriptors 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 - xmodule.x_module.descriptor_global_handler_url = cms.lib.xblock.runtime.handler_url - xmodule.x_module.descriptor_global_local_resource_url = xblock_local_resource_url + xmodule.x_module.block_global_handler_url = cms.lib.xblock.runtime.handler_url + xmodule.x_module.block_global_local_resource_url = xblock_local_resource_url diff --git a/common/djangoapps/util/block_utils.py b/common/djangoapps/util/block_utils.py index 7c84ace75c7d..1b937017ccca 100644 --- a/common/djangoapps/util/block_utils.py +++ b/common/djangoapps/util/block_utils.py @@ -3,34 +3,34 @@ """ -def yield_dynamic_descriptor_descendants(descriptor, user_id, block_creator=None): +def yield_dynamic_block_descendants(block, user_id, block_creator=None): """ - This returns all of the descendants of a descriptor. If the descriptor + This returns all of the descendants of a block. If the block has dynamic children, the block will be created using block_creator - and the children (as descriptors) of that module will be returned. + and the children (as blocks) of that module will be returned. """ - stack = [descriptor] + stack = [block] while len(stack) > 0: - next_descriptor = stack.pop() - stack.extend(get_dynamic_descriptor_children(next_descriptor, user_id, block_creator)) - yield next_descriptor + next_block = stack.pop() + stack.extend(get_dynamic_block_children(next_block, user_id, block_creator)) + yield next_block -def get_dynamic_descriptor_children(descriptor, user_id, block_creator=None, usage_key_filter=None): +def get_dynamic_block_children(block, user_id, block_creator=None, usage_key_filter=None): """ - Returns the children of the given descriptor, while supporting descriptors with dynamic children. + Returns the children of the given block, while supporting blocks 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: + if block.has_dynamic_children(): + parent_block = None + if block.scope_ids.user_id and user_id == block.scope_ids.user_id: # do not rebind the block if it's already bound to a user. - block = descriptor + parent_block = block elif block_creator: - block = block_creator(descriptor) - if block: - block_children = block.get_child_descriptors() + parent_block = block_creator(block) + if parent_block: + block_children = parent_block.get_child_blocks() else: - block_children = descriptor.get_children(usage_key_filter) + block_children = block.get_children(usage_key_filter) return block_children diff --git a/common/djangoapps/util/course.py b/common/djangoapps/util/course.py index 0df1208ae3c8..721410ff6976 100644 --- a/common/djangoapps/util/course.py +++ b/common/djangoapps/util/course.py @@ -40,7 +40,7 @@ def get_encoded_course_sharing_utm_params(): def get_link_for_about_page(course): """ Arguments: - course: This can be either a course overview object or a course descriptor. + course: This can be either a course overview object or a course block. Returns the course sharing url, this can be one of course's social sharing url, marketing url, or lms course about url. @@ -65,7 +65,7 @@ def get_link_for_about_page(course): def has_certificates_enabled(course): """ Arguments: - course: This can be either a course overview object or a course descriptor. + course: This can be either a course overview object or a course block. Returns a boolean if the course has enabled certificates """ if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): diff --git a/common/djangoapps/util/milestones_helpers.py b/common/djangoapps/util/milestones_helpers.py index 75bcc29b0714..f7909a08630e 100644 --- a/common/djangoapps/util/milestones_helpers.py +++ b/common/djangoapps/util/milestones_helpers.py @@ -150,35 +150,35 @@ def get_pre_requisite_courses_not_completed(user, enrolled_courses): return pre_requisite_courses -def get_prerequisite_courses_display(course_descriptor): +def get_prerequisite_courses_display(course_block): """ It would retrieve pre-requisite courses, make display strings and return list of dictionary with course key as 'key' field and course display name as `display` field. """ pre_requisite_courses = [] - if is_prerequisite_courses_enabled() and course_descriptor.pre_requisite_courses: - for course_id in course_descriptor.pre_requisite_courses: + if is_prerequisite_courses_enabled() and course_block.pre_requisite_courses: + for course_id in course_block.pre_requisite_courses: course_key = CourseKey.from_string(course_id) - required_course_descriptor = modulestore().get_course(course_key) + required_course_block = modulestore().get_course(course_key) prc = { 'key': course_key, - 'display': get_course_display_string(required_course_descriptor) + 'display': get_course_display_string(required_course_block) } pre_requisite_courses.append(prc) return pre_requisite_courses -def get_course_display_string(descriptor): +def get_course_display_string(block): """ Returns a string to display for a course or course overview. Arguments: - descriptor (CourseBlock|CourseOverview): a course or course overview. + block (CourseBlock|CourseOverview): a course or course overview. """ return ' '.join([ - descriptor.display_org_with_default, - descriptor.display_number_with_default + block.display_org_with_default, + block.display_number_with_default ]) diff --git a/common/djangoapps/util/tests/test_course.py b/common/djangoapps/util/tests/test_course.py index a1fb598ca6d6..1c476b9756f5 100644 --- a/common/djangoapps/util/tests/test_course.py +++ b/common/djangoapps/util/tests/test_course.py @@ -44,7 +44,7 @@ def get_course_sharing_link(self, enable_social_sharing, enable_mktg_site, use_o enable_mktg_site(Boolean): A feature flag to decide activation of marketing site. Keyword Arguments: - use_overview: indicates whether course overview or course descriptor should get + use_overview: indicates whether course overview or course block should get past to get_link_for_about_page. Returns course sharing url. @@ -115,10 +115,10 @@ def test_sharing_link_with_course_overview_attrs(self, overview_attrs, expected_ ), ) @ddt.unpack - def test_sharing_link_with_course_descriptor(self, enable_social_sharing, expected_course_sharing_link): + def test_sharing_link_with_course_block(self, enable_social_sharing, expected_course_sharing_link): """ Verify the method gives correct course sharing url on passing - course descriptor as a parameter. + course block as a parameter. """ actual_course_sharing_link = self.get_course_sharing_link( enable_social_sharing=enable_social_sharing, diff --git a/lms/djangoapps/certificates/api.py b/lms/djangoapps/certificates/api.py index 48fe0f7ef13a..c76e34a95bb7 100644 --- a/lms/djangoapps/certificates/api.py +++ b/lms/djangoapps/certificates/api.py @@ -610,7 +610,7 @@ def certificates_viewable_for_course(course): Returns True if certificates are viewable for any student enrolled in the course, False otherwise. Arguments: - course (CourseOverview or course descriptor): The course to check if certificates are viewable + course (CourseOverview or course block): The course to check if certificates are viewable Returns: boolean: whether the certificates are viewable or not @@ -879,7 +879,7 @@ def available_date_for_certificate(course, certificate): Returns the available date to use with a certificate Arguments: - course (CourseOverview or course descriptor): The course we're checking + course (CourseOverview or course block): The course we're checking certificate (GeneratedCertificate): The certificate we're getting the date for """ if _course_uses_available_date(course): @@ -892,7 +892,7 @@ def display_date_for_certificate(course, certificate): Returns the display date that a certificate should display. Arguments: - course (CourseOverview or course descriptor): The course we're getting the date for + course (CourseOverview or course block): The course we're getting the date for Returns: datetime.date """ diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 96832e3cb694..4d0cc82626af 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -747,7 +747,7 @@ def test_render_html_view_with_valid_signatories(self): @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_course_display_name_not_override_with_course_title(self): - # if certificate in descriptor has not course_title then course name should not be overridden with this title. + # if certificate in block has not course_title then course name should not be overridden with this title. test_certificates = [ { 'id': 0, diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index b859cfe92ca2..4d99b7d7722d 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -349,8 +349,8 @@ def _get_user_certificate(request, user, course_key, course_overview, preview_mo Returns None if there is no certificate generated for given user otherwise returns `GeneratedCertificate` instance. - We use the course_overview instead of the course descriptor here, so we get the certificate_available_date and - certificates_display_behavior validation logic, rather than the raw data from the course descriptor. + We use the course_overview instead of the course block here, so we get the certificate_available_date and + certificates_display_behavior validation logic, rather than the raw data from the course block. """ user_certificate = None if preview_mode: diff --git a/lms/djangoapps/course_api/blocks/api.py b/lms/djangoapps/course_api/blocks/api.py index 156fa3ed6e3a..a79e9759e191 100644 --- a/lms/djangoapps/course_api/blocks/api.py +++ b/lms/djangoapps/course_api/blocks/api.py @@ -159,7 +159,7 @@ def get_block_metadata(block, includes=()): Get metadata about the specified XBlock. Args: - block (XModuleDescriptor): block object + block (XBlock): block object includes (list|set): list or set of metadata keys to include. Valid keys are: index_dictionary: a dictionary of data used to add this XBlock's content to a search index. diff --git a/lms/djangoapps/course_api/blocks/transformers/student_view.py b/lms/djangoapps/course_api/blocks/transformers/student_view.py index 997b69dafcaa..b677bd66f5b6 100644 --- a/lms/djangoapps/course_api/blocks/transformers/student_view.py +++ b/lms/djangoapps/course_api/blocks/transformers/student_view.py @@ -33,7 +33,7 @@ def collect(cls, block_structure): for block_key in block_structure.topological_traversal(): block = block_structure.get_xblock(block_key) - # We're iterating through descriptors (not bound to a user) that are + # We're iterating through blocks (not bound to a user) that are # given to us by the modulestore. The reason we look at # block.__class__ is to avoid the XModuleDescriptor -> XModule # proxying that would happen if we just examined block directly, diff --git a/lms/djangoapps/course_api/tests/test_serializers.py b/lms/djangoapps/course_api/tests/test_serializers.py index 4ee5e10265e4..60971df57741 100644 --- a/lms/djangoapps/course_api/tests/test_serializers.py +++ b/lms/djangoapps/course_api/tests/test_serializers.py @@ -163,8 +163,8 @@ def setUp(self): super().setUp() # update the expected_data to include the 'overview' data. - about_descriptor = XBlock.load_class('about') - overview_template = about_descriptor.get_template('overview.yaml') + about_block = XBlock.load_class('about') + overview_template = about_block.get_template('overview.yaml') self.expected_data['overview'] = overview_template.get('data') # override test case diff --git a/lms/djangoapps/course_home_api/progress/views.py b/lms/djangoapps/course_home_api/progress/views.py index dc0ea63525f7..fd96ff6c08a5 100644 --- a/lms/djangoapps/course_home_api/progress/views.py +++ b/lms/djangoapps/course_home_api/progress/views.py @@ -226,8 +226,8 @@ def get(self, request, *args, **kwargs): user_grade = course_grade.percent user_has_passing_grade = user_grade >= course.lowest_passing_grade - descriptor = modulestore().get_course(course_key) - grading_policy = descriptor.grading_policy + block = modulestore().get_course(course_key) + grading_policy = block.grading_policy verification_status = IDVerificationService.user_status(student) verification_link = None if verification_status['status'] is None or verification_status['status'] == 'expired': diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index f71f2daec5bb..74f1d74f837f 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -73,7 +73,7 @@ def has_ccx_coach_role(user, course_key): Check if user is a coach on this ccx. Arguments: - user (User): the user whose descriptor access we are checking. + user (User): the user whose course access we are checking. course_key (CCXLocator): Key to CCX. Returns: @@ -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 block, descriptor, location, or + obj: The object to check access for. A block, location, or certain special strings (e.g. 'global') action: A string specifying the action that the client is trying to perform. @@ -146,11 +146,11 @@ def has_access(user, action, obj, course_key=None): return _has_access_course(user, action, obj) if isinstance(obj, ErrorBlock): - return _has_access_error_desc(user, action, obj, course_key) + return _has_access_error_block(user, action, obj, course_key) - # NOTE: any descriptor access checkers need to go above this + # NOTE: any block access checkers need to go above this if isinstance(obj, XBlock): - return _has_access_descriptor(user, action, obj, course_key) + return _has_access_to_block(user, action, obj, course_key) if isinstance(obj, CourseKey): return _has_access_course_key(user, action, obj) @@ -200,7 +200,7 @@ def _is_prerequisites_disabled(): return ( _is_prerequisites_disabled() - or _has_staff_access_to_descriptor(user, course, course.id) + or _has_staff_access_to_block(user, course, course.id) or user.is_anonymous or _has_fulfilled_prerequisites(user, [course.id]) ) @@ -226,7 +226,7 @@ def _can_load_course_on_mobile(user, course): return ( is_mobile_available_for_user(user, course) and ( - _has_staff_access_to_descriptor(user, course, course.id) or + _has_staff_access_to_block(user, course, course.id) or _has_fulfilled_all_milestones(user, course.id) ) ) @@ -244,13 +244,13 @@ def _can_enroll_courselike(user, courselike): Returns: AccessResponse, indicating whether the user can enroll. """ - # Courselike objects (e.g., course descriptors and CourseOverviews) have an attribute named `id` + # Courselike objects (CourseBlock and CourseOverview) have an attribute named `id` # which actually points to a CourseKey. Sigh. course_key = courselike.id course_enrollment_open = courselike.is_enrollment_open() - user_has_staff_access = _has_staff_access_to_descriptor(user, courselike, course_key) + user_has_staff_access = _has_staff_access_to_block(user, courselike, course_key) # If the user appears in CourseEnrollmentAllowed paired with the given course key, # they may enroll, except if the CEA has already been used by a different user. @@ -331,14 +331,14 @@ def can_load(): # _can_view_courseware_with_prerequisites, user, courselike # ) # ).or( - # _has_staff_access_to_descriptor, user, courselike, courselike.id + # _has_staff_access_to_block, user, courselike, courselike.id # ) if courselike.id.deprecated: # we no longer support accessing Old Mongo courses return OldMongoAccessError(courselike) visible_to_nonstaff = _visible_to_nonstaff_users(courselike) if not visible_to_nonstaff: - staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id) + staff_access = _has_staff_access_to_block(user, courselike, courselike.id) if staff_access: return staff_access else: @@ -346,7 +346,7 @@ def can_load(): open_for_learner = check_course_open_for_learner(user, courselike) if not open_for_learner: - staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id) + staff_access = _has_staff_access_to_block(user, courselike, courselike.id) if staff_access: return staff_access else: @@ -354,7 +354,7 @@ def can_load(): view_with_prereqs = _can_view_courseware_with_prerequisites(user, courselike) if not view_with_prereqs: - staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id) + staff_access = _has_staff_access_to_block(user, courselike, courselike.id) if staff_access: return staff_access else: @@ -362,7 +362,7 @@ def can_load(): has_not_expired = check_course_expired(user, courselike) if not has_not_expired: - staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id) + staff_access = _has_staff_access_to_block(user, courselike, courselike.id) if staff_access: return staff_access else: @@ -389,25 +389,25 @@ def see_exists(): def can_see_in_catalog(): """ Implements the "can see course in catalog" logic if a course should be visible in the main course catalog - In this case we use the catalog_visibility property on the course descriptor + In this case we use the catalog_visibility property on the course block but also allow course staff to see this. """ return ( _has_catalog_visibility(courselike, CATALOG_VISIBILITY_CATALOG_AND_ABOUT) - or _has_staff_access_to_descriptor(user, courselike, courselike.id) + or _has_staff_access_to_block(user, courselike, courselike.id) ) @function_trace('can_see_about_page') def can_see_about_page(): """ Implements the "can see course about page" logic if a course about page should be visible - In this case we use the catalog_visibility property on the course descriptor + In this case we use the catalog_visibility property on the course block but also allow course staff to see this. """ return ( _has_catalog_visibility(courselike, CATALOG_VISIBILITY_CATALOG_AND_ABOUT) or _has_catalog_visibility(courselike, CATALOG_VISIBILITY_ABOUT) - or _has_staff_access_to_descriptor(user, courselike, courselike.id) + or _has_staff_access_to_block(user, courselike, courselike.id) ) checkers = { @@ -415,8 +415,8 @@ def can_see_about_page(): 'load_mobile': lambda: can_load() and _can_load_course_on_mobile(user, courselike), 'enroll': can_enroll, 'see_exists': see_exists, - 'staff': lambda: _has_staff_access_to_descriptor(user, courselike, courselike.id), - 'instructor': lambda: _has_instructor_access_to_descriptor(user, courselike, courselike.id), + 'staff': lambda: _has_staff_access_to_block(user, courselike, courselike.id), + 'instructor': lambda: _has_instructor_access_to_block(user, courselike, courselike.id), 'see_in_catalog': can_see_in_catalog, 'see_about_page': can_see_about_page, } @@ -424,30 +424,30 @@ def can_see_about_page(): return _dispatch(checkers, action, user, courselike) -def _has_access_error_desc(user, action, descriptor, course_key): +def _has_access_error_block(user, action, block, course_key): """ - Only staff should see error descriptors. + Only staff should see error blocks. Valid actions: - 'load' -- load this descriptor, showing it to the user. - 'staff' -- staff access to descriptor. + 'load' -- load this block, showing it to the user. + 'staff' -- staff access to block. """ def check_for_staff(): - return _has_staff_access_to_descriptor(user, descriptor, course_key) + return _has_staff_access_to_block(user, block, course_key) checkers = { 'load': check_for_staff, 'staff': check_for_staff, - 'instructor': lambda: _has_instructor_access_to_descriptor(user, descriptor, course_key) + 'instructor': lambda: _has_instructor_access_to_block(user, block, course_key) } - return _dispatch(checkers, action, user, descriptor) + return _dispatch(checkers, action, user, block) -def _has_group_access(descriptor, user, course_key): +def _has_group_access(block, user, course_key): """ This function returns a boolean indicating whether or not `user` has - sufficient group memberships to "load" a block (the `descriptor`) + sufficient group memberships to "load" a block """ # Allow staff and instructors roles group access, as they are not masquerading as a student. if get_user_role(user, course_key) in ['staff', 'instructor']: @@ -455,7 +455,7 @@ def _has_group_access(descriptor, user, course_key): # use merged_group_access which takes group access on the block's # parents / ancestors into account - merged_access = descriptor.merged_group_access + merged_access = block.merged_group_access # resolve the partition IDs in group_access to actual # partition objects, skipping those which contain empty group directives. @@ -465,7 +465,7 @@ def _has_group_access(descriptor, user, course_key): partitions = [] for partition_id, group_ids in merged_access.items(): try: - partition = descriptor._get_user_partition(partition_id) # pylint: disable=protected-access + partition = block._get_user_partition(partition_id) # pylint: disable=protected-access # check for False in merged_access, which indicates that at least one # partition's group list excludes all students. @@ -509,7 +509,7 @@ def _has_group_access(descriptor, user, course_key): # If missing_groups is empty, the user is granted access. # If missing_groups is NOT empty, we generate an error based on one of the particular groups they are missing. missing_groups = [] - block_key = descriptor.scope_ids.usage_id + block_key = block.scope_ids.usage_id for partition, groups in partition_groups: user_group = partition.scheme.get_group_for_user( course_key, @@ -522,7 +522,7 @@ def _has_group_access(descriptor, user, course_key): user_group, groups, partition.access_denied_message(block_key, user, user_group, groups), - partition.access_denied_fragment(descriptor, user, user_group, groups), + partition.access_denied_fragment(block, user, user_group, groups), )) if missing_groups: @@ -542,15 +542,15 @@ def _has_group_access(descriptor, user, course_key): return ACCESS_GRANTED -def _has_access_descriptor(user, action, descriptor, course_key=None): +def _has_access_to_block(user, action, block, course_key=None): """ - Check if user has access to this descriptor. + Check if user has access to this block. Valid actions: - 'load' -- load this descriptor, showing it to the user. - 'staff' -- staff access to descriptor. + 'load' -- load this block, showing it to the user. + 'staff' -- staff access to block. - NOTE: This is the fallback logic for descriptors that don't have custom policy + NOTE: This is the fallback logic for blocks that don't have custom policy (e.g. courses). If you call this method directly instead of going through has_access(), it will not do the right thing. """ @@ -562,26 +562,26 @@ def can_load(): 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 - # before this method is that _has_staff_access_to_descriptor short-circuits and returns True + # access to this content, then deny access. The problem with calling _has_staff_access_to_block + # before this method is that _has_staff_access_to_block short-circuits and returns True # for staff users in preview mode. - group_access_response = _has_group_access(descriptor, user, course_key) + group_access_response = _has_group_access(block, user, course_key) if not group_access_response: return group_access_response # 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) + staff_access_response = _has_staff_access_to_block(user, block, course_key) if staff_access_response: return staff_access_response return ( - _visible_to_nonstaff_users(descriptor, display_error_to_user=False) and + _visible_to_nonstaff_users(block, display_error_to_user=False) and ( - _has_detached_class_tag(descriptor) or + _has_detached_class_tag(block) or check_start_date( user, - descriptor.days_early_for_beta, - descriptor.start, + block.days_early_for_beta, + block.start, course_key, display_error_to_user=False ) @@ -590,11 +590,11 @@ def can_load(): checkers = { 'load': can_load, - 'staff': lambda: _has_staff_access_to_descriptor(user, descriptor, course_key), - 'instructor': lambda: _has_instructor_access_to_descriptor(user, descriptor, course_key) + 'staff': lambda: _has_staff_access_to_block(user, block, course_key), + 'instructor': lambda: _has_instructor_access_to_block(user, block, course_key) } - return _dispatch(checkers, action, user, descriptor) + return _dispatch(checkers, action, user, block) def _has_access_location(user, action, location, course_key): @@ -762,53 +762,53 @@ def administrative_accesses_to_course_for_user(user, course_key): return global_staff, staff_access, instructor_access -@function_trace('_has_instructor_access_to_descriptor') -def _has_instructor_access_to_descriptor(user, descriptor, course_key): +@function_trace('_has_instructor_access_to_block') +def _has_instructor_access_to_block(user, block, course_key): """Helper method that checks whether the user has staff access to the course of the location. - descriptor: something that has a location attribute + block: something that has a location attribute """ - return _has_instructor_access_to_location(user, descriptor.location, course_key) + return _has_instructor_access_to_location(user, block.location, course_key) -@function_trace('_has_staff_access_to_descriptor') -def _has_staff_access_to_descriptor(user, descriptor, course_key): +@function_trace('_has_staff_access_to_block') +def _has_staff_access_to_block(user, block, course_key): """Helper method that checks whether the user has staff access to the course of the location. - descriptor: something that has a location attribute + block: something that has a location attribute """ - return _has_staff_access_to_location(user, descriptor.location, course_key) + return _has_staff_access_to_location(user, block.location, course_key) -def _visible_to_nonstaff_users(descriptor, display_error_to_user=True): +def _visible_to_nonstaff_users(block, display_error_to_user=True): """ Returns if the object is visible to nonstaff users. Arguments: - descriptor: object to check + block: object to check display_error_to_user: If True, show an error message to the user say the content was hidden. Otherwise, hide the content silently. """ - if descriptor.visible_to_staff_only: + if block.visible_to_staff_only: return VisibilityError(display_error_to_user=display_error_to_user) else: return ACCESS_GRANTED -def _can_access_descriptor_with_milestones(user, descriptor, course_key): +def _can_access_block_with_milestones(user, block, course_key): """ Returns if the object is blocked by an unfulfilled milestone. Args: user: the user trying to access this content - descriptor: the object being accessed - course_key: key for the course for this descriptor + block: the object being accessed + course_key: key for the course """ if milestones_helpers.get_course_content_milestones( course_key, - str(descriptor.location), + str(block.location), 'requires', user.id ): @@ -818,14 +818,14 @@ def _can_access_descriptor_with_milestones(user, descriptor, course_key): return ACCESS_GRANTED -def _has_detached_class_tag(descriptor): +def _has_detached_class_tag(block): """ - Returns if the given descriptor's type is marked as detached. + Returns if the given block's type is marked as detached. Arguments: - descriptor: object to check + block: object to check """ - return ACCESS_GRANTED if 'detached' in descriptor._class_tags else ACCESS_DENIED # pylint: disable=protected-access + return ACCESS_GRANTED if 'detached' in block._class_tags else ACCESS_DENIED # pylint: disable=protected-access def _has_fulfilled_all_milestones(user, course_id): @@ -859,29 +859,29 @@ def _has_catalog_visibility(course, visibility_type): return ACCESS_GRANTED if course.catalog_visibility == visibility_type else ACCESS_DENIED -def _is_descriptor_mobile_available(descriptor): +def _is_block_mobile_available(block): """ - Returns if descriptor is available on mobile. + Returns if block is available on mobile. """ - if IgnoreMobileAvailableFlagConfig.is_enabled() or descriptor.mobile_available: + if IgnoreMobileAvailableFlagConfig.is_enabled() or block.mobile_available: return ACCESS_GRANTED else: return MobileAvailabilityError() -def is_mobile_available_for_user(user, descriptor): +def is_mobile_available_for_user(user, block): """ Returns whether the given course is mobile_available for the given user. Checks: mobile_available flag on the course Beta User and staff access overrides the mobile_available flag Arguments: - descriptor (CourseBlock|CourseOverview): course or overview of course in question + block (CourseBlock|CourseOverview): course or overview of course in question """ return ( - auth.user_has_role(user, CourseBetaTesterRole(descriptor.id)) - or _has_staff_access_to_descriptor(user, descriptor, descriptor.id) - or _is_descriptor_mobile_available(descriptor) + auth.user_has_role(user, CourseBetaTesterRole(block.id)) + or _has_staff_access_to_block(user, block, block.id) + or _is_block_mobile_available(block) ) diff --git a/lms/djangoapps/courseware/block_render.py b/lms/djangoapps/courseware/block_render.py index 6cf435f5a0b9..b66a193f4f3f 100644 --- a/lms/djangoapps/courseware/block_render.py +++ b/lms/djangoapps/courseware/block_render.py @@ -297,7 +297,7 @@ def get_block(user, request, usage_key, field_data_cache, position=None, log_if_ XModule javascript to be bound correctly - depth : number of levels of descendents to cache when loading this module. None means cache all descendents - - static_asset_path : static asset path to use (overrides descriptor's value); needed + - static_asset_path : static asset path to use (overrides block's value); needed by get_course_info_section, because info section modules do not have a course as the parent module, and thus do not inherit this lms key value. @@ -310,8 +310,8 @@ def get_block(user, request, usage_key, field_data_cache, position=None, log_if_ if possible. If not possible, return None. """ try: - descriptor = modulestore().get_item(usage_key, depth=depth) - return get_block_for_descriptor(user, request, descriptor, field_data_cache, usage_key.course_key, + block = modulestore().get_item(usage_key, depth=depth) + return get_block_for_descriptor(user, request, block, field_data_cache, usage_key.course_key, position=position, wrap_xblock_display=wrap_xblock_display, grade_bucket_type=grade_bucket_type, @@ -365,7 +365,7 @@ def display_access_messages(user, block, view, frag, context): # pylint: disabl # pylint: disable=too-many-statements -def get_block_for_descriptor(user, request, descriptor, field_data_cache, course_key, +def get_block_for_descriptor(user, request, block, 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): @@ -387,7 +387,7 @@ def get_block_for_descriptor(user, request, descriptor, field_data_cache, course return get_block_for_descriptor_internal( user=user, - descriptor=descriptor, + block=block, student_data=student_data, course_id=course_key, track_function=track_function, @@ -469,17 +469,17 @@ def make_xqueue_callback(dispatch='score_update'): waittime=settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS, ) - def inner_get_block(descriptor): + def inner_get_block(block): """ - Delegate to get_block_for_descriptor_internal() with all values except `descriptor` set. + Delegate to get_block_for_descriptor_internal() with all values except `block` set. Because it does an access check, it may return None. """ - # TODO: fix this so that make_xqueue_callback uses the descriptor passed into + # TODO: fix this so that make_xqueue_callback uses the block passed into # inner_get_block, not the parent's callback. Add it as an argument.... return get_block_for_descriptor_internal( user=user, - descriptor=descriptor, + block=block, student_data=student_data, course_id=course_id, track_function=track_function, @@ -648,7 +648,7 @@ def inner_get_block(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_block_for_descriptor_internal(user, descriptor, student_data, course_id, track_function, request_token, +def get_block_for_descriptor_internal(user, block, 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): @@ -664,7 +664,7 @@ def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, student_data = prepare_runtime_for_user( user=user, student_data=student_data, # These have implicit user bindings, the rest of args are considered not to - block=descriptor, + block=block, course_id=course_id, track_function=track_function, position=position, @@ -678,7 +678,7 @@ def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, will_recheck_access=will_recheck_access, ) - descriptor.bind_for_student( + block.bind_for_student( user.id, [ partial(DateLookupFieldData, course_id=course_id, user=user), @@ -687,16 +687,16 @@ def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, ], ) - descriptor.scope_ids = descriptor.scope_ids._replace(user_id=user.id) + block.scope_ids = block.scope_ids._replace(user_id=user.id) # Do not check access when it's a noauth request. - # Not that the access check needs to happen after the descriptor is bound + # Not that the access check needs to happen after the block is bound # for the student, since there may be field override data for the student # that affects xblock visibility. user_needs_access_check = getattr(user, 'known', True) and not isinstance(user, SystemUser) if user_needs_access_check: - access = has_access(user, 'load', descriptor, course_id) - # A descriptor should only be returned if either the user has access, or the user doesn't have access, but + access = has_access(user, 'load', block, course_id) + # A block should only be returned if either the user has access, or the user doesn't have access, but # the failed access has a message for the user and the caller of this function specifies it will check access # again. This allows blocks to show specific error message or upsells when access is denied. caller_will_handle_access_error = ( @@ -705,10 +705,10 @@ def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, and (access.user_message or access.user_fragment) ) if access or caller_will_handle_access_error: - descriptor.has_access_error = bool(caller_will_handle_access_error) - return descriptor + block.has_access_error = bool(caller_will_handle_access_error) + return block return None - return descriptor + return block def load_single_xblock(request, user_id, course_id, usage_key_string, course=None, will_recheck_access=False): @@ -719,7 +719,7 @@ def load_single_xblock(request, user_id, course_id, usage_key_string, course=Non course_key = CourseKey.from_string(course_id) usage_key = usage_key.map_into_course(course_key) user = User.objects.get(id=user_id) - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( course_key, user, modulestore().get_item(usage_key), @@ -873,15 +873,15 @@ def _get_usage_key_for_course(course_key, usage_id) -> UsageKey: raise Http404("Invalid location") from exc -def _get_descriptor_by_usage_key(usage_key): +def _get_block_by_usage_key(usage_key): """ - Gets a descriptor instance based on a mapped-to-course usage_key + Gets a block instance based on a mapped-to-course usage_key Returns (instance, tracking_context) """ try: - descriptor = modulestore().get_item(usage_key) - descriptor_orig_usage_key, descriptor_orig_version = modulestore().get_block_original_usage(usage_key) + block = modulestore().get_item(usage_key) + block_orig_usage_key, block_orig_version = modulestore().get_block_original_usage(usage_key) except ItemNotFoundError as exc: log.warning( "Invalid location for course id %s: %s", @@ -893,17 +893,17 @@ def _get_descriptor_by_usage_key(usage_key): tracking_context = { 'module': { # xss-lint: disable=python-deprecated-display-name - 'display_name': descriptor.display_name_with_default_escaped, - 'usage_key': str(descriptor.location), + 'display_name': block.display_name_with_default_escaped, + 'usage_key': str(block.location), } } # For blocks that are inherited from a content library, we add some additional metadata: - if descriptor_orig_usage_key is not None: - tracking_context['module']['original_usage_key'] = str(descriptor_orig_usage_key) - tracking_context['module']['original_usage_version'] = str(descriptor_orig_version) + if block_orig_usage_key is not None: + tracking_context['module']['original_usage_key'] = str(block_orig_usage_key) + tracking_context['module']['original_usage_version'] = str(block_orig_version) - return descriptor, tracking_context + return block, tracking_context def get_block_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None, @@ -915,19 +915,19 @@ def get_block_by_usage_id(request, course_id, usage_id, disable_staff_debug_info """ course_key = CourseKey.from_string(course_id) usage_key = _get_usage_key_for_course(course_key, usage_id) - descriptor, tracking_context = _get_descriptor_by_usage_key(usage_key) + block, tracking_context = _get_block_by_usage_key(usage_key) - _, user = setup_masquerade(request, course_key, has_access(request.user, 'staff', descriptor, course_key)) - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + _, user = setup_masquerade(request, course_key, has_access(request.user, 'staff', block, course_key)) + field_data_cache = FieldDataCache.cache_for_block_descendents( course_key, user, - descriptor, + block, read_only=CrawlersConfig.is_crawler(request), ) instance = get_block_for_descriptor( user, request, - descriptor, + block, field_data_cache, usage_key.course_key, disable_staff_debug_info=disable_staff_debug_info, @@ -978,13 +978,13 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course block_usage_key = usage_key # Peek at the handler method to see if it actually wants to check access itself. (The handler may not want - # inaccessible blocks stripped from the tree.) This ends up doing two modulestore lookups for the descriptor, + # inaccessible blocks stripped from the tree.) This ends up doing two modulestore lookups for the block, # but the blocks should be available in the request cache the second time. # At the time of writing, this is only used by one handler. If this usage grows, we may want to re-evaluate # how we do this to something more elegant. If you are the author of a third party block that decides it wants # to set this too, please let us know so we can consider making this easier / better-documented. - descriptor, _ = _get_descriptor_by_usage_key(block_usage_key) - handler_method = getattr(descriptor, handler, False) + block, _ = _get_block_by_usage_key(block_usage_key) + handler_method = getattr(block, handler, False) will_recheck_access = handler_method and getattr(handler_method, 'will_recheck_access', False) instance, tracking_context = get_block_by_usage_id( diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 676a42bd70e6..009ebf6fdb52 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -76,7 +76,7 @@ def get_course(course_id, depth=0): """ - Given a course id, return the corresponding course descriptor. + Given a course id, return the corresponding course block. If the course does not exist, raises a CourseRunNotFound. This is appropriate for internal use. @@ -92,9 +92,9 @@ def get_course(course_id, depth=0): def get_course_with_access(user, action, course_key, depth=0, check_if_enrolled=False, check_survey_complete=True, check_if_authenticated=False): # lint-amnesty, pylint: disable=line-too-long """ - Given a course_key, look up the corresponding course descriptor, + Given a course_key, look up the corresponding course block, check that the user has the access to perform the specified action - on the course, and return the descriptor. + on the course, and return the block. Raises a 404 if the course_key is invalid, or the user doesn't have access. @@ -857,26 +857,26 @@ def get_problems_in_section(section): """ This returns a dict having problems in a section. Returning dict has problem location as keys and problem - descriptor as values. + block as values. """ - problem_descriptors = defaultdict() + problem_blocks = defaultdict() if not isinstance(section, UsageKey): section_key = UsageKey.from_string(section) else: section_key = section # it will be a Mongo performance boost, if you pass in a depth=3 argument here # as it will optimize round trips to the database to fetch all children for the current node - section_descriptor = modulestore().get_item(section_key, depth=3) + section_block = modulestore().get_item(section_key, depth=3) # iterate over section, sub-section, vertical - for subsection in section_descriptor.get_children(): + for subsection in section_block.get_children(): for vertical in subsection.get_children(): for component in vertical.get_children(): if component.location.block_type == 'problem' and getattr(component, 'has_score', False): - problem_descriptors[str(component.location)] = component + problem_blocks[str(component.location)] = component - return problem_descriptors + return problem_blocks def get_current_child(xblock, min_depth=None, requested_child=None): diff --git a/lms/djangoapps/courseware/management/commands/clean_xml.py b/lms/djangoapps/courseware/management/commands/clean_xml.py index 2dd247de4da5..7cebce361205 100644 --- a/lms/djangoapps/courseware/management/commands/clean_xml.py +++ b/lms/djangoapps/courseware/management/commands/clean_xml.py @@ -17,7 +17,7 @@ def traverse_tree(course): """ - Load every descriptor in course. Return bool success value. + Load every block in course. Return bool success value. """ queue = [course] while len(queue) > 0: diff --git a/lms/djangoapps/courseware/masquerade.py b/lms/djangoapps/courseware/masquerade.py index e838f862c518..5ce266c463d6 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -112,8 +112,8 @@ def get(self, request, course_key_string): group_id=None, user_name=None, ) - descriptor = modulestore().get_course(course_key) - partitions = get_all_partitions_for_course(descriptor, active_only=True) + block = modulestore().get_course(course_key) + partitions = get_all_partitions_for_course(block, active_only=True) data = { 'success': True, 'active': { diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py index 26578f286c11..59fcc725ed36 100644 --- a/lms/djangoapps/courseware/model_data.py +++ b/lms/djangoapps/courseware/model_data.py @@ -51,30 +51,30 @@ class InvalidWriteError(Exception): """ -def _all_usage_keys(descriptors, aside_types): +def _all_usage_keys(blocks, aside_types): """ - Return a set of all usage_ids for the `descriptors` and for - as all asides in `aside_types` for those descriptors. + Return a set of all usage_ids for the `blocks` and for + as all asides in `aside_types` for those blocks. """ usage_ids = set() - for descriptor in descriptors: - usage_ids.add(descriptor.scope_ids.usage_id) + for block in blocks: + usage_ids.add(block.scope_ids.usage_id) for aside_type in aside_types: - usage_ids.add(AsideUsageKeyV1(descriptor.scope_ids.usage_id, aside_type)) - usage_ids.add(AsideUsageKeyV2(descriptor.scope_ids.usage_id, aside_type)) + usage_ids.add(AsideUsageKeyV1(block.scope_ids.usage_id, aside_type)) + usage_ids.add(AsideUsageKeyV2(block.scope_ids.usage_id, aside_type)) return usage_ids -def _all_block_types(descriptors, aside_types): +def _all_block_types(blocks, aside_types): """ - Return a set of all block_types for the supplied `descriptors` and for - the asides types in `aside_types` associated with those descriptors. + Return a set of all block_types for the supplied `blocks` and for + the asides types in `aside_types` associated with those blocks. """ block_types = set() - for descriptor in descriptors: - block_types.add(BlockTypeKeyV1(descriptor.entry_point, descriptor.scope_ids.block_type)) + for block in blocks: + block_types.add(BlockTypeKeyV1(block.entry_point, block.scope_ids.block_type)) for aside_type in aside_types: block_types.add(BlockTypeKeyV1(XBlockAside.entry_point, aside_type)) @@ -665,15 +665,15 @@ class FieldDataCache: A cache of django model objects needed to supply the data for a block and its descendants """ - def __init__(self, descriptors, course_id, user, asides=None, read_only=False): + def __init__(self, blocks, 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. + Find any courseware.models objects that are needed by any block + in blocks. Attempts to minimize the number of queries to the database. Note: Only blocks that have store_state = True or have shared state will have a StudentModule. Arguments - descriptors: A list of XModuleDescriptors. + blocks: A list of XBlocks. course_id: The id of the current course user: The user for which to cache data asides: The list of aside types to load, or None to prefetch no asides. @@ -705,84 +705,84 @@ def __init__(self, descriptors, course_id, user, asides=None, read_only=False): ), } self.scorable_locations = set() - self.add_descriptors_to_cache(descriptors) + self.add_blocks_to_cache(blocks) - def add_descriptors_to_cache(self, descriptors): + def add_blocks_to_cache(self, blocks): """ - Add all `descriptors` to this FieldDataCache. + Add all `blocks` to this FieldDataCache. """ if self.user.is_authenticated: - self.scorable_locations.update(desc.location for desc in descriptors if desc.has_score) - for scope, fields in self._fields_to_cache(descriptors).items(): + self.scorable_locations.update(block.location for block in blocks if block.has_score) + for scope, fields in self._fields_to_cache(blocks).items(): if scope not in self.cache: continue - self.cache[scope].cache_fields(fields, descriptors, self.asides) + self.cache[scope].cache_fields(fields, blocks, self.asides) - def add_descriptor_descendents(self, descriptor, depth=None, descriptor_filter=lambda descriptor: True): + def add_block_descendents(self, block, depth=None, block_filter=lambda block: True): """ - Add all descendants of `descriptor` to this FieldDataCache. + Add all descendants of `block` to this FieldDataCache. Arguments: - descriptor: An XModuleDescriptor + block: An XBlock 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 + the supplied block. If depth is None, load all descendant StudentModules + block_filter is a function that accepts a block and return whether the field data should be cached """ - def get_child_descriptors(descriptor, depth, descriptor_filter): + def get_child_blocks(block, depth, block_filter): """ - Return a list of all child descriptors down to the specified depth - that match the descriptor filter. Includes `descriptor` + Return a list of all child blocks down to the specified depth + that match the block filter. Includes `block` - descriptor: The parent to search inside + block: The parent to search inside depth: The number of levels to descend, or None for infinite depth - descriptor_filter(descriptor): A function that returns True - if descriptor should be included in the results + block_filter(block): A function that returns True + if block should be included in the results """ - if descriptor_filter(descriptor): - descriptors = [descriptor] + if block_filter(block): + blocks = [block] else: - descriptors = [] + blocks = [] 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_block_descriptors(): - descriptors.extend(get_child_descriptors(child, new_depth, descriptor_filter)) + for child in block.get_children() + block.get_required_block_descriptors(): + blocks.extend(get_child_blocks(child, new_depth, block_filter)) - return descriptors + return blocks - with modulestore().bulk_operations(descriptor.location.course_key): - descriptors = get_child_descriptors(descriptor, depth, descriptor_filter) + with modulestore().bulk_operations(block.location.course_key): + blocks = get_child_blocks(block, depth, block_filter) - self.add_descriptors_to_cache(descriptors) + self.add_blocks_to_cache(blocks) @classmethod - def cache_for_descriptor_descendents(cls, course_id, user, descriptor, depth=None, - descriptor_filter=lambda descriptor: True, - asides=None, read_only=False): + def cache_for_block_descendents(cls, course_id, user, block, depth=None, + block_filter=lambda block: True, + asides=None, read_only=False): """ course_id: the course in the context of which we want StudentModules. user: the django user for whom to load modules. - descriptor: An XModuleDescriptor + block: An XBlock 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 + the supplied block. If depth is None, load all descendant StudentModules + block_filter is a function that accepts a block and return whether the field data should be cached """ cache = FieldDataCache([], course_id, user, asides=asides, read_only=read_only) - cache.add_descriptor_descendents(descriptor, depth, descriptor_filter) + cache.add_block_descendents(block, depth, block_filter) return cache - def _fields_to_cache(self, descriptors): + def _fields_to_cache(self, blocks): """ Returns a map of scopes to fields in that scope that should be cached """ scope_map = defaultdict(set) - for descriptor in descriptors: - for field in descriptor.fields.values(): + for block in blocks: + for field in block.fields.values(): scope_map[field.scope].add(field) return scope_map diff --git a/lms/djangoapps/courseware/tests/helpers.py b/lms/djangoapps/courseware/tests/helpers.py index 99dbf75250c2..577f8b2ca323 100644 --- a/lms/djangoapps/courseware/tests/helpers.py +++ b/lms/djangoapps/courseware/tests/helpers.py @@ -85,20 +85,20 @@ def initialize_module(self, runtime_kwargs=None, **kwargs): # lint-amnesty, pyl 'category': self.CATEGORY }) - self.item_descriptor = BlockFactory.create(**kwargs) + self.block = BlockFactory.create(**kwargs) self.runtime = self.new_descriptor_runtime() field_data = {} field_data.update(self.MODEL_DATA) student_data = DictFieldData(field_data) - self.item_descriptor._field_data = LmsFieldData(self.item_descriptor._field_data, student_data) # lint-amnesty, pylint: disable=protected-access + self.block._field_data = LmsFieldData(self.block._field_data, student_data) # lint-amnesty, pylint: disable=protected-access if runtime_kwargs is None: runtime_kwargs = {} - self.new_module_runtime(runtime=self.item_descriptor.runtime, **runtime_kwargs) + self.new_module_runtime(runtime=self.block.runtime, **runtime_kwargs) - self.item_url = str(self.item_descriptor.location) + self.item_url = str(self.block.location) def setup_course(self): # lint-amnesty, pylint: disable=missing-function-docstring self.course = CourseFactory.create(data=self.COURSE_DATA) diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py index b472234d41f8..8a4cbabad6cc 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -182,15 +182,15 @@ def setUp(self): self.staff = GlobalStaffFactory() def verify_access(self, mock_unit, student_should_have_access, expected_error_type=None): - """ Verify the expected result from _has_access_descriptor """ - response = access._has_access_descriptor(self.anonymous_user, 'load', mock_unit, course_key=self.course.id) + """ Verify the expected result from _has_access_to_block """ + response = access._has_access_to_block(self.anonymous_user, 'load', mock_unit, course_key=self.course.id) assert student_should_have_access == bool(response) if expected_error_type is not None: assert isinstance(response, expected_error_type) assert response.to_json()['error_code'] is not None - assert access._has_access_descriptor(self.course_staff, 'load', mock_unit, course_key=self.course.id) + assert access._has_access_to_block(self.course_staff, 'load', mock_unit, course_key=self.course.id) def test_has_staff_access_to_preview_mode(self): """ @@ -356,31 +356,31 @@ def test__has_access_string(self): ('instructor', False, False, True) ) @ddt.unpack - def test__has_access_error_desc(self, action, expected_student, expected_staff, expected_instructor): - descriptor = Mock() + def test__has_access_error_block(self, action, expected_student, expected_staff, expected_instructor): + block = Mock() for (user, expected_response) in ( (self.student, expected_student), (self.course_staff, expected_staff), (self.course_instructor, expected_instructor) ): - assert bool(access._has_access_error_desc(user, action, descriptor, self.course.id)) == expected_response + assert bool(access._has_access_error_block(user, action, block, self.course.id)) == expected_response with pytest.raises(ValueError): - access._has_access_error_desc(self.course_instructor, 'not_load_or_staff', descriptor, self.course.id) + access._has_access_error_block(self.course_instructor, 'not_load_or_staff', block, self.course.id) - def test__has_access_descriptor(self): + def test__has_access_to_block(self): # TODO: override DISABLE_START_DATES and test the start date branch of the method user = Mock() - descriptor = Mock(user_partitions=[]) - descriptor._class_tags = {} - descriptor.merged_group_access = {} + block = Mock(user_partitions=[]) + block._class_tags = {} + block.merged_group_access = {} # Always returns true because DISABLE_START_DATES is set in test.py - assert access._has_access_descriptor(user, 'load', descriptor) - assert access._has_access_descriptor(user, 'instructor', descriptor) + assert access._has_access_to_block(user, 'load', block) + assert access._has_access_to_block(user, 'instructor', block) with pytest.raises(ValueError): - access._has_access_descriptor(user, 'not_load_or_staff', descriptor) + access._has_access_to_block(user, 'not_load_or_staff', block) @ddt.data( (True, None, access_response.VisibilityError), @@ -392,20 +392,20 @@ def test__has_access_descriptor(self): ) @ddt.unpack @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False}) - def test__has_access_descriptor_staff_lock(self, visible_to_staff_only, start, expected_error_type=None): + def test__has_access_to_block_staff_lock(self, visible_to_staff_only, start, expected_error_type=None): """ Tests that "visible_to_staff_only" overrides start date. """ expected_access = expected_error_type is None mock_unit = Mock(location=self.course.location, user_partitions=[]) - mock_unit._class_tags = {} # Needed for detached check in _has_access_descriptor + mock_unit._class_tags = {} # Needed for detached check in _has_access_to_block mock_unit.visible_to_staff_only = visible_to_staff_only mock_unit.start = self.DATES[start] mock_unit.merged_group_access = {} self.verify_access(mock_unit, expected_access, expected_error_type) - def test__has_access_descriptor_beta_user(self): + def test__has_access_to_block_beta_user(self): mock_unit = Mock(user_partitions=[]) mock_unit._class_tags = {} mock_unit.days_early_for_beta = 2 @@ -413,7 +413,7 @@ def test__has_access_descriptor_beta_user(self): mock_unit.visible_to_staff_only = False mock_unit.merged_group_access = {} - assert bool(access._has_access_descriptor(self.beta_user, 'load', mock_unit, course_key=self.course.id)) + assert bool(access._has_access_to_block(self.beta_user, 'load', mock_unit, course_key=self.course.id)) @ddt.data(None, YESTERDAY, TOMORROW) @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False}) @@ -421,12 +421,12 @@ def test__has_access_descriptor_beta_user(self): 'lms.djangoapps.courseware.access_utils.get_current_request_hostname', Mock(return_value='preview.localhost') ) - def test__has_access_descriptor_in_preview_mode(self, start): + def test__has_access_to_block_in_preview_mode(self, start): """ - Tests that descriptor has access in preview mode. + Tests that block has access in preview mode. """ mock_unit = Mock(location=self.course.location, user_partitions=[]) - mock_unit._class_tags = {} # Needed for detached check in _has_access_descriptor + mock_unit._class_tags = {} # Needed for detached check in _has_access_to_block mock_unit.visible_to_staff_only = False mock_unit.start = self.DATES[start] mock_unit.merged_group_access = {} @@ -441,13 +441,13 @@ def test__has_access_descriptor_in_preview_mode(self, start): @ddt.unpack @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False}) @patch('lms.djangoapps.courseware.access_utils.get_current_request_hostname', Mock(return_value='localhost')) - def test__has_access_descriptor_when_not_in_preview_mode(self, start, expected_error_type): + def test__has_access_to_block_when_not_in_preview_mode(self, start, expected_error_type): """ - Tests that descriptor has no access when start date in future & without preview. + Tests that block has no access when start date in future & without preview. """ expected_access = expected_error_type is None mock_unit = Mock(location=self.course.location, user_partitions=[]) - mock_unit._class_tags = {} # Needed for detached check in _has_access_descriptor + mock_unit._class_tags = {} # Needed for detached check in _has_access_to_block mock_unit.visible_to_staff_only = False mock_unit.start = self.DATES[start] mock_unit.merged_group_access = {} @@ -663,12 +663,12 @@ def test__access_on_mobile(self, mobile_available, student_expected, staff_expec """ Test course access on mobile for staff and students. """ - descriptor = CourseFactory() - descriptor.visible_to_staff_only = False - descriptor.mobile_available = mobile_available + course = CourseFactory() + course.visible_to_staff_only = False + course.mobile_available = mobile_available - assert bool(access._has_access_course(self.student, 'load_mobile', descriptor)) == student_expected - assert bool(access._has_access_course(self.staff, 'load_mobile', descriptor)) == staff_expected + assert bool(access._has_access_course(self.student, 'load_mobile', course)) == student_expected + assert bool(access._has_access_course(self.staff, 'load_mobile', course)) == staff_expected @patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True}) def test_courseware_page_unfulfilled_prereqs(self): diff --git a/lms/djangoapps/courseware/tests/test_block_render.py b/lms/djangoapps/courseware/tests/test_block_render.py index 37c38486719b..9c2e5e9766ea 100644 --- a/lms/djangoapps/courseware/tests/test_block_render.py +++ b/lms/djangoapps/courseware/tests/test_block_render.py @@ -251,7 +251,7 @@ def test_block_render_with_jump_to_id(self): course = get_course_with_access(self.mock_user, 'load', self.course_key) - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( self.course_key, self.mock_user, course, depth=2) block = render.get_block( @@ -411,14 +411,14 @@ def test_rebinding_same_user(self, block_type): request = self.request_factory.get('') request.user = self.mock_user course = CourseFactory() - descriptor = BlockFactory(category=block_type, parent=course) - field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user) + block = BlockFactory(category=block_type, parent=course) + field_data_cache = FieldDataCache([self.toy_course, block], self.toy_course.id, self.mock_user) # 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_block_for_descriptor( self.mock_user, request, - descriptor, + block, field_data_cache, self.toy_course.id, course=self.toy_course @@ -426,7 +426,7 @@ def test_rebinding_same_user(self, block_type): render.get_block_for_descriptor( self.mock_user, request, - descriptor, + block, field_data_cache, self.toy_course.id, course=self.toy_course @@ -442,7 +442,7 @@ def test_rebinding_same_user(self, block_type): @ddt.data('regular', 'test_aside') def test_rebind_different_users(self, block_category): """ - This tests the rebinding a descriptor to a student does not result + This tests the rebinding a block to a student does not result in overly nested _field_data. """ def create_aside(item, block_type): @@ -467,33 +467,33 @@ def create_aside(item, block_type): request.user = self.mock_user course = CourseFactory.create() - descriptor = BlockFactory(category="html", parent=course) + block = BlockFactory(category="html", parent=course) if block_category == 'test_aside': - descriptor = create_aside(descriptor, "test_aside") + block = create_aside(block, "test_aside") field_data_cache = FieldDataCache( - [course, descriptor], course.id, self.mock_user + [course, block], course.id, self.mock_user ) # grab what _field_data was originally set to - original_field_data = descriptor._field_data # lint-amnesty, pylint: disable=no-member, protected-access + original_field_data = block._field_data # lint-amnesty, pylint: disable=no-member, protected-access render.get_block_for_descriptor( - self.mock_user, request, descriptor, field_data_cache, course.id, course=course + self.mock_user, request, block, field_data_cache, course.id, course=course ) # check that _unwrapped_field_data is the same as the original # _field_data, but now _field_data as been reset. # pylint: disable=protected-access - 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 + assert block._unwrapped_field_data is original_field_data # lint-amnesty, pylint: disable=no-member + assert block._unwrapped_field_data is not block._field_data # lint-amnesty, pylint: disable=no-member # now bind this block to a few other students for user in [UserFactory(), UserFactory(), self.mock_user]: render.get_block_for_descriptor( user, request, - descriptor, + block, field_data_cache, course.id, course=course @@ -501,14 +501,14 @@ def create_aside(item, block_type): # _field_data should now be wrapped by LmsFieldData # pylint: disable=protected-access - assert isinstance(descriptor._field_data, LmsFieldData) # lint-amnesty, pylint: disable=no-member + assert isinstance(block._field_data, LmsFieldData) # lint-amnesty, pylint: disable=no-member # the LmsFieldData should now wrap OverrideFieldData - assert isinstance(descriptor._field_data._authored_data._source, OverrideFieldData) # lint-amnesty, pylint: disable=no-member, line-too-long + assert isinstance(block._field_data._authored_data._source, OverrideFieldData) # lint-amnesty, pylint: disable=no-member, line-too-long # the OverrideFieldData should point to the date FieldData - assert isinstance(descriptor._field_data._authored_data._source.fallback, DateLookupFieldData) # lint-amnesty, pylint: disable=no-member, line-too-long - assert descriptor._field_data._authored_data._source.fallback._defaults is descriptor._unwrapped_field_data # lint-amnesty, pylint: disable=no-member, line-too-long + assert isinstance(block._field_data._authored_data._source.fallback, DateLookupFieldData) # lint-amnesty, pylint: disable=no-member, line-too-long + assert block._field_data._authored_data._source.fallback._defaults is block._unwrapped_field_data # lint-amnesty, pylint: disable=no-member, line-too-long def test_hash_resource(self): """ @@ -903,17 +903,17 @@ def test_skip_handlers_for_masquerading_staff(self): @patch('xmodule.services.grades_signals.SCORE_PUBLISHED.send') def test_anonymous_user_not_be_graded(self, mock_score_signal): course = CourseFactory.create() - descriptor_kwargs = { + block_kwargs = { 'category': 'problem', } request = self.request_factory.get('/') request.user = AnonymousUser() - descriptor = BlockFactory.create(**descriptor_kwargs) + block = BlockFactory.create(**block_kwargs) render.handle_xblock_callback( request, str(course.id), - quote_slashes(str(descriptor.location)), + quote_slashes(str(block.location)), 'xmodule_handler', 'problem_check', ) @@ -929,12 +929,12 @@ def test_anonymous_user_not_be_graded(self, mock_score_signal): 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 = { + block_kwargs = { 'category': 'sequential', 'parent': course, } - descriptor = BlockFactory.create(**descriptor_kwargs) - usage_id = str(descriptor.location) + block = BlockFactory.create(**block_kwargs) + usage_id = str(block.location) # Send no special parameters, which will be invalid, but we don't care request = self.request_factory.post('/', data='{}', content_type='application/json') @@ -1021,7 +1021,7 @@ def setup_request_and_course(self, num_finds, num_sends): with self.modulestore.bulk_operations(self.course_key): with check_mongo_calls(num_finds, num_sends): self.toy_course = self.store.get_course(self.course_key, depth=2) # pylint: disable=attribute-defined-outside-init - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( # lint-amnesty, pylint: disable=attribute-defined-outside-init + self.field_data_cache = FieldDataCache.cache_for_block_descendents( # lint-amnesty, pylint: disable=attribute-defined-outside-init self.course_key, self.request.user, self.toy_course, depth=2 ) @@ -1113,7 +1113,7 @@ def setUp(self): self.modulestore = self.store._get_modulestore_for_courselike(self.course_key) # pylint: disable=protected-access with self.modulestore.bulk_operations(self.course_key): self.toy_course = self.store.get_course(self.course_key, depth=2) - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.field_data_cache = FieldDataCache.cache_for_block_descendents( self.course_key, self.request.user, self.toy_course, depth=2 ) @@ -1348,7 +1348,7 @@ def _setup_test_data(self, enrollment_mode, is_practice_exam, attempt_status): self.toy_course = self.update_course(self.toy_course, self.user.id) # refresh cache after update - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.field_data_cache = FieldDataCache.cache_for_block_descendents( self.course_key, self.request.user, self.toy_course, depth=2 ) @@ -1440,7 +1440,7 @@ def setUp(self): self.request = RequestFactoryNoCsrf().get(f'/courses/{self.course.id}/{self.chapter.display_name}') self.request.user = UserFactory() - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, self.request.user, self.course, depth=2 ) gating_api.add_prerequisite(self.course.id, self.open_seq.location) @@ -1504,15 +1504,15 @@ def setUp(self): self.rewrite_link = 'Test rewrite' self.rewrite_bad_link = '' self.course_link = 'Test course rewrite' - self.descriptor = BlockFactory.create( + self.block = BlockFactory.create( category='html', data=self.content_string + self.rewrite_link + self.rewrite_bad_link + self.course_link ) - self.location = self.descriptor.location - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.location = self.block.location + self.field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, self.user, - self.descriptor + self.block ) def test_xblock_display_wrapper_enabled(self): @@ -1649,12 +1649,12 @@ def test_json_init_data(self, json_data, json_output): mock_request = MagicMock() mock_request.user = mock_user course = CourseFactory() - descriptor = BlockFactory(category='withjson', parent=course) - field_data_cache = FieldDataCache([course, descriptor], course.id, mock_user) + block = BlockFactory(category='withjson', parent=course) + field_data_cache = FieldDataCache([course, block], course.id, mock_user) block = render.get_block_for_descriptor( mock_user, mock_request, - descriptor, + block, field_data_cache, course.id, course=course @@ -1704,17 +1704,17 @@ def setUp(self): options=['Correct', 'Incorrect'], correct_option='Correct' ) - self.descriptor = BlockFactory.create( + self.block = BlockFactory.create( category='problem', data=problem_xml, display_name='Option Response Problem' ) - self.location = self.descriptor.location - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.location = self.block.location + self.field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, self.user, - self.descriptor + self.block ) @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_DEBUG_INFO_TO_STAFF': False}) @@ -1757,14 +1757,14 @@ def test_staff_debug_info_score_for_invalid_dropdown(self): """ - problem_descriptor = BlockFactory.create( + problem_block = BlockFactory.create( category='problem', data=problem_xml ) block = render.get_block( self.user, self.request, - problem_descriptor.location, + problem_block.location, self.field_data_cache ) html_fragment = block.render(STUDENT_VIEW) @@ -1774,26 +1774,26 @@ def test_staff_debug_info_score_for_invalid_dropdown(self): """) - assert expected_score_override_html.format(block_id=problem_descriptor.location.block_id) in\ + assert expected_score_override_html.format(block_id=problem_block.location.block_id) in\ html_fragment.content @XBlock.register_temp_plugin(DetachedXBlock, identifier='detached-block') def test_staff_debug_info_disabled_for_detached_blocks(self): """Staff markup should not be present on detached blocks.""" - descriptor = BlockFactory.create( + detached_block = BlockFactory.create( category='detached-block', display_name='Detached Block' ) - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, self.user, - descriptor + detached_block ) block = render.get_block( self.user, self.request, - descriptor.location, + detached_block.location, field_data_cache, ) result_fragment = block.render(STUDENT_VIEW) @@ -1813,21 +1813,21 @@ def test_histogram_disabled(self): def test_histogram_enabled_for_unscored_xblocks(self): """Histograms should not display for xblocks which are not scored.""" - html_descriptor = BlockFactory.create( + html_block = BlockFactory.create( category='html', data='Here are some course details.' ) - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, self.user, - self.descriptor + self.block ) with patch('openedx.core.lib.xblock_utils.grade_histogram') as mock_grade_histogram: mock_grade_histogram.return_value = [] block = render.get_block( self.user, self.request, - html_descriptor.location, + html_block.location, field_data_cache, ) block.render(STUDENT_VIEW) @@ -1888,7 +1888,7 @@ def setUp(self): @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( + block = Mock( spec=xblock_class, _field_data=Mock(spec=FieldData, name='field_data'), location=location, @@ -1901,36 +1901,36 @@ def _get_anonymous_id(self, course_id, xblock_class): # lint-amnesty, pylint: d name='runtime', ), scope_ids=Mock(spec=ScopeIds), - name='descriptor', + name='block', _field_data_cache={}, _dirty_fields={}, fields={}, days_early_for_beta=None, ) - descriptor.runtime = DescriptorSystem(None, None, None) + block.runtime = DescriptorSystem(None, None, None) # Use the xblock_class's bind_for_student method - descriptor.bind_for_student = partial(xblock_class.bind_for_student, descriptor) + block.bind_for_student = partial(xblock_class.bind_for_student, block) if hasattr(xblock_class, 'module_class'): - descriptor.module_class = xblock_class.module_class + block.module_class = xblock_class.module_class - block = render.get_block_for_descriptor_internal( + rendered_block = render.get_block_for_descriptor_internal( user=self.user, - descriptor=descriptor, + block=block, student_data=Mock(spec=FieldData, name='student_data'), course_id=course_id, track_function=Mock(name='track_function'), # Track Function request_token='request_token', course=self.course, ) - current_user = block.runtime.service(block, 'user').get_current_user() + current_user = rendered_block.runtime.service(rendered_block, 'user').get_current_user() return current_user.opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID) @ddt.data(*PER_STUDENT_ANONYMIZED_XBLOCKS) - def test_per_student_anonymized_id(self, descriptor_class): + def test_per_student_anonymized_id(self, block_class): for course_id in ('MITx/6.00x/2012_Fall', 'MITx/6.00x/2013_Spring'): assert 'de619ab51c7f4e9c7216b4644c24f3b5' == \ - self._get_anonymous_id(CourseKey.from_string(course_id), descriptor_class) + self._get_anonymous_id(CourseKey.from_string(course_id), block_class) @ddt.data(*PER_COURSE_ANONYMIZED_XBLOCKS) def test_per_course_anonymized_id(self, xblock_class): @@ -2014,14 +2014,14 @@ def handle_callback_and_get_context_info(self, metadata from the emitted problem_check event. """ - descriptor_kwargs = { + block_kwargs = { 'category': 'problem', 'data': self.problem_xml } if problem_display_name: - descriptor_kwargs['display_name'] = problem_display_name + block_kwargs['display_name'] = problem_display_name - descriptor = BlockFactory.create(**descriptor_kwargs) + block = BlockFactory.create(**block_kwargs) mock_tracker_for_context = MagicMock() with patch('lms.djangoapps.courseware.block_render.tracker', mock_tracker_for_context), patch( 'xmodule.services.tracker', mock_tracker_for_context @@ -2029,7 +2029,7 @@ def handle_callback_and_get_context_info(self, render.handle_xblock_callback( self.request, str(self.course.id), - quote_slashes(str(descriptor.location)), + quote_slashes(str(block.location)), 'xmodule_handler', 'problem_check', ) @@ -2096,7 +2096,7 @@ 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( + field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, user, self.course, depth=2) return render.get_block( @@ -2167,7 +2167,7 @@ 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( + field_data_cache = FieldDataCache.cache_for_block_descendents( self.course.id, user, self.course, depth=2) if item is None: @@ -2248,9 +2248,9 @@ def test_event_publishing(self, mock_track_function): request = self.request_factory.get('') request.user = self.mock_user course = CourseFactory() - descriptor = BlockFactory(category='xblock', parent=course) - field_data_cache = FieldDataCache([course, descriptor], course.id, self.mock_user) - block = render.get_block(self.mock_user, request, descriptor.location, field_data_cache) + block = BlockFactory(category='xblock', parent=course) + field_data_cache = FieldDataCache([course, block], course.id, self.mock_user) + block = render.get_block(self.mock_user, request, block.location, field_data_cache) event_type = 'event_type' event = {'event': 'data'} @@ -2273,7 +2273,7 @@ def _prepare_runtime(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, @@ -2291,7 +2291,7 @@ def setUp(self): self.student_data = Mock() self.track_function = Mock() self.request_token = Mock() - self.descriptor = BlockFactory(category="pure", parent=self.course) + self.block = BlockFactory(category="pure", parent=self.course) self._prepare_runtime() @@ -2334,19 +2334,19 @@ def test_expected_services_exist(self, expected_service): """ Tests that the 'user', 'i18n', and 'fs' services are provided by the LMS runtime. """ - service = self.descriptor.runtime.service(self.descriptor, expected_service) + service = self.block.runtime.service(self.block, expected_service) assert service is not None def test_beta_tester_fields_added(self): """ Tests that the beta tester fields are set on LMS runtime. """ - self.descriptor.days_early_for_beta = 5 + self.block.days_early_for_beta = 5 self._prepare_runtime() # pylint: disable=no-member - assert not self.descriptor.runtime.user_is_beta_tester - assert self.descriptor.runtime.days_early_for_beta == 5 + assert not self.block.runtime.user_is_beta_tester + assert self.block.runtime.days_early_for_beta == 5 def test_get_set_tag(self): """ @@ -2356,23 +2356,23 @@ def test_get_set_tag(self): key = 'key1' # test for when we haven't set the tag yet - tag = self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key) + tag = self.block.runtime.service(self.block, 'user_tags').get_tag(scope, key) assert tag is None # set the tag set_value = 'value' - self.descriptor.runtime.service(self.descriptor, 'user_tags').set_tag(scope, key, set_value) - tag = self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag(scope, key) + self.block.runtime.service(self.block, 'user_tags').set_tag(scope, key, set_value) + tag = self.block.runtime.service(self.block, 'user_tags').get_tag(scope, key) assert tag == set_value # Try to set tag in wrong scope with pytest.raises(ValueError): - self.descriptor.runtime.service(self.descriptor, 'user_tags').set_tag('fake_scope', key, set_value) + self.block.runtime.service(self.block, 'user_tags').set_tag('fake_scope', key, set_value) # Try to get tag in wrong scope with pytest.raises(ValueError): - self.descriptor.runtime.service(self.descriptor, 'user_tags').get_tag('fake_scope', key) + self.block.runtime.service(self.block, 'user_tags').get_tag('fake_scope', key) @ddt.ddt @@ -2382,23 +2382,23 @@ class TestBadgingService(LMSXBlockServiceMixin): @patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True}) def test_service_rendered(self): self._prepare_runtime() - assert self.descriptor.runtime.service(self.descriptor, 'badging') + assert self.block.runtime.service(self.block, 'badging') def test_no_service_rendered(self): with pytest.raises(NoSuchServiceError): - self.descriptor.runtime.service(self.descriptor, 'badging') + self.block.runtime.service(self.block, 'badging') @ddt.data(True, False) @patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True}) def test_course_badges_toggle(self, toggle): self.course = CourseFactory.create(metadata={'issue_badges': toggle}) self._prepare_runtime() - assert self.descriptor.runtime.service(self.descriptor, 'badging').course_badges_enabled is toggle + assert self.block.runtime.service(self.block, 'badging').course_badges_enabled is toggle @patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True}) def test_get_badge_class(self): self._prepare_runtime() - badge_service = self.descriptor.runtime.service(self.descriptor, 'badging') + badge_service = self.block.runtime.service(self.block, 'badging') premade_badge_class = BadgeClassFactory.create() # Ignore additional parameters. This class already exists. # We should get back the first class we created, rather than a new one. @@ -2422,7 +2422,7 @@ def test_module_i18n_lms_service(self): """ Test: module i18n service in LMS """ - i18n_service = self.descriptor.runtime.service(self.descriptor, 'i18n') + i18n_service = self.block.runtime.service(self.block, 'i18n') assert i18n_service is not None assert isinstance(i18n_service, XBlockI18nService) @@ -2430,32 +2430,32 @@ def test_no_service_exception_with_none_declaration_(self): """ Test: NoSuchServiceError should be raised block declaration returns none """ - self.descriptor.service_declaration = Mock(return_value=None) + self.block.service_declaration = Mock(return_value=None) with pytest.raises(NoSuchServiceError): - self.descriptor.runtime.service(self.descriptor, 'i18n') + self.block.runtime.service(self.block, 'i18n') def test_no_service_exception_(self): """ Test: NoSuchServiceError should be raised if i18n service is none. """ - i18nService = self.descriptor.runtime._services['i18n'] # pylint: disable=protected-access - self.descriptor.runtime._runtime_services['i18n'] = None # pylint: disable=protected-access - self.descriptor.runtime._services['i18n'] = None # pylint: disable=protected-access + i18nService = self.block.runtime._services['i18n'] # pylint: disable=protected-access + self.block.runtime._runtime_services['i18n'] = None # pylint: disable=protected-access + self.block.runtime._services['i18n'] = None # pylint: disable=protected-access with pytest.raises(NoSuchServiceError): - self.descriptor.runtime.service(self.descriptor, 'i18n') - self.descriptor.runtime._services['i18n'] = i18nService # pylint: disable=protected-access + self.block.runtime.service(self.block, 'i18n') + self.block.runtime._services['i18n'] = i18nService # pylint: disable=protected-access def test_i18n_service_callable(self): """ Test: _services dict should contain the callable i18n service in LMS. """ - assert callable(self.descriptor.runtime._services.get('i18n')) # pylint: disable=protected-access + assert callable(self.block.runtime._services.get('i18n')) # pylint: disable=protected-access def test_i18n_service_not_callable(self): """ Test: i18n service should not be callable in LMS after initialization. """ - assert not callable(self.descriptor.runtime.service(self.descriptor, 'i18n')) + assert not callable(self.block.runtime.service(self.block, 'i18n')) class PureXBlockWithChildren(PureXBlock): @@ -2490,15 +2490,6 @@ def test_unbound(self): block = self._load_block() self.assertUnboundChildren(block) - @ddt.data(*USER_NUMBERS) - @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') - def test_unbound_then_bound_as_descriptor(self, user_number): - user = self.users[user_number] - block = self._load_block() - self.assertUnboundChildren(block) - self._bind_block(block, user) - self.assertBoundChildren(block, user) - @ddt.data(*USER_NUMBERS) @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') def test_unbound_then_bound_as_xblock(self, user_number): @@ -2508,14 +2499,6 @@ def test_unbound_then_bound_as_xblock(self, user_number): self._bind_block(block, user) self.assertBoundChildren(block, user) - @ddt.data(*USER_NUMBERS) - @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') - def test_bound_only_as_descriptor(self, user_number): - user = self.users[user_number] - block = self._load_block() - self._bind_block(block, user) - self.assertBoundChildren(block, user) - @ddt.data(*USER_NUMBERS) @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') def test_bound_only_as_xblock(self, user_number): @@ -2545,7 +2528,7 @@ def _bind_block(self, block, user): Bind `block` to the supplied `user`. """ course_id = self.course.id - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( course_id, user, block, @@ -2606,25 +2589,25 @@ def setUp(self): def test_get_item(self): course = CourseFactory() - self._verify_descriptor('video', course, 'HiddenBlockWithMixins') + self._verify_block('video', course, 'HiddenBlockWithMixins') def test_dynamic_updates(self): """Tests that the list of disabled xblocks can dynamically update.""" course = CourseFactory() - item_usage_id = self._verify_descriptor('problem', course, 'ProblemBlockWithMixins') + item_usage_id = self._verify_block('problem', course, 'ProblemBlockWithMixins') XBlockConfiguration(name='problem', enabled=False).save() # First verify that the cached value is used until there is a new request cache. - self._verify_descriptor('problem', course, 'ProblemBlockWithMixins', item_usage_id) + self._verify_block('problem', course, 'ProblemBlockWithMixins', item_usage_id) # Now simulate a new request cache. self.store.request_cache.data.clear() - self._verify_descriptor('problem', course, 'HiddenBlockWithMixins', item_usage_id) + self._verify_block('problem', course, 'HiddenBlockWithMixins', item_usage_id) - def _verify_descriptor(self, category, course, descriptor, item_id=None): + def _verify_block(self, category, course, block, item_id=None): """ Helper method that gets an item with the specified category from the - modulestore and verifies that it has the expected descriptor name. + modulestore and verifies that it has the expected block name. Returns the item's usage_id. """ @@ -2633,7 +2616,7 @@ def _verify_descriptor(self, category, course, descriptor, item_id=None): item_id = item.scope_ids.usage_id # lint-amnesty, pylint: disable=no-member item = self.store.get_item(item_id) - assert item.__class__.__name__ == descriptor + assert item.__class__.__name__ == block return item_id @@ -2650,15 +2633,15 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): @classmethod def setUpClass(cls): """ - Set up the course and descriptor used to instantiate the runtime. + Set up the course and block used to instantiate the runtime. """ super().setUpClass() org = 'edX' number = 'LmsModuleShimTest' run = '2021_Fall' cls.course = CourseFactory.create(org=org, number=number, run=run) - cls.descriptor = BlockFactory(category="vertical", parent=cls.course) - cls.problem_descriptor = BlockFactory(category="problem", parent=cls.course) + cls.block = BlockFactory(category="vertical", parent=cls.course) + cls.problem_block = BlockFactory(category="problem", parent=cls.course) def setUp(self): """ @@ -2673,7 +2656,7 @@ def setUp(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, @@ -2690,37 +2673,37 @@ def test_user_service_attributes(self, attribute, expected_value): """ Tests that the deprecated attributes provided by the user service match expected values. """ - assert getattr(self.descriptor.runtime, attribute) == expected_value + assert getattr(self.block.runtime, attribute) == expected_value @patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True)) def test_user_is_staff(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) - assert self.descriptor.runtime.user_is_staff - assert self.descriptor.runtime.get_user_role() == 'student' + assert self.block.runtime.user_is_staff + assert self.block.runtime.get_user_role() == 'student' @patch('lms.djangoapps.courseware.block_render.get_user_role', Mock(return_value='instructor', autospec=True)) def test_get_user_role(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) - assert self.descriptor.runtime.get_user_role() == 'instructor' + assert self.block.runtime.get_user_role() == 'instructor' def test_anonymous_student_id(self): - assert self.descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id) + assert self.block.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id) def test_anonymous_student_id_bug(self): """ @@ -2730,76 +2713,76 @@ def test_anonymous_student_id_bug(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.problem_descriptor, + self.problem_block, self.course.id, self.track_function, self.request_token, course=self.course, ) # Ensure the problem block returns a per-user anonymous id - assert self.problem_descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None) + assert self.problem_block.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None) _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) # Ensure the vertical block returns a per-course+user anonymous id - assert self.descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id) + assert self.block.runtime.anonymous_student_id == anonymous_id_for_user(self.user, self.course.id) # Ensure the problem runtime's anonymous student ID is unchanged after the above call. - assert self.problem_descriptor.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None) + assert self.problem_block.runtime.anonymous_student_id == anonymous_id_for_user(self.user, None) def test_user_service_with_anonymous_user(self): _ = render.prepare_runtime_for_user( AnonymousUser(), self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) - assert self.descriptor.runtime.anonymous_student_id is None - assert self.descriptor.runtime.seed == 0 - assert self.descriptor.runtime.user_id is None - assert not self.descriptor.runtime.user_is_staff - assert not self.descriptor.runtime.get_user_role() + assert self.block.runtime.anonymous_student_id is None + assert self.block.runtime.seed == 0 + assert self.block.runtime.user_id is None + assert not self.block.runtime.user_is_staff + assert not self.block.runtime.get_user_role() def test_get_real_user(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) course_anonymous_student_id = anonymous_id_for_user(self.user, self.course.id) - assert self.descriptor.runtime.get_real_user(course_anonymous_student_id) == self.user # pylint: disable=not-callable + assert self.block.runtime.get_real_user(course_anonymous_student_id) == self.user # pylint: disable=not-callable no_course_anonymous_student_id = anonymous_id_for_user(self.user, None) - assert self.descriptor.runtime.get_real_user(no_course_anonymous_student_id) == self.user # pylint: disable=not-callable + assert self.block.runtime.get_real_user(no_course_anonymous_student_id) == self.user # pylint: disable=not-callable # Tests that the default is to use the user service's anonymous_student_id - assert self.descriptor.runtime.get_real_user() == self.user # pylint: disable=not-callable + assert self.block.runtime.get_real_user() == self.user # pylint: disable=not-callable def test_render_template(self): - rendered = self.descriptor.runtime.render_template('templates/edxmako.html', {'element_id': 'hi'}) # pylint: disable=not-callable + rendered = self.block.runtime.render_template('templates/edxmako.html', {'element_id': 'hi'}) # pylint: disable=not-callable assert rendered == '
Testing the MakoService
\n' def test_xqueue(self): - xqueue = self.descriptor.runtime.xqueue + xqueue = self.block.runtime.xqueue assert isinstance(xqueue['interface'], XQueueInterface) assert xqueue['interface'].url == 'http://sandbox-xqueue.edx.org' assert xqueue['default_queuename'] == 'edX-LmsModuleShimTest' assert xqueue['waittime'] == 5 - callback_url = f'http://localhost:8000/courses/{self.course.id}/xqueue/232/{self.descriptor.location}' + callback_url = f'http://localhost:8000/courses/{self.course.id}/xqueue/232/{self.block.location}' assert xqueue['construct_callback']() == f'{callback_url}/score_update' assert xqueue['construct_callback']('mock_dispatch') == f'{callback_url}/mock_dispatch' @@ -2819,31 +2802,31 @@ def test_xqueue_settings(self): _ = render.prepare_runtime_for_user( self.user, self.student_data, - self.descriptor, + self.block, self.course.id, self.track_function, self.request_token, course=self.course, ) - xqueue = self.descriptor.runtime.xqueue + xqueue = self.block.runtime.xqueue assert isinstance(xqueue['interface'], XQueueInterface) assert xqueue['interface'].url == 'http://xqueue.url' assert xqueue['default_queuename'] == 'edX-LmsModuleShimTest' assert xqueue['waittime'] == 15 - callback_url = f'http://alt.url/courses/{self.course.id}/xqueue/232/{self.descriptor.location}' + callback_url = f'http://alt.url/courses/{self.course.id}/xqueue/232/{self.block.location}' assert xqueue['construct_callback']() == f'{callback_url}/score_update' assert xqueue['construct_callback']('mock_dispatch') == f'{callback_url}/mock_dispatch' @override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+LmsModuleShimTest\+2021_Fall']) def test_can_execute_unsafe_code_when_allowed(self): - assert self.descriptor.runtime.can_execute_unsafe_code() + assert self.block.runtime.can_execute_unsafe_code() @override_settings(COURSES_WITH_UNSAFE_CODE=[r'course-v1:edX\+full\+2021_Fall']) def test_cannot_execute_unsafe_code_when_disallowed(self): - assert not self.descriptor.runtime.can_execute_unsafe_code() + assert not self.block.runtime.can_execute_unsafe_code() def test_cannot_execute_unsafe_code(self): - assert not self.descriptor.runtime.can_execute_unsafe_code() + assert not self.block.runtime.can_execute_unsafe_code() @override_settings(PYTHON_LIB_FILENAME=PYTHON_LIB_FILENAME) def test_get_python_lib_zip(self): @@ -2853,7 +2836,7 @@ def test_get_python_lib_zip(self): source_file=self.PYTHON_LIB_SOURCE_FILE, target_filename=self.PYTHON_LIB_FILENAME, ) - assert self.descriptor.runtime.get_python_lib_zip() == zipfile + assert self.block.runtime.get_python_lib_zip() == zipfile def test_no_get_python_lib_zip(self): zipfile = upload_file_to_course( @@ -2862,32 +2845,32 @@ def test_no_get_python_lib_zip(self): source_file=self.PYTHON_LIB_SOURCE_FILE, target_filename=self.PYTHON_LIB_FILENAME, ) - assert self.descriptor.runtime.get_python_lib_zip() is None + assert self.block.runtime.get_python_lib_zip() is None def test_cache(self): - assert hasattr(self.descriptor.runtime.cache, 'get') - assert hasattr(self.descriptor.runtime.cache, 'set') + assert hasattr(self.block.runtime.cache, 'get') + assert hasattr(self.block.runtime.cache, 'set') def test_replace_urls(self): html = '' - assert self.descriptor.runtime.replace_urls(html) == \ + assert self.block.runtime.replace_urls(html) == \ static_replace.replace_static_urls(html, course_id=self.course.id) def test_replace_course_urls(self): html = '' - assert self.descriptor.runtime.replace_course_urls(html) == \ + assert self.block.runtime.replace_course_urls(html) == \ static_replace.replace_course_urls(html, course_key=self.course.id) def test_replace_jump_to_id_urls(self): html = '' jump_to_id_base_url = reverse('jump_to_id', kwargs={'course_id': str(self.course.id), 'module_id': ''}) - assert self.descriptor.runtime.replace_jump_to_id_urls(html) == \ + assert self.block.runtime.replace_jump_to_id_urls(html) == \ static_replace.replace_jump_to_id_urls(html, self.course.id, jump_to_id_base_url) @XBlock.register_temp_plugin(PureXBlock, 'pure') @XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock') def test_course_id(self): - descriptor = BlockFactory(category="pure", parent=self.course) + block = BlockFactory(category="pure", parent=self.course) - block = render.get_block(self.user, Mock(), descriptor.location, None) - assert str(block.runtime.course_id) == self.COURSE_ID + rendered_block = render.get_block(self.user, Mock(), block.location, None) + assert str(rendered_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 d4d6c97fbe1d..166a8ccbdbe1 100644 --- a/lms/djangoapps/courseware/tests/test_courses.py +++ b/lms/djangoapps/courseware/tests/test_courses.py @@ -382,7 +382,7 @@ def test_repeated_course_block_instantiation(self, loops, course_depth): course = modulestore().get_course(course.id, depth=course_depth) for _ in range(loops): - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( course.id, self.user, course, depth=course_depth ) course_block = get_block_for_descriptor( diff --git a/lms/djangoapps/courseware/tests/test_discussion_xblock.py b/lms/djangoapps/courseware/tests/test_discussion_xblock.py index 159add3e050d..ea265daab764 100644 --- a/lms/djangoapps/courseware/tests/test_discussion_xblock.py +++ b/lms/djangoapps/courseware/tests/test_discussion_xblock.py @@ -295,7 +295,7 @@ def test_html_with_user(self): """ discussion_xblock = get_block_for_descriptor_internal( user=self.user, - descriptor=self.discussion, + block=self.discussion, student_data=mock.Mock(name='student_data'), course_id=self.course.id, track_function=mock.Mock(name='track_function'), @@ -335,10 +335,10 @@ def test_discussion_render_successfully_with_orphan_parent(self): assert orphan_sequential.location.block_type == root.location.block_type assert orphan_sequential.location.block_id == root.location.block_id - # Get xblock bound to a user and a descriptor. + # Get xblock bound to a user and a block. discussion_xblock = get_block_for_descriptor_internal( user=self.user, - descriptor=discussion, + block=discussion, student_data=mock.Mock(name='student_data'), course_id=self.course.id, track_function=mock.Mock(name='track_function'), @@ -388,7 +388,7 @@ def test_discussion_xblock_visibility(self): discussion_xblock = get_block_for_descriptor_internal( user=self.user, - descriptor=self.discussion, + block=self.discussion, student_data=mock.Mock(name='student_data'), course_id=self.course.id, track_function=mock.Mock(name='track_function'), @@ -438,7 +438,7 @@ def test_permissions_query_load(self): for discussion in discussions: discussion_xblock = get_block_for_descriptor_internal( user=user, - descriptor=discussion, + block=discussion, student_data=mock.Mock(name='student_data'), course_id=course.id, track_function=mock.Mock(name='track_function'), diff --git a/lms/djangoapps/courseware/tests/test_entrance_exam.py b/lms/djangoapps/courseware/tests/test_entrance_exam.py index 7024ea5c3c3b..240a9494fc8f 100644 --- a/lms/djangoapps/courseware/tests/test_entrance_exam.py +++ b/lms/djangoapps/courseware/tests/test_entrance_exam.py @@ -340,7 +340,7 @@ def _return_table_of_contents(self): Returns the table of contents for course self.course, for chapter self.entrance_exam, and for section self.exam1 """ - self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( # pylint: disable=attribute-defined-outside-init + self.field_data_cache = FieldDataCache.cache_for_block_descendents( # pylint: disable=attribute-defined-outside-init self.course.id, self.request.user, self.entrance_exam @@ -372,7 +372,7 @@ def answer_entrance_exam_problem(course, request, problem, user=None, value=1, m user = request.user grade_dict = {'value': value, 'max_value': max_value, 'user_id': user.id} - field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + field_data_cache = FieldDataCache.cache_for_block_descendents( course.id, user, course, diff --git a/lms/djangoapps/courseware/tests/test_lti_integration.py b/lms/djangoapps/courseware/tests/test_lti_integration.py index e7d7f856ba06..036cc8da2d7e 100644 --- a/lms/djangoapps/courseware/tests/test_lti_integration.py +++ b/lms/djangoapps/courseware/tests/test_lti_integration.py @@ -40,11 +40,11 @@ def setUp(self): mocked_decoded_signature = 'my_signature=' # Note: this course_id is actually a course_key - context_id = str(self.item_descriptor.course_id) - user_service = self.item_descriptor.runtime.service(self.item_descriptor, 'user') + context_id = str(self.block.course_id) + user_service = self.block.runtime.service(self.block, 'user') user_id = str(user_service.get_current_user().opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID)) hostname = settings.LMS_BASE - resource_link_id = str(urllib.parse.quote(f'{hostname}-{self.item_descriptor.location.html_id()}')) + resource_link_id = str(urllib.parse.quote(f'{hostname}-{self.block.location.html_id()}')) sourcedId = "{context}:{resource_link}:{user_id}".format( context=urllib.parse.quote(context_id), @@ -75,14 +75,14 @@ def setUp(self): saved_sign = oauthlib.oauth1.Client.sign self.expected_context = { - 'display_name': self.item_descriptor.display_name, + 'display_name': self.block.display_name, 'input_fields': self.correct_headers, - 'element_class': self.item_descriptor.category, - 'element_id': self.item_descriptor.location.html_id(), + 'element_class': self.block.category, + 'element_id': self.block.location.html_id(), 'launch_url': 'http://www.example.com', # default value 'open_in_a_new_page': True, - 'form_url': self.item_descriptor.runtime.handler_url( - self.item_descriptor, + 'form_url': self.block.runtime.handler_url( + self.block, 'preview_handler' ).rstrip('/?'), 'hide_launch': False, @@ -90,11 +90,11 @@ def setUp(self): 'module_score': None, 'comment': '', 'weight': 1.0, - 'ask_to_send_username': self.item_descriptor.ask_to_send_username, - 'ask_to_send_email': self.item_descriptor.ask_to_send_email, - 'description': self.item_descriptor.description, - 'button_text': self.item_descriptor.button_text, - 'accept_grades_past_due': self.item_descriptor.accept_grades_past_due, + 'ask_to_send_username': self.block.ask_to_send_username, + 'ask_to_send_email': self.block.ask_to_send_email, + 'description': self.block.description, + 'button_text': self.block.button_text, + 'accept_grades_past_due': self.block.accept_grades_past_due, } def mocked_sign(self, *args, **kwargs): @@ -117,12 +117,12 @@ def mocked_sign(self, *args, **kwargs): self.addCleanup(patcher.stop) def test_lti_constructor(self): - generated_content = self.item_descriptor.render(STUDENT_VIEW).content + generated_content = self.block.render(STUDENT_VIEW).content expected_content = self.runtime.render_template('lti.html', self.expected_context) assert generated_content == expected_content def test_lti_preview_handler(self): - generated_content = self.item_descriptor.preview_handler(None, None).body + generated_content = self.block.preview_handler(None, None).body expected_content = self.runtime.render_template('lti_form.html', self.expected_context) assert generated_content.decode('utf-8') == expected_content diff --git a/lms/djangoapps/courseware/tests/test_model_data.py b/lms/djangoapps/courseware/tests/test_model_data.py index 36c0a878723a..6c763d57b338 100644 --- a/lms/djangoapps/courseware/tests/test_model_data.py +++ b/lms/djangoapps/courseware/tests/test_model_data.py @@ -35,13 +35,13 @@ def mock_field(scope, name): return field -def mock_descriptor(fields=[]): # lint-amnesty, pylint: disable=dangerous-default-value, missing-function-docstring - descriptor = Mock(entry_point=XBlock.entry_point) - descriptor.scope_ids = ScopeIds('user1', 'mock_problem', LOCATION('def_id'), LOCATION('usage_id')) - descriptor.module_class.fields.values.return_value = fields - descriptor.fields.values.return_value = fields - descriptor.module_class.__name__ = 'MockProblemModule' - return descriptor +def mock_block(fields=[]): # lint-amnesty, pylint: disable=dangerous-default-value, missing-function-docstring + block = Mock(entry_point=XBlock.entry_point) + block.scope_ids = ScopeIds('user1', 'mock_problem', LOCATION('def_id'), LOCATION('usage_id')) + block.module_class.fields.values.return_value = fields + block.fields.values.return_value = fields + block.module_class.__name__ = 'MockProblemModule' + return block # The user ids here are 1 because we make a student in the setUp functions, and # they get an id of 1. There's an assertion in setUp to ensure that assumption @@ -63,7 +63,7 @@ def setUp(self): super().setUp() self.user = UserFactory.create(username='user') self.field_data_cache = FieldDataCache( - [mock_descriptor([mock_field(Scope.user_state, 'a_field')])], + [mock_block([mock_field(Scope.user_state, 'a_field')])], COURSE_KEY, self.user, ) @@ -120,10 +120,10 @@ def setUp(self): assert self.user.id == 1 # check our assumption hard-coded in the key functions above. - # There should be only one query to load a single descriptor with a single user_state field + # There should be only one query to load a single block with a single user_state field with self.assertNumQueries(1): self.field_data_cache = FieldDataCache( - [mock_descriptor([mock_field(Scope.user_state, 'a_field')])], + [mock_block([mock_field(Scope.user_state, 'a_field')])], COURSE_KEY, self.user, ) @@ -250,10 +250,10 @@ def setUp(self): assert self.user.id == 1 # check our assumption hard-coded in the key functions above. - # The descriptor has no fields, so FDC shouldn't send any queries + # The block has no fields, so FDC shouldn't send any queries with self.assertNumQueries(0): self.field_data_cache = FieldDataCache( - [mock_descriptor()], + [mock_block()], COURSE_KEY, self.user, ) @@ -318,14 +318,14 @@ def setUp(self): self.user = field_storage.student else: self.user = UserFactory.create() - self.mock_descriptor = mock_descriptor([ + self.mock_block = mock_block([ mock_field(self.scope, 'existing_field'), mock_field(self.scope, 'other_existing_field')]) # Each field is stored as a separate row in the table, # but we can query them in a single query with self.assertNumQueries(1): self.field_data_cache = FieldDataCache( - [self.mock_descriptor], + [self.mock_block], COURSE_KEY, self.user, ) diff --git a/lms/djangoapps/courseware/tests/test_video_handlers.py b/lms/djangoapps/courseware/tests/test_video_handlers.py index 737c6c25b9af..9ae07c42efac 100644 --- a/lms/djangoapps/courseware/tests/test_video_handlers.py +++ b/lms/djangoapps/courseware/tests/test_video_handlers.py @@ -172,12 +172,12 @@ def test_handle_ajax_wrong_dispatch(self): assert status_codes.pop() == 404 def test_handle_ajax_for_speed_with_nan(self): - self.item_descriptor.handle_ajax('save_user_state', {'speed': json.dumps(1.0)}) - assert self.item_descriptor.speed == 1.0 - assert self.item_descriptor.global_speed == 1.0 + self.block.handle_ajax('save_user_state', {'speed': json.dumps(1.0)}) + assert self.block.speed == 1.0 + assert self.block.global_speed == 1.0 # try to set NaN value for speed. - response = self.item_descriptor.handle_ajax( + response = self.block.handle_ajax( 'save_user_state', {'speed': json.dumps(float('NaN'))} ) @@ -186,8 +186,8 @@ def test_handle_ajax_for_speed_with_nan(self): assert json.loads(response)['error'] == expected_error # verify that the speed and global speed are still 1.0 - assert self.item_descriptor.speed == 1.0 - assert self.item_descriptor.global_speed == 1.0 + assert self.block.speed == 1.0 + assert self.block.global_speed == 1.0 def test_handle_ajax(self): @@ -206,41 +206,41 @@ def test_handle_ajax(self): HTTP_X_REQUESTED_WITH='XMLHttpRequest') assert response.status_code == 200 - assert self.item_descriptor.speed is None - self.item_descriptor.handle_ajax('save_user_state', {'speed': json.dumps(2.0)}) - assert self.item_descriptor.speed == 2.0 - assert self.item_descriptor.global_speed == 2.0 + assert self.block.speed is None + self.block.handle_ajax('save_user_state', {'speed': json.dumps(2.0)}) + assert self.block.speed == 2.0 + assert self.block.global_speed == 2.0 - assert self.item_descriptor.saved_video_position == timedelta(0) - self.item_descriptor.handle_ajax('save_user_state', {'saved_video_position': "00:00:10"}) - assert self.item_descriptor.saved_video_position == timedelta(0, 10) + assert self.block.saved_video_position == timedelta(0) + self.block.handle_ajax('save_user_state', {'saved_video_position': "00:00:10"}) + assert self.block.saved_video_position == timedelta(0, 10) - assert self.item_descriptor.transcript_language == 'en' - self.item_descriptor.handle_ajax('save_user_state', {'transcript_language': "uk"}) - assert self.item_descriptor.transcript_language == 'uk' + assert self.block.transcript_language == 'en' + self.block.handle_ajax('save_user_state', {'transcript_language': "uk"}) + assert self.block.transcript_language == 'uk' - assert self.item_descriptor.bumper_do_not_show_again is False - self.item_descriptor.handle_ajax('save_user_state', {'bumper_do_not_show_again': True}) - assert self.item_descriptor.bumper_do_not_show_again is True + assert self.block.bumper_do_not_show_again is False + self.block.handle_ajax('save_user_state', {'bumper_do_not_show_again': True}) + assert self.block.bumper_do_not_show_again is True with freezegun.freeze_time(now()): - assert self.item_descriptor.bumper_last_view_date is None - self.item_descriptor.handle_ajax('save_user_state', {'bumper_last_view_date': True}) - assert self.item_descriptor.bumper_last_view_date == now() + assert self.block.bumper_last_view_date is None + self.block.handle_ajax('save_user_state', {'bumper_last_view_date': True}) + assert self.block.bumper_last_view_date == now() - response = self.item_descriptor.handle_ajax('save_user_state', {'demoo�': "sample"}) + response = self.block.handle_ajax('save_user_state', {'demoo�': "sample"}) assert json.loads(response)['success'] is True def get_handler_url(self, handler, suffix): """ - Return the URL for the specified handler on self.item_descriptor. + Return the URL for the specified handler on self.block. """ - return self.item_descriptor.runtime.handler_url( - self.item_descriptor, handler, suffix + return self.block.runtime.handler_url( + self.block, handler, suffix ).rstrip('/?') def tearDown(self): - _clear_assets(self.item_descriptor.location) + _clear_assets(self.block.location) super().tearDown() @@ -268,24 +268,23 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p def setUp(self): super().setUp() - self.item_descriptor.render(STUDENT_VIEW) - self.item = self.item_descriptor + self.block.render(STUDENT_VIEW) self.subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]} def test_available_translation_en(self): good_sjson = _create_file(json.dumps(self.subs)) - _upload_sjson_file(good_sjson, self.item_descriptor.location) - self.item.sub = _get_subs_id(good_sjson.name) + _upload_sjson_file(good_sjson, self.block.location) + self.block.sub = _get_subs_id(good_sjson.name) request = Request.blank('/available_translations') - response = self.item.transcript(request=request, dispatch='available_translations') + response = self.block.transcript(request=request, dispatch='available_translations') assert json.loads(response.body.decode('utf-8')) == ['en'] def test_available_translation_non_en(self): - _upload_file(_create_srt_file(), self.item_descriptor.location, os.path.split(self.srt_file.name)[1]) + _upload_file(_create_srt_file(), self.block.location, os.path.split(self.srt_file.name)[1]) request = Request.blank('/available_translations') - response = self.item.transcript(request=request, dispatch='available_translations') + response = self.block.transcript(request=request, dispatch='available_translations') assert json.loads(response.body.decode('utf-8')) == ['uk'] @patch('xmodule.video_block.transcripts_utils.get_video_transcript_content') @@ -302,16 +301,16 @@ def test_multiple_available_translations(self, mock_get_video_transcript_content good_sjson = _create_file(json.dumps(self.subs)) # Upload english transcript. - _upload_sjson_file(good_sjson, self.item_descriptor.location) + _upload_sjson_file(good_sjson, self.block.location) # Upload non-english transcript. - _upload_file(self.srt_file, self.item_descriptor.location, os.path.split(self.srt_file.name)[1]) + _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1]) - self.item.sub = _get_subs_id(good_sjson.name) - self.item.edx_video_id = 'an-edx-video-id' + self.block.sub = _get_subs_id(good_sjson.name) + self.block.edx_video_id = 'an-edx-video-id' request = Request.blank('/available_translations') - response = self.item.transcript(request=request, dispatch='available_translations') + response = self.block.transcript(request=request, dispatch='available_translations') assert sorted(json.loads(response.body.decode('utf-8'))) == sorted(['en', 'uk']) @patch('xmodule.video_block.transcripts_utils.get_video_transcript_content') @@ -365,13 +364,13 @@ def test_val_available_translations( for lang_code, in_content_store in dict(transcripts).items(): if in_content_store: file_name, __ = os.path.split(self.srt_file.name) - _upload_file(self.srt_file, self.item_descriptor.location, file_name) + _upload_file(self.srt_file, self.block.location, file_name) transcripts[lang_code] = file_name else: transcripts[lang_code] = 'non_existent.srt.sjson' if sub: sjson_transcript = _create_file(json.dumps(self.subs)) - _upload_sjson_file(sjson_transcript, self.item_descriptor.location) + _upload_sjson_file(sjson_transcript, self.block.location) sub = _get_subs_id(sjson_transcript.name) mock_get_video_transcript_content.return_value = { @@ -383,12 +382,12 @@ def test_val_available_translations( 'file_name': 'edx.sjson' } mock_get_transcript_languages.return_value = val_transcripts - self.item.transcripts = transcripts - self.item.sub = sub - self.item.edx_video_id = 'an-edx-video-id' + self.block.transcripts = transcripts + self.block.sub = sub + self.block.edx_video_id = 'an-edx-video-id' # Make request to available translations dispatch. request = Request.blank('/available_translations') - response = self.item.transcript(request=request, dispatch='available_translations') + response = self.block.transcript(request=request, dispatch='available_translations') self.assertCountEqual(json.loads(response.body.decode('utf-8')), result) @patch('xmodule.video_block.transcripts_utils.edxval_api.get_available_transcript_languages') @@ -398,7 +397,7 @@ def test_val_available_translations_feature_disabled(self, mock_get_available_tr """ mock_get_available_transcript_languages.return_value = ['en', 'de', 'ro'] request = Request.blank('/available_translations') - response = self.item.transcript(request=request, dispatch='available_translations') + response = self.block.transcript(request=request, dispatch='available_translations') assert response.status_code == 404 @@ -426,19 +425,18 @@ class TestTranscriptAvailableTranslationsBumperDispatch(TestVideo): # lint-amne def setUp(self): super().setUp() - self.item_descriptor.render(STUDENT_VIEW) - self.item = self.item_descriptor + self.block.render(STUDENT_VIEW) self.dispatch = "available_translations/?is_bumper=1" - self.item.video_bumper = {"transcripts": {"en": ""}} + self.block.video_bumper = {"transcripts": {"en": ""}} @ddt.data("en", "uk") def test_available_translation_en_and_non_en(self, lang): filename = os.path.split(self.srt_file.name)[1] - _upload_file(self.srt_file, self.item_descriptor.location, filename) - self.item.video_bumper["transcripts"][lang] = filename + _upload_file(self.srt_file, self.block.location, filename) + self.block.video_bumper["transcripts"][lang] = filename request = Request.blank('/' + self.dispatch) - response = self.item.transcript(request=request, dispatch=self.dispatch) + response = self.block.transcript(request=request, dispatch=self.dispatch) assert json.loads(response.body.decode('utf-8')) == [lang] @patch('xmodule.video_block.transcripts_utils.get_available_transcript_languages') @@ -453,16 +451,16 @@ def test_multiple_available_translations(self, mock_get_transcript_languages): en_translation_filename = os.path.split(en_translation.name)[1] uk_translation_filename = os.path.split(self.srt_file.name)[1] # Upload english transcript. - _upload_file(en_translation, self.item_descriptor.location, en_translation_filename) + _upload_file(en_translation, self.block.location, en_translation_filename) # Upload non-english transcript. - _upload_file(self.srt_file, self.item_descriptor.location, uk_translation_filename) + _upload_file(self.srt_file, self.block.location, uk_translation_filename) - self.item.video_bumper["transcripts"]["en"] = en_translation_filename - self.item.video_bumper["transcripts"]["uk"] = uk_translation_filename + self.block.video_bumper["transcripts"]["en"] = en_translation_filename + self.block.video_bumper["transcripts"]["uk"] = uk_translation_filename request = Request.blank('/' + self.dispatch) - response = self.item.transcript(request=request, dispatch=self.dispatch) + response = self.block.transcript(request=request, dispatch=self.dispatch) # Assert that bumper only get its own translations. assert sorted(json.loads(response.body.decode('utf-8'))) == sorted(['en', 'uk']) @@ -492,12 +490,11 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl def setUp(self): super().setUp() - self.item_descriptor.render(STUDENT_VIEW) - self.item = self.item_descriptor + self.block.render(STUDENT_VIEW) def test_download_transcript_not_exist(self): request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') assert response.status == '404 Not Found' @patch( @@ -506,7 +503,7 @@ def test_download_transcript_not_exist(self): ) def test_download_srt_exist(self, __): request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') assert response.body.decode('utf-8') == 'Subs!' assert response.headers['Content-Type'] == 'application/x-subrip; charset=utf-8' assert response.headers['Content-Language'] == 'en' @@ -516,19 +513,19 @@ def test_download_srt_exist(self, __): return_value=('Subs!', 'txt', 'text/plain; charset=utf-8') ) def test_download_txt_exist(self, __): - self.item.transcript_format = 'txt' + self.block.transcript_format = 'txt' request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') assert response.body.decode('utf-8') == 'Subs!' assert response.headers['Content-Type'] == 'text/plain; charset=utf-8' assert response.headers['Content-Language'] == 'en' def test_download_en_no_sub(self): request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') assert response.status == '404 Not Found' with pytest.raises(NotFoundError): - get_transcript(self.item) + get_transcript(self.block) @patch( 'xmodule.video_block.transcripts_utils.get_transcript_for_video', @@ -536,7 +533,7 @@ def test_download_en_no_sub(self): ) def test_download_non_en_non_ascii_filename(self, __): request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') assert response.body.decode('utf-8') == 'Subs!' assert response.headers['Content-Type'] == 'application/x-subrip; charset=utf-8' assert response.headers['Content-Disposition'] == 'attachment; filename="en_塞.srt"' @@ -558,7 +555,7 @@ def test_download_fallback_transcript(self, mock_get_video_transcript_data): # Make request to XModule transcript handler request = Request.blank('/download') - response = self.item.transcript(request=request, dispatch='download') + response = self.block.transcript(request=request, dispatch='download') # Expected response expected_content = '0\n00:00:00,010 --> 00:00:00,100\nHi, welcome to Edx.\n\n' @@ -602,9 +599,8 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: def setUp(self): super().setUp() - self.item_descriptor.render(STUDENT_VIEW) - self.item = self.item_descriptor - self.item.video_bumper = {"transcripts": {"en": ""}} + self.block.render(STUDENT_VIEW) + self.block.video_bumper = {"transcripts": {"en": ""}} @ddt.data( # No language @@ -623,7 +619,7 @@ def setUp(self): @ddt.unpack def test_translation_fails(self, url, dispatch, status_code): request = Request.blank(url) - response = self.item.transcript(request=request, dispatch=dispatch) + response = self.block.transcript(request=request, dispatch=dispatch) assert response.status == status_code @ddt.data( @@ -633,12 +629,12 @@ def test_translation_fails(self, url, dispatch, status_code): def test_translaton_en_youtube_success(self, url, dispatch, attach): subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]} good_sjson = _create_file(json.dumps(subs)) - _upload_sjson_file(good_sjson, self.item_descriptor.location) + _upload_sjson_file(good_sjson, self.block.location) subs_id = _get_subs_id(good_sjson.name) - attach(self.item, subs_id) + attach(self.block, subs_id) request = Request.blank(url.format(subs_id)) - response = self.item.transcript(request=request, dispatch=dispatch) + response = self.block.transcript(request=request, dispatch=dispatch) self.assertDictEqual(json.loads(response.body.decode('utf-8')), subs) def test_translation_non_en_youtube_success(self): @@ -650,20 +646,20 @@ def test_translation_non_en_youtube_success(self): ] } self.srt_file.seek(0) - _upload_file(self.srt_file, self.item_descriptor.location, os.path.split(self.srt_file.name)[1]) + _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1]) subs_id = _get_subs_id(self.srt_file.name) # youtube 1_0 request, will generate for all speeds for existing ids - self.item.youtube_id_1_0 = subs_id - self.item.youtube_id_0_75 = '0_75' - self.store.update_item(self.item, self.user.id) + self.block.youtube_id_1_0 = subs_id + self.block.youtube_id_0_75 = '0_75' + self.store.update_item(self.block, self.user.id) request = Request.blank(f'/translation/uk?videoId={subs_id}') - response = self.item.transcript(request=request, dispatch='translation/uk') + response = self.block.transcript(request=request, dispatch='translation/uk') self.assertDictEqual(json.loads(response.body.decode('utf-8')), subs) # 0_75 subs are exist request = Request.blank('/translation/uk?videoId={}'.format('0_75')) - response = self.item.transcript(request=request, dispatch='translation/uk') + response = self.block.transcript(request=request, dispatch='translation/uk') calculated_0_75 = { 'end': [75], 'start': [9], @@ -674,10 +670,10 @@ def test_translation_non_en_youtube_success(self): self.assertDictEqual(json.loads(response.body.decode('utf-8')), calculated_0_75) # 1_5 will be generated from 1_0 - self.item.youtube_id_1_5 = '1_5' - self.store.update_item(self.item, self.user.id) + self.block.youtube_id_1_5 = '1_5' + self.store.update_item(self.block, self.user.id) request = Request.blank('/translation/uk?videoId={}'.format('1_5')) - response = self.item.transcript(request=request, dispatch='translation/uk') + response = self.block.transcript(request=request, dispatch='translation/uk') calculated_1_5 = { 'end': [150], 'start': [18], @@ -693,13 +689,13 @@ def test_translation_non_en_youtube_success(self): @ddt.unpack def test_translaton_en_html5_success(self, url, dispatch, attach): good_sjson = _create_file(json.dumps(TRANSCRIPT)) - _upload_sjson_file(good_sjson, self.item_descriptor.location) + _upload_sjson_file(good_sjson, self.block.location) subs_id = _get_subs_id(good_sjson.name) - attach(self.item, subs_id) - self.store.update_item(self.item, self.user.id) + attach(self.block, subs_id) + self.store.update_item(self.block, self.user.id) request = Request.blank(url) - response = self.item.transcript(request=request, dispatch=dispatch) + response = self.block.transcript(request=request, dispatch=dispatch) self.assertDictEqual(json.loads(response.body.decode('utf-8')), TRANSCRIPT) def test_translaton_non_en_html5_success(self): @@ -711,12 +707,12 @@ def test_translaton_non_en_html5_success(self): ] } self.srt_file.seek(0) - _upload_file(self.srt_file, self.item_descriptor.location, os.path.split(self.srt_file.name)[1]) + _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1]) # manually clean youtube_id_1_0, as it has default value - self.item.youtube_id_1_0 = "" + self.block.youtube_id_1_0 = "" request = Request.blank('/translation/uk') - response = self.item.transcript(request=request, dispatch='translation/uk') + response = self.block.transcript(request=request, dispatch='translation/uk') self.assertDictEqual(json.loads(response.body.decode('utf-8')), subs) def test_translation_static_transcript_xml_with_data_dirc(self): @@ -730,25 +726,25 @@ def test_translation_static_transcript_xml_with_data_dirc(self): test_modulestore = MagicMock() attrs = {'get_course.return_value': Mock(data_dir='dummy/static', static_asset_path='')} test_modulestore.configure_mock(**attrs) - self.item_descriptor.runtime.modulestore = test_modulestore + self.block.runtime.modulestore = test_modulestore # Test youtube style en request = Request.blank('/translation/en?videoId=12345') - response = self.item.transcript(request=request, dispatch='translation/en') + response = self.block.transcript(request=request, dispatch='translation/en') assert response.status == '307 Temporary Redirect' assert ('Location', '/static/dummy/static/subs_12345.srt.sjson') in response.headerlist # Test HTML5 video style - self.item.sub = 'OEoXaMPEzfM' + self.block.sub = 'OEoXaMPEzfM' request = Request.blank('/translation/en') - response = self.item.transcript(request=request, dispatch='translation/en') + response = self.block.transcript(request=request, dispatch='translation/en') assert response.status == '307 Temporary Redirect' assert ('Location', '/static/dummy/static/subs_OEoXaMPEzfM.srt.sjson') in response.headerlist # Test different language to ensure we are just ignoring it since we can't # translate with static fallback request = Request.blank('/translation/uk') - response = self.item.transcript(request=request, dispatch='translation/uk') + response = self.block.transcript(request=request, dispatch='translation/uk') assert response.status == '404 Not Found' @ddt.data( @@ -774,9 +770,9 @@ def test_translation_static_transcript(self, url, dispatch, status_code, sub=Non self._set_static_asset_path() if attach: - attach(self.item, sub) + attach(self.block, sub) request = Request.blank(url) - response = self.item.transcript(request=request, dispatch=dispatch) + response = self.block.transcript(request=request, dispatch=dispatch) assert response.status == status_code if sub: assert ('Location', f'/static/dummy/static/subs_{sub}.srt.sjson') in response.headerlist @@ -791,7 +787,7 @@ def test_translation_static_non_course(self, __): # When course_id is not mocked out, these values would result in 307, as tested above. request = Request.blank('/translation/en?videoId=12345') - response = self.item.transcript(request=request, dispatch='translation/en') + response = self.block.transcript(request=request, dispatch='translation/en') assert response.status == '404 Not Found' def _set_static_asset_path(self): @@ -821,7 +817,7 @@ def test_translation_fallback_transcript(self, mock_get_video_transcript_data): mock_get_video_transcript_data.return_value = transcript # Make request to XModule transcript handler - response = self.item.transcript(request=Request.blank('/translation/en'), dispatch='translation/en') + response = self.block.transcript(request=Request.blank('/translation/en'), dispatch='translation/en') # Expected headers expected_headers = { @@ -842,7 +838,7 @@ def test_translation_fallback_transcript_feature_disabled(self): Verify that val transcript is not returned when its feature is disabled. """ # Make request to XModule transcript handler - response = self.item.transcript(request=Request.blank('/translation/en'), dispatch='translation/en') + response = self.block.transcript(request=Request.blank('/translation/en'), dispatch='translation/en') # Assert the actual response assert response.status_code == 404 @@ -870,20 +866,20 @@ class TestStudioTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, py def test_translation_fails(self): # No language request = Request.blank("") - response = self.item_descriptor.studio_transcript(request=request, dispatch="translation") + response = self.block.studio_transcript(request=request, dispatch="translation") assert response.status == '400 Bad Request' # No language_code param in request.GET request = Request.blank("") - response = self.item_descriptor.studio_transcript(request=request, dispatch="translation") + response = self.block.studio_transcript(request=request, dispatch="translation") assert response.status == '400 Bad Request' assert response.json['error'] == 'Language is required.' # Correct case: filename = os.path.split(self.srt_file.name)[1] - _upload_file(self.srt_file, self.item_descriptor.location, filename) + _upload_file(self.srt_file, self.block.location, filename) request = Request.blank("translation?language_code=uk") - response = self.item_descriptor.studio_transcript(request=request, dispatch="translation?language_code=uk") + response = self.block.studio_transcript(request=request, dispatch="translation?language_code=uk") self.srt_file.seek(0) assert response.body == self.srt_file.read() assert response.headers['Content-Type'] == 'application/x-subrip; charset=utf-8' @@ -892,9 +888,9 @@ def test_translation_fails(self): # Non ascii file name download: self.srt_file.seek(0) - _upload_file(self.srt_file, self.item_descriptor.location, "塞.srt") + _upload_file(self.srt_file, self.block.location, "塞.srt") request = Request.blank("translation?language_code=zh") - response = self.item_descriptor.studio_transcript(request=request, dispatch="translation?language_code=zh") + response = self.block.studio_transcript(request=request, dispatch="translation?language_code=zh") self.srt_file.seek(0) assert response.body == self.srt_file.read() assert response.headers['Content-Type'] == 'application/x-subrip; charset=utf-8' @@ -945,9 +941,9 @@ def test_studio_transcript_post_validations(self, post_data, error_message): Verify that POST request validations works as expected. """ # mock available_translations method - self.item_descriptor.available_translations = lambda transcripts, verify_assets: ['ur'] + self.block.available_translations = lambda transcripts, verify_assets: ['ur'] request = Request.blank('/translation', POST=post_data) - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.json['error'] == error_message @ddt.data( @@ -981,11 +977,11 @@ def test_studio_transcript_post_w_no_edx_video_id(self, edx_video_id): }) request = Request.blank('/translation', POST=post_data) - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status == '201 Created' response = json.loads(response.text) assert response['language_code'], 'uk' - self.assertDictEqual(self.item_descriptor.transcripts, {}) + self.assertDictEqual(self.block.transcripts, {}) assert edxval_api.get_video_transcript_data(video_id=response['edx_video_id'], language_code='uk') def test_studio_transcript_post_bad_content(self): @@ -1000,7 +996,7 @@ def test_studio_transcript_post_bad_content(self): } request = Request.blank("/translation", POST=post_data) - response = self.item_descriptor.studio_transcript(request=request, dispatch="translation") + response = self.block.studio_transcript(request=request, dispatch="translation") assert response.status_code == 400 assert response.json['error'] == 'There is a problem with this transcript file. Try to upload a different file.' @@ -1033,7 +1029,7 @@ def test_translation_missing_required_params(self, params): Verify that DELETE dispatch works as expected when required args are missing from request """ request = Request(self.REQUEST_META, body=json.dumps(params).encode('utf-8')) - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status_code == 400 def test_translation_delete_w_edx_video_id(self): @@ -1060,8 +1056,8 @@ def test_translation_delete_w_edx_video_id(self): assert api.get_video_transcript_data(video_id=self.EDX_VIDEO_ID, language_code=self.LANGUAGE_CODE_UK) request = Request(self.REQUEST_META, body=request_body.encode('utf-8')) - self.item_descriptor.edx_video_id = self.EDX_VIDEO_ID - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + self.block.edx_video_id = self.EDX_VIDEO_ID + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status_code == 200 # verify that a video transcript dose not exist for expected data @@ -1076,20 +1072,20 @@ def test_translation_delete_wo_edx_video_id(self): request = Request(self.REQUEST_META, body=request_body.encode('utf-8')) # upload and verify that srt file exists in assets - _upload_file(self.SRT_FILE, self.item_descriptor.location, srt_file_name_uk) - assert _check_asset(self.item_descriptor.location, srt_file_name_uk) + _upload_file(self.SRT_FILE, self.block.location, srt_file_name_uk) + assert _check_asset(self.block.location, srt_file_name_uk) # verify transcripts field - assert self.item_descriptor.transcripts != {} - assert self.LANGUAGE_CODE_UK in self.item_descriptor.transcripts + assert self.block.transcripts != {} + assert self.LANGUAGE_CODE_UK in self.block.transcripts # make request and verify response - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status_code == 200 # verify that srt file is deleted - assert self.item_descriptor.transcripts == {} - assert not _check_asset(self.item_descriptor.location, srt_file_name_uk) + assert self.block.transcripts == {} + assert not _check_asset(self.block.location, srt_file_name_uk) def test_translation_delete_w_english_lang(self): """ @@ -1097,45 +1093,45 @@ def test_translation_delete_w_english_lang(self): """ request_body = json.dumps({'lang': self.LANGUAGE_CODE_EN, 'edx_video_id': ''}) srt_file_name_en = subs_filename('english_translation.srt', lang=self.LANGUAGE_CODE_EN) - self.item_descriptor.transcripts['en'] = 'english_translation.srt' + self.block.transcripts['en'] = 'english_translation.srt' request = Request(self.REQUEST_META, body=request_body.encode('utf-8')) # upload and verify that srt file exists in assets - _upload_file(self.SRT_FILE, self.item_descriptor.location, srt_file_name_en) - assert _check_asset(self.item_descriptor.location, srt_file_name_en) + _upload_file(self.SRT_FILE, self.block.location, srt_file_name_en) + assert _check_asset(self.block.location, srt_file_name_en) # make request and verify response - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status_code == 200 # verify that srt file is deleted - assert self.LANGUAGE_CODE_EN not in self.item_descriptor.transcripts - assert not _check_asset(self.item_descriptor.location, srt_file_name_en) + assert self.LANGUAGE_CODE_EN not in self.block.transcripts + assert not _check_asset(self.block.location, srt_file_name_en) def test_translation_delete_w_sub(self): """ Verify that DELETE dispatch works as expected when translation is present against `sub` field """ request_body = json.dumps({'lang': self.LANGUAGE_CODE_EN, 'edx_video_id': ''}) - sub_file_name = subs_filename(self.item_descriptor.sub, lang=self.LANGUAGE_CODE_EN) + sub_file_name = subs_filename(self.block.sub, lang=self.LANGUAGE_CODE_EN) request = Request(self.REQUEST_META, body=request_body.encode('utf-8')) # sub should not be empy - assert not self.item_descriptor.sub == '' + assert not self.block.sub == '' # lint-amnesty, pylint: disable=wrong-assert-type # upload and verify that srt file exists in assets - _upload_file(self.SRT_FILE, self.item_descriptor.location, sub_file_name) - assert _check_asset(self.item_descriptor.location, sub_file_name) + _upload_file(self.SRT_FILE, self.block.location, sub_file_name) + assert _check_asset(self.block.location, sub_file_name) # make request and verify response - response = self.item_descriptor.studio_transcript(request=request, dispatch='translation') + response = self.block.studio_transcript(request=request, dispatch='translation') assert response.status_code == 200 # verify that sub is empty and transcript is deleted also - assert self.item_descriptor.sub == '' + assert self.block.sub == '' # lint-amnesty, pylint: disable=wrong-assert-type - assert not _check_asset(self.item_descriptor.location, sub_file_name) + assert not _check_asset(self.block.location, sub_file_name) class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inherits-tests @@ -1161,8 +1157,7 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri def setUp(self): super().setUp() - self.item_descriptor.render(STUDENT_VIEW) - self.item = self.item_descriptor + self.block.render(STUDENT_VIEW) def test_good_transcript(self): """ @@ -1185,10 +1180,10 @@ def test_good_transcript(self): } """)) - _upload_sjson_file(good_sjson, self.item.location) - self.item.sub = _get_subs_id(good_sjson.name) + _upload_sjson_file(good_sjson, self.block.location) + self.block.sub = _get_subs_id(good_sjson.name) - text, filename, mime_type = get_transcript(self.item) + text, filename, mime_type = get_transcript(self.block) expected_text = textwrap.dedent("""\ 0 @@ -1202,7 +1197,7 @@ def test_good_transcript(self): """) assert text == expected_text - assert filename[:(- 4)] == ('en_' + self.item.sub) + assert filename[:(- 4)] == ('en_' + self.block.sub) assert mime_type == 'application/x-subrip; charset=utf-8' def test_good_txt_transcript(self): @@ -1223,29 +1218,29 @@ def test_good_txt_transcript(self): } """)) - _upload_sjson_file(good_sjson, self.item.location) - self.item.sub = _get_subs_id(good_sjson.name) - text, filename, mime_type = get_transcript(self.item, output_format=Transcript.TXT) + _upload_sjson_file(good_sjson, self.block.location) + self.block.sub = _get_subs_id(good_sjson.name) + text, filename, mime_type = get_transcript(self.block, output_format=Transcript.TXT) expected_text = textwrap.dedent("""\ Hi, welcome to Edx. Let's start with what is on your screen right now.""") assert text == expected_text - assert filename == (('en_' + self.item.sub) + '.txt') + assert filename == (('en_' + self.block.sub) + '.txt') assert mime_type == 'text/plain; charset=utf-8' def test_en_with_empty_sub(self): - self.item.sub = "" - self.item.transcripts = None + self.block.sub = "" + self.block.transcripts = None # no self.sub, self.youttube_1_0 exist, but no file in assets with pytest.raises(NotFoundError): - get_transcript(self.item) + get_transcript(self.block) # no self.sub and no self.youtube_1_0, no non-en transcritps - self.item.youtube_id_1_0 = None + self.block.youtube_id_1_0 = None with pytest.raises(NotFoundError): - get_transcript(self.item) + get_transcript(self.block) # no self.sub but youtube_1_0 exists with file in assets good_sjson = _create_file(content=textwrap.dedent("""\ @@ -1264,10 +1259,10 @@ def test_en_with_empty_sub(self): ] } """)) - _upload_sjson_file(good_sjson, self.item.location) - self.item.youtube_id_1_0 = _get_subs_id(good_sjson.name) + _upload_sjson_file(good_sjson, self.block.location) + self.block.youtube_id_1_0 = _get_subs_id(good_sjson.name) - text, filename, mime_type = get_transcript(self.item) + text, filename, mime_type = get_transcript(self.block) expected_text = textwrap.dedent("""\ 0 00:00:00,270 --> 00:00:02,720 @@ -1280,16 +1275,16 @@ def test_en_with_empty_sub(self): """) assert text == expected_text - assert filename == (('en_' + self.item.youtube_id_1_0) + '.srt') + assert filename == (('en_' + self.block.youtube_id_1_0) + '.srt') assert mime_type == 'application/x-subrip; charset=utf-8' def test_non_en_with_non_ascii_filename(self): - self.item.transcript_language = 'zh' + self.block.transcript_language = 'zh' self.srt_file.seek(0) - _upload_file(self.srt_file, self.item_descriptor.location, "塞.srt") + _upload_file(self.srt_file, self.block.location, "塞.srt") - transcripts = self.item.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable - text, filename, mime_type = get_transcript(self.item) + transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable + text, filename, mime_type = get_transcript(self.block) expected_text = textwrap.dedent(""" 0 00:00:00,12 --> 00:00:00,100 @@ -1302,12 +1297,12 @@ def test_non_en_with_non_ascii_filename(self): def test_value_error_handled(self): good_sjson = _create_file(content='bad content') - _upload_sjson_file(good_sjson, self.item.location) - self.item.sub = _get_subs_id(good_sjson.name) + _upload_sjson_file(good_sjson, self.block.location) + self.block.sub = _get_subs_id(good_sjson.name) - transcripts = self.item.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable + transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable error_transcript = {"start": [], "end": [], "text": ["An error occured obtaining the transcript."]} - content, _, _ = get_transcript(self.item) + content, _, _ = get_transcript(self.block) assert error_transcript["text"][0] in content def test_key_error(self): @@ -1324,9 +1319,9 @@ def test_key_error(self): } """) - _upload_sjson_file(good_sjson, self.item.location) - self.item.sub = _get_subs_id(good_sjson.name) + _upload_sjson_file(good_sjson, self.block.location) + self.block.sub = _get_subs_id(good_sjson.name) - transcripts = self.item.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable + transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable with pytest.raises(KeyError): - get_transcript(self.item) + get_transcript(self.block) diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py index 9887c100593d..44800162d56a 100644 --- a/lms/djangoapps/courseware/tests/test_video_mongo.py +++ b/lms/djangoapps/courseware/tests/test_video_mongo.py @@ -81,7 +81,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas def test_video_constructor(self): """Make sure that all parameters extracted correctly from xml""" - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content sources = ['example.mp4', 'example.webm'] expected_context = { @@ -95,12 +95,12 @@ def test_video_constructor(self): 'download_video_link': 'example.mp4', 'handout': None, 'hide_downloads': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'is_embed': False, 'metadata': json.dumps(OrderedDict({ 'autoAdvance': False, 'saveStateEnabled': True, - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'autoplay': False, 'streams': '0.75:jNCf2gIqpeE,1.00:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg', 'sources': sources, @@ -138,7 +138,7 @@ def test_video_constructor(self): 'public_video_url': None, } - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -165,7 +165,7 @@ def test_video_constructor(self): """Make sure that if the 'youtube' attribute is omitted in XML, then the template generates an empty string for the YouTube streams. """ - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content sources = ['example.mp4', 'example.webm'] expected_context = { @@ -180,11 +180,11 @@ def test_video_constructor(self): 'handout': None, 'hide_downloads': False, 'is_embed': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'metadata': json.dumps(OrderedDict({ 'autoAdvance': False, 'saveStateEnabled': True, - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'autoplay': False, 'streams': '1.00:3_yD_cEKoCk', 'sources': sources, @@ -222,7 +222,7 @@ def test_video_constructor(self): 'public_video_url': None, } - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') expected_result = get_context_dict_from_string( mako_service.render_template('video.html', expected_context) ) @@ -249,11 +249,11 @@ class TestVideoPublicAccess(BaseTestVideoXBlock): @ddt.unpack def test_public_video_url(self, is_lms_platform, enable_public_share): """Test public video url.""" - assert self.item_descriptor.public_access is True + assert self.block.public_access is True if not is_lms_platform: - self.item_descriptor.runtime.is_author_mode = True + self.block.runtime.is_author_mode = True with patch.object(PUBLIC_VIDEO_SHARE, 'is_enabled', return_value=enable_public_share): - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content # public video url iif PUBLIC_VIDEO_SHARE waffle and is_lms_platform, public_access are true assert bool(get_context_dict_from_string(context)['public_video_url']) \ is (is_lms_platform and enable_public_share) @@ -307,10 +307,10 @@ def setUp(self): def get_handler_url(self, handler, suffix): """ Return the URL for the specified handler on the block represented by - self.item_descriptor. + self.block. """ - return self.item_descriptor.runtime.handler_url( - self.item_descriptor, handler, suffix + return self.block.runtime.handler_url( + self.block, handler, suffix ).rstrip('/?') def test_get_html_track(self): @@ -379,7 +379,7 @@ def test_get_html_track(self): 'download_video_link': 'example.mp4', 'handout': None, 'hide_downloads': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'is_embed': False, 'metadata': '', 'track': None, @@ -406,27 +406,27 @@ def test_get_html_track(self): self.initialize_block(data=DATA) track_url = self.get_handler_url('transcript', 'download') - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content metadata.update({ 'transcriptLanguages': {"en": "English"} if not data['transcripts'] else {"uk": 'Українська'}, 'transcriptLanguage': 'en' if not data['transcripts'] or data.get('sub') else 'uk', 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', }) expected_context.update({ 'transcript_download_format': ( - None if self.item_descriptor.track and self.item_descriptor.download_track else 'srt' + None if self.block.track and self.block.download_track else 'srt' ), 'track': ( track_url if data['expected_track_url'] == 'a_sub_file.srt.sjson' else data['expected_track_url'] ), - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'metadata': json.dumps(metadata) }) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -500,7 +500,7 @@ def test_get_html_source(self): 'download_video_link': 'example.mp4', 'handout': None, 'hide_downloads': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'is_embed': False, 'metadata': self.default_metadata_dict, 'track': None, @@ -521,23 +521,23 @@ def test_get_html_source(self): sources=data['sources'] ) self.initialize_block(data=DATA) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content expected_context = dict(initial_context) expected_context['metadata'].update({ 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'sources': data['result'].get('sources', []), }) expected_context.update({ - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'download_video_link': data['result'].get('download_video_link'), 'metadata': json.dumps(expected_context['metadata']) }) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -581,7 +581,7 @@ def test_get_html_with_non_existent_edx_video_id(self): # Referencing a non-existent VAL ID in courseware won't cause an error -- # it'll just fall back to the values in the VideoBlock. - assert 'example.mp4' in self.item_descriptor.render(STUDENT_VIEW).content + assert 'example.mp4' in self.block.render(STUDENT_VIEW).content def test_get_html_with_mocked_edx_video_id(self): # lint-amnesty, pylint: disable=invalid-name, redefined-outer-name @@ -629,7 +629,7 @@ def test_get_html_with_mocked_edx_video_id(self): 'handout': None, 'hide_downloads': False, 'is_embed': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'track': None, 'transcript_download_format': 'srt', 'transcript_download_formats_list': [ @@ -664,23 +664,23 @@ def test_get_html_with_mocked_edx_video_id(self): } ] } - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content expected_context = dict(initial_context) expected_context['metadata'].update({ 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'sources': data['result']['sources'], }) expected_context.update({ - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'download_video_link': data['result']['download_video_link'], 'metadata': json.dumps(expected_context['metadata']) }) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -708,7 +708,7 @@ def test_get_html_with_existing_edx_video_id(self): # context returned by get_html when provided with above data # expected_context, a dict to assert with context context, expected_context = self.helper_get_html_with_edx_video_id(data) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -739,7 +739,7 @@ def test_get_html_with_existing_unstripped_edx_video_id(self): # expected_context, a dict to assert with context context, expected_context = self.helper_get_html_with_edx_video_id(data) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -803,7 +803,7 @@ def helper_get_html_with_edx_video_id(self, data): 'handout': None, 'hide_downloads': False, 'is_embed': False, - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'track': None, 'transcript_download_format': 'srt', 'transcript_download_formats_list': [ @@ -824,7 +824,7 @@ def helper_get_html_with_edx_video_id(self, data): ) self.initialize_block(data=DATA) # context returned by get_html - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content # expected_context, expected context to be returned by get_html expected_context = dict(initial_context) @@ -832,11 +832,11 @@ def helper_get_html_with_edx_video_id(self, data): 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'sources': data['result']['sources'], }) expected_context.update({ - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'download_video_link': data['result']['download_video_link'], 'metadata': json.dumps(expected_context['metadata']) }) @@ -940,25 +940,25 @@ def side_effect(*args, **kwargs): # lint-amnesty, pylint: disable=unused-argume self.initialize_block(data=DATA, runtime_kwargs={ 'user_location': 'CN', }) - user_service = self.item_descriptor.runtime.service(self.item_descriptor, 'user') + user_service = self.block.runtime.service(self.block, 'user') user_location = user_service.get_current_user().opt_attrs[ATTR_KEY_REQUEST_COUNTRY_CODE] assert user_location == 'CN' - context = self.item_descriptor.render('student_view').content + context = self.block.render('student_view').content expected_context = dict(initial_context) expected_context['metadata'].update({ 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'sources': data['result'].get('sources', []), }) expected_context.update({ - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'download_video_link': data['result'].get('download_video_link'), 'metadata': json.dumps(expected_context['metadata']) }) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -1048,22 +1048,22 @@ def test_get_html_cdn_source_external_video(self): 'client_video_id': 'external video', 'encoded_videos': {} } - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content expected_context = dict(initial_context) expected_context['metadata'].update({ 'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'), 'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'), 'publishCompletionUrl': self.get_handler_url('publish_completion', ''), - 'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state', + 'saveStateUrl': self.block.ajax_url + '/save_user_state', 'sources': data['result'].get('sources', []), }) expected_context.update({ - 'id': self.item_descriptor.location.html_id(), + 'id': self.block.location.html_id(), 'download_video_link': data['result'].get('download_video_link'), 'metadata': json.dumps(expected_context['metadata']) }) - mako_service = self.item_descriptor.runtime.service(self.item_descriptor, 'mako') + mako_service = self.block.runtime.service(self.block, 'mako') assert get_context_dict_from_string(context) ==\ get_context_dict_from_string(mako_service.render_template('video.html', expected_context)) @@ -1087,9 +1087,9 @@ def test_get_html_on_toggling_hls_feature(self, hls_feature_enabled, expected_va feature_enabled.return_value = hls_feature_enabled video_xml = '' self.initialize_block(data=video_xml) - self.item_descriptor.render(STUDENT_VIEW) + self.block.render(STUDENT_VIEW) get_urls_for_profiles.assert_called_with( - self.item_descriptor.edx_video_id, + self.block.edx_video_id, expected_val_profiles, ) @@ -1112,7 +1112,7 @@ def test_get_html_hls(self, get_urls_for_profiles): } self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert "'download_video_link': 'https://mp4.com/dm.mp4'" in context assert '"streams": "1.00:https://yt.com/?v=v0TFmdO4ZP0"' in context @@ -1130,7 +1130,7 @@ def test_get_html_hls_no_video_id(self): """ self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert "'download_video_link': None" in context def test_get_html_non_hls_video_download(self): @@ -1146,7 +1146,7 @@ def test_get_html_non_hls_video_download(self): """ self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert "'download_video_link': 'http://example.com/example.mp4'" in context def test_html_student_public_view(self): @@ -1160,9 +1160,9 @@ def test_html_student_public_view(self): """ self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert '"saveStateEnabled": true' in context - context = self.item_descriptor.render(PUBLIC_VIEW).content + context = self.block.render(PUBLIC_VIEW).content assert '"saveStateEnabled": false' in context @patch('xmodule.video_block.video_block.edxval_api.get_course_video_image_url') @@ -1174,7 +1174,7 @@ def test_poster_image(self, get_course_video_image_url): get_course_video_image_url.return_value = '/media/video-images/poster.png' self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert '"poster": "/media/video-images/poster.png"' in context @@ -1187,7 +1187,7 @@ def test_poster_image_without_edx_video_id(self, get_course_video_image_url): get_course_video_image_url.return_value = '/media/video-images/poster.png' self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert "'poster': 'null'" in context @@ -1198,7 +1198,7 @@ def test_hls_primary_playback_on_toggling_hls_feature(self): """ video_xml = '' self.initialize_block(data=video_xml) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert '"prioritizeHls": false' in context @ddt.data( @@ -1252,7 +1252,7 @@ def test_deprecate_youtube_course_waffle_flag(self, data): with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=data['course_override']): with override_waffle_flag(DEPRECATE_YOUTUBE, active=data['waffle_enabled']): self.initialize_block(data=video_xml, metadata=metadata) - context = self.item_descriptor.render(STUDENT_VIEW).content + context = self.block.render(STUDENT_VIEW).content assert '"prioritizeHls": {}'.format(data['result']) in context @@ -1316,7 +1316,7 @@ def test_val_encoding_in_context(self, val_video_encodings, video_url): self.initialize_block( data='' ) - context = self.item_descriptor.get_context() + context = self.block.get_context() assert context['transcripts_basic_tab_metadata']['video_url']['value'] == video_url @ddt.data( @@ -1354,7 +1354,7 @@ def test_val_encoding_in_context_without_external_youtube_source(self, val_video self.initialize_block( data='' ) - context = self.item_descriptor.get_context() + context = self.block.get_context() assert context['transcripts_basic_tab_metadata']['video_url']['value'] == video_url @@ -1388,7 +1388,7 @@ def test_editor_saved_when_html5_sub_not_exist(self, default_store): """ self.MODULESTORE = MODULESTORES[default_store] # pylint: disable=invalid-name self.initialize_block(metadata=self.metadata) - item = self.store.get_item(self.item_descriptor.location) + item = self.store.get_item(self.block.location) with open(self.file_path, "rb") as myfile: # lint-amnesty, pylint: disable=bad-option-value, open-builtin save_to_store(myfile.read(), self.file_name, 'text/sjson', item.location) item.sub = "3_yD_cEKoCk" @@ -1408,7 +1408,7 @@ def test_editor_saved_when_youtube_and_html5_subs_exist(self, default_store): """ self.MODULESTORE = MODULESTORES[default_store] self.initialize_block(metadata=self.metadata) - item = self.store.get_item(self.item_descriptor.location) + item = self.store.get_item(self.block.location) with open(self.file_path, "rb") as myfile: # lint-amnesty, pylint: disable=bad-option-value, open-builtin save_to_store(myfile.read(), self.file_name, 'text/sjson', item.location) save_to_store(myfile.read(), 'subs_video.srt.sjson', 'text/sjson', item.location) @@ -1433,7 +1433,7 @@ def test_editor_saved_with_unstripped_video_id(self, default_store): 'edx_video_id': unstripped_video_id }) self.initialize_block(metadata=self.metadata) - item = self.store.get_item(self.item_descriptor.location) + item = self.store.get_item(self.block.location) assert item.edx_video_id == unstripped_video_id # Now, modifying and saving the video block should strip the video id. @@ -1451,7 +1451,7 @@ def test_editor_saved_with_yt_val_profile(self, default_store): """ self.MODULESTORE = MODULESTORES[default_store] self.initialize_block(metadata=self.metadata) - item = self.store.get_item(self.item_descriptor.location) + item = self.store.get_item(self.block.location) assert item.youtube_id_1_0 == '3_yD_cEKoCk' # Now, modify `edx_video_id` and save should override `youtube_id_1_0`. @@ -1493,7 +1493,7 @@ def setUp(self): ) self.transcript_url = "transcript_url" self.initialize_block(data=sample_xml) - self.video = self.item_descriptor + self.video = self.block self.video.runtime.handler_url = Mock(return_value=self.transcript_url) def setup_val_video(self, associate_course_in_val=False): @@ -1595,7 +1595,7 @@ def test_no_edx_video_id_and_no_fallback(self): ]) self.transcript_url = "transcript_url" self.initialize_block(data=sample_xml) - self.video = self.item_descriptor + self.video = self.block self.video.runtime.handler_url = Mock(return_value=self.transcript_url) result = self.get_result() self.verify_result_with_youtube_url(result) @@ -1659,11 +1659,11 @@ def test_student_view_with_val_transcripts_enabled(self, transcripts, english_su @ddt.ddt class VideoBlockTest(TestCase, VideoBlockTestBase): """ - Tests for video descriptor that requires access to django settings. + Tests for video block that requires access to django settings. """ def setUp(self): super().setUp() - self.descriptor.runtime.handler_url = MagicMock() + self.block.runtime.handler_url = MagicMock() self.temp_dir = mkdtemp() file_system = OSFS(self.temp_dir) self.file_system = file_system.makedir(EXPORT_IMPORT_COURSE_DIR, recreate=True) @@ -1695,12 +1695,12 @@ def test_get_context(self): 'template': 'tabs/metadata-edit-tab.html' } ] - rendered_context = self.descriptor.get_context() + rendered_context = self.block.get_context() self.assertListEqual(rendered_context['tabs'], correct_tabs) # Assert that the Video ID field is present in basic tab metadata context. assert rendered_context['transcripts_basic_tab_metadata']['edx_video_id'] ==\ - self.descriptor.editable_metadata_fields['edx_video_id'] + self.block.editable_metadata_fields['edx_video_id'] def test_export_val_data_with_internal(self): """ @@ -1712,11 +1712,11 @@ def test_export_val_data_with_internal(self): combine(self.temp_dir, EXPORT_IMPORT_COURSE_DIR), combine(EXPORT_IMPORT_STATIC_DIR, transcript_file_name) ) - self.descriptor.edx_video_id = 'test_edx_video_id' + self.block.edx_video_id = 'test_edx_video_id' create_profile('mobile') create_video({ - 'edx_video_id': self.descriptor.edx_video_id, + 'edx_video_id': self.block.edx_video_id, 'client_video_id': 'test_client_video_id', 'duration': 111.0, 'status': 'dummy', @@ -1728,7 +1728,7 @@ def test_export_val_data_with_internal(self): }], }) create_or_update_video_transcript( - video_id=self.descriptor.edx_video_id, + video_id=self.block.edx_video_id, language_code=language_code, metadata={ 'provider': 'Cielo24', @@ -1737,7 +1737,7 @@ def test_export_val_data_with_internal(self): file_data=ContentFile(TRANSCRIPT_FILE_SRT_DATA) ) - actual = self.descriptor.definition_to_xml(resource_fs=self.file_system) + actual = self.block.definition_to_xml(resource_fs=self.file_system) expected_str = """ ''' - descriptor = instantiate_descriptor(data=xml_data_transcripts) - translations = descriptor.available_translations(descriptor.get_transcripts_info(), verify_assets=False) + block = instantiate_block(data=xml_data_transcripts) + translations = block.available_translations(block.get_transcripts_info(), verify_assets=False) assert translations != ['ur'] def assert_validation_message(self, validation, expected_msg): @@ -1114,16 +1114,16 @@ def test_no_transcript_validation_message(self, xml_transcripts, expected_valida {xml_transcripts} '''.format(xml_transcripts=xml_transcripts) - descriptor = instantiate_descriptor(data=xml_data_transcripts) - validation = descriptor.validate() + block = instantiate_block(data=xml_data_transcripts) + validation = block.validate() self.assert_validation_message(validation, expected_validation_msg) def test_video_transcript_none(self): """ Test video when transcripts is None. """ - descriptor = instantiate_descriptor(data=None) - descriptor.transcripts = None - response = descriptor.get_transcripts_info() + block = instantiate_block(data=None) + block.transcripts = None + response = block.get_transcripts_info() expected = {'transcripts': {}, 'sub': ''} assert expected == response diff --git a/xmodule/tests/test_xml_block.py b/xmodule/tests/test_xml_block.py index 24ab557df316..7f33aad0f998 100644 --- a/xmodule/tests/test_xml_block.py +++ b/xmodule/tests/test_xml_block.py @@ -251,8 +251,8 @@ def test_override_default(self): ) def test_integer_field(self): - descriptor = self.get_descriptor(DictFieldData({'max_attempts': '7'})) - editable_fields = descriptor.editable_metadata_fields + block = self.get_block(DictFieldData({'max_attempts': '7'})) + editable_fields = block.editable_metadata_fields assert 8 == len(editable_fields) self.assert_field_values( editable_fields, 'max_attempts', TestFields.max_attempts, @@ -264,7 +264,7 @@ def test_integer_field(self): explicitly_set=False, value='local default', default_value='local default' ) - editable_fields = self.get_descriptor(DictFieldData({})).editable_metadata_fields + editable_fields = self.get_block(DictFieldData({})).editable_metadata_fields self.assert_field_values( editable_fields, 'max_attempts', TestFields.max_attempts, explicitly_set=False, value=1000, default_value=1000, type='Integer', @@ -274,8 +274,8 @@ def test_integer_field(self): def test_inherited_field(self): kvs = InheritanceKeyValueStore(initial_values={}, inherited_settings={'showanswer': 'inherited'}) model_data = KvsFieldData(kvs) - descriptor = self.get_descriptor(model_data) - editable_fields = descriptor.editable_metadata_fields + block = self.get_block(model_data) + editable_fields = block.editable_metadata_fields self.assert_field_values( editable_fields, 'showanswer', InheritanceMixin.showanswer, explicitly_set=False, value='inherited', default_value='inherited' @@ -287,8 +287,8 @@ def test_inherited_field(self): inherited_settings={'showanswer': 'inheritable value'} ) model_data = KvsFieldData(kvs) - descriptor = self.get_descriptor(model_data) - editable_fields = descriptor.editable_metadata_fields + block = self.get_block(model_data) + editable_fields = block.editable_metadata_fields self.assert_field_values( editable_fields, 'showanswer', InheritanceMixin.showanswer, explicitly_set=True, value='explicit', default_value='inheritable value' @@ -298,8 +298,8 @@ def test_type_and_options(self): # test_display_name_field verifies that a String field is of type "Generic". # test_integer_field verifies that a Integer field is of type "Integer". - descriptor = self.get_descriptor(DictFieldData({})) - editable_fields = descriptor.editable_metadata_fields + block = self.get_block(DictFieldData({})) + editable_fields = block.editable_metadata_fields # Tests for select self.assert_field_values( @@ -343,16 +343,16 @@ def get_xml_editable_fields(self, field_data): field_data=field_data, ).editable_metadata_fields - def get_descriptor(self, field_data): - class TestModuleDescriptor(TestFields, self.TestableXmlXBlock): # lint-amnesty, pylint: disable=abstract-method + def get_block(self, field_data): + class TestModuleBlock(TestFields, self.TestableXmlXBlock): # lint-amnesty, pylint: disable=abstract-method @property def non_editable_metadata_fields(self): non_editable_fields = super().non_editable_metadata_fields - non_editable_fields.append(TestModuleDescriptor.due) + non_editable_fields.append(TestModuleBlock.due) return non_editable_fields system = get_test_descriptor_system(render_template=Mock()) - return system.construct_xblock_from_class(TestModuleDescriptor, field_data=field_data, scope_ids=Mock()) + return system.construct_xblock_from_class(TestModuleBlock, field_data=field_data, scope_ids=Mock()) def assert_field_values(self, editable_fields, name, field, explicitly_set, value, default_value, # lint-amnesty, pylint: disable=dangerous-default-value type='Generic', options=[]): # lint-amnesty, pylint: disable=redefined-builtin diff --git a/xmodule/tests/xml/__init__.py b/xmodule/tests/xml/__init__.py index 56b6d1a2e6bc..77ca1882f6a3 100644 --- a/xmodule/tests/xml/__init__.py +++ b/xmodule/tests/xml/__init__.py @@ -23,7 +23,7 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable def __init__(self, xml_import_data): self.course_id = CourseKey.from_string(xml_import_data.course_id) self.default_class = xml_import_data.default_class - self._descriptors = {} + self._blocks = {} def get_policy(usage_id): """Return the policy data for the specified usage""" @@ -42,19 +42,19 @@ def get_policy(usage_id): ) def process_xml(self, xml): # pylint: disable=method-hidden - """Parse `xml` as an XBlock, and add it to `self._descriptors`""" + """Parse `xml` as an XBlock, and add it to `self._blocks`""" self.get_asides = Mock(return_value=[]) - descriptor = self.xblock_from_node( + block = self.xblock_from_node( etree.fromstring(xml), None, CourseLocationManager(self.course_id), ) - self._descriptors[str(descriptor.location)] = descriptor - return descriptor + self._blocks[str(block.location)] = block + return block def load_item(self, location, for_parent=None): # pylint: disable=method-hidden, unused-argument - """Return the descriptor loaded for `location`""" - return self._descriptors[str(location)] + """Return the block loaded for `location`""" + return self._blocks[str(location)] class XModuleXmlImportTest(TestCase): diff --git a/xmodule/video_block/transcripts_utils.py b/xmodule/video_block/transcripts_utils.py index 0cbc79945b8d..39f18ca741ca 100644 --- a/xmodule/video_block/transcripts_utils.py +++ b/xmodule/video_block/transcripts_utils.py @@ -241,13 +241,13 @@ def get_transcripts_from_youtube(youtube_id, settings, i18n, youtube_transcript_ return {'start': sub_starts, 'end': sub_ends, 'text': sub_texts} -def download_youtube_subs(youtube_id, video_descriptor, settings): # lint-amnesty, pylint: disable=redefined-outer-name +def download_youtube_subs(youtube_id, video_block, settings): # lint-amnesty, pylint: disable=redefined-outer-name """ Download transcripts from Youtube. Args: youtube_id: str, actual youtube_id of the video. - video_descriptor: video descriptor instance. + video_block: video block instance. We save transcripts for 1.0 speed, as for other speed conversion is done on front-end. @@ -257,7 +257,7 @@ def download_youtube_subs(youtube_id, video_descriptor, settings): # lint-amnes Raises: GetTranscriptsFromYouTubeException, if fails. """ - i18n = video_descriptor.runtime.service(video_descriptor, "i18n") + i18n = video_block.runtime.service(video_block, "i18n") _ = i18n.ugettext subs = get_transcripts_from_youtube(youtube_id, settings, i18n) @@ -961,7 +961,7 @@ def get_transcript_from_contentstore(video, language, output_format, transcripts Get video transcript from content store. Arguments: - video (Video Descriptor): Video descriptor + video (Video block): Video block language (unicode): transcript language output_format (unicode): transcript output format transcripts_info (dict): transcript info for a video @@ -1089,7 +1089,7 @@ def get_transcript(video, lang=None, output_format=Transcript.SRT, youtube_id=No Get video transcript from edx-val or content store. Arguments: - video (Video Descriptor): Video Descriptor + video (Video block): Video block lang (unicode): transcript language output_format (unicode): transcript output format youtube_id (unicode): youtube video id diff --git a/xmodule/x_module.py b/xmodule/x_module.py index 031a895b0faa..3434a80b3955 100644 --- a/xmodule/x_module.py +++ b/xmodule/x_module.py @@ -286,7 +286,7 @@ class XModuleMixin(XModuleFields, XBlock): Adding this Mixin to an :class:`XBlock` allows it to cooperate with old-style :class:`XModules` """ - # Attributes for inspection of the descriptor + # Attributes for inspection of the block # This indicates whether the xmodule is a problem-type. # It should respond to max_score() and grade(). It can be graded or ungraded @@ -299,7 +299,7 @@ class XModuleMixin(XModuleFields, XBlock): # Class level variable - # True if this descriptor always requires recalculation of grades, for + # True if this block always requires recalculation of grades, for # example if the score can change via an extrnal service, not just when the # student interacts with the module on the page. A specific example is # FoldIt, which posts grade-changing updates through a separate API. @@ -563,10 +563,10 @@ def get_icon_class(self): def has_dynamic_children(self): """ - Returns True if this descriptor has dynamic children for a given + Returns True if this block has dynamic children for a given student when the module is created. - Returns False if the children of this descriptor are the same + Returns False if the children of this block are the same children that the module will return for any student. """ return False @@ -1002,7 +1002,7 @@ def wrap_aside(self, block, aside, view, frag, context): # pylint: disable=un # Runtime.handler_url interface. # # The monkey-patching happens in cms/djangoapps/xblock_config/apps.py and lms/djangoapps/lms_xblock/apps.py -def descriptor_global_handler_url(block, handler_name, suffix='', query='', thirdparty=False): +def block_global_handler_url(block, handler_name, suffix='', query='', thirdparty=False): """ See :meth:`xblock.runtime.Runtime.handler_url`. """ @@ -1014,7 +1014,7 @@ def descriptor_global_handler_url(block, handler_name, suffix='', query='', thir # the Runtime part of its interface. This function matches the Runtime.local_resource_url interface # # The monkey-patching happens in cms/djangoapps/xblock_config/apps.py and lms/djangoapps/lms_xblock/apps.py -def descriptor_global_local_resource_url(block, uri): +def block_global_local_resource_url(block, uri): """ See :meth:`xblock.runtime.Runtime.local_resource_url`. """ @@ -1529,7 +1529,7 @@ def handler_url(self, block, handler_name, suffix='', query='', thirdparty=False # defined for LMS/CMS through the handler_url_override property. if getattr(self, 'handler_url_override', None): return self.handler_url_override(block, handler_name, suffix, query, thirdparty) - return descriptor_global_handler_url(block, handler_name, suffix, query, thirdparty) + return block_global_handler_url(block, handler_name, suffix, query, thirdparty) def local_resource_url(self, block, uri): """ @@ -1539,7 +1539,7 @@ def local_resource_url(self, block, uri): # This means that LMS/CMS don't have a way to define a subclass of DescriptorSystem # that implements the correct local_resource_url. So, for now, instead, we will reference a # global function that the application can override. - return descriptor_global_local_resource_url(block, uri) + return block_global_local_resource_url(block, uri) def applicable_aside_types(self, block): """ diff --git a/xmodule/xml_block.py b/xmodule/xml_block.py index e67e23604635..cb7c096ce942 100644 --- a/xmodule/xml_block.py +++ b/xmodule/xml_block.py @@ -152,7 +152,7 @@ def _get_metadata_from_xml(xml_object, remove=True): @classmethod def definition_from_xml(cls, xml_object, system): """ - Return the definition to be passed to the newly created descriptor + Return the definition to be passed to the newly created block during from_xml xml_object: An etree Element @@ -199,7 +199,7 @@ def load_file(cls, filepath, fs, def_id): # pylint: disable=invalid-name @classmethod def load_definition(cls, xml_object, system, def_id, id_generator): """ - Load a descriptor definition from the specified xml_object. + Load a block from the specified xml_object. Subclasses should not need to override this except in special cases (e.g. html block) @@ -365,7 +365,7 @@ def parse_xml(cls, node, runtime, _keys, id_generator): xblock = runtime.construct_xblock_from_class( cls, - # We're loading a descriptor, so student_id is meaningless + # We're loading a block, so student_id is meaningless ScopeIds(None, node.tag, def_id, usage_id), field_data, ) @@ -405,7 +405,7 @@ def _format_filepath(cls, category, name): return f'{category}/{name}.{cls.filename_extension}' def export_to_file(self): - """If this returns True, write the definition of this descriptor to a separate + """If this returns True, write the definition of this block to a separate file. NOTE: Do not override this without a good reason. It is here