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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) +
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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()),
|
||||
)
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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 []
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user