From c80fba689a36aa35489ded8018eb997c4ef4e8a1 Mon Sep 17 00:00:00 2001 From: Pooja Kulkarni Date: Wed, 4 Jan 2023 13:55:45 -0500 Subject: [PATCH] refactor: rename descriptor -> block within lms/djangoapps/courseware Co-authored-by: Agrendalath --- lms/djangoapps/courseware/access.py | 152 ++++---- lms/djangoapps/courseware/block_render.py | 76 ++-- lms/djangoapps/courseware/courses.py | 18 +- .../management/commands/clean_xml.py | 2 +- lms/djangoapps/courseware/masquerade.py | 4 +- lms/djangoapps/courseware/model_data.py | 104 +++--- lms/djangoapps/courseware/tests/helpers.py | 8 +- .../courseware/tests/test_access.py | 58 ++-- .../courseware/tests/test_block_render.py | 311 ++++++++--------- .../courseware/tests/test_courses.py | 2 +- .../tests/test_discussion_xblock.py | 10 +- .../courseware/tests/test_entrance_exam.py | 4 +- .../courseware/tests/test_lti_integration.py | 30 +- .../courseware/tests/test_model_data.py | 28 +- .../courseware/tests/test_video_handlers.py | 325 +++++++++--------- .../courseware/tests/test_video_mongo.py | 226 ++++++------ lms/djangoapps/courseware/tests/test_views.py | 2 +- .../courseware/tests/test_word_cloud.py | 21 +- lms/djangoapps/courseware/tests/tests.py | 28 +- .../courseware/user_state_client.py | 2 +- lms/djangoapps/courseware/views/index.py | 8 +- lms/djangoapps/courseware/views/views.py | 14 +- 22 files changed, 701 insertions(+), 732 deletions(-) diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index f71f2daec5..74f1d74f83 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 _can_view_courseware_with_prerequisites(user, course): 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 _has_access_course(user, action, courselike): # _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 _has_access_course(user, action, courselike): 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 _has_access_course(user, action, courselike): 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 _has_access_course(user, action, courselike): 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 _has_access_course(user, action, courselike): 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 _has_access_course(user, action, courselike): '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 _has_access_course(user, action, courselike): 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 _has_access_descriptor(user, action, descriptor, course_key=None): 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 _has_access_descriptor(user, action, descriptor, course_key=None): 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 6cf435f5a0..b66a193f4f 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 prepare_runtime_for_user( 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 prepare_runtime_for_user( # 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 676a42bd70..009ebf6fdb 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -76,7 +76,7 @@ _Assignment = namedtuple( 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 2dd247de4d..7cebce3612 100644 --- a/lms/djangoapps/courseware/management/commands/clean_xml.py +++ b/lms/djangoapps/courseware/management/commands/clean_xml.py @@ -17,7 +17,7 @@ from xmodule.modulestore.xml import XMLModuleStore 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 e838f862c5..5ce266c463 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -112,8 +112,8 @@ class MasqueradeView(View): 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 26578f286c..59fcc725ed 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 @@ class FieldDataCache: ), } 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 99dbf75250..577f8b2ca3 100644 --- a/lms/djangoapps/courseware/tests/helpers.py +++ b/lms/djangoapps/courseware/tests/helpers.py @@ -85,20 +85,20 @@ class BaseTestXmodule(ModuleStoreTestCase): '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 b472234d41..8a4cbabad6 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -182,15 +182,15 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes 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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes ('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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes ) @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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes 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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes '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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes @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 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes """ 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 37c3848671..9c2e5e9766 100644 --- a/lms/djangoapps/courseware/tests/test_block_render.py +++ b/lms/djangoapps/courseware/tests/test_block_render.py @@ -251,7 +251,7 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): 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 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): 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 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): 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 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): @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 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): 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 @@ class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): # _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 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas @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 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas 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 @@ class TestTOC(ModuleStoreTestCase): 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 @@ class TestProctoringRendering(ModuleStoreTestCase): 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 @@ class TestProctoringRendering(ModuleStoreTestCase): 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 @@ class TestGatedSubsectionRendering(ModuleStoreTestCase, MilestonesTestCaseMixin) 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 @@ class TestHtmlModifiers(ModuleStoreTestCase): 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 @@ class JsonInitDataTest(ModuleStoreTestCase): 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 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase): 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 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase): """ - 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 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase): """) - 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 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase): 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 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase) @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 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase) 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 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase): 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 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase): 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 @@ class TestXBlockRuntimeEvent(TestSubmittingProblems): """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 @@ class TestRebindBlock(TestSubmittingProblems): """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 @@ class TestEventPublishing(ModuleStoreTestCase, LoginEnrollmentTestCase): 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 @@ class LMSXBlockServiceMixin(SharedModuleStoreTestCase): _ = 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 @@ class LMSXBlockServiceMixin(SharedModuleStoreTestCase): 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 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin): """ 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 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin): 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 @@ class TestI18nService(LMSXBlockServiceMixin): """ 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 @@ class TestI18nService(LMSXBlockServiceMixin): """ 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 @@ class TestFilteredChildren(SharedModuleStoreTestCase): 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 @@ class TestFilteredChildren(SharedModuleStoreTestCase): 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 @@ class TestFilteredChildren(SharedModuleStoreTestCase): 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 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase): 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 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase): 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): _ = 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): """ 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): _ = 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): _ = 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): 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 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase): 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 d4d6c97fbe..166a8ccbdb 100644 --- a/lms/djangoapps/courseware/tests/test_courses.py +++ b/lms/djangoapps/courseware/tests/test_courses.py @@ -382,7 +382,7 @@ class CourseInstantiationTests(ModuleStoreTestCase): 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 159add3e05..ea265daab7 100644 --- a/lms/djangoapps/courseware/tests/test_discussion_xblock.py +++ b/lms/djangoapps/courseware/tests/test_discussion_xblock.py @@ -295,7 +295,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase): """ 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 @@ class TestXBlockInCourse(SharedModuleStoreTestCase): 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 @@ class TestXBlockInCourse(SharedModuleStoreTestCase): 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 @@ class TestXBlockQueryLoad(SharedModuleStoreTestCase): 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 7024ea5c3c..240a9494fc 100644 --- a/lms/djangoapps/courseware/tests/test_entrance_exam.py +++ b/lms/djangoapps/courseware/tests/test_entrance_exam.py @@ -340,7 +340,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest 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 e7d7f856ba..036cc8da2d 100644 --- a/lms/djangoapps/courseware/tests/test_lti_integration.py +++ b/lms/djangoapps/courseware/tests/test_lti_integration.py @@ -40,11 +40,11 @@ class TestLTI(BaseTestXmodule): 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 @@ class TestLTI(BaseTestXmodule): 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 @@ class TestLTI(BaseTestXmodule): '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 @@ class TestLTI(BaseTestXmodule): 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 36c0a87872..6c763d57b3 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 @@ class TestInvalidScopes(TestCase): # lint-amnesty, pylint: disable=missing-clas 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 @@ class TestStudentModuleStorage(OtherUserFailureTestMixin, TestCase): 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 @@ class TestMissingStudentModule(TestCase): # lint-amnesty, pylint: disable=missi 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 @@ class StorageTestBase: 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 737c6c25b9..9ae07c42ef 100644 --- a/lms/djangoapps/courseware/tests/test_video_handlers.py +++ b/lms/djangoapps/courseware/tests/test_video_handlers.py @@ -172,12 +172,12 @@ class TestVideo(BaseTestVideoXBlock): 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 @@ class TestVideo(BaseTestVideoXBlock): 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 @@ class TestVideo(BaseTestVideoXBlock): 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 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p 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 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p 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 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p '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 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p """ 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 @@ class TestTranscriptAvailableTranslationsBumperDispatch(TestVideo): # lint-amne 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 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl ) 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 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl 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 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl ) 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 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl # 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: @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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: ] } 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: @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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: ] } 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: # 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint: 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 @@ class TestStudioTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, py # 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 @@ class TestStudioTranscriptTranslationPostDispatch(TestVideo): # lint-amnesty, p 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 @@ class TestStudioTranscriptTranslationPostDispatch(TestVideo): # lint-amnesty, p }) 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 @@ class TestStudioTranscriptTranslationPostDispatch(TestVideo): # lint-amnesty, p } 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 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty, 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 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty, 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 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty, 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 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty, """ 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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri } """)) - _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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri """) 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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri } """)) - _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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri ] } """)) - _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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri """) 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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri 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 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri } """) - _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 9887c10059..44800162d5 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 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas '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 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas '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 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests """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 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests '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 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): # 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): } ] } - 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): # context returned by get_html when provided with above data # expected_context, a dict to assert with context context, expected_context = self.helper_get_html_with_edx_video_id(data) - mako_service = self.item_descriptor.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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): # expected_context, a dict to assert with context context, expected_context = self.helper_get_html_with_edx_video_id(data) - mako_service = self.item_descriptor.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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): ) 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): '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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): } 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): """ 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): """ 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): """ 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): """ 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 @@ class TestGetHtmlMethod(BaseTestVideoXBlock): 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 @@ class TestVideoBlockInitialization(BaseTestVideoXBlock): 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 @@ class TestVideoBlockInitialization(BaseTestVideoXBlock): 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 @@ class TestEditorSavedMethod(BaseTestVideoXBlock): """ 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 @@ class TestEditorSavedMethod(BaseTestVideoXBlock): """ 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 @@ class TestEditorSavedMethod(BaseTestVideoXBlock): '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 @@ class TestEditorSavedMethod(BaseTestVideoXBlock): """ 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 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase) ) 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 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase) ]) 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 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase) @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 @@ class VideoBlockTest(TestCase, VideoBlockTestBase): '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 @@ class VideoBlockTest(TestCase, VideoBlockTestBase): 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 @@ class VideoBlockTest(TestCase, VideoBlockTestBase): }], }) 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 @@ class VideoBlockTest(TestCase, VideoBlockTestBase): 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 = """