refactor: rename module -> block within lms/djangoapps/courseware

Also, removed unused `_has_access_xmodule` methid from `lms/djangoapps/courseware/access.py`.
This commit is contained in:
0x29a
2022-12-23 15:27:31 +01:00
committed by Agrendalath
parent 611563600c
commit 9d8375ff99
55 changed files with 432 additions and 443 deletions

View File

@@ -207,7 +207,7 @@ def _preview_module_system(request, descriptor, field_data):
preview_anonymous_user_id = anonymous_id_for_user(request.user, course_id)
return PreviewModuleSystem(
get_module=partial(_load_preview_module, request),
get_block=partial(_load_preview_module, request),
mixins=settings.XBLOCK_MIXINS,
# Set up functions to modify the fragment produced by student_view

View File

@@ -183,7 +183,7 @@ How to output coverage locally
These are examples of how to run a single test and get coverage::
pytest cms/djangoapps/contentstore/tests/test_import.py --cov --cov-config=.coveragerc-local # cms example
pytest lms/djangoapps/courseware/tests/test_module_render.py --cov --cov-config=.coveragerc-local # lms example
pytest lms/djangoapps/courseware/tests/test_block_render.py --cov --cov-config=.coveragerc-local # lms example
That ``--cov-conifg=.coveragerc-local`` option is important - without it, the coverage
tool will look for paths that exist on our jenkins test servers, but not on your local devstack.

View File

@@ -5,7 +5,7 @@ like DISABLE_START_DATES.
Note: The access control logic in this file does NOT check for enrollment in
a course. It is expected that higher layers check for enrollment so we
don't have to hit the enrollments table on every module load.
don't have to hit the enrollments table on every block load.
If enrollment is to be checked, use get_course_with_access in courseware.courses.
It is a wrapper around has_access that additionally checks for enrollment.
@@ -104,8 +104,8 @@ def has_access(user, action, obj, course_key=None):
switching based on various settings.
Things this module understands:
- start dates for modules
- visible_to_staff_only for modules
- start dates for blocks
- visible_to_staff_only for blocks
- DISABLE_START_DATES
- different access for instructor, staff, course staff, and students.
- mobile_available flag for course blocks
@@ -113,7 +113,7 @@ def has_access(user, action, obj, course_key=None):
user: a Django user object. May be anonymous. If none is passed,
anonymous is assumed
obj: The object to check access for. A module, descriptor, location, or
obj: The object to check access for. A block, descriptor, location, or
certain special strings (e.g. 'global')
action: A string specifying the action that the client is trying to perform.
@@ -557,9 +557,9 @@ def _has_access_descriptor(user, action, descriptor, course_key=None):
def can_load():
"""
NOTE: This does not check that the student is enrolled in the course
that contains this module. We may or may not want to allow non-enrolled
students to see modules. If not, views should check the course, so we
don't have to hit the enrollments table on every module load.
that contains this block. We may or may not want to allow non-enrolled
students to see blocks. If not, views should check the course, so we
don't have to hit the enrollments table on every block load.
"""
# If the user (or the role the user is currently masquerading as) does not have
# access to this content, then deny access. The problem with calling _has_staff_access_to_descriptor
@@ -569,7 +569,7 @@ def _has_access_descriptor(user, action, descriptor, course_key=None):
if not group_access_response:
return group_access_response
# If the user has staff access, they can load the module and checks below are not needed.
# If the user has staff access, they can load the block and checks below are not needed.
staff_access_response = _has_staff_access_to_descriptor(user, descriptor, course_key)
if staff_access_response:
return staff_access_response
@@ -597,17 +597,6 @@ def _has_access_descriptor(user, action, descriptor, course_key=None):
return _dispatch(checkers, action, user, descriptor)
def _has_access_xmodule(user, action, xmodule, course_key):
"""
Check if user has access to this xmodule.
Valid actions:
- same as the valid actions for xmodule.descriptor
"""
# Delegate to the descriptor
return has_access(user, action, xmodule.descriptor, course_key)
def _has_access_location(user, action, location, course_key):
"""
Check if user has access to this location.

View File

@@ -1,5 +1,5 @@
"""
Module rendering
Block rendering
"""
@@ -107,7 +107,7 @@ log = logging.getLogger(__name__)
class LmsModuleRenderError(Exception):
"""
An exception class for exceptions thrown by module_render that don't fit well elsewhere
An exception class for exceptions thrown by block_render that don't fit well elsewhere
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass
@@ -155,7 +155,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
field_data_cache must include data from the course blocks and 2 levels of its descendants
'''
with modulestore().bulk_operations(course.id):
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
user, request, course, field_data_cache, course.id, course=course
)
if course_block is None:
@@ -276,17 +276,16 @@ def _add_timed_exam_info(user, course, section, section_context):
})
def get_module(user, request, usage_key, field_data_cache,
position=None, log_if_not_found=True, wrap_xmodule_display=True,
grade_bucket_type=None, depth=0,
static_asset_path='', course=None, will_recheck_access=False):
def get_block(user, request, usage_key, field_data_cache, position=None, log_if_not_found=True,
wrap_xblock_display=True, grade_bucket_type=None, depth=0, static_asset_path='', course=None,
will_recheck_access=False):
"""
Get an instance of the xmodule class identified by location,
Get an instance of the XBlock class identified by location,
setting the state based on an existing StudentModule, or creating one if none
exists.
Arguments:
- user : User for whom we're getting the module
- user : User for whom we're getting the block
- request : current django HTTPrequest. Note: request.user isn't used for anything--all auth
and such works based on user.
- usage_key : A UsageKey object identifying the module to load
@@ -294,7 +293,7 @@ def get_module(user, request, usage_key, field_data_cache,
- position : extra information from URL for user-specified
position within module
- log_if_not_found : If this is True, we log a debug message if we cannot find the requested xmodule.
- wrap_xmodule_display : If this is True, wrap the output display in a single div to allow for the
- wrap_xblock_display : If this is True, wrap the output display in a single div to allow for the
XModule javascript to be bound correctly
- depth : number of levels of descendents to cache when loading this module.
None means cache all descendents
@@ -306,26 +305,26 @@ def get_module(user, request, usage_key, field_data_cache,
before rendering the content in order to display access error messages
to the user.
Returns: xmodule instance, or None if the user does not have access to the
module. If there's an error, will try to return an instance of ErrorBlock
Returns: XBlock instance, or None if the user does not have access to the
block. If there's an error, will try to return an instance of ErrorBlock
if possible. If not possible, return None.
"""
try:
descriptor = modulestore().get_item(usage_key, depth=depth)
return get_module_for_descriptor(user, request, descriptor, field_data_cache, usage_key.course_key,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
course=course, will_recheck_access=will_recheck_access)
return get_block_for_descriptor(user, request, descriptor, field_data_cache, usage_key.course_key,
position=position,
wrap_xblock_display=wrap_xblock_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
course=course, will_recheck_access=will_recheck_access)
except ItemNotFoundError:
if log_if_not_found:
log.debug("Error in get_module: ItemNotFoundError")
log.debug("Error in get_block: ItemNotFoundError")
return None
except: # pylint: disable=W0702
# Something has gone terribly wrong, but still not letting it turn into a 500.
log.exception("Error in get_module")
log.exception("Error in get_block")
return None
@@ -366,16 +365,16 @@ def display_access_messages(user, block, view, frag, context): # pylint: disabl
# pylint: disable=too-many-statements
def get_module_for_descriptor(user, request, descriptor, field_data_cache, course_key,
position=None, wrap_xmodule_display=True, grade_bucket_type=None,
static_asset_path='', disable_staff_debug_info=False,
course=None, will_recheck_access=False):
def get_block_for_descriptor(user, request, descriptor, field_data_cache, course_key,
position=None, wrap_xblock_display=True, grade_bucket_type=None,
static_asset_path='', disable_staff_debug_info=False,
course=None, will_recheck_access=False):
"""
Implements get_module, extracting out the request-specific functionality.
Implements get_block, extracting out the request-specific functionality.
disable_staff_debug_info : If this is True, exclude staff debug information in the rendering of the module.
disable_staff_debug_info : If this is True, exclude staff debug information in the rendering of the block.
See get_module() docstring for further details.
See get_block() docstring for further details.
"""
track_function = make_track_function(request)
@@ -386,14 +385,14 @@ def get_module_for_descriptor(user, request, descriptor, field_data_cache, cours
student_kvs = MasqueradingKeyValueStore(student_kvs, request.session)
student_data = KvsFieldData(student_kvs)
return get_module_for_descriptor_internal(
return get_block_for_descriptor_internal(
user=user,
descriptor=descriptor,
student_data=student_data,
course_id=course_key,
track_function=track_function,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
wrap_xblock_display=wrap_xblock_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
user_location=user_location,
@@ -413,7 +412,7 @@ def get_module_system_for_user(
track_function,
request_token,
position=None,
wrap_xmodule_display=True,
wrap_xblock_display=True,
grade_bucket_type=None,
static_asset_path='',
user_location=None,
@@ -425,16 +424,16 @@ def get_module_system_for_user(
Helper function that returns a module system and student_data bound to a user and a descriptor.
The purpose of this function is to factor out everywhere a user is implicitly bound when creating a module,
to allow an existing module to be re-bound to a user. Most of the user bindings happen when creating the
to allow an existing block to be re-bound to a user. Most of the user bindings happen when creating the
closures that feed the instantiation of ModuleSystem.
The arguments fall into two categories: those that have explicit or implicit user binding, which are user
and student_data, and those don't and are just present so that ModuleSystem can be instantiated, which
are all the other arguments. Ultimately, this isn't too different than how get_module_for_descriptor_internal
are all the other arguments. Ultimately, this isn't too different than how get_block_for_descriptor_internal
was before refactoring.
Arguments:
see arguments for get_module()
see arguments for get_block()
request_token (str): A token unique to the request use by xblock initialization
Returns:
@@ -458,7 +457,7 @@ def get_module_system_for_user(
return xqueue_callback_url_prefix + relative_xqueue_callback_url
# Default queuename is course-specific and is derived from the course that
# contains the current module.
# contains the current block.
# TODO: Queuename should be derived from 'course_settings.json' of each course
xqueue_default_queuename = descriptor.location.org + '-' + descriptor.location.course
@@ -471,15 +470,15 @@ def get_module_system_for_user(
waittime=settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS,
)
def inner_get_module(descriptor):
def inner_get_block(descriptor):
"""
Delegate to get_module_for_descriptor_internal() with all values except `descriptor` set.
Delegate to get_block_for_descriptor_internal() with all values except `descriptor` set.
Because it does an access check, it may return None.
"""
# TODO: fix this so that make_xqueue_callback uses the descriptor passed into
# inner_get_module, not the parent's callback. Add it as an argument....
return get_module_for_descriptor_internal(
# inner_get_block, not the parent's callback. Add it as an argument....
return get_block_for_descriptor_internal(
user=user,
descriptor=descriptor,
student_data=student_data,
@@ -487,7 +486,7 @@ def get_module_system_for_user(
track_function=track_function,
request_token=request_token,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
wrap_xblock_display=wrap_xblock_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
user_location=user_location,
@@ -522,7 +521,7 @@ def get_module_system_for_user(
get_module_system_for_user,
track_function=track_function,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
wrap_xblock_display=wrap_xblock_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
user_location=user_location,
@@ -541,9 +540,9 @@ def get_module_system_for_user(
if settings.FEATURES.get("LICENSING", False):
block_wrappers.append(partial(wrap_with_license, mako_service=mako_service))
# Wrap the output display in a single div to allow for the XModule
# Wrap the output display in a single div to allow for the XBlock
# javascript to be bound correctly
if wrap_xmodule_display is True:
if wrap_xblock_display is True:
block_wrappers.append(partial(
wrap_xblock,
'LmsRuntime',
@@ -589,7 +588,7 @@ def get_module_system_for_user(
store = modulestore()
system = LmsModuleSystem(
get_module=inner_get_module,
get_block=inner_get_block,
# TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington)
mixins=descriptor.runtime.mixologist._mixins, # pylint: disable=protected-access
wrappers=block_wrappers,
@@ -650,15 +649,14 @@ def get_module_system_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_module_for_descriptor_internal(user, descriptor, student_data, course_id,
track_function, request_token,
position=None, wrap_xmodule_display=True, grade_bucket_type=None,
static_asset_path='', user_location=None, disable_staff_debug_info=False,
course=None, will_recheck_access=False):
def get_block_for_descriptor_internal(user, descriptor, student_data, course_id, track_function, request_token,
position=None, wrap_xblock_display=True, grade_bucket_type=None,
static_asset_path='', user_location=None, disable_staff_debug_info=False,
course=None, will_recheck_access=False):
"""
Actually implement get_module, without requiring a request.
Actually implement get_block, without requiring a request.
See get_module() docstring for further details.
See get_block() docstring for further details.
Arguments:
request_token (str): A unique token for this request, used to isolate xblock rendering
@@ -671,7 +669,7 @@ def get_module_for_descriptor_internal(user, descriptor, student_data, course_id
course_id=course_id,
track_function=track_function,
position=position,
wrap_xmodule_display=wrap_xmodule_display,
wrap_xblock_display=wrap_xblock_display,
grade_bucket_type=grade_bucket_type,
static_asset_path=static_asset_path,
user_location=user_location,
@@ -729,7 +727,7 @@ def load_single_xblock(request, user_id, course_id, usage_key_string, course=Non
modulestore().get_item(usage_key),
depth=0,
)
instance = get_module(
instance = get_block(
user,
request,
usage_key,
@@ -910,10 +908,10 @@ def _get_descriptor_by_usage_key(usage_key):
return descriptor, tracking_context
def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None,
will_recheck_access=False):
def get_block_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None,
will_recheck_access=False):
"""
Gets a module instance based on its `usage_id` in a course, for a given request/user
Gets a block instance based on its `usage_id` in a course, for a given request/user
Returns (instance, tracking_context)
"""
@@ -928,7 +926,7 @@ def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_inf
descriptor,
read_only=CrawlersConfig.is_crawler(request),
)
instance = get_module_for_descriptor(
instance = get_block_for_descriptor(
user,
request,
descriptor,
@@ -991,12 +989,12 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
handler_method = getattr(descriptor, handler, False)
will_recheck_access = handler_method and getattr(handler_method, 'will_recheck_access', False)
instance, tracking_context = get_module_by_usage_id(
instance, tracking_context = get_block_by_usage_id(
request, course_id, str(block_usage_key), course=course, will_recheck_access=will_recheck_access,
)
# Name the transaction so that we can view XBlock handlers separately in
# New Relic. The suffix is necessary for XModule handlers because the
# New Relic. The suffix is necessary for XBlock handlers because the
# "handler" in those cases is always just "xmodule_handler".
nr_tx_name = f"{instance.__class__.__name__}.{handler}"
nr_tx_name += f"/{suffix}" if (suffix and handler == "xmodule_handler") else ""
@@ -1025,12 +1023,12 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
raise Http404 # lint-amnesty, pylint: disable=raise-missing-from
# If we can't find the module, respond with a 404
# If we can't find the block, respond with a 404
except NotFoundError:
log.exception("Module indicating to user that request doesn't exist")
raise Http404 # lint-amnesty, pylint: disable=raise-missing-from
# For XModule-specific errors, we log the error and respond with an error message
# For XBlock-specific errors, we log the error and respond with an error message
except ProcessingError as err:
log.warning("Module encountered an error while processing AJAX call",
exc_info=True)
@@ -1067,7 +1065,7 @@ def xblock_view(request, course_id, usage_id, view_name):
with modulestore().bulk_operations(course_key):
course = modulestore().get_course(course_key)
instance, _ = get_module_by_usage_id(request, course_id, usage_id, course=course)
instance, _ = get_block_by_usage_id(request, course_id, usage_id, course=course)
try:
fragment = instance.render(view_name, context=request.GET)

View File

@@ -49,7 +49,7 @@ from lms.djangoapps.courseware.date_summary import (
from lms.djangoapps.courseware.exceptions import CourseAccessRedirect, CourseRunNotFound
from lms.djangoapps.courseware.masquerade import check_content_start_date_for_masquerade_user
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module
from lms.djangoapps.courseware.block_render import get_block
from lms.djangoapps.survey.utils import SurveyRequiredAccessError, check_survey_required_and_unanswered
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.enrollments.api import get_course_enrollment_details
@@ -370,22 +370,22 @@ def get_course_about_section(request, course, section_key):
# Use an empty cache
field_data_cache = FieldDataCache([], course.id, request.user)
about_module = get_module(
about_block = get_block(
request.user,
request,
loc,
field_data_cache,
log_if_not_found=False,
wrap_xmodule_display=False,
wrap_xblock_display=False,
static_asset_path=course.static_asset_path,
course=course
)
html = ''
if about_module is not None:
if about_block is not None:
try:
html = about_module.render(STUDENT_VIEW).content
html = about_block.render(STUDENT_VIEW).content
except Exception: # pylint: disable=broad-except
html = render_to_string('courseware/error-message.html', None)
log.exception(
@@ -406,14 +406,14 @@ def get_course_about_section(request, course, section_key):
def get_course_info_usage_key(course, section_key):
"""
Returns the usage key for the specified section's course info module.
Returns the usage key for the specified section's course info block.
"""
return course.id.make_usage_key('course_info', section_key)
def get_course_info_section_module(request, user, course, section_key):
def get_course_info_section_block(request, user, course, section_key):
"""
This returns the course info module for a given section_key.
This returns the course info block for a given section_key.
Valid keys:
- handouts
@@ -426,13 +426,13 @@ def get_course_info_section_module(request, user, course, section_key):
# Use an empty cache
field_data_cache = FieldDataCache([], course.id, user)
return get_module(
return get_block(
user,
request,
usage_key,
field_data_cache,
log_if_not_found=False,
wrap_xmodule_display=False,
wrap_xblock_display=False,
static_asset_path=course.static_asset_path,
course=course
)
@@ -449,12 +449,12 @@ def get_course_info_section(request, user, course, section_key):
- updates
- guest_updates
"""
info_module = get_course_info_section_module(request, user, course, section_key)
info_block = get_course_info_section_block(request, user, course, section_key)
html = ''
if info_module is not None:
if info_block is not None:
try:
html = info_module.render(STUDENT_VIEW).content.strip()
html = info_block.render(STUDENT_VIEW).content.strip()
except Exception: # pylint: disable=broad-except
html = render_to_string('courseware/error-message.html', None)
log.exception(
@@ -879,10 +879,10 @@ def get_problems_in_section(section):
return problem_descriptors
def get_current_child(xmodule, min_depth=None, requested_child=None):
def get_current_child(xblock, min_depth=None, requested_child=None):
"""
Get the xmodule.position's display item of an xmodule that has a position and
children. If xmodule has no position or is out of bounds, return the first
Get the xblock.position's display item of an xblock that has a position and
children. If xblock has no position or is out of bounds, return the first
child with children of min_depth.
For example, if chapter_one has no position set, with two child sections,
@@ -905,13 +905,13 @@ def get_current_child(xmodule, min_depth=None, requested_child=None):
else:
return children[0]
def _get_default_child_module(child_modules):
"""Returns the first child of xmodule, subject to min_depth."""
def _get_default_child_block(child_blocks):
"""Returns the first child of xblock, subject to min_depth."""
if min_depth is None or min_depth <= 0:
return _get_child(child_modules)
return _get_child(child_blocks)
else:
content_children = [
child for child in child_modules
child for child in child_blocks
if child.has_children_at_depth(min_depth - 1) and child.get_children()
]
return _get_child(content_children) if content_children else None
@@ -921,21 +921,21 @@ def get_current_child(xmodule, min_depth=None, requested_child=None):
try:
# In python 3, hasattr() catches AttributeErrors only then returns False.
# All other exceptions bubble up the call stack.
has_position = hasattr(xmodule, 'position') # This conditions returns AssertionError from xblock.fields lib.
has_position = hasattr(xblock, 'position') # This conditions returns AssertionError from xblock.fields lib.
except AssertionError:
return child
if has_position:
children = xmodule.get_children()
children = xblock.get_children()
if len(children) > 0:
if xmodule.position is not None and not requested_child:
pos = int(xmodule.position) - 1 # position is 1-indexed
if xblock.position is not None and not requested_child:
pos = int(xblock.position) - 1 # position is 1-indexed
if 0 <= pos < len(children):
child = children[pos]
if min_depth is not None and (min_depth > 0 and not child.has_children_at_depth(min_depth - 1)):
child = None
if child is None:
child = _get_default_child_module(children)
child = _get_default_child_block(children)
return child

View File

@@ -58,15 +58,15 @@ def user_has_passed_entrance_exam(user, course):
def get_entrance_exam_content(user, course):
"""
Get the entrance exam content information (ie, chapter module)
Get the entrance exam content information (ie, chapter block)
"""
required_content = get_required_content(course.id, user)
exam_module = None
exam_block = None
for content in required_content:
usage_key = UsageKey.from_string(content).map_into_course(course.id)
module_item = modulestore().get_item(usage_key)
if not module_item.hide_from_toc and module_item.is_entrance_exam:
exam_module = module_item
block = modulestore().get_item(usage_key)
if not block.hide_from_toc and block.is_entrance_exam:
exam_block = block
break
return exam_module
return exam_block

View File

@@ -9,7 +9,7 @@ base on membership of a student in a cohort, or similar. The use of an
extensible, modular architecture allows for overrides being done in ways not
envisioned by the authors.
Currently, this module is used in the `module_render` module in this same
Currently, this module is used in the `block_render` module in this same
package and is used to wrap the `authored_data` when constructing an
`LmsFieldData`. This means overrides will be in effect for all scopes covered
by `authored_data`, e.g. course content and settings stored in Mongo.

View File

@@ -1,16 +1,16 @@
"""
Dump the structure of a course as a JSON object.
The resulting JSON object has one entry for each module in the course:
The resulting JSON object has one entry for each block in the course:
{
"$module_url": {
"category": "$module_category",
"children": [$module_children_urls... ],
"metadata": {$module_metadata}
"$block_url": {
"category": "$block_category",
"children": [$block_children_urls... ],
"metadata": {$block_metadata}
},
"$module_url": ....
"$block_url": ....
...
}
@@ -73,30 +73,30 @@ class Command(BaseCommand): # lint-amnesty, pylint: disable=missing-class-docst
# Convert course data to dictionary and dump it as JSON to stdout
info = dump_module(course, inherited=options['inherited'], defaults=options['inherited_defaults'])
info = dump_block(course, inherited=options['inherited'], defaults=options['inherited_defaults'])
return json.dumps(info, indent=2, sort_keys=True, default=str)
def dump_module(module, destination=None, inherited=False, defaults=False):
def dump_block(block, destination=None, inherited=False, defaults=False):
"""
Add the module and all its children to the destination dictionary in
Add the block and all its children to the destination dictionary in
as a flat structure.
"""
destination = destination if destination else {}
items = own_metadata(module)
items = own_metadata(block)
# HACK: add discussion ids to list of items to export (AN-6696)
if isinstance(module, DiscussionXBlock) and 'discussion_id' not in items:
items['discussion_id'] = module.discussion_id
if isinstance(block, DiscussionXBlock) and 'discussion_id' not in items:
items['discussion_id'] = block.discussion_id
filtered_metadata = {k: v for k, v in items.items() if k not in FILTER_LIST}
destination[str(module.location)] = {
'category': module.location.block_type,
'children': [str(child) for child in getattr(module, 'children', [])],
destination[str(block.location)] = {
'category': block.location.block_type,
'children': [str(child) for child in getattr(block, 'children', [])],
'metadata': filtered_metadata,
}
@@ -116,10 +116,10 @@ def dump_module(module, destination=None, inherited=False, defaults=False):
else:
return field.values != field.default
inherited_metadata = {field.name: field.read_json(module) for field in module.fields.values() if is_inherited(field)} # lint-amnesty, pylint: disable=line-too-long
destination[str(module.location)]['inherited_metadata'] = inherited_metadata
inherited_metadata = {field.name: field.read_json(block) for field in block.fields.values() if is_inherited(field)} # lint-amnesty, pylint: disable=line-too-long
destination[str(block.location)]['inherited_metadata'] = inherited_metadata
for child in module.get_children():
dump_module(child, destination, inherited, defaults)
for child in block.get_children():
dump_block(child, destination, inherited, defaults)
return destination

View File

@@ -663,13 +663,13 @@ class UserInfoCache(DjangoOrmFieldCache):
class FieldDataCache:
"""
A cache of django model objects needed to supply the data
for a module and its descendants
for a block and its descendants
"""
def __init__(self, descriptors, course_id, user, asides=None, read_only=False):
"""
Find any courseware.models objects that are needed by any descriptor
in descriptors. Attempts to minimize the number of queries to the database.
Note: Only modules that have store_state = True or have shared
Note: Only blocks that have store_state = True or have shared
state will have a StudentModule.
Arguments
@@ -725,7 +725,7 @@ class FieldDataCache:
Arguments:
descriptor: An XModuleDescriptor
depth is the number of levels of descendant modules to load StudentModules for, in addition to
depth is the number of levels of descendant blocks to load StudentModules for, in addition to
the supplied descriptor. If depth is None, load all descendant StudentModules
descriptor_filter is a function that accepts a descriptor and return whether the field data
should be cached
@@ -767,7 +767,7 @@ class FieldDataCache:
course_id: the course in the context of which we want StudentModules.
user: the django user for whom to load modules.
descriptor: An XModuleDescriptor
depth is the number of levels of descendant modules to load StudentModules for, in addition to
depth is the number of levels of descendant blocks to load StudentModules for, in addition to
the supplied descriptor. If depth is None, load all descendant StudentModules
descriptor_filter is a function that accepts a descriptor and return whether the field data
should be cached

View File

@@ -340,14 +340,14 @@ class XBlockFieldBase(models.Model):
class XModuleUserStateSummaryField(XBlockFieldBase): # lint-amnesty, pylint: disable=model-no-explicit-unicode
"""
Stores data set in the Scope.user_state_summary scope by an xmodule field
Stores data set in the Scope.user_state_summary scope by an xblock field
"""
class Meta:
app_label = "courseware"
unique_together = (('usage_id', 'field_name'),)
# The definition id for the module
# The definition id for the block
usage_id = UsageKeyField(max_length=255, db_index=True)
@@ -360,7 +360,7 @@ class XModuleStudentPrefsField(XBlockFieldBase): # lint-amnesty, pylint: disabl
app_label = "courseware"
unique_together = (('student', 'module_type', 'field_name'),)
# The type of the module for these preferences
# The type of the block for these preferences
module_type = BlockTypeKeyField(max_length=64, db_index=True)
student = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE)

View File

@@ -1,5 +1,5 @@
"""
Test for lms courseware app, module render unit
Test for lms courseware app, block render unit
"""
@@ -67,14 +67,14 @@ from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.xblock_django.constants import ATTR_KEY_ANONYMOUS_USER_ID
from lms.djangoapps.badges.tests.factories import BadgeClassFactory
from lms.djangoapps.badges.tests.test_models import get_image
from lms.djangoapps.courseware import module_render as render
from lms.djangoapps.courseware import block_render as render
from lms.djangoapps.courseware.access_response import AccessResponse
from lms.djangoapps.courseware.courses import get_course_info_section, get_course_with_access
from lms.djangoapps.courseware.field_overrides import OverrideFieldData
from lms.djangoapps.courseware.masquerade import CourseMasquerade
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.courseware.module_render import get_module_for_descriptor, hash_resource
from lms.djangoapps.courseware.block_render import get_block_for_descriptor, hash_resource
from lms.djangoapps.courseware.tests.factories import StudentModuleFactory
from lms.djangoapps.courseware.tests.test_submitting_problems import TestSubmittingProblems
from lms.djangoapps.courseware.tests.tests import LoginEnrollmentTestCase
@@ -193,9 +193,9 @@ class XBlockWithoutCompletionAPI(XBlock):
@ddt.ddt
class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
class BlockRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Tests of courseware.module_render
Tests of courseware.block_render
"""
@classmethod
@@ -217,9 +217,9 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
self.mock_user.id = 1
self.request_factory = RequestFactoryNoCsrf()
# Construct a mock module for the modulestore to return
self.mock_module = MagicMock()
self.mock_module.id = 1
# Construct a mock block for the modulestore to return
self.mock_block = MagicMock()
self.mock_block.id = 1
self.dispatch = 'score_update'
# Construct a 'standard' xqueue_callback url
@@ -228,7 +228,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
kwargs=dict(
course_id=str(self.course_key),
userid=str(self.mock_user.id),
mod_id=self.mock_module.id,
mod_id=self.mock_block.id,
dispatch=self.dispatch
)
)
@@ -237,10 +237,10 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
OverrideFieldData.provider_classes = None
super().tearDown()
def test_get_module(self):
assert render.get_module('dummyuser', None, 'invalid location', None) is None
def test_get_block(self):
assert render.get_block('dummyuser', None, 'invalid location', None) is None
def test_module_render_with_jump_to_id(self):
def test_block_render_with_jump_to_id(self):
"""
This test validates that the /jump_to_id/<id> shorthand for intracourse linking works assertIn
expected. Note there's a HTML element in the 'toy' course with the url_name 'toyjumpto' which
@@ -254,7 +254,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course_key, self.mock_user, course, depth=2)
module = render.get_module(
block = render.get_block(
self.mock_user,
mock_request,
self.course_key.make_usage_key('html', 'toyjumpto'),
@@ -262,7 +262,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
)
# get the rendered HTML output which should have the rewritten link
html = module.render(STUDENT_VIEW).content
html = block.render(STUDENT_VIEW).content
# See if the url got rewritten to the target link
# note if the URL mapping changes then this assertion will break
@@ -279,22 +279,22 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
'xqueue_body': 'hello world',
}
# Patch getmodule to return our mock module
with patch('lms.djangoapps.courseware.module_render.load_single_xblock', return_value=self.mock_module):
# Patch getmodule to return our mock block
with patch('lms.djangoapps.courseware.block_render.load_single_xblock', return_value=self.mock_block):
# call xqueue_callback with our mocked information
request = self.request_factory.post(self.callback_url, data)
render.xqueue_callback(
request,
str(self.course_key),
self.mock_user.id,
self.mock_module.id,
self.mock_block.id,
self.dispatch
)
# Verify that handle ajax is called with the correct data
request.POST._mutable = True # lint-amnesty, pylint: disable=protected-access
request.POST['queuekey'] = fake_key
self.mock_module.handle_ajax.assert_called_once_with(self.dispatch, request.POST)
self.mock_block.handle_ajax.assert_called_once_with(self.dispatch, request.POST)
def test_xqueue_callback_missing_header_info(self):
data = {
@@ -302,7 +302,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
'xqueue_body': 'hello world',
}
with patch('lms.djangoapps.courseware.module_render.load_single_xblock', return_value=self.mock_module):
with patch('lms.djangoapps.courseware.block_render.load_single_xblock', return_value=self.mock_block):
# Test with missing xqueue data
with pytest.raises(Http404):
request = self.request_factory.post(self.callback_url, {})
@@ -310,7 +310,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
request,
str(self.course_key),
self.mock_user.id,
self.mock_module.id,
self.mock_block.id,
self.dispatch
)
@@ -321,7 +321,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
request,
str(self.course_key),
self.mock_user.id,
self.mock_module.id,
self.mock_block.id,
self.dispatch
)
@@ -413,9 +413,9 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
course = CourseFactory()
descriptor = BlockFactory(category=block_type, parent=course)
field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user)
# This is verifying that caching doesn't cause an error during get_module_for_descriptor, which
# This is verifying that caching doesn't cause an error during get_block_for_descriptor, which
# is why it calls the method twice identically.
render.get_module_for_descriptor(
render.get_block_for_descriptor(
self.mock_user,
request,
descriptor,
@@ -423,7 +423,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
self.toy_course.id,
course=self.toy_course
)
render.get_module_for_descriptor(
render.get_block_for_descriptor(
self.mock_user,
request,
descriptor,
@@ -478,7 +478,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
# grab what _field_data was originally set to
original_field_data = descriptor._field_data # lint-amnesty, pylint: disable=no-member, protected-access
render.get_module_for_descriptor(
render.get_block_for_descriptor(
self.mock_user, request, descriptor, field_data_cache, course.id, course=course
)
@@ -488,9 +488,9 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
assert descriptor._unwrapped_field_data is original_field_data # lint-amnesty, pylint: disable=no-member
assert descriptor._unwrapped_field_data is not descriptor._field_data # lint-amnesty, pylint: disable=no-member
# now bind this module to a few other students
# now bind this block to a few other students
for user in [UserFactory(), UserFactory(), self.mock_user]:
render.get_module_for_descriptor(
render.get_block_for_descriptor(
user,
request,
descriptor,
@@ -537,9 +537,9 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
self.mock_user = UserFactory.create()
self.request_factory = RequestFactoryNoCsrf()
# Construct a mock module for the modulestore to return
self.mock_module = MagicMock()
self.mock_module.id = 1
# Construct a mock block for the modulestore to return
self.mock_block = MagicMock()
self.mock_block.id = 1
self.dispatch = 'score_update'
# Construct a 'standard' xqueue_callback url
@@ -547,7 +547,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
'xqueue_callback', kwargs={
'course_id': str(self.course_key),
'userid': str(self.mock_user.id),
'mod_id': self.mock_module.id,
'mod_id': self.mock_block.id,
'dispatch': self.dispatch
}
)
@@ -650,7 +650,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
request.user = self.mock_user
assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': ('Submission aborted! Your file "%s" is too large (max size: %d MB)' % (inputfile.name, (settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))))}, indent=2) # pylint: disable=line-too-long
def test_xmodule_dispatch(self):
def test_xblock_dispatch(self):
request = self.request_factory.post('dummy_url', data={'position': 1})
request.user = self.mock_user
response = render.handle_xblock_callback(
@@ -686,7 +686,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
'goto_position',
)
def test_bad_xmodule_dispatch(self):
def test_bad_xblock_dispatch(self):
request = self.request_factory.post('dummy_url')
request.user = self.mock_user
with pytest.raises(Http404):
@@ -803,12 +803,12 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
)
with patch(
'lms.djangoapps.courseware.module_render.is_xblock_aside',
'lms.djangoapps.courseware.block_render.is_xblock_aside',
return_value=is_xblock_aside
), patch(
'lms.djangoapps.courseware.module_render.get_aside_from_xblock'
'lms.djangoapps.courseware.block_render.get_aside_from_xblock'
) as mocked_get_aside_from_xblock, patch(
'lms.djangoapps.courseware.module_render.webob_to_django_response'
'lms.djangoapps.courseware.block_render.webob_to_django_response'
) as mocked_webob_to_django_response:
render.handle_xblock_callback(
request,
@@ -833,7 +833,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
request.user = self.mock_user
with patch(
'lms.djangoapps.courseware.module_render.is_xblock_aside',
'lms.djangoapps.courseware.block_render.is_xblock_aside',
return_value=True
), self.assertRaises(Http404):
render.handle_xblock_callback(
@@ -925,7 +925,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
('goto_position', False), # does not set it
)
@ddt.unpack
@patch('lms.djangoapps.courseware.module_render.get_module_for_descriptor', wraps=get_module_for_descriptor)
@patch('lms.djangoapps.courseware.block_render.get_block_for_descriptor', wraps=get_block_for_descriptor)
def test_will_recheck_access_handler_attribute(self, handler, will_recheck_access, mock_get_module):
"""Confirm that we pay attention to any 'will_recheck_access' attributes on handler methods"""
course = CourseFactory.create()
@@ -1320,14 +1320,14 @@ class TestProctoringRendering(ModuleStoreTestCase):
'ICRV1'
)
module = render.get_module(
block = render.get_block(
self.request.user,
self.request,
usage_key,
self.field_data_cache,
wrap_xmodule_display=True,
wrap_xblock_display=True,
)
content = module.render(STUDENT_VIEW).content
content = block.render(STUDENT_VIEW).content
assert expected in content
@@ -1515,49 +1515,49 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.descriptor
)
def test_xmodule_display_wrapper_enabled(self):
module = render.get_module(
def test_xblock_display_wrapper_enabled(self):
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
wrap_xmodule_display=True,
wrap_xblock_display=True,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert len(PyQuery(result_fragment.content)('div.xblock.xblock-student_view.xmodule_HtmlBlock')) == 1
def test_xmodule_display_wrapper_disabled(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
wrap_xmodule_display=False,
wrap_xblock_display=False,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'div class="xblock xblock-student_view xmodule_display xmodule_HtmlBlock"' not in result_fragment.content
def test_static_link_rewrite(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
key = self.course.location
assert f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block/foo_content' in result_fragment.content
def test_static_badlink_rewrite(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
key = self.course.location
assert f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block/file.jpg' in result_fragment.content
@@ -1568,14 +1568,14 @@ class TestHtmlModifiers(ModuleStoreTestCase):
static_asset_path is set as an lms kv in course. That should make static paths
not be mangled (ie not changed to c4x://).
'''
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
static_asset_path="toy_course_dir",
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'href="/static/toy_course_dir' in result_fragment.content
def test_course_image(self):
@@ -1606,13 +1606,13 @@ class TestHtmlModifiers(ModuleStoreTestCase):
# at least this makes sure get_course_info_section returns without exception
def test_course_link_rewrite(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert f'/courses/{str(self.course.id)}/bar/content' in result_fragment.content
@@ -1651,7 +1651,7 @@ class JsonInitDataTest(ModuleStoreTestCase):
course = CourseFactory()
descriptor = BlockFactory(category='withjson', parent=course)
field_data_cache = FieldDataCache([course, descriptor], course.id, mock_user)
module = render.get_module_for_descriptor(
block = render.get_block_for_descriptor(
mock_user,
mock_request,
descriptor,
@@ -1659,7 +1659,7 @@ class JsonInitDataTest(ModuleStoreTestCase):
course.id,
course=course
)
html = module.render(STUDENT_VIEW).content
html = block.render(STUDENT_VIEW).content
assert json_output in html
# No matter what data goes in, there should only be one close-script tag.
assert html.count('</script>') == 1
@@ -1680,7 +1680,7 @@ class DetachedXBlock(XBlock):
@patch.dict('django.conf.settings.FEATURES', {'DISPLAY_DEBUG_INFO_TO_STAFF': True, 'DISPLAY_HISTOGRAMS_TO_STAFF': True})
@patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True))
@patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True))
class TestStaffDebugInfo(SharedModuleStoreTestCase):
"""Tests to verify that Staff Debug Info panel and histograms are displayed to staff."""
MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
@@ -1719,23 +1719,23 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
@patch.dict('django.conf.settings.FEATURES', {'DISPLAY_DEBUG_INFO_TO_STAFF': False})
def test_staff_debug_info_disabled(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'Staff Debug' not in result_fragment.content
def test_staff_debug_info_enabled(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'Staff Debug' in result_fragment.content
def test_staff_debug_info_score_for_invalid_dropdown(self):
@@ -1761,13 +1761,13 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
category='problem',
data=problem_xml
)
module = render.get_module(
block = render.get_block(
self.user,
self.request,
problem_descriptor.location,
self.field_data_cache
)
html_fragment = module.render(STUDENT_VIEW)
html_fragment = block.render(STUDENT_VIEW)
expected_score_override_html = textwrap.dedent("""<div>
<label for="sd_fs_{block_id}">Score (for override only):</label>
<input type="text" tabindex="0" id="sd_fs_{block_id}" placeholder="0"/>
@@ -1790,28 +1790,28 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
self.user,
descriptor
)
module = render.get_module(
block = render.get_block(
self.user,
self.request,
descriptor.location,
field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'Staff Debug' not in result_fragment.content
@patch.dict('django.conf.settings.FEATURES', {'DISPLAY_HISTOGRAMS_TO_STAFF': False})
def test_histogram_disabled(self):
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
result_fragment = module.render(STUDENT_VIEW)
result_fragment = block.render(STUDENT_VIEW)
assert 'histrogram' not in result_fragment.content
def test_histogram_enabled_for_unscored_xmodules(self):
"""Histograms should not display for xmodules which are not scored."""
def test_histogram_enabled_for_unscored_xblocks(self):
"""Histograms should not display for xblocks which are not scored."""
html_descriptor = BlockFactory.create(
category='html',
@@ -1824,17 +1824,17 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
)
with patch('openedx.core.lib.xblock_utils.grade_histogram') as mock_grade_histogram:
mock_grade_histogram.return_value = []
module = render.get_module(
block = render.get_block(
self.user,
self.request,
html_descriptor.location,
field_data_cache,
)
module.render(STUDENT_VIEW)
block.render(STUDENT_VIEW)
assert not mock_grade_histogram.called
def test_histogram_enabled_for_scored_xmodules(self):
"""Histograms should display for xmodules which are scored."""
def test_histogram_enabled_for_scored_xblocks(self):
"""Histograms should display for xblocks which are scored."""
StudentModuleFactory.create(
course_id=self.course.id,
@@ -1846,13 +1846,13 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
)
with patch('openedx.core.lib.xblock_utils.grade_histogram') as mock_grade_histogram:
mock_grade_histogram.return_value = []
module = render.get_module(
block = render.get_block(
self.user,
self.request,
self.location,
self.field_data_cache,
)
module.render(STUDENT_VIEW)
block.render(STUDENT_VIEW)
assert mock_grade_histogram.called
@@ -1885,7 +1885,7 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
super().setUp()
self.user = UserFactory()
@patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True))
@patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True))
def _get_anonymous_id(self, course_id, xblock_class): # lint-amnesty, pylint: disable=missing-function-docstring
location = course_id.make_usage_key('dummy_category', 'dummy_name')
descriptor = Mock(
@@ -1913,16 +1913,16 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
if hasattr(xblock_class, 'module_class'):
descriptor.module_class = xblock_class.module_class
module = render.get_module_for_descriptor_internal(
block = render.get_block_for_descriptor_internal(
user=self.user,
descriptor=descriptor,
student_data=Mock(spec=FieldData, name='student_data'),
course_id=course_id,
track_function=Mock(name='track_function'), # Track Function
track_function=Mock(name='track_function'), # Track Function
request_token='request_token',
course=self.course,
)
current_user = module.xmodule_runtime.service(module, 'user').get_current_user()
current_user = block.xmodule_runtime.service(block, 'user').get_current_user()
return current_user.opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID)
@ddt.data(*PER_STUDENT_ANONYMIZED_XBLOCKS)
@@ -1970,8 +1970,8 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
def test_context_contains_display_name(self, mock_tracker):
problem_display_name = 'Option Response Problem'
module_info = self.handle_callback_and_get_module_info(mock_tracker, problem_display_name)
assert problem_display_name == module_info['display_name']
block_info = self.handle_callback_and_get_block_info(mock_tracker, problem_display_name)
assert problem_display_name == block_info['display_name']
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
@patch('xmodule.modulestore.mongo.base.CachingDescriptorSystem.applicable_aside_types',
@@ -2009,7 +2009,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
problem_display_name=None,
call_idx=0):
"""
Creates a fake module, invokes the callback and extracts the 'context'
Creates a fake block, invokes the callback and extracts the 'context'
metadata from the emitted problem_check event.
"""
@@ -2022,7 +2022,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
descriptor = BlockFactory.create(**descriptor_kwargs)
mock_tracker_for_context = MagicMock()
with patch('lms.djangoapps.courseware.module_render.tracker', mock_tracker_for_context), patch(
with patch('lms.djangoapps.courseware.block_render.tracker', mock_tracker_for_context), patch(
'xmodule.services.tracker', mock_tracker_for_context
):
render.handle_xblock_callback(
@@ -2045,9 +2045,9 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
return context
def handle_callback_and_get_module_info(self, mock_tracker, problem_display_name=None):
def handle_callback_and_get_block_info(self, mock_tracker, problem_display_name=None):
"""
Creates a fake module, invokes the callback and extracts the 'module'
Creates a fake block, invokes the callback and extracts the 'block'
metadata from the emitted problem_check event.
"""
event = self.handle_callback_and_get_context_info(
@@ -2056,7 +2056,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
return event['module']
def test_missing_display_name(self, mock_tracker):
actual_display_name = self.handle_callback_and_get_module_info(mock_tracker)['display_name']
actual_display_name = self.handle_callback_and_get_block_info(mock_tracker)['display_name']
assert actual_display_name.startswith('problem')
def test_library_source_information(self, mock_tracker):
@@ -2072,14 +2072,14 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
return original_usage_key, original_usage_version
with patch('xmodule.modulestore.mixed.MixedModuleStore.get_block_original_usage', _mock_get_original_usage):
module_info = self.handle_callback_and_get_module_info(mock_tracker)
assert 'original_usage_key' in module_info
assert module_info['original_usage_key'] == str(original_usage_key)
assert 'original_usage_version' in module_info
assert module_info['original_usage_version'] == str(original_usage_version)
block_info = self.handle_callback_and_get_block_info(mock_tracker)
assert 'original_usage_key' in block_info
assert block_info['original_usage_key'] == str(original_usage_key)
assert 'original_usage_version' in block_info
assert block_info['original_usage_version'] == str(original_usage_version)
class TestXmoduleRuntimeEvent(TestSubmittingProblems):
class TestXBlockRuntimeEvent(TestSubmittingProblems):
"""
Inherit from TestSubmittingProblems to get functionality that set up a course and problems structure
"""
@@ -2091,37 +2091,37 @@ class TestXmoduleRuntimeEvent(TestSubmittingProblems):
self.grade_dict = {'value': 0.18, 'max_value': 32}
self.delete_dict = {'value': None, 'max_value': None}
def get_module_for_user(self, user):
"""Helper function to get useful module at self.location in self.course_id for user"""
def get_block_for_user(self, user):
"""Helper function to get useful block at self.location in self.course_id for user"""
mock_request = MagicMock()
mock_request.user = user
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course.id, user, self.course, depth=2)
return render.get_module(
return render.get_block(
user,
mock_request,
self.problem.location,
field_data_cache,
)
def set_module_grade_using_publish(self, grade_dict):
def set_block_grade_using_publish(self, grade_dict):
"""Publish the user's grade, takes grade_dict as input"""
module = self.get_module_for_user(self.student_user)
module.system.publish(module, 'grade', grade_dict)
return module
block = self.get_block_for_user(self.student_user)
block.system.publish(block, 'grade', grade_dict)
return block
def test_xmodule_runtime_publish(self):
def test_xblock_runtime_publish(self):
"""Tests the publish mechanism"""
self.set_module_grade_using_publish(self.grade_dict)
self.set_block_grade_using_publish(self.grade_dict)
student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location)
assert student_module.grade == self.grade_dict['value']
assert student_module.max_grade == self.grade_dict['max_value']
def test_xmodule_runtime_publish_delete(self):
def test_xblock_runtime_publish_delete(self):
"""Test deleting the grade using the publish mechanism"""
module = self.set_module_grade_using_publish(self.grade_dict)
module.system.publish(module, 'grade', self.delete_dict)
block = self.set_block_grade_using_publish(self.grade_dict)
block.system.publish(block, 'grade', self.delete_dict)
student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location)
assert student_module.grade is None
assert student_module.max_grade is None
@@ -2130,7 +2130,7 @@ class TestXmoduleRuntimeEvent(TestSubmittingProblems):
def test_score_change_signal(self, send_mock):
"""Test that a Django signal is generated when a score changes"""
with freeze_time(datetime.now().replace(tzinfo=pytz.UTC)):
self.set_module_grade_using_publish(self.grade_dict)
self.set_block_grade_using_publish(self.grade_dict)
expected_signal_kwargs = {
'sender': None,
'raw_possible': self.grade_dict['max_value'],
@@ -2148,9 +2148,9 @@ class TestXmoduleRuntimeEvent(TestSubmittingProblems):
send_mock.assert_called_with(**expected_signal_kwargs)
class TestRebindModule(TestSubmittingProblems):
class TestRebindBlock(TestSubmittingProblems):
"""
Tests to verify the functionality of rebinding a module.
Tests to verify the functionality of rebinding a block.
Inherit from TestSubmittingProblems to get functionality that set up a course structure
"""
@@ -2162,8 +2162,8 @@ class TestRebindModule(TestSubmittingProblems):
self.user = UserFactory.create()
self.anon_user = AnonymousUser()
def get_module_for_user(self, user, item=None):
"""Helper function to get useful module at self.location in self.course_id for user"""
def get_block_for_user(self, user, item=None):
"""Helper function to get useful block at self.location in self.course_id for user"""
mock_request = MagicMock()
mock_request.user = user
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
@@ -2172,57 +2172,57 @@ class TestRebindModule(TestSubmittingProblems):
if item is None:
item = self.lti
return render.get_module(
return render.get_block(
user,
mock_request,
item.location,
field_data_cache,
)
def test_rebind_module_to_new_users(self):
module = self.get_module_for_user(self.user, self.problem)
def test_rebind_block_to_new_users(self):
block = self.get_block_for_user(self.user, self.problem)
# Bind the module to another student, which will remove "correct_map"
# from the module's _field_data_cache and _dirty_fields.
# Bind the block to another student, which will remove "correct_map"
# from the block's _field_data_cache and _dirty_fields.
user2 = UserFactory.create()
module.bind_for_student(module.system, user2.id)
block.bind_for_student(block.system, user2.id)
# XBlock's save method assumes that if a field is in _dirty_fields,
# then it's also in _field_data_cache. If this assumption
# doesn't hold, then we get an error trying to bind this module
# doesn't hold, then we get an error trying to bind this block
# to a third student, since we've removed "correct_map" from
# _field_data cache, but not _dirty_fields, when we bound
# this module to the second student. (TNL-2640)
# this block to the second student. (TNL-2640)
user3 = UserFactory.create()
module.bind_for_student(module.system, user3.id)
block.bind_for_student(block.system, user3.id)
def test_rebind_noauth_module_to_user_not_anonymous(self):
def test_rebind_noauth_block_to_user_not_anonymous(self):
"""
Tests that an exception is thrown when rebind_noauth_module_to_user is run from a
module bound to a real user
Tests that an exception is thrown when rebind_noauth_block_to_user is run from a
block bound to a real user
"""
module = self.get_module_for_user(self.user)
block = self.get_block_for_user(self.user)
user2 = UserFactory()
user2.id = 2
with self.assertRaisesRegex(
RebindUserServiceError,
"rebind_noauth_module_to_user can only be called from a module bound to an anonymous user"
):
assert module.runtime.service(module, 'rebind_user').rebind_noauth_module_to_user(module, user2)
assert block.runtime.service(block, 'rebind_user').rebind_noauth_module_to_user(block, user2)
def test_rebind_noauth_module_to_user_anonymous(self):
def test_rebind_noauth_block_to_user_anonymous(self):
"""
Tests that get_user_module_for_noauth succeeds when rebind_noauth_module_to_user is run from a
module bound to AnonymousUser
Tests that get_user_block_for_noauth succeeds when rebind_noauth_block_to_user is run from a
block bound to AnonymousUser
"""
module = self.get_module_for_user(self.anon_user)
block = self.get_block_for_user(self.anon_user)
user2 = UserFactory()
user2.id = 2
module.runtime.service(module, 'rebind_user').rebind_noauth_module_to_user(module, user2)
assert module
assert module.system.anonymous_student_id == anonymous_id_for_user(user2, self.course.id)
assert module.scope_ids.user_id == user2.id
assert module.scope_ids.user_id == user2.id
block.runtime.service(block, 'rebind_user').rebind_noauth_module_to_user(block, user2)
assert block
assert block.system.anonymous_student_id == anonymous_id_for_user(user2, self.course.id)
assert block.scope_ids.user_id == user2.id
assert block.scope_ids.user_id == user2.id
@ddt.ddt
@@ -2249,7 +2249,7 @@ class TestEventPublishing(ModuleStoreTestCase, LoginEnrollmentTestCase):
course = CourseFactory()
descriptor = BlockFactory(category='xblock', parent=course)
field_data_cache = FieldDataCache([course, descriptor], course.id, self.mock_user)
block = render.get_module(self.mock_user, request, descriptor.location, field_data_cache)
block = render.get_block(self.mock_user, request, descriptor.location, field_data_cache)
event_type = 'event_type'
event = {'event': 'data'}
@@ -2477,7 +2477,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
self.users = {number: UserFactory() for number in USER_NUMBERS}
self._old_has_access = render.has_access
patcher = patch('lms.djangoapps.courseware.module_render.has_access', self._has_access)
patcher = patch('lms.djangoapps.courseware.block_render.has_access', self._has_access)
patcher.start()
self.addCleanup(patcher.stop)
@@ -2497,7 +2497,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
@ddt.data(*USER_NUMBERS)
@XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock')
def test_unbound_then_bound_as_xmodule(self, user_number):
def test_unbound_then_bound_as_xblock(self, user_number):
user = self.users[user_number]
block = self._load_block()
self.assertUnboundChildren(block)
@@ -2514,7 +2514,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
@ddt.data(*USER_NUMBERS)
@XBlock.register_temp_plugin(PureXBlockWithChildren, identifier='xblock')
def test_bound_only_as_xmodule(self, user_number):
def test_bound_only_as_xblock(self, user_number):
user = self.users[user_number]
block = self._load_block()
self._bind_block(block, user)
@@ -2546,7 +2546,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
user,
block,
)
return get_module_for_descriptor(
return get_block_for_descriptor(
user,
Mock(name='request', user=user),
block,
@@ -2688,7 +2688,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
"""
assert getattr(self.runtime, attribute) == expected_value
@patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True))
@patch('lms.djangoapps.courseware.block_render.has_access', Mock(return_value=True, autospec=True))
def test_user_is_staff(self):
runtime, _ = render.get_module_system_for_user(
self.user,
@@ -2702,7 +2702,7 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
assert runtime.user_is_staff
assert runtime.get_user_role() == 'student'
@patch('lms.djangoapps.courseware.module_render.get_user_role', Mock(return_value='instructor', autospec=True))
@patch('lms.djangoapps.courseware.block_render.get_user_role', Mock(return_value='instructor', autospec=True))
def test_get_user_role(self):
runtime, _ = render.get_module_system_for_user(
self.user,
@@ -2885,5 +2885,5 @@ class LmsModuleSystemShimTest(SharedModuleStoreTestCase):
def test_course_id(self):
descriptor = BlockFactory(category="pure", parent=self.course)
block = render.get_module(self.user, Mock(), descriptor.location, None)
block = render.get_block(self.user, Mock(), descriptor.location, None)
assert str(block.runtime.course_id) == self.COURSE_ID

View File

@@ -39,7 +39,7 @@ from lms.djangoapps.courseware.courses import (
get_current_child
)
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException
from openedx.core.djangolib.testing.utils import get_mock_request
from openedx.core.lib.courses import course_image_url
@@ -162,21 +162,21 @@ class CoursesTest(ModuleStoreTestCase):
expected_courses, f'testing get_courses with filter_={filter_}'
def test_get_current_child(self):
mock_xmodule = mock.MagicMock()
assert get_current_child(mock_xmodule) is None
mock_xblock = mock.MagicMock()
assert get_current_child(mock_xblock) is None
mock_xmodule.position = -1
mock_xmodule.get_children.return_value = ['one', 'two', 'three']
assert get_current_child(mock_xmodule) == 'one'
mock_xblock.position = -1
mock_xblock.get_children.return_value = ['one', 'two', 'three']
assert get_current_child(mock_xblock) == 'one'
mock_xmodule.position = 2
assert get_current_child(mock_xmodule) == 'two'
assert get_current_child(mock_xmodule, requested_child='first') == 'one'
assert get_current_child(mock_xmodule, requested_child='last') == 'three'
mock_xblock.position = 2
assert get_current_child(mock_xblock) == 'two'
assert get_current_child(mock_xblock, requested_child='first') == 'one'
assert get_current_child(mock_xblock, requested_child='last') == 'three'
mock_xmodule.position = 3
mock_xmodule.get_children.return_value = []
assert get_current_child(mock_xmodule) is None
mock_xblock.position = 3
mock_xblock.get_children.return_value = []
assert get_current_child(mock_xblock) is None
class ModuleStoreBranchSettingTest(ModuleStoreTestCase):
@@ -287,8 +287,8 @@ class CoursesRenderTest(ModuleStoreTestCase):
"<a href='/asset-v1:edX+toy+2012_Fall+type@asset+block/handouts_sample_handout.txt'>Sample</a>"
# Test when render raises an exception
with mock.patch('lms.djangoapps.courseware.courses.get_module') as mock_module_render:
mock_module_render.return_value = mock.MagicMock(
with mock.patch('lms.djangoapps.courseware.courses.get_block') as mock_block_render:
mock_block_render.return_value = mock.MagicMock(
render=mock.Mock(side_effect=Exception('Render failed!'))
)
course_info = get_course_info_section(self.request, self.request.user, self.course, 'handouts')
@@ -301,8 +301,8 @@ class CoursesRenderTest(ModuleStoreTestCase):
assert course_about == 'A course about toys.'
# Test when render raises an exception
with mock.patch('lms.djangoapps.courseware.courses.get_module') as mock_module_render:
mock_module_render.return_value = mock.MagicMock(
with mock.patch('lms.djangoapps.courseware.courses.get_block') as mock_block_render:
mock_block_render.return_value = mock.MagicMock(
render=mock.Mock(side_effect=Exception('Render failed!'))
)
course_about = get_course_about_section(self.request, self.course, 'short_description')
@@ -385,7 +385,7 @@ class CourseInstantiationTests(ModuleStoreTestCase):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course.id, self.user, course, depth=course_depth
)
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
self.user,
fake_request,
course,

View File

@@ -21,7 +21,7 @@ from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE,
from xmodule.modulestore.tests.factories import BlockFactory, ToyCourseFactory
from lms.djangoapps.course_api.blocks.tests.helpers import deserialize_usage_key
from lms.djangoapps.courseware.module_render import get_module_for_descriptor_internal
from lms.djangoapps.courseware.block_render import get_block_for_descriptor_internal
from lms.djangoapps.courseware.tests.helpers import XModuleRenderingTestBase
from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
@@ -294,7 +294,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
"""
Test rendered DiscussionXBlock permissions.
"""
discussion_xblock = get_module_for_descriptor_internal(
discussion_xblock = get_block_for_descriptor_internal(
user=self.user,
descriptor=self.discussion,
student_data=mock.Mock(name='student_data'),
@@ -337,7 +337,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
assert orphan_sequential.location.block_id == root.location.block_id
# Get xblock bound to a user and a descriptor.
discussion_xblock = get_module_for_descriptor_internal(
discussion_xblock = get_block_for_descriptor_internal(
user=self.user,
descriptor=discussion,
student_data=mock.Mock(name='student_data'),
@@ -387,7 +387,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
provider_type=Provider.OPEN_EDX,
)
discussion_xblock = get_module_for_descriptor_internal(
discussion_xblock = get_block_for_descriptor_internal(
user=self.user,
descriptor=self.discussion,
student_data=mock.Mock(name='student_data'),
@@ -437,7 +437,7 @@ class TestXBlockQueryLoad(SharedModuleStoreTestCase):
num_queries = 6
for discussion in discussions:
discussion_xblock = get_module_for_descriptor_internal(
discussion_xblock = get_block_for_descriptor_internal(
user=user,
descriptor=discussion,
student_data=mock.Mock(name='student_data'),

View File

@@ -17,7 +17,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory
from xmodule.capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module, handle_xblock_callback, toc_for_course
from lms.djangoapps.courseware.block_render import get_block, handle_xblock_callback, toc_for_course
from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase
from openedx.core.djangolib.testing.utils import get_mock_request
from common.djangoapps.student.models import CourseEnrollment
@@ -378,13 +378,13 @@ def answer_entrance_exam_problem(course, request, problem, user=None, value=1, m
course,
depth=2
)
module = get_module(
block = get_block(
user,
request,
problem.scope_ids.usage_id,
field_data_cache,
)
module.system.publish(problem, 'grade', grade_dict)
block.system.publish(problem, 'grade', grade_dict)
def add_entrance_exam_milestone(course, entrance_exam):

View File

@@ -10,7 +10,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory
from xmodule.partitions.partitions import Group, UserPartition
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
@@ -314,7 +314,7 @@ class SplitTestPosition(SharedModuleStoreTestCase):
def test_changing_position_works(self):
# Make a mock FieldDataCache for this course, so we can get the course block
mock_field_data_cache = FieldDataCache([self.course], self.course.id, self.student)
course = get_module_for_descriptor(
course = get_block_for_descriptor(
self.student,
MagicMock(name='request'),
self.course,

View File

@@ -280,8 +280,8 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
assert 'static_tab' in tab_content
# Test when render raises an exception
with patch('lms.djangoapps.courseware.views.views.get_module') as mock_module_render:
mock_module_render.return_value = MagicMock(
with patch('lms.djangoapps.courseware.views.views.get_block') as mock_block_render:
mock_block_render.return_value = MagicMock(
render=Mock(side_effect=Exception('Render failed!'))
)
static_tab_content = get_static_tab_fragment(request, course, tab).content

View File

@@ -1188,7 +1188,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
@ddt.ddt
class TestVideoBlockInitialization(BaseTestVideoXBlock):
"""
Make sure that module initialization works correctly.
Make sure that block initialization works correctly.
"""
CATEGORY = "video"
DATA = SOURCE_XML

View File

@@ -70,7 +70,7 @@ from lms.djangoapps.commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.utils import EcommerceService
from lms.djangoapps.courseware.access_utils import check_course_open_for_learner
from lms.djangoapps.courseware.model_data import FieldDataCache, set_score
from lms.djangoapps.courseware.module_render import get_module, handle_xblock_callback
from lms.djangoapps.courseware.block_render import get_block, handle_xblock_callback
from lms.djangoapps.courseware.tests.factories import StudentModuleFactory
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin, get_expiration_banner_text, set_preview_mode
from lms.djangoapps.courseware.testutils import RenderXBlockTestMixin
@@ -194,46 +194,46 @@ class TestJumpTo(ModuleStoreTestCase):
assert response.url == expected_redirect_url
@set_preview_mode(True)
def test_jump_to_legacy_from_module(self):
def test_jump_to_legacy_from_block(self):
with self.store.default_store(ModuleStoreEnum.Type.split):
course = CourseFactory.create()
chapter = BlockFactory.create(category='chapter', parent_location=course.location)
sequence = BlockFactory.create(category='sequential', parent_location=chapter.location)
vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.location)
vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.location)
module1 = BlockFactory.create(category='html', parent_location=vertical1.location)
module2 = BlockFactory.create(category='html', parent_location=vertical2.location)
block1 = BlockFactory.create(category='html', parent_location=vertical1.location)
block2 = BlockFactory.create(category='html', parent_location=vertical2.location)
activate_block_id = urlencode({'activate_block_id': str(module1.location)})
activate_block_id = urlencode({'activate_block_id': str(block1.location)})
expected_redirect_url = (
f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/1?{activate_block_id}'
)
jumpto_url = f'/courses/{course.id}/jump_to/{module1.location}'
jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}'
response = self.client.get(jumpto_url)
self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302)
activate_block_id = urlencode({'activate_block_id': str(module2.location)})
activate_block_id = urlencode({'activate_block_id': str(block2.location)})
expected_redirect_url = (
f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/2?{activate_block_id}'
)
jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}'
jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}'
response = self.client.get(jumpto_url)
self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302)
@set_preview_mode(False)
def test_jump_to_mfe_from_module(self):
def test_jump_to_mfe_from_block(self):
course = CourseFactory.create()
chapter = BlockFactory.create(category='chapter', parent_location=course.location)
sequence = BlockFactory.create(category='sequential', parent_location=chapter.location)
vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.location)
vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.location)
module1 = BlockFactory.create(category='html', parent_location=vertical1.location)
module2 = BlockFactory.create(category='html', parent_location=vertical2.location)
block1 = BlockFactory.create(category='html', parent_location=vertical1.location)
block2 = BlockFactory.create(category='html', parent_location=vertical2.location)
expected_redirect_url = (
f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical1.location}'
)
jumpto_url = f'/courses/{course.id}/jump_to/{module1.location}'
jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}'
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
@@ -241,7 +241,7 @@ class TestJumpTo(ModuleStoreTestCase):
expected_redirect_url = (
f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical2.location}'
)
jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}'
jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}'
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
@@ -249,7 +249,7 @@ class TestJumpTo(ModuleStoreTestCase):
# The new courseware experience does not support this sort of course structure;
# it assumes a simple course->chapter->sequence->unit->component tree.
@set_preview_mode(True)
def test_jump_to_legacy_from_nested_module(self):
def test_jump_to_legacy_from_nested_block(self):
with self.store.default_store(ModuleStoreEnum.Type.split):
course = CourseFactory.create()
chapter = BlockFactory.create(category='chapter', parent_location=course.location)
@@ -257,17 +257,17 @@ class TestJumpTo(ModuleStoreTestCase):
vertical = BlockFactory.create(category='vertical', parent_location=sequence.location)
nested_sequence = BlockFactory.create(category='sequential', parent_location=vertical.location)
nested_vertical1 = BlockFactory.create(category='vertical', parent_location=nested_sequence.location)
# put a module into nested_vertical1 for completeness
# put a block into nested_vertical1 for completeness
BlockFactory.create(category='html', parent_location=nested_vertical1.location)
nested_vertical2 = BlockFactory.create(category='vertical', parent_location=nested_sequence.location)
module2 = BlockFactory.create(category='html', parent_location=nested_vertical2.location)
block2 = BlockFactory.create(category='html', parent_location=nested_vertical2.location)
# internal position of module2 will be 1_2 (2nd item withing 1st item)
activate_block_id = urlencode({'activate_block_id': str(module2.location)})
# internal position of block2 will be 1_2 (2nd item withing 1st item)
activate_block_id = urlencode({'activate_block_id': str(block2.location)})
expected_redirect_url = (
f'/courses/{course.id}/courseware/{chapter.url_name}/{sequence.url_name}/1?{activate_block_id}'
)
jumpto_url = f'/courses/{course.id}/jump_to/{module2.location}'
jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}'
response = self.client.get(jumpto_url)
self.assertRedirects(response, expected_redirect_url, status_code=302, target_status_code=302)
@@ -1927,7 +1927,7 @@ class ProgressPageShowCorrectnessTests(ProgressPageBaseTests):
"""
Submit the given score to the problem on behalf of the user
"""
# Get the module for the problem, as viewed by the user
# Get the block for the problem, as viewed by the user
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course.id,
self.user,
@@ -1935,16 +1935,16 @@ class ProgressPageShowCorrectnessTests(ProgressPageBaseTests):
depth=2
)
self.addCleanup(set_current_request, None)
module = get_module(
block = get_block(
self.user,
get_mock_request(self.user),
self.problem.scope_ids.usage_id,
field_data_cache,
field_data_cache
)
# Submit the given score/max_score to the problem xmodule
grade_dict = {'value': value, 'max_value': max_value, 'user_id': self.user.id}
module.system.publish(self.problem, 'grade', grade_dict)
block.system.publish(self.problem, 'grade', grade_dict)
def assert_progress_page_show_grades(self, response, show_correctness, due_date, graded,
show_grades, score, max_score, avg): # lint-amnesty, pylint: disable=unused-argument

View File

@@ -95,7 +95,7 @@ class PageLoaderTestCase(LoginEnrollmentTestCase):
Assert that the url loads correctly.
If expect_redirect, then also check that we were redirected.
If check_content, then check that we don't get
an error message about unavailable modules.
an error message about unavailable blocks.
"""
url = reverse(django_url, kwargs=kwargs)

View File

@@ -61,7 +61,7 @@ from ..entrance_exams import (
)
from ..masquerade import check_content_start_date_for_masquerade_user, setup_masquerade
from ..model_data import FieldDataCache
from ..module_render import get_module_for_descriptor, toc_for_course
from ..block_render import get_block_for_descriptor, toc_for_course
from ..permissions import MASQUERADE_AS_STUDENT
from ..toggles import ENABLE_OPTIMIZELY_IN_COURSEWARE, courseware_mfe_is_active
from .views import CourseTabView
@@ -103,7 +103,7 @@ class CoursewareIndex(View):
course_id (unicode): course id
chapter (unicode): chapter url_name
section (unicode): section url_name
position (unicode): position in module, eg of <sequential> module
position (unicode): position in block, eg of <sequential> block
"""
self.course_key = CourseKey.from_string(course_id)
@@ -357,7 +357,7 @@ class CoursewareIndex(View):
read_only=CrawlersConfig.is_crawler(request),
)
self.course = get_module_for_descriptor(
self.course = get_block_for_descriptor(
self.effective_user,
self.request,
self.course,
@@ -377,7 +377,7 @@ class CoursewareIndex(View):
self.field_data_cache.add_descriptor_descendents(self.section, depth=None)
# Bind section to user
self.section = get_module_for_descriptor(
self.section = get_block_for_descriptor(
self.effective_user,
self.request,
self.section,
@@ -579,23 +579,23 @@ def save_positions_recursively_up(user, request, field_data_cache, xmodule, cour
Recurses up the course tree starting from a leaf
Saving the position property based on the previous node as it goes
"""
current_module = xmodule
current_block = xmodule
while current_module:
parent_location = modulestore().get_parent_location(current_module.location)
while current_block:
parent_location = modulestore().get_parent_location(current_block.location)
parent = None
if parent_location:
parent_descriptor = modulestore().get_item(parent_location)
parent = get_module_for_descriptor(
parent = get_block_for_descriptor(
user,
request,
parent_descriptor,
field_data_cache,
current_module.location.course_key,
current_block.location.course_key,
course=course
)
if parent and hasattr(parent, 'position'):
save_child_position(parent, current_module.location.block_id)
save_child_position(parent, current_block.location.block_id)
current_module = parent
current_block = parent

View File

@@ -129,7 +129,7 @@ from openedx.features.course_experience.utils import dates_banner_should_display
from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML
from openedx.features.enterprise_support.api import data_sharing_consent_required
from ..module_render import get_module, get_module_by_usage_id, get_module_for_descriptor
from ..block_render import get_block, get_block_by_usage_id, get_block_for_descriptor
from ..tabs import _get_dynamic_tabs
from ..toggles import COURSEWARE_OPTIMIZED_RENDER_XBLOCK
@@ -1258,16 +1258,16 @@ def get_static_tab_fragment(request, course, tab):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course.id, request.user, modulestore().get_item(loc), depth=0
)
tab_module = get_module(
tab_block = get_block(
request.user, request, loc, field_data_cache, static_asset_path=course.static_asset_path, course=course
)
logging.debug('course_block = %s', tab_module)
logging.debug('course_block = %s', tab_block)
fragment = Fragment()
if tab_module is not None:
if tab_block is not None:
try:
fragment = tab_module.render(STUDENT_VIEW, {})
fragment = tab_block.render(STUDENT_VIEW, {})
except Exception: # pylint: disable=broad-except
fragment.content = render_to_string('courseware/error-message.html', None)
log.exception(
@@ -1301,12 +1301,12 @@ def get_course_lti_endpoints(request, course_id):
return HttpResponse(status=404)
anonymous_user = AnonymousUser()
anonymous_user.known = False # make these "noauth" requests like module_render.handle_xblock_callback_noauth
anonymous_user.known = False # make these "noauth" requests like block_render.handle_xblock_callback_noauth
lti_descriptors = modulestore().get_items(course.id, qualifiers={'category': 'lti'})
lti_descriptors.extend(modulestore().get_items(course.id, qualifiers={'category': 'lti_consumer'}))
lti_noauth_modules = [
get_module_for_descriptor(
lti_noauth_blocks = [
get_block_for_descriptor(
anonymous_user,
request,
descriptor,
@@ -1323,13 +1323,13 @@ def get_course_lti_endpoints(request, course_id):
endpoints = [
{
'display_name': module.display_name,
'lti_2_0_result_service_json_endpoint': module.get_outcome_service_url(
'display_name': block.display_name,
'lti_2_0_result_service_json_endpoint': block.get_outcome_service_url(
service_name='lti_2_0_result_rest_handler') + "/user/{anon_user_id}",
'lti_1_1_result_service_xml_endpoint': module.get_outcome_service_url(
'lti_1_1_result_service_xml_endpoint': block.get_outcome_service_url(
service_name='grade_handler'),
}
for module in lti_noauth_modules
for block in lti_noauth_blocks
]
return HttpResponse(json.dumps(endpoints), content_type='application/json') # lint-amnesty, pylint: disable=http-response-with-content-type-json, http-response-with-json-dumps
@@ -1539,7 +1539,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True):
# get the block, which verifies whether the user has access to the block.
recheck_access = request.GET.get('recheck_access') == '1'
block, _ = get_module_by_usage_id(
block, _ = get_block_by_usage_id(
request, str(course_key), str(usage_key), disable_staff_debug_info=True, course=course,
will_recheck_access=recheck_access
)
@@ -1635,7 +1635,7 @@ def render_public_video_xblock(request, usage_key_string):
with modulestore().bulk_operations(course_key):
course = get_course_by_id(course_key, 0)
block, _ = get_module_by_usage_id(
block, _ = get_block_by_usage_id(
request,
str(course_key),
str(usage_key),

View File

@@ -23,7 +23,7 @@ from oauth2_provider.models import Application
from common.djangoapps.edxmako.shortcuts import render_to_string
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, SuperuserFactory, UserFactory
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from lms.djangoapps.courseware.tabs import get_course_tab_list
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
from openedx.core.djangoapps.oauth_dispatch.tests.factories import ApplicationFactory
@@ -962,7 +962,7 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
Returns the course block.
"""
field_data_cache = FieldDataCache([self.course], self.course.id, self.user) # lint-amnesty, pylint: disable=no-member
return get_module_for_descriptor(
return get_block_for_descriptor(
self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course # lint-amnesty, pylint: disable=no-member
)

View File

@@ -21,7 +21,7 @@ from common.djangoapps.edxmako.shortcuts import render_to_response
from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest
from lms.djangoapps.courseware.courses import get_course_with_access
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from lms.djangoapps.edxnotes.exceptions import EdxNotesParseError, EdxNotesServiceUnavailable
from lms.djangoapps.edxnotes.helpers import (
DEFAULT_PAGE,
@@ -74,7 +74,7 @@ def edxnotes(request, course_id):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course.id, request.user, course, depth=2
)
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
request.user, request, course, field_data_cache, course_key, course=course
)
position = get_course_position(course_block)
@@ -195,7 +195,7 @@ def edxnotes_visibility(request, course_id):
course_key = CourseKey.from_string(course_id)
course = get_course_with_access(request.user, "load", course_key)
field_data_cache = FieldDataCache([course], course_key, request.user)
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
request.user, request, course, field_data_cache, course_key, course=course
)

View File

@@ -10,7 +10,7 @@ from unittest.mock import MagicMock, patch
import pytz
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module
from lms.djangoapps.courseware.block_render import get_block
from xmodule.graders import ProblemScore # lint-amnesty, pylint: disable=wrong-import-order
@@ -79,7 +79,7 @@ def answer_problem(course, request, problem, score=1, max_value=1):
course,
depth=2
)
module = get_module(
module = get_block(
user,
request,
problem.scope_ids.usage_id,

View File

@@ -12,7 +12,7 @@ from edx_django_utils.monitoring import set_code_owner_attribute
from common.djangoapps.student.models import get_user_by_username_or_email
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from openedx.core.lib.request_utils import get_request_or_stub
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order
@@ -71,7 +71,7 @@ def update_exam_completion_task(user_identifier: str, content_id: str, completio
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
root_descriptor.scope_ids.usage_id.context_key, user, root_descriptor, read_only=True,
)
root_module = get_module_for_descriptor(
root_module = get_block_for_descriptor(
user, request, root_descriptor, field_data_cache, root_descriptor.scope_ids.usage_id.context_key,
)
if not root_module:

View File

@@ -233,10 +233,10 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
@mock.patch('lms.djangoapps.instructor.tasks.log.error')
def test_complete_student_attempt_failed_module(self, mock_logger):
"""
Assert complete_student_attempt with failed get_module raises error and returns None
Assert complete_student_attempt with failed get_block raises error and returns None
"""
username = self.student.username
with mock.patch('lms.djangoapps.instructor.tasks.get_module_for_descriptor', return_value=None):
with mock.patch('lms.djangoapps.instructor.tasks.get_block_for_descriptor', return_value=None):
self.service.complete_student_attempt(username, str(self.course.location))
mock_logger.assert_called_once_with(
self.complete_error_prefix.format(user=username, content_id=self.course.location) +

View File

@@ -4,7 +4,7 @@ Helpers for instructor app.
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module
from lms.djangoapps.courseware.block_render import get_block
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
@@ -35,4 +35,4 @@ def get_module_for_student(student, usage_key, request=None, course=None):
descriptor = modulestore().get_item(usage_key, depth=0)
field_data_cache = FieldDataCache([descriptor], usage_key.course_key, student)
return get_module(student, request, usage_key, field_data_cache, course=course)
return get_block(student, request, usage_key, field_data_cache, course=course)

View File

@@ -50,7 +50,7 @@ from lms.djangoapps.certificates.models import (
)
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.courses import get_studio_url
from lms.djangoapps.courseware.module_render import get_module_by_usage_id
from lms.djangoapps.courseware.block_render import get_block_by_usage_id
from lms.djangoapps.discussion.django_comment_client.utils import has_forum_access
from lms.djangoapps.grades.api import is_writable_gradebook_enabled
from lms.djangoapps.instructor.constants import INSTRUCTOR_DASHBOARD_PLUGIN_VIEW_NAME
@@ -757,7 +757,7 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
})
openassessment_block = openassessment_blocks[0]
block, __ = get_module_by_usage_id(
block, __ = get_block_by_usage_id(
request, str(course_key), str(openassessment_block.location),
disable_staff_debug_info=True, course=course
)

View File

@@ -20,7 +20,7 @@ from common.djangoapps.util.db import outer_atomic
from lms.djangoapps.courseware.courses import get_problems_in_section
from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.courseware.module_render import get_module_for_descriptor_internal
from lms.djangoapps.courseware.block_render import get_block_for_descriptor_internal
from lms.djangoapps.grades.api import events as grades_events
from openedx.core.lib.courses import get_course_by_id
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
@@ -335,7 +335,7 @@ def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule
Fetches a StudentModule instance for a given `course_id`, `student` object, and `module_descriptor`.
`xmodule_instance_args` is used to provide information for creating a track function and an XQueue callback.
These are passed, along with `grade_bucket_type`, to get_module_for_descriptor_internal, which sidesteps
These are passed, along with `grade_bucket_type`, to get_block_for_descriptor_internal, which sidesteps
the need for a Request object when instantiating an xmodule instance.
"""
# reconstitute the problem's corresponding XModule:
@@ -357,7 +357,7 @@ def _get_module_instance_for_task(course_id, student, module_descriptor, xmodule
'''
return lambda event_type, event: task_track(request_info, task_info, event_type, event, page='x_module_task')
return get_module_for_descriptor_internal(
return get_block_for_descriptor_internal(
user=student,
descriptor=module_descriptor,
student_data=student_data,

View File

@@ -292,7 +292,7 @@ class TestOverrideScoreInstructorTask(TestInstructorTasks):
mock_instance = MagicMock()
del mock_instance.set_score
with patch(
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal'
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal'
) as mock_get_module:
mock_get_module.return_value = mock_instance
with pytest.raises(UpdateProblemModuleStateError):
@@ -313,7 +313,7 @@ class TestOverrideScoreInstructorTask(TestInstructorTasks):
num_students = 1
self._create_students_with_state(num_students, input_state)
task_entry = self._create_input_entry(score=0)
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal',
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal',
return_value=None):
self._run_task_with_mock_celery(override_problem_score, task_entry.id, task_entry.task_id)
@@ -338,7 +338,7 @@ class TestOverrideScoreInstructorTask(TestInstructorTasks):
self._create_students_with_state(num_students)
task_entry = self._create_input_entry(score=0)
with patch(
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal'
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal'
) as mock_get_module:
mock_get_module.return_value = mock_instance
mock_instance.max_score = MagicMock(return_value=99999.0)
@@ -425,7 +425,7 @@ class TestRescoreInstructorTask(TestInstructorTasks):
mock_instance = MagicMock()
del mock_instance.rescore_problem
del mock_instance.rescore
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal') as mock_get_module: # lint-amnesty, pylint: disable=line-too-long
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal') as mock_get_module: # lint-amnesty, pylint: disable=line-too-long
mock_get_module.return_value = mock_instance
with pytest.raises(UpdateProblemModuleStateError):
self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id)
@@ -448,7 +448,7 @@ class TestRescoreInstructorTask(TestInstructorTasks):
num_students = 1
self._create_students_with_state(num_students, input_state)
task_entry = self._create_input_entry()
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal', return_value=None): # lint-amnesty, pylint: disable=line-too-long
with patch('lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal', return_value=None): # lint-amnesty, pylint: disable=line-too-long
self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id)
self.assert_task_output(
@@ -474,7 +474,7 @@ class TestRescoreInstructorTask(TestInstructorTasks):
self._create_students_with_state(num_students)
task_entry = self._create_input_entry()
with patch(
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_module_for_descriptor_internal'
'lms.djangoapps.instructor_task.tasks_helper.module_state.get_block_for_descriptor_internal'
) as mock_get_module:
mock_get_module.return_value = mock_instance
self._run_task_with_mock_celery(rescore_problem, task_entry.id, task_entry.task_id)

View File

@@ -51,7 +51,7 @@ class TestHandlerUrl(TestCase):
super().setUp()
self.block = BlockMock(name='block')
self.runtime = LmsModuleSystem(
get_module=Mock(),
get_block=Mock(),
descriptor_runtime=Mock(),
)

View File

@@ -12,7 +12,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from common.djangoapps.static_replace import make_static_urls_absolute
from lms.djangoapps.courseware.courses import get_course_info_section_module
from lms.djangoapps.courseware.courses import get_course_info_section_block
from lms.djangoapps.course_goals.models import UserActivity
from openedx.core.lib.xblock_utils import get_course_update_items
from openedx.features.course_experience import ENABLE_COURSE_GOALS
@@ -47,7 +47,7 @@ class CourseUpdatesList(generics.ListAPIView):
@mobile_course_access()
def list(self, request, course, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
course_updates_module = get_course_info_section_module(request, request.user, course, 'updates')
course_updates_module = get_course_info_section_block(request, request.user, course, 'updates')
update_items = get_course_update_items(course_updates_module)
updates_to_show = [
@@ -82,7 +82,7 @@ class CourseHandoutsList(generics.ListAPIView):
@mobile_course_access()
def list(self, request, course, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
course_handouts_module = get_course_info_section_module(request, request.user, course, 'handouts')
course_handouts_module = get_course_info_section_block(request, request.user, course, 'handouts')
if course_handouts_module:
if course_handouts_module.data == "<ol></ol>":
handouts_html = None

View File

@@ -25,7 +25,7 @@ from lms.djangoapps.courseware.access import is_mobile_available_for_user
from lms.djangoapps.courseware.access_utils import ACCESS_GRANTED
from lms.djangoapps.courseware.courses import get_current_child
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
from lms.djangoapps.courseware.views.index import save_positions_recursively_up
from lms.djangoapps.mobile_api.models import MobileConfig
from lms.djangoapps.mobile_api.utils import API_V1, API_V05, API_V2
@@ -143,7 +143,7 @@ class UserCourseStatus(views.APIView):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course.id, request.user, course, depth=2)
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
request.user, request, course, field_data_cache, course.id, course=course
)
@@ -179,7 +179,7 @@ class UserCourseStatus(views.APIView):
module_descriptor = modulestore().get_item(module_key)
except ItemNotFoundError:
return Response(errors.ERROR_INVALID_MODULE_ID, status=400)
module = get_module_for_descriptor(
module = get_block_for_descriptor(
request.user, request, module_descriptor, field_data_cache, course.id, course=course
)

View File

@@ -7,7 +7,7 @@ import json
from opaque_keys.edx.keys import UsageKey
from rest_framework.request import clone_request
from lms.djangoapps.courseware.module_render import handle_xblock_callback_noauth
from lms.djangoapps.courseware.block_render import handle_xblock_callback_noauth
from lms.djangoapps.ora_staff_grader.errors import MissingParamResponse

View File

@@ -17,7 +17,7 @@ from common.djangoapps.student import views as student_views
from common.djangoapps.util import views as util_views
from lms.djangoapps.branding import views as branding_views
from lms.djangoapps.courseware.masquerade import MasqueradeView
from lms.djangoapps.courseware.module_render import (
from lms.djangoapps.courseware.block_render import (
handle_xblock_callback,
handle_xblock_callback_noauth,
xblock_view,

View File

@@ -40,7 +40,7 @@ from lms.djangoapps.courseware.masquerade import (
is_masquerading_as_non_audit_enrollment,
)
from lms.djangoapps.courseware.models import LastSeenCoursewareTimezone
from lms.djangoapps.courseware.module_render import get_module_by_usage_id
from lms.djangoapps.courseware.block_render import get_block_by_usage_id
from lms.djangoapps.courseware.toggles import course_exit_page_is_active
from lms.djangoapps.courseware.views.views import get_cert_data
from lms.djangoapps.gating.api import get_entrance_exam_score, get_entrance_exam_usage_key
@@ -584,7 +584,7 @@ class SequenceMetadata(DeveloperErrorViewMixin, APIView):
reset_masquerade_data=True,
)
sequence, _ = get_module_by_usage_id(
sequence, _ = get_block_by_usage_id(
self.request,
str(usage_key.course_key),
str(usage_key),

View File

@@ -131,7 +131,7 @@ def _get_course_block(course_descriptor, user):
# Adding courseware imports here to insulate other apps (e.g. schedules) to
# avoid import errors.
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
from lms.djangoapps.courseware.block_render import get_block_for_descriptor
# Fake a request to fool parts of the courseware that want to inspect it.
request = get_request_or_stub()
@@ -142,7 +142,7 @@ def _get_course_block(course_descriptor, user):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course_descriptor.id, user, course_descriptor, depth=1, read_only=True,
)
course_block = get_module_for_descriptor(
course_block = get_block_for_descriptor(
user, request, course_descriptor, field_data_cache, course_descriptor.id, course=course_descriptor,
)
if not course_block:

View File

@@ -161,9 +161,9 @@ class TestContentHighlights(ModuleStoreTestCase): # lint-amnesty, pylint: disab
with pytest.raises(CourseUpdateDoesNotExist):
get_next_section_highlights(self.user, self.course_key, two_days_ago, six_days.date())
@patch('lms.djangoapps.courseware.module_render.get_module_for_descriptor')
def test_get_highlights_without_module(self, mock_get_module):
mock_get_module.return_value = None
@patch('lms.djangoapps.courseware.block_render.get_block_for_descriptor')
def test_get_highlights_without_block(self, mock_get_block):
mock_get_block.return_value = None
with self.store.bulk_operations(self.course_key):
self._create_chapter(highlights=['Test highlight'])

View File

@@ -31,7 +31,7 @@ from common.djangoapps.track import contexts as track_contexts
from common.djangoapps.track import views as track_views
from common.djangoapps.xblock_django.user_service import DjangoXBlockUserService
from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache
from lms.djangoapps.courseware import module_render
from lms.djangoapps.courseware import block_render
from lms.djangoapps.grades.api import signals as grades_signals
from openedx.core.djangoapps.xblock.apps import get_xblock_app_config
from openedx.core.djangoapps.xblock.runtime.blockstore_field_data import BlockstoreChildrenData, BlockstoreFieldData
@@ -258,11 +258,11 @@ class XBlockRuntime(RuntimeShim, Runtime):
elif service_name == 'rebind_user':
# this service should ideally be initialized with all the arguments of get_module_system_for_user
# but only the positional arguments are passed here as the other arguments are too
# specific to the lms.module_render module
# specific to the lms.block_render module
return RebindUserService(
self.user,
context_key,
module_render.get_module_system_for_user,
block_render.get_module_system_for_user,
track_function=make_track_function(),
request_token=request_token(crum.get_current_request()),
)

View File

@@ -27,7 +27,7 @@ from common.djangoapps.student.tests.factories import InstructorFactory
from common.djangoapps.student.tests.factories import OrgInstructorFactory
from common.djangoapps.student.tests.factories import OrgStaffFactory
from common.djangoapps.student.tests.factories import StaffFactory
from lms.djangoapps.courseware.module_render import load_single_xblock
from lms.djangoapps.courseware.block_render import load_single_xblock
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin
from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory
from openedx.core.djangoapps.django_comment_common.models import (

View File

@@ -5,7 +5,7 @@ Utilities for course updates.
import hashlib
from datetime import datetime
from lms.djangoapps.courseware.courses import get_course_info_section_module
from lms.djangoapps.courseware.courses import get_course_info_section_block
from openedx.core.djangoapps.user_api.course_tag.api import get_course_tag, set_course_tag
STATUS_VISIBLE = 'visible'
@@ -59,7 +59,7 @@ def get_ordered_updates(request, course):
"""
Returns all public course updates in reverse chronological order, including dismissed ones.
"""
info_module = get_course_info_section_module(request, request.user, course, 'updates')
info_module = get_course_info_section_block(request, request.user, course, 'updates')
if not info_module:
return []

View File

@@ -10,7 +10,7 @@ from django.views.decorators.cache import cache_control
from opaque_keys.edx.keys import CourseKey
from web_fragments.fragment import Fragment
from lms.djangoapps.courseware.courses import get_course_info_section_module, get_course_with_access
from lms.djangoapps.courseware.courses import get_course_info_section_block, get_course_with_access
from lms.djangoapps.courseware.views.views import CourseTabView
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from openedx.features.course_experience import default_course_url
@@ -76,7 +76,7 @@ class CourseUpdatesFragmentView(EdxFragmentView):
for older implementations and a few tests that store
a single html object representing all the updates.
"""
info_module = get_course_info_section_module(request, request.user, course, 'updates')
info_module = get_course_info_section_block(request, request.user, course, 'updates')
info_block = getattr(info_module, '_xmodule', info_module)
return info_block.system.service(
info_block, "replace_urls"

View File

@@ -8,7 +8,7 @@ from edx_toggles.toggles.testutils import override_waffle_flag
from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.module_render import get_module
from lms.djangoapps.courseware.block_render import get_block
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
@@ -33,7 +33,7 @@ class ShowAnswerFieldOverrideTest(ModuleStoreTestCase):
def get_course_block(self, course):
request = RequestFactory().request()
field_data_cache = FieldDataCache([], course.id, self.user)
return get_module(self.user, request, course.location, field_data_cache, course=course)
return get_block(self.user, request, course.location, field_data_cache, course=course)
@ddt.data(True, False)
def test_override_enabled_for(self, active):

View File

@@ -125,15 +125,15 @@ class CompletionServiceTestCase(CompletionWaffleTestMixin, SharedModuleStoreTest
module_system.descriptor_runtime = module.runtime._descriptor_system # pylint: disable=protected-access
module_system._services['library_tools'] = LibraryToolsService(self.store, self.user.id) # pylint: disable=protected-access
def get_module(descriptor):
"""Mocks module_system get_module function"""
def get_block(descriptor):
"""Mocks module_system get_block_for_descriptor function"""
sub_module_system = get_test_system(course_id=module.location.course_key)
sub_module_system.get_module = get_module
sub_module_system.get_block_for_descriptor = get_block
sub_module_system.descriptor_runtime = descriptor._runtime # pylint: disable=protected-access
descriptor.bind_for_student(sub_module_system, self.user.id)
return descriptor
module_system.get_module = get_module
module_system.get_block_for_descriptor = get_block
module.xmodule_runtime = module_system
def test_completion_service(self):

View File

@@ -399,7 +399,7 @@ class ProblemBlock(
def handle_ajax(self, dispatch, data):
"""
This is called by courseware.module_render, to handle an AJAX call.
This is called by courseware.block_render, to handle an AJAX call.
`data` is request.POST.
@@ -1286,7 +1286,7 @@ class ProblemBlock(
id=self.location.html_id(), ajax_url=self.ajax_url, html=HTML(html)
)
# Now do all the substitutions which the LMS module_render normally does, but
# Now do all the substitutions which the LMS block_render normally does, but
# we need to do here explicitly since we can get called for our HTML via AJAX
html = self.runtime.service(self, "replace_urls").replace_urls(html)

View File

@@ -317,7 +317,9 @@ class ConditionalBlock(
"""
Returns a list of bound XBlocks instances upon which XBlock depends.
"""
return [self.system.get_module(descriptor) for descriptor in self.get_required_module_descriptors()]
return [
self.system.get_block_for_descriptor(descriptor) for descriptor in self.get_required_module_descriptors()
]
def get_required_module_descriptors(self):
"""

View File

@@ -30,7 +30,7 @@ log = logging.getLogger(__name__)
# way to tell if the module is being used in a staff context or not. Errors that get discovered
# at course load time are turned into ErrorBlock objects, and automatically hidden from students.
# Unfortunately, we can also have errors when loading modules mid-request, and then we need to decide
# what to show, and the logic for that belongs in the LMS (e.g. in get_module), so the error handler
# what to show, and the logic for that belongs in the LMS (e.g. in get_block), so the error handler
# decides whether to create a staff or not-staff module.

View File

@@ -744,7 +744,7 @@ oauth_consumer_key="", oauth_signature="frVp4JuvT1mVXlxktiAUjQ7%2F1cw%3D"'}
@XBlock.handler
def grade_handler(self, request, suffix): # lint-amnesty, pylint: disable=unused-argument
"""
This is called by courseware.module_render, to handle an AJAX call.
This is called by courseware.block_render, to handle an AJAX call.
Used only for grading. Returns XML response.

View File

@@ -147,7 +147,7 @@ class RebindUserService(Service):
"""
An XBlock Service that allows modules to get rebound to real users if it was previously bound to an AnonymousUser.
This used to be a local function inside the `lms.djangoapps.courseware.module_render.get_module_system_for_user`
This used to be a local function inside the `lms.djangoapps.courseware.block_render.get_module_system_for_user`
method, and was passed as a constructor argument to x_module.ModuleSystem. This has been refactored out into a
service to simplify the ModuleSystem and lives in this module temporarily.
@@ -160,7 +160,7 @@ class RebindUserService(Service):
course (Course) - Course Object
get_module_system_for_user (function) - The helper function that will be called to create a module system
for a specfic user. This is the parent function from which this service was reactored out.
`lms.djangoapps.courseware.module_render.get_module_system_for_user`
`lms.djangoapps.courseware.block_render.get_module_system_for_user`
kwargs (dict) - all the keyword arguments that need to be passed to the `get_module_system_for_user`
function when it is called during rebinding
"""

View File

@@ -192,7 +192,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
Return the user bound child block for the partition or None.
"""
if self.child_descriptor is not None:
return self.system.get_module(self.child_descriptor)
return self.system.get_block_for_descriptor(self.child_descriptor)
else:
return None
@@ -272,7 +272,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
for child_location in self.children: # pylint: disable=no-member
child_descriptor = self.get_child_descriptor_by_location(child_location)
child = self.system.get_module(child_descriptor)
child = self.system.get_block_for_descriptor(child_descriptor)
rendered_child = child.render(STUDENT_VIEW, context)
fragment.add_fragment_resources(rendered_child)
group_name, updated_group_id = self.get_data_for_vertical(child)
@@ -347,7 +347,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
"""
html = ""
for active_child_descriptor in children:
active_child = self.system.get_module(active_child_descriptor)
active_child = self.system.get_block_for_descriptor(active_child_descriptor)
rendered_child = active_child.render(StudioEditableBlock.get_preview_view_name(active_child), context)
if active_child.category == 'vertical':
group_name, group_id = self.get_data_for_vertical(active_child)

View File

@@ -121,8 +121,8 @@ def get_test_system(
id_manager = CourseLocationManager(course_id)
def get_module(descriptor):
"""Mocks module_system get_module function"""
def get_block(descriptor):
"""Mocks module_system get_block function"""
# Unlike XBlock Runtimes or DescriptorSystems,
# each XModule is provided with a new ModuleSystem.
@@ -138,7 +138,7 @@ def get_test_system(
return descriptor
return TestModuleSystem(
get_module=get_module,
get_block=get_block,
services={
'user': user_service,
'mako': mako_service,

View File

@@ -130,9 +130,9 @@ class ConditionalFactory:
ScopeIds(None, None, cond_location, cond_location)
)
cond_descriptor.xmodule_runtime = system
system.get_module = lambda desc: desc if visible_to_nonstaff_users(desc) else None
system.get_block_for_descriptor = lambda desc: desc if visible_to_nonstaff_users(desc) else None
cond_descriptor.get_required_blocks = [
system.get_module(source_descriptor),
system.get_block_for_descriptor(source_descriptor),
]
# return dict:
@@ -228,7 +228,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
def get_module_for_location(self, location):
descriptor = self.modulestore.get_item(location, depth=None)
return self.test_system.get_module(descriptor)
return self.test_system.get_block_for_descriptor(descriptor)
@patch('xmodule.x_module.descriptor_global_local_resource_url')
@patch.dict(settings.FEATURES, {'ENABLE_EDXNOTES': False})

View File

@@ -62,15 +62,15 @@ class LibraryContentTest(MixedSplitTestCase):
module_system.descriptor_runtime = module.runtime._descriptor_system # pylint: disable=protected-access
module_system._services['library_tools'] = self.tools # pylint: disable=protected-access
def get_module(descriptor):
"""Mocks module_system get_module function"""
def get_block(descriptor):
"""Mocks module_system get_block function"""
sub_module_system = get_test_system(course_id=module.location.course_key)
sub_module_system.get_module = get_module
sub_module_system.get_block_for_descriptor = get_block
sub_module_system.descriptor_runtime = descriptor._runtime # pylint: disable=protected-access
descriptor.bind_for_student(sub_module_system, self.user_id)
return descriptor
module_system.get_module = get_module
module_system.get_block_for_descriptor = get_block
module.xmodule_runtime = module_system

View File

@@ -480,7 +480,7 @@ class VideoStudioViewHandlers:
We raise all exceptions right in Studio:
NotFoundError:
Video or asset was deleted from module/contentstore, but request came later.
Seems impossible to be raised. module_render.py catches NotFoundErrors from here.
Seems impossible to be raised. block_render.py catches NotFoundErrors from here.
/translation POST:
TypeError:

View File

@@ -1656,15 +1656,15 @@ class ModuleSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemShim,
def __init__(
self,
get_module,
get_block,
descriptor_runtime,
**kwargs,
**kwargs
):
"""
Create a closure around the system environment.
get_module - function that takes a descriptor and returns a corresponding
module instance object. If the current user does not have
get_block - function that takes a descriptor and returns a corresponding
block instance object. If the current user does not have
access to that location, returns None.
descriptor_runtime - A `DescriptorSystem` to use for loading xblocks by id
@@ -1674,7 +1674,7 @@ class ModuleSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemShim,
kwargs.setdefault('id_generator', getattr(descriptor_runtime, 'id_generator', AsideKeyGenerator()))
super().__init__(**kwargs)
self.get_module = get_module
self.get_block_for_descriptor = get_block
self.xmodule_instance = None
@@ -1705,7 +1705,7 @@ class ModuleSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemShim,
return self.handler_url(self.xmodule_instance, 'xmodule_handler', '', '').rstrip('/?')
def get_block(self, block_id, for_parent=None): # lint-amnesty, pylint: disable=arguments-differ
return self.get_module(self.descriptor_runtime.get_block(block_id, for_parent=for_parent))
return self.get_block_for_descriptor(self.descriptor_runtime.get_block(block_id, for_parent=for_parent))
def resource_url(self, resource):
raise NotImplementedError("edX Platform doesn't currently implement XBlock resource urls")