diff --git a/cms/djangoapps/contentstore/api/tests/base.py b/cms/djangoapps/contentstore/api/tests/base.py
index dd460734645c..150f299538ec 100644
--- a/cms/djangoapps/contentstore/api/tests/base.py
+++ b/cms/djangoapps/contentstore/api/tests/base.py
@@ -43,44 +43,44 @@ def initialize_course(cls, course):
cls.store.update_item(course, cls.staff.id)
cls.section = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="chapter",
)
cls.subsection1 = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
)
unit1 = BlockFactory.create(
- parent_location=cls.subsection1.location,
+ parent_location=cls.subsection1.usage_key,
category="vertical",
)
BlockFactory.create(
- parent_location=unit1.location,
+ parent_location=unit1.usage_key,
category="video",
)
BlockFactory.create(
- parent_location=unit1.location,
+ parent_location=unit1.usage_key,
category="problem",
)
cls.subsection2 = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
)
unit2 = BlockFactory.create(
- parent_location=cls.subsection2.location,
+ parent_location=cls.subsection2.usage_key,
category="vertical",
)
unit3 = BlockFactory.create(
- parent_location=cls.subsection2.location,
+ parent_location=cls.subsection2.usage_key,
category="vertical",
)
BlockFactory.create(
- parent_location=unit3.location,
+ parent_location=unit3.usage_key,
category="video",
)
BlockFactory.create(
- parent_location=unit3.location,
+ parent_location=unit3.usage_key,
category="video",
)
diff --git a/cms/djangoapps/contentstore/api/tests/test_validation.py b/cms/djangoapps/contentstore/api/tests/test_validation.py
index a091eedcc577..c679cf89fa26 100644
--- a/cms/djangoapps/contentstore/api/tests/test_validation.py
+++ b/cms/djangoapps/contentstore/api/tests/test_validation.py
@@ -76,11 +76,11 @@ def initialize_course(cls, course):
)
section = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="chapter",
)
BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="sequential",
)
@@ -183,23 +183,23 @@ def initialize_course(cls, course):
Sets up test course structure.
"""
section = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="chapter",
)
subsection = BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="sequential",
)
unit = BlockFactory.create(
- parent_location=subsection.location,
+ parent_location=subsection.usage_key,
category="vertical",
)
cls.block1 = BlockFactory.create(
- parent_location=unit.location,
+ parent_location=unit.usage_key,
category="library_content",
)
cls.block2 = BlockFactory.create(
- parent_location=unit.location,
+ parent_location=unit.usage_key,
category="library_content",
)
@@ -273,8 +273,8 @@ def test_list_ready_to_update_reference_success(self, mock_block, mock_auth):
data = response.json()
self.assertListEqual(data, [
- {'usage_key': str(self.block1.location)},
- {'usage_key': str(self.block2.location)},
+ {'usage_key': str(self.block1.usage_key)},
+ {'usage_key': str(self.block2.usage_key)},
])
mock_auth.assert_called_once()
diff --git a/cms/djangoapps/contentstore/api/views/course_quality.py b/cms/djangoapps/contentstore/api/views/course_quality.py
index 6ff2c02e2f6c..505f58924a47 100644
--- a/cms/djangoapps/contentstore/api/views/course_quality.py
+++ b/cms/djangoapps/contentstore/api/views/course_quality.py
@@ -218,12 +218,12 @@ def _get_subsections_and_units(cls, course, request):
for unit in visible_units:
leaf_blocks = cls._get_leaf_blocks(unit)
- unit_dict[unit.location] = dict(
+ unit_dict[unit.usage_key] = dict(
num_leaf_blocks=len(leaf_blocks),
- leaf_block_types={block.location.block_type for block in leaf_blocks},
+ leaf_block_types={block.usage_key.block_type for block in leaf_blocks},
)
- subsection_dict[subsection.location] = unit_dict
+ subsection_dict[subsection.usage_key] = unit_dict
return subsection_dict
@classmethod
@@ -257,7 +257,7 @@ def _get_children(cls, parent): # lint-amnesty, pylint: disable=missing-functio
def _get_leaf_blocks(cls, unit): # lint-amnesty, pylint: disable=missing-function-docstring
def leaf_filter(block):
return (
- block.location.block_type not in ('chapter', 'sequential', 'vertical') and
+ block.usage_key.block_type not in ('chapter', 'sequential', 'vertical') and
len(cls._get_children(block)) == 0
)
diff --git a/cms/djangoapps/contentstore/api/views/course_validation.py b/cms/djangoapps/contentstore/api/views/course_validation.py
index fd3e447b2746..1553ba1c37d8 100644
--- a/cms/djangoapps/contentstore/api/views/course_validation.py
+++ b/cms/djangoapps/contentstore/api/views/course_validation.py
@@ -143,7 +143,7 @@ def _assignments_validation(self, course, request): # lint-amnesty, pylint: dis
]
assignments_with_dates_before_start = (
[
- {'id': str(a.location), 'display_name': a.display_name}
+ {'id': str(a.usage_key), 'display_name': a.display_name}
for a in assignments_with_dates
if a.due < course.start
]
@@ -153,7 +153,7 @@ def _assignments_validation(self, course, request): # lint-amnesty, pylint: dis
assignments_with_dates_after_end = (
[
- {'id': str(a.location), 'display_name': a.display_name}
+ {'id': str(a.usage_key), 'display_name': a.display_name}
for a in assignments_with_dates
if a.due > course.end
]
@@ -169,7 +169,7 @@ def _assignments_validation(self, course, request): # lint-amnesty, pylint: dis
]
assignments_with_dates_before_start = (
[
- {'id': str(a.location), 'display_name': a.display_name}
+ {'id': str(a.usage_key), 'display_name': a.display_name}
for a in assignments_with_dates
if a.due < course.start
]
@@ -179,7 +179,7 @@ def _assignments_validation(self, course, request): # lint-amnesty, pylint: dis
assignments_with_dates_after_end = (
[
- {'id': str(a.location), 'display_name': a.display_name}
+ {'id': str(a.usage_key), 'display_name': a.display_name}
for a in assignments_with_dates
if a.due > course.end
]
@@ -200,14 +200,14 @@ def _assignments_validation(self, course, request): # lint-amnesty, pylint: dis
parent_unit = modulestore().get_item(ora.parent)
parent_assignment = modulestore().get_item(parent_unit.parent)
assignments_with_ora_dates_before_start.append({
- 'id': str(parent_assignment.location),
+ 'id': str(parent_assignment.usage_key),
'display_name': parent_assignment.display_name
})
if course.end and self._has_date_after_end(ora, course.end):
parent_unit = modulestore().get_item(ora.parent)
parent_assignment = modulestore().get_item(parent_unit.parent)
assignments_with_ora_dates_after_end.append({
- 'id': str(parent_assignment.location),
+ 'id': str(parent_assignment.usage_key),
'display_name': parent_assignment.display_name
})
diff --git a/cms/djangoapps/contentstore/asset_storage_handlers.py b/cms/djangoapps/contentstore/asset_storage_handlers.py
index bbb1deaad21a..d03b2a90a6cb 100644
--- a/cms/djangoapps/contentstore/asset_storage_handlers.py
+++ b/cms/djangoapps/contentstore/asset_storage_handlers.py
@@ -188,7 +188,7 @@ def _get_asset_usage_path(course_key, assets):
if handout and asset_key_string in handout:
usage_dict = {'display_location': '', 'url': ''}
xblock_display_name = getattr(block, 'display_name', '')
- xblock_location = str(block.location)
+ xblock_location = str(block.usage_key)
unit = block.get_parent()
unit_location = str(block.parent)
unit_display_name = getattr(unit, 'display_name', '')
@@ -204,7 +204,7 @@ def _get_asset_usage_path(course_key, assets):
if static_path in data or asset_key_string in data:
usage_dict = {'display_location': '', 'url': ''}
xblock_display_name = getattr(block, 'display_name', '')
- xblock_location = str(block.location)
+ xblock_location = str(block.usage_key)
unit = block.get_parent()
unit_location = str(block.parent)
unit_display_name = getattr(unit, 'display_name', '')
diff --git a/cms/djangoapps/contentstore/core/course_optimizer_provider.py b/cms/djangoapps/contentstore/core/course_optimizer_provider.py
index 134329992cfe..a83a06acbeb5 100644
--- a/cms/djangoapps/contentstore/core/course_optimizer_provider.py
+++ b/cms/djangoapps/contentstore/core/course_optimizer_provider.py
@@ -244,7 +244,7 @@ def _update_node_tree_and_dictionary(block, link, link_state, node_tree, diction
# Traverse the path and build the tree structure
for xblock in path:
- xblock_id = xblock.location
+ xblock_id = xblock.usage_key
updated_dictionary.setdefault(
xblock_id,
{
@@ -258,7 +258,7 @@ def _update_node_tree_and_dictionary(block, link, link_state, node_tree, diction
# Add block-level details for the last xblock in the path (URL and broken/locked links)
updated_dictionary[xblock_id].setdefault(
'url',
- f'/course/{block.course_id}/editor/{block.category}/{block.location}'
+ f'/course/{block.course_id}/editor/{block.category}/{block.usage_key}'
)
# The link_state == True condition is maintained for backward compatibility.
@@ -358,7 +358,7 @@ def sort_course_sections(course_key, data):
if not course_blocks or 'LinkCheckOutput' not in data or 'sections' not in data['LinkCheckOutput']:
return data
- sorted_section_ids = [section.location for section in course_blocks[0].get_children()]
+ sorted_section_ids = [section.usage_key for section in course_blocks[0].get_children()]
sections_map = {section['id']: section for section in data['LinkCheckOutput']['sections']}
data['LinkCheckOutput']['sections'] = [
sections_map[section_id]
diff --git a/cms/djangoapps/contentstore/core/tests/test_course_optimizer_provider.py b/cms/djangoapps/contentstore/core/tests/test_course_optimizer_provider.py
index 0780848dfda9..5a5dcb402554 100644
--- a/cms/djangoapps/contentstore/core/tests/test_course_optimizer_provider.py
+++ b/cms/djangoapps/contentstore/core/tests/test_course_optimizer_provider.py
@@ -61,10 +61,10 @@ def test_update_node_tree_and_dictionary_returns_node_tree(self):
when passed a block level xblock.
"""
expected_tree = {
- self.mock_section.location: {
- self.mock_subsection.location: {
- self.mock_unit.location: {
- self.mock_block.location: {}
+ self.mock_section.usage_key: {
+ self.mock_subsection.usage_key: {
+ self.mock_unit.usage_key: {
+ self.mock_block.usage_key: {}
}
}
}
@@ -81,22 +81,22 @@ def test_update_node_tree_and_dictionary_returns_dictionary(self):
when passed a block level xblock.
"""
expected_dictionary = {
- self.mock_section.location: {
+ self.mock_section.usage_key: {
'display_name': 'Section Name',
'category': 'chapter'
},
- self.mock_subsection.location: {
+ self.mock_subsection.usage_key: {
'display_name': 'Subsection Name',
'category': 'sequential'
},
- self.mock_unit.location: {
+ self.mock_unit.usage_key: {
'display_name': 'Unit Name',
'category': 'vertical'
},
- self.mock_block.location: {
+ self.mock_block.usage_key: {
'display_name': 'Block Name',
'category': 'html',
- 'url': f'/course/{self.course.id}/editor/html/{self.mock_block.location}',
+ 'url': f'/course/{self.course.id}/editor/html/{self.mock_block.usage_key}',
'locked_links': ['example_link']
}
}
@@ -375,12 +375,12 @@ def test_course_updates_and_custom_pages_structure(self):
# Test data that represents the broken links JSON structure
json_content = [
[
- str(self.mock_block.location),
+ str(self.mock_block.usage_key),
"http://content-link.com",
LinkState.BROKEN,
],
[
- str(self.mock_unit.location),
+ str(self.mock_unit.usage_key),
"http://unit-link.com",
LinkState.LOCKED,
],
diff --git a/cms/djangoapps/contentstore/course_group_config.py b/cms/djangoapps/contentstore/course_group_config.py
index a6babd0a0c2f..87bf18d91803 100644
--- a/cms/djangoapps/contentstore/course_group_config.py
+++ b/cms/djangoapps/contentstore/course_group_config.py
@@ -139,7 +139,7 @@ def _get_usage_dict(course, unit, block, scheme_name=None):
unit_url = reverse_usage_url(
'container_handler',
- course.location.course_key.make_usage_key(unit_for_url.location.block_type, unit_for_url.location.block_id)
+ course.usage_key.course_key.make_usage_key(unit_for_url.usage_key.block_type, unit_for_url.usage_key.block_id)
)
usage_dict = {'label': f"{unit.display_name} / {block.display_name}", 'url': unit_url}
@@ -194,7 +194,7 @@ def _get_content_experiment_usage_info(store, course, split_tests): # pylint: d
for split_test in split_tests:
unit = split_test.get_parent()
if not unit:
- log.warning("Unable to find parent for split_test %s", split_test.location)
+ log.warning("Unable to find parent for split_test %s", split_test.usage_key)
# Make sure that this user_partition appears in the output even though it has no content
usage_info[split_test.user_partition_id] = []
continue
@@ -234,7 +234,7 @@ def get_partitions_usage_info(store, course):
for block, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items):
unit = block.get_parent()
if not unit:
- log.warning("Unable to find parent for component %s", block.location)
+ log.warning("Unable to find parent for component %s", block.usage_key)
continue
usage_info[partition_id][group_id].append(GroupConfiguration._get_usage_dict(
diff --git a/cms/djangoapps/contentstore/courseware_index.py b/cms/djangoapps/contentstore/courseware_index.py
index b7b74992035a..d6e4ffb2a5b6 100644
--- a/cms/djangoapps/contentstore/courseware_index.py
+++ b/cms/djangoapps/contentstore/courseware_index.py
@@ -161,7 +161,7 @@ def get_item_location(item):
"""
Gets the version agnostic item location
"""
- return item.location.version_agnostic().replace(branch=None)
+ return item.usage_key.version_agnostic().replace(branch=None)
def prepare_item_index(item, skip_index=False, groups_usage_info=None):
"""
@@ -192,7 +192,7 @@ def prepare_item_index(item, skip_index=False, groups_usage_info=None):
for group in split_partition.groups:
group_id = str(group.id)
child_location = item.group_id_to_child.get(group_id, None)
- if child_location == split_test_child.location:
+ if child_location == split_test_child.usage_key:
groups_usage_info.update({
str(get_item_location(split_test_child)): [group_id],
})
@@ -242,8 +242,8 @@ def prepare_item_index(item, skip_index=False, groups_usage_info=None):
return item_content_groups
except Exception as err: # pylint: disable=broad-except
# broad exception so that index operation does not fail on one item of many
- log.warning('Could not index item: %s - %r', item.location, err)
- error_list.append(_('Could not index item: {}').format(item.location))
+ log.warning('Could not index item: %s - %r', item.usage_key, err)
+ error_list.append(_('Could not index item: {}').format(item.usage_key))
try:
with modulestore.branch_setting(ModuleStoreEnum.RevisionOption.published_only):
@@ -617,7 +617,7 @@ def index_about_information(cls, modulestore, course):
# load data for all of the 'about' blocks for this course into a dictionary
about_dictionary = {
- item.location.block_id: item.data
+ item.usage_key.block_id: item.data
for item in modulestore.get_items(course.id, qualifiers={"category": "about"})
}
diff --git a/cms/djangoapps/contentstore/exams.py b/cms/djangoapps/contentstore/exams.py
index 8a4ddc09425e..798a1112e53d 100644
--- a/cms/djangoapps/contentstore/exams.py
+++ b/cms/djangoapps/contentstore/exams.py
@@ -56,7 +56,7 @@ def register_exams(course_key):
exams_list = []
locations = []
for timed_exam in timed_exams:
- location = str(timed_exam.location)
+ location = str(timed_exam.usage_key)
msg = (
'Found {location} as an exam in course structure.'.format(
location=location
@@ -84,7 +84,7 @@ def register_exams(course_key):
exams_list.append({
'course_id': str(course_key),
- 'content_id': str(timed_exam.location),
+ 'content_id': str(timed_exam.usage_key),
'exam_name': timed_exam.display_name,
'time_limit_mins': timed_exam.default_time_limit_minutes,
# If the subsection has no due date, then infer a due date from the course end date. This behavior is a
diff --git a/cms/djangoapps/contentstore/helpers.py b/cms/djangoapps/contentstore/helpers.py
index 9bfab1f1f385..df2e60e8ea12 100644
--- a/cms/djangoapps/contentstore/helpers.py
+++ b/cms/djangoapps/contentstore/helpers.py
@@ -69,7 +69,7 @@ def get_parent_xblock(xblock):
"""
Returns the xblock that is the parent of the specified xblock, or None if it has no parent.
"""
- locator = xblock.location
+ locator = xblock.usage_key
parent_location = modulestore().get_parent_location(locator)
if parent_location is None:
@@ -153,17 +153,17 @@ def xblock_studio_url(xblock, parent_xblock=None, find_parent=False):
return None
category = xblock.category
if category == 'course':
- return reverse_course_url('course_handler', xblock.location.course_key)
+ return reverse_course_url('course_handler', xblock.usage_key.course_key)
elif category in ('chapter', 'sequential'):
return '{url}?show={usage_key}'.format(
- url=reverse_course_url('course_handler', xblock.location.course_key),
- usage_key=urllib.parse.quote(str(xblock.location))
+ url=reverse_course_url('course_handler', xblock.usage_key.course_key),
+ usage_key=urllib.parse.quote(str(xblock.usage_key))
)
elif category == 'library':
- library_key = xblock.location.course_key
+ library_key = xblock.usage_key.course_key
return reverse_library_url('library_handler', library_key)
else:
- return reverse_usage_url('container_handler', xblock.location)
+ return reverse_usage_url('container_handler', xblock.usage_key)
def xblock_lms_url(xblock) -> str:
@@ -177,7 +177,7 @@ def xblock_lms_url(xblock) -> str:
str: The LMS URL for the specified xblock.
"""
lms_root_url = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)
- return f"{lms_root_url}/courses/{xblock.location.course_key}/jump_to/{xblock.location}"
+ return f"{lms_root_url}/courses/{xblock.usage_key.course_key}/jump_to/{xblock.usage_key}"
def xblock_embed_lms_url(xblock) -> str:
@@ -191,7 +191,7 @@ def xblock_embed_lms_url(xblock) -> str:
str: The LMS URL for the specified xblock in embed mode.
"""
lms_root_url = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)
- return f"{lms_root_url}/xblock/{xblock.location}"
+ return f"{lms_root_url}/xblock/{xblock.usage_key}"
def xblock_type_display_name(xblock, default_display_name=None):
@@ -597,7 +597,7 @@ def _import_xml_node_to_parent(
# Save the XBlock into modulestore. We need to save the block and its parent for this to work:
new_xblock = store.update_item(temp_xblock, user.id, allow_not_found=True)
new_xblock.parent = parent_key
- parent_xblock.children.append(new_xblock.location)
+ parent_xblock.children.append(new_xblock.usage_key)
store.update_item(parent_xblock, user.id)
children_handled = False
@@ -622,13 +622,13 @@ def _import_xml_node_to_parent(
# copy the tags from the upstream as ready-only
content_tagging_api.copy_tags_as_read_only(
new_xblock.upstream,
- new_xblock.location,
+ new_xblock.usage_key,
)
elif tags and node_copied_from:
object_tags = tags.get(node_copied_from)
if object_tags:
content_tagging_api.set_all_object_tags(
- content_key=new_xblock.location,
+ content_key=new_xblock.usage_key,
object_tags=object_tags,
)
@@ -812,7 +812,7 @@ def is_item_in_course_tree(item):
if its parent has been deleted and is now an orphan.
"""
ancestor = item.get_parent()
- while ancestor is not None and ancestor.location.block_type != "course":
+ while ancestor is not None and ancestor.usage_key.block_type != "course":
ancestor = ancestor.get_parent()
return ancestor is not None
diff --git a/cms/djangoapps/contentstore/management/commands/delete_v1_libraries.py b/cms/djangoapps/contentstore/management/commands/delete_v1_libraries.py
index b9a4368f6d6b..34a030dd1e94 100644
--- a/cms/djangoapps/contentstore/management/commands/delete_v1_libraries.py
+++ b/cms/djangoapps/contentstore/management/commands/delete_v1_libraries.py
@@ -75,7 +75,7 @@ def handle(self, *args, **options): # lint-amnesty, pylint: disable=unused-argu
store = modulestore()
if query_yes_no(self.CONFIRMATION_PROMPT, default="no"):
v1_library_keys = [
- library.location.library_key.replace(branch=None) for library in store.get_libraries()
+ library.usage_key.library_key.replace(branch=None) for library in store.get_libraries()
]
else:
return
diff --git a/cms/djangoapps/contentstore/management/commands/export_content_library.py b/cms/djangoapps/contentstore/management/commands/export_content_library.py
index b56c172e374e..e51841f533cb 100644
--- a/cms/djangoapps/contentstore/management/commands/export_content_library.py
+++ b/cms/djangoapps/contentstore/management/commands/export_content_library.py
@@ -62,4 +62,4 @@ def handle(self, *args, **options):
tarball.file.seek(0)
with open(target, 'wb') as f:
shutil.copyfileobj(tarball.file, f)
- print(f'Library "{library.location.library_key}" exported to "{target}"')
+ print(f'Library "{library.usage_key.library_key}" exported to "{target}"')
diff --git a/cms/djangoapps/contentstore/management/commands/import_content_library.py b/cms/djangoapps/contentstore/management/commands/import_content_library.py
index 7d2a64825a31..9584c85d3ea8 100644
--- a/cms/djangoapps/contentstore/management/commands/import_content_library.py
+++ b/cms/djangoapps/contentstore/management/commands/import_content_library.py
@@ -111,8 +111,8 @@ def _get_or_create_library(org, number, display_name, user):
"display_name": display_name
},
)
- add_instructor(library.location.library_key, user, user)
- return library.location.library_key, True
+ add_instructor(library.usage_key.library_key, user, user)
+ return library.usage_key.library_key, True
except DuplicateCourseError:
# Course exists, return its key
return LibraryLocator(org=org, library=number), False
diff --git a/cms/djangoapps/contentstore/management/commands/reindex_library.py b/cms/djangoapps/contentstore/management/commands/reindex_library.py
index cf352576f6be..594b56c6d8a1 100644
--- a/cms/djangoapps/contentstore/management/commands/reindex_library.py
+++ b/cms/djangoapps/contentstore/management/commands/reindex_library.py
@@ -55,7 +55,7 @@ def handle(self, *args, **options):
if options['all']:
if query_yes_no(self.CONFIRMATION_PROMPT, default="no"):
- library_keys = [library.location.library_key.replace(branch=None) for library in store.get_libraries()]
+ library_keys = [library.usage_key.library_key.replace(branch=None) for library in store.get_libraries()]
else:
return
else:
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py b/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py
index 75650d41dcb2..a4349faa7927 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_delete_orphans.py
@@ -90,7 +90,7 @@ def create_split_course_with_published_orphan(self):
orphan = self.store.create_item(
self.user.id, course.id, 'html', "PublishedOnlyOrphan"
)
- self.store.publish(orphan.location, self.user.id)
+ self.store.publish(orphan.usage_key, self.user.id)
# grab the published branch of the course
published_branch = course.id.for_branch(
@@ -104,13 +104,13 @@ def create_split_course_with_published_orphan(self):
# delete this orphan from the draft branch without
# auto-publishing this change to the published branch
self.store.delete_item(
- orphan.location, self.user.id, skip_auto_publish=True
+ orphan.usage_key, self.user.id, skip_auto_publish=True
)
# now there should be no orphans in the draft branch, but
# there should be one in published
self.assertOrphanCount(course.id, 0)
self.assertOrphanCount(published_branch, 1)
- self.assertIn(orphan.location, [x.location for x in self.store.get_items(published_branch)])
+ self.assertIn(orphan.usage_key, [x.usage_key for x in self.store.get_items(published_branch)])
return course, orphan
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_fix_not_found.py b/cms/djangoapps/contentstore/management/commands/tests/test_fix_not_found.py
index b9372d15204b..1c5b7bd7c832 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_fix_not_found.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_fix_not_found.py
@@ -25,7 +25,7 @@ def test_no_args(self):
def test_fix_not_found(self):
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
- BlockFactory.create(category='chapter', parent_location=course.location)
+ BlockFactory.create(category='chapter', parent_location=course.usage_key)
# get course again in order to update its children list
course = self.store.get_course(course.id)
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py b/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py
index ea16707d7eb8..e7493c36aaff 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_force_publish.py
@@ -76,16 +76,16 @@ def test_force_publish(self):
Test 'force_publish' command
"""
# Add some changes to course
- chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
+ chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
self.store.create_child(
self.test_user_id,
- chapter.location,
+ chapter.usage_key,
'html',
block_id='html_component'
)
# verify that course has changes.
- self.assertTrue(self.store.has_changes(self.store.get_item(self.course.location)))
+ self.assertTrue(self.store.has_changes(self.store.get_item(self.course.usage_key)))
# get draft and publish branch versions
versions = get_course_versions(str(self.course.id))
@@ -102,7 +102,7 @@ def test_force_publish(self):
call_command('force_publish', str(self.course.id), '--commit')
# verify that course has no changes
- self.assertFalse(self.store.has_changes(self.store.get_item(self.course.location)))
+ self.assertFalse(self.store.has_changes(self.store.get_item(self.course.usage_key)))
# get new draft and publish branch versions
versions = get_course_versions(str(self.course.id))
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py
index 6d14b4a339f2..9a85f404acdf 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py
@@ -52,7 +52,7 @@ def setUp(self):
def _get_lib_key(self, library):
""" Get's library key as it is passed to indexer """
- return library.location.library_key
+ return library.usage_key.library_key
def _build_calls(self, *courses):
""" Builds a list of mock.call instances representing calls to reindexing method """
diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py
index d5013cf69462..98a80d600cf3 100644
--- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py
+++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py
@@ -44,7 +44,7 @@ def setUp(self):
def _get_lib_key(self, library):
""" Get's library key as it is passed to indexer """
- return library.location.library_key
+ return library.usage_key.library_key
def _build_calls(self, *libraries):
""" BUilds a list of mock.call instances representing calls to reindexing method """
diff --git a/cms/djangoapps/contentstore/outlines.py b/cms/djangoapps/contentstore/outlines.py
index 72d5c4f257f0..4bc49adc2bfe 100644
--- a/cms/djangoapps/contentstore/outlines.py
+++ b/cms/djangoapps/contentstore/outlines.py
@@ -51,12 +51,12 @@ def _error_for_not_section(not_section):
"""
return ContentErrorData(
message=(
- f' contains a <{not_section.location.block_type}> tag with '
- f'url_name="{not_section.location.block_id}" and '
+ f' contains a <{not_section.usage_key.block_type}> tag with '
+ f'url_name="{not_section.usage_key.block_id}" and '
f'display_name="{getattr(not_section, "display_name", "")}". '
f'Expected tag instead.'
),
- usage_key=_remove_version_info(not_section.location),
+ usage_key=_remove_version_info(not_section.usage_key),
)
@@ -68,14 +68,14 @@ def _error_for_not_sequence(section, not_sequence):
"""
return ContentErrorData(
message=(
- f' with url_name="{section.location.block_id}" and '
+ f' with url_name="{section.usage_key.block_id}" and '
f'display_name="{section.display_name}" contains a '
- f'<{not_sequence.location.block_type}> tag with '
- f'url_name="{not_sequence.location.block_id}" and '
+ f'<{not_sequence.usage_key.block_type}> tag with '
+ f'url_name="{not_sequence.usage_key.block_id}" and '
f'display_name="{getattr(not_sequence, "display_name", "")}". '
f'Expected a tag.'
),
- usage_key=_remove_version_info(not_sequence.location),
+ usage_key=_remove_version_info(not_sequence.usage_key),
)
@@ -88,18 +88,18 @@ def _error_for_duplicate_child(section, duplicate_child, original_section):
"""
return ContentErrorData(
message=(
- f' with url_name="{section.location.block_id}" and '
+ f' with url_name="{section.usage_key.block_id}" and '
f'display_name="{section.display_name}" contains a '
- f'<{duplicate_child.location.block_type}> tag with '
- f'url_name="{duplicate_child.location.block_id}" and '
+ f'<{duplicate_child.usage_key.block_type}> tag with '
+ f'url_name="{duplicate_child.usage_key.block_id}" and '
f'display_name="{getattr(duplicate_child, "display_name", "")}" '
f'that is defined in another section with '
- f'url_name="{original_section.location.block_id}" and '
+ f'url_name="{original_section.usage_key.block_id}" and '
f'display_name="{original_section.display_name}". Expected a '
f'unique tag instead.'
),
- usage_key=_remove_version_info(duplicate_child.location),
+ usage_key=_remove_version_info(duplicate_child.usage_key),
)
@@ -234,12 +234,12 @@ def _make_section_data(section, unique_sequences):
section_errors = []
# First check if it's not a section at all, and short circuit if it isn't.
- if section.location.block_type != 'chapter':
+ if section.usage_key.block_type != 'chapter':
section_errors.append(_error_for_not_section(section))
return (None, section_errors, unique_sequences)
section_user_partition_groups, error = _make_user_partition_groups(
- section.location, section.group_access
+ section.usage_key, section.group_access
)
# Invalid user partition errors aren't fatal. Just log and continue on.
if error:
@@ -249,21 +249,21 @@ def _make_section_data(section, unique_sequences):
sequences_data = []
for sequence in section.get_children():
- if sequence.location.block_type not in valid_sequence_tags:
+ if sequence.usage_key.block_type not in valid_sequence_tags:
section_errors.append(_error_for_not_sequence(section, sequence))
continue
# We need to check if there are duplicate sequences. If there are
# duplicate sequences the course outline generation will fail. We ignore
# the duplicated sequences, so they will not be sent to
# learning_sequences.
- if sequence.location in unique_sequences:
- original_section = unique_sequences[sequence.location]
+ if sequence.usage_key in unique_sequences:
+ original_section = unique_sequences[sequence.usage_key]
section_errors.append(_error_for_duplicate_child(section, sequence, original_section))
continue
else:
- unique_sequences[sequence.location] = section
+ unique_sequences[sequence.usage_key] = section
seq_user_partition_groups, error = _make_user_partition_groups(
- sequence.location, sequence.group_access
+ sequence.usage_key, sequence.group_access
)
if error:
section_errors.append(error)
@@ -279,19 +279,19 @@ def _make_section_data(section, unique_sequences):
# no conflicting value set at the Sequence level.
if user_partition_id not in seq_user_partition_groups:
section_errors.append(
- _make_bubbled_up_error(sequence.location, user_partition_id, group_ids)
+ _make_bubbled_up_error(sequence.usage_key, user_partition_id, group_ids)
)
seq_user_partition_groups[user_partition_id] = group_ids
else:
section_errors.append(
_make_not_bubbled_up_error(
- sequence.location, sequence.group_access, user_partition_id, group_ids
+ sequence.usage_key, sequence.group_access, user_partition_id, group_ids
)
)
sequences_data.append(
CourseLearningSequenceData(
- usage_key=_remove_version_info(sequence.location),
+ usage_key=_remove_version_info(sequence.usage_key),
title=sequence.display_name_with_default,
inaccessible_after_due=sequence.hide_after_due,
exam=ExamData(
@@ -308,7 +308,7 @@ def _make_section_data(section, unique_sequences):
)
section_data = CourseSectionData(
- usage_key=_remove_version_info(section.location),
+ usage_key=_remove_version_info(section.usage_key),
title=section.display_name_with_default,
sequences=sequences_data,
visibility=VisibilityData(
diff --git a/cms/djangoapps/contentstore/proctoring.py b/cms/djangoapps/contentstore/proctoring.py
index bd33049006c4..93e8c140bd40 100644
--- a/cms/djangoapps/contentstore/proctoring.py
+++ b/cms/djangoapps/contentstore/proctoring.py
@@ -71,7 +71,7 @@ def register_special_exams(course_key):
for timed_exam in timed_exams:
msg = (
'Found {location} as a timed-exam in course structure. Inspecting...'.format(
- location=str(timed_exam.location)
+ location=str(timed_exam.usage_key)
)
)
log.info(msg)
@@ -89,7 +89,7 @@ def register_special_exams(course_key):
}
try:
- exam = get_exam_by_content_id(str(course_key), str(timed_exam.location))
+ exam = get_exam_by_content_id(str(course_key), str(timed_exam.usage_key))
# update case, make sure everything is synced
exam_metadata['exam_id'] = exam['id']
@@ -99,7 +99,7 @@ def register_special_exams(course_key):
except ProctoredExamNotFoundException:
exam_metadata['course_id'] = str(course_key)
- exam_metadata['content_id'] = str(timed_exam.location)
+ exam_metadata['content_id'] = str(timed_exam.usage_key)
exam_id = create_exam(**exam_metadata)
msg = f'Created new timed exam {exam_id}'
log.info(msg)
@@ -136,7 +136,7 @@ def register_special_exams(course_key):
search = [
timed_exam for timed_exam in timed_exams if
- str(timed_exam.location) == exam['content_id']
+ str(timed_exam.usage_key) == exam['content_id']
]
if not search:
# This means it was turned off in Studio, we need to mark
diff --git a/cms/djangoapps/contentstore/rest_api/v0/tests/test_tabs.py b/cms/djangoapps/contentstore/rest_api/v0/tests/test_tabs.py
index 5e83c9313617..e6702438afc0 100644
--- a/cms/djangoapps/contentstore/rest_api/v0/tests/test_tabs.py
+++ b/cms/djangoapps/contentstore/rest_api/v0/tests/test_tabs.py
@@ -44,7 +44,7 @@ def setUp(self):
# add a static tab to the course, for code coverage
self.test_tab = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="static_tab",
display_name="Static_1",
)
diff --git a/cms/djangoapps/contentstore/rest_api/v1/serializers/vertical_block.py b/cms/djangoapps/contentstore/rest_api/v1/serializers/vertical_block.py
index 5df4804027cb..ff4409ac4129 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/serializers/vertical_block.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/serializers/vertical_block.py
@@ -87,8 +87,8 @@ class ContainerHandlerSerializer(serializers.Serializer):
user_clipboard = serializers.DictField()
is_fullwidth_content = serializers.BooleanField()
assets_url = serializers.SerializerMethodField()
- unit_block_id = serializers.CharField(source="unit.location.block_id")
- subsection_location = serializers.CharField(source="subsection.location")
+ unit_block_id = serializers.CharField(source="unit.usage_key.block_id")
+ subsection_location = serializers.CharField(source="subsection.usage_key")
course_sequence_ids = serializers.ListField(child=serializers.CharField())
library_content_picker_url = serializers.CharField()
diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/course_index.py b/cms/djangoapps/contentstore/rest_api/v1/views/course_index.py
index 42b5b1e9d78d..739e5f070b6a 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/views/course_index.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/views/course_index.py
@@ -255,7 +255,7 @@ def get(self, request: Request, usage_key_string: str):
with modulestore().bulk_operations(usage_key.course_key):
# load course once to reuse it for user_partitions query
- course = modulestore().get_course(current_xblock.location.course_key)
+ course = modulestore().get_course(current_xblock.usage_key.course_key)
children = []
if current_xblock.has_children:
for child in current_xblock.children:
@@ -269,8 +269,8 @@ def get(self, request: Request, usage_key_string: str):
children.append({
"xblock": child_info,
"name": child_info.display_name_with_default,
- "block_id": child_info.location,
- "block_type": child_info.location.block_type,
+ "block_id": child_info.usage_key,
+ "block_type": child_info.usage_key.block_type,
"user_partition_info": user_partition_info,
"user_partitions": user_partitions,
"upstream_link": (
diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_index.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_index.py
index 310d0ba80adc..4424fa12a9ab 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_index.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_index.py
@@ -74,7 +74,7 @@ def test_course_index_response(self):
"source_edit_url": ""
},
"language_code": "en",
- "lms_link": get_lms_link_for_item(self.course.location),
+ "lms_link": get_lms_link_for_item(self.course.usage_key),
"mfe_proctored_exam_settings_url": (
f"http://course-authoring-mfe/course/{self.course.id}"
"/pages-and-resources/proctoring/settings"
@@ -99,7 +99,7 @@ def test_course_index_response(self):
@override_waffle_flag(CUSTOM_RELATIVE_DATES, active=False)
def test_course_index_response_with_show_locators(self):
"""Check successful response content with show query param"""
- response = self.client.get(self.url, {"show": str(self.unit.location)})
+ response = self.client.get(self.url, {"show": str(self.unit.usage_key)})
expected_response = {
"course_release_date": "Set Date",
"course_structure": _course_outline_json(self.request, self.course),
@@ -113,10 +113,10 @@ def test_course_index_response_with_show_locators(self):
"is_custom_relative_dates_active": False,
"initial_state": {
"expanded_locators": [
- str(self.unit.location),
- str(self.xblock.location),
+ str(self.unit.usage_key),
+ str(self.xblock.usage_key),
],
- "locator_to_show": str(self.unit.location),
+ "locator_to_show": str(self.unit.usage_key),
},
"initial_user_clipboard": {
"content": None,
@@ -125,7 +125,7 @@ def test_course_index_response_with_show_locators(self):
"source_edit_url": ""
},
"language_code": "en",
- "lms_link": get_lms_link_for_item(self.course.location),
+ "lms_link": get_lms_link_for_item(self.course.usage_key),
"mfe_proctored_exam_settings_url": (
f"http://course-authoring-mfe/course/{self.course.id}"
"/pages-and-resources/proctoring/settings"
diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py
index a155ceb235a4..b22505bf7445 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py
@@ -127,7 +127,7 @@ def test_home_page_response(self):
"courses": [{
"course_key": course_id,
"display_name": self.course.display_name,
- "lms_link": f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.location}',
+ "lms_link": f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.usage_key}',
"number": self.course.number,
"org": self.course.org,
"rerun_link": f'/course_rerun/{course_id}',
@@ -153,7 +153,7 @@ def test_home_page_response_with_api_v2(self):
OrderedDict([
("course_key", course_id),
("display_name", self.course.display_name),
- ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.location}'),
+ ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.usage_key}'),
("number", self.course.number),
("org", self.course.org),
("rerun_link", f'/course_rerun/{course_id}'),
diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_proctoring.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_proctoring.py
index 6cf08fe101e9..fd8938005c5e 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_proctoring.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_proctoring.py
@@ -197,7 +197,7 @@ def test_update_exam_settings_200_escalation_email(self):
)
# course settings have been updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.enable_proctored_exams is True
assert updated.proctoring_provider == "test_proctoring_provider"
assert updated.proctoring_escalation_email == "foo@bar.com"
@@ -234,7 +234,7 @@ def test_update_exam_settings_200_no_escalation_email(self):
)
# course settings have been updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.enable_proctored_exams is True
assert updated.proctoring_provider == "test_proctoring_provider"
assert updated.proctoring_escalation_email is None
@@ -265,7 +265,7 @@ def test_update_exam_settings_excluded_field(self):
)
# excluded course settings are not updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.proctoring_escalation_email is None
@override_settings(
@@ -295,7 +295,7 @@ def test_update_exam_settings_invalid_value(self):
)
# course settings have been updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.enable_proctored_exams is False
assert updated.proctoring_provider == "null"
@@ -361,7 +361,7 @@ def test_nonadmin_with_zendesk_ticket(
)
logger_mock.assert_any_call(logger_string)
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.create_zendesk_tickets is create_zendesk_tickets
@override_waffle_flag(EXAMS_IDA, active=True)
@@ -393,7 +393,7 @@ def test_200_for_lti_provider(self):
)
# course settings have been updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.enable_proctored_exams is True
assert updated.proctoring_provider == "lti_external"
@@ -422,7 +422,7 @@ def test_400_for_disabled_lti(self):
)
# course settings have been updated
- updated = modulestore().get_item(self.course.location)
+ updated = modulestore().get_item(self.course.usage_key)
assert updated.enable_proctored_exams is False
assert updated.proctoring_provider == "null"
diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_vertical_block.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_vertical_block.py
index cd1e1a99d074..dfc84720f980 100644
--- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_vertical_block.py
+++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_vertical_block.py
@@ -64,19 +64,19 @@ def setup_xblock(self):
self._publish_library_block(self.html_block["id"])
self.chapter = self.create_block(
- parent=self.course.location,
+ parent=self.course.usage_key,
category="chapter",
display_name="Week 1",
)
self.sequential = self.create_block(
- parent=self.chapter.location,
+ parent=self.chapter.usage_key,
category="sequential",
display_name="Lesson 1",
)
self.vertical = self.create_block(
- self.sequential.location,
+ self.sequential.usage_key,
"vertical",
"Unit",
upstream=self.unit["id"],
@@ -84,13 +84,13 @@ def setup_xblock(self):
)
self.html_unit_first = self.create_block(
- parent=self.vertical.location,
+ parent=self.vertical.usage_key,
category="html",
display_name="Html Content 1",
)
self.html_unit_second = self.create_block(
- parent=self.vertical.location,
+ parent=self.vertical.usage_key,
category="html",
display_name="Html Content 2",
upstream=self.html_block["id"],
@@ -146,7 +146,7 @@ def test_success_response(self):
"""
Check that endpoint is valid and success response.
"""
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -155,8 +155,8 @@ def test_ancestor_xblocks_response(self):
Check if the ancestor_xblocks are returned as expected.
"""
course_key_str = str(self.course.id)
- chapter_usage_key = str(self.chapter.location)
- sequential_usage_key = str(self.sequential.location)
+ chapter_usage_key = str(self.chapter.usage_key)
+ sequential_usage_key = str(self.sequential.usage_key)
# URL encode the usage keys for the URLs
chapter_encoded = quote(chapter_usage_key, safe='')
@@ -187,7 +187,7 @@ def test_ancestor_xblocks_response(self):
}
]
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
response_ancestor_xblocks = response.json().get("ancestor_xblocks", [])
@@ -222,7 +222,7 @@ def test_success_response(self):
"""
Check that endpoint returns valid response data.
"""
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
@@ -236,7 +236,7 @@ def test_success_response_with_upstream_info(self):
"""
Check that endpoint returns valid response data using `get_upstream_info` query param
"""
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(f"{url}?get_upstream_info=true")
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
@@ -256,8 +256,8 @@ def test_xblock_is_published(self):
"""
Check that published xBlock container returns.
"""
- self.publish_item(self.store, self.vertical.location)
- url = self.get_reverse_url(self.vertical.location)
+ self.publish_item(self.store, self.vertical.usage_key)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
self.assertTrue(response.data["is_published"])
@@ -265,7 +265,7 @@ def test_children_content(self):
"""
Check that returns valid response with children of vertical container.
"""
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
expected_user_partition_info = {
@@ -288,8 +288,8 @@ def test_children_content(self):
expected_response = [
{
"name": self.html_unit_first.display_name_with_default,
- "block_id": str(self.html_unit_first.location),
- "block_type": self.html_unit_first.location.block_type,
+ "block_id": str(self.html_unit_first.usage_key),
+ "block_type": self.html_unit_first.usage_key.block_type,
"upstream_link": None,
"user_partition_info": expected_user_partition_info,
"user_partitions": expected_user_partitions,
@@ -306,8 +306,8 @@ def test_children_content(self):
},
{
"name": self.html_unit_second.display_name_with_default,
- "block_id": str(self.html_unit_second.location),
- "block_type": self.html_unit_second.location.block_type,
+ "block_id": str(self.html_unit_second.usage_key),
+ "block_type": self.html_unit_second.usage_key.block_type,
"actions": {
"can_copy": True,
"can_duplicate": True,
@@ -352,7 +352,7 @@ def test_actions_with_turned_off_taxonomy_flag(self):
"""
Check that action manage_tags for each child item has the same value as taxonomy flag.
"""
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
for children in response.data["children"]:
self.assertFalse(children["actions"]["can_manage_tags"])
@@ -372,8 +372,8 @@ def test_validation_errors(self):
self.store.update_item(self.course, self.user.id)
user_partition = self.course.user_partitions[0]
- vertical = self.store.get_item(self.vertical.location)
- html_unit_first = self.store.get_item(self.html_unit_first.location)
+ vertical = self.store.get_item(self.vertical.usage_key)
+ html_unit_first = self.store.get_item(self.html_unit_first.usage_key)
group_first = user_partition.groups[0]
group_second = user_partition.groups[1]
@@ -383,10 +383,10 @@ def test_validation_errors(self):
self.set_group_access(html_unit_first, {user_partition.id: [group_first.id]})
# update vertical/html
- vertical = self.store.get_item(self.vertical.location)
- html_unit_first = self.store.get_item(self.html_unit_first.location)
+ vertical = self.store.get_item(self.vertical.usage_key)
+ html_unit_first = self.store.get_item(self.html_unit_first.usage_key)
- url = self.get_reverse_url(self.vertical.location)
+ url = self.get_reverse_url(self.vertical.usage_key)
response = self.client.get(url)
children_response = response.data["children"]
diff --git a/cms/djangoapps/contentstore/rest_api/v2/serializers/home.py b/cms/djangoapps/contentstore/rest_api/v2/serializers/home.py
index 857291fe838b..186674ee7225 100644
--- a/cms/djangoapps/contentstore/rest_api/v2/serializers/home.py
+++ b/cms/djangoapps/contentstore/rest_api/v2/serializers/home.py
@@ -38,7 +38,7 @@ class CourseCommonSerializerV2(serializers.Serializer):
def get_lms_link(self, obj):
"""Get LMS link for course."""
- return get_lms_link_for_item(obj.location)
+ return get_lms_link_for_item(obj.usage_key)
def get_cms_link(self, obj):
"""Get CMS link for course."""
diff --git a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py
index f82859f74bd3..42a7cb0ff478 100644
--- a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py
+++ b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py
@@ -518,7 +518,7 @@ def call_api_post(self, library_content_key, category):
`library_content_key` as upstream
"""
data = {
- "parent_locator": str(self.course.location),
+ "parent_locator": str(self.course.usage_key),
"display_name": "Test block",
"library_content_key": library_content_key,
"category": category,
diff --git a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_home.py b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_home.py
index 93a9941f4f1a..e1c2eeb08282 100644
--- a/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_home.py
+++ b/cms/djangoapps/contentstore/rest_api/v2/views/tests/test_home.py
@@ -55,7 +55,7 @@ def test_home_page_response(self):
OrderedDict([
("course_key", course_id),
("display_name", self.course.display_name),
- ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.location}'),
+ ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{course_id}/jump_to/{self.course.usage_key}'),
("cms_link", f'//{settings.CMS_BASE}{reverse_course_url("course_handler", self.course.id)}'),
("number", self.course.number),
("org", self.course.org),
@@ -69,7 +69,7 @@ def test_home_page_response(self):
("display_name", self.archived_course.display_name),
(
"lms_link",
- f'{settings.LMS_ROOT_URL}/courses/{archived_course_id}/jump_to/{self.archived_course.location}'
+ f'{settings.LMS_ROOT_URL}/courses/{archived_course_id}/jump_to/{self.archived_course.usage_key}'
),
(
"cms_link",
@@ -108,7 +108,7 @@ def test_active_only_query_if_passed(self):
self.assertEqual(response.data["results"]["courses"], [OrderedDict([
("course_key", str(self.course.id)),
("display_name", self.course.display_name),
- ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{str(self.course.id)}/jump_to/{self.course.location}'),
+ ("lms_link", f'{settings.LMS_ROOT_URL}/courses/{str(self.course.id)}/jump_to/{self.course.usage_key}'),
("cms_link", f'//{settings.CMS_BASE}{reverse_course_url("course_handler", self.course.id)}'),
("number", self.course.number),
("org", self.course.org),
@@ -136,7 +136,7 @@ def test_archived_only_query_if_passed(self):
'{url_root}/courses/{course_id}/jump_to/{location}'.format(
url_root=settings.LMS_ROOT_URL,
course_id=str(self.archived_course.id),
- location=self.archived_course.location
+ location=self.archived_course.usage_key
),
),
("cms_link", f'//{settings.CMS_BASE}{reverse_course_url("course_handler", self.archived_course.id)}'),
@@ -166,7 +166,7 @@ def test_search_query_if_passed(self):
'{url_root}/courses/{course_id}/jump_to/{location}'.format(
url_root=settings.LMS_ROOT_URL,
course_id=str(self.archived_course.id),
- location=self.archived_course.location
+ location=self.archived_course.usage_key
),
),
("cms_link", f'//{settings.CMS_BASE}{reverse_course_url("course_handler", self.archived_course.id)}'),
diff --git a/cms/djangoapps/contentstore/signals/handlers.py b/cms/djangoapps/contentstore/signals/handlers.py
index e28cbf313acb..0a90c7da1c47 100644
--- a/cms/djangoapps/contentstore/signals/handlers.py
+++ b/cms/djangoapps/contentstore/signals/handlers.py
@@ -212,13 +212,13 @@ def handle_item_deleted(**kwargs):
deleted_block = modulestore().get_item(usage_key)
except ItemNotFoundError:
return
- id_list = {deleted_block.location}
+ id_list = {deleted_block.usage_key}
for block in yield_dynamic_block_descendants(deleted_block, kwargs.get('user_id')):
# Remove prerequisite milestone data
- gating_api.remove_prerequisite(block.location)
+ gating_api.remove_prerequisite(block.usage_key)
# Remove any 'requires' course content milestone relationships
- gating_api.set_required_content(course_key, block.location, None, None, None)
- id_list.add(block.location)
+ gating_api.set_required_content(course_key, block.usage_key, None, None, None)
+ id_list.add(block.usage_key)
ComponentLink.objects.filter(downstream_usage_key__in=id_list).delete()
ContainerLink.objects.filter(downstream_usage_key__in=id_list).delete()
diff --git a/cms/djangoapps/contentstore/tasks.py b/cms/djangoapps/contentstore/tasks.py
index 983471e1ebef..a1b6f1ea2f77 100644
--- a/cms/djangoapps/contentstore/tasks.py
+++ b/cms/djangoapps/contentstore/tasks.py
@@ -432,8 +432,8 @@ def create_export_tarball(course_block, course_key, context, status=None):
LOGGER.exception('There was an error exporting %s', course_key, exc_info=True)
parent = None
try:
- failed_item = modulestore().get_item(exc.location)
- parent_loc = modulestore().get_parent_location(failed_item.location)
+ failed_item = modulestore().get_item(exc.usage_key)
+ parent_loc = modulestore().get_parent_location(failed_item.usage_key)
if parent_loc is not None:
parent = modulestore().get_item(parent_loc)
@@ -444,7 +444,7 @@ def create_export_tarball(course_block, course_key, context, status=None):
context.update({
'in_err': True,
'raw_err_msg': str(exc),
- 'edit_unit_url': reverse_usage_url("container_handler", parent.location) if parent else "",
+ 'edit_unit_url': reverse_usage_url("container_handler", parent.usage_key) if parent else "",
})
if status:
status.fail(json.dumps({'raw_error_msg': context['raw_err_msg'],
@@ -741,7 +741,7 @@ def read_chunk():
verbose=True,
)
- new_location = courselike_items[0].location
+ new_location = courselike_items[0].usage_key
LOGGER.debug('new course at %s', new_location)
LOGGER.info(f'{log_prefix}: Course import successful')
@@ -765,7 +765,7 @@ def read_chunk():
settings={'is_entrance_exam': True}
)[0]
- metadata = {'entrance_exam_id': str(entrance_exam_chapter.location)}
+ metadata = {'entrance_exam_id': str(entrance_exam_chapter.usage_key)}
CourseMetadata.update_from_dict(metadata, course, user)
from .views.entrance_exam import add_entrance_exam_milestone
add_entrance_exam_milestone(course.id, entrance_exam_chapter)
@@ -1020,7 +1020,7 @@ def replace_all_library_source_blocks_ids_for_course(course_key_string, v1_to_v2
for branch in [ModuleStoreEnum.BranchName.draft, ModuleStoreEnum.BranchName.published]
]
- published_dict = {block.location: block for block in published_blocks}
+ published_dict = {block.usage_key: block for block in published_blocks}
for draft_library_source_block in draft_blocks:
try:
@@ -1038,19 +1038,19 @@ def replace_all_library_source_blocks_ids_for_course(course_key_string, v1_to_v2
# This way, if authors "discard changes," they won't be reverted back to the V1 lib.
# However, we also don't want to publish the draft branch.
try:
- if published_dict[draft_library_source_block.location] is not None:
+ if published_dict[draft_library_source_block.usage_key] is not None:
#temporarily set the published version to be the draft & publish it.
- temp = published_dict[draft_library_source_block.location]
+ temp = published_dict[draft_library_source_block.usage_key]
temp.source_library_id = new_source_id
store.update_item(temp, None)
- store.publish(temp.location, None)
+ store.publish(temp.usage_key, None)
draft_library_source_block.source_library_id = new_source_id
store.update_item(draft_library_source_block, None)
except KeyError:
#Warn, but just update the draft block if no published block for draft block.
LOGGER.warning(
'No matching published block for draft block %s',
- str(draft_library_source_block.location)
+ str(draft_library_source_block.usage_key)
)
draft_library_source_block.source_library_id = new_source_id
store.update_item(draft_library_source_block, None)
@@ -1078,7 +1078,7 @@ def undo_all_library_source_blocks_ids_for_course(course_key_string, v1_to_v2_li
for branch in [ModuleStoreEnum.BranchName.draft, ModuleStoreEnum.BranchName.published]
]
- published_dict = {block.location: block for block in published_blocks}
+ published_dict = {block.usage_key: block for block in published_blocks}
for draft_library_source_block in draft_blocks:
try:
@@ -1096,19 +1096,19 @@ def undo_all_library_source_blocks_ids_for_course(course_key_string, v1_to_v2_li
# This way, if authors "discard changes," they won't be reverted back to the V1 lib.
# However, we also don't want to publish the draft branch.
try:
- if published_dict[draft_library_source_block.location] is not None:
+ if published_dict[draft_library_source_block.usage_key] is not None:
#temporarily set the published version to be the draft & publish it.
- temp = published_dict[draft_library_source_block.location]
+ temp = published_dict[draft_library_source_block.usage_key]
temp.source_library_id = new_source_id
store.update_item(temp, None)
- store.publish(temp.location, None)
+ store.publish(temp.usage_key, None)
draft_library_source_block.source_library_id = new_source_id
store.update_item(draft_library_source_block, None)
except KeyError:
#Warn, but just update the draft block if no published block for draft block.
LOGGER.warning(
'No matching published block for draft block %s',
- str(draft_library_source_block.location)
+ str(draft_library_source_block.usage_key)
)
draft_library_source_block.source_library_id = new_source_id
store.update_item(draft_library_source_block, None)
@@ -1258,7 +1258,7 @@ def _scan_course_for_links(course_key):
# and it doesn't contain user-facing links to scan.
if block.category == 'drag-and-drop-v2':
continue
- block_id = str(block.location)
+ block_id = str(block.usage_key)
block_info = get_block_info(block)
block_data = block_info['data']
url_list = extract_content_URLs_from_course(block_data)
@@ -2105,7 +2105,7 @@ def _update_course_content_link(block_id, old_url, new_url, course_key, user):
if hasattr(block, "data") and old_url in block.data:
block.data = block.data.replace(old_url, new_url)
store.update_item(block, user.id)
- store.publish(block.location, user.id)
+ store.publish(block.usage_key, user.id)
LOGGER.info(
f"Updated block {block_id} data with new URL: {old_url} -> {new_url}"
)
diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py
index 431a155d20a9..ea36e21a9e18 100644
--- a/cms/djangoapps/contentstore/tests/test_contentstore.py
+++ b/cms/djangoapps/contentstore/tests/test_contentstore.py
@@ -313,7 +313,7 @@ def verify_content_existence(self, store, root_dir, course_id, dirname, category
for item in items:
filesystem = OSFS(root_dir / ('test_export/' + dirname))
- self.assertTrue(filesystem.exists(item.location.block_id + filename_suffix))
+ self.assertTrue(filesystem.exists(item.usage_key.block_id + filename_suffix))
def test_export_course_with_metadata_only_video(self):
content_store = contentstore()
@@ -330,7 +330,7 @@ def test_export_course_with_metadata_only_video(self):
parent = verticals[0]
- BlockFactory.create(parent_location=parent.location, category="video", display_name="untitled")
+ BlockFactory.create(parent_location=parent.usage_key, category="video", display_name="untitled")
root_dir = path(mkdtemp_clean())
@@ -356,7 +356,7 @@ def test_export_course_with_metadata_only_word_cloud(self):
parent = verticals[0]
- BlockFactory.create(parent_location=parent.location, category="word_cloud", display_name="untitled")
+ BlockFactory.create(parent_location=parent.usage_key, category="word_cloud", display_name="untitled")
root_dir = path(mkdtemp_clean())
@@ -383,15 +383,15 @@ def test_import_after_renaming_xml_data(self):
create_if_not_present=True
)
all_items = split_store.get_items(course_after_rename[0].id, qualifiers={'category': 'chapter'})
- renamed_chapter = [item for item in all_items if item.location.block_id == 'renamed_chapter'][0]
+ renamed_chapter = [item for item in all_items if item.usage_key.block_id == 'renamed_chapter'][0]
self.assertIsNotNone(renamed_chapter.published_on)
self.assertIsNotNone(renamed_chapter.parent)
- self.assertIn(renamed_chapter.location, course_after_rename[0].children)
+ self.assertIn(renamed_chapter.usage_key, course_after_rename[0].children)
original_chapter = [item for item in all_items
- if item.location.block_id == 'b9870b9af59841a49e6e02765d0e3bbf'][0]
+ if item.usage_key.block_id == 'b9870b9af59841a49e6e02765d0e3bbf'][0]
self.assertIsNone(original_chapter.published_on)
self.assertIsNone(original_chapter.parent)
- self.assertNotIn(original_chapter.location, course_after_rename[0].children)
+ self.assertNotIn(original_chapter.usage_key, course_after_rename[0].children)
def test_empty_data_roundtrip(self):
"""
@@ -411,7 +411,7 @@ def test_empty_data_roundtrip(self):
# Create a block, and ensure that its `data` field is empty
word_cloud = BlockFactory.create(
- parent_location=parent.location, category="word_cloud", display_name="untitled")
+ parent_location=parent.usage_key, category="word_cloud", display_name="untitled")
del word_cloud.data
self.assertEqual(word_cloud.data, '')
@@ -498,13 +498,13 @@ def test_export_course_no_xml_attributes(self):
# create OpenAssessmentBlock:
open_assessment = BlockFactory.create(
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
category="openassessment",
display_name="untitled",
)
# convert it to draft
draft_open_assessment = self.store.convert_to_draft(
- open_assessment.location, self.user.id
+ open_assessment.usage_key, self.user.id
)
# note that it has no `xml_attributes` attribute
@@ -531,12 +531,12 @@ def setUp(self):
super().setUp()
# save locs not items b/c the items won't have the subsequently created children in them until refetched
self.chapter_loc = self.store.create_child(
- self.user.id, self.course.location, 'chapter', 'test_chapter'
- ).location
+ self.user.id, self.course.usage_key, 'chapter', 'test_chapter'
+ ).usage_key
self.seq_loc = self.store.create_child(
self.user.id, self.chapter_loc, 'sequential', 'test_seq'
- ).location
- self.vert_loc = self.store.create_child(self.user.id, self.seq_loc, 'vertical', 'test_vert').location
+ ).usage_key
+ self.vert_loc = self.store.create_child(self.user.id, self.seq_loc, 'vertical', 'test_vert').usage_key
# now create some things quasi like the toy course had
self.problem = self.store.create_child(
self.user.id, self.vert_loc, 'problem', 'test_problem', fields={
@@ -570,7 +570,7 @@ def setUp(self):
"answers": [{"id": "yes", "text": "Yes"}, {"id": "no", "text": "No"}],
}
)
- self.course = self.store.publish(self.course.location, self.user.id)
+ self.course = self.store.publish(self.course.usage_key, self.user.id)
def check_components_on_page(self, component_types, expected_types):
"""
@@ -655,7 +655,7 @@ def test_export_with_orphan_vertical(self):
information but the draft child xblock has parent information.
"""
# Make an existing unit a draft
- self.problem = self.store.unpublish(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.usage_key, self.user.id)
root_dir = path(mkdtemp_clean())
export_course_to_xml(self.store, None, self.course.id, root_dir, 'test_export')
@@ -726,20 +726,20 @@ def test_get_items(self):
Unfortunately, None = published for the revision field, so get_items() would return
both draft and non-draft copies.
"""
- self.problem = self.store.unpublish(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.usage_key, self.user.id)
# Query get_items() and find the html item. This should just return back a single item (not 2).
direct_store_items = self.store.get_items(
self.course.id, revision=ModuleStoreEnum.RevisionOption.published_only
)
- items_from_direct_store = [item for item in direct_store_items if item.location == self.problem.location]
+ items_from_direct_store = [item for item in direct_store_items if item.usage_key == self.problem.usage_key]
self.assertEqual(len(items_from_direct_store), 0)
# Fetch from the draft store.
draft_store_items = self.store.get_items(
self.course.id, revision=ModuleStoreEnum.RevisionOption.draft_only
)
- items_from_draft_store = [item for item in draft_store_items if item.location == self.problem.location]
+ items_from_draft_store = [item for item in draft_store_items if item.usage_key == self.problem.usage_key]
self.assertEqual(len(items_from_draft_store), 1)
def test_draft_metadata(self):
@@ -752,31 +752,31 @@ def test_draft_metadata(self):
course = self.store.update_item(self.course, self.user.id)
course.graceperiod = timedelta(days=1, hours=5, minutes=59, seconds=59)
course = self.store.update_item(course, self.user.id)
- problem = self.store.get_item(self.problem.location)
+ problem = self.store.get_item(self.problem.usage_key)
self.assertEqual(problem.graceperiod, course.graceperiod)
self.assertNotIn('graceperiod', own_metadata(problem))
- self.store.convert_to_draft(problem.location, self.user.id)
+ self.store.convert_to_draft(problem.usage_key, self.user.id)
# refetch to check metadata
- problem = self.store.get_item(problem.location)
+ problem = self.store.get_item(problem.usage_key)
self.assertEqual(problem.graceperiod, course.graceperiod)
self.assertNotIn('graceperiod', own_metadata(problem))
# publish block
- self.store.publish(problem.location, self.user.id)
+ self.store.publish(problem.usage_key, self.user.id)
# refetch to check metadata
- problem = self.store.get_item(problem.location)
+ problem = self.store.get_item(problem.usage_key)
self.assertEqual(problem.graceperiod, course.graceperiod)
self.assertNotIn('graceperiod', own_metadata(problem))
# put back in draft and change metadata and see if it's now marked as 'own_metadata'
- self.store.convert_to_draft(problem.location, self.user.id)
- problem = self.store.get_item(problem.location)
+ self.store.convert_to_draft(problem.usage_key, self.user.id)
+ problem = self.store.get_item(problem.usage_key)
new_graceperiod = timedelta(hours=1)
@@ -791,17 +791,17 @@ def test_draft_metadata(self):
self.store.update_item(problem, self.user.id)
# read back to make sure it reads as 'own-metadata'
- problem = self.store.get_item(problem.location)
+ problem = self.store.get_item(problem.usage_key)
self.assertIn('graceperiod', own_metadata(problem))
self.assertEqual(problem.graceperiod, new_graceperiod)
# republish
- self.store.publish(problem.location, self.user.id)
+ self.store.publish(problem.usage_key, self.user.id)
# and re-read and verify 'own-metadata'
- self.store.convert_to_draft(problem.location, self.user.id)
- problem = self.store.get_item(problem.location)
+ self.store.convert_to_draft(problem.usage_key, self.user.id)
+ problem = self.store.get_item(problem.usage_key)
self.assertIn('graceperiod', own_metadata(problem))
self.assertEqual(problem.graceperiod, new_graceperiod)
@@ -812,10 +812,10 @@ def test_get_depth_with_drafts(self):
self.assertEqual(num_drafts, 0)
# put into draft
- self.problem = self.store.unpublish(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.usage_key, self.user.id)
# make sure we can query that item and verify that it is a draft
- draft_problem = self.store.get_item(self.problem.location)
+ draft_problem = self.store.get_item(self.problem.usage_key)
self.assertEqual(self.store.has_published_version(draft_problem), False)
# now requery with depth
@@ -1006,7 +1006,7 @@ def test_course_handouts_rewrites(self):
)
# get block info (json)
- resp = self.client.get(get_url('xblock_handler', handouts.location))
+ resp = self.client.get(get_url('xblock_handler', handouts.usage_key))
# make sure we got a successful response
self.assertEqual(resp.status_code, 200)
@@ -1397,7 +1397,7 @@ def test_course_factory(self):
def test_item_factory(self):
"""Test that the item factory works correctly."""
course = CourseFactory.create()
- item = BlockFactory.create(parent_location=course.location)
+ item = BlockFactory.create(parent_location=course.usage_key)
self.assertIsInstance(item, SequenceBlock)
def test_create_block(self):
@@ -1405,7 +1405,7 @@ def test_create_block(self):
course = CourseFactory.create()
section_data = {
- 'parent_locator': str(course.location),
+ 'parent_locator': str(course.usage_key),
'category': 'chapter',
'display_name': 'Section One',
}
@@ -1423,15 +1423,15 @@ def test_create_block(self):
def test_hide_xblock_from_toc_via_handler(self, hide_from_toc):
"""Test that the hide_from_toc field can be set via the xblock_handler."""
course = CourseFactory.create()
- sequential = BlockFactory.create(parent_location=course.location)
+ sequential = BlockFactory.create(parent_location=course.usage_key)
data = {
"metadata": {
"hide_from_toc": hide_from_toc
}
}
- response = self.client.ajax_post(get_url("xblock_handler", sequential.location), data)
- sequential = self.store.get_item(sequential.location)
+ response = self.client.ajax_post(get_url("xblock_handler", sequential.usage_key), data)
+ sequential = self.store.get_item(sequential.usage_key)
self.assertEqual(response.status_code, 200)
self.assertEqual(hide_from_toc, sequential.hide_from_toc)
@@ -1441,7 +1441,7 @@ def test_capa_block(self):
course = CourseFactory.create()
problem_data = {
- 'parent_locator': str(course.location),
+ 'parent_locator': str(course.usage_key),
'category': 'problem'
}
@@ -1632,10 +1632,10 @@ def test_forum_id_generation(self):
discussion_item = self.store.create_item(self.user.id, course.id, 'discussion', 'new_component')
# now fetch it from the modulestore to instantiate its descriptor
- fetched = self.store.get_item(discussion_item.location)
+ fetched = self.store.get_item(discussion_item.usage_key)
# refetch it to be safe
- refetched = self.store.get_item(discussion_item.location)
+ refetched = self.store.get_item(discussion_item.usage_key)
# and make sure the same discussion items have the same discussion ids
self.assertEqual(fetched.discussion_id, discussion_item.discussion_id)
@@ -1662,11 +1662,11 @@ def test_metadata_inheritance(self):
# crate a new block and add it as a child to a vertical
parent = verticals[0]
new_block = self.store.create_child(
- self.user.id, parent.location, 'html', 'new_component'
+ self.user.id, parent.usage_key, 'html', 'new_component'
)
# flush the cache
- new_block = self.store.get_item(new_block.location)
+ new_block = self.store.get_item(new_block.usage_key)
# check for grace period definition which should be defined at the course level
self.assertEqual(parent.graceperiod, new_block.graceperiod)
@@ -1682,13 +1682,13 @@ def test_metadata_inheritance(self):
self.store.update_item(new_block, self.user.id)
# flush the cache and refetch
- new_block = self.store.get_item(new_block.location)
+ new_block = self.store.get_item(new_block.usage_key)
self.assertEqual(timedelta(1), new_block.graceperiod)
def test_default_metadata_inheritance(self):
course = CourseFactory.create()
- vertical = BlockFactory.create(parent_location=course.location)
+ vertical = BlockFactory.create(parent_location=course.usage_key)
course.children.append(vertical)
# in memory
self.assertIsNotNone(course.start)
@@ -1698,8 +1698,8 @@ def test_default_metadata_inheritance(self):
self.assertIn('GRADE_CUTOFFS', course.grading_policy)
# by fetching
- fetched_course = self.store.get_item(course.location)
- fetched_item = self.store.get_item(vertical.location)
+ fetched_course = self.store.get_item(course.usage_key)
+ fetched_item = self.store.get_item(vertical.usage_key)
self.assertIsNotNone(fetched_course.start)
self.assertEqual(course.start, fetched_course.start)
self.assertEqual(fetched_course.start, fetched_item.start)
@@ -1772,7 +1772,7 @@ def setUp(self):
video_data = VideoBlock.parse_video_xml(video_sample_xml)
video_data.pop('source')
self.video_block = BlockFactory.create(
- parent_location=course.location, category='video',
+ parent_location=course.usage_key, category='video',
**video_data
)
@@ -1794,7 +1794,7 @@ def test_metadata_not_persistence(self):
'track'
}
- location = self.video_block.location
+ location = self.video_block.usage_key
for field_name in attrs_to_strip:
delattr(self.video_block, field_name)
@@ -2113,7 +2113,7 @@ def test_video_license_export(self):
content_store = contentstore()
root_dir = path(mkdtemp_clean())
video_block = BlockFactory.create(
- parent_location=self.course.location, category='video',
+ parent_location=self.course.usage_key, category='video',
license="all-rights-reserved"
)
export_course_to_xml(self.store, content_store, self.course.id, root_dir, 'test_license')
diff --git a/cms/djangoapps/contentstore/tests/test_core_caching.py b/cms/djangoapps/contentstore/tests/test_core_caching.py
index e6b23c2deeed..bcf9ed9dc205 100644
--- a/cms/djangoapps/contentstore/tests/test_core_caching.py
+++ b/cms/djangoapps/contentstore/tests/test_core_caching.py
@@ -14,11 +14,11 @@ class Content:
Mock cached content
"""
def __init__(self, location, content):
- self.location = location
+ self.usage_key = location
self.content = content
def get_id(self):
- return self.location.to_deprecated_son()
+ return self.usage_key.to_deprecated_son()
class CachingTestCase(TestCase):
diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py
index 876bb37ee783..27fffbc8f007 100644
--- a/cms/djangoapps/contentstore/tests/test_course_settings.py
+++ b/cms/djangoapps/contentstore/tests/test_course_settings.py
@@ -952,8 +952,8 @@ def test_delete_grace_period(self):
def test_update_section_grader_type(self, send_signal, tracker, uuid):
uuid.return_value = 'mockUUID'
# Get the block and the section_grader_type and assert they are the default values
- block = modulestore().get_item(self.course.location)
- section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)
+ block = modulestore().get_item(self.course.usage_key)
+ section_grader_type = CourseGradingModel.get_section_grader_type(self.course.usage_key)
self.assertEqual('notgraded', section_grader_type['graderType'])
self.assertEqual(None, block.format)
@@ -961,8 +961,8 @@ def test_update_section_grader_type(self, send_signal, tracker, uuid):
# Change the default grader type to Homework, which should also mark the section as graded
CourseGradingModel.update_section_grader_type(self.course, 'Homework', self.user)
- block = modulestore().get_item(self.course.location)
- section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)
+ block = modulestore().get_item(self.course.usage_key)
+ section_grader_type = CourseGradingModel.get_section_grader_type(self.course.usage_key)
grading_policy_1 = self._grading_policy_hash_for_course()
self.assertEqual('Homework', section_grader_type['graderType'])
@@ -971,8 +971,8 @@ def test_update_section_grader_type(self, send_signal, tracker, uuid):
# Change the grader type back to notgraded, which should also unmark the section as graded
CourseGradingModel.update_section_grader_type(self.course, 'notgraded', self.user)
- block = modulestore().get_item(self.course.location)
- section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)
+ block = modulestore().get_item(self.course.usage_key)
+ section_grader_type = CourseGradingModel.get_section_grader_type(self.course.usage_key)
grading_policy_2 = self._grading_policy_hash_for_course()
self.assertEqual('notgraded', section_grader_type['graderType'])
@@ -1077,7 +1077,7 @@ def setup_test_set_get_section_grader_ajax(self):
# see if test makes sense
self.assertGreater(len(sections), 0, "No sections found")
section = sections[0] # just take the first one
- return reverse_usage_url('xblock_handler', section.location)
+ return reverse_usage_url('xblock_handler', section.usage_key)
def test_set_get_section_grader_ajax(self):
"""
diff --git a/cms/djangoapps/contentstore/tests/test_courseware_index.py b/cms/djangoapps/contentstore/tests/test_courseware_index.py
index 3ab3fa373f81..ddb2fa203e86 100644
--- a/cms/djangoapps/contentstore/tests/test_courseware_index.py
+++ b/cms/djangoapps/contentstore/tests/test_courseware_index.py
@@ -51,7 +51,7 @@ def create_children(store, parent, category, load_factor):
created_count = 0
for child_index in range(load_factor):
child_object = BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
category=category,
display_name=f"{category} {child_index} {time.clock()}", # lint-amnesty, pylint: disable=no-member
modulestore=store,
@@ -153,7 +153,7 @@ def setup_course_base(self, store):
)
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name="Week 1",
modulestore=store,
@@ -161,7 +161,7 @@ def setup_course_base(self, store):
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name="Lesson 1",
modulestore=store,
@@ -169,7 +169,7 @@ def setup_course_base(self, store):
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category='vertical',
display_name='Subsection 1',
modulestore=store,
@@ -178,7 +178,7 @@ def setup_course_base(self, store):
)
# unspecified start - should inherit from container
self.html_unit = BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category="html",
display_name="Html Content",
modulestore=store,
@@ -213,7 +213,7 @@ def _test_indexing_course(self, store):
self.assertEqual(response["total"], 3)
# Publish the vertical as is, and any unpublished children should now be available
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 4)
@@ -221,14 +221,14 @@ def _test_indexing_course(self, store):
def _test_not_indexing_unpublished_content(self, store):
""" add a new one, only appers in index once added """
# Publish the vertical to start with
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 4)
# Now add a new unit to the existing vertical
BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category="html",
display_name="Some other content",
publish_item=False,
@@ -240,7 +240,7 @@ def _test_not_indexing_unpublished_content(self, store):
# Now publish it and we should find it
# Publish the vertical as is, and everything should be available
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 5)
@@ -265,19 +265,19 @@ def _test_delete_course_from_search_index_after_course_deletion(self, store): #
def _test_deleting_item(self, store):
""" test deleting an item """
# Publish the vertical to start with
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 4)
# just a delete should not change anything
- self.delete_item(store, self.html_unit.location)
+ self.delete_item(store, self.html_unit.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 4)
# but after publishing, we should no longer find the html_unit
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 3)
@@ -288,17 +288,17 @@ def _test_start_date_propagation(self, store):
later_date = self.vertical.start
# Publish the vertical
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search()
self.assertEqual(response["total"], 4)
results = response["results"]
date_map = {
- str(self.chapter.location): early_date,
- str(self.sequential.location): early_date,
- str(self.vertical.location): later_date,
- str(self.html_unit.location): later_date,
+ str(self.chapter.usage_key): early_date,
+ str(self.sequential.usage_key): early_date,
+ str(self.vertical.usage_key): later_date,
+ str(self.html_unit.usage_key): later_date,
}
for result in results:
self.assertEqual(result["data"]["start_date"], date_map[result["data"]["id"]])
@@ -311,13 +311,13 @@ def _test_search_disabled(self, store):
def _test_time_based_index(self, store):
""" Make sure that a time based request to index does not index anything too old """
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
indexed_count = self.reindex_course(store)
self.assertEqual(indexed_count, 4)
# Add a new sequential
sequential2 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name='Section 2',
modulestore=store,
@@ -327,14 +327,14 @@ def _test_time_based_index(self, store):
# add a new vertical
vertical2 = BlockFactory.create(
- parent_location=sequential2.location,
+ parent_location=sequential2.usage_key,
category='vertical',
display_name='Subsection 2',
modulestore=store,
publish_item=True,
)
BlockFactory.create(
- parent_location=vertical2.location,
+ parent_location=vertical2.usage_key,
category="html",
display_name="Some other content",
publish_item=False,
@@ -342,7 +342,7 @@ def _test_time_based_index(self, store):
)
before_time = datetime.now(UTC)
- self.publish_item(store, vertical2.location)
+ self.publish_item(store, vertical2.usage_key)
# index based on time, will include an index of the origin sequential
# because it is in a common subtree but not of the original vertical
# because the original sequential's subtree is too old
@@ -415,7 +415,7 @@ def _test_course_about_mode_index(self, store):
def _test_course_location_info(self, store):
""" Test that course location information is added to index """
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
self.reindex_course(store)
response = self.search(query_string="Html Content")
self.assertEqual(response["total"], 1)
@@ -427,7 +427,7 @@ def _test_course_location_info(self, store):
def _test_course_location_null(self, store):
""" Test that course location information is added to index """
sequential2 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name=None,
modulestore=store,
@@ -436,14 +436,14 @@ def _test_course_location_null(self, store):
)
# add a new vertical
vertical2 = BlockFactory.create(
- parent_location=sequential2.location,
+ parent_location=sequential2.usage_key,
category='vertical',
display_name='Subsection 2',
modulestore=store,
publish_item=True,
)
BlockFactory.create(
- parent_location=vertical2.location,
+ parent_location=vertical2.usage_key,
category="html",
display_name="Find Me",
publish_item=True,
@@ -460,7 +460,7 @@ def _test_course_location_null(self, store):
@patch('django.conf.settings.SEARCH_ENGINE', 'search.tests.utils.ErroringIndexEngine')
def _test_exception(self, store):
""" Test that exception within indexing yields a SearchIndexingError """
- self.publish_item(store, self.vertical.location)
+ self.publish_item(store, self.vertical.usage_key)
with self.assertRaises(SearchIndexingError):
self.reindex_course(store)
@@ -547,7 +547,7 @@ def _do_test_large_course_deletion(self, store, load_factor):
""" Test that deleting items from a course works even when present within a very large course """
def id_list(top_parent_object):
""" private function to get ids from object down the tree """
- list_of_ids = [str(top_parent_object.location)]
+ list_of_ids = [str(top_parent_object.usage_key)]
for child in top_parent_object.get_children():
list_of_ids.extend(id_list(child))
return list_of_ids
@@ -565,7 +565,7 @@ def id_list(top_parent_object):
# delete the first chapter
chapter_to_delete = course.get_children()[0]
- self.delete_item(store, chapter_to_delete.location)
+ self.delete_item(store, chapter_to_delete.usage_key)
# index and check correctness
CoursewareSearchIndexer.do_course_reindex(store, course.id)
@@ -608,21 +608,21 @@ def setUpClass(cls):
cls.course = CourseFactory.create(start=datetime(2015, 3, 1, tzinfo=UTC))
cls.chapter = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
category='chapter',
display_name="Week 1",
publish_item=True,
start=datetime(2015, 3, 1, tzinfo=UTC),
)
cls.sequential = BlockFactory.create(
- parent_location=cls.chapter.location,
+ parent_location=cls.chapter.usage_key,
category='sequential',
display_name="Lesson 1",
publish_item=True,
start=datetime(2015, 3, 1, tzinfo=UTC),
)
cls.vertical = BlockFactory.create(
- parent_location=cls.sequential.location,
+ parent_location=cls.sequential.usage_key,
category='vertical',
display_name='Subsection 1',
publish_item=True,
@@ -630,7 +630,7 @@ def setUpClass(cls):
)
# unspecified start - should inherit from container
cls.html_unit = BlockFactory.create(
- parent_location=cls.vertical.location,
+ parent_location=cls.vertical.usage_key,
category="html",
display_name="Html Content",
publish_item=False,
@@ -639,14 +639,14 @@ def setUpClass(cls):
cls.library = LibraryFactory.create()
cls.library_block1 = BlockFactory.create(
- parent_location=cls.library.location,
+ parent_location=cls.library.usage_key,
category="html",
display_name="Html Content",
publish_item=False,
)
cls.library_block2 = BlockFactory.create(
- parent_location=cls.library.location,
+ parent_location=cls.library.usage_key,
category="html",
display_name="Html Content 2",
publish_item=False,
@@ -680,11 +680,11 @@ def test_task_indexing_course(self):
def test_task_library_update(self):
""" Making sure that the receiver correctly fires off the task when invoked by signal """
searcher = SearchEngine.get_search_engine(LibrarySearchIndexer.INDEX_NAME)
- library_search_key = str(normalize_key_for_search(self.library.location.library_key))
+ library_search_key = str(normalize_key_for_search(self.library.usage_key.library_key))
response = searcher.search(field_dictionary={"library": library_search_key})
self.assertEqual(response["total"], 0)
- listen_for_library_update(self, self.library.location.library_key)
+ listen_for_library_update(self, self.library.usage_key.library_key)
# Note that this test will only succeed if celery is working in inline mode
response = searcher.search(field_dictionary={"library": library_search_key})
@@ -727,7 +727,7 @@ def setup_course_base(self, store):
self.library = LibraryFactory.create(modulestore=store)
self.html_unit1 = BlockFactory.create(
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
category="html",
display_name="Html Content",
modulestore=store,
@@ -735,7 +735,7 @@ def setup_course_base(self, store):
)
self.html_unit2 = BlockFactory.create(
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
category="html",
display_name="Html Content 2",
modulestore=store,
@@ -746,11 +746,11 @@ def setup_course_base(self, store):
def _get_default_search(self):
""" Returns field_dictionary for default search """
- return {"library": str(self.library.location.library_key.replace(version_guid=None, branch=None))}
+ return {"library": str(self.library.usage_key.library_key.replace(version_guid=None, branch=None))}
def reindex_library(self, store):
""" kick off complete reindex of the course """
- return LibrarySearchIndexer.do_library_reindex(store, self.library.location.library_key)
+ return LibrarySearchIndexer.do_library_reindex(store, self.library.usage_key.library_key)
def _get_contents(self, response):
""" Extracts contents from search response """
@@ -776,7 +776,7 @@ def _test_creating_item(self, store):
# updating a library item causes immediate reindexing
data = "Some data"
BlockFactory.create(
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
category="html",
display_name="Html Content 3",
data=data,
@@ -813,7 +813,7 @@ def _test_deleting_item(self, store):
self.assertEqual(response["total"], 2)
# deleting a library item causes immediate reindexing
- self.delete_item(store, self.html_unit1.location)
+ self.delete_item(store, self.html_unit1.usage_key)
self.reindex_library(store)
response = self.search()
self.assertEqual(response["total"], 1)
@@ -876,7 +876,7 @@ def _setup_course_with_content(self):
Set up course with html content in it.
"""
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name="Week 1",
modulestore=self.store,
@@ -885,7 +885,7 @@ def _setup_course_with_content(self):
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name="Lesson 1",
modulestore=self.store,
@@ -894,7 +894,7 @@ def _setup_course_with_content(self):
)
self.sequential2 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name="Lesson 2",
modulestore=self.store,
@@ -903,7 +903,7 @@ def _setup_course_with_content(self):
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category='vertical',
display_name='Subsection 1',
modulestore=self.store,
@@ -912,7 +912,7 @@ def _setup_course_with_content(self):
)
self.vertical2 = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category='vertical',
display_name='Subsection 2',
modulestore=self.store,
@@ -921,7 +921,7 @@ def _setup_course_with_content(self):
)
self.vertical3 = BlockFactory.create(
- parent_location=self.sequential2.location,
+ parent_location=self.sequential2.usage_key,
category='vertical',
display_name='Subsection 3',
modulestore=self.store,
@@ -931,7 +931,7 @@ def _setup_course_with_content(self):
# unspecified start - should inherit from container
self.html_unit1 = BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category="html",
display_name="Html Content 1",
modulestore=self.store,
@@ -940,7 +940,7 @@ def _setup_course_with_content(self):
self.html_unit1.parent = self.vertical
self.html_unit2 = BlockFactory.create(
- parent_location=self.vertical2.location,
+ parent_location=self.vertical2.usage_key,
category="html",
display_name="Html Content 2",
modulestore=self.store,
@@ -949,7 +949,7 @@ def _setup_course_with_content(self):
self.html_unit2.parent = self.vertical2
self.html_unit3 = BlockFactory.create(
- parent_location=self.vertical2.location,
+ parent_location=self.vertical2.usage_key,
category="html",
display_name="Html Content 3",
modulestore=self.store,
@@ -966,7 +966,7 @@ def _setup_split_test_block(self):
c2_url = self.course.id.make_usage_key("vertical", "condition_2_vertical")
self.split_test_unit = BlockFactory.create(
- parent_location=self.vertical3.location,
+ parent_location=self.vertical3.usage_key,
category='split_test',
user_partition_id=0,
display_name="Test Content Experiment 1",
@@ -974,7 +974,7 @@ def _setup_split_test_block(self):
)
self.condition_0_vertical = BlockFactory.create(
- parent_location=self.split_test_unit.location,
+ parent_location=self.split_test_unit.usage_key,
category="vertical",
display_name="Group ID 2",
location=c0_url,
@@ -982,7 +982,7 @@ def _setup_split_test_block(self):
self.condition_0_vertical.parent = self.vertical3
self.condition_1_vertical = BlockFactory.create(
- parent_location=self.split_test_unit.location,
+ parent_location=self.split_test_unit.usage_key,
category="vertical",
display_name="Group ID 3",
location=c1_url,
@@ -990,7 +990,7 @@ def _setup_split_test_block(self):
self.condition_1_vertical.parent = self.vertical3
self.condition_2_vertical = BlockFactory.create(
- parent_location=self.split_test_unit.location,
+ parent_location=self.split_test_unit.usage_key,
category="vertical",
display_name="Group ID 4",
location=c2_url,
@@ -998,7 +998,7 @@ def _setup_split_test_block(self):
self.condition_2_vertical.parent = self.vertical3
self.html_unit4 = BlockFactory.create(
- parent_location=self.condition_0_vertical.location,
+ parent_location=self.condition_0_vertical.usage_key,
category="html",
display_name="Split A",
publish_item=True,
@@ -1006,7 +1006,7 @@ def _setup_split_test_block(self):
self.html_unit4.parent = self.condition_0_vertical
self.html_unit5 = BlockFactory.create(
- parent_location=self.condition_1_vertical.location,
+ parent_location=self.condition_1_vertical.usage_key,
category="html",
display_name="Split B",
publish_item=True,
@@ -1014,7 +1014,7 @@ def _setup_split_test_block(self):
self.html_unit5.parent = self.condition_1_vertical
self.html_unit6 = BlockFactory.create(
- parent_location=self.condition_2_vertical.location,
+ parent_location=self.condition_2_vertical.usage_key,
category="html",
display_name="Split C",
publish_item=True,
@@ -1080,7 +1080,7 @@ def _html_group_result(self, html_unit, content_groups):
"""
return {
'course_name': self.course.display_name,
- 'id': str(html_unit.location),
+ 'id': str(html_unit.usage_key),
'content': {'html_content': '', 'display_name': html_unit.display_name},
'course': str(self.course.id),
'location': [
@@ -1100,7 +1100,7 @@ def _html_experiment_group_result(self, html_unit, content_groups):
"""
return {
'course_name': self.course.display_name,
- 'id': str(html_unit.location),
+ 'id': str(html_unit.usage_key),
'content': {'html_content': '', 'display_name': html_unit.display_name},
'course': str(self.course.id),
'location': [
@@ -1129,7 +1129,7 @@ def _vertical_experiment_group_result(self, vertical, content_groups):
],
'content_type': 'Sequence',
'content_groups': content_groups,
- 'id': str(vertical.location),
+ 'id': str(vertical.usage_key),
'course_name': self.course.display_name,
'org': self.course.org
}
@@ -1140,7 +1140,7 @@ def _html_nogroup_result(self, html_unit):
"""
return {
'course_name': self.course.display_name,
- 'id': str(html_unit.location),
+ 'id': str(html_unit.usage_key),
'content': {'html_content': '', 'display_name': html_unit.display_name},
'course': str(self.course.id),
'location': [
@@ -1180,12 +1180,12 @@ def test_content_group_gets_indexed(self):
group_access_content = {'group_access': {666: [1]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit1.location),
+ reverse_usage_url("xblock_handler", self.html_unit1.usage_key),
data={'metadata': group_access_content}
)
- self.publish_item(self.store, self.html_unit1.location)
- self.publish_item(self.store, self.split_test_unit.location)
+ self.publish_item(self.store, self.html_unit1.usage_key)
+ self.publish_item(self.store, self.split_test_unit.usage_key)
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
self.reindex_course(self.store)
@@ -1250,11 +1250,11 @@ def test_content_group_not_indexed_on_delete(self):
group_access_content = {'group_access': {666: [1]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit1.location),
+ reverse_usage_url("xblock_handler", self.html_unit1.usage_key),
data={'metadata': group_access_content}
)
- self.publish_item(self.store, self.html_unit1.location)
+ self.publish_item(self.store, self.html_unit1.usage_key)
# Checking group indexed correctly
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
@@ -1267,11 +1267,11 @@ def test_content_group_not_indexed_on_delete(self):
empty_group_access = {'group_access': {}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit1.location),
+ reverse_usage_url("xblock_handler", self.html_unit1.usage_key),
data={'metadata': empty_group_access}
)
- self.publish_item(self.store, self.html_unit1.location)
+ self.publish_item(self.store, self.html_unit1.usage_key)
# Checking group removed and not indexed any more
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
@@ -1285,11 +1285,11 @@ def test_group_indexed_only_on_assigned_html_block(self):
""" indexing course with content groups assigned to one of multiple html units """
group_access_content = {'group_access': {666: [1]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit1.location),
+ reverse_usage_url("xblock_handler", self.html_unit1.usage_key),
data={'metadata': group_access_content}
)
- self.publish_item(self.store, self.html_unit1.location)
+ self.publish_item(self.store, self.html_unit1.usage_key)
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
self.reindex_course(self.store)
@@ -1305,16 +1305,16 @@ def test_different_groups_indexed_on_assigned_html_blocks(self):
group_access_content_2 = {'group_access': {666: [0]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit1.location),
+ reverse_usage_url("xblock_handler", self.html_unit1.usage_key),
data={'metadata': group_access_content_1}
)
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit2.location),
+ reverse_usage_url("xblock_handler", self.html_unit2.usage_key),
data={'metadata': group_access_content_2}
)
- self.publish_item(self.store, self.html_unit1.location)
- self.publish_item(self.store, self.html_unit2.location)
+ self.publish_item(self.store, self.html_unit1.usage_key)
+ self.publish_item(self.store, self.html_unit2.usage_key)
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
self.reindex_course(self.store)
@@ -1334,16 +1334,16 @@ def test_different_groups_indexed_on_same_vertical_html_blocks(self):
group_access_content_2 = {'group_access': {666: [0]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit2.location),
+ reverse_usage_url("xblock_handler", self.html_unit2.usage_key),
data={'metadata': group_access_content_1}
)
self.client.ajax_post(
- reverse_usage_url("xblock_handler", self.html_unit3.location),
+ reverse_usage_url("xblock_handler", self.html_unit3.usage_key),
data={'metadata': group_access_content_2}
)
- self.publish_item(self.store, self.html_unit2.location)
- self.publish_item(self.store, self.html_unit3.location)
+ self.publish_item(self.store, self.html_unit2.usage_key)
+ self.publish_item(self.store, self.html_unit3.usage_key)
with patch(settings.SEARCH_ENGINE + '.index') as mock_index:
self.reindex_course(self.store)
diff --git a/cms/djangoapps/contentstore/tests/test_crud.py b/cms/djangoapps/contentstore/tests/test_crud.py
index 792d0386ac48..116b13cef448 100644
--- a/cms/djangoapps/contentstore/tests/test_crud.py
+++ b/cms/djangoapps/contentstore/tests/test_crud.py
@@ -26,7 +26,7 @@ def test_get_templates(self):
def test_get_some_templates(self):
course = CourseFactory.create()
- htmlblock = BlockFactory.create(category="html", parent_location=course.location)
+ htmlblock = BlockFactory.create(category="html", parent_location=course.usage_key)
self.assertEqual(len(SequenceBlock.templates()), 0)
self.assertGreater(len(htmlblock.templates()), 0)
@@ -50,14 +50,14 @@ def test_factories(self):
self.assertEqual(course_from_store.id.run, '2014')
test_chapter = BlockFactory.create(
- parent_location=test_course.location,
+ parent_location=test_course.usage_key,
category='chapter',
display_name='chapter 1'
)
self.assertIsInstance(test_chapter, SequenceBlock)
# refetch parent which should now point to child
test_course = self.store.get_course(test_course.id.version_agnostic())
- self.assertIn(test_chapter.location, test_course.children)
+ self.assertIn(test_chapter.usage_key, test_course.children)
with self.assertRaises(DuplicateCourseError):
CourseFactory.create(
@@ -106,7 +106,7 @@ def test_delete_course(self):
user_id=ModuleStoreEnum.UserID.test,
)
BlockFactory.create(
- parent_location=test_course.location,
+ parent_location=test_course.usage_key,
category='chapter',
display_name='chapter 1'
)
@@ -115,7 +115,7 @@ def test_delete_course(self):
# verify it can be retrieved by id
self.assertIsInstance(self.store.get_course(id_locator), CourseBlock)
# TODO reenable when split_draft supports getting specific versions
- # guid_locator = test_course.location.course_agnostic()
+ # guid_locator = test_course.usage_key.course_agnostic()
# Verify it can be retrieved by guid
# self.assertIsInstance(self.store.get_item(guid_locator), CourseBlock)
self.store.delete_course(id_locator, ModuleStoreEnum.UserID.test)
diff --git a/cms/djangoapps/contentstore/tests/test_exams.py b/cms/djangoapps/contentstore/tests/test_exams.py
index 823038957714..f65a1ce961a2 100644
--- a/cms/djangoapps/contentstore/tests/test_exams.py
+++ b/cms/djangoapps/contentstore/tests/test_exams.py
@@ -120,7 +120,7 @@ def test_publishing_exam(self, is_proctored_exam, is_practice_exam,
expected_exams = [{
'course_id': self.course_key,
- 'content_id': str(sequence.location),
+ 'content_id': str(sequence.usage_key),
'exam_name': sequence.display_name,
'time_limit_mins': sequence.default_time_limit_minutes,
'due_date': expected_due_date,
@@ -155,7 +155,7 @@ def test_dangling_exam(self, mock_patch_course_exams):
is_proctored_enabled=True,
hide_after_due=False,
)
- self.store.delete_item(self.chapter.location, self.user.id)
+ self.store.delete_item(self.chapter.usage_key, self.user.id)
listen_for_course_publish(self, self.course.id)
mock_patch_course_exams.assert_called_once_with([], self.course_key)
diff --git a/cms/djangoapps/contentstore/tests/test_filters.py b/cms/djangoapps/contentstore/tests/test_filters.py
index 4011ae728b34..cdf0bab0ffff 100644
--- a/cms/djangoapps/contentstore/tests/test_filters.py
+++ b/cms/djangoapps/contentstore/tests/test_filters.py
@@ -41,10 +41,10 @@ def setUp(self): # pylint: disable=arguments-differ
self.upload_date = datetime(2013, 6, 1, 10, 30, tzinfo=UTC)
self.content_type = 'image/jpg'
self.course_key = CourseLocator('org', 'class', 'run')
- self.location = self.course_key.make_asset_key('asset', 'my_file_name.jpg')
+ self.usage_key = self.course_key.make_asset_key('asset', 'my_file_name.jpg')
self.thumbnail_location = self.course_key.make_asset_key('thumbnail', 'my_file_name_thumb.jpg')
- self.asset_url = StaticContent.serialize_asset_key_with_slash(self.location)
+ self.asset_url = StaticContent.serialize_asset_key_with_slash(self.usage_key)
@override_settings(
OPEN_EDX_FILTERS_CONFIG={
@@ -68,7 +68,7 @@ def test_lms_url_requested_filter_executed(self):
"my_file",
self.content_type,
self.upload_date,
- self.location,
+ self.usage_key,
self.thumbnail_location,
True,
self.course_key
@@ -89,7 +89,7 @@ def test_lms_url_requested_without_filter_configuration(self):
"my_file",
self.content_type,
self.upload_date,
- self.location,
+ self.usage_key,
self.thumbnail_location,
True,
self.course_key
diff --git a/cms/djangoapps/contentstore/tests/test_gating.py b/cms/djangoapps/contentstore/tests/test_gating.py
index 91d2395bfde4..d5af490b0bd1 100644
--- a/cms/djangoapps/contentstore/tests/test_gating.py
+++ b/cms/djangoapps/contentstore/tests/test_gating.py
@@ -43,25 +43,25 @@ def setUp(self):
category='sequential',
display_name="Gated Sequential"
)
- gating_api.add_prerequisite(self.course.id, self.open_seq.location)
- gating_api.set_required_content(self.course.id, self.gated_seq.location, self.open_seq.location, 100, 100)
+ gating_api.add_prerequisite(self.course.id, self.open_seq.usage_key)
+ gating_api.set_required_content(self.course.id, self.gated_seq.usage_key, self.open_seq.usage_key, 100, 100)
@patch('cms.djangoapps.contentstore.signals.handlers.gating_api.set_required_content')
@patch('cms.djangoapps.contentstore.signals.handlers.gating_api.remove_prerequisite')
def test_chapter_deleted(self, mock_remove_prereq, mock_set_required):
""" Test gating milestone data is cleanup up when course content item is deleted """
- handle_item_deleted(usage_key=self.chapter.location, user_id=0)
- mock_remove_prereq.assert_called_with(self.open_seq.location)
+ handle_item_deleted(usage_key=self.chapter.usage_key, user_id=0)
+ mock_remove_prereq.assert_called_with(self.open_seq.usage_key)
mock_set_required.assert_called_with(
- self.open_seq.location.course_key, self.open_seq.location, None, None, None
+ self.open_seq.usage_key.course_key, self.open_seq.usage_key, None, None, None
)
@patch('cms.djangoapps.contentstore.signals.handlers.gating_api.set_required_content')
@patch('cms.djangoapps.contentstore.signals.handlers.gating_api.remove_prerequisite')
def test_sequential_deleted(self, mock_remove_prereq, mock_set_required):
""" Test gating milestone data is cleanup up when course content item is deleted """
- handle_item_deleted(usage_key=self.open_seq.location, user_id=0)
- mock_remove_prereq.assert_called_with(self.open_seq.location)
+ handle_item_deleted(usage_key=self.open_seq.usage_key, user_id=0)
+ mock_remove_prereq.assert_called_with(self.open_seq.usage_key)
mock_set_required.assert_called_with(
- self.open_seq.location.course_key, self.open_seq.location, None, None, None
+ self.open_seq.usage_key.course_key, self.open_seq.usage_key, None, None, None
)
diff --git a/cms/djangoapps/contentstore/tests/test_libraries.py b/cms/djangoapps/contentstore/tests/test_libraries.py
index 376ba56d8dd9..ea7177dd2772 100644
--- a/cms/djangoapps/contentstore/tests/test_libraries.py
+++ b/cms/djangoapps/contentstore/tests/test_libraries.py
@@ -82,7 +82,7 @@ def _add_library_content_block(self, course, library_key, publish_item=False, ot
"""
return BlockFactory.create(
category='library_content',
- parent_location=course.location,
+ parent_location=course.usage_key,
user_id=self.user.id,
publish_item=publish_item,
source_library_id=str(library_key),
@@ -92,7 +92,7 @@ def _add_library_content_block(self, course, library_key, publish_item=False, ot
def _add_simple_content_block(self):
""" Adds simple HTML block to library """
return BlockFactory.create(
- category="html", parent_location=self.library.location,
+ category="html", parent_location=self.library.usage_key,
user_id=self.user.id, publish_item=False
)
@@ -107,12 +107,12 @@ def _upgrade_and_sync(self, lib_content_block, status_code_expected=200):
handler_url = reverse_usage_url(
'preview_handler',
- lib_content_block.location,
+ lib_content_block.usage_key,
kwargs={'handler': 'upgrade_and_sync'}
)
response = self.client.ajax_post(handler_url)
self.assertEqual(response.status_code, status_code_expected)
- return modulestore().get_item(lib_content_block.location)
+ return modulestore().get_item(lib_content_block.usage_key)
def _bind_block(self, block, user=None):
"""
@@ -190,14 +190,14 @@ def test_consistent_children(self):
for num in range(8):
BlockFactory.create(
data=f"This is #{num + 1}",
- category="html", parent_location=self.library.location, user_id=self.user.id, publish_item=False
+ category="html", parent_location=self.library.usage_key, user_id=self.user.id, publish_item=False
)
with modulestore().default_store(ModuleStoreEnum.Type.split):
course = CourseFactory.create()
lc_block = self._add_library_content_block(course, self.lib_key, {'max_count': 1})
- lc_block_key = lc_block.location
+ lc_block_key = lc_block.usage_key
lc_block = self._upgrade_and_sync(lc_block)
def get_child_of_lc_block(block):
@@ -225,7 +225,7 @@ def check():
lc_block = modulestore().get_item(lc_block_key) # Reload block from the database
self._bind_block(lc_block)
current_child = get_child_of_lc_block(lc_block)
- self.assertEqual(current_child.location, chosen_child.location)
+ self.assertEqual(current_child.usage_key, chosen_child.usage_key)
self.assertEqual(current_child.data, chosen_child.data)
self.assertEqual(current_child.definition_locator.definition_id, chosen_child_defn_id)
@@ -266,7 +266,7 @@ def test_fields(self):
name_value = "A Scope.settings value"
lib_block = BlockFactory.create(
category="html",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name=name_value,
@@ -296,13 +296,13 @@ def test_block_with_children(self):
# In the library, create a vertical block with a child:
vert_block = BlockFactory.create(
category="vertical",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
)
child_block = BlockFactory.create(
category="html",
- parent_location=vert_block.location,
+ parent_location=vert_block.usage_key,
user_id=self.user.id,
publish_item=False,
display_name=name_value,
@@ -337,7 +337,7 @@ def test_switch_to_unknown_source_library_preserves_settings(self):
data_value = "Hello world!"
BlockFactory.create(
category="html",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name="HTML BLock",
@@ -360,12 +360,12 @@ def test_switch_to_unknown_source_library_preserves_settings(self):
# Now, change the block settings to have an invalid library key:
bad_library_id = "library-v1:NOT+FOUND"
resp = self._update_block(
- lc_block.location,
+ lc_block.usage_key,
{"source_library_id": bad_library_id},
)
self.assertEqual(resp.status_code, 200)
- lc_block = modulestore().get_item(lc_block.location)
+ lc_block = modulestore().get_item(lc_block.usage_key)
# Source library id should be set to the new bad one...
assert lc_block.source_library_id == bad_library_id
# ...but old source library version should be preserved...
@@ -379,7 +379,7 @@ def test_switch_to_unknown_source_library_preserves_settings(self):
self._upgrade_and_sync(lc_block, status_code_expected=400)
# (Repeat the exact same checks)
- lc_block = modulestore().get_item(lc_block.location)
+ lc_block = modulestore().get_item(lc_block.usage_key)
# Source library id should be set to the new bad one...
assert lc_block.source_library_id == bad_library_id
# ...but old source library version should be preserved...
@@ -397,7 +397,7 @@ def test_sync_if_source_library_changed(self):
data1, data2 = "Hello world from lib 1!", "Hello other world from lib 2"
BlockFactory.create(
category="html",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name="Lib 1: HTML BLock",
@@ -406,7 +406,7 @@ def test_sync_if_source_library_changed(self):
BlockFactory.create(
category="html",
- parent_location=library2.location,
+ parent_location=library2.usage_key,
user_id=self.user.id,
publish_item=False,
display_name="Lib 2: HTML BLock",
@@ -429,13 +429,13 @@ def test_sync_if_source_library_changed(self):
# Now, switch over to new library. Don't call upgrade_and_sync, because we are
# testing that it happens automatically.
resp = self._update_block(
- lc_block.location,
+ lc_block.usage_key,
{"source_library_id": str(library2key)},
)
self.assertEqual(resp.status_code, 200)
# Check that the course now has the new lib's new block.
- lc_block = modulestore().get_item(lc_block.location)
+ lc_block = modulestore().get_item(lc_block.usage_key)
self.assertEqual(len(lc_block.children), 1)
html_block_2 = modulestore().get_item(lc_block.children[0])
self.assertEqual(html_block_2.data, data2)
@@ -445,7 +445,7 @@ def test_sync_if_capa_type_changed(self):
name1, name2 = "Option Problem", "Multiple Choice Problem"
BlockFactory.create(
category="problem",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name=name1,
@@ -453,7 +453,7 @@ def test_sync_if_capa_type_changed(self):
)
BlockFactory.create(
category="problem",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name=name2,
@@ -470,22 +470,22 @@ def test_sync_if_capa_type_changed(self):
self.assertEqual(len(lc_block.children), 2)
resp = self._update_block(
- lc_block.location,
+ lc_block.usage_key,
{"capa_type": 'optionresponse'},
)
self.assertEqual(resp.status_code, 200)
- lc_block = modulestore().get_item(lc_block.location)
+ lc_block = modulestore().get_item(lc_block.usage_key)
self.assertEqual(len(lc_block.children), 1)
html_block = modulestore().get_item(lc_block.children[0])
self.assertEqual(html_block.display_name, name1)
resp = self._update_block(
- lc_block.location,
+ lc_block.usage_key,
{"capa_type": 'multiplechoiceresponse'},
)
self.assertEqual(resp.status_code, 200)
- lc_block = modulestore().get_item(lc_block.location)
+ lc_block = modulestore().get_item(lc_block.usage_key)
self.assertEqual(len(lc_block.children), 1)
html_block = modulestore().get_item(lc_block.children[0])
@@ -547,7 +547,7 @@ def _can_access_library(self, library):
if isinstance(library, (str, LibraryLocator)):
lib_key = library
else:
- lib_key = library.location.library_key
+ lib_key = library.usage_key.library_key
response = self.client.get(reverse_library_url('library_handler', str(lib_key)))
self.assertIn(response.status_code, (200, 302, 403))
return response.status_code == 200
@@ -656,7 +656,7 @@ def test_read_only_role(self, use_org_level_role):
self._login_as_non_staff_user()
self.assertFalse(self._can_access_library(self.library))
- block_url = reverse_usage_url('xblock_handler', block.location)
+ block_url = reverse_usage_url('xblock_handler', block.usage_key)
def can_read_block():
""" Check if studio lets us view the XBlock in the library """
@@ -679,8 +679,8 @@ def can_delete_block():
def can_copy_block():
""" Check if studio lets us duplicate the XBlock in the library """
response = self.client.ajax_post(reverse_url('xblock_handler'), {
- 'parent_locator': str(self.library.location),
- 'duplicate_source_locator': str(block.location),
+ 'parent_locator': str(self.library.usage_key),
+ 'duplicate_source_locator': str(block.usage_key),
})
self.assertIn(response.status_code, (200, 403)) # 400 would be ambiguous
return response.status_code == 200
@@ -688,7 +688,7 @@ def can_copy_block():
def can_create_block():
""" Check if studio lets us make a new XBlock in the library """
response = self.client.ajax_post(reverse_url('xblock_handler'), {
- 'parent_locator': str(self.library.location), 'category': 'html',
+ 'parent_locator': str(self.library.usage_key), 'category': 'html',
})
self.assertIn(response.status_code, (200, 403)) # 400 would be ambiguous
return response.status_code == 200
@@ -737,12 +737,12 @@ def test_duplicate_across_courses(self, library_role, course_role, expected_resu
if library_role:
library_role(self.lib_key).add_users(self.non_staff_user)
if course_role:
- course_role(course.location.course_key).add_users(self.non_staff_user)
+ course_role(course.usage_key.course_key).add_users(self.non_staff_user)
# Copy block to the course:
response = self.client.ajax_post(reverse_url('xblock_handler'), {
- 'parent_locator': str(course.location),
- 'duplicate_source_locator': str(block.location),
+ 'parent_locator': str(course.usage_key),
+ 'duplicate_source_locator': str(block.usage_key),
})
self.assertIn(response.status_code, (200, 403)) # 400 would be ambiguous
duplicate_action_allowed = (response.status_code == 200)
@@ -774,7 +774,7 @@ def test_upgrade_and_sync_handler_content_permissions(self, library_role, course
if library_role:
library_role(self.lib_key).add_users(self.non_staff_user)
if course_role:
- course_role(course.location.course_key).add_users(self.non_staff_user)
+ course_role(course.usage_key.course_key).add_users(self.non_staff_user)
# Try updating our library content block:
lc_block = self._add_library_content_block(course, self.lib_key)
@@ -806,7 +806,7 @@ def test_studio_user_permissions(self):
lib_block = BlockFactory.create(
category='library_content',
- parent_location=course.location,
+ parent_location=course.usage_key,
user_id=self.non_staff_user.id,
publish_item=False
)
@@ -816,7 +816,7 @@ def _get_settings_html():
Helper function to get block settings HTML
Used to check the available libraries.
"""
- edit_view_url = reverse_usage_url("xblock_view_handler", lib_block.location, {"view_name": STUDIO_VIEW})
+ edit_view_url = reverse_usage_url("xblock_view_handler", lib_block.usage_key, {"view_name": STUDIO_VIEW})
resp = self.client.get_json(edit_view_url)
self.assertEqual(resp.status_code, 200)
@@ -857,7 +857,7 @@ def setUp(self):
# Create a problem block in the library:
self.problem = BlockFactory.create(
category="problem",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
display_name=self.original_display_name, # display_name is a Scope.settings field
weight=self.original_weight, # weight is also a Scope.settings field
user_id=self.user.id,
@@ -908,7 +908,7 @@ def test_reset_override(self):
self.problem_in_course.display_name = new_display_name
self.problem_in_course.weight = new_weight
modulestore().update_item(self.problem_in_course, self.user.id)
- self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
+ self.problem_in_course = modulestore().get_item(self.problem_in_course.usage_key)
self.assertEqual(self.problem_in_course.display_name, new_display_name)
self.assertEqual(self.problem_in_course.weight, new_weight)
@@ -919,7 +919,7 @@ def test_reset_override(self):
# Save, reload, and verify:
modulestore().update_item(self.problem_in_course, self.user.id)
- self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
+ self.problem_in_course = modulestore().get_item(self.problem_in_course.usage_key)
self.assertEqual(self.problem_in_course.display_name, self.original_display_name)
self.assertEqual(self.problem_in_course.weight, self.original_weight)
@@ -939,7 +939,7 @@ def test_consistent_definitions(self):
self.problem.display_name = "NEW"
modulestore().update_item(self.problem, self.user.id)
self.lc_block = self._upgrade_and_sync(self.lc_block)
- self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
+ self.problem_in_course = modulestore().get_item(self.problem_in_course.usage_key)
self.assertEqual(self.problem.definition_locator.definition_id, definition_id)
self.assertEqual(self.problem_in_course.definition_locator.definition_id, definition_id)
@@ -960,11 +960,11 @@ def test_persistent_overrides(self, duplicate):
if duplicate:
# Check that this also works when the RCB is duplicated.
self.lc_block = modulestore().get_item(
- duplicate_block(self.course.location, self.lc_block.location, self.user)
+ duplicate_block(self.course.usage_key, self.lc_block.usage_key, self.user)
)
self.problem_in_course = modulestore().get_item(self.lc_block.children[0])
else:
- self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
+ self.problem_in_course = modulestore().get_item(self.problem_in_course.usage_key)
self.assertEqual(self.problem_in_course.display_name, new_display_name)
self.assertEqual(self.problem_in_course.weight, new_weight)
@@ -976,7 +976,7 @@ def test_persistent_overrides(self, duplicate):
modulestore().update_item(self.problem, self.user.id)
self.lc_block = self._upgrade_and_sync(self.lc_block)
- self.problem_in_course = modulestore().get_item(self.problem_in_course.location)
+ self.problem_in_course = modulestore().get_item(self.problem_in_course.usage_key)
self.assertEqual(self.problem_in_course.display_name, new_display_name)
self.assertEqual(self.problem_in_course.weight, new_weight)
@@ -997,7 +997,7 @@ def test_duplicated_version(self):
# Create an additional problem block in the library:
BlockFactory.create(
category="problem",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
)
@@ -1009,14 +1009,14 @@ def test_duplicated_version(self):
self.assertEqual(len(self.library.children), 2)
# But the block hasn't.
- self.lc_block = store.get_item(self.lc_block.location)
+ self.lc_block = store.get_item(self.lc_block.usage_key)
self.assertEqual(len(self.lc_block.children), 1)
- self.assertEqual(self.problem_in_course.location, self.lc_block.children[0])
+ self.assertEqual(self.problem_in_course.usage_key, self.lc_block.children[0])
self.assertEqual(self.problem_in_course.display_name, self.original_display_name)
# Duplicate self.lc_block:
duplicate = store.get_item(
- duplicate_block(self.course.location, self.lc_block.location, self.user)
+ duplicate_block(self.course.usage_key, self.lc_block.usage_key, self.user)
)
# The duplicate should have identical children to the original:
self.assertTrue(self.lc_block.source_library_version)
@@ -1027,7 +1027,7 @@ def test_duplicated_version(self):
# Refresh our reference to the block
self.lc_block = self._upgrade_and_sync(self.lc_block)
- self.problem_in_course = store.get_item(self.problem_in_course.location)
+ self.problem_in_course = store.get_item(self.problem_in_course.usage_key)
# and the block has changed too.
self.assertEqual(len(self.lc_block.children), 2)
diff --git a/cms/djangoapps/contentstore/tests/test_orphan.py b/cms/djangoapps/contentstore/tests/test_orphan.py
index 244eecebf9af..45e03f010743 100644
--- a/cms/djangoapps/contentstore/tests/test_orphan.py
+++ b/cms/djangoapps/contentstore/tests/test_orphan.py
@@ -27,41 +27,41 @@ def create_course_with_orphans(self, default_store):
course = CourseFactory.create(default_store=default_store)
# create chapters and add them to course tree
- chapter1 = self.store.create_child(self.user.id, course.location, 'chapter', "Chapter1")
- self.store.publish(chapter1.location, self.user.id)
+ chapter1 = self.store.create_child(self.user.id, course.usage_key, 'chapter', "Chapter1")
+ self.store.publish(chapter1.usage_key, self.user.id)
- chapter2 = self.store.create_child(self.user.id, course.location, 'chapter', "Chapter2")
- self.store.publish(chapter2.location, self.user.id)
+ chapter2 = self.store.create_child(self.user.id, course.usage_key, 'chapter', "Chapter2")
+ self.store.publish(chapter2.usage_key, self.user.id)
# orphan chapter
orphan_chapter = self.store.create_item(self.user.id, course.id, 'chapter', "OrphanChapter")
- self.store.publish(orphan_chapter.location, self.user.id)
+ self.store.publish(orphan_chapter.usage_key, self.user.id)
# create vertical and add it as child to chapter1
- vertical1 = self.store.create_child(self.user.id, chapter1.location, 'vertical', "Vertical1")
- self.store.publish(vertical1.location, self.user.id)
+ vertical1 = self.store.create_child(self.user.id, chapter1.usage_key, 'vertical', "Vertical1")
+ self.store.publish(vertical1.usage_key, self.user.id)
# create orphan vertical
orphan_vertical = self.store.create_item(self.user.id, course.id, 'vertical', "OrphanVert")
- self.store.publish(orphan_vertical.location, self.user.id)
+ self.store.publish(orphan_vertical.usage_key, self.user.id)
# create component and add it to vertical1
- html1 = self.store.create_child(self.user.id, vertical1.location, 'html', "Html1")
- self.store.publish(html1.location, self.user.id)
+ html1 = self.store.create_child(self.user.id, vertical1.usage_key, 'html', "Html1")
+ self.store.publish(html1.usage_key, self.user.id)
# create component and add it as a child to vertical1 and orphan_vertical
- multi_parent_html = self.store.create_child(self.user.id, vertical1.location, 'html', "multi_parent_html")
- self.store.publish(multi_parent_html.location, self.user.id)
+ multi_parent_html = self.store.create_child(self.user.id, vertical1.usage_key, 'html', "multi_parent_html")
+ self.store.publish(multi_parent_html.usage_key, self.user.id)
- orphan_vertical.children.append(multi_parent_html.location)
+ orphan_vertical.children.append(multi_parent_html.usage_key)
self.store.update_item(orphan_vertical, self.user.id)
# create an orphaned html block
orphan_html = self.store.create_item(self.user.id, course.id, 'html', "OrphanHtml")
- self.store.publish(orphan_html.location, self.user.id)
+ self.store.publish(orphan_html.usage_key, self.user.id)
- self.store.create_child(self.user.id, course.location, 'static_tab', "staticuno")
- self.store.create_child(self.user.id, course.location, 'course_info', "updates")
+ self.store.create_child(self.user.id, course.usage_key, 'static_tab', "staticuno")
+ self.store.create_child(self.user.id, course.usage_key, 'course_info', "updates")
return course
@@ -92,11 +92,11 @@ def test_get_orphans(self):
).content.decode('utf-8')
)
self.assertEqual(len(orphans), 3, f"Wrong # {orphans}")
- location = course.location.replace(category='chapter', name='OrphanChapter')
+ location = course.usage_key.replace(category='chapter', name='OrphanChapter')
self.assertIn(str(location), orphans)
- location = course.location.replace(category='vertical', name='OrphanVert')
+ location = course.usage_key.replace(category='vertical', name='OrphanVert')
self.assertIn(str(location), orphans)
- location = course.location.replace(category='html', name='OrphanHtml')
+ location = course.usage_key.replace(category='html', name='OrphanHtml')
self.assertIn(str(location), orphans)
def test_delete_orphans(self):
@@ -155,24 +155,24 @@ def test_path_to_location_for_orphan_vertical(self):
multi_parent_html = self.store.get_item(BlockUsageLocator(course.id, 'html', 'multi_parent_html'))
# Verify `OrphanVert` is an orphan
- self.assertIn(orphan_vertical.location, self.store.get_orphans(course.id))
+ self.assertIn(orphan_vertical.usage_key, self.store.get_orphans(course.id))
# Verify `multi_parent_html` is child of both `Vertical1` and `OrphanVert`
- self.assertIn(multi_parent_html.location, orphan_vertical.children)
- self.assertIn(multi_parent_html.location, vertical1.children)
+ self.assertIn(multi_parent_html.usage_key, orphan_vertical.children)
+ self.assertIn(multi_parent_html.usage_key, vertical1.children)
# HTML component has `vertical1` as its parent.
- html_parent = self.store.get_parent_location(multi_parent_html.location)
- self.assertNotEqual(str(html_parent), str(orphan_vertical.location))
- self.assertEqual(str(html_parent), str(vertical1.location))
+ html_parent = self.store.get_parent_location(multi_parent_html.usage_key)
+ self.assertNotEqual(str(html_parent), str(orphan_vertical.usage_key))
+ self.assertEqual(str(html_parent), str(vertical1.usage_key))
# Get path of the `multi_parent_html` & verify path_to_location returns a expected path
- path = path_to_location(self.store, multi_parent_html.location)
+ path = path_to_location(self.store, multi_parent_html.usage_key)
expected_path = (
course.id,
- chapter1.location.block_id,
- vertical1.location.block_id,
- multi_parent_html.location.block_id,
+ chapter1.usage_key.block_id,
+ vertical1.usage_key.block_id,
+ multi_parent_html.usage_key.block_id,
"",
path[-1]
)
@@ -201,38 +201,38 @@ def test_path_to_location_for_orphan_chapter(self):
vertical1 = self.store.get_item(BlockUsageLocator(course.id, 'vertical', 'Vertical1'))
# Verify `OrhanChapter` is an orphan
- self.assertIn(orphan_chapter.location, self.store.get_orphans(course.id))
+ self.assertIn(orphan_chapter.usage_key, self.store.get_orphans(course.id))
# Create a vertical (`Vertical0`) in orphan chapter (`OrphanChapter`).
# OrphanChapter -> Vertical0
- vertical0 = self.store.create_child(self.user.id, orphan_chapter.location, 'vertical', "Vertical0")
- self.store.publish(vertical0.location, self.user.id)
+ vertical0 = self.store.create_child(self.user.id, orphan_chapter.usage_key, 'vertical', "Vertical0")
+ self.store.publish(vertical0.usage_key, self.user.id)
# Create a component in `Vertical0`
# OrphanChapter -> Vertical0 -> Html
- html = self.store.create_child(self.user.id, vertical0.location, 'html', "HTML0")
- self.store.publish(html.location, self.user.id)
+ html = self.store.create_child(self.user.id, vertical0.usage_key, 'html', "HTML0")
+ self.store.publish(html.usage_key, self.user.id)
# Verify chapter1 is parent of vertical1.
- vertical1_parent = self.store.get_parent_location(vertical1.location)
- self.assertEqual(str(vertical1_parent), str(chapter1.location))
+ vertical1_parent = self.store.get_parent_location(vertical1.usage_key)
+ self.assertEqual(str(vertical1_parent), str(chapter1.usage_key))
# Make `Vertical1` the parent of `HTML0`. So `HTML0` will have to parents (`Vertical0` & `Vertical1`)
- vertical1.children.append(html.location)
+ vertical1.children.append(html.usage_key)
self.store.update_item(vertical1, self.user.id)
# Get parent location & verify its either of the two verticals. As both parents are non-orphan,
# alphabetically least is returned
- html_parent = self.store.get_parent_location(html.location)
- self.assertEqual(str(html_parent), str(vertical1.location))
+ html_parent = self.store.get_parent_location(html.usage_key)
+ self.assertEqual(str(html_parent), str(vertical1.usage_key))
# verify path_to_location returns a expected path
- path = path_to_location(self.store, html.location)
+ path = path_to_location(self.store, html.usage_key)
expected_path = (
course.id,
- chapter1.location.block_id,
- vertical1.location.block_id,
- html.location.block_id,
+ chapter1.usage_key.block_id,
+ vertical1.usage_key.block_id,
+ html.usage_key.block_id,
"",
path[-1]
)
diff --git a/cms/djangoapps/contentstore/tests/test_outlines.py b/cms/djangoapps/contentstore/tests/test_outlines.py
index 108edd82df43..f424fba5cbe8 100644
--- a/cms/djangoapps/contentstore/tests/test_outlines.py
+++ b/cms/djangoapps/contentstore/tests/test_outlines.py
@@ -177,13 +177,13 @@ def test_duplicate_children(self):
parent=self.draft_course,
category='chapter',
display_name="Section 2",
- children=[seq.location]
+ children=[seq.usage_key]
)
section_3 = BlockFactory.create(
parent=self.draft_course,
category='chapter',
display_name="Section 3",
- children=[seq.location]
+ children=[seq.usage_key]
)
self.store.update_item(section_2, self.user.id)
@@ -291,8 +291,8 @@ def test_sequence_without_section(self):
outline, errs = get_outline_from_modulestore(self.course_key)
assert len(errs) == 1
- # Strip version information from seq.location before comparison.
- assert errs[0].usage_key == seq.location.map_into_course(self.course_key)
+ # Strip version information from seq.usage_key before comparison.
+ assert errs[0].usage_key == seq.usage_key.map_into_course(self.course_key)
assert outline.sections == []
assert outline.sequences == {}
@@ -479,7 +479,7 @@ def _outline_seq_data(self, modulestore_seq):
# Recently modified content can have full version information on their
# CourseKeys. We need to strip that out and have versionless-CourseKeys
# or they won't be found properly.
- versionless_usage_key = modulestore_seq.location.map_into_course(self.course_key)
+ versionless_usage_key = modulestore_seq.usage_key.map_into_course(self.course_key)
outline_seq_data = outline.sequences[versionless_usage_key]
return outline_seq_data, versionless_usage_key
@@ -527,21 +527,21 @@ def test_task_invocation(self):
default_store=ModuleStoreEnum.Type.split,
)
section = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="chapter",
display_name="First Section"
)
BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="sequential",
display_name="First Sequence"
)
BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="sequential",
display_name="Second Sequence"
)
- self.store.publish(course.location, self.user.id)
+ self.store.publish(course.usage_key, self.user.id)
outline = get_course_outline(course_key)
assert len(outline.sections) == 1
diff --git a/cms/djangoapps/contentstore/tests/test_proctoring.py b/cms/djangoapps/contentstore/tests/test_proctoring.py
index d9b83a811ef0..768185995a98 100644
--- a/cms/djangoapps/contentstore/tests/test_proctoring.py
+++ b/cms/djangoapps/contentstore/tests/test_proctoring.py
@@ -66,7 +66,7 @@ def _verify_exam_data(self, sequence, expected_active):
self.assertEqual(exam['hide_after_due'], sequence.hide_after_due)
self.assertEqual(exam['course_id'], str(self.course.id))
- self.assertEqual(exam['content_id'], str(sequence.location))
+ self.assertEqual(exam['content_id'], str(sequence.usage_key))
self.assertEqual(exam['exam_name'], sequence.display_name)
self.assertEqual(exam['time_limit_mins'], sequence.default_time_limit_minutes)
self.assertEqual(exam['is_proctored'], sequence.is_proctored_exam)
@@ -207,7 +207,7 @@ def test_dangling_exam(self):
exams = get_all_exams_for_course(str(self.course.id))
self.assertEqual(len(exams), 1)
- self.store.delete_item(chapter.location, self.user.id)
+ self.store.delete_item(chapter.usage_key, self.user.id)
# republish course
listen_for_course_publish(self, self.course.id)
diff --git a/cms/djangoapps/contentstore/tests/test_tasks.py b/cms/djangoapps/contentstore/tests/test_tasks.py
index 5a76b7d67fe7..0d71aa2086f0 100644
--- a/cms/djangoapps/contentstore/tests/test_tasks.py
+++ b/cms/djangoapps/contentstore/tests/test_tasks.py
@@ -67,7 +67,7 @@ def test_success(self):
"""
Verify that a routine course export task succeeds
"""
- key = str(self.course.location.course_key)
+ key = str(self.course.usage_key.course_key)
result = export_olx.delay(self.user.id, key, 'en')
status = UserTaskStatus.objects.get(task_id=result.id)
self.assertEqual(status.state, UserTaskStatus.SUCCEEDED)
@@ -81,7 +81,7 @@ def test_exception(self, mock_export): # pylint: disable=unused-argument
"""
The export task should fail gracefully if an exception is thrown
"""
- key = str(self.course.location.course_key)
+ key = str(self.course.usage_key.course_key)
result = export_olx.delay(self.user.id, key, 'en')
self._assert_failed(result, json.dumps({'raw_error_msg': 'Boom!'}))
@@ -91,7 +91,7 @@ def test_invalid_user_id(self, mock_raise_exc): # pylint: disable=unused-argume
Verify that attempts to export a course as an invalid user fail
"""
user = UserFactory(id=User.objects.order_by('-id').first().pk + 100)
- key = str(self.course.location.course_key)
+ key = str(self.course.usage_key.course_key)
result = export_olx.delay(user.id, key, 'en')
self._assert_failed(result, f'Unknown User ID: {user.id}')
@@ -100,7 +100,7 @@ def test_non_course_author(self):
Verify that users who aren't authors of the course are unable to export it
"""
_, nonstaff_user = self.create_non_staff_authed_user_client()
- key = str(self.course.location.course_key)
+ key = str(self.course.usage_key.course_key)
result = export_olx.delay(nonstaff_user.id, key, 'en')
self._assert_failed(result, 'Permission denied')
@@ -408,15 +408,15 @@ def test_scan_course_excludes_drag_and_drop(self, mock_modulestore, mock_get_blo
"""
vertical = BlockFactory.create(
category='vertical',
- parent_location=self.test_course.location
+ parent_location=self.test_course.usage_key
)
drag_and_drop_block = BlockFactory.create(
category='drag-and-drop-v2',
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
)
text_block = BlockFactory.create(
category='html',
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
data='Test Link -> Example.com'
)
diff --git a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
index 9163ff1ffc75..1779cc298bbc 100644
--- a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
+++ b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py
@@ -723,10 +723,10 @@ def setUp(self):
self.sjson_mime_type = transcripts_utils.Transcript.mime_types[transcripts_utils.Transcript.SJSON]
self.user = UserFactory.create()
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.course.location)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.course.usage_key)
self.video = BlockFactory.create(
category='video',
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
edx_video_id='1234-5678-90'
)
@@ -741,7 +741,7 @@ def create_transcript(self, subs_id, language='en', filename='video.srt', youtub
html5_sources = html5_sources or []
self.video = BlockFactory.create(
category='video',
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
sub=subs_id,
youtube_id_1_0=youtube_id_1_0,
transcripts=transcripts,
@@ -857,7 +857,7 @@ def test_get_transcript_from_contentstore(
Verify that `get_transcript` function returns correct data when transcript is in content store.
"""
base_filename = 'video_101.srt'
- self.upload_file(self.create_srt_file(self.subs_srt.encode('utf-8')), self.video.location, base_filename)
+ self.upload_file(self.create_srt_file(self.subs_srt.encode('utf-8')), self.video.usage_key, base_filename)
self.create_transcript(subs_id, language, base_filename, youtube_id_1_0, html5_sources)
content, file_name, mimetype = transcripts_utils.get_transcript(
self.video,
@@ -919,7 +919,7 @@ def test_get_transcript_no_content(self):
"""
Verify that `get_transcript` function returns correct exception when transcript content is empty.
"""
- self.upload_file(self.create_srt_file(b''), self.video.location, 'ur_video_101.srt')
+ self.upload_file(self.create_srt_file(b''), self.video.usage_key, 'ur_video_101.srt')
self.create_transcript('', 'ur', 'ur_video_101.srt')
with self.assertRaises(NotFoundError) as no_content_exception:
diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py
index 48e0c425cec7..d95cffd71417 100644
--- a/cms/djangoapps/contentstore/tests/test_utils.py
+++ b/cms/djangoapps/contentstore/tests/test_utils.py
@@ -174,12 +174,12 @@ def _create_xblock_with_start_date(self, name, start_date, publish=False, visibl
"""Helper to create an xblock with a start date, optionally publishing it"""
vertical = modulestore().create_item(
- self.dummy_user, self.course.location.course_key, 'vertical', name,
+ self.dummy_user, self.course.usage_key.course_key, 'vertical', name,
fields={'start': start_date, 'visible_to_staff_only': visible_to_staff_only}
)
if publish:
- modulestore().publish(vertical.location, self.dummy_user)
+ modulestore().publish(vertical.usage_key, self.dummy_user)
return vertical
@@ -190,14 +190,14 @@ class ReleaseDateSourceTest(CourseTestCase):
def setUp(self):
super().setUp()
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
- self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
+ self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
# Read again so that children lists are accurate
- self.chapter = self.store.get_item(self.chapter.location)
- self.sequential = self.store.get_item(self.sequential.location)
- self.vertical = self.store.get_item(self.vertical.location)
+ self.chapter = self.store.get_item(self.chapter.usage_key)
+ self.sequential = self.store.get_item(self.sequential.usage_key)
+ self.vertical = self.store.get_item(self.vertical.usage_key)
self.date_one = datetime(1980, 1, 1, tzinfo=UTC)
self.date_two = datetime(2020, 1, 1, tzinfo=UTC)
@@ -214,7 +214,7 @@ def _update_release_dates(self, chapter_start, sequential_start, vertical_start)
def _verify_release_date_source(self, item, expected_source):
"""Helper to verify that the release date source of a given item matches the expected source"""
source = utils.find_release_date_source(item)
- self.assertEqual(source.location, expected_source.location)
+ self.assertEqual(source.usage_key, expected_source.usage_key)
self.assertEqual(source.start, expected_source.start)
def test_chapter_source_for_vertical(self):
@@ -244,18 +244,18 @@ class StaffLockTest(CourseTestCase):
def setUp(self):
super().setUp()
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
- self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
- self.orphan = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
+ self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
+ self.orphan = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
# Read again so that children lists are accurate
- self.chapter = self.store.get_item(self.chapter.location)
- self.sequential = self.store.get_item(self.sequential.location)
- self.vertical = self.store.get_item(self.vertical.location)
+ self.chapter = self.store.get_item(self.chapter.usage_key)
+ self.sequential = self.store.get_item(self.sequential.usage_key)
+ self.vertical = self.store.get_item(self.vertical.usage_key)
# Orphan the orphaned xblock
- self.sequential.children = [self.vertical.location]
+ self.sequential.children = [self.vertical.usage_key]
self.sequential = self.store.update_item(self.sequential, ModuleStoreEnum.UserID.test)
def _set_staff_lock(self, xblock, is_locked):
@@ -283,7 +283,7 @@ class StaffLockSourceTest(StaffLockTest):
def _verify_staff_lock_source(self, item, expected_source):
"""Helper to verify that the staff lock source of a given item matches the expected source"""
source = utils.find_staff_lock_source(item)
- self.assertEqual(source.location, expected_source.location)
+ self.assertEqual(source.usage_key, expected_source.usage_key)
self.assertTrue(source.visible_to_staff_only)
def test_chapter_source_for_vertical(self):
@@ -362,10 +362,10 @@ def setUp(self):
problem = BlockFactory.create(
category='problem', parent=vertical, data=""
)
- self.sequential = self.store.get_item(sequential.location)
- self.vertical = self.store.get_item(vertical.location)
- self.html = self.store.get_item(html.location)
- self.problem = self.store.get_item(problem.location)
+ self.sequential = self.store.get_item(sequential.usage_key)
+ self.vertical = self.store.get_item(vertical.usage_key)
+ self.html = self.store.get_item(html.usage_key)
+ self.problem = self.store.get_item(problem.usage_key)
# Add partitions to the course
self.course.user_partitions = [
@@ -433,9 +433,9 @@ def test_sequential_and_problem_have_group_access(self):
self.set_group_access(self.vertical, {1: []})
self.set_group_access(self.problem, {2: [3, 4]})
# get updated sequential/vertical/problem
- self.sequential = self.store.get_item(self.sequential.location)
- self.vertical = self.store.get_item(self.vertical.location)
- self.problem = self.store.get_item(self.problem.location)
+ self.sequential = self.store.get_item(self.sequential.usage_key)
+ self.vertical = self.store.get_item(self.vertical.usage_key)
+ self.problem = self.store.get_item(self.problem.usage_key)
# Note that "has_children_visible_to_specific_partition_groups" only checks immediate children.
self.assertFalse(utils.has_children_visible_to_specific_partition_groups(self.sequential))
@@ -459,7 +459,7 @@ def setUp(self):
"""Create a dummy course. """
super().setUp()
self.course = CourseFactory()
- self.block = BlockFactory.create(category="problem", parent_location=self.course.location)
+ self.block = BlockFactory.create(category="problem", parent_location=self.course.usage_key)
# Set up some default partitions
self._set_partitions([
diff --git a/cms/djangoapps/contentstore/tests/test_xblock_handler_permissions.py b/cms/djangoapps/contentstore/tests/test_xblock_handler_permissions.py
index 84a5b51895a5..96e306aaaaac 100644
--- a/cms/djangoapps/contentstore/tests/test_xblock_handler_permissions.py
+++ b/cms/djangoapps/contentstore/tests/test_xblock_handler_permissions.py
@@ -17,93 +17,93 @@ class XBlockHandlerPermissionsTest(CourseTestCase):
def setUp(self):
super().setUp()
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
- self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
- self.html_block = BlockFactory.create(category='html', parent_location=self.vertical.location)
- self.static_tab = BlockFactory.create(category='static_tab', parent_location=self.course.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
+ self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
+ self.html_block = BlockFactory.create(category='html', parent_location=self.vertical.usage_key)
+ self.static_tab = BlockFactory.create(category='static_tab', parent_location=self.course.usage_key)
self.non_staff_client, _ = self.create_non_staff_authed_user_client()
# --- GET /xblock/{blockId} ---
def test_get_block_fields_staff_allowed(self):
- self.assertEqual(self.client.get_json(f'/xblock/{self.html_block.location}').status_code, 200)
+ self.assertEqual(self.client.get_json(f'/xblock/{self.html_block.usage_key}').status_code, 200)
def test_get_block_fields_non_staff_forbidden(self):
- self.assertEqual(self.non_staff_client.get_json(f'/xblock/{self.html_block.location}').status_code, 403)
+ self.assertEqual(self.non_staff_client.get_json(f'/xblock/{self.html_block.usage_key}').status_code, 403)
# --- POST /xblock/{blockId} metadata ---
def test_post_metadata_staff_allowed(self):
resp = self.client.ajax_post(
- f'/xblock/{self.html_block.location}', data={'metadata': {'display_name': 'New Name'}}
+ f'/xblock/{self.html_block.usage_key}', data={'metadata': {'display_name': 'New Name'}}
)
self.assertEqual(resp.status_code, 200)
def test_post_metadata_non_staff_forbidden(self):
resp = self.non_staff_client.ajax_post(
- f'/xblock/{self.html_block.location}', data={'metadata': {'display_name': 'New Name'}}
+ f'/xblock/{self.html_block.usage_key}', data={'metadata': {'display_name': 'New Name'}}
)
self.assertEqual(resp.status_code, 403)
# --- POST /xblock/{blockId} publish ---
def test_publish_staff_allowed(self):
- resp = self.client.ajax_post(f'/xblock/{self.vertical.location}', data={'publish': 'make_public'})
+ resp = self.client.ajax_post(f'/xblock/{self.vertical.usage_key}', data={'publish': 'make_public'})
self.assertEqual(resp.status_code, 200)
def test_publish_non_staff_forbidden(self):
- resp = self.non_staff_client.ajax_post(f'/xblock/{self.vertical.location}', data={'publish': 'make_public'})
+ resp = self.non_staff_client.ajax_post(f'/xblock/{self.vertical.usage_key}', data={'publish': 'make_public'})
self.assertEqual(resp.status_code, 403)
# --- DELETE /xblock/{blockId} ---
def test_delete_block_staff_allowed(self):
- resp = self.client.delete(f'/xblock/{self.html_block.location}', HTTP_ACCEPT='application/json')
+ resp = self.client.delete(f'/xblock/{self.html_block.usage_key}', HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 204)
def test_delete_block_non_staff_forbidden(self):
- resp = self.non_staff_client.delete(f'/xblock/{self.html_block.location}', HTTP_ACCEPT='application/json')
+ resp = self.non_staff_client.delete(f'/xblock/{self.html_block.usage_key}', HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 403)
# --- POST /xblock/ (create/duplicate) ---
def test_post_duplicate_staff_allowed(self):
data = {
- 'duplicate_source_locator': str(self.html_block.location),
- 'parent_locator': str(self.vertical.location),
+ 'duplicate_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(self.vertical.usage_key),
}
self.assertEqual(self.client.ajax_post('/xblock/', data=data).status_code, 200)
def test_post_duplicate_non_staff_forbidden(self):
data = {
- 'duplicate_source_locator': str(self.html_block.location),
- 'parent_locator': str(self.vertical.location),
+ 'duplicate_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(self.vertical.usage_key),
}
self.assertEqual(self.non_staff_client.ajax_post('/xblock/', data=data).status_code, 403)
def test_post_add_component_staff_allowed(self):
- data = {'category': 'html', 'parent_locator': str(self.vertical.location)}
+ data = {'category': 'html', 'parent_locator': str(self.vertical.usage_key)}
self.assertEqual(self.client.ajax_post('/xblock/', data=data).status_code, 200)
def test_post_add_component_non_staff_forbidden(self):
- data = {'category': 'html', 'parent_locator': str(self.vertical.location)}
+ data = {'category': 'html', 'parent_locator': str(self.vertical.usage_key)}
self.assertEqual(self.non_staff_client.ajax_post('/xblock/', data=data).status_code, 403)
# --- PUT /xblock/{blockId} (reorder) ---
def test_put_reorder_staff_allowed(self):
- data={'children': [str(self.html_block.location)]}
+ data={'children': [str(self.html_block.usage_key)]}
resp = self.client.put(
- f'/xblock/{self.vertical.location}', data=data,
+ f'/xblock/{self.vertical.usage_key}', data=data,
content_type='application/json', HTTP_ACCEPT='application/json',
)
self.assertEqual(resp.status_code, 200)
def test_put_reorder_non_staff_forbidden(self):
- data={'children': [str(self.html_block.location)]}
+ data={'children': [str(self.html_block.usage_key)]}
resp = self.non_staff_client.put(
- f'/xblock/{self.vertical.location}', data=data,
+ f'/xblock/{self.vertical.usage_key}', data=data,
content_type='application/json', HTTP_ACCEPT='application/json',
)
self.assertEqual(resp.status_code, 403)
@@ -111,10 +111,10 @@ def test_put_reorder_non_staff_forbidden(self):
# --- PATCH /xblock/ (move) ---
def test_patch_move_component_staff_allowed(self):
- vertical2 = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
+ vertical2 = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
data={
- 'move_source_locator': str(self.html_block.location),
- 'parent_locator': str(vertical2.location),
+ 'move_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(vertical2.usage_key),
}
resp = self.client.patch(
'/xblock/', data=data, content_type='application/json', HTTP_ACCEPT='application/json',
@@ -123,8 +123,8 @@ def test_patch_move_component_staff_allowed(self):
def test_patch_move_component_non_staff_forbidden(self):
data={
- 'move_source_locator': str(self.html_block.location),
- 'parent_locator': str(self.vertical.location),
+ 'move_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(self.vertical.usage_key),
}
resp = self.non_staff_client.patch(
'/xblock/', data=data, content_type='application/json', HTTP_ACCEPT='application/json',
@@ -136,7 +136,7 @@ def test_patch_move_component_non_staff_forbidden(self):
def test_put_update_custom_page_staff_allowed(self):
data={'metadata': {'display_name': 'Updated Page'}}
resp = self.client.put(
- f'/xblock/{self.static_tab.location}', data=data,
+ f'/xblock/{self.static_tab.usage_key}', data=data,
content_type='application/json', HTTP_ACCEPT='application/json',
)
self.assertEqual(resp.status_code, 200)
@@ -144,38 +144,38 @@ def test_put_update_custom_page_staff_allowed(self):
def test_put_update_custom_page_non_staff_forbidden(self):
data={'metadata': {'display_name': 'Updated Page'}}
resp = self.non_staff_client.put(
- f'/xblock/{self.static_tab.location}', data=data,
+ f'/xblock/{self.static_tab.usage_key}', data=data,
content_type='application/json', HTTP_ACCEPT='application/json',
)
self.assertEqual(resp.status_code, 403)
def test_delete_custom_page_staff_allowed(self):
- resp = self.client.delete(f'/xblock/{self.static_tab.location}', HTTP_ACCEPT='application/json')
+ resp = self.client.delete(f'/xblock/{self.static_tab.usage_key}', HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 204)
def test_delete_custom_page_non_staff_forbidden(self):
- resp = self.non_staff_client.delete(f'/xblock/{self.static_tab.location}', HTTP_ACCEPT='application/json')
+ resp = self.non_staff_client.delete(f'/xblock/{self.static_tab.usage_key}', HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 403)
def test_post_static_tab_content_staff_allowed(self):
resp = self.client.ajax_post(
- f'/xblock/{self.static_tab.location}', data={'data': 'Content
', 'metadata': {'display_name': 'Page'}}
+ f'/xblock/{self.static_tab.usage_key}', data={'data': 'Content
', 'metadata': {'display_name': 'Page'}}
)
self.assertEqual(resp.status_code, 200)
def test_post_static_tab_content_non_staff_forbidden(self):
resp = self.non_staff_client.ajax_post(
- f'/xblock/{self.static_tab.location}', data={'data': 'Content
', 'metadata': {'display_name': 'Page'}}
+ f'/xblock/{self.static_tab.usage_key}', data={'data': 'Content
', 'metadata': {'display_name': 'Page'}}
)
self.assertEqual(resp.status_code, 403)
def test_get_handouts_staff_allowed(self):
- handouts = BlockFactory.create(category='course_info', parent_location=self.course.location)
- self.assertEqual(self.client.get_json(f'/xblock/{handouts.location}').status_code, 200)
+ handouts = BlockFactory.create(category='course_info', parent_location=self.course.usage_key)
+ self.assertEqual(self.client.get_json(f'/xblock/{handouts.usage_key}').status_code, 200)
def test_get_handouts_non_staff_forbidden(self):
- handouts = BlockFactory.create(category='course_info', parent_location=self.course.location)
- self.assertEqual(self.non_staff_client.get_json(f'/xblock/{handouts.location}').status_code, 403)
+ handouts = BlockFactory.create(category='course_info', parent_location=self.course.usage_key)
+ self.assertEqual(self.non_staff_client.get_json(f'/xblock/{handouts.usage_key}').status_code, 403)
@patch('cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers.authz_api.is_user_allowed', return_value=True)
@@ -190,18 +190,18 @@ class XBlockHandlerAuthzPermissionsTest(CourseTestCase):
def setUp(self):
super().setUp()
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
- self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
- self.html_block = BlockFactory.create(category='html', parent_location=self.vertical.location)
- self.static_tab = BlockFactory.create(category='static_tab', parent_location=self.course.location)
- self.course_info = BlockFactory.create(category='course_info', parent_location=self.course.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
+ self.sequential = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
+ self.html_block = BlockFactory.create(category='html', parent_location=self.vertical.usage_key)
+ self.static_tab = BlockFactory.create(category='static_tab', parent_location=self.course.usage_key)
+ self.course_info = BlockFactory.create(category='course_info', parent_location=self.course.usage_key)
# --- GET /xblock/{blockId} ---
def test_get_regular_block_checks_view_course(self, _mock_flag, mock_is_allowed):
"""GET on regular block should check courses.view_course permission"""
- self.client.get_json(f'/xblock/{self.html_block.location}')
+ self.client.get_json(f'/xblock/{self.html_block.usage_key}')
mock_is_allowed.assert_called_with(
self.user.username,
'courses.view_course',
@@ -210,7 +210,7 @@ def test_get_regular_block_checks_view_course(self, _mock_flag, mock_is_allowed)
def test_get_course_info_checks_view_course_updates(self, _mock_flag, mock_is_allowed):
"""GET on course_info block should check courses.view_course_updates permission"""
- self.client.get_json(f'/xblock/{self.course_info.location}')
+ self.client.get_json(f'/xblock/{self.course_info.usage_key}')
mock_is_allowed.assert_called_with(
self.user.username,
'courses.view_course_updates',
@@ -219,7 +219,7 @@ def test_get_course_info_checks_view_course_updates(self, _mock_flag, mock_is_al
def test_get_static_tab_checks_view_course(self, _mock_flag, mock_is_allowed):
"""GET on static_tab should check courses.view_course"""
- self.client.get_json(f'/xblock/{self.static_tab.location}')
+ self.client.get_json(f'/xblock/{self.static_tab.usage_key}')
mock_is_allowed.assert_called_with(
self.user.username,
'courses.view_course',
@@ -230,7 +230,7 @@ def test_get_static_tab_checks_view_course(self, _mock_flag, mock_is_allowed):
def test_post_regular_block_checks_edit_course_content(self, _mock_flag, mock_is_allowed):
"""POST on regular block without publish should check courses.edit_course_content"""
- self.client.ajax_post(f'/xblock/{self.html_block.location}', data={'metadata': {'display_name': 'New'}})
+ self.client.ajax_post(f'/xblock/{self.html_block.usage_key}', data={'metadata': {'display_name': 'New'}})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.edit_course_content',
@@ -240,7 +240,7 @@ def test_post_regular_block_checks_edit_course_content(self, _mock_flag, mock_is
def test_post_with_publish_none_and_metadata_checks_edit(self, _mock_flag, mock_is_allowed):
"""POST with publish=None + metadata should check courses.edit_course_content"""
self.client.ajax_post(
- f'/xblock/{self.vertical.location}',
+ f'/xblock/{self.vertical.usage_key}',
data={'publish': None, 'metadata': {'visible_to_staff_only': True}}
)
mock_is_allowed.assert_called_with(
@@ -253,7 +253,7 @@ def test_post_with_publish_none_and_metadata_checks_edit(self, _mock_flag, mock_
def test_post_with_publish_checks_publish_course_content(self, _mock_flag, mock_is_allowed):
"""POST with publish='make_public' should check courses.publish_course_content"""
- self.client.ajax_post(f'/xblock/{self.vertical.location}', data={'publish': 'make_public'})
+ self.client.ajax_post(f'/xblock/{self.vertical.usage_key}', data={'publish': 'make_public'})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.publish_course_content',
@@ -262,7 +262,7 @@ def test_post_with_publish_checks_publish_course_content(self, _mock_flag, mock_
def test_post_discard_changes_checks_publish(self, _mock_flag, mock_is_allowed):
"""POST with publish='discard_changes' should check courses.publish_course_content"""
- self.client.ajax_post(f'/xblock/{self.vertical.location}', data={'publish': 'discard_changes'})
+ self.client.ajax_post(f'/xblock/{self.vertical.usage_key}', data={'publish': 'discard_changes'})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.publish_course_content',
@@ -271,7 +271,7 @@ def test_post_discard_changes_checks_publish(self, _mock_flag, mock_is_allowed):
def test_post_republish_without_changes_checks_publish(self, _mock_flag, mock_is_allowed):
"""POST with publish='republish' and no content changes should check courses.publish_course_content"""
- self.client.ajax_post(f'/xblock/{self.vertical.location}', data={'publish': 'republish'})
+ self.client.ajax_post(f'/xblock/{self.vertical.usage_key}', data={'publish': 'republish'})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.publish_course_content',
@@ -281,7 +281,7 @@ def test_post_republish_without_changes_checks_publish(self, _mock_flag, mock_is
def test_post_make_public_with_content_changes_checks_edit(self, _mock_flag, mock_is_allowed):
"""POST with publish='make_public' + metadata should check courses.edit_course_content"""
self.client.ajax_post(
- f'/xblock/{self.vertical.location}',
+ f'/xblock/{self.vertical.usage_key}',
data={'publish': 'make_public', 'metadata': {'display_name': 'New'}}
)
mock_is_allowed.assert_called_with(
@@ -293,7 +293,7 @@ def test_post_make_public_with_content_changes_checks_edit(self, _mock_flag, moc
def test_post_republish_with_metadata_checks_edit(self, _mock_flag, mock_is_allowed):
"""POST with publish='republish' + metadata changes should check courses.edit_course_content"""
self.client.ajax_post(
- f'/xblock/{self.chapter.location}',
+ f'/xblock/{self.chapter.usage_key}',
data={'publish': 'republish', 'metadata': {'highlights': ['Week 1']}}
)
mock_is_allowed.assert_called_with(
@@ -305,7 +305,7 @@ def test_post_republish_with_metadata_checks_edit(self, _mock_flag, mock_is_allo
def test_post_republish_with_grader_type_checks_edit(self, _mock_flag, mock_is_allowed):
"""POST with publish='republish' + graderType should check courses.edit_course_content"""
self.client.ajax_post(
- f'/xblock/{self.sequential.location}',
+ f'/xblock/{self.sequential.usage_key}',
data={'publish': 'republish', 'graderType': 'Homework', 'prereqMinScore': 100}
)
mock_is_allowed.assert_called_with(
@@ -318,7 +318,7 @@ def test_post_republish_with_grader_type_checks_edit(self, _mock_flag, mock_is_a
def test_delete_regular_block_checks_edit_course_content(self, _mock_flag, mock_is_allowed):
"""DELETE on regular block should check courses.edit_course_content"""
- self.client.delete(f'/xblock/{self.html_block.location}', HTTP_ACCEPT='application/json')
+ self.client.delete(f'/xblock/{self.html_block.usage_key}', HTTP_ACCEPT='application/json')
mock_is_allowed.assert_called_with(
self.user.username,
'courses.edit_course_content',
@@ -327,7 +327,7 @@ def test_delete_regular_block_checks_edit_course_content(self, _mock_flag, mock_
def test_delete_static_tab_checks_manage_pages_and_resources(self, _mock_flag, mock_is_allowed):
"""DELETE on static_tab should check courses.manage_pages_and_resources"""
- self.client.delete(f'/xblock/{self.static_tab.location}', HTTP_ACCEPT='application/json')
+ self.client.delete(f'/xblock/{self.static_tab.usage_key}', HTTP_ACCEPT='application/json')
mock_is_allowed.assert_called_with(
self.user.username,
'courses.manage_pages_and_resources',
@@ -338,7 +338,7 @@ def test_delete_static_tab_checks_manage_pages_and_resources(self, _mock_flag, m
def test_create_block_checks_edit_course_content(self, _mock_flag, mock_is_allowed):
"""POST /xblock/ to create block should check courses.edit_course_content"""
- self.client.ajax_post('/xblock/', data={'category': 'html', 'parent_locator': str(self.vertical.location)})
+ self.client.ajax_post('/xblock/', data={'category': 'html', 'parent_locator': str(self.vertical.usage_key)})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.edit_course_content',
@@ -349,7 +349,7 @@ def test_create_static_tab_checks_manage_pages_and_resources(self, _mock_flag, m
"""PUT /xblock/ to create static_tab should check courses.manage_pages_and_resources"""
self.client.put(
'/xblock/',
- data={'category': 'static_tab', 'parent_locator': str(self.course.location)},
+ data={'category': 'static_tab', 'parent_locator': str(self.course.usage_key)},
content_type='application/json', HTTP_ACCEPT='application/json',
)
mock_is_allowed.assert_called_with(
@@ -363,8 +363,8 @@ def test_duplicate_block_checks_edit_course_content(self, _mock_flag, mock_is_al
self.client.ajax_post(
'/xblock/',
data={
- 'duplicate_source_locator': str(self.html_block.location),
- 'parent_locator': str(self.vertical.location),
+ 'duplicate_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(self.vertical.usage_key),
}
)
mock_is_allowed.assert_called_with(
@@ -378,8 +378,8 @@ def test_duplicate_block_checks_edit_course_content(self, _mock_flag, mock_is_al
def test_put_reorder_checks_edit_course_content(self, _mock_flag, mock_is_allowed):
"""PUT on regular block (reorder children) should check courses.edit_course_content"""
self.client.put(
- f'/xblock/{self.vertical.location}',
- data={'children': [str(self.html_block.location)]},
+ f'/xblock/{self.vertical.usage_key}',
+ data={'children': [str(self.html_block.usage_key)]},
content_type='application/json', HTTP_ACCEPT='application/json',
)
mock_is_allowed.assert_called_with(
@@ -392,12 +392,12 @@ def test_put_reorder_checks_edit_course_content(self, _mock_flag, mock_is_allowe
def test_move_block_checks_edit_course_content(self, _mock_flag, mock_is_allowed):
"""PATCH /xblock/ to move should check courses.edit_course_content"""
- vertical2 = BlockFactory.create(category='vertical', parent_location=self.sequential.location)
+ vertical2 = BlockFactory.create(category='vertical', parent_location=self.sequential.usage_key)
self.client.patch(
'/xblock/',
data={
- 'move_source_locator': str(self.html_block.location),
- 'parent_locator': str(vertical2.location),
+ 'move_source_locator': str(self.html_block.usage_key),
+ 'parent_locator': str(vertical2.usage_key),
},
content_type='application/json',
HTTP_ACCEPT='application/json',
@@ -412,7 +412,7 @@ def test_move_block_checks_edit_course_content(self, _mock_flag, mock_is_allowed
def test_post_static_tab_checks_manage_pages_and_resources(self, _mock_flag, mock_is_allowed):
"""POST on static_tab should check courses.manage_pages_and_resources"""
- self.client.ajax_post(f'/xblock/{self.static_tab.location}', data={'metadata': {'display_name': 'Updated'}})
+ self.client.ajax_post(f'/xblock/{self.static_tab.usage_key}', data={'metadata': {'display_name': 'Updated'}})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.manage_pages_and_resources',
@@ -422,7 +422,7 @@ def test_post_static_tab_checks_manage_pages_and_resources(self, _mock_flag, moc
def test_put_static_tab_checks_manage_pages_and_resources(self, _mock_flag, mock_is_allowed):
"""PUT on static_tab should check courses.manage_pages_and_resources"""
self.client.put(
- f'/xblock/{self.static_tab.location}',
+ f'/xblock/{self.static_tab.usage_key}',
data={'metadata': {'display_name': 'Updated'}},
content_type='application/json', HTTP_ACCEPT='application/json',
)
@@ -434,7 +434,7 @@ def test_put_static_tab_checks_manage_pages_and_resources(self, _mock_flag, mock
def test_post_course_info_checks_manage_course_updates(self, _mock_flag, mock_is_allowed):
"""POST on course_info block should check courses.manage_course_updates"""
- self.client.ajax_post(f'/xblock/{self.course_info.location}', data={'data': 'Updated
'})
+ self.client.ajax_post(f'/xblock/{self.course_info.usage_key}', data={'data': 'Updated
'})
mock_is_allowed.assert_called_with(
self.user.username,
'courses.manage_course_updates',
@@ -444,7 +444,7 @@ def test_post_course_info_checks_manage_course_updates(self, _mock_flag, mock_is
def test_put_course_info_checks_manage_course_updates(self, _mock_flag, mock_is_allowed):
"""PUT on course_info should check courses.manage_course_updates"""
self.client.put(
- f'/xblock/{self.course_info.location}',
+ f'/xblock/{self.course_info.usage_key}',
data={'data': 'Updated
'},
content_type='application/json',
HTTP_ACCEPT='application/json',
@@ -460,11 +460,11 @@ def test_put_course_info_checks_manage_course_updates(self, _mock_flag, mock_is_
def test_authz_denied_raises_permission_denied(self, _mock_flag, mock_is_allowed):
"""When authz denies permission, PermissionDenied should be raised"""
mock_is_allowed.return_value = False
- response = self.client.get_json(f'/xblock/{self.html_block.location}')
+ response = self.client.get_json(f'/xblock/{self.html_block.usage_key}')
self.assertEqual(response.status_code, 403)
def test_authz_flag_disabled_uses_legacy_permissions(self, _mock_flag, mock_is_allowed):
"""When authz flag is disabled, should use legacy permission checks"""
with patch.object(core_toggles.AUTHZ_COURSE_AUTHORING_FLAG, 'is_enabled', return_value=False):
- self.client.get_json(f'/xblock/{self.html_block.location}')
+ self.client.get_json(f'/xblock/{self.html_block.usage_key}')
mock_is_allowed.assert_not_called()
diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py
index 42f57563c292..5a20aeb0d894 100644
--- a/cms/djangoapps/contentstore/tests/utils.py
+++ b/cms/djangoapps/contentstore/tests/utils.py
@@ -133,8 +133,8 @@ def assertCoursesEqual(self, course1_id, course2_id):
course2_items = self.store.get_items(course2_id)
self.assertGreater(len(course1_items), 0) # ensure it found content instead of [] == []
if len(course1_items) != len(course2_items):
- course1_block_ids = {item.location.block_id for item in course1_items}
- course2_block_ids = {item.location.block_id for item in course2_items}
+ course1_block_ids = {item.usage_key.block_id for item in course1_items}
+ course2_block_ids = {item.usage_key.block_id for item in course2_items}
raise AssertionError(
"Course1 extra blocks: {}; course2 extra blocks: {}".format(
course1_block_ids - course2_block_ids, course2_block_ids - course1_block_ids
@@ -142,7 +142,7 @@ def assertCoursesEqual(self, course1_id, course2_id):
)
for course1_item in course1_items:
- course1_item_loc = course1_item.location
+ course1_item_loc = course1_item.usage_key
course2_item_loc = course2_id.make_usage_key(course1_item_loc.block_type, course1_item_loc.block_id)
if course1_item_loc.block_type == 'course':
# mongo uses the run as the name, split uses 'course'
@@ -194,7 +194,7 @@ def check_verticals(self, items):
# assert is here to make sure that the course being tested actually has verticals (units) to check.
self.assertGreater(len(items), 0, "Course has no verticals (units) to check")
for block in items:
- resp = self.client.get_html(get_url('container_handler', block.location))
+ resp = self.client.get_html(get_url('container_handler', block.usage_key))
self.assertEqual(resp.status_code, 200)
def assertAssetsEqual(self, asset_son, course1_id, course2_id):
diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py
index f40fad42152c..6cedf852e270 100644
--- a/cms/djangoapps/contentstore/utils.py
+++ b/cms/djangoapps/contentstore/utils.py
@@ -582,7 +582,7 @@ def is_currently_visible_to_students(xblock):
"""
try:
- published = modulestore().get_item(xblock.location, revision=ModuleStoreEnum.RevisionOption.published_only)
+ published = modulestore().get_item(xblock.usage_key, revision=ModuleStoreEnum.RevisionOption.published_only)
# If there's no published version then the xblock is clearly not visible
except ItemNotFoundError:
return False
@@ -637,7 +637,7 @@ def find_release_date_source(xblock):
if xblock.category == 'chapter':
return xblock
- parent_location = modulestore().get_parent_location(xblock.location,
+ parent_location = modulestore().get_parent_location(xblock.usage_key,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# Orphaned xblocks set their own release date
if not parent_location:
@@ -664,7 +664,7 @@ def find_staff_lock_source(xblock):
if xblock.category == 'chapter':
return None
- parent_location = modulestore().get_parent_location(xblock.location,
+ parent_location = modulestore().get_parent_location(xblock.usage_key,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# Orphaned xblocks set their own staff lock
if not parent_location:
@@ -680,7 +680,7 @@ def ancestor_has_staff_lock(xblock, parent_xblock=None):
Can avoid mongo query by passing in parent_xblock.
"""
if parent_xblock is None:
- parent_location = modulestore().get_parent_location(xblock.location,
+ parent_location = modulestore().get_parent_location(xblock.usage_key,
revision=ModuleStoreEnum.RevisionOption.draft_preferred)
if not parent_location:
return False
@@ -692,7 +692,7 @@ def get_sequence_usage_keys(course):
"""
Extracts a list of 'subsections' usage_keys
"""
- return [str(subsection.location)
+ return [str(subsection.usage_key)
for section in course.get_children()
for subsection in section.get_children()]
@@ -813,12 +813,12 @@ def get_user_partition_info(xblock, schemes=None, course=None):
]
"""
- course = course or modulestore().get_course(xblock.location.course_key)
+ course = course or modulestore().get_course(xblock.usage_key.course_key)
if course is None:
log.warning(
"Could not find course %s to retrieve user partition information",
- xblock.location.course_key
+ xblock.usage_key.course_key
)
return []
@@ -990,8 +990,8 @@ def get_subsections_in_section():
return section_subsections
except AttributeError:
log.error("URL Retrieval Error: subsection {subsection} included in section {section}".format(
- section=section.location,
- subsection=subsection.location
+ section=section.usage_key,
+ subsection=subsection.usage_key
))
return None
@@ -1004,7 +1004,7 @@ def get_sections_in_course():
return section_subsections
except AttributeError:
log.error("URL Retrieval Error: In section {section} in course".format(
- section=section.location,
+ section=section.usage_key,
))
return None
@@ -1013,16 +1013,16 @@ def get_subsection_location(section_subsections, current_subsection, direction):
Returns the desired location of the adjacent subsections in a section.
"""
location = None
- subsection_index = section_subsections.index(next(s for s in subsections if s.location ==
- current_subsection.location))
+ subsection_index = section_subsections.index(next(s for s in subsections if s.usage_key ==
+ current_subsection.usage_key))
try:
if direction == 'previous':
if subsection_index > 0:
prev_subsection = subsections[subsection_index - 1]
- location = prev_subsection.get_children()[-1].location
+ location = prev_subsection.get_children()[-1].usage_key
else:
next_subsection = subsections[subsection_index + 1]
- location = next_subsection.get_children()[0].location
+ location = next_subsection.get_children()[0].usage_key
return location
except IndexError:
return None
@@ -1032,15 +1032,15 @@ def get_section_location(course_sections, current_section, direction):
Returns the desired location of the adjacent sections in a course.
"""
location = None
- section_index = course_sections.index(next(s for s in sections if s.location == current_section.location))
+ section_index = course_sections.index(next(s for s in sections if s.usage_key == current_section.usage_key))
try:
if direction == 'previous':
if section_index > 0:
prev_section = sections[section_index - 1]
- location = prev_section.get_children()[-1].get_children()[-1].location
+ location = prev_section.get_children()[-1].get_children()[-1].usage_key
else:
next_section = sections[section_index + 1]
- location = next_section.get_children()[0].get_children()[0].location
+ location = next_section.get_children()[0].get_children()[0].usage_key
return location
except IndexError:
return None
@@ -1161,7 +1161,7 @@ def duplicate_block(
source_item = store.get_item(duplicate_source_usage_key)
if not dest_usage_key:
# Change the blockID to be unique.
- dest_usage_key = source_item.location.replace(name=uuid4().hex)
+ dest_usage_key = source_item.usage_key.replace(name=uuid4().hex)
category = dest_usage_key.block_type
@@ -1194,7 +1194,7 @@ def duplicate_block(
if source_item.has_children and not shallow and not children_handled:
dest_block.children = dest_block.children or []
for child in source_item.children:
- dupe = duplicate_block(dest_block.location, child, user=user, is_child=True)
+ dupe = duplicate_block(dest_block.usage_key, child, user=user, is_child=True)
if dupe not in dest_block.children: # _duplicate_block may add the child for us.
dest_block.children.append(dupe)
store.update_item(dest_block, user.id)
@@ -1204,11 +1204,11 @@ def duplicate_block(
parent = store.get_item(parent_usage_key)
# If source was already a child of the parent, add duplicate immediately afterward.
# Otherwise, add child to end.
- if source_item.location in parent.children:
- source_index = parent.children.index(source_item.location)
- parent.children.insert(source_index + 1, dest_block.location)
+ if source_item.usage_key in parent.children:
+ source_index = parent.children.index(source_item.usage_key)
+ parent.children.insert(source_index + 1, dest_block.usage_key)
else:
- parent.children.append(dest_block.location)
+ parent.children.append(dest_block.usage_key)
store.update_item(parent, user.id)
# .. event_implemented_name: XBLOCK_DUPLICATED
@@ -1216,13 +1216,13 @@ def duplicate_block(
XBLOCK_DUPLICATED.send_event(
time=datetime.now(timezone.utc),
xblock_info=DuplicatedXBlockData(
- usage_key=dest_block.location,
- block_type=dest_block.location.block_type,
+ usage_key=dest_block.usage_key,
+ block_type=dest_block.usage_key.block_type,
source_usage_key=duplicate_source_usage_key,
)
)
- return dest_block.location
+ return dest_block.usage_key
def update_from_source(*, source_block, destination_block, user_id):
@@ -1415,17 +1415,17 @@ def get_course_settings(request, course_key, course_block):
# see if the ORG of this course can be attributed to a defined configuration . In that case, the
# course about page should be editable in Studio
publisher_enabled = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'ENABLE_PUBLISHER',
settings.FEATURES.get('ENABLE_PUBLISHER', False)
)
marketing_enabled = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
enable_extended_course_details = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'ENABLE_EXTENDED_COURSE_DETAILS',
settings.FEATURES.get('ENABLE_EXTENDED_COURSE_DETAILS', False)
)
@@ -1433,7 +1433,7 @@ def get_course_settings(request, course_key, course_block):
about_page_editable = not publisher_enabled
enrollment_end_editable = GlobalStaff().has_user(request.user) or not publisher_enabled
short_description_editable = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'EDITABLE_SHORT_DESCRIPTION',
settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
)
@@ -1908,7 +1908,7 @@ def _get_course_index_context(request, course_key, course_block):
)
from openedx.core.djangoapps.content_staging import api as content_staging_api
- lms_link = get_lms_link_for_item(course_block.location)
+ lms_link = get_lms_link_for_item(course_block.usage_key)
reindex_link = None
if settings.FEATURES.get('ENABLE_COURSEWARE_INDEX', False):
if GlobalStaff().has_user(request.user):
@@ -1934,7 +1934,7 @@ def _get_course_index_context(request, course_key, course_block):
deprecated_blocks_info = _deprecated_blocks_info(course_block, deprecated_block_names)
frontend_app_publisher_url = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'FRONTEND_APP_PUBLISHER_URL',
settings.FEATURES.get('FRONTEND_APP_PUBLISHER_URL', False)
)
@@ -2039,14 +2039,14 @@ def get_container_handler_context(request, usage_key, course, xblock): # pylint
subsection = get_parent_xblock(unit)
if subsection is None:
- raise ValueError(f"Could not determine parent subsection from unit {unit.location}")
+ raise ValueError(f"Could not determine parent subsection from unit {unit.usage_key}")
section = get_parent_xblock(subsection)
if section is None:
- raise ValueError(f"Could not determine ancestor section from unit {unit.location}")
+ raise ValueError(f"Could not determine ancestor section from unit {unit.usage_key}")
# for the sequence navigator
- prev_url, next_url = get_sibling_urls(subsection, unit.location)
+ prev_url, next_url = get_sibling_urls(subsection, unit.usage_key)
# these are quoted here because they'll end up in a query string on the page,
# and quoting with mako will trigger the xss linter...
prev_url = quote_plus(prev_url) if prev_url else None
@@ -2068,21 +2068,21 @@ def get_container_handler_context(request, usage_key, course, xblock): # pylint
# preview will need this
index = 1
for child in subsection.get_children():
- if child.location == unit.location:
+ if child.usage_key == unit.usage_key:
break
index += 1
# Get the status of the user's clipboard so they can paste components if they have something to paste
user_clipboard = content_staging_api.get_user_clipboard_json(request.user.id, request)
library_block_types = [problem_type['component'] for problem_type in LIBRARY_BLOCK_TYPES]
- is_library_xblock = xblock.location.block_type in library_block_types
+ is_library_xblock = xblock.usage_key.block_type in library_block_types
context = {
'language_code': request.LANGUAGE_CODE,
'context_course': course, # Needed only for display of menus at top of page.
'action': action,
'xblock': xblock,
- 'xblock_locator': xblock.location,
+ 'xblock_locator': xblock.usage_key,
'unit': unit,
'is_unit_page': is_unit_page,
'is_collapsible': is_library_xblock,
@@ -2376,7 +2376,7 @@ def get_xblock_render_context(request, block):
"reorderable_items": set(),
"paging": None,
"force_render": None,
- "item_url": "/container/{block.location}",
+ "item_url": "/container/{block.usage_key}",
"tags_count_map": {},
}
diff --git a/cms/djangoapps/contentstore/video_storage_handlers.py b/cms/djangoapps/contentstore/video_storage_handlers.py
index 46215ae90362..7b61957625c1 100644
--- a/cms/djangoapps/contentstore/video_storage_handlers.py
+++ b/cms/djangoapps/contentstore/video_storage_handlers.py
@@ -295,7 +295,7 @@ def get_video_usage_path(course_key, edx_video_id):
try:
if video_id == edx_video_id:
usage_dict = {'display_location': '', 'url': ''}
- video_location = str(video.location)
+ video_location = str(video.usage_key)
xblock_display_name = getattr(video, 'display_name', '')
unit = video.get_parent()
unit_location = str(video.parent)
diff --git a/cms/djangoapps/contentstore/views/block.py b/cms/djangoapps/contentstore/views/block.py
index b57042085df2..83fa6c867ca1 100644
--- a/cms/djangoapps/contentstore/views/block.py
+++ b/cms/djangoapps/contentstore/views/block.py
@@ -222,7 +222,7 @@ def xblock_view_handler(request, usage_key_string, view_name):
# added to the list.
reorderable_items = set()
if view_name == "reorderable_container_child_preview":
- reorderable_items.add(xblock.location)
+ reorderable_items.add(xblock.usage_key)
paging = None
try:
diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py
index 8b16fdbad80d..2be4873bb03c 100644
--- a/cms/djangoapps/contentstore/views/component.py
+++ b/cms/djangoapps/contentstore/views/component.py
@@ -163,10 +163,10 @@ def container_handler(request, usage_key_string): # pylint: disable=too-many-st
if use_new_unit_page(course.id):
if is_unit(xblock) or is_library_content(xblock):
- return redirect(get_unit_url(course.id, xblock.location))
+ return redirect(get_unit_url(course.id, xblock.usage_key))
if split_xblock := get_parent_if_split_test(xblock):
- return redirect(get_unit_url(course.id, split_xblock.location))
+ return redirect(get_unit_url(course.id, split_xblock.usage_key))
container_handler_context = get_container_handler_context(request, usage_key, course, xblock)
container_handler_context.update({
@@ -310,7 +310,7 @@ def create_support_legend_dict():
component_types = _filter_disabled_blocks(component_types)
# Filter out discussion component from component_types if non-legacy discussion provider is configured for course
- component_types = _filter_discussion_for_non_legacy_provider(component_types, courselike.location.course_key)
+ component_types = _filter_discussion_for_non_legacy_provider(component_types, courselike.usage_key.course_key)
# Content Libraries currently don't allow opting in to unsupported xblocks/problem types.
allow_unsupported = getattr(courselike, "allow_unsupported_xblocks", False)
@@ -549,8 +549,8 @@ def _get_item_in_course(request, usage_key):
course = modulestore().get_course(course_key)
item = modulestore().get_item(usage_key, depth=1)
- lms_link = get_lms_link_for_item(item.location)
- preview_lms_link = get_lms_link_for_item(item.location, preview=True)
+ lms_link = get_lms_link_for_item(item.usage_key)
+ preview_lms_link = get_lms_link_for_item(item.usage_key, preview=True)
return course, item, lms_link, preview_lms_link
diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py
index 115aea1a83aa..3099c9c9b458 100644
--- a/cms/djangoapps/contentstore/views/course.py
+++ b/cms/djangoapps/contentstore/views/course.py
@@ -404,7 +404,7 @@ def course_filter(course_summary):
Filter out unusable and inaccessible courses
"""
# TODO remove this condition when templates purged from db
- if course_summary.location.course == 'templates':
+ if course_summary.usage_key.course == 'templates':
return False
return has_studio_read_access(request.user, course_summary.id)
@@ -489,7 +489,7 @@ def course_filter(course):
return False
# TODO remove this condition when templates purged from db
- if course.location.course == 'templates':
+ if course.usage_key.course == 'templates':
return False
return has_studio_read_access(request.user, course.id)
@@ -517,7 +517,7 @@ def course_filter(course):
return False
# TODO remove this condition when templates purged from db
- if course.location.course == 'templates':
+ if course.usage_key.course == 'templates':
return False
return has_studio_read_access(request.user, course.id)
@@ -646,7 +646,7 @@ def _accessible_libraries_iter(user, org=None):
else:
libraries = modulestore().get_library_summaries()
# No need to worry about ErrorBlocks - split's get_libraries() never returns them.
- return (lib for lib in libraries if has_studio_read_access(user, lib.location.library_key))
+ return (lib for lib in libraries if has_studio_read_access(user, lib.usage_key.library_key))
@login_required
@@ -688,11 +688,11 @@ def format_library_for_view(library, request, migration: ModulestoreMigration |
}
return {
'display_name': library.display_name,
- 'library_key': str(library.location.library_key),
- 'url': reverse_library_url('library_handler', str(library.location.library_key)),
+ 'library_key': str(library.usage_key.library_key),
+ 'url': reverse_library_url('library_handler', str(library.usage_key.library_key)),
'org': library.display_org_with_default,
'number': library.display_number_with_default,
- 'can_edit': has_studio_write_access(request.user, library.location.library_key),
+ 'can_edit': has_studio_write_access(request.user, library.usage_key.library_key),
'is_migrated': migration is not None,
**migration_info,
}
@@ -791,13 +791,13 @@ def format_course_for_view(course):
"""
course_context = {
'display_name': course.display_name,
- 'course_key': str(course.location.course_key),
+ 'course_key': str(course.usage_key.course_key),
'url': reverse_course_url('course_handler', course.id),
- 'lms_link': get_lms_link_for_item(course.location),
+ 'lms_link': get_lms_link_for_item(course.usage_key),
'rerun_link': _get_rerun_link_for_item(course.id),
'org': course.display_org_with_default,
'number': course.display_number_with_default,
- 'run': course.location.run
+ 'run': course.usage_key.run
}
if course.id.deprecated:
course_context.update({
@@ -1301,7 +1301,7 @@ def advanced_settings_handler(request, course_key_string):
if use_new_advanced_settings_page(course_key):
return redirect(get_advanced_settings_url(course_key))
publisher_enabled = configuration_helpers.get_value_for_org(
- course_block.location.org,
+ course_block.usage_key.org,
'ENABLE_PUBLISHER',
settings.FEATURES.get('ENABLE_PUBLISHER', False)
)
@@ -1783,7 +1783,7 @@ def bulk_enable_disable_discussions(request, course_key_string):
store.update_item(vertical, user.id)
if store.has_published_version(vertical):
- store.publish(vertical.location, user.id)
+ store.publish(vertical.usage_key, user.id)
changed += 1
return JsonResponse({"units_updated_and_republished": changed})
except Exception as e: # lint-amnesty, pylint: disable=broad-except
diff --git a/cms/djangoapps/contentstore/views/entrance_exam.py b/cms/djangoapps/contentstore/views/entrance_exam.py
index 5d914366bd9e..3ba7b286bdae 100644
--- a/cms/djangoapps/contentstore/views/entrance_exam.py
+++ b/cms/djangoapps/contentstore/views/entrance_exam.py
@@ -132,7 +132,7 @@ def _create_entrance_exam(request, course_key, entrance_exam_minimum_score_pct=N
return HttpResponse(status=400)
# Create the entrance exam item (currently it's just a chapter)
- parent_locator = str(course.location)
+ parent_locator = str(course.usage_key)
created_block = create_xblock(
parent_locator=parent_locator,
user=request.user,
@@ -147,13 +147,13 @@ def _create_entrance_exam(request, course_key, entrance_exam_minimum_score_pct=N
metadata = {
'entrance_exam_enabled': True,
'entrance_exam_minimum_score_pct': entrance_exam_minimum_score_pct,
- 'entrance_exam_id': str(created_block.location),
+ 'entrance_exam_id': str(created_block.usage_key),
}
CourseMetadata.update_from_dict(metadata, course, request.user)
# Create the entrance exam section item.
create_xblock(
- parent_locator=str(created_block.location),
+ parent_locator=str(created_block.usage_key),
user=request.user,
category='sequential',
display_name=_('Entrance Exam - Subsection')
@@ -179,7 +179,7 @@ def _get_entrance_exam(request, course_key):
try:
exam_block = modulestore().get_item(exam_key)
return HttpResponse( # lint-amnesty, pylint: disable=http-response-with-content-type-json
- dump_js_escaped_json({'locator': str(exam_block.location)}),
+ dump_js_escaped_json({'locator': str(exam_block.usage_key)}),
status=200, content_type='application/json')
except ItemNotFoundError:
return HttpResponse(status=404)
@@ -262,7 +262,7 @@ def add_entrance_exam_milestone(course_id, x_block): # lint-amnesty, pylint: di
)
milestones_helpers.add_course_content_milestone(
str(course_id),
- str(x_block.location),
+ str(x_block.usage_key),
relationship_types['FULFILLS'],
milestone
)
diff --git a/cms/djangoapps/contentstore/views/library.py b/cms/djangoapps/contentstore/views/library.py
index bcc0ffe84842..075b7852f3a6 100644
--- a/cms/djangoapps/contentstore/views/library.py
+++ b/cms/djangoapps/contentstore/views/library.py
@@ -187,16 +187,16 @@ def _list_libraries(request):
lib_info = [
{
"display_name": lib.display_name,
- "library_key": str(lib.location.library_key),
+ "library_key": str(lib.usage_key.library_key),
}
for lib in libraries
if (
(
text_search in lib.display_name.lower() or
- text_search in lib.location.library_key.org.lower() or
- text_search in lib.location.library_key.library.lower()
+ text_search in lib.usage_key.library_key.org.lower() or
+ text_search in lib.usage_key.library_key.library.lower()
) and
- has_studio_read_access(request.user, lib.location.library_key)
+ has_studio_read_access(request.user, lib.usage_key.library_key)
)
]
return JsonResponse(lib_info)
@@ -226,7 +226,7 @@ def _create_library(request):
fields={"display_name": display_name},
)
# Give the user admin ("Instructor") role for this library:
- add_instructor(new_lib.location.library_key, request.user, request.user)
+ add_instructor(new_lib.usage_key.library_key, request.user, request.user)
except PermissionDenied as error: # pylint: disable=unused-variable
log.info(
"User does not have the permission to create LIBRARY in this organization."
@@ -267,7 +267,7 @@ def _create_library(request):
).format(organization_key=org)
})
- lib_key_str = str(new_lib.location.library_key)
+ lib_key_str = str(new_lib.usage_key.library_key)
return JsonResponse({
'url': reverse_library_url('library_handler', lib_key_str),
'library_key': lib_key_str,
@@ -284,8 +284,8 @@ def library_blocks_view(library, user, response_format):
Assumes that read permissions have been checked before calling this.
"""
- assert isinstance(library.location.library_key, LibraryLocator)
- assert isinstance(library.location, LibraryUsageLocator)
+ assert isinstance(library.usage_key.library_key, LibraryLocator)
+ assert isinstance(library.usage_key, LibraryUsageLocator)
children = library.children
if response_format == "json":
@@ -293,13 +293,13 @@ def library_blocks_view(library, user, response_format):
prev_version = library.runtime.course_entry.structure['previous_version']
return JsonResponse({
"display_name": library.display_name,
- "library_id": str(library.location.library_key),
+ "library_id": str(library.usage_key.library_key),
"version": str(library.runtime.course_entry.course_key.version_guid),
"previous_version": str(prev_version) if prev_version else None,
"blocks": [str(x) for x in children],
})
- can_edit = has_studio_write_access(user, library.location.library_key)
+ can_edit = has_studio_write_access(user, library.usage_key.library_key)
xblock_info = create_xblock_info(library, include_ancestor_info=False, graders=[])
component_templates = get_component_templates(library, library=True) if can_edit else []
diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py
index 6600430a7a89..5c6333c0550f 100644
--- a/cms/djangoapps/contentstore/views/preview.py
+++ b/cms/djangoapps/contentstore/views/preview.py
@@ -162,7 +162,7 @@ def _prepare_runtime_for_preview(request, block):
block: An XBlock
"""
- course_id = block.location.course_key
+ course_id = block.usage_key.course_key
display_name_only = (block.category == 'static_tab')
wrappers = [
@@ -298,7 +298,7 @@ def _is_xblock_reorderable(xblock, context):
otherwise returns false.
"""
try:
- return xblock.location in context['reorderable_items']
+ return xblock.usage_key in context['reorderable_items']
except KeyError:
return False
@@ -313,12 +313,12 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
# Only add the Studio wrapper when on the container page. The "Pages" page will remain as is for now.
if not context.get('is_pages_view', None) and view in PREVIEW_VIEWS:
root_xblock = context.get('root_xblock')
- is_root = root_xblock and xblock.location == root_xblock.location
+ is_root = root_xblock and xblock.usage_key == root_xblock.usage_key
is_reorderable = _is_xblock_reorderable(xblock, context)
selected_groups_label = get_visibility_partition_info(xblock)['selected_groups_label']
if selected_groups_label:
selected_groups_label = _('Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label) # lint-amnesty, pylint: disable=line-too-long
- course = modulestore().get_course(xblock.location.course_key)
+ course = modulestore().get_course(xblock.usage_key.course_key)
can_edit = context.get('can_edit', True)
can_add = context.get('can_add', True)
@@ -344,7 +344,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
tags_count_map = context.get('tags_count_map')
tags_count = 0
if tags_count_map:
- tags_count = tags_count_map.get(str(xblock.location), 0)
+ tags_count = tags_count_map.get(str(xblock.usage_key), 0)
template_context = {
'xblock_context': context,
'xblock': xblock,
diff --git a/cms/djangoapps/contentstore/views/tabs.py b/cms/djangoapps/contentstore/views/tabs.py
index 8fa9d024458d..83976d418cf0 100644
--- a/cms/djangoapps/contentstore/views/tabs.py
+++ b/cms/djangoapps/contentstore/views/tabs.py
@@ -199,7 +199,7 @@ def get_tab_by_locator(tab_list: List[CourseTab], tab_location: Union[str, Usage
item = modulestore().get_item(tab_location)
static_tab = StaticTab(
name=item.display_name,
- url_slug=item.location.name,
+ url_slug=item.usage_key.name,
)
return CourseTabList.get_tab_by_id(tab_list, static_tab.tab_id)
diff --git a/cms/djangoapps/contentstore/views/tests/test_block.py b/cms/djangoapps/contentstore/views/tests/test_block.py
index 31f5244e2f55..0789c9d84b67 100644
--- a/cms/djangoapps/contentstore/views/tests/test_block.py
+++ b/cms/djangoapps/contentstore/views/tests/test_block.py
@@ -111,7 +111,7 @@ def setUp(self):
super().setUp()
self.course_key = self.course.id
- self.usage_key = self.course.location
+ self.usage_key = self.course.usage_key
def get_item_from_modulestore(self, usage_key):
"""
@@ -489,7 +489,7 @@ def test_ancestor_info(self, field_type):
# Create a parent chapter
chap1 = self.create_xblock(
- parent_usage_key=self.course.location,
+ parent_usage_key=self.course.usage_key,
display_name="chapter1",
category="chapter",
)
@@ -526,7 +526,7 @@ def assert_xblock_info(xblock, xblock_info):
xblock (XBlock): An XBlock item.
xblock_info (dict): A dict containing xblock information.
"""
- self.assertEqual(str(xblock.location), xblock_info["id"])
+ self.assertEqual(str(xblock.usage_key), xblock_info["id"])
self.assertEqual(xblock.display_name, xblock_info["display_name"])
self.assertEqual(xblock.category, xblock_info["category"])
@@ -563,7 +563,7 @@ def test_delete_static_page(self):
course = CourseFactory.create()
# Add static tab
resp = self.create_xblock(
- category="static_tab", parent_usage_key=course.location
+ category="static_tab", parent_usage_key=course.usage_key
)
usage_key = self.response_usage_key(resp)
@@ -590,8 +590,8 @@ def test_create_nicely(self):
new_obj = self.get_item_from_modulestore(chap_usage_key)
self.assertEqual(new_obj.scope_ids.block_type, "chapter")
self.assertEqual(new_obj.display_name, display_name)
- self.assertEqual(new_obj.location.org, self.course.location.org)
- self.assertEqual(new_obj.location.course, self.course.location.course)
+ self.assertEqual(new_obj.usage_key.org, self.course.usage_key.org)
+ self.assertEqual(new_obj.usage_key.course, self.course.usage_key.course)
# get the course and ensure it now points to this one
course = self.get_item_from_modulestore(self.usage_key)
@@ -674,8 +674,8 @@ def _check_equality(
self.assertEqual(duplicated_asides[0].field13, "aside1_default_value3")
self.assertNotEqual(
- str(original_item.location),
- str(duplicated_item.location),
+ str(original_item.usage_key),
+ str(duplicated_item.usage_key),
"Location of duplicate should be different from original",
)
@@ -696,7 +696,7 @@ def _check_equality(
# Set the location and parent to be the same so we can make sure the rest of the
# duplicate is equal.
- duplicated_item.location = original_item.location
+ duplicated_item.usage_key = original_item.usage_key
duplicated_item.parent = original_item.parent
# Children will also be duplicated, so for the purposes of testing equality, we will set
@@ -930,12 +930,12 @@ def test_shallow_duplicate(self):
)
BlockFactory(parent=source_chapter, category="html", display_name="Child")
# Refresh.
- source_chapter = self.store.get_item(source_chapter.location)
+ source_chapter = self.store.get_item(source_chapter.usage_key)
self.assertEqual(len(source_chapter.get_children()), 1)
destination_course = CourseFactory()
destination_location = duplicate_block(
- parent_usage_key=destination_course.location,
- duplicate_source_usage_key=source_chapter.location,
+ parent_usage_key=destination_course.usage_key,
+ duplicate_source_usage_key=source_chapter.usage_key,
user=user,
display_name=source_chapter.display_name,
shallow=True,
@@ -969,8 +969,8 @@ def test_duplicate_library_content_block(self): # pylint: disable=too-many-stat
publish_item=False,
)
original_lib_version = store.get_library(
- lib.location.library_key, remove_version=False, remove_branch=False,
- ).location.library_key.version_guid
+ lib.usage_key.library_key, remove_version=False, remove_branch=False,
+ ).usage_key.library_key.version_guid
assert original_lib_version is not None
# Create a library content block (lc), point it out our library, and sync it.
@@ -983,13 +983,13 @@ def test_duplicate_library_content_block(self): # pylint: disable=too-many-stat
lc = BlockFactory(
parent=unit,
category="library_content",
- source_library_id=str(lib.location.library_key),
+ source_library_id=str(lib.usage_key.library_key),
display_name="LC Block",
max_count=1,
publish_item=False,
)
lc.sync_from_library()
- lc = store.get_item(lc.location) # we must reload because sync_from_library happens out-of-thread
+ lc = store.get_item(lc.usage_key) # we must reload because sync_from_library happens out-of-thread
assert lc.source_library_version == str(original_lib_version)
lc_html_1 = store.get_item(lc.children[0])
lc_html_2 = store.get_item(lc.children[1])
@@ -1017,8 +1017,8 @@ def test_duplicate_library_content_block(self): # pylint: disable=too-many-stat
store.update_item(lib_html_1, self.user.id)
store.update_item(lib_html_2, self.user.id)
updated_lib_version = store.get_library(
- lib.location.library_key, remove_version=False, remove_branch=False,
- ).location.library_key.version_guid
+ lib.usage_key.library_key, remove_version=False, remove_branch=False,
+ ).usage_key.library_key.version_guid
assert updated_lib_version is not None
assert updated_lib_version != original_lib_version
@@ -1027,17 +1027,17 @@ def test_duplicate_library_content_block(self): # pylint: disable=too-many-stat
# All settings should match between lc and dupe.
dupe = store.get_item(
self._duplicate_item(
- parent_usage_key=unit.location,
- source_usage_key=lc.location,
+ parent_usage_key=unit.usage_key,
+ source_usage_key=lc.usage_key,
display_name="Dupe LC Block",
)
)
- lc = store.get_item(lc.location)
- unit = store.get_item(unit.location)
- assert unit.children == [lc.location, dupe.location]
+ lc = store.get_item(lc.usage_key)
+ unit = store.get_item(unit.usage_key)
+ assert unit.children == [lc.usage_key, dupe.usage_key]
assert len(lc.children) == len(dupe.children) == 2
assert lc.max_count == dupe.max_count == 1
- assert lc.source_library_id == dupe.source_library_id == str(lib.location.library_key)
+ assert lc.source_library_id == dupe.source_library_id == str(lib.usage_key.library_key)
assert lc.source_library_version == dupe.source_library_version == str(original_lib_version)
# The lc block's children should remain unchanged.
@@ -1064,7 +1064,7 @@ def test_duplicate_library_content_block(self): # pylint: disable=too-many-stat
# Finally, upgrade the dupe's library version, and make sure it pulls in updated library block *content*,
# whilst preserving *settings overrides* (specifically, HTML 1's title override).
dupe.sync_from_library(upgrade_to_latest=True)
- dupe = store.get_item(dupe.location)
+ dupe = store.get_item(dupe.usage_key)
assert dupe.source_library_version == str(updated_lib_version)
assert len(dupe.children) == 2
dupe_html_1 = store.get_item(dupe.children[0])
@@ -1096,16 +1096,16 @@ def test_duplicate_tags(self):
tagging_api.add_tag_to_taxonomy(taxonomyB, "four")
# Tag the chapter
- tagging_api.tag_object(str(source_chapter.location), taxonomyA, ["one", "two"])
- tagging_api.tag_object(str(source_chapter.location), taxonomyB, ["three", "four"])
+ tagging_api.tag_object(str(source_chapter.usage_key), taxonomyA, ["one", "two"])
+ tagging_api.tag_object(str(source_chapter.usage_key), taxonomyB, ["three", "four"])
# Tag the child block
- tagging_api.tag_object(str(source_block.location), taxonomyA, ["two"],)
+ tagging_api.tag_object(str(source_block.usage_key), taxonomyA, ["two"],)
# Duplicate the chapter (and its children)
dupe_location = duplicate_block(
- parent_usage_key=source_course.location,
- duplicate_source_usage_key=source_chapter.location,
+ parent_usage_key=source_course.usage_key,
+ duplicate_source_usage_key=source_chapter.usage_key,
user=user,
)
dupe_chapter = self.store.get_item(dupe_location)
@@ -1114,17 +1114,17 @@ def test_duplicate_tags(self):
# Check that the duplicated blocks also duplicated tags
expected_chapter_tags = [
- f' {str(dupe_chapter.location)}: A=one',
- f' {str(dupe_chapter.location)}: A=two',
- f' {str(dupe_chapter.location)}: B=four',
- f' {str(dupe_chapter.location)}: B=three',
+ f' {str(dupe_chapter.usage_key)}: A=one',
+ f' {str(dupe_chapter.usage_key)}: A=two',
+ f' {str(dupe_chapter.usage_key)}: B=four',
+ f' {str(dupe_chapter.usage_key)}: B=three',
]
- dupe_chapter_tags = [str(object_tag) for object_tag in tagging_api.get_object_tags(str(dupe_chapter.location))]
+ dupe_chapter_tags = [str(object_tag) for object_tag in tagging_api.get_object_tags(str(dupe_chapter.usage_key))]
assert dupe_chapter_tags == expected_chapter_tags
expected_block_tags = [
- f' {str(dupe_block.location)}: A=two',
+ f' {str(dupe_block.usage_key)}: A=two',
]
- dupe_block_tags = [str(object_tag) for object_tag in tagging_api.get_object_tags(str(dupe_block.location))]
+ dupe_block_tags = [str(object_tag) for object_tag in tagging_api.get_object_tags(str(dupe_block.usage_key))]
assert dupe_block_tags == expected_block_tags
@@ -1163,14 +1163,14 @@ def setup_course(self, default_store=None):
# Create a parent chapter
chap1 = self.create_xblock(
- parent_usage_key=course.location,
+ parent_usage_key=course.usage_key,
display_name="chapter1",
category="chapter",
)
self.chapter_usage_key = self.response_usage_key(chap1)
chap2 = self.create_xblock(
- parent_usage_key=course.location,
+ parent_usage_key=course.usage_key,
display_name="chapter2",
category="chapter",
)
@@ -1225,7 +1225,7 @@ def setup_course(self, default_store=None):
)
self.split_test_usage_key = self.response_usage_key(resp)
- self.course = self.store.get_item(course.location)
+ self.course = self.store.get_item(course.usage_key)
def setup_and_verify_content_experiment(self, partition_id):
"""
@@ -1342,7 +1342,7 @@ def test_move_source_index(self):
parent = self.get_item_from_modulestore(self.vert_usage_key)
children = parent.get_children()
self.assertEqual(len(children), 4)
- self.assertEqual(children[1].location, html2_usage_key)
+ self.assertEqual(children[1].usage_key, html2_usage_key)
def test_move_undo(self):
"""
@@ -2078,7 +2078,7 @@ def test_move_orphaned_child_error(self):
"""
unit_1_key = self.store.create_item(
self.user.id, self.course_key, "vertical", "unit1"
- ).location
+ ).usage_key
# adding orphaned unit 1 should return an error
resp = self.client.ajax_post(
@@ -2251,7 +2251,7 @@ def _make_draft_content_different_from_published(self):
self.assertIsNone(published.due)
# Fetch the published version again to make sure the due date is still unset.
published = modulestore().get_item(
- published.location, revision=ModuleStoreEnum.RevisionOption.published_only
+ published.usage_key, revision=ModuleStoreEnum.RevisionOption.published_only
)
self.assertIsNone(published.due)
@@ -2308,7 +2308,7 @@ def test_published_and_draft_contents_with_update(self):
self.assertNotEqual(draft.data, published.data)
# Fetch the published version again to make sure the data is correct.
published = modulestore().get_item(
- published.location, revision=ModuleStoreEnum.RevisionOption.published_only
+ published.usage_key, revision=ModuleStoreEnum.RevisionOption.published_only
)
self.assertNotEqual(draft.data, published.data)
@@ -2481,11 +2481,11 @@ def test_create_groups(self):
# Verify that the group_id_to_child mapping is correct.
self.assertEqual(2, len(split_test.group_id_to_child))
self.assertEqual(
- vertical_0.location,
+ vertical_0.usage_key,
split_test.group_id_to_child[str(self.first_user_partition_group_1.id)],
)
self.assertEqual(
- vertical_1.location,
+ vertical_1.usage_key,
split_test.group_id_to_child[str(self.first_user_partition_group_2.id)],
)
@@ -2542,19 +2542,19 @@ def test_change_user_partition_id(self):
# Verify that the group_id_to child mapping is correct.
self.assertEqual(3, len(split_test.group_id_to_child))
self.assertEqual(
- vertical_0.location,
+ vertical_0.usage_key,
split_test.group_id_to_child[str(self.second_user_partition_group_1.id)],
)
self.assertEqual(
- vertical_1.location,
+ vertical_1.usage_key,
split_test.group_id_to_child[str(self.second_user_partition_group_2.id)],
)
self.assertEqual(
- vertical_2.location,
+ vertical_2.usage_key,
split_test.group_id_to_child[str(self.second_user_partition_group_3.id)],
)
- self.assertNotEqual(initial_vertical_0_location, vertical_0.location)
- self.assertNotEqual(initial_vertical_1_location, vertical_1.location)
+ self.assertNotEqual(initial_vertical_0_location, vertical_0.usage_key)
+ self.assertNotEqual(initial_vertical_1_location, vertical_1.usage_key)
def test_change_same_user_partition_id(self):
"""
@@ -3082,7 +3082,7 @@ def test_discussion_button_present_legacy_provider(self):
"""
Test the Discussion button present when legacy discussion provider configured for course
"""
- course_key = self.course.location.course_key
+ course_key = self.course.usage_key.course_key
# Create a discussion configuration with discussion provider set as legacy
DiscussionsConfiguration.objects.create(
@@ -3097,7 +3097,7 @@ def test_discussion_button_absent_non_legacy_provider(self):
"""
Test the Discussion button not present when non-legacy discussion provider configured for course
"""
- course_key = self.course.location.course_key
+ course_key = self.course.usage_key.course_key
# Create a discussion configuration with discussion provider set as legacy
DiscussionsConfiguration.objects.create(
@@ -3154,26 +3154,26 @@ def setUp(self):
super().setUp()
user_id = self.user.id
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Week 1",
user_id=user_id,
highlights=["highlight"],
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Lesson 1",
user_id=user_id,
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name="Unit 1",
user_id=user_id,
)
self.video = BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category="video",
display_name="My Video",
user_id=user_id,
@@ -3188,18 +3188,18 @@ def test_json_responses(self):
def test_xblock_outline_handler_mongo_calls(self):
course = CourseFactory.create()
chapter = BlockFactory.create(
- parent_location=course.location, category='chapter', display_name='Week 1'
+ parent_location=course.usage_key, category='chapter', display_name='Week 1'
)
- outline_url = reverse_usage_url('xblock_outline_handler', chapter.location)
+ outline_url = reverse_usage_url('xblock_outline_handler', chapter.usage_key)
with check_mongo_calls(3):
self.client.get(outline_url, HTTP_ACCEPT='application/json')
sequential = BlockFactory.create(
- parent_location=chapter.location, category='sequential', display_name='Sequential 1'
+ parent_location=chapter.usage_key, category='sequential', display_name='Sequential 1'
)
BlockFactory.create(
- parent_location=sequential.location, category='vertical', display_name='Vertical 1'
+ parent_location=sequential.usage_key, category='vertical', display_name='Vertical 1'
)
# calls should be same after adding two new children for split only.
with check_mongo_calls(3):
@@ -3207,13 +3207,13 @@ def test_xblock_outline_handler_mongo_calls(self):
def test_entrance_exam_chapter_xblock_info(self):
chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Entrance Exam",
user_id=self.user.id,
is_entrance_exam=True,
)
- chapter = modulestore().get_item(chapter.location)
+ chapter = modulestore().get_item(chapter.usage_key)
xblock_info = create_xblock_info(
chapter,
include_child_info=True,
@@ -3229,12 +3229,12 @@ def test_entrance_exam_chapter_xblock_info(self):
def test_none_entrance_exam_chapter_xblock_info(self):
chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Test Chapter",
user_id=self.user.id,
)
- chapter = modulestore().get_item(chapter.location)
+ chapter = modulestore().get_item(chapter.usage_key)
xblock_info = create_xblock_info(
chapter,
include_child_info=True,
@@ -3251,7 +3251,7 @@ def test_none_entrance_exam_chapter_xblock_info(self):
def test_entrance_exam_sequential_xblock_info(self):
chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Entrance Exam",
user_id=self.user.id,
@@ -3260,13 +3260,13 @@ def test_entrance_exam_sequential_xblock_info(self):
)
subsection = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category="sequential",
display_name="Subsection - Entrance Exam",
user_id=self.user.id,
in_entrance_exam=True,
)
- subsection = modulestore().get_item(subsection.location)
+ subsection = modulestore().get_item(subsection.usage_key)
xblock_info = create_xblock_info(
subsection, include_child_info=True, include_children_predicate=ALWAYS
)
@@ -3276,12 +3276,12 @@ def test_entrance_exam_sequential_xblock_info(self):
def test_none_entrance_exam_sequential_xblock_info(self):
subsection = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Subsection - Exam",
user_id=self.user.id,
)
- subsection = modulestore().get_item(subsection.location)
+ subsection = modulestore().get_item(subsection.usage_key)
xblock_info = create_xblock_info(
subsection,
include_child_info=True,
@@ -3292,7 +3292,7 @@ def test_none_entrance_exam_sequential_xblock_info(self):
self.assertIsNone(xblock_info.get("is_header_visible", None))
def test_chapter_xblock_info(self):
- chapter = modulestore().get_item(self.chapter.location)
+ chapter = modulestore().get_item(self.chapter.usage_key)
xblock_info = create_xblock_info(
chapter,
include_child_info=True,
@@ -3301,7 +3301,7 @@ def test_chapter_xblock_info(self):
self.validate_chapter_xblock_info(xblock_info)
def test_sequential_xblock_info(self):
- sequential = modulestore().get_item(self.sequential.location)
+ sequential = modulestore().get_item(self.sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3310,7 +3310,7 @@ def test_sequential_xblock_info(self):
self.validate_sequential_xblock_info(xblock_info)
def test_vertical_xblock_info(self):
- vertical = modulestore().get_item(self.vertical.location)
+ vertical = modulestore().get_item(self.vertical.usage_key)
xblock_info = create_xblock_info(
vertical,
@@ -3323,7 +3323,7 @@ def test_vertical_xblock_info(self):
self.validate_vertical_xblock_info(xblock_info)
def test_component_xblock_info(self):
- video = modulestore().get_item(self.video.location)
+ video = modulestore().get_item(self.video.usage_key)
xblock_info = create_xblock_info(
video, include_child_info=True, include_children_predicate=ALWAYS
)
@@ -3335,7 +3335,7 @@ def test_validate_start_date(self):
"""
course = CourseFactory.create()
chapter = BlockFactory.create(
- parent_location=course.location, category='chapter', display_name='Week 1'
+ parent_location=course.usage_key, category='chapter', display_name='Week 1'
)
chapter.start = datetime(year=1899, month=1, day=1, tzinfo=UTC)
@@ -3385,7 +3385,7 @@ def validate_course_xblock_info(
Validate that the xblock info is correct for the test course.
"""
self.assertEqual(xblock_info["category"], "course")
- self.assertEqual(xblock_info["id"], str(self.course.location))
+ self.assertEqual(xblock_info["id"], str(self.course.usage_key))
self.assertEqual(xblock_info["display_name"], self.course.display_name)
self.assertTrue(xblock_info["published"])
self.assertFalse(xblock_info["highlights_enabled_for_messaging"])
@@ -3400,7 +3400,7 @@ def validate_chapter_xblock_info(self, xblock_info, has_child_info=True):
Validate that the xblock info is correct for the test chapter.
"""
self.assertEqual(xblock_info["category"], "chapter")
- self.assertEqual(xblock_info["id"], str(self.chapter.location))
+ self.assertEqual(xblock_info["id"], str(self.chapter.usage_key))
self.assertEqual(xblock_info["display_name"], "Week 1")
self.assertTrue(xblock_info["published"])
self.assertIsNone(xblock_info.get("edited_by", None))
@@ -3425,7 +3425,7 @@ def validate_sequential_xblock_info(self, xblock_info, has_child_info=True):
Validate that the xblock info is correct for the test sequential.
"""
self.assertEqual(xblock_info["category"], "sequential")
- self.assertEqual(xblock_info["id"], str(self.sequential.location))
+ self.assertEqual(xblock_info["id"], str(self.sequential.usage_key))
self.assertEqual(xblock_info["display_name"], "Lesson 1")
self.assertTrue(xblock_info["published"])
self.assertIsNone(xblock_info.get("edited_by", None))
@@ -3440,7 +3440,7 @@ def validate_vertical_xblock_info(self, xblock_info):
Validate that the xblock info is correct for the test vertical.
"""
self.assertEqual(xblock_info["category"], "vertical")
- self.assertEqual(xblock_info["id"], str(self.vertical.location))
+ self.assertEqual(xblock_info["id"], str(self.vertical.usage_key))
self.assertEqual(xblock_info["display_name"], "Unit 1")
self.assertTrue(xblock_info["published"])
self.assertEqual(xblock_info["edited_by"], "testuser")
@@ -3464,7 +3464,7 @@ def validate_component_xblock_info(self, xblock_info):
Validate that the xblock info is correct for the test component.
"""
self.assertEqual(xblock_info["category"], "video")
- self.assertEqual(xblock_info["id"], str(self.video.location))
+ self.assertEqual(xblock_info["id"], str(self.video.usage_key))
self.assertEqual(xblock_info["display_name"], "My Video")
self.assertTrue(xblock_info["published"])
self.assertIsNone(xblock_info.get("edited_by", None))
@@ -3542,20 +3542,20 @@ def setUp(self):
super().setUp()
user_id = self.user.id
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Week 1",
user_id=user_id,
highlights=["highlight"],
)
# get updated course
- self.course = self.store.get_item(self.course.location)
+ self.course = self.store.get_item(self.course.usage_key)
self.course.enable_proctored_exams = True
self.course.save()
self.course = self.store.update_item(self.course, self.user.id)
def test_proctoring_is_enabled_for_course(self):
- course = modulestore().get_item(self.course.location)
+ course = modulestore().get_item(self.course.usage_key)
xblock_info = create_xblock_info(
course,
include_child_info=True,
@@ -3574,7 +3574,7 @@ def test_special_exam_xblock_info(
mock_get_exam_configuration_dashboard_url,
):
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3583,7 +3583,7 @@ def test_special_exam_xblock_info(
default_time_limit_minutes=100,
is_onboarding_exam=False,
)
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3621,7 +3621,7 @@ def test_show_review_rules_xblock_info(
# Set course.proctoring_provider to test_proctoring_provider
self.course.proctoring_provider = 'test_proctoring_provider'
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3630,7 +3630,7 @@ def test_show_review_rules_xblock_info(
default_time_limit_minutes=100,
is_onboarding_exam=False,
)
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3658,7 +3658,7 @@ def test_proctoring_values_correct_depending_on_lti_external(
_mock_get_exam_configuration_dashboard_url,
):
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3674,7 +3674,7 @@ def test_proctoring_values_correct_depending_on_lti_external(
# mock_does_backend_support_onboarding returns True
mock_does_backend_support_onboarding.return_value = True
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3701,7 +3701,7 @@ def test_xblock_was_ever_linked_to_external_exam(
_mock_get_exam_configuration_dashboard_url,
):
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3710,7 +3710,7 @@ def test_xblock_was_ever_linked_to_external_exam(
is_onboarding_exam=False,
)
mock_get_exam_by_content_id.return_value = {"external_id": external_id}
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3729,7 +3729,7 @@ def test_xblock_was_never_linked_to_external_exam(
_mock_get_exam_configuration_dashboard_url,
):
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3737,7 +3737,7 @@ def test_xblock_was_never_linked_to_external_exam(
is_time_limited=False,
is_onboarding_exam=False,
)
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
xblock_info = create_xblock_info(
sequential,
include_child_info=True,
@@ -3756,7 +3756,7 @@ def test_special_exam_xblock_info_get_dashboard_error(
mock_get_exam_configuration_dashboard_url,
):
sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Test Lesson 1",
user_id=self.user.id,
@@ -3765,7 +3765,7 @@ def test_special_exam_xblock_info_get_dashboard_error(
default_time_limit_minutes=100,
is_onboarding_exam=False,
)
- sequential = modulestore().get_item(sequential.location)
+ sequential = modulestore().get_item(sequential.usage_key)
mock_get_exam_configuration_dashboard_url.side_effect = Exception("proctoring error")
xblock_info = create_xblock_info(
sequential,
@@ -3794,19 +3794,19 @@ def setUp(self):
user_id = self.user.id
self.library = LibraryFactory.create()
self.top_level_html = BlockFactory.create(
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
category="html",
user_id=user_id,
publish_item=False,
)
self.vertical = BlockFactory.create(
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
category="vertical",
user_id=user_id,
publish_item=False,
)
self.child_html = BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category="html",
display_name="Test HTML Child Block",
user_id=user_id,
@@ -3814,13 +3814,13 @@ def setUp(self):
)
def test_lib_xblock_info(self):
- html_block = modulestore().get_item(self.top_level_html.location)
+ html_block = modulestore().get_item(self.top_level_html.usage_key)
xblock_info = create_xblock_info(html_block)
self.validate_component_xblock_info(xblock_info, html_block)
self.assertIsNone(xblock_info.get("child_info", None))
def test_lib_child_xblock_info(self):
- html_block = modulestore().get_item(self.child_html.location)
+ html_block = modulestore().get_item(self.child_html.usage_key)
xblock_info = create_xblock_info(
html_block, include_ancestor_info=True, include_child_info=True
)
@@ -3829,7 +3829,7 @@ def test_lib_child_xblock_info(self):
ancestors = xblock_info["ancestor_info"]["ancestors"]
self.assertEqual(len(ancestors), 2)
self.assertEqual(ancestors[0]["category"], "vertical")
- self.assertEqual(ancestors[0]["id"], str(self.vertical.location))
+ self.assertEqual(ancestors[0]["id"], str(self.vertical.usage_key))
self.assertEqual(ancestors[1]["category"], "library")
def validate_component_xblock_info(self, xblock_info, original_block):
@@ -3837,7 +3837,7 @@ def validate_component_xblock_info(self, xblock_info, original_block):
Validate that the xblock info is correct for the test component.
"""
self.assertEqual(xblock_info["category"], original_block.category)
- self.assertEqual(xblock_info["id"], str(original_block.location))
+ self.assertEqual(xblock_info["id"], str(original_block.usage_key))
self.assertEqual(xblock_info["display_name"], original_block.display_name)
self.assertIsNone(xblock_info.get("has_changes", None))
self.assertIsNone(xblock_info.get("published", None))
@@ -3856,9 +3856,9 @@ def test_add_xblock(self):
"""
lib = LibraryFactory.create()
self.create_xblock(
- parent_usage_key=lib.location, display_name="Test", category="html"
+ parent_usage_key=lib.usage_key, display_name="Test", category="html"
)
- lib = self.store.get_library(lib.location.library_key)
+ lib = self.store.get_library(lib.usage_key.library_key)
self.assertTrue(lib.children)
xblock_locator = lib.children[0]
self.assertEqual(self.store.get_item(xblock_locator).display_name, "Test")
@@ -3869,10 +3869,10 @@ def test_no_add_discussion(self):
"""
lib = LibraryFactory.create()
response = self.create_xblock(
- parent_usage_key=lib.location, display_name="Test", category="discussion"
+ parent_usage_key=lib.usage_key, display_name="Test", category="discussion"
)
self.assertEqual(response.status_code, 400)
- lib = self.store.get_library(lib.location.library_key)
+ lib = self.store.get_library(lib.usage_key.library_key)
self.assertFalse(lib.children)
def test_no_add_advanced(self):
@@ -3880,10 +3880,10 @@ def test_no_add_advanced(self):
lib.advanced_modules = ["lti"]
lib.save()
response = self.create_xblock(
- parent_usage_key=lib.location, display_name="Test", category="lti"
+ parent_usage_key=lib.usage_key, display_name="Test", category="lti"
)
self.assertEqual(response.status_code, 400)
- lib = self.store.get_library(lib.location.library_key)
+ lib = self.store.get_library(lib.usage_key.library_key)
self.assertFalse(lib.children)
@@ -3904,16 +3904,16 @@ def _create_child(
Creates a child xblock for the given parent.
"""
child = BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
category=category,
display_name=display_name,
user_id=self.user.id,
publish_item=publish_item,
)
if staff_only:
- self._enable_staff_only(child.location)
+ self._enable_staff_only(child.usage_key)
# In case the staff_only state was set, return the updated xblock.
- return modulestore().get_item(child.location)
+ return modulestore().get_item(child.usage_key)
def _get_child_xblock_info(self, xblock_info, index):
"""
@@ -4027,7 +4027,7 @@ def _verify_explicit_staff_lock_state(
def test_empty_chapter(self):
empty_chapter = self._create_child(self.course, "chapter", "Empty Chapter")
- xblock_info = self._get_xblock_info(empty_chapter.location)
+ xblock_info = self._get_xblock_info(empty_chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.unscheduled)
def test_chapter_self_paced_default_start_date(self):
@@ -4037,14 +4037,14 @@ def test_chapter_self_paced_default_start_date(self):
chapter = self._create_child(course, "chapter", "Test Chapter")
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Published Unit", publish_item=True)
- self._set_release_date(chapter.location, DEFAULT_START_DATE)
- xblock_info = self._get_xblock_info(chapter.location)
+ self._set_release_date(chapter.usage_key, DEFAULT_START_DATE)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.live)
def test_empty_sequential(self):
chapter = self._create_child(self.course, "chapter", "Test Chapter")
self._create_child(chapter, "sequential", "Empty Sequential")
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.unscheduled)
self._verify_visibility_state(
xblock_info, VisibilityState.unscheduled, path=self.FIRST_SUBSECTION_PATH
@@ -4058,8 +4058,8 @@ def test_published_unit(self):
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Published Unit", publish_item=True)
self._create_child(sequential, "vertical", "Staff Only Unit", staff_only=True)
- self._set_release_date(chapter.location, datetime.now(UTC) + timedelta(days=1))
- xblock_info = self._get_xblock_info(chapter.location)
+ self._set_release_date(chapter.usage_key, datetime.now(UTC) + timedelta(days=1))
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.ready)
self._verify_visibility_state(
xblock_info, VisibilityState.ready, path=self.FIRST_SUBSECTION_PATH
@@ -4079,8 +4079,8 @@ def test_released_unit(self):
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Published Unit", publish_item=True)
self._create_child(sequential, "vertical", "Staff Only Unit", staff_only=True)
- self._set_release_date(chapter.location, datetime.now(UTC) - timedelta(days=1))
- xblock_info = self._get_xblock_info(chapter.location)
+ self._set_release_date(chapter.usage_key, datetime.now(UTC) - timedelta(days=1))
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.live)
self._verify_visibility_state(
xblock_info, VisibilityState.live, path=self.FIRST_SUBSECTION_PATH
@@ -4103,8 +4103,8 @@ def test_unpublished_changes(self):
)
self._create_child(sequential, "vertical", "Staff Only Unit", staff_only=True)
# Setting the display name creates a draft version of unit.
- self._set_display_name(unit.location, "Updated Unit")
- xblock_info = self._get_xblock_info(chapter.location)
+ self._set_display_name(unit.usage_key, "Updated Unit")
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.needs_attention)
self._verify_visibility_state(
xblock_info,
@@ -4123,12 +4123,12 @@ def test_partially_released_section(self):
released_sequential = self._create_child(chapter, 'sequential', "Released Sequential")
self._create_child(released_sequential, 'vertical', "Released Unit", publish_item=True)
self._create_child(released_sequential, 'vertical', "Staff Only Unit 1", staff_only=True)
- self._set_release_date(chapter.location, datetime.now(UTC) - timedelta(days=1))
+ self._set_release_date(chapter.usage_key, datetime.now(UTC) - timedelta(days=1))
published_sequential = self._create_child(chapter, 'sequential', "Published Sequential")
self._create_child(published_sequential, 'vertical', "Published Unit", publish_item=True)
self._create_child(published_sequential, 'vertical', "Staff Only Unit 2", staff_only=True)
- self._set_release_date(published_sequential.location, datetime.now(UTC) + timedelta(days=1))
- xblock_info = self._get_xblock_info(chapter.location)
+ self._set_release_date(published_sequential.usage_key, datetime.now(UTC) + timedelta(days=1))
+ xblock_info = self._get_xblock_info(chapter.usage_key)
# Verify the state of the released sequential
self._verify_visibility_state(xblock_info, VisibilityState.live, path=[0])
@@ -4156,7 +4156,7 @@ def test_staff_only_section(self):
)
sequential = self._create_child(chapter, "sequential", "Test Sequential")
vertical = self._create_child(sequential, "vertical", "Unit")
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.staff_only)
self._verify_visibility_state(
xblock_info, VisibilityState.staff_only, path=self.FIRST_SUBSECTION_PATH
@@ -4173,7 +4173,7 @@ def test_staff_only_section(self):
xblock_info, False, path=self.FIRST_UNIT_PATH
)
- vertical_info = self._get_xblock_info(vertical.location)
+ vertical_info = self._get_xblock_info(vertical.usage_key)
add_container_page_publishing_info(vertical, vertical_info)
self.assertEqual(
_xblock_type_and_display_name(chapter), vertical_info["staff_lock_from"]
@@ -4188,7 +4188,7 @@ def test_no_staff_only_section(self):
self._create_child(
chapter, "sequential", "Test Staff Locked Sequential", staff_only=True
)
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(
xblock_info, VisibilityState.staff_only, should_equal=False
)
@@ -4207,7 +4207,7 @@ def test_staff_only_subsection(self):
chapter, "sequential", "Test Sequential", staff_only=True
)
vertical = self._create_child(sequential, "vertical", "Unit")
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.staff_only)
self._verify_visibility_state(
xblock_info, VisibilityState.staff_only, path=self.FIRST_SUBSECTION_PATH
@@ -4224,7 +4224,7 @@ def test_staff_only_subsection(self):
xblock_info, False, path=self.FIRST_UNIT_PATH
)
- vertical_info = self._get_xblock_info(vertical.location)
+ vertical_info = self._get_xblock_info(vertical.usage_key)
add_container_page_publishing_info(vertical, vertical_info)
self.assertEqual(
_xblock_type_and_display_name(sequential), vertical_info["staff_lock_from"]
@@ -4238,7 +4238,7 @@ def test_no_staff_only_subsection(self):
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Unit")
self._create_child(sequential, "vertical", "Locked Unit", staff_only=True)
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(
xblock_info,
VisibilityState.staff_only,
@@ -4259,7 +4259,7 @@ def test_staff_only_unit(self):
chapter = self._create_child(self.course, "chapter", "Test Chapter")
sequential = self._create_child(chapter, "sequential", "Test Sequential")
vertical = self._create_child(sequential, "vertical", "Unit", staff_only=True)
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.staff_only)
self._verify_visibility_state(
xblock_info, VisibilityState.staff_only, path=self.FIRST_SUBSECTION_PATH
@@ -4276,7 +4276,7 @@ def test_staff_only_unit(self):
xblock_info, True, path=self.FIRST_UNIT_PATH
)
- vertical_info = self._get_xblock_info(vertical.location)
+ vertical_info = self._get_xblock_info(vertical.usage_key)
add_container_page_publishing_info(vertical, vertical_info)
self.assertEqual(
_xblock_type_and_display_name(vertical), vertical_info["staff_lock_from"]
@@ -4288,9 +4288,9 @@ def test_unscheduled_section_with_live_subsection(self):
self._create_child(sequential, "vertical", "Published Unit", publish_item=True)
self._create_child(sequential, "vertical", "Staff Only Unit", staff_only=True)
self._set_release_date(
- sequential.location, datetime.now(UTC) - timedelta(days=1)
+ sequential.usage_key, datetime.now(UTC) - timedelta(days=1)
)
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.needs_attention)
self._verify_visibility_state(
xblock_info, VisibilityState.live, path=self.FIRST_SUBSECTION_PATH
@@ -4307,11 +4307,11 @@ def test_unreleased_section_with_live_subsection(self):
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Published Unit", publish_item=True)
self._create_child(sequential, "vertical", "Staff Only Unit", staff_only=True)
- self._set_release_date(chapter.location, datetime.now(UTC) + timedelta(days=1))
+ self._set_release_date(chapter.usage_key, datetime.now(UTC) + timedelta(days=1))
self._set_release_date(
- sequential.location, datetime.now(UTC) - timedelta(days=1)
+ sequential.usage_key, datetime.now(UTC) - timedelta(days=1)
)
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.needs_attention)
self._verify_visibility_state(
xblock_info, VisibilityState.live, path=self.FIRST_SUBSECTION_PATH
@@ -4332,7 +4332,7 @@ def test_locked_section_staff_only_message(self):
)
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Unit")
- xblock_info = self._get_xblock_outline_info(chapter.location)
+ xblock_info = self._get_xblock_outline_info(chapter.usage_key)
self._verify_has_staff_only_message(xblock_info, True)
self._verify_has_staff_only_message(
xblock_info, False, path=self.FIRST_SUBSECTION_PATH
@@ -4348,7 +4348,7 @@ def test_locked_unit_staff_only_message(self):
chapter = self._create_child(self.course, "chapter", "Test Chapter")
sequential = self._create_child(chapter, "sequential", "Test Sequential")
self._create_child(sequential, "vertical", "Unit", staff_only=True)
- xblock_info = self._get_xblock_outline_info(chapter.location)
+ xblock_info = self._get_xblock_outline_info(chapter.usage_key)
self._verify_has_staff_only_message(xblock_info, True)
self._verify_has_staff_only_message(
xblock_info, True, path=self.FIRST_SUBSECTION_PATH
@@ -4367,10 +4367,10 @@ def test_self_paced_item_visibility_state(self):
# Create course, chapter and setup future release date to make chapter in scheduled state
course = CourseFactory.create()
chapter = self._create_child(course, "chapter", "Test Chapter")
- self._set_release_date(chapter.location, datetime.now(UTC) + timedelta(days=1))
+ self._set_release_date(chapter.usage_key, datetime.now(UTC) + timedelta(days=1))
# Check that chapter has scheduled state
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.ready)
self.assertFalse(course.self_paced)
@@ -4380,7 +4380,7 @@ def test_self_paced_item_visibility_state(self):
self.assertTrue(course.self_paced)
# Check that in self paced course content has live state now
- xblock_info = self._get_xblock_info(chapter.location)
+ xblock_info = self._get_xblock_info(chapter.usage_key)
self._verify_visibility_state(xblock_info, VisibilityState.live)
@@ -4429,7 +4429,7 @@ def create_source_block(self, course):
self.store.update_item(source_block, self.user.id, asides=[aside])
# quick sanity checks
- source_block = self.store.get_item(source_block.location)
+ source_block = self.store.get_item(source_block.usage_key)
self.assertEqual(source_block.due, datetime(2010, 11, 22, 4, 0, tzinfo=UTC))
self.assertEqual(source_block.display_name, "Source Block")
self.assertEqual(
@@ -4473,7 +4473,7 @@ def test_update_from_source(self):
destination_block=destination_block,
user_id=user.id,
)
- self.check_updated(source_block, destination_block.location)
+ self.check_updated(source_block, destination_block.usage_key)
@XBlockAside.register_temp_plugin(AsideTest, "test_aside")
def test_update_clobbers(self):
@@ -4507,7 +4507,7 @@ def test_update_clobbers(self):
destination_block=destination_block,
user_id=user.id,
)
- self.check_updated(source_block, destination_block.location)
+ self.check_updated(source_block, destination_block.usage_key)
class TestXblockEditView(CourseTestCase):
@@ -4530,7 +4530,7 @@ def setUp(self):
self.video = self._create_block(self.child_vertical, "video", "My Video")
self.store = modulestore()
- self.store.publish(self.vertical.location, self.user.id)
+ self.store.publish(self.vertical.usage_key, self.user.id)
def _create_block(self, parent, category, display_name, **kwargs):
"""
@@ -4546,7 +4546,7 @@ def _create_block(self, parent, category, display_name, **kwargs):
)
def test_xblock_edit_view(self):
- url = reverse_usage_url("xblock_edit_handler", self.video.location)
+ url = reverse_usage_url("xblock_edit_handler", self.video.usage_key)
resp = self.client.get_html(url)
self.assertEqual(resp.status_code, 200)
@@ -4554,7 +4554,7 @@ def test_xblock_edit_view(self):
self.assertIn("var decodedActionName = 'edit';", html_content)
def test_xblock_edit_view_contains_resources(self):
- url = reverse_usage_url("xblock_edit_handler", self.video.location)
+ url = reverse_usage_url("xblock_edit_handler", self.video.usage_key)
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
diff --git a/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py b/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py
index ba6d0b243165..9d4f23421b8a 100644
--- a/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py
+++ b/cms/djangoapps/contentstore/views/tests/test_clipboard_paste.py
@@ -93,14 +93,14 @@ def test_copy_and_paste_unit(self):
# Paste the unit
paste_response = client.post(XBLOCK_ENDPOINT, {
- "parent_locator": str(dest_sequential.location),
+ "parent_locator": str(dest_sequential.usage_key),
"staged_content": "clipboard",
}, format="json")
assert paste_response.status_code == 200
dest_unit_key = UsageKey.from_string(paste_response.json()["locator"])
# Now there should be a one unit/vertical as a child of the destination sequential/subsection:
- updated_sequential = self.store.get_item(dest_sequential.location)
+ updated_sequential = self.store.get_item(dest_sequential.usage_key)
assert updated_sequential.children == [dest_unit_key]
# And it should match the original:
orig_unit = self.store.get_item(unit_key)
@@ -124,7 +124,7 @@ def test_copy_and_paste_component(self, block_args):
Test copying a component (XBlock) from one course into another
"""
source_course = CourseFactory.create(display_name='Source Course')
- source_block = BlockFactory.create(parent_location=source_course.location, **block_args)
+ source_block = BlockFactory.create(parent_location=source_course.usage_key, **block_args)
dest_course = CourseFactory.create(display_name='Destination Course')
with self.store.bulk_operations(dest_course.id):
@@ -134,12 +134,12 @@ def test_copy_and_paste_component(self, block_args):
# Copy the block
client = APIClient()
client.login(username=self.user.username, password=self.user_password)
- copy_response = client.post(CLIPBOARD_ENDPOINT, {"usage_key": str(source_block.location)}, format="json")
+ copy_response = client.post(CLIPBOARD_ENDPOINT, {"usage_key": str(source_block.usage_key)}, format="json")
assert copy_response.status_code == 200
# Paste the unit
paste_response = client.post(XBLOCK_ENDPOINT, {
- "parent_locator": str(dest_sequential.location),
+ "parent_locator": str(dest_sequential.usage_key),
"staged_content": "clipboard",
}, format="json")
assert paste_response.status_code == 200
@@ -148,7 +148,7 @@ def test_copy_and_paste_component(self, block_args):
dest_block = self.store.get_item(dest_block_key)
assert dest_block.display_name == source_block.display_name
# The new block should store a reference to where it was copied from
- assert dest_block.copied_from_block == str(source_block.location)
+ assert dest_block.copied_from_block == str(source_block.usage_key)
def _setup_tagged_content(self, course_key) -> dict:
"""
@@ -163,14 +163,14 @@ def _setup_tagged_content(self, course_key) -> dict:
category='discussion',
display_name='Toy_forum',
publish_item=True,
- ).location
+ ).usage_key
with self.store.bulk_operations(course_key):
html_block_key = BlockFactory.create(
parent=self.store.get_item(unit_key),
category="html",
display_name="Toy_text",
publish_item=True,
- ).location
+ ).usage_key
library = ClipboardPasteFromV1LibraryTestCase.setup_library()
with self.store.bulk_operations(course_key):
@@ -180,7 +180,7 @@ def _setup_tagged_content(self, course_key) -> dict:
source_library_id=str(library.context_key),
display_name="LC Block",
publish_item=True,
- ).location
+ ).usage_key
# Add tags to the unit
taxonomy_all_org = tagging_api.create_taxonomy(
@@ -290,7 +290,7 @@ def test_copy_and_paste_unit_with_tags(self):
# Paste the unit
paste_response = client.post(XBLOCK_ENDPOINT, {
- "parent_locator": str(dest_sequential.location),
+ "parent_locator": str(dest_sequential.usage_key),
"staged_content": "clipboard",
}, format="json")
assert paste_response.status_code == 200
@@ -351,7 +351,7 @@ def test_paste_with_assets(self):
target_filename="picture2.jpg",
)
source_html = BlockFactory.create(
- parent_location=source_course.location,
+ parent_location=source_course.usage_key,
category="html",
display_name="Some HTML",
data="""
@@ -373,7 +373,7 @@ def test_paste_with_assets(self):
)
# Now copy the HTML block from the source cost and paste it into the destination:
- copy_response = client.post(CLIPBOARD_ENDPOINT, {"usage_key": str(source_html.location)}, format="json")
+ copy_response = client.post(CLIPBOARD_ENDPOINT, {"usage_key": str(source_html.usage_key)}, format="json")
assert copy_response.status_code == 200
# Paste the video
@@ -646,13 +646,13 @@ def test_paste_library_content_block(self):
"""
# Copy a library content block that has children:
copy_response = self.client.post(CLIPBOARD_ENDPOINT, {
- "usage_key": str(self.orig_lc_block.location)
+ "usage_key": str(self.orig_lc_block.usage_key)
}, format="json")
assert copy_response.status_code == 200
# Paste the Library content block:
paste_response = self.client.post(XBLOCK_ENDPOINT, {
- "parent_locator": str(self.course.location),
+ "parent_locator": str(self.course.usage_key),
"staged_content": "clipboard",
}, format="json")
assert paste_response.status_code == 200
@@ -667,14 +667,14 @@ def test_paste_library_content_block(self):
# Otherwise, user state saved against this child will be lost when it syncs.
self._sync_lc_block_from_library('dest_lc_block')
updated_dest_child = self.store.get_item(self.dest_lc_block.children[0])
- assert dest_child.location == updated_dest_child.location
+ assert dest_child.usage_key == updated_dest_child.usage_key
def _sync_lc_block_from_library(self, attr_name):
"""
Helper method to "sync" a Library Content Block by [re-]fetching its
children from the library.
"""
- usage_key = getattr(self, attr_name).location
+ usage_key = getattr(self, attr_name).usage_key
# It's easiest to do this via the REST API:
handler_url = reverse_usage_url('preview_handler', usage_key, kwargs={'handler': 'upgrade_and_sync'})
response = self.client.post(handler_url)
diff --git a/cms/djangoapps/contentstore/views/tests/test_container_page.py b/cms/djangoapps/contentstore/views/tests/test_container_page.py
index e6b58257b69d..9ba1264aa48c 100644
--- a/cms/djangoapps/contentstore/views/tests/test_container_page.py
+++ b/cms/djangoapps/contentstore/views/tests/test_container_page.py
@@ -55,20 +55,20 @@ def setUp(self):
self.unreleased_public_vertical = self._create_block(
parent=self.sequential, category='vertical', display_name='Unreleased Public Unit',
start=future)
- self.store.publish(self.unreleased_public_vertical.location, self.user.id)
- self.store.publish(self.released_public_vertical.location, self.user.id)
- self.store.publish(self.vertical.location, self.user.id)
+ self.store.publish(self.unreleased_public_vertical.usage_key, self.user.id)
+ self.store.publish(self.released_public_vertical.usage_key, self.user.id)
+ self.store.publish(self.vertical.usage_key, self.user.id)
def test_container_html(self):
assets_url = reverse(
- 'assets_handler', kwargs={'course_key_string': str(self.child_container.location.course_key)}
+ 'assets_handler', kwargs={'course_key_string': str(self.child_container.usage_key.course_key)}
)
self._test_html_content(
self.child_container,
expected_section_tag=(
''.format(
- self.child_container.location, assets_url
+ self.child_container.usage_key, assets_url
)
),
expected_breadcrumbs=(
@@ -77,10 +77,10 @@ def test_container_html(self):
).format(
course=re.escape(str(self.course.id)),
section_parameters=re.escape('?show={}'.format(quote(
- str(self.chapter.location).encode()
+ str(self.chapter.usage_key).encode()
))),
subsection_parameters=re.escape('?show={}'.format(quote(
- str(self.sequential.location).encode()
+ str(self.sequential.usage_key).encode()
))),
),
)
@@ -96,14 +96,14 @@ def test_container_on_container_html(self):
def test_container_html(xblock):
assets_url = reverse(
- 'assets_handler', kwargs={'course_key_string': str(draft_container.location.course_key)}
+ 'assets_handler', kwargs={'course_key_string': str(draft_container.usage_key.course_key)}
)
self._test_html_content(
xblock,
expected_section_tag=(
''.format(
- draft_container.location, assets_url
+ draft_container.usage_key, assets_url
)
),
expected_breadcrumbs=(
@@ -111,9 +111,9 @@ def test_container_html(xblock):
'Unit.*'
).format(
course=re.escape(str(self.course.id)),
- unit_parameters=re.escape(str(self.vertical.location)),
+ unit_parameters=re.escape(str(self.vertical.usage_key)),
subsection_parameters=re.escape('?show={}'.format(quote(
- str(self.sequential.location).encode()
+ str(self.sequential.usage_key).encode()
))),
),
)
@@ -122,8 +122,8 @@ def test_container_html(xblock):
test_container_html(draft_container)
# Now publish the unit and validate again
- self.store.publish(self.vertical.location, self.user.id)
- draft_container = self.store.get_item(draft_container.location)
+ self.store.publish(self.vertical.usage_key, self.user.id)
+ draft_container = self.store.get_item(draft_container.usage_key)
test_container_html(draft_container)
def _test_html_content(self, xblock, expected_section_tag, expected_breadcrumbs):
@@ -139,9 +139,9 @@ def test_public_container_preview_html(self):
"""
Verify that a public xblock's container preview returns the expected HTML.
"""
- published_unit = self.store.publish(self.vertical.location, self.user.id)
- published_child_container = self.store.get_item(self.child_container.location)
- published_child_vertical = self.store.get_item(self.child_vertical.location)
+ published_unit = self.store.publish(self.vertical.usage_key, self.user.id)
+ published_child_container = self.store.get_item(self.child_container.usage_key)
+ published_child_vertical = self.store.get_item(self.child_vertical.usage_key)
self.validate_preview_html(published_unit, self.container_view)
self.validate_preview_html(published_child_container, self.container_view)
self.validate_preview_html(published_child_vertical, self.reorderable_child_view)
@@ -210,7 +210,7 @@ def test_public_child_container_preview_html(self):
Verify that a public container rendered as a child of the container page returns the expected HTML.
"""
empty_child_container = self._create_block(self.vertical, 'split_test', 'Split Test 1')
- published_empty_child_container = self.store.publish(empty_child_container.location, self.user.id)
+ published_empty_child_container = self.store.publish(empty_child_container.usage_key, self.user.id)
self.validate_preview_html(published_empty_child_container, self.reorderable_child_view, can_add=False)
def test_draft_child_container_preview_html(self):
@@ -243,7 +243,7 @@ def test_container_page_with_valid_and_invalid_usage_key_string(self):
# Check 200 response if 'usage_key_string' is correct
response = views.container_handler(
request=request,
- usage_key_string=str(self.vertical.location)
+ usage_key_string=str(self.vertical.usage_key)
)
self.assertEqual(response.status_code, 200)
@@ -255,14 +255,14 @@ class ContainerEmbedPageTestCase(ContainerPageTestCase): # lint-amnesty, pylint
def test_container_html(self):
assets_url = reverse(
- 'assets_handler', kwargs={'course_key_string': str(self.child_container.location.course_key)}
+ 'assets_handler', kwargs={'course_key_string': str(self.child_container.usage_key.course_key)}
)
self._test_html_content(
self.child_container,
expected_section_tag=(
''.format(
- self.child_container.location, assets_url
+ self.child_container.usage_key, assets_url
)
),
)
@@ -278,14 +278,14 @@ def test_container_on_container_html(self):
def test_container_html(xblock):
assets_url = reverse(
- 'assets_handler', kwargs={'course_key_string': str(draft_container.location.course_key)}
+ 'assets_handler', kwargs={'course_key_string': str(draft_container.usage_key.course_key)}
)
self._test_html_content(
xblock,
expected_section_tag=(
''.format(
- draft_container.location, assets_url
+ draft_container.usage_key, assets_url
)
),
)
@@ -294,8 +294,8 @@ def test_container_html(xblock):
test_container_html(draft_container)
# Now publish the unit and validate again
- self.store.publish(self.vertical.location, self.user.id)
- draft_container = self.store.get_item(draft_container.location)
+ self.store.publish(self.vertical.usage_key, self.user.id)
+ draft_container = self.store.get_item(draft_container.usage_key)
test_container_html(draft_container)
def _test_html_content(self, xblock, expected_section_tag): # lint-amnesty, pylint: disable=arguments-differ
diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py
index 58c425c601a3..6e2e15d4edcc 100644
--- a/cms/djangoapps/contentstore/views/tests/test_course_index.py
+++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py
@@ -47,16 +47,16 @@ def setUp(self):
super().setUp()
self.chapter = BlockFactory.create(
- parent_location=self.course.location, category='chapter', display_name="Week 1"
+ parent_location=self.course.usage_key, category='chapter', display_name="Week 1"
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location, category='sequential', display_name="Lesson 1"
+ parent_location=self.chapter.usage_key, category='sequential', display_name="Lesson 1"
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location, category='vertical', display_name='Subsection 1'
+ parent_location=self.sequential.usage_key, category='vertical', display_name='Subsection 1'
)
self.video = BlockFactory.create(
- parent_location=self.vertical.location, category="video", display_name="My Video"
+ parent_location=self.vertical.usage_key, category="video", display_name="My Video"
)
@ddt.data(True, False)
@@ -78,7 +78,7 @@ def test_json_responses(self, is_concise):
# First spot check some values in the root response
self.assertEqual(json_response['category'], 'course')
- self.assertEqual(json_response['id'], str(self.course.location))
+ self.assertEqual(json_response['id'], str(self.course.usage_key))
self.assertEqual(json_response['display_name'], self.course.display_name)
self.assertNotEqual(json_response.get('published', False), is_concise)
self.assertIsNone(json_response.get('visibility_state'))
@@ -88,7 +88,7 @@ def test_json_responses(self, is_concise):
self.assertGreater(len(children), 0)
first_child_response = children[0]
self.assertEqual(first_child_response['category'], 'chapter')
- self.assertEqual(first_child_response['id'], str(self.chapter.location))
+ self.assertEqual(first_child_response['id'], str(self.chapter.usage_key))
self.assertEqual(first_child_response['display_name'], 'Week 1')
self.assertNotEqual(json_response.get('published', False), is_concise)
if not is_concise:
@@ -111,7 +111,7 @@ def assert_correct_json_response(self, json_response, is_concise=False):
self.assert_correct_json_response(child_response, is_concise)
def test_course_outline_initial_state(self):
- course_block = modulestore().get_item(self.course.location)
+ course_block = modulestore().get_item(self.course.usage_key)
course_structure = create_xblock_info(
course_block,
include_child_info=True,
@@ -122,12 +122,12 @@ def test_course_outline_initial_state(self):
self.assertIsNone(course_outline_initial_state('no-such-locator', course_structure))
# Verify that the correct initial state is returned for the test chapter
- chapter_locator = str(self.chapter.location)
+ chapter_locator = str(self.chapter.usage_key)
initial_state = course_outline_initial_state(chapter_locator, course_structure)
self.assertEqual(initial_state['locator_to_show'], chapter_locator)
expanded_locators = initial_state['expanded_locators']
- self.assertIn(str(self.sequential.location), expanded_locators)
- self.assertIn(str(self.vertical.location), expanded_locators)
+ self.assertIn(str(self.sequential.usage_key), expanded_locators)
+ self.assertIn(str(self.vertical.usage_key), expanded_locators)
def _create_test_data(self, course_block, create_blocks=False, publish=True, block_types=None):
"""
@@ -142,10 +142,10 @@ def _create_test_data(self, course_block, create_blocks=False, publish=True, blo
)
if not publish:
- self.store.unpublish(self.vertical.location, self.user.id)
+ self.store.unpublish(self.vertical.usage_key, self.user.id)
# get updated vertical
- self.vertical = modulestore().get_item(self.vertical.location)
+ self.vertical = modulestore().get_item(self.vertical.usage_key)
course_block.advanced_modules.extend(block_types)
def _verify_deprecated_info(self, course_id, advanced_modules, info, deprecated_block_types):
@@ -156,7 +156,7 @@ def _verify_deprecated_info(self, course_id, advanced_modules, info, deprecated_
for block_type in deprecated_block_types:
expected_blocks.append(
[
- reverse_usage_url('container_handler', self.vertical.location),
+ reverse_usage_url('container_handler', self.vertical.usage_key),
f'{block_type} Problem'
]
)
@@ -183,10 +183,10 @@ def test_verify_deprecated_warning_message(self, publish, block_types):
"""
Verify deprecated warning info.
"""
- course_block = modulestore().get_item(self.course.location)
+ course_block = modulestore().get_item(self.course.usage_key)
self._create_test_data(course_block, create_blocks=True, block_types=block_types, publish=publish)
# get updated course_block
- course_block = modulestore().get_item(self.course.location)
+ course_block = modulestore().get_item(self.course.usage_key)
info = _deprecated_blocks_info(course_block, block_types)
self._verify_deprecated_info(
@@ -209,10 +209,10 @@ def test_verify_warn_only_on_enabled_blocks(self, enabled_block_types, deprecate
Verify that we only warn about block_types that are both deprecated and enabled.
"""
expected_block_types = list(set(enabled_block_types) & set(deprecated_block_types))
- course_block = modulestore().get_item(self.course.location)
+ course_block = modulestore().get_item(self.course.usage_key)
self._create_test_data(course_block, create_blocks=True, block_types=enabled_block_types)
# get updated course_module
- course_block = modulestore().get_item(self.course.location)
+ course_block = modulestore().get_item(self.course.usage_key)
info = _deprecated_blocks_info(course_block, deprecated_block_types)
self._verify_deprecated_info(
course_block.id,
@@ -254,20 +254,20 @@ def setUp(self):
modulestore().update_item(self.course, self.user.id)
self.chapter = BlockFactory.create(
- parent_location=self.course.location, category='chapter', display_name="Week 1"
+ parent_location=self.course.usage_key, category='chapter', display_name="Week 1"
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location, category='sequential', display_name="Lesson 1"
+ parent_location=self.chapter.usage_key, category='sequential', display_name="Lesson 1"
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location, category='vertical', display_name='Subsection 1'
+ parent_location=self.sequential.usage_key, category='vertical', display_name='Subsection 1'
)
self.video = BlockFactory.create(
- parent_location=self.vertical.location, category="video", display_name="My Video"
+ parent_location=self.vertical.usage_key, category="video", display_name="My Video"
)
self.html = BlockFactory.create(
- parent_location=self.vertical.location, category="html", display_name="My HTML",
+ parent_location=self.vertical.usage_key, category="html", display_name="My HTML",
data="This is my unique HTML content
",
)
diff --git a/cms/djangoapps/contentstore/views/tests/test_discussion_enabled.py b/cms/djangoapps/contentstore/views/tests/test_discussion_enabled.py
index d19f18f2e264..a1d678e1e95c 100644
--- a/cms/djangoapps/contentstore/views/tests/test_discussion_enabled.py
+++ b/cms/djangoapps/contentstore/views/tests/test_discussion_enabled.py
@@ -33,25 +33,25 @@ def get_test_course(self):
modulestore=self.store
)
self.chapter = BlockFactory(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="What is SHIELD?",
modulestore=self.store
)
self.sequential = BlockFactory(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="HQ",
modulestore=self.store
)
self.vertical = BlockFactory(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name="Triskelion",
modulestore=self.store
)
self.vertical_1 = BlockFactory(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name="Helicarrier",
modulestore=self.store
@@ -72,7 +72,7 @@ def get_discussion_enabled_status(self, xblock, client=None):
"""
Issue a GET request to fetch value of discussion_enabled flag of param:xblock's
"""
- resp = self._get_discussion_enabled_status(xblock.location, client=client)
+ resp = self._get_discussion_enabled_status(xblock.usage_key, client=client)
content = json.loads(resp.content.decode("utf-8"))
return content.get("discussion_enabled", None)
@@ -81,7 +81,7 @@ def set_discussion_enabled_status(self, xblock, value, client=None):
Issue a POST request to update value of discussion_enabled flag of param:xblock's
"""
client = client if client is not None else self.client
- xblock_location = xblock.location
+ xblock_location = xblock.usage_key
url = reverse_usage_url("xblock_handler", xblock_location)
resp = client.post(
url,
diff --git a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py
index dea52cbe7b6f..7583cac32040 100644
--- a/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py
+++ b/cms/djangoapps/contentstore/views/tests/test_entrance_exam.py
@@ -42,7 +42,7 @@ def setUp(self):
"""
super().setUp()
self.course_key = self.course.id
- self.usage_key = self.course.location
+ self.usage_key = self.course.usage_key
self.course_url = f'/course/{str(self.course.id)}'
self.exam_url = f'/course/{str(self.course.id)}/entrance_exam/'
self.milestone_relationship_types = milestones_helpers.get_milestone_relationship_types()
@@ -51,7 +51,7 @@ def test_entrance_exam_milestone_addition(self):
"""
Unit Test: test addition of entrance exam milestone content
"""
- parent_locator = str(self.course.location)
+ parent_locator = str(self.course.usage_key)
created_block = create_xblock(
parent_locator=parent_locator,
user=self.user,
@@ -62,7 +62,7 @@ def test_entrance_exam_milestone_addition(self):
add_entrance_exam_milestone(self.course.id, created_block)
content_milestones = milestones_helpers.get_course_content_milestones(
str(self.course.id),
- str(created_block.location),
+ str(created_block.usage_key),
self.milestone_relationship_types['FULFILLS']
)
self.assertTrue(len(content_milestones))
@@ -72,7 +72,7 @@ def test_entrance_exam_milestone_removal(self):
"""
Unit Test: test removal of entrance exam milestone content
"""
- parent_locator = str(self.course.location)
+ parent_locator = str(self.course.usage_key)
created_block = create_xblock(
parent_locator=parent_locator,
user=self.user,
@@ -83,7 +83,7 @@ def test_entrance_exam_milestone_removal(self):
add_entrance_exam_milestone(self.course.id, created_block)
content_milestones = milestones_helpers.get_course_content_milestones(
str(self.course.id),
- str(created_block.location),
+ str(created_block.usage_key),
self.milestone_relationship_types['FULFILLS']
)
self.assertEqual(len(content_milestones), 1)
@@ -93,7 +93,7 @@ def test_entrance_exam_milestone_removal(self):
remove_entrance_exam_milestone_reference(request, self.course.id)
content_milestones = milestones_helpers.get_course_content_milestones(
str(self.course.id),
- str(created_block.location),
+ str(created_block.usage_key),
self.milestone_relationship_types['FULFILLS']
)
self.assertEqual(len(content_milestones), 0)
diff --git a/cms/djangoapps/contentstore/views/tests/test_gating.py b/cms/djangoapps/contentstore/views/tests/test_gating.py
index 73febb91e6b9..a489c093827b 100644
--- a/cms/djangoapps/contentstore/views/tests/test_gating.py
+++ b/cms/djangoapps/contentstore/views/tests/test_gating.py
@@ -37,25 +37,25 @@ def setUp(self):
# create a chapter
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name='untitled chapter'
)
# create 2 sequentials
self.seq1 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name='untitled sequential 1'
)
- self.seq1_url = reverse_usage_url('xblock_handler', self.seq1.location)
+ self.seq1_url = reverse_usage_url('xblock_handler', self.seq1.usage_key)
self.seq2 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name='untitled sequential 2'
)
- self.seq2_url = reverse_usage_url('xblock_handler', self.seq2.location)
+ self.seq2_url = reverse_usage_url('xblock_handler', self.seq2.usage_key)
@patch('cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers.gating_api.add_prerequisite')
def test_add_prerequisite(self, mock_add_prereq):
@@ -67,7 +67,7 @@ def test_add_prerequisite(self, mock_add_prereq):
self.seq1_url,
data={'isPrereq': True}
)
- mock_add_prereq.assert_called_with(self.course.id, self.seq1.location)
+ mock_add_prereq.assert_called_with(self.course.id, self.seq1.usage_key)
@patch('cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers.gating_api.remove_prerequisite')
def test_remove_prerequisite(self, mock_remove_prereq):
@@ -79,7 +79,7 @@ def test_remove_prerequisite(self, mock_remove_prereq):
self.seq1_url,
data={'isPrereq': False}
)
- mock_remove_prereq.assert_called_with(self.seq1.location)
+ mock_remove_prereq.assert_called_with(self.seq1.usage_key)
@patch('cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers.gating_api.set_required_content')
def test_add_gate(self, mock_set_required_content):
@@ -89,13 +89,13 @@ def test_add_gate(self, mock_set_required_content):
self.client.ajax_post(
self.seq2_url,
- data={'prereqUsageKey': str(self.seq1.location), 'prereqMinScore': '100',
+ data={'prereqUsageKey': str(self.seq1.usage_key), 'prereqMinScore': '100',
'prereqMinCompletion': '100'}
)
mock_set_required_content.assert_called_with(
self.course.id,
- self.seq2.location,
- str(self.seq1.location),
+ self.seq2.usage_key,
+ str(self.seq1.usage_key),
'100',
'100'
)
@@ -112,7 +112,7 @@ def test_remove_gate(self, mock_set_required_content):
)
mock_set_required_content.assert_called_with(
self.course.id,
- self.seq2.location,
+ self.seq2.usage_key,
'',
'',
''
@@ -132,17 +132,17 @@ def test_get_prerequisite(
mock_is_prereq, mock_get_required_content, mock_get_prereqs
):
mock_is_prereq.return_value = True
- mock_get_required_content.return_value = str(self.seq1.location), min_score, min_completion
+ mock_get_required_content.return_value = str(self.seq1.usage_key), min_score, min_completion
mock_get_prereqs.return_value = [
- {'namespace': f'{str(self.seq1.location)}{GATING_NAMESPACE_QUALIFIER}'},
- {'namespace': f'{str(self.seq2.location)}{GATING_NAMESPACE_QUALIFIER}'}
+ {'namespace': f'{str(self.seq1.usage_key)}{GATING_NAMESPACE_QUALIFIER}'},
+ {'namespace': f'{str(self.seq2.usage_key)}{GATING_NAMESPACE_QUALIFIER}'}
]
resp = json.loads(self.client.get_json(self.seq2_url).content.decode('utf-8'))
- mock_is_prereq.assert_called_with(self.course.id, self.seq2.location)
- mock_get_required_content.assert_called_with(self.course.id, self.seq2.location)
+ mock_is_prereq.assert_called_with(self.course.id, self.seq2.usage_key)
+ mock_get_required_content.assert_called_with(self.course.id, self.seq2.usage_key)
mock_get_prereqs.assert_called_with(self.course.id)
self.assertTrue(resp['is_prereq'])
- self.assertEqual(resp['prereq'], str(self.seq1.location))
+ self.assertEqual(resp['prereq'], str(self.seq1.usage_key))
self.assertEqual(resp['prereq_min_score'], min_score)
self.assertEqual(resp['prereq_min_completion'], min_completion)
self.assertEqual(resp['visibility_state'], VisibilityState.gated)
@@ -151,10 +151,10 @@ def test_get_prerequisite(
@patch('cms.djangoapps.contentstore.signals.handlers.gating_api.remove_prerequisite')
def test_delete_item_signal_handler_called(self, mock_remove_prereq, mock_set_required):
seq3 = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name='untitled sequential 3'
)
- self.client.delete(reverse_usage_url('xblock_handler', seq3.location))
- mock_remove_prereq.assert_called_with(seq3.location)
- mock_set_required.assert_called_with(seq3.location.course_key, seq3.location, None, None, None)
+ self.client.delete(reverse_usage_url('xblock_handler', seq3.usage_key))
+ mock_remove_prereq.assert_called_with(seq3.usage_key)
+ mock_set_required.assert_called_with(seq3.usage_key.course_key, seq3.usage_key, None, None, None)
diff --git a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py
index 6e9192aff526..9a04697f2c3e 100644
--- a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py
+++ b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py
@@ -58,12 +58,12 @@ def _create_content_experiment(self, cid=-1, group_id=None, cid_for_problem=None
"""
sequential = BlockFactory.create(
category='sequential',
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name=f'Test Subsection {name_suffix}'
)
vertical = BlockFactory.create(
category='vertical',
- parent_location=sequential.location,
+ parent_location=sequential.usage_key,
display_name=f'Test Unit {name_suffix}'
)
c0_url = self.course.id.make_usage_key("vertical", f"split_test_cond0_{name_suffix}")
@@ -71,25 +71,25 @@ def _create_content_experiment(self, cid=-1, group_id=None, cid_for_problem=None
c2_url = self.course.id.make_usage_key("vertical", f"split_test_cond2_{name_suffix}")
split_test = BlockFactory.create(
category='split_test',
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
user_partition_id=cid,
display_name=f"Test Content Experiment {name_suffix}{special_characters}",
group_id_to_child={"0": c0_url, "1": c1_url, "2": c2_url}
)
BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 0 vertical",
location=c0_url,
)
c1_vertical = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 1 vertical",
location=c1_url,
)
BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 2 vertical",
location=c2_url,
@@ -99,19 +99,19 @@ def _create_content_experiment(self, cid=-1, group_id=None, cid_for_problem=None
if group_id and cid_for_problem:
problem = BlockFactory.create(
category='problem',
- parent_location=c1_vertical.location,
+ parent_location=c1_vertical.usage_key,
display_name="Test Problem"
)
self.client.ajax_post(
- reverse_usage_url("xblock_handler", problem.location),
+ reverse_usage_url("xblock_handler", problem.usage_key),
data={'metadata': {'group_access': {cid_for_problem: [group_id]}}}
)
- c1_vertical.children.append(problem.location)
+ c1_vertical.children.append(problem.usage_key)
partitions_json = [p.to_json() for p in self.course.user_partitions]
self.client.ajax_post(
- reverse_usage_url("xblock_handler", split_test.location),
+ reverse_usage_url("xblock_handler", split_test.usage_key),
data={'metadata': {'user_partitions': partitions_json}}
)
@@ -123,14 +123,14 @@ def _create_problem_with_content_group(self, cid, group_id, name_suffix='', spec
Create a problem
Assign content group to the problem.
"""
- vertical_parent_location = self.course.location
+ vertical_parent_location = self.course.usage_key
if not orphan:
subsection = BlockFactory.create(
category='sequential',
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name=f"Test Subsection {name_suffix}"
)
- vertical_parent_location = subsection.location
+ vertical_parent_location = subsection.usage_key
vertical = BlockFactory.create(
category='vertical',
@@ -140,19 +140,19 @@ def _create_problem_with_content_group(self, cid, group_id, name_suffix='', spec
problem = BlockFactory.create(
category='problem',
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
display_name=f"Test Problem {name_suffix}{special_characters}"
)
group_access_content = {'group_access': {cid: [group_id]}}
self.client.ajax_post(
- reverse_usage_url("xblock_handler", problem.location),
+ reverse_usage_url("xblock_handler", problem.usage_key),
data={'metadata': group_access_content}
)
if not orphan:
- self.course.children.append(subsection.location)
+ self.course.children.append(subsection.usage_key)
self.save_course()
return vertical, problem
@@ -748,7 +748,7 @@ def test_can_get_correct_usage_info_when_special_characters_are_in_content(self)
expected = self._get_expected_content_group(
usage_for_group=[
{
- 'url': f"/container/{vertical.location}",
+ 'url': f"/container/{vertical.usage_key}",
'label': "Test Unit 0 / Test Problem 0JOSÉ ANDRÉS"
}
]
@@ -767,7 +767,7 @@ def test_can_get_correct_usage_info_for_content_groups(self):
expected = self._get_expected_content_group(usage_for_group=[
{
- 'url': f'/container/{vertical.location}',
+ 'url': f'/container/{vertical.usage_key}',
'label': 'Test Unit 0 / Test Problem 0'
}
])
@@ -785,7 +785,7 @@ def test_can_get_correct_usage_info_with_orphan(self):
# Assert that there is an orphan in the course, and that it's the vertical
self.assertEqual(len(self.store.get_orphans(self.course.id)), 1)
- self.assertIn(vertical.location, self.store.get_orphans(self.course.id))
+ self.assertIn(vertical.usage_key, self.store.get_orphans(self.course.id))
# Get the expected content group information.
expected = self._get_expected_content_group(usage_for_group=[])
@@ -809,11 +809,11 @@ def test_can_use_one_content_group_in_multiple_problems(self):
expected = self._get_expected_content_group(usage_for_group=[
{
- 'url': f'/container/{vertical1.location}',
+ 'url': f'/container/{vertical1.usage_key}',
'label': 'Test Unit 1 / Test Problem 1'
},
{
- 'url': f'/container/{vertical.location}',
+ 'url': f'/container/{vertical.usage_key}',
'label': 'Test Unit 0 / Test Problem 0'
}
])
@@ -876,7 +876,7 @@ def test_can_get_correct_usage_info_for_split_test(self):
'groups': [
{'id': 3, 'name': 'Problem Group', 'version': 1, 'usage': [
{
- 'url': f'/container/{split_test.location}',
+ 'url': f'/container/{split_test.usage_key}',
'label': 'Condition 1 vertical / Test Problem'
}
]},
@@ -909,7 +909,7 @@ def test_can_get_correct_usage_info_for_unit(self):
)
self.client.ajax_post(
- reverse_usage_url("xblock_handler", vertical.location),
+ reverse_usage_url("xblock_handler", vertical.usage_key),
data={'metadata': {'group_access': {0: [0]}}}
)
@@ -925,11 +925,11 @@ def test_can_get_correct_usage_info_for_unit(self):
'groups': [
{'id': 0, 'name': 'Group', 'version': 1, 'usage': [
{
- 'url': f"/container/{vertical.location}",
+ 'url': f"/container/{vertical.usage_key}",
'label': "Test Subsection 0 / Test Unit 0"
},
{
- 'url': f"/container/{vertical.location}",
+ 'url': f"/container/{vertical.usage_key}",
'label': "Test Unit 0 / Test Problem 0"
}
]},
@@ -964,7 +964,7 @@ def test_can_get_correct_usage_info(self):
{'id': 2, 'name': 'Group C', 'version': 1},
],
'usage': [{
- 'url': f'/container/{split_test.location}',
+ 'url': f'/container/{split_test.usage_key}',
'label': 'Test Unit 0 / Test Content Experiment 0',
'validation': None,
}],
@@ -1010,7 +1010,7 @@ def test_can_get_usage_info_when_special_characters_are_used(self):
{'id': 2, 'name': 'Group C', 'version': 1},
],
'usage': [{
- 'url': reverse_usage_url("container_handler", split_test.location),
+ 'url': reverse_usage_url("container_handler", split_test.usage_key),
'label': "Test Unit 0 / Test Content Experiment 0JOSÉ ANDRÉS",
'validation': None,
}],
@@ -1043,11 +1043,11 @@ def test_can_use_one_configuration_in_multiple_experiments(self):
{'id': 2, 'name': 'Group C', 'version': 1},
],
'usage': [{
- 'url': f'/container/{split_test.location}',
+ 'url': f'/container/{split_test.usage_key}',
'label': 'Test Unit 0 / Test Content Experiment 0',
'validation': None,
}, {
- 'url': f'/container/{split_test1.location}',
+ 'url': f'/container/{split_test1.usage_key}',
'label': 'Test Unit 1 / Test Content Experiment 1',
'validation': None,
}],
@@ -1172,7 +1172,7 @@ def verify_validation_add_usage_info(self, expected_result, mocked_message, mock
self._add_user_partitions()
split_test = self._create_content_experiment(cid=0, name_suffix='0')[1]
- validation = StudioValidation(split_test.location)
+ validation = StudioValidation(split_test.usage_key)
validation.add(mocked_message)
mocked_validation_messages.return_value = validation
@@ -1207,7 +1207,7 @@ def verify_validation_update_usage_info(self, expected_result, mocked_message, m
self._add_user_partitions()
split_test = self._create_content_experiment(cid=0, name_suffix='0')[1]
- validation = StudioValidation(split_test.location)
+ validation = StudioValidation(split_test.usage_key)
if mocked_message is not None:
validation.add(mocked_message)
mocked_validation_messages.return_value = validation
diff --git a/cms/djangoapps/contentstore/views/tests/test_helpers.py b/cms/djangoapps/contentstore/views/tests/test_helpers.py
index e64cbaf46335..654a9a312f7a 100644
--- a/cms/djangoapps/contentstore/views/tests/test_helpers.py
+++ b/cms/djangoapps/contentstore/views/tests/test_helpers.py
@@ -23,41 +23,41 @@ def test_xblock_studio_url(self):
self.assertEqual(xblock_studio_url(self.course), course_url)
# Verify chapter URL
- chapter = BlockFactory.create(parent_location=self.course.location, category='chapter',
+ chapter = BlockFactory.create(parent_location=self.course.usage_key, category='chapter',
display_name="Week 1")
self.assertEqual(
xblock_studio_url(chapter),
- f'{course_url}?show={quote(str(chapter.location).encode())}'
+ f'{course_url}?show={quote(str(chapter.usage_key).encode())}'
)
# Verify sequential URL
- sequential = BlockFactory.create(parent_location=chapter.location, category='sequential',
+ sequential = BlockFactory.create(parent_location=chapter.usage_key, category='sequential',
display_name="Lesson 1")
self.assertEqual(
xblock_studio_url(sequential),
- f'{course_url}?show={quote(str(sequential.location).encode())}'
+ f'{course_url}?show={quote(str(sequential.usage_key).encode())}'
)
# Verify unit URL
- vertical = BlockFactory.create(parent_location=sequential.location, category='vertical',
+ vertical = BlockFactory.create(parent_location=sequential.usage_key, category='vertical',
display_name='Unit')
- self.assertEqual(xblock_studio_url(vertical), f'/container/{vertical.location}')
+ self.assertEqual(xblock_studio_url(vertical), f'/container/{vertical.usage_key}')
# Verify child vertical URL
- child_vertical = BlockFactory.create(parent_location=vertical.location, category='vertical',
+ child_vertical = BlockFactory.create(parent_location=vertical.usage_key, category='vertical',
display_name='Child Vertical')
- self.assertEqual(xblock_studio_url(child_vertical), f'/container/{child_vertical.location}')
+ self.assertEqual(xblock_studio_url(child_vertical), f'/container/{child_vertical.usage_key}')
# Verify video URL
- video = BlockFactory.create(parent_location=child_vertical.location, category="video",
+ video = BlockFactory.create(parent_location=child_vertical.usage_key, category="video",
display_name="My Video")
self.assertIsNone(xblock_studio_url(video))
# Verify video URL with find_parent=True
- self.assertEqual(xblock_studio_url(video, find_parent=True), f'/container/{child_vertical.location}')
+ self.assertEqual(xblock_studio_url(video, find_parent=True), f'/container/{child_vertical.usage_key}')
# Verify library URL
library = LibraryFactory.create()
- expected_url = f'/library/{str(library.location.library_key)}'
+ expected_url = f'/library/{str(library.usage_key.library_key)}'
self.assertEqual(xblock_studio_url(library), expected_url)
@patch('cms.djangoapps.contentstore.helpers.configuration_helpers.get_value')
@@ -66,20 +66,20 @@ def test_xblock_lms_url(self, mock_get_value: Mock):
# Verify chapter URL
chapter = BlockFactory.create(
- parent_location=self.course.location, category='chapter', display_name="Week 1"
+ parent_location=self.course.usage_key, category='chapter', display_name="Week 1"
)
self.assertEqual(
xblock_lms_url(chapter),
- f"lms.example.com/courses/{chapter.location.course_key}/jump_to/{chapter.location}"
+ f"lms.example.com/courses/{chapter.usage_key.course_key}/jump_to/{chapter.usage_key}"
)
# Verify sequential URL
sequential = BlockFactory.create(
- parent_location=chapter.location, category='sequential', display_name="Lesson 1"
+ parent_location=chapter.usage_key, category='sequential', display_name="Lesson 1"
)
self.assertEqual(
xblock_lms_url(sequential),
- f"lms.example.com/courses/{sequential.location.course_key}/jump_to/{sequential.location}"
+ f"lms.example.com/courses/{sequential.usage_key.course_key}/jump_to/{sequential.usage_key}"
)
@patch('cms.djangoapps.contentstore.helpers.configuration_helpers.get_value')
@@ -88,44 +88,44 @@ def test_xblock_embed_lms_url(self, mock_get_value: Mock):
# Verify chapter URL
chapter = BlockFactory.create(
- parent_location=self.course.location, category='chapter', display_name="Week 1"
+ parent_location=self.course.usage_key, category='chapter', display_name="Week 1"
)
- self.assertEqual(xblock_embed_lms_url(chapter), f"lms.example.com/xblock/{chapter.location}")
+ self.assertEqual(xblock_embed_lms_url(chapter), f"lms.example.com/xblock/{chapter.usage_key}")
# Verify sequential URL
sequential = BlockFactory.create(
- parent_location=chapter.location, category='sequential', display_name="Lesson 1"
+ parent_location=chapter.usage_key, category='sequential', display_name="Lesson 1"
)
- self.assertEqual(xblock_embed_lms_url(sequential), f"lms.example.com/xblock/{sequential.location}")
+ self.assertEqual(xblock_embed_lms_url(sequential), f"lms.example.com/xblock/{sequential.usage_key}")
def test_xblock_type_display_name(self):
# Verify chapter type display name
- chapter = BlockFactory.create(parent_location=self.course.location, category='chapter')
+ chapter = BlockFactory.create(parent_location=self.course.usage_key, category='chapter')
self.assertEqual(xblock_type_display_name(chapter), 'Section')
self.assertEqual(xblock_type_display_name('chapter'), 'Section')
# Verify sequential type display name
- sequential = BlockFactory.create(parent_location=chapter.location, category='sequential')
+ sequential = BlockFactory.create(parent_location=chapter.usage_key, category='sequential')
self.assertEqual(xblock_type_display_name(sequential), 'Subsection')
self.assertEqual(xblock_type_display_name('sequential'), 'Subsection')
# Verify unit type display names
- vertical = BlockFactory.create(parent_location=sequential.location, category='vertical')
+ vertical = BlockFactory.create(parent_location=sequential.usage_key, category='vertical')
self.assertEqual(xblock_type_display_name(vertical), 'Unit')
self.assertEqual(xblock_type_display_name('vertical'), 'Unit')
# Verify child vertical type display name
- child_vertical = BlockFactory.create(parent_location=vertical.location, category='vertical',
+ child_vertical = BlockFactory.create(parent_location=vertical.usage_key, category='vertical',
display_name='Child Vertical')
self.assertEqual(xblock_type_display_name(child_vertical), 'Vertical')
# Verify video type display names
- video = BlockFactory.create(parent_location=vertical.location, category="video")
+ video = BlockFactory.create(parent_location=vertical.usage_key, category="video")
self.assertEqual(xblock_type_display_name(video), 'Video')
self.assertEqual(xblock_type_display_name('video'), 'Video')
# Verify split test type display names
- split_test = BlockFactory.create(parent_location=vertical.location, category="split_test")
+ split_test = BlockFactory.create(parent_location=vertical.usage_key, category="split_test")
self.assertEqual(xblock_type_display_name(split_test), 'Content Experiment')
self.assertEqual(xblock_type_display_name('split_test'), 'Content Experiment')
diff --git a/cms/djangoapps/contentstore/views/tests/test_import_export.py b/cms/djangoapps/contentstore/views/tests/test_import_export.py
index 170c341c32be..05208f49fe70 100644
--- a/cms/djangoapps/contentstore/views/tests/test_import_export.py
+++ b/cms/djangoapps/contentstore/views/tests/test_import_export.py
@@ -445,31 +445,31 @@ def test_library_import(self):
"""
# Create some blocks to overwrite
library = LibraryFactory.create(modulestore=self.store)
- lib_key = library.location.library_key
+ lib_key = library.usage_key.library_key
test_block = BlockFactory.create(
category="vertical",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user.id,
publish_item=False,
)
test_block2 = BlockFactory.create(
category="vertical",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user.id,
publish_item=False
)
# Create a library and blocks that should remain unmolested.
unchanged_lib = LibraryFactory.create()
- unchanged_key = unchanged_lib.location.library_key
+ unchanged_key = unchanged_lib.usage_key.library_key
test_block3 = BlockFactory.create(
category="vertical",
- parent_location=unchanged_lib.location,
+ parent_location=unchanged_lib.usage_key,
user_id=self.user.id,
publish_item=False
)
test_block4 = BlockFactory.create(
category="vertical",
- parent_location=unchanged_lib.location,
+ parent_location=unchanged_lib.usage_key,
user_id=self.user.id,
publish_item=False
)
@@ -505,7 +505,7 @@ def test_library_import(self):
finally:
shutil.rmtree(extract_dir)
- self.assertEqual(lib_key, library_items[0].location.library_key)
+ self.assertEqual(lib_key, library_items[0].usage_key.library_key)
library = self.store.get_library(lib_key)
children = [self.store.get_item(child).url_name for child in library.children]
self.assertEqual(len(children), 3)
@@ -529,7 +529,7 @@ def test_library_import_branch_settings(self, branch_setting):
"""
with self.store.branch_setting(branch_setting):
library = LibraryFactory.create(modulestore=self.store)
- lib_key = library.location.library_key
+ lib_key = library.usage_key.library_key
extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
# the extract_dir needs to be passed as a relative dir to
# import_library_from_xml
@@ -804,10 +804,10 @@ def test_unknown_xblock_top_level(self):
Export unknown XBlock type (i.e. we uninstalled the XBlock), top level.
"""
fake_xblock = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='not_a_real_block_type'
)
- self.store.publish(fake_xblock.location, self.user.id)
+ self.store.publish(fake_xblock.usage_key, self.user.id)
# Now check the resulting export
tar_ball = self.test_export_async()
@@ -839,15 +839,15 @@ def test_unknown_xblock_subsection_level(self):
Export unknown XBlock type deeper in the course.
"""
vertical = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='vertical',
display_name='sample_vertical',
)
fake_xblock = BlockFactory.create(
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
category='not_a_real_block_type',
)
- self.store.publish(fake_xblock.location, self.user.id)
+ self.store.publish(fake_xblock.usage_key, self.user.id)
# Now check the resulting export
tar_ball = self.test_export_async()
@@ -905,13 +905,13 @@ def test_library_export(self):
library = LibraryFactory.create(modulestore=self.store)
video_block = BlockFactory.create(
category="video",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user.id,
publish_item=False,
youtube_id_1_0=youtube_id
)
name = library.url_name
- lib_key = library.location.library_key
+ lib_key = library.usage_key.library_key
root_dir = path(tempfile.mkdtemp())
try:
export_library_to_xml(self.store, contentstore(), lib_key, root_dir, name)
@@ -935,10 +935,10 @@ def test_export_success_with_custom_tag(self):
"""
xml_string = 'slides'
vertical = BlockFactory.create(
- parent_location=self.course.location, category='vertical', display_name='foo'
+ parent_location=self.course.usage_key, category='vertical', display_name='foo'
)
BlockFactory.create(
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
category='customtag',
display_name='custom_tag_foo',
data=xml_string
@@ -1076,9 +1076,9 @@ def setUp(self):
def test_content_library_export_import(self):
library1 = LibraryFactory.create(modulestore=self.store)
- source_library1_key = library1.location.library_key
+ source_library1_key = library1.usage_key.library_key
library2 = LibraryFactory.create(modulestore=self.store)
- source_library2_key = library2.location.library_key
+ source_library2_key = library2.usage_key.library_key
import_library_from_xml(
self.store,
@@ -1134,7 +1134,7 @@ def setUp(self):
# Create a problem in library
BlockFactory.create(
category="problem",
- parent_location=self.library.location,
+ parent_location=self.library.usage_key,
user_id=self.user.id,
publish_item=False,
display_name='Test Problem',
@@ -1150,18 +1150,18 @@ def _setup_source_course_with_library_content(self, publish=False, version=None)
Sets up course with library content.
"""
chapter = BlockFactory.create(
- parent_location=self.source_course.location,
+ parent_location=self.source_course.usage_key,
category='chapter',
display_name='Test Section'
)
sequential = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category='sequential',
display_name='Test Sequential'
)
vertical = BlockFactory.create(
category='vertical',
- parent_location=sequential.location,
+ parent_location=sequential.usage_key,
display_name='Test Unit'
)
lc_block = self._add_library_content_block(
@@ -1225,7 +1225,7 @@ def test_library_content_on_course_export_import(self, publish_item, generate_ve
export_course_to_xml(
self.store,
contentstore(),
- self.source_course.location.course_key,
+ self.source_course.usage_key.course_key,
self.export_dir,
'exported_source_course',
)
@@ -1237,15 +1237,15 @@ def test_library_content_on_course_export_import(self, publish_item, generate_ve
self.export_dir,
['exported_source_course'],
static_content_store=contentstore(),
- target_id=dest_course.location.course_key,
+ target_id=dest_course.usage_key.course_key,
load_error_blocks=False,
raise_on_failure=True,
create_if_not_present=True,
)
self.assert_problem_display_names(
- self.source_course.location,
- dest_course.location,
+ self.source_course.usage_key,
+ dest_course.usage_key,
publish_item
)
@@ -1268,18 +1268,18 @@ def _setup_source_course_with_problem_content(self, data, publish_item=False):
Sets up course with problem content.
"""
chapter = BlockFactory.create(
- parent_location=self.source_course.location,
+ parent_location=self.source_course.usage_key,
category='chapter',
display_name='Test Section'
)
sequential = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category='sequential',
display_name='Test Sequential'
)
vertical = BlockFactory.create(
category='vertical',
- parent_location=sequential.location,
+ parent_location=sequential.usage_key,
display_name='Test Unit'
)
@@ -1356,7 +1356,7 @@ def test_problem_content_on_course_export_import(self, problem_data, expected_pr
export_course_to_xml(
self.store,
contentstore(),
- self.source_course.location.course_key,
+ self.source_course.usage_key.course_key,
self.export_dir,
'exported_source_course',
)
@@ -1367,13 +1367,13 @@ def test_problem_content_on_course_export_import(self, problem_data, expected_pr
self.export_dir,
['exported_source_course'],
static_content_store=contentstore(),
- target_id=dest_course.location.course_key,
+ target_id=dest_course.usage_key.course_key,
load_error_blocks=False,
raise_on_failure=True,
create_if_not_present=True,
)
- self.assert_problem_definition(dest_course.location, expected_problem_content)
+ self.assert_problem_definition(dest_course.usage_key, expected_problem_content)
class ImportAuthzTest(CourseAuthzTestMixin, BaseCourseViewTest):
diff --git a/cms/djangoapps/contentstore/views/tests/test_library.py b/cms/djangoapps/contentstore/views/tests/test_library.py
index fd62faa56db1..ae6ac6935a0f 100644
--- a/cms/djangoapps/contentstore/views/tests/test_library.py
+++ b/cms/djangoapps/contentstore/views/tests/test_library.py
@@ -175,7 +175,7 @@ def test_list_libraries(self):
"""
# Create some more libraries
libraries = [LibraryFactory.create() for _ in range(3)]
- lib_dict = {lib.location.library_key: lib for lib in libraries}
+ lib_dict = {lib.usage_key.library_key: lib for lib in libraries}
response = self.client.get_json(LIBRARY_REST_URL)
self.assertEqual(response.status_code, 200)
@@ -285,7 +285,7 @@ def test_no_duplicate_libraries(self):
We should not be able to create multiple libraries with the same key
"""
lib = LibraryFactory.create()
- lib_key = lib.location.library_key
+ lib_key = lib.usage_key.library_key
response = self.client.ajax_post(LIBRARY_REST_URL, {
'org': lib_key.org,
'library': lib_key.library,
@@ -337,10 +337,10 @@ def test_get_lib_info(self):
Test that we can get data about a library (in JSON format) using /library/:key/
"""
# Create a library
- lib_key = LibraryFactory.create().location.library_key
+ lib_key = LibraryFactory.create().usage_key.library_key
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
- version = lib.location.library_key.version_guid
+ version = lib.usage_key.library_key.version_guid
self.assertNotEqual(version, None)
response = self.client.get_json(make_url_for_lib(lib_key))
@@ -359,7 +359,7 @@ def test_get_lib_edit_html(self):
"""
lib = LibraryFactory.create()
- response = self.client.get(make_url_for_lib(lib.location.library_key))
+ response = self.client.get(make_url_for_lib(lib.usage_key.library_key))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "foobar"}
)
@@ -95,7 +95,7 @@ def test_preview_no_asides(self):
"""
course = CourseFactory.create()
html = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="html",
data={'data': "foobar"}
)
@@ -130,19 +130,19 @@ def test_preview_conditional_block_children_context(self, mock_is_condition_sati
course = CourseFactory.create()
conditional_block = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="conditional"
)
# child conditional_block
BlockFactory.create(
- parent_location=conditional_block.location,
+ parent_location=conditional_block.usage_key,
category="conditional"
)
url = reverse_usage_url(
'preview_handler',
- conditional_block.location,
+ conditional_block.usage_key,
kwargs={'handler': 'xmodule_handler/conditional_get'}
)
response = client.post(url)
@@ -158,18 +158,18 @@ def test_block_branch_not_changed_by_preview_handler(self):
course = CourseFactory.create()
block = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="problem"
)
url = reverse_usage_url(
'preview_handler',
- block.location,
+ block.usage_key,
kwargs={'handler': 'xmodule_handler/problem_check'}
)
response = client.post(url)
self.assertEqual(response.status_code, 200)
- self.assertFalse(modulestore().has_changes(modulestore().get_item(block.location)))
+ self.assertFalse(modulestore().has_changes(modulestore().get_item(block.usage_key)))
@XBlock.needs("i18n")
@@ -238,7 +238,7 @@ def setUp(self):
self.contentstore = contentstore()
self.block = BlockFactory(category="problem", parent=course)
_prepare_runtime_for_preview(self.request, block=self.block)
- self.course = self.store.get_item(course.location)
+ self.course = self.store.get_item(course.usage_key)
def test_get_user_role(self):
assert self.block.runtime.get_user_role() == 'staff'
diff --git a/cms/djangoapps/contentstore/views/tests/test_tabs.py b/cms/djangoapps/contentstore/views/tests/test_tabs.py
index b4e4d17181ef..f37c75ec8f3b 100644
--- a/cms/djangoapps/contentstore/views/tests/test_tabs.py
+++ b/cms/djangoapps/contentstore/views/tests/test_tabs.py
@@ -28,7 +28,7 @@ def setUp(self):
# add a static tab to the course, for code coverage
self.test_tab = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="static_tab",
display_name="Static_1"
)
@@ -164,7 +164,7 @@ def test_tab_preview_html(self):
"""
Verify that the static tab renders itself with the correct HTML
"""
- preview_url = f'/xblock/{self.test_tab.location}/{STUDENT_VIEW}'
+ preview_url = f'/xblock/{self.test_tab.usage_key}/{STUDENT_VIEW}'
resp = self.client.get(preview_url, HTTP_ACCEPT='application/json')
assert resp.status_code == 200
diff --git a/cms/djangoapps/contentstore/views/tests/test_textbooks.py b/cms/djangoapps/contentstore/views/tests/test_textbooks.py
index 0756d236ed42..ba4e4d158005 100644
--- a/cms/djangoapps/contentstore/views/tests/test_textbooks.py
+++ b/cms/djangoapps/contentstore/views/tests/test_textbooks.py
@@ -280,7 +280,7 @@ def test_replace_by_id(self):
self.assertEqual(resp2.status_code, 200)
compare = json.loads(resp2.content.decode('utf-8'))
self.assertEqual(compare, replacement)
- course = self.store.get_item(self.course.location)
+ course = self.store.get_item(self.course.usage_key)
self.assertEqual(
course.pdf_textbooks,
[self.textbook1, replacement]
diff --git a/cms/djangoapps/contentstore/views/tests/test_transcripts.py b/cms/djangoapps/contentstore/views/tests/test_transcripts.py
index a3b70641ed3c..d17ff218208c 100644
--- a/cms/djangoapps/contentstore/views/tests/test_transcripts.py
+++ b/cms/djangoapps/contentstore/views/tests/test_transcripts.py
@@ -89,7 +89,7 @@ def setUp(self):
# Add video block
data = {
- 'parent_locator': str(self.course.location),
+ 'parent_locator': str(self.course.usage_key),
'category': 'video',
'type': 'video'
}
@@ -145,7 +145,7 @@ def create_non_video_block(self):
Setup non video block for tests.
"""
data = {
- 'parent_locator': str(self.course.location),
+ 'parent_locator': str(self.course.usage_key),
'category': 'problem',
'type': 'problem'
}
@@ -1077,7 +1077,7 @@ def test_fail_data_with_bad_locator(self):
def test_fail_for_non_video_block(self):
# Not video block: setup
data = {
- 'parent_locator': str(self.course.location),
+ 'parent_locator': str(self.course.usage_key),
'category': 'problem',
'type': 'problem'
}
diff --git a/cms/djangoapps/contentstore/views/tests/test_unit_page.py b/cms/djangoapps/contentstore/views/tests/test_unit_page.py
index 932f9515a513..46d892bdc34f 100644
--- a/cms/djangoapps/contentstore/views/tests/test_unit_page.py
+++ b/cms/djangoapps/contentstore/views/tests/test_unit_page.py
@@ -17,9 +17,9 @@ class UnitPageTestCase(StudioPageTestCase):
def setUp(self):
super().setUp()
- self.vertical = BlockFactory.create(parent_location=self.sequential.location,
+ self.vertical = BlockFactory.create(parent_location=self.sequential.usage_key,
category='vertical', display_name='Unit')
- self.video = BlockFactory.create(parent_location=self.vertical.location,
+ self.video = BlockFactory.create(parent_location=self.vertical.usage_key,
category="video", display_name="My Video")
self.store = modulestore()
@@ -27,7 +27,7 @@ def test_public_component_preview_html(self):
"""
Verify that a public xblock's preview returns the expected HTML.
"""
- published_video = self.store.publish(self.video.location, self.user.id) # lint-amnesty, pylint: disable=unused-variable
+ published_video = self.store.publish(self.video.usage_key, self.user.id) # lint-amnesty, pylint: disable=unused-variable
self.validate_preview_html(self.video, STUDENT_VIEW, in_unit=True, can_add=False)
def test_draft_component_preview_html(self):
@@ -41,11 +41,11 @@ def test_public_child_container_preview_html(self):
Verify that a public child container rendering on the unit page (which shows a View arrow
to the container page) returns the expected HTML.
"""
- child_container = BlockFactory.create(parent_location=self.vertical.location,
+ child_container = BlockFactory.create(parent_location=self.vertical.usage_key,
category='split_test', display_name='Split Test')
- BlockFactory.create(parent_location=child_container.location,
+ BlockFactory.create(parent_location=child_container.usage_key,
category='html', display_name='grandchild')
- published_child_container = self.store.publish(child_container.location, self.user.id)
+ published_child_container = self.store.publish(child_container.usage_key, self.user.id)
self.validate_preview_html(published_child_container, STUDENT_VIEW, in_unit=True, can_add=False)
def test_draft_child_container_preview_html(self):
@@ -53,9 +53,9 @@ def test_draft_child_container_preview_html(self):
Verify that a draft child container rendering on the unit page (which shows a View arrow
to the container page) returns the expected HTML.
"""
- child_container = BlockFactory.create(parent_location=self.vertical.location,
+ child_container = BlockFactory.create(parent_location=self.vertical.usage_key,
category='split_test', display_name='Split Test')
- BlockFactory.create(parent_location=child_container.location,
+ BlockFactory.create(parent_location=child_container.usage_key,
category='html', display_name='grandchild')
- draft_child_container = self.store.get_item(child_container.location)
+ draft_child_container = self.store.get_item(child_container.usage_key)
self.validate_preview_html(draft_child_container, STUDENT_VIEW, in_unit=True, can_add=False)
diff --git a/cms/djangoapps/contentstore/views/tests/test_videos.py b/cms/djangoapps/contentstore/views/tests/test_videos.py
index e42ef2198c8d..37fdfed57cc2 100644
--- a/cms/djangoapps/contentstore/views/tests/test_videos.py
+++ b/cms/djangoapps/contentstore/views/tests/test_videos.py
@@ -1,1764 +1,1764 @@
-"""
-Unit tests for video-related REST APIs.
-"""
-
-
-import csv
-import json
-import re
-from contextlib import contextmanager
-from datetime import datetime
-from io import StringIO
-from unittest.mock import Mock, patch
-
-import dateutil.parser
-from common.djangoapps.student.tests.factories import UserFactory
-import ddt
-import pytz
-from django.test import TestCase
-from django.conf import settings
-from django.test.utils import override_settings
-from django.urls import reverse
-from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
-from edxval.api import (
- create_or_update_transcript_preferences,
- create_or_update_video_transcript,
- create_profile,
- create_video,
- get_course_video_image_url,
- get_transcript_preferences,
- get_video_info
-)
-from cms.djangoapps.contentstore.models import VideoUploadConfig
-from cms.djangoapps.contentstore.tests.utils import CourseTestCase
-from cms.djangoapps.contentstore.utils import reverse_course_url
-from openedx.core.djangoapps.profile_images.tests.helpers import make_image_file
-from openedx.core.djangoapps.video_pipeline.config.waffle import (
- DEPRECATE_YOUTUBE,
- ENABLE_DEVSTACK_VIDEO_UPLOADS,
-)
-from openedx.core.djangoapps.waffle_utils.models import WaffleFlagCourseOverrideModel
-from xmodule.modulestore.django import modulestore
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
-from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
-
-from ..videos import (
- KEY_EXPIRATION_IN_SECONDS,
- VIDEO_IMAGE_UPLOAD_ENABLED,
-)
-from cms.djangoapps.contentstore.video_storage_handlers import (
- TranscriptProvider,
- StatusDisplayStrings,
- convert_video_status,
- storage_service_bucket,
- storage_service_key,
- PUBLIC_VIDEO_SHARE
-)
-
-
-def setup_s3_mocks(mock_boto3_resource, bucket_name='test-bucket'):
- """
- Helper function to set up consistent boto3 S3 mocks.
-
- Args:
- mock_boto3_resource: The patched boto3.resource mock
- bucket_name: Name for the mock bucket (default: 'test-bucket')
-
- Returns:
- tuple: (mock_s3_client, mock_bucket, mock_s3_resource)
- """
- mock_s3_client = Mock()
- mock_bucket = Mock()
- mock_bucket.name = bucket_name
- mock_bucket.meta.client = mock_s3_client
- mock_s3_resource = Mock()
- mock_s3_resource.Bucket.return_value = mock_bucket
- mock_boto3_resource.return_value = mock_s3_resource
- return mock_s3_client, mock_bucket, mock_s3_resource
-
-
-class VideoUploadTestBase:
- """
- Test cases for the video upload feature
- """
-
- def get_url_for_course_key(self, course_key, kwargs=None):
- """Return video handler URL for the given course"""
- return reverse_course_url(self.VIEW_NAME, course_key, kwargs) # lint-amnesty, pylint: disable=no-member
-
- def setUp(self):
- super().setUp() # lint-amnesty, pylint: disable=no-member
- self.url = self.get_url_for_course_key(self.course.id)
- self.test_token = "test_token"
- self.course.video_upload_pipeline = {
- "course_video_upload_token": self.test_token,
- }
- self.save_course() # lint-amnesty, pylint: disable=no-member
-
- # create another course for videos belonging to multiple courses
- self.course2 = CourseFactory.create()
- self.course2.video_upload_pipeline = {
- "course_video_upload_token": self.test_token,
- }
- self.course2.save()
- self.store.update_item(self.course2, self.user.id) # lint-amnesty, pylint: disable=no-member
-
- # course ids for videos
- course_ids = [str(self.course.id), str(self.course2.id)]
- created = datetime.now(pytz.utc)
-
- self.profiles = ["profile1", "profile2"]
- self.previous_uploads = [
- {
- "edx_video_id": "test1",
- "client_video_id": "test1.mp4",
- "duration": 42.0,
- "status": "upload",
- "courses": course_ids,
- "encoded_videos": [],
- "created": created
- },
- {
- "edx_video_id": "test2",
- "client_video_id": "test2.mp4",
- "duration": 128.0,
- "status": "file_complete",
- "courses": course_ids,
- "created": created,
- "encoded_videos": [
- {
- "profile": "profile1",
- "url": "http://example.com/profile1/test2.mp4",
- "file_size": 1600,
- "bitrate": 100,
- },
- {
- "profile": "profile2",
- "url": "http://example.com/profile2/test2.mov",
- "file_size": 16000,
- "bitrate": 1000,
- },
- ],
- },
- {
- "edx_video_id": "non-ascii",
- "client_video_id": "nón-ascii-näme.mp4",
- "duration": 256.0,
- "status": "transcode_active",
- "courses": course_ids,
- "created": created,
- "encoded_videos": [
- {
- "profile": "profile1",
- "url": "http://example.com/profile1/nón-ascii-näme.mp4",
- "file_size": 3200,
- "bitrate": 100,
- },
- ]
- },
- ]
- # Ensure every status string is tested
- self.previous_uploads += [
- {
- "edx_video_id": f"status_test_{status}",
- "client_video_id": "status_test.mp4",
- "duration": 3.14,
- "status": status,
- "courses": course_ids,
- "created": created,
- "encoded_videos": [],
- }
- for status in (
- list(StatusDisplayStrings._STATUS_MAP.keys()) + # pylint:disable=protected-access
- ["non_existent_status"]
- )
- ]
- for profile in self.profiles:
- create_profile(profile)
- for video in self.previous_uploads:
- create_video(video)
-
- def _get_previous_upload(self, edx_video_id):
- """Returns the previous upload with the given video id."""
- return next(
- video
- for video in self.previous_uploads
- if video["edx_video_id"] == edx_video_id
- )
-
-
-class VideoStudioAccessTestsMixin:
- """
- Base Access tests for studio video views
- """
- def test_anon_user(self):
- self.client.logout()
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 302)
-
- def test_put(self):
- response = self.client.put(self.url)
- self.assertEqual(response.status_code, 405)
-
- def test_invalid_course_key(self):
- response = self.client.get(
- self.get_url_for_course_key("Non/Existent/Course")
- )
- self.assertEqual(response.status_code, 404)
-
- def test_non_staff_user(self):
- client, __ = self.create_non_staff_authed_user_client()
- response = client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
-
-class VideoPipelineStudioAccessTestsMixin:
- """
- Access tests for video views that rely on the video pipeline
- """
- def test_video_pipeline_not_enabled(self):
- settings.FEATURES["ENABLE_VIDEO_UPLOAD_PIPELINE"] = False
- self.assertEqual(self.client.get(self.url).status_code, 404)
-
- def test_video_pipeline_not_configured(self):
- settings.VIDEO_UPLOAD_PIPELINE = None
- self.assertEqual(self.client.get(self.url).status_code, 404)
-
- def test_course_not_configured(self):
- self.course.video_upload_pipeline = {}
- self.save_course()
- self.assertEqual(self.client.get(self.url).status_code, 404)
-
-
-class VideoUploadPostTestsMixin:
- """
- Shared test cases for video post tests.
- """
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- def test_post_success(self, mock_boto3_resource):
- files = [
- {
- 'file_name': 'first.mp4',
- 'content_type': 'video/mp4',
- },
- {
- 'file_name': 'second.mp4',
- 'content_type': 'video/mp4',
- },
- {
- 'file_name': 'third.mov',
- 'content_type': 'video/quicktime',
- },
- {
- 'file_name': 'fourth.mp4',
- 'content_type': 'video/mp4',
- },
- ]
-
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Mock generate_presigned_url to return different URLs for each file
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- response = self.client.post(
- self.url,
- json.dumps({'files': files}),
- content_type='application/json'
- )
- self.assertEqual(response.status_code, 200)
- response_obj = json.loads(response.content.decode('utf-8'))
-
- # Verify boto3 resource was called correctly
- mock_boto3_resource.assert_called_once_with(
- "s3",
- aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
- aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY
- )
-
- self.assertEqual(len(response_obj['files']), len(files))
- self.assertEqual(mock_s3_client.generate_presigned_url.call_count, len(files))
-
- for i, file_info in enumerate(files):
- # Get the call args for this file's presigned URL generation
- call_args = mock_s3_client.generate_presigned_url.call_args_list[i]
- args, kwargs = call_args
-
- # Verify the operation and params
- self.assertEqual(args[0], 'put_object')
- self.assertEqual(kwargs['Params']['Bucket'], 'test-bucket')
- self.assertEqual(kwargs['Params']['ContentType'], file_info['content_type'])
- self.assertEqual(kwargs['ExpiresIn'], KEY_EXPIRATION_IN_SECONDS)
-
- # Extract video_id from the key
- key_name = kwargs['Params']['Key']
- path_match = re.match(
- (
- settings.VIDEO_UPLOAD_PIPELINE['ROOT_PATH'] +
- '/([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12})$'
- ),
- key_name
- )
- self.assertIsNotNone(path_match)
- video_id = path_match.group(1)
-
- # Verify metadata
- metadata = kwargs['Params']['Metadata']
- self.assertEqual(metadata['course_video_upload_token'], self.test_token)
- self.assertEqual(metadata['client_video_id'], file_info['file_name'])
- self.assertEqual(metadata['course_key'], str(self.course.id))
-
- # Ensure VAL was updated
- val_info = get_video_info(video_id)
- self.assertEqual(val_info['status'], 'upload')
- self.assertEqual(val_info['client_video_id'], file_info['file_name'])
- self.assertEqual(val_info['duration'], 0)
- self.assertEqual(val_info['courses'], [{str(self.course.id): None}])
-
- # Ensure response is correct
- response_file = response_obj['files'][i]
- self.assertEqual(response_file['file_name'], file_info['file_name'])
- self.assertEqual(response_file['upload_url'], f'http://example.com/url_{file_info["file_name"]}')
-
- def test_post_non_json(self):
- response = self.client.post(self.url, {"files": []})
- self.assertEqual(response.status_code, 400)
-
- def test_post_malformed_json(self):
- response = self.client.post(self.url, "{", content_type="application/json")
- self.assertEqual(response.status_code, 400)
-
- def test_post_invalid_json(self):
- def assert_bad(content):
- """Make request with content and assert that response is 400"""
- response = self.client.post(
- self.url,
- json.dumps(content),
- content_type="application/json"
- )
- self.assertEqual(response.status_code, 400)
-
- # Top level missing files key
- assert_bad({})
-
- # Entry missing file_name
- assert_bad({"files": [{"content_type": "video/mp4"}]})
-
- # Entry missing content_type
- assert_bad({"files": [{"file_name": "test.mp4"}]})
-
-
-@ddt.ddt
-@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
-@override_settings(VIDEO_UPLOAD_PIPELINE={
- "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
-})
-class VideosHandlerTestCase(
- VideoUploadTestBase,
- VideoStudioAccessTestsMixin,
- VideoPipelineStudioAccessTestsMixin,
- VideoUploadPostTestsMixin,
- CourseTestCase
-):
- """Test cases for the main video upload endpoint"""
-
- VIEW_NAME = 'videos_handler'
-
- def test_get_json(self):
- response = self.client.get_json(self.url)
- self.assertEqual(response.status_code, 200)
- response_videos = json.loads(response.content.decode('utf-8'))['videos']
- self.assertEqual(len(response_videos), len(self.previous_uploads))
- for i, response_video in enumerate(response_videos):
- # Videos should be returned by creation date descending
- original_video = self.previous_uploads[-(i + 1)]
- print(response_video.keys())
- self.assertEqual(
- set(response_video.keys()),
- {
- 'edx_video_id',
- 'client_video_id',
- 'created',
- 'duration',
- 'status',
- 'status_nontranslated',
- 'course_video_image_url',
- 'file_size',
- 'download_link',
- 'transcripts',
- 'transcription_status',
- 'transcript_urls',
- 'error_description',
- }
- )
- dateutil.parser.parse(response_video['created'])
- for field in ['edx_video_id', 'client_video_id', 'duration']:
- self.assertEqual(response_video[field], original_video[field])
- self.assertEqual(
- response_video['status'],
- convert_video_status(original_video)
- )
-
- @ddt.data(
- (
- [
- 'edx_video_id', 'client_video_id', 'created', 'duration',
- 'status', 'status_nontranslated', 'course_video_image_url', 'file_size',
- 'download_link', 'transcripts', 'transcription_status', 'transcript_urls',
- 'error_description'
- ],
- [
- {
- 'video_id': 'test1',
- 'language_code': 'en',
- 'file_name': 'edx101.srt',
- 'file_format': 'srt',
- 'provider': 'Cielo24'
- }
- ],
- ['en']
- ),
- (
- [
- 'edx_video_id', 'client_video_id', 'created', 'duration',
- 'status', 'status_nontranslated', 'course_video_image_url', 'file_size',
- 'download_link', 'transcripts', 'transcription_status', 'transcript_urls',
- 'error_description'
- ],
- [
- {
- 'video_id': 'test1',
- 'language_code': 'en',
- 'file_name': 'edx101_en.srt',
- 'file_format': 'srt',
- 'provider': 'Cielo24'
- },
- {
- 'video_id': 'test1',
- 'language_code': 'es',
- 'file_name': 'edx101_es.srt',
- 'file_format': 'srt',
- 'provider': 'Cielo24'
- }
- ],
- ['en', 'es']
- )
- )
- @ddt.unpack
- def test_get_json_transcripts(self, expected_video_keys, uploaded_transcripts, expected_transcripts):
- """
- Test that transcripts are attached based on whether the video transcript feature is enabled.
- """
- for transcript in uploaded_transcripts:
- create_or_update_video_transcript(
- transcript['video_id'],
- transcript['language_code'],
- metadata={
- 'file_name': transcript['file_name'],
- 'file_format': transcript['file_format'],
- 'provider': transcript['provider']
- }
- )
-
- response = self.client.get_json(self.url)
- self.assertEqual(response.status_code, 200)
- response_videos = json.loads(response.content.decode('utf-8'))['videos']
- self.assertEqual(len(response_videos), len(self.previous_uploads))
- for response_video in response_videos:
- print(response_video)
-
- self.assertEqual(set(response_video.keys()), set(expected_video_keys))
- if response_video['edx_video_id'] == self.previous_uploads[0]['edx_video_id']:
- self.assertEqual(response_video.get('transcripts', []), expected_transcripts)
-
- def test_get_redirects_to_video_uploads_url(self):
- """
- Test that GET requests redirect to the MFE video uploads page.
- """
- from cms.djangoapps.contentstore.utils import get_video_uploads_url
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 302)
- self.assertEqual(response.url, get_video_uploads_url(self.course.id))
-
- @override_settings(AWS_ACCESS_KEY_ID="test_key_id", AWS_SECRET_ACCESS_KEY="test_secret")
- @patch("cms.djangoapps.contentstore.video_storage_handlers.boto3.resource")
- @ddt.data(
- (
- [
- {
- "file_name": "supported-1.mp4",
- "content_type": "video/mp4",
- },
- {
- "file_name": "supported-2.mov",
- "content_type": "video/quicktime",
- },
- ],
- 200
- ),
- (
- [
- {
- "file_name": "unsupported-1.txt",
- "content_type": "text/plain",
- },
- {
- "file_name": "unsupported-2.png",
- "content_type": "image/png",
- },
- ],
- 400
- )
- )
- @ddt.unpack
- def test_video_supported_file_formats(self, files, expected_status, mock_boto3_resource):
- """
- Test that video upload works correctly against supported and unsupported file formats.
- """
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Mock generate_presigned_url to return different URLs for each file
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- # Check supported formats
- response = self.client.post(
- self.url,
- json.dumps({"files": files}),
- content_type="application/json"
- )
- self.assertEqual(response.status_code, expected_status)
- response = json.loads(response.content.decode('utf-8'))
-
- if expected_status == 200:
- self.assertNotIn('error', response)
- else:
- self.assertIn('error', response)
- self.assertEqual(response['error'], "Request 'files' entry contain unsupported content_type")
-
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- def test_upload_with_non_ascii_charaters(self, mock_boto3_resource):
- """
- Test that video uploads throws error message when file name contains special characters.
- """
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- file_name = 'test\u2019_file.mp4'
- files = [{'file_name': file_name, 'content_type': 'video/mp4'}]
-
- response = self.client.post(
- self.url,
- json.dumps({'files': files}),
- content_type='application/json'
- )
- self.assertEqual(response.status_code, 400)
- response = json.loads(response.content.decode('utf-8'))
- self.assertEqual(response['error'], 'The file name for %s must contain only ASCII characters.' % file_name)
-
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret', AWS_SECURITY_TOKEN='token')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- @override_waffle_flag(ENABLE_DEVSTACK_VIDEO_UPLOADS, active=True)
- def test_devstack_upload_connection(self, mock_boto3_resource):
- files = [{'file_name': 'first.mp4', 'content_type': 'video/mp4'}]
-
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Mock generate_presigned_url to return different URLs for each file
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- response = self.client.post(
- self.url,
- json.dumps({'files': files}),
- content_type='application/json'
- )
-
- self.assertEqual(response.status_code, 200)
- mock_boto3_resource.assert_called_once_with(
- "s3",
- aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
- aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
- security_token=settings.AWS_SECURITY_TOKEN
- )
-
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- def test_send_course_to_vem_pipeline(self, mock_boto3_resource):
- """
- Test that uploads always go to VEM S3 bucket by default.
- """
- files = [{'file_name': 'first.mp4', 'content_type': 'video/mp4'}]
-
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Mock generate_presigned_url to return different URLs for each file
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- response = self.client.post(
- self.url,
- json.dumps({'files': files}),
- content_type='application/json'
- )
-
- self.assertEqual(response.status_code, 200)
- mock_s3_resource.Bucket.assert_called_once_with(
- settings.VIDEO_UPLOAD_PIPELINE['VEM_S3_BUCKET'] # pylint: disable=unsubscriptable-object
- )
-
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- @ddt.data(
- {
- 'global_waffle': True,
- 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.off,
- 'expect_token': True
- },
- {
- 'global_waffle': False,
- 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.on,
- 'expect_token': False
- },
- {
- 'global_waffle': False,
- 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.off,
- 'expect_token': True
- }
- )
- def test_video_upload_token_in_meta(self, data, mock_boto3_resource):
- """
- Test video upload token in s3 metadata.
- """
- @contextmanager
- def proxy_manager(manager, ignore_manager):
- """
- This acts as proxy to the original manager in the arguments given
- the original manager is not set to be ignored.
- """
- if ignore_manager:
- yield
- else:
- with manager:
- yield
-
- file_data = {
- 'file_name': 'first.mp4',
- 'content_type': 'video/mp4',
- }
-
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Track generate_presigned_url calls to inspect metadata
- presigned_url_calls = []
-
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- presigned_url_calls.append((operation, Params, ExpiresIn))
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=data['course_override']):
- with override_waffle_flag(DEPRECATE_YOUTUBE, active=data['global_waffle']):
- response = self.client.post(
- self.url,
- json.dumps({'files': [file_data]}),
- content_type='application/json'
- )
- self.assertEqual(response.status_code, 200)
-
- # Check if course_video_upload_token is in metadata based on expectation
- if data['expect_token']:
- # We should find the token in the metadata
- self.assertEqual(len(presigned_url_calls), 1)
- metadata = presigned_url_calls[0][1]['Metadata']
- self.assertIn('course_video_upload_token', metadata)
- self.assertEqual(metadata['course_video_upload_token'], self.test_token)
- else:
- # If we don't expect a token, verify it's not in metadata
- if presigned_url_calls:
- metadata = presigned_url_calls[0][1]['Metadata']
- self.assertNotIn('course_video_upload_token', metadata)
-
- def _assert_video_removal(self, url, edx_video_id, deleted_videos):
- """
- Verify that if correct video is removed from a particular course.
-
- Arguments:
- url (str): URL to get uploaded videos
- edx_video_id (str): video id
- deleted_videos (int): how many videos are deleted
- """
- response = self.client.get_json(url)
- self.assertEqual(response.status_code, 200)
- response_videos = json.loads(response.content.decode('utf-8'))["videos"]
- self.assertEqual(len(response_videos), len(self.previous_uploads) - deleted_videos)
-
- if deleted_videos:
- self.assertNotIn(edx_video_id, [video.get('edx_video_id') for video in response_videos])
- else:
- self.assertIn(edx_video_id, [video.get('edx_video_id') for video in response_videos])
-
- def test_video_removal(self):
- """
- Verifies that video removal is working as expected.
- """
- edx_video_id = 'test1'
- remove_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
- response = self.client.delete(remove_url, HTTP_ACCEPT="application/json")
- self.assertEqual(response.status_code, 204)
-
- self._assert_video_removal(self.url, edx_video_id, 1)
-
- def test_video_removal_multiple_courses(self):
- """
- Verifies that video removal is working as expected for multiple courses.
-
- If a video is used by multiple courses then removal from one course shouldn't effect the other course.
- """
- # remove video from course1
- edx_video_id = 'test1'
- remove_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
- response = self.client.delete(remove_url, HTTP_ACCEPT="application/json")
- self.assertEqual(response.status_code, 204)
-
- # verify that video is only deleted from course1 only
- self._assert_video_removal(self.url, edx_video_id, 1)
- self._assert_video_removal(self.get_url_for_course_key(self.course2.id), edx_video_id, 0)
-
- def test_convert_video_status(self):
- """
- Verifies that convert_video_status works as expected.
- """
- video = self.previous_uploads[0]
-
- # video status should be failed if it's in upload state for more than 24 hours
- video['created'] = datetime(2016, 1, 1, 10, 10, 10, 0, pytz.UTC)
- status = convert_video_status(video)
- self.assertEqual(status, StatusDisplayStrings.get('upload_failed'))
-
- # `invalid_token` should be converted to `youtube_duplicate`
- video['created'] = datetime.now(pytz.UTC)
- video['status'] = 'invalid_token'
- status = convert_video_status(video)
- self.assertEqual(status, StatusDisplayStrings.get('youtube_duplicate'))
-
- # The "encode status" should be converted to `file_complete` if video encodes are complete
- video['status'] = 'transcription_in_progress'
- status = convert_video_status(video, is_video_encodes_ready=True)
- self.assertEqual(status, StatusDisplayStrings.get('file_complete'))
-
- # If encoding is not complete return the status as it is
- video['status'] = 's3_upload_failed'
- status = convert_video_status(video)
- self.assertEqual(status, StatusDisplayStrings.get('s3_upload_failed'))
-
- # for all other status, there should not be any conversion
- statuses = list(StatusDisplayStrings._STATUS_MAP.keys()) # pylint: disable=protected-access
- statuses.remove('invalid_token')
- for status in statuses:
- video['status'] = status
- new_status = convert_video_status(video)
- self.assertEqual(new_status, StatusDisplayStrings.get(status))
-
- def assert_video_status(self, url, edx_video_id, status):
- """
- Verifies that video with `edx_video_id` has `status`
- """
- response = self.client.get_json(url)
- self.assertEqual(response.status_code, 200)
- videos = json.loads(response.content.decode('utf-8'))["videos"]
- for video in videos:
- if video['edx_video_id'] == edx_video_id:
- return self.assertEqual(video['status'], status)
-
- # Test should fail if video not found
- self.assertEqual(True, False, 'Invalid edx_video_id')
-
- @patch('cms.djangoapps.contentstore.video_storage_handlers.LOGGER')
- def test_video_status_update_request(self, mock_logger):
- """
- Verifies that video status update request works as expected.
- """
- url = self.get_url_for_course_key(self.course.id)
- edx_video_id = 'test1'
- self.assert_video_status(url, edx_video_id, 'Uploading')
-
- response = self.client.post(
- url,
- json.dumps([{
- 'edxVideoId': edx_video_id,
- 'status': 'upload_failed',
- 'message': 'server down'
- }]),
- content_type="application/json"
- )
-
- mock_logger.info.assert_called_with(
- 'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
- edx_video_id,
- 'upload_failed',
- 'server down'
- )
-
- self.assertEqual(response.status_code, 204)
-
- self.assert_video_status(url, edx_video_id, 'Failed')
-
- @ddt.data(
- ('test_video_token', "Transcription in Progress"),
- ('', "Ready"),
- )
- @ddt.unpack
- def test_video_transcript_status_conversion(self, course_video_upload_token, expected_video_status_text):
- """
- Verifies that video status `transcription_in_progress` gets converted
- correctly into the `file_complete` for the new video workflow and
- stays as it is, for the old video workflow.
- """
- self.course.video_upload_pipeline = {
- 'course_video_upload_token': course_video_upload_token
- }
- self.save_course()
-
- url = self.get_url_for_course_key(self.course.id)
- edx_video_id = 'test1'
- self.assert_video_status(url, edx_video_id, 'Uploading')
-
- response = self.client.post(
- url,
- json.dumps([{
- 'edxVideoId': edx_video_id,
- 'status': 'transcription_in_progress',
- 'message': 'Transcription is in progress'
- }]),
- content_type="application/json"
- )
- self.assertEqual(response.status_code, 204)
-
- self.assert_video_status(url, edx_video_id, expected_video_status_text)
-
-
-@ddt.ddt
-@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
-@override_settings(VIDEO_UPLOAD_PIPELINE={
- "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
-})
-class GenerateVideoUploadLinkTestCase(
- VideoUploadTestBase,
- VideoUploadPostTestsMixin,
- CourseTestCase
-):
- """
- Test cases for the main video upload endpoint
- """
-
- VIEW_NAME = 'generate_video_upload_link'
-
- def test_unsupported_requests_fail(self):
- """
- The API only supports post, make sure other requests fail
- """
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 405)
-
- response = self.client.put(self.url)
- self.assertEqual(response.status_code, 405)
-
- response = self.client.patch(self.url)
- self.assertEqual(response.status_code, 405)
-
-
-@ddt.ddt
-@patch.dict('django.conf.settings.FEATURES', {'ENABLE_VIDEO_UPLOAD_PIPELINE': True})
-@override_settings(VIDEO_UPLOAD_PIPELINE={'BUCKET': 'test_bucket', 'ROOT_PATH': 'test_root'})
-class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
- """
- Tests for video image.
- """
-
- VIEW_NAME = "video_images_handler"
-
- def verify_image_upload_reponse(self, course_id, edx_video_id, upload_response):
- """
- Verify that image is uploaded successfully.
-
- Arguments:
- course_id: ID of course
- edx_video_id: ID of video
- upload_response: Upload response object
-
- Returns:
- uploaded image url
- """
- self.assertEqual(upload_response.status_code, 200)
- response = json.loads(upload_response.content.decode('utf-8'))
- val_image_url = get_course_video_image_url(course_id=course_id, edx_video_id=edx_video_id)
- self.assertEqual(response['image_url'], val_image_url)
-
- return val_image_url
-
- def verify_error_message(self, response, error_message):
- """
- Verify that image upload failure gets proper error message.
-
- Arguments:
- response: Response object.
- error_message: Expected error message.
- """
- self.assertEqual(response.status_code, 400)
- response = json.loads(response.content.decode('utf-8'))
- self.assertIn('error', response)
- self.assertEqual(response['error'], error_message)
-
- @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, False)
- def test_video_image_upload_disabled(self):
- """
- Tests the video image upload when the feature is disabled.
- """
- video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': 'test_vid_id'})
- response = self.client.post(video_image_upload_url, {'file': 'dummy_file'}, format='multipart')
- self.assertEqual(response.status_code, 404)
-
- @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
- def test_video_image(self):
- """
- Test video image is saved.
- """
- edx_video_id = 'test1'
- video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
- with make_image_file(
- dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
- ) as image_file:
- response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
- image_url1 = self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
-
- # upload again to verify that new image is uploaded successfully
- with make_image_file(
- dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
- ) as image_file:
- response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
- image_url2 = self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
-
- self.assertNotEqual(image_url1, image_url2)
-
- @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
- def test_video_image_no_file(self):
- """
- Test that an error error message is returned if upload request is incorrect.
- """
- video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': 'test1'})
- response = self.client.post(video_image_upload_url, {})
- self.verify_error_message(response, 'An image file is required.')
-
- @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
- def test_no_video_image(self):
- """
- Test image url is set to None if no video image.
- """
- edx_video_id = 'test1'
- get_videos_url = reverse_course_url('videos_handler', self.course.id)
- video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
- with make_image_file(
- dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
- ) as image_file:
- self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
-
- val_image_url = get_course_video_image_url(course_id=self.course.id, edx_video_id=edx_video_id)
-
- response = self.client.get_json(get_videos_url)
- self.assertEqual(response.status_code, 200)
- response_videos = json.loads(response.content.decode('utf-8'))["videos"]
- for response_video in response_videos:
- if response_video['edx_video_id'] == edx_video_id:
- self.assertEqual(response_video['course_video_image_url'], val_image_url)
- else:
- self.assertEqual(response_video['course_video_image_url'], None)
-
- @ddt.data(
- # Image file type validation
- (
- {
- 'extension': '.png'
- },
- None
- ),
- (
- {
- 'extension': '.gif'
- },
- None
- ),
- (
- {
- 'extension': '.bmp'
- },
- None
- ),
- (
- {
- 'extension': '.jpg'
- },
- None
- ),
- (
- {
- 'extension': '.jpeg'
- },
- None
- ),
- (
- {
- 'extension': '.PNG'
- },
- None
- ),
- (
- {
- 'extension': '.tiff'
- },
- 'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
- supported_file_formats=list(settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys())
- )
- ),
- # Image file size validation
- (
- {
- 'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MAX_BYTES'] + 10
- },
- 'This image file must be smaller than {image_max_size}.'.format(
- image_max_size=settings.VIDEO_IMAGE_MAX_FILE_SIZE_MB
- )
- ),
- (
- {
- 'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES'] - 10
- },
- 'This image file must be larger than {image_min_size}.'.format(
- image_min_size=settings.VIDEO_IMAGE_MIN_FILE_SIZE_KB
- )
- ),
- # Image file minimum width / height
- (
- {
- 'width': 16, # 16x9
- 'height': 9
- },
- 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long
- image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
- image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
- image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
- image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
- )
- ),
- (
- {
- 'width': settings.VIDEO_IMAGE_MIN_WIDTH - 10,
- 'height': settings.VIDEO_IMAGE_MIN_HEIGHT
- },
- 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long
- image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
- image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
- image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
- image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
- )
- ),
- (
- {
- 'width': settings.VIDEO_IMAGE_MIN_WIDTH,
- 'height': settings.VIDEO_IMAGE_MIN_HEIGHT - 10
- },
- (
- 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
- 'The minimum resolution is {image_file_min_width}x{image_file_min_height}.'
- ).format(
- image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
- image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
- image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
- image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
- )
- ),
- (
- {
- 'width': 1200, # not 16:9, but width/height check first.
- 'height': 100
- },
- (
- 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
- 'The minimum resolution is {image_file_min_width}x{image_file_min_height}.'
- ).format(
- image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
- image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
- image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
- image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
- )
- ),
- # Image file aspect ratio validation
- (
- {
- 'width': settings.VIDEO_IMAGE_MAX_WIDTH, # 1280x720
- 'height': settings.VIDEO_IMAGE_MAX_HEIGHT
- },
- None
- ),
- (
- {
- 'width': 850, # 16:9
- 'height': 478
- },
- None
- ),
- (
- {
- 'width': 940, # 1.67 ratio, applicable aspect ratio margin of .01
- 'height': 560
- },
- None
- ),
- (
- {
- 'width': settings.VIDEO_IMAGE_MIN_WIDTH + 100,
- 'height': settings.VIDEO_IMAGE_MIN_HEIGHT + 200
- },
- 'This image file must have an aspect ratio of {video_image_aspect_ratio_text}.'.format(
- video_image_aspect_ratio_text=settings.VIDEO_IMAGE_ASPECT_RATIO_TEXT
- )
- ),
- # Image file name validation
- (
- {
- 'prefix': 'nøn-åßç¡¡'
- },
- 'The image file name can only contain letters, numbers, hyphens (-), and underscores (_).'
- )
- )
- @ddt.unpack
- @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
- def test_video_image_validation_message(self, image_data, error_message):
- """
- Test video image validation gives proper error message.
-
- Arguments:
- image_data (Dict): Specific data to create image file.
- error_message (String): Error message
- """
- edx_video_id = 'test1'
- video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
- with make_image_file(
- dimensions=(
- image_data.get('width', settings.VIDEO_IMAGE_MIN_WIDTH),
- image_data.get('height', settings.VIDEO_IMAGE_MIN_HEIGHT)
- ),
- prefix=image_data.get('prefix', 'videoimage'),
- extension=image_data.get('extension', '.png'),
- force_size=image_data.get('size', settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES'])
- ) as image_file:
- response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
- if error_message:
- self.verify_error_message(response, error_message)
- else:
- self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
-
-
-@ddt.ddt
-@patch(
- 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled',
- Mock(return_value=True)
-)
-@patch.dict('django.conf.settings.FEATURES', {'ENABLE_VIDEO_UPLOAD_PIPELINE': True})
-class TranscriptPreferencesTestCase(VideoUploadTestBase, CourseTestCase):
- """
- Tests for video transcripts preferences.
- """
-
- VIEW_NAME = 'transcript_preferences_handler'
-
- def test_405_with_not_allowed_request_method(self):
- """
- Verify that 405 is returned in case of not-allowed request methods.
- Allowed request methods are POST and DELETE.
- """
- video_transcript_url = self.get_url_for_course_key(self.course.id)
- response = self.client.get(
- video_transcript_url,
- content_type='application/json'
- )
- self.assertEqual(response.status_code, 405)
-
- @ddt.data(
- # Video transcript feature disabled
- (
- {},
- False,
- '',
- 404,
- ),
- # Error cases
- (
- {},
- True,
- "Invalid provider None.",
- 400
- ),
- (
- {
- 'provider': ''
- },
- True,
- "Invalid provider .",
- 400
- ),
- (
- {
- 'provider': 'dummy-provider'
- },
- True,
- "Invalid provider dummy-provider.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24
- },
- True,
- "Invalid cielo24 fidelity None.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- },
- True,
- "Invalid cielo24 turnaround None.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- 'cielo24_turnaround': 'STANDARD',
- 'video_source_language': 'en'
- },
- True,
- "Invalid languages [].",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PREMIUM',
- 'cielo24_turnaround': 'STANDARD',
- 'video_source_language': 'es'
- },
- True,
- "Unsupported source language es.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- 'cielo24_turnaround': 'STANDARD',
- 'video_source_language': 'en',
- 'preferred_languages': ['es', 'ur']
- },
- True,
- "Invalid languages ['es', 'ur'].",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.THREE_PLAY_MEDIA
- },
- True,
- "Invalid 3play turnaround None.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
- 'three_play_turnaround': 'standard',
- 'video_source_language': 'zh',
- },
- True,
- "Unsupported source language zh.",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
- 'three_play_turnaround': 'standard',
- 'video_source_language': 'es',
- 'preferred_languages': ['es', 'ur']
- },
- True,
- "Invalid languages ['es', 'ur'].",
- 400
- ),
- (
- {
- 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
- 'three_play_turnaround': 'standard',
- 'video_source_language': 'en',
- 'preferred_languages': ['es', 'ur']
- },
- True,
- "Invalid languages ['es', 'ur'].",
- 400
- ),
- # Success
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- 'cielo24_turnaround': 'STANDARD',
- 'video_source_language': 'es',
- 'preferred_languages': ['en']
- },
- True,
- '',
- 200
- ),
- (
- {
- 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
- 'three_play_turnaround': 'standard',
- 'preferred_languages': ['en'],
- 'video_source_language': 'en',
- },
- True,
- '',
- 200
- )
- )
- @ddt.unpack
- def test_video_transcript(self, preferences, is_video_transcript_enabled, error_message, expected_status_code):
- """
- Tests that transcript handler works correctly.
- """
- video_transcript_url = self.get_url_for_course_key(self.course.id)
- preferences_data = {
- 'provider': preferences.get('provider'),
- 'cielo24_fidelity': preferences.get('cielo24_fidelity'),
- 'cielo24_turnaround': preferences.get('cielo24_turnaround'),
- 'three_play_turnaround': preferences.get('three_play_turnaround'),
- 'preferred_languages': preferences.get('preferred_languages', []),
- 'video_source_language': preferences.get('video_source_language'),
- }
-
- with patch(
- 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
- ) as video_transcript_feature:
- video_transcript_feature.return_value = is_video_transcript_enabled
- response = self.client.post(
- video_transcript_url,
- json.dumps(preferences_data),
- content_type='application/json'
- )
- status_code = response.status_code
- response = json.loads(response.content.decode('utf-8')) if is_video_transcript_enabled else response
-
- self.assertEqual(status_code, expected_status_code)
- self.assertEqual(response.get('error', ''), error_message)
-
- # Remove modified and course_id fields from the response so as to check the expected transcript preferences.
- response.get('transcript_preferences', {}).pop('modified', None)
- response.get('transcript_preferences', {}).pop('course_id', None)
- expected_preferences = preferences_data if is_video_transcript_enabled and not error_message else {}
- self.assertDictEqual(response.get('transcript_preferences', {}), expected_preferences)
-
- def test_remove_transcript_preferences(self):
- """
- Test that transcript handler removes transcript preferences correctly.
- """
- # First add course wide transcript preferences.
- preferences = create_or_update_transcript_preferences(str(self.course.id))
-
- # Verify transcript preferences exist
- self.assertIsNotNone(preferences)
-
- response = self.client.delete(
- self.get_url_for_course_key(self.course.id),
- content_type='application/json'
- )
-
- self.assertEqual(response.status_code, 204)
-
- # Verify transcript preferences no loger exist
- preferences = get_transcript_preferences(str(self.course.id))
- self.assertIsNone(preferences)
-
- def test_remove_transcript_preferences_not_found(self):
- """
- Test that transcript handler works correctly even when no preferences are found.
- """
- course_id = 'course-v1:dummy+course+id'
- # Verify transcript preferences do not exist
- preferences = get_transcript_preferences(course_id)
- self.assertIsNone(preferences)
-
- response = self.client.delete(
- self.get_url_for_course_key(course_id),
- content_type='application/json'
- )
- self.assertEqual(response.status_code, 204)
-
- # Verify transcript preferences do not exist
- preferences = get_transcript_preferences(course_id)
- self.assertIsNone(preferences)
-
- @ddt.data(
- (
- None,
- False
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- 'cielo24_turnaround': 'STANDARD',
- 'preferred_languages': ['en']
- },
- False
- ),
- (
- {
- 'provider': TranscriptProvider.CIELO24,
- 'cielo24_fidelity': 'PROFESSIONAL',
- 'cielo24_turnaround': 'STANDARD',
- 'preferred_languages': ['en']
- },
- True
- )
- )
- @ddt.unpack
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.get_transcript_preferences')
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- def test_transcript_preferences_metadata(self, transcript_preferences, is_video_transcript_enabled,
- mock_boto3_resource, mock_transcript_preferences):
- """
- Tests that transcript preference metadata is only set if it is video transcript feature is enabled and
- transcript preferences are already stored in the system.
- """
- file_name = 'test-video.mp4'
- request_data = {'files': [{'file_name': file_name, 'content_type': 'video/mp4'}]}
-
- mock_transcript_preferences.return_value = transcript_preferences
-
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
-
- # Track generate_presigned_url calls to inspect metadata
- presigned_url_calls = []
-
- def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
- presigned_url_calls.append((operation, Params, ExpiresIn))
- file_name = Params['Metadata']['client_video_id']
- return f'http://example.com/url_{file_name}'
-
- mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
-
- videos_handler_url = reverse_course_url('videos_handler', self.course.id)
- with patch(
- 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
- ) as video_transcript_feature:
- video_transcript_feature.return_value = is_video_transcript_enabled
- response = self.client.post(videos_handler_url, json.dumps(request_data), content_type='application/json')
-
- self.assertEqual(response.status_code, 200)
-
- # Ensure `transcript_preferences` was set up in metadata correctly if sent through request.
- if is_video_transcript_enabled and transcript_preferences:
- self.assertEqual(len(presigned_url_calls), 1)
- metadata = presigned_url_calls[0][1]['Metadata']
- self.assertIn('transcript_preferences', metadata)
- self.assertEqual(metadata['transcript_preferences'], json.dumps(transcript_preferences))
- else:
- # If conditions aren't met, verify transcript_preferences is not in metadata
- if presigned_url_calls:
- metadata = presigned_url_calls[0][1]['Metadata']
- self.assertNotIn('transcript_preferences', metadata)
-
-
-@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
-@override_settings(VIDEO_UPLOAD_PIPELINE={"BUCKET": "test_bucket", "ROOT_PATH": "test_root"})
-class VideoUrlsCsvTestCase(
- VideoUploadTestBase,
- VideoStudioAccessTestsMixin,
- VideoPipelineStudioAccessTestsMixin,
- CourseTestCase
-):
- """Test cases for the CSV download endpoint for video uploads"""
-
- VIEW_NAME = "video_encodings_download"
-
- def setUp(self):
- super().setUp()
- VideoUploadConfig(profile_whitelist="profile1").save()
-
- def _check_csv_response(self, expected_profiles):
- """
- Check that the response is a valid CSV response containing rows
- corresponding to previous_uploads and including the expected profiles.
- """
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
- self.assertEqual(
- response["Content-Disposition"],
- f"attachment; filename=\"{self.course.id.course}_video_urls.csv\""
- )
- response_content = b"".join(response.streaming_content)
- response_reader = StringIO(response_content.decode())
- reader = csv.DictReader(response_reader, dialect=csv.excel)
- self.assertEqual(
- reader.fieldnames,
- (
- ["Name", "Duration", "Date Added", "Video ID", "Status"] +
- [f"{profile} URL" for profile in expected_profiles]
- )
- )
- rows = list(reader)
- self.assertEqual(len(rows), len(self.previous_uploads))
- for i, row in enumerate(rows):
- response_video = dict(row.items())
- # Videos should be returned by creation date descending
- original_video = self.previous_uploads[-(i + 1)]
- client_video_id = original_video["client_video_id"]
- self.assertEqual(response_video["Name"], client_video_id)
- self.assertEqual(response_video["Duration"], str(original_video["duration"]))
- dateutil.parser.parse(response_video["Date Added"])
- self.assertEqual(response_video["Video ID"], original_video["edx_video_id"])
- self.assertEqual(response_video["Status"], convert_video_status(original_video))
- for profile in expected_profiles:
- response_profile_url = response_video[f"{profile} URL"]
- original_encoded_for_profile = next(
- (
- original_encoded
- for original_encoded in original_video["encoded_videos"]
- if original_encoded["profile"] == profile
- ),
- None
- )
- if original_encoded_for_profile:
- original_encoded_for_profile_url = original_encoded_for_profile["url"]
- self.assertEqual(response_profile_url, original_encoded_for_profile_url)
- else:
- self.assertEqual(response_profile_url, "")
-
- def test_basic(self):
- self._check_csv_response(["profile1"])
-
- def test_profile_whitelist(self):
- VideoUploadConfig(profile_whitelist="profile1,profile2").save()
- self._check_csv_response(["profile1", "profile2"])
-
- def test_non_ascii_course(self):
- course = CourseFactory.create(
- number="nón-äscii",
- video_upload_pipeline={
- "course_video_upload_token": self.test_token,
- }
- )
- response = self.client.get(self.get_url_for_course_key(course.id))
- self.assertEqual(response.status_code, 200)
- self.assertEqual(
- response["Content-Disposition"],
- "attachment; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
- )
-
-
-@ddt.ddt
-class GetVideoFeaturesTestCase(
- CourseTestCase
-):
- """Test cases for the get_video_features endpoint """
- def setUp(self):
- super().setUp()
- self.url = self.get_url_for_course_key()
-
- def get_url_for_course_key(self):
- """ Helper to generate a url for a course key """
- return reverse("video_features")
-
- def test_basic(self):
- """ Test for expected return keys """
- response = self.client.get(self.get_url_for_course_key())
- self.assertEqual(response.status_code, 200)
- self.assertEqual(
- set(response.json().keys()),
- {
- 'videoSharingEnabled',
- 'allowThumbnailUpload',
- }
- )
-
- @ddt.data(True, False)
- def test_video_share_enabled(self, is_enabled):
- """ Test the public video share flag """
- self._test_video_feature(
- PUBLIC_VIDEO_SHARE,
- 'videoSharingEnabled',
- override_waffle_flag,
- is_enabled,
- )
-
- @ddt.data(True, False)
- def test_video_image_upload_enabled(self, is_enabled):
- """ Test the video image upload switch """
- self._test_video_feature(
- VIDEO_IMAGE_UPLOAD_ENABLED,
- 'allowThumbnailUpload',
- override_waffle_switch,
- is_enabled,
- )
-
- def _test_video_feature(self, flag, key, override_fn, is_enabled):
- """ Test that setting a waffle flag or switch on or off will cause the expected result """
- with override_fn(flag, is_enabled):
- response = self.client.get(self.get_url_for_course_key())
-
- self.assertEqual(response.status_code, 200)
- self.assertEqual(response.json()[key], is_enabled)
-
-
-class GetStorageBucketTestCase(TestCase):
- """ This test just check that connection works and returns the bucket.
- It does not involve any mocking and triggers errors if has any import issue.
- """
- @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
- @override_settings(VIDEO_UPLOAD_PIPELINE={
- "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
- })
- @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
- def test_storage_bucket(self, mock_boto3_resource):
- """ Test that storage service functions work correctly with boto3."""
- # Setup boto3 mocks
- mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource, 'vem_test_bucket')
-
- # Test storage_service_bucket function
- bucket = storage_service_bucket()
- self.assertEqual(bucket.name, 'vem_test_bucket')
- mock_s3_resource.Bucket.assert_called_once_with('vem_test_bucket')
-
- # Test storage_service_key function
- edx_video_id = 'dummy_video'
- key_name = storage_service_key(bucket, file_name=edx_video_id)
- expected_key = 'test_root/dummy_video'
- self.assertEqual(key_name, expected_key)
-
- # Test that we can generate presigned URL using the bucket's client
- mock_s3_client.generate_presigned_url.return_value = (
- 'https://vem_test_bucket.s3.amazonaws.com:443/test_root/dummy_video?signature=test'
- )
- upload_url = mock_s3_client.generate_presigned_url(
- 'put_object',
- Params={
- 'Bucket': bucket.name,
- 'Key': key_name,
- 'ContentType': 'video/mp4'
- },
- ExpiresIn=KEY_EXPIRATION_IN_SECONDS
- )
-
- self.assertIn("vem_test_bucket.s3.amazonaws.com", upload_url)
- self.assertIn("test_root/dummy_video", upload_url)
-
-
-class CourseYoutubeEdxVideoIds(ModuleStoreTestCase):
- """
- This test checks youtube videos in a course
- """
- VIEW_NAME = 'youtube_edx_video_ids'
-
- def setUp(self):
- super().setUp()
- self.course = CourseFactory.create()
- self.course_with_no_youtube_videos = CourseFactory.create()
- self.store = modulestore()
- self.user = UserFactory()
- self.client.login(username=self.user.username, password='Password1234')
-
- def get_url_for_course_key(self, course_key, kwargs=None):
- """Return video handler URL for the given course"""
- return reverse_course_url(self.VIEW_NAME, course_key, kwargs) # lint-amnesty, pylint: disable=no-member
-
- def test_course_with_youtube_videos(self):
- course_key = self.course.id
-
- with self.store.bulk_operations(course_key):
- chapter_loc = self.store.create_child(
- self.user.id, self.course.location, 'chapter', 'test_chapter'
- ).location
- seq_loc = self.store.create_child(
- self.user.id, chapter_loc, 'sequential', 'test_seq'
- ).location
- vert_loc = self.store.create_child(self.user.id, seq_loc, 'vertical', 'test_vert').location
- self.store.create_child(
- self.user.id,
- vert_loc,
- 'problem',
- 'test_problem',
- fields={"data": "Test"}
- )
- self.store.create_child(
- self.user.id, vert_loc, 'video', fields={
- "youtube_is_available": False,
- "name": "sample_video",
- "edx_video_id": "youtube_193_84709099",
- }
- )
-
- response = self.client.get(self.get_url_for_course_key(course_key))
- self.assertEqual(response.status_code, 200)
-
- edx_video_ids = json.loads(response.content.decode('utf-8'))['edx_video_ids']
- self.assertEqual(len(edx_video_ids), 1)
-
- def test_course_with_no_youtube_videos(self):
- course_key = self.course_with_no_youtube_videos.id
-
- with self.store.bulk_operations(course_key):
- chapter_loc = self.store.create_child(
- self.user.id, self.course_with_no_youtube_videos.location, 'chapter', 'test_chapter'
- ).location
- seq_loc = self.store.create_child(
- self.user.id, chapter_loc, 'sequential', 'test_seq'
- ).location
- vert_loc = self.store.create_child(self.user.id, seq_loc, 'vertical', 'test_vert').location
- self.store.create_child(
- self.user.id, vert_loc, 'problem', 'test_problem', fields={"data": "Test"}
- )
- self.store.create_child(
- self.user.id, vert_loc, 'video', fields={
- "youtube_id_1_0": None,
- "name": "sample_video",
- "edx_video_id": "no_youtube_193_84709099",
- }
- )
-
- response = self.client.get(self.get_url_for_course_key(course_key))
-
- edx_video_ids = json.loads(response.content.decode('utf-8'))['edx_video_ids']
- self.assertEqual(response.status_code, 200)
- self.assertEqual(len(edx_video_ids), 0)
+"""
+Unit tests for video-related REST APIs.
+"""
+
+
+import csv
+import json
+import re
+from contextlib import contextmanager
+from datetime import datetime
+from io import StringIO
+from unittest.mock import Mock, patch
+
+import dateutil.parser
+from common.djangoapps.student.tests.factories import UserFactory
+import ddt
+import pytz
+from django.test import TestCase
+from django.conf import settings
+from django.test.utils import override_settings
+from django.urls import reverse
+from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
+from edxval.api import (
+ create_or_update_transcript_preferences,
+ create_or_update_video_transcript,
+ create_profile,
+ create_video,
+ get_course_video_image_url,
+ get_transcript_preferences,
+ get_video_info
+)
+from cms.djangoapps.contentstore.models import VideoUploadConfig
+from cms.djangoapps.contentstore.tests.utils import CourseTestCase
+from cms.djangoapps.contentstore.utils import reverse_course_url
+from openedx.core.djangoapps.profile_images.tests.helpers import make_image_file
+from openedx.core.djangoapps.video_pipeline.config.waffle import (
+ DEPRECATE_YOUTUBE,
+ ENABLE_DEVSTACK_VIDEO_UPLOADS,
+)
+from openedx.core.djangoapps.waffle_utils.models import WaffleFlagCourseOverrideModel
+from xmodule.modulestore.django import modulestore
+from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
+
+from ..videos import (
+ KEY_EXPIRATION_IN_SECONDS,
+ VIDEO_IMAGE_UPLOAD_ENABLED,
+)
+from cms.djangoapps.contentstore.video_storage_handlers import (
+ TranscriptProvider,
+ StatusDisplayStrings,
+ convert_video_status,
+ storage_service_bucket,
+ storage_service_key,
+ PUBLIC_VIDEO_SHARE
+)
+
+
+def setup_s3_mocks(mock_boto3_resource, bucket_name='test-bucket'):
+ """
+ Helper function to set up consistent boto3 S3 mocks.
+
+ Args:
+ mock_boto3_resource: The patched boto3.resource mock
+ bucket_name: Name for the mock bucket (default: 'test-bucket')
+
+ Returns:
+ tuple: (mock_s3_client, mock_bucket, mock_s3_resource)
+ """
+ mock_s3_client = Mock()
+ mock_bucket = Mock()
+ mock_bucket.name = bucket_name
+ mock_bucket.meta.client = mock_s3_client
+ mock_s3_resource = Mock()
+ mock_s3_resource.Bucket.return_value = mock_bucket
+ mock_boto3_resource.return_value = mock_s3_resource
+ return mock_s3_client, mock_bucket, mock_s3_resource
+
+
+class VideoUploadTestBase:
+ """
+ Test cases for the video upload feature
+ """
+
+ def get_url_for_course_key(self, course_key, kwargs=None):
+ """Return video handler URL for the given course"""
+ return reverse_course_url(self.VIEW_NAME, course_key, kwargs) # lint-amnesty, pylint: disable=no-member
+
+ def setUp(self):
+ super().setUp() # lint-amnesty, pylint: disable=no-member
+ self.url = self.get_url_for_course_key(self.course.id)
+ self.test_token = "test_token"
+ self.course.video_upload_pipeline = {
+ "course_video_upload_token": self.test_token,
+ }
+ self.save_course() # lint-amnesty, pylint: disable=no-member
+
+ # create another course for videos belonging to multiple courses
+ self.course2 = CourseFactory.create()
+ self.course2.video_upload_pipeline = {
+ "course_video_upload_token": self.test_token,
+ }
+ self.course2.save()
+ self.store.update_item(self.course2, self.user.id) # lint-amnesty, pylint: disable=no-member
+
+ # course ids for videos
+ course_ids = [str(self.course.id), str(self.course2.id)]
+ created = datetime.now(pytz.utc)
+
+ self.profiles = ["profile1", "profile2"]
+ self.previous_uploads = [
+ {
+ "edx_video_id": "test1",
+ "client_video_id": "test1.mp4",
+ "duration": 42.0,
+ "status": "upload",
+ "courses": course_ids,
+ "encoded_videos": [],
+ "created": created
+ },
+ {
+ "edx_video_id": "test2",
+ "client_video_id": "test2.mp4",
+ "duration": 128.0,
+ "status": "file_complete",
+ "courses": course_ids,
+ "created": created,
+ "encoded_videos": [
+ {
+ "profile": "profile1",
+ "url": "http://example.com/profile1/test2.mp4",
+ "file_size": 1600,
+ "bitrate": 100,
+ },
+ {
+ "profile": "profile2",
+ "url": "http://example.com/profile2/test2.mov",
+ "file_size": 16000,
+ "bitrate": 1000,
+ },
+ ],
+ },
+ {
+ "edx_video_id": "non-ascii",
+ "client_video_id": "nón-ascii-näme.mp4",
+ "duration": 256.0,
+ "status": "transcode_active",
+ "courses": course_ids,
+ "created": created,
+ "encoded_videos": [
+ {
+ "profile": "profile1",
+ "url": "http://example.com/profile1/nón-ascii-näme.mp4",
+ "file_size": 3200,
+ "bitrate": 100,
+ },
+ ]
+ },
+ ]
+ # Ensure every status string is tested
+ self.previous_uploads += [
+ {
+ "edx_video_id": f"status_test_{status}",
+ "client_video_id": "status_test.mp4",
+ "duration": 3.14,
+ "status": status,
+ "courses": course_ids,
+ "created": created,
+ "encoded_videos": [],
+ }
+ for status in (
+ list(StatusDisplayStrings._STATUS_MAP.keys()) + # pylint:disable=protected-access
+ ["non_existent_status"]
+ )
+ ]
+ for profile in self.profiles:
+ create_profile(profile)
+ for video in self.previous_uploads:
+ create_video(video)
+
+ def _get_previous_upload(self, edx_video_id):
+ """Returns the previous upload with the given video id."""
+ return next(
+ video
+ for video in self.previous_uploads
+ if video["edx_video_id"] == edx_video_id
+ )
+
+
+class VideoStudioAccessTestsMixin:
+ """
+ Base Access tests for studio video views
+ """
+ def test_anon_user(self):
+ self.client.logout()
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 302)
+
+ def test_put(self):
+ response = self.client.put(self.url)
+ self.assertEqual(response.status_code, 405)
+
+ def test_invalid_course_key(self):
+ response = self.client.get(
+ self.get_url_for_course_key("Non/Existent/Course")
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_non_staff_user(self):
+ client, __ = self.create_non_staff_authed_user_client()
+ response = client.get(self.url)
+ self.assertEqual(response.status_code, 403)
+
+
+class VideoPipelineStudioAccessTestsMixin:
+ """
+ Access tests for video views that rely on the video pipeline
+ """
+ def test_video_pipeline_not_enabled(self):
+ settings.FEATURES["ENABLE_VIDEO_UPLOAD_PIPELINE"] = False
+ self.assertEqual(self.client.get(self.url).status_code, 404)
+
+ def test_video_pipeline_not_configured(self):
+ settings.VIDEO_UPLOAD_PIPELINE = None
+ self.assertEqual(self.client.get(self.url).status_code, 404)
+
+ def test_course_not_configured(self):
+ self.course.video_upload_pipeline = {}
+ self.save_course()
+ self.assertEqual(self.client.get(self.url).status_code, 404)
+
+
+class VideoUploadPostTestsMixin:
+ """
+ Shared test cases for video post tests.
+ """
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ def test_post_success(self, mock_boto3_resource):
+ files = [
+ {
+ 'file_name': 'first.mp4',
+ 'content_type': 'video/mp4',
+ },
+ {
+ 'file_name': 'second.mp4',
+ 'content_type': 'video/mp4',
+ },
+ {
+ 'file_name': 'third.mov',
+ 'content_type': 'video/quicktime',
+ },
+ {
+ 'file_name': 'fourth.mp4',
+ 'content_type': 'video/mp4',
+ },
+ ]
+
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Mock generate_presigned_url to return different URLs for each file
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ response = self.client.post(
+ self.url,
+ json.dumps({'files': files}),
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 200)
+ response_obj = json.loads(response.content.decode('utf-8'))
+
+ # Verify boto3 resource was called correctly
+ mock_boto3_resource.assert_called_once_with(
+ "s3",
+ aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
+ aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY
+ )
+
+ self.assertEqual(len(response_obj['files']), len(files))
+ self.assertEqual(mock_s3_client.generate_presigned_url.call_count, len(files))
+
+ for i, file_info in enumerate(files):
+ # Get the call args for this file's presigned URL generation
+ call_args = mock_s3_client.generate_presigned_url.call_args_list[i]
+ args, kwargs = call_args
+
+ # Verify the operation and params
+ self.assertEqual(args[0], 'put_object')
+ self.assertEqual(kwargs['Params']['Bucket'], 'test-bucket')
+ self.assertEqual(kwargs['Params']['ContentType'], file_info['content_type'])
+ self.assertEqual(kwargs['ExpiresIn'], KEY_EXPIRATION_IN_SECONDS)
+
+ # Extract video_id from the key
+ key_name = kwargs['Params']['Key']
+ path_match = re.match(
+ (
+ settings.VIDEO_UPLOAD_PIPELINE['ROOT_PATH'] +
+ '/([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12})$'
+ ),
+ key_name
+ )
+ self.assertIsNotNone(path_match)
+ video_id = path_match.group(1)
+
+ # Verify metadata
+ metadata = kwargs['Params']['Metadata']
+ self.assertEqual(metadata['course_video_upload_token'], self.test_token)
+ self.assertEqual(metadata['client_video_id'], file_info['file_name'])
+ self.assertEqual(metadata['course_key'], str(self.course.id))
+
+ # Ensure VAL was updated
+ val_info = get_video_info(video_id)
+ self.assertEqual(val_info['status'], 'upload')
+ self.assertEqual(val_info['client_video_id'], file_info['file_name'])
+ self.assertEqual(val_info['duration'], 0)
+ self.assertEqual(val_info['courses'], [{str(self.course.id): None}])
+
+ # Ensure response is correct
+ response_file = response_obj['files'][i]
+ self.assertEqual(response_file['file_name'], file_info['file_name'])
+ self.assertEqual(response_file['upload_url'], f'http://example.com/url_{file_info["file_name"]}')
+
+ def test_post_non_json(self):
+ response = self.client.post(self.url, {"files": []})
+ self.assertEqual(response.status_code, 400)
+
+ def test_post_malformed_json(self):
+ response = self.client.post(self.url, "{", content_type="application/json")
+ self.assertEqual(response.status_code, 400)
+
+ def test_post_invalid_json(self):
+ def assert_bad(content):
+ """Make request with content and assert that response is 400"""
+ response = self.client.post(
+ self.url,
+ json.dumps(content),
+ content_type="application/json"
+ )
+ self.assertEqual(response.status_code, 400)
+
+ # Top level missing files key
+ assert_bad({})
+
+ # Entry missing file_name
+ assert_bad({"files": [{"content_type": "video/mp4"}]})
+
+ # Entry missing content_type
+ assert_bad({"files": [{"file_name": "test.mp4"}]})
+
+
+@ddt.ddt
+@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
+@override_settings(VIDEO_UPLOAD_PIPELINE={
+ "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
+})
+class VideosHandlerTestCase(
+ VideoUploadTestBase,
+ VideoStudioAccessTestsMixin,
+ VideoPipelineStudioAccessTestsMixin,
+ VideoUploadPostTestsMixin,
+ CourseTestCase
+):
+ """Test cases for the main video upload endpoint"""
+
+ VIEW_NAME = 'videos_handler'
+
+ def test_get_json(self):
+ response = self.client.get_json(self.url)
+ self.assertEqual(response.status_code, 200)
+ response_videos = json.loads(response.content.decode('utf-8'))['videos']
+ self.assertEqual(len(response_videos), len(self.previous_uploads))
+ for i, response_video in enumerate(response_videos):
+ # Videos should be returned by creation date descending
+ original_video = self.previous_uploads[-(i + 1)]
+ print(response_video.keys())
+ self.assertEqual(
+ set(response_video.keys()),
+ {
+ 'edx_video_id',
+ 'client_video_id',
+ 'created',
+ 'duration',
+ 'status',
+ 'status_nontranslated',
+ 'course_video_image_url',
+ 'file_size',
+ 'download_link',
+ 'transcripts',
+ 'transcription_status',
+ 'transcript_urls',
+ 'error_description',
+ }
+ )
+ dateutil.parser.parse(response_video['created'])
+ for field in ['edx_video_id', 'client_video_id', 'duration']:
+ self.assertEqual(response_video[field], original_video[field])
+ self.assertEqual(
+ response_video['status'],
+ convert_video_status(original_video)
+ )
+
+ @ddt.data(
+ (
+ [
+ 'edx_video_id', 'client_video_id', 'created', 'duration',
+ 'status', 'status_nontranslated', 'course_video_image_url', 'file_size',
+ 'download_link', 'transcripts', 'transcription_status', 'transcript_urls',
+ 'error_description'
+ ],
+ [
+ {
+ 'video_id': 'test1',
+ 'language_code': 'en',
+ 'file_name': 'edx101.srt',
+ 'file_format': 'srt',
+ 'provider': 'Cielo24'
+ }
+ ],
+ ['en']
+ ),
+ (
+ [
+ 'edx_video_id', 'client_video_id', 'created', 'duration',
+ 'status', 'status_nontranslated', 'course_video_image_url', 'file_size',
+ 'download_link', 'transcripts', 'transcription_status', 'transcript_urls',
+ 'error_description'
+ ],
+ [
+ {
+ 'video_id': 'test1',
+ 'language_code': 'en',
+ 'file_name': 'edx101_en.srt',
+ 'file_format': 'srt',
+ 'provider': 'Cielo24'
+ },
+ {
+ 'video_id': 'test1',
+ 'language_code': 'es',
+ 'file_name': 'edx101_es.srt',
+ 'file_format': 'srt',
+ 'provider': 'Cielo24'
+ }
+ ],
+ ['en', 'es']
+ )
+ )
+ @ddt.unpack
+ def test_get_json_transcripts(self, expected_video_keys, uploaded_transcripts, expected_transcripts):
+ """
+ Test that transcripts are attached based on whether the video transcript feature is enabled.
+ """
+ for transcript in uploaded_transcripts:
+ create_or_update_video_transcript(
+ transcript['video_id'],
+ transcript['language_code'],
+ metadata={
+ 'file_name': transcript['file_name'],
+ 'file_format': transcript['file_format'],
+ 'provider': transcript['provider']
+ }
+ )
+
+ response = self.client.get_json(self.url)
+ self.assertEqual(response.status_code, 200)
+ response_videos = json.loads(response.content.decode('utf-8'))['videos']
+ self.assertEqual(len(response_videos), len(self.previous_uploads))
+ for response_video in response_videos:
+ print(response_video)
+
+ self.assertEqual(set(response_video.keys()), set(expected_video_keys))
+ if response_video['edx_video_id'] == self.previous_uploads[0]['edx_video_id']:
+ self.assertEqual(response_video.get('transcripts', []), expected_transcripts)
+
+ def test_get_redirects_to_video_uploads_url(self):
+ """
+ Test that GET requests redirect to the MFE video uploads page.
+ """
+ from cms.djangoapps.contentstore.utils import get_video_uploads_url
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response.url, get_video_uploads_url(self.course.id))
+
+ @override_settings(AWS_ACCESS_KEY_ID="test_key_id", AWS_SECRET_ACCESS_KEY="test_secret")
+ @patch("cms.djangoapps.contentstore.video_storage_handlers.boto3.resource")
+ @ddt.data(
+ (
+ [
+ {
+ "file_name": "supported-1.mp4",
+ "content_type": "video/mp4",
+ },
+ {
+ "file_name": "supported-2.mov",
+ "content_type": "video/quicktime",
+ },
+ ],
+ 200
+ ),
+ (
+ [
+ {
+ "file_name": "unsupported-1.txt",
+ "content_type": "text/plain",
+ },
+ {
+ "file_name": "unsupported-2.png",
+ "content_type": "image/png",
+ },
+ ],
+ 400
+ )
+ )
+ @ddt.unpack
+ def test_video_supported_file_formats(self, files, expected_status, mock_boto3_resource):
+ """
+ Test that video upload works correctly against supported and unsupported file formats.
+ """
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Mock generate_presigned_url to return different URLs for each file
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ # Check supported formats
+ response = self.client.post(
+ self.url,
+ json.dumps({"files": files}),
+ content_type="application/json"
+ )
+ self.assertEqual(response.status_code, expected_status)
+ response = json.loads(response.content.decode('utf-8'))
+
+ if expected_status == 200:
+ self.assertNotIn('error', response)
+ else:
+ self.assertIn('error', response)
+ self.assertEqual(response['error'], "Request 'files' entry contain unsupported content_type")
+
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ def test_upload_with_non_ascii_charaters(self, mock_boto3_resource):
+ """
+ Test that video uploads throws error message when file name contains special characters.
+ """
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ file_name = 'test\u2019_file.mp4'
+ files = [{'file_name': file_name, 'content_type': 'video/mp4'}]
+
+ response = self.client.post(
+ self.url,
+ json.dumps({'files': files}),
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 400)
+ response = json.loads(response.content.decode('utf-8'))
+ self.assertEqual(response['error'], 'The file name for %s must contain only ASCII characters.' % file_name)
+
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret', AWS_SECURITY_TOKEN='token')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ @override_waffle_flag(ENABLE_DEVSTACK_VIDEO_UPLOADS, active=True)
+ def test_devstack_upload_connection(self, mock_boto3_resource):
+ files = [{'file_name': 'first.mp4', 'content_type': 'video/mp4'}]
+
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Mock generate_presigned_url to return different URLs for each file
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ response = self.client.post(
+ self.url,
+ json.dumps({'files': files}),
+ content_type='application/json'
+ )
+
+ self.assertEqual(response.status_code, 200)
+ mock_boto3_resource.assert_called_once_with(
+ "s3",
+ aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
+ aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
+ security_token=settings.AWS_SECURITY_TOKEN
+ )
+
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ def test_send_course_to_vem_pipeline(self, mock_boto3_resource):
+ """
+ Test that uploads always go to VEM S3 bucket by default.
+ """
+ files = [{'file_name': 'first.mp4', 'content_type': 'video/mp4'}]
+
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Mock generate_presigned_url to return different URLs for each file
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ response = self.client.post(
+ self.url,
+ json.dumps({'files': files}),
+ content_type='application/json'
+ )
+
+ self.assertEqual(response.status_code, 200)
+ mock_s3_resource.Bucket.assert_called_once_with(
+ settings.VIDEO_UPLOAD_PIPELINE['VEM_S3_BUCKET'] # pylint: disable=unsubscriptable-object
+ )
+
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ @ddt.data(
+ {
+ 'global_waffle': True,
+ 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.off,
+ 'expect_token': True
+ },
+ {
+ 'global_waffle': False,
+ 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.on,
+ 'expect_token': False
+ },
+ {
+ 'global_waffle': False,
+ 'course_override': WaffleFlagCourseOverrideModel.ALL_CHOICES.off,
+ 'expect_token': True
+ }
+ )
+ def test_video_upload_token_in_meta(self, data, mock_boto3_resource):
+ """
+ Test video upload token in s3 metadata.
+ """
+ @contextmanager
+ def proxy_manager(manager, ignore_manager):
+ """
+ This acts as proxy to the original manager in the arguments given
+ the original manager is not set to be ignored.
+ """
+ if ignore_manager:
+ yield
+ else:
+ with manager:
+ yield
+
+ file_data = {
+ 'file_name': 'first.mp4',
+ 'content_type': 'video/mp4',
+ }
+
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Track generate_presigned_url calls to inspect metadata
+ presigned_url_calls = []
+
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ presigned_url_calls.append((operation, Params, ExpiresIn))
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ with patch.object(WaffleFlagCourseOverrideModel, 'override_value', return_value=data['course_override']):
+ with override_waffle_flag(DEPRECATE_YOUTUBE, active=data['global_waffle']):
+ response = self.client.post(
+ self.url,
+ json.dumps({'files': [file_data]}),
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 200)
+
+ # Check if course_video_upload_token is in metadata based on expectation
+ if data['expect_token']:
+ # We should find the token in the metadata
+ self.assertEqual(len(presigned_url_calls), 1)
+ metadata = presigned_url_calls[0][1]['Metadata']
+ self.assertIn('course_video_upload_token', metadata)
+ self.assertEqual(metadata['course_video_upload_token'], self.test_token)
+ else:
+ # If we don't expect a token, verify it's not in metadata
+ if presigned_url_calls:
+ metadata = presigned_url_calls[0][1]['Metadata']
+ self.assertNotIn('course_video_upload_token', metadata)
+
+ def _assert_video_removal(self, url, edx_video_id, deleted_videos):
+ """
+ Verify that if correct video is removed from a particular course.
+
+ Arguments:
+ url (str): URL to get uploaded videos
+ edx_video_id (str): video id
+ deleted_videos (int): how many videos are deleted
+ """
+ response = self.client.get_json(url)
+ self.assertEqual(response.status_code, 200)
+ response_videos = json.loads(response.content.decode('utf-8'))["videos"]
+ self.assertEqual(len(response_videos), len(self.previous_uploads) - deleted_videos)
+
+ if deleted_videos:
+ self.assertNotIn(edx_video_id, [video.get('edx_video_id') for video in response_videos])
+ else:
+ self.assertIn(edx_video_id, [video.get('edx_video_id') for video in response_videos])
+
+ def test_video_removal(self):
+ """
+ Verifies that video removal is working as expected.
+ """
+ edx_video_id = 'test1'
+ remove_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
+ response = self.client.delete(remove_url, HTTP_ACCEPT="application/json")
+ self.assertEqual(response.status_code, 204)
+
+ self._assert_video_removal(self.url, edx_video_id, 1)
+
+ def test_video_removal_multiple_courses(self):
+ """
+ Verifies that video removal is working as expected for multiple courses.
+
+ If a video is used by multiple courses then removal from one course shouldn't effect the other course.
+ """
+ # remove video from course1
+ edx_video_id = 'test1'
+ remove_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
+ response = self.client.delete(remove_url, HTTP_ACCEPT="application/json")
+ self.assertEqual(response.status_code, 204)
+
+ # verify that video is only deleted from course1 only
+ self._assert_video_removal(self.url, edx_video_id, 1)
+ self._assert_video_removal(self.get_url_for_course_key(self.course2.id), edx_video_id, 0)
+
+ def test_convert_video_status(self):
+ """
+ Verifies that convert_video_status works as expected.
+ """
+ video = self.previous_uploads[0]
+
+ # video status should be failed if it's in upload state for more than 24 hours
+ video['created'] = datetime(2016, 1, 1, 10, 10, 10, 0, pytz.UTC)
+ status = convert_video_status(video)
+ self.assertEqual(status, StatusDisplayStrings.get('upload_failed'))
+
+ # `invalid_token` should be converted to `youtube_duplicate`
+ video['created'] = datetime.now(pytz.UTC)
+ video['status'] = 'invalid_token'
+ status = convert_video_status(video)
+ self.assertEqual(status, StatusDisplayStrings.get('youtube_duplicate'))
+
+ # The "encode status" should be converted to `file_complete` if video encodes are complete
+ video['status'] = 'transcription_in_progress'
+ status = convert_video_status(video, is_video_encodes_ready=True)
+ self.assertEqual(status, StatusDisplayStrings.get('file_complete'))
+
+ # If encoding is not complete return the status as it is
+ video['status'] = 's3_upload_failed'
+ status = convert_video_status(video)
+ self.assertEqual(status, StatusDisplayStrings.get('s3_upload_failed'))
+
+ # for all other status, there should not be any conversion
+ statuses = list(StatusDisplayStrings._STATUS_MAP.keys()) # pylint: disable=protected-access
+ statuses.remove('invalid_token')
+ for status in statuses:
+ video['status'] = status
+ new_status = convert_video_status(video)
+ self.assertEqual(new_status, StatusDisplayStrings.get(status))
+
+ def assert_video_status(self, url, edx_video_id, status):
+ """
+ Verifies that video with `edx_video_id` has `status`
+ """
+ response = self.client.get_json(url)
+ self.assertEqual(response.status_code, 200)
+ videos = json.loads(response.content.decode('utf-8'))["videos"]
+ for video in videos:
+ if video['edx_video_id'] == edx_video_id:
+ return self.assertEqual(video['status'], status)
+
+ # Test should fail if video not found
+ self.assertEqual(True, False, 'Invalid edx_video_id')
+
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.LOGGER')
+ def test_video_status_update_request(self, mock_logger):
+ """
+ Verifies that video status update request works as expected.
+ """
+ url = self.get_url_for_course_key(self.course.id)
+ edx_video_id = 'test1'
+ self.assert_video_status(url, edx_video_id, 'Uploading')
+
+ response = self.client.post(
+ url,
+ json.dumps([{
+ 'edxVideoId': edx_video_id,
+ 'status': 'upload_failed',
+ 'message': 'server down'
+ }]),
+ content_type="application/json"
+ )
+
+ mock_logger.info.assert_called_with(
+ 'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
+ edx_video_id,
+ 'upload_failed',
+ 'server down'
+ )
+
+ self.assertEqual(response.status_code, 204)
+
+ self.assert_video_status(url, edx_video_id, 'Failed')
+
+ @ddt.data(
+ ('test_video_token', "Transcription in Progress"),
+ ('', "Ready"),
+ )
+ @ddt.unpack
+ def test_video_transcript_status_conversion(self, course_video_upload_token, expected_video_status_text):
+ """
+ Verifies that video status `transcription_in_progress` gets converted
+ correctly into the `file_complete` for the new video workflow and
+ stays as it is, for the old video workflow.
+ """
+ self.course.video_upload_pipeline = {
+ 'course_video_upload_token': course_video_upload_token
+ }
+ self.save_course()
+
+ url = self.get_url_for_course_key(self.course.id)
+ edx_video_id = 'test1'
+ self.assert_video_status(url, edx_video_id, 'Uploading')
+
+ response = self.client.post(
+ url,
+ json.dumps([{
+ 'edxVideoId': edx_video_id,
+ 'status': 'transcription_in_progress',
+ 'message': 'Transcription is in progress'
+ }]),
+ content_type="application/json"
+ )
+ self.assertEqual(response.status_code, 204)
+
+ self.assert_video_status(url, edx_video_id, expected_video_status_text)
+
+
+@ddt.ddt
+@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
+@override_settings(VIDEO_UPLOAD_PIPELINE={
+ "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
+})
+class GenerateVideoUploadLinkTestCase(
+ VideoUploadTestBase,
+ VideoUploadPostTestsMixin,
+ CourseTestCase
+):
+ """
+ Test cases for the main video upload endpoint
+ """
+
+ VIEW_NAME = 'generate_video_upload_link'
+
+ def test_unsupported_requests_fail(self):
+ """
+ The API only supports post, make sure other requests fail
+ """
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 405)
+
+ response = self.client.put(self.url)
+ self.assertEqual(response.status_code, 405)
+
+ response = self.client.patch(self.url)
+ self.assertEqual(response.status_code, 405)
+
+
+@ddt.ddt
+@patch.dict('django.conf.settings.FEATURES', {'ENABLE_VIDEO_UPLOAD_PIPELINE': True})
+@override_settings(VIDEO_UPLOAD_PIPELINE={'BUCKET': 'test_bucket', 'ROOT_PATH': 'test_root'})
+class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
+ """
+ Tests for video image.
+ """
+
+ VIEW_NAME = "video_images_handler"
+
+ def verify_image_upload_reponse(self, course_id, edx_video_id, upload_response):
+ """
+ Verify that image is uploaded successfully.
+
+ Arguments:
+ course_id: ID of course
+ edx_video_id: ID of video
+ upload_response: Upload response object
+
+ Returns:
+ uploaded image url
+ """
+ self.assertEqual(upload_response.status_code, 200)
+ response = json.loads(upload_response.content.decode('utf-8'))
+ val_image_url = get_course_video_image_url(course_id=course_id, edx_video_id=edx_video_id)
+ self.assertEqual(response['image_url'], val_image_url)
+
+ return val_image_url
+
+ def verify_error_message(self, response, error_message):
+ """
+ Verify that image upload failure gets proper error message.
+
+ Arguments:
+ response: Response object.
+ error_message: Expected error message.
+ """
+ self.assertEqual(response.status_code, 400)
+ response = json.loads(response.content.decode('utf-8'))
+ self.assertIn('error', response)
+ self.assertEqual(response['error'], error_message)
+
+ @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, False)
+ def test_video_image_upload_disabled(self):
+ """
+ Tests the video image upload when the feature is disabled.
+ """
+ video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': 'test_vid_id'})
+ response = self.client.post(video_image_upload_url, {'file': 'dummy_file'}, format='multipart')
+ self.assertEqual(response.status_code, 404)
+
+ @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
+ def test_video_image(self):
+ """
+ Test video image is saved.
+ """
+ edx_video_id = 'test1'
+ video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
+ with make_image_file(
+ dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
+ ) as image_file:
+ response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
+ image_url1 = self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
+
+ # upload again to verify that new image is uploaded successfully
+ with make_image_file(
+ dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
+ ) as image_file:
+ response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
+ image_url2 = self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
+
+ self.assertNotEqual(image_url1, image_url2)
+
+ @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
+ def test_video_image_no_file(self):
+ """
+ Test that an error error message is returned if upload request is incorrect.
+ """
+ video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': 'test1'})
+ response = self.client.post(video_image_upload_url, {})
+ self.verify_error_message(response, 'An image file is required.')
+
+ @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
+ def test_no_video_image(self):
+ """
+ Test image url is set to None if no video image.
+ """
+ edx_video_id = 'test1'
+ get_videos_url = reverse_course_url('videos_handler', self.course.id)
+ video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
+ with make_image_file(
+ dimensions=(settings.VIDEO_IMAGE_MIN_WIDTH, settings.VIDEO_IMAGE_MIN_HEIGHT),
+ ) as image_file:
+ self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
+
+ val_image_url = get_course_video_image_url(course_id=self.course.id, edx_video_id=edx_video_id)
+
+ response = self.client.get_json(get_videos_url)
+ self.assertEqual(response.status_code, 200)
+ response_videos = json.loads(response.content.decode('utf-8'))["videos"]
+ for response_video in response_videos:
+ if response_video['edx_video_id'] == edx_video_id:
+ self.assertEqual(response_video['course_video_image_url'], val_image_url)
+ else:
+ self.assertEqual(response_video['course_video_image_url'], None)
+
+ @ddt.data(
+ # Image file type validation
+ (
+ {
+ 'extension': '.png'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.gif'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.bmp'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.jpg'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.jpeg'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.PNG'
+ },
+ None
+ ),
+ (
+ {
+ 'extension': '.tiff'
+ },
+ 'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
+ supported_file_formats=list(settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys())
+ )
+ ),
+ # Image file size validation
+ (
+ {
+ 'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MAX_BYTES'] + 10
+ },
+ 'This image file must be smaller than {image_max_size}.'.format(
+ image_max_size=settings.VIDEO_IMAGE_MAX_FILE_SIZE_MB
+ )
+ ),
+ (
+ {
+ 'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES'] - 10
+ },
+ 'This image file must be larger than {image_min_size}.'.format(
+ image_min_size=settings.VIDEO_IMAGE_MIN_FILE_SIZE_KB
+ )
+ ),
+ # Image file minimum width / height
+ (
+ {
+ 'width': 16, # 16x9
+ 'height': 9
+ },
+ 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long
+ image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
+ image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
+ image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
+ image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
+ )
+ ),
+ (
+ {
+ 'width': settings.VIDEO_IMAGE_MIN_WIDTH - 10,
+ 'height': settings.VIDEO_IMAGE_MIN_HEIGHT
+ },
+ 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format( # lint-amnesty, pylint: disable=line-too-long
+ image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
+ image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
+ image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
+ image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
+ )
+ ),
+ (
+ {
+ 'width': settings.VIDEO_IMAGE_MIN_WIDTH,
+ 'height': settings.VIDEO_IMAGE_MIN_HEIGHT - 10
+ },
+ (
+ 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
+ 'The minimum resolution is {image_file_min_width}x{image_file_min_height}.'
+ ).format(
+ image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
+ image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
+ image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
+ image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
+ )
+ ),
+ (
+ {
+ 'width': 1200, # not 16:9, but width/height check first.
+ 'height': 100
+ },
+ (
+ 'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
+ 'The minimum resolution is {image_file_min_width}x{image_file_min_height}.'
+ ).format(
+ image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
+ image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
+ image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
+ image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
+ )
+ ),
+ # Image file aspect ratio validation
+ (
+ {
+ 'width': settings.VIDEO_IMAGE_MAX_WIDTH, # 1280x720
+ 'height': settings.VIDEO_IMAGE_MAX_HEIGHT
+ },
+ None
+ ),
+ (
+ {
+ 'width': 850, # 16:9
+ 'height': 478
+ },
+ None
+ ),
+ (
+ {
+ 'width': 940, # 1.67 ratio, applicable aspect ratio margin of .01
+ 'height': 560
+ },
+ None
+ ),
+ (
+ {
+ 'width': settings.VIDEO_IMAGE_MIN_WIDTH + 100,
+ 'height': settings.VIDEO_IMAGE_MIN_HEIGHT + 200
+ },
+ 'This image file must have an aspect ratio of {video_image_aspect_ratio_text}.'.format(
+ video_image_aspect_ratio_text=settings.VIDEO_IMAGE_ASPECT_RATIO_TEXT
+ )
+ ),
+ # Image file name validation
+ (
+ {
+ 'prefix': 'nøn-åßç¡¡'
+ },
+ 'The image file name can only contain letters, numbers, hyphens (-), and underscores (_).'
+ )
+ )
+ @ddt.unpack
+ @override_waffle_switch(VIDEO_IMAGE_UPLOAD_ENABLED, True)
+ def test_video_image_validation_message(self, image_data, error_message):
+ """
+ Test video image validation gives proper error message.
+
+ Arguments:
+ image_data (Dict): Specific data to create image file.
+ error_message (String): Error message
+ """
+ edx_video_id = 'test1'
+ video_image_upload_url = self.get_url_for_course_key(self.course.id, {'edx_video_id': edx_video_id})
+ with make_image_file(
+ dimensions=(
+ image_data.get('width', settings.VIDEO_IMAGE_MIN_WIDTH),
+ image_data.get('height', settings.VIDEO_IMAGE_MIN_HEIGHT)
+ ),
+ prefix=image_data.get('prefix', 'videoimage'),
+ extension=image_data.get('extension', '.png'),
+ force_size=image_data.get('size', settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES'])
+ ) as image_file:
+ response = self.client.post(video_image_upload_url, {'file': image_file}, format='multipart')
+ if error_message:
+ self.verify_error_message(response, error_message)
+ else:
+ self.verify_image_upload_reponse(self.course.id, edx_video_id, response)
+
+
+@ddt.ddt
+@patch(
+ 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled',
+ Mock(return_value=True)
+)
+@patch.dict('django.conf.settings.FEATURES', {'ENABLE_VIDEO_UPLOAD_PIPELINE': True})
+class TranscriptPreferencesTestCase(VideoUploadTestBase, CourseTestCase):
+ """
+ Tests for video transcripts preferences.
+ """
+
+ VIEW_NAME = 'transcript_preferences_handler'
+
+ def test_405_with_not_allowed_request_method(self):
+ """
+ Verify that 405 is returned in case of not-allowed request methods.
+ Allowed request methods are POST and DELETE.
+ """
+ video_transcript_url = self.get_url_for_course_key(self.course.id)
+ response = self.client.get(
+ video_transcript_url,
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 405)
+
+ @ddt.data(
+ # Video transcript feature disabled
+ (
+ {},
+ False,
+ '',
+ 404,
+ ),
+ # Error cases
+ (
+ {},
+ True,
+ "Invalid provider None.",
+ 400
+ ),
+ (
+ {
+ 'provider': ''
+ },
+ True,
+ "Invalid provider .",
+ 400
+ ),
+ (
+ {
+ 'provider': 'dummy-provider'
+ },
+ True,
+ "Invalid provider dummy-provider.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24
+ },
+ True,
+ "Invalid cielo24 fidelity None.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ },
+ True,
+ "Invalid cielo24 turnaround None.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ 'cielo24_turnaround': 'STANDARD',
+ 'video_source_language': 'en'
+ },
+ True,
+ "Invalid languages [].",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PREMIUM',
+ 'cielo24_turnaround': 'STANDARD',
+ 'video_source_language': 'es'
+ },
+ True,
+ "Unsupported source language es.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ 'cielo24_turnaround': 'STANDARD',
+ 'video_source_language': 'en',
+ 'preferred_languages': ['es', 'ur']
+ },
+ True,
+ "Invalid languages ['es', 'ur'].",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.THREE_PLAY_MEDIA
+ },
+ True,
+ "Invalid 3play turnaround None.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
+ 'three_play_turnaround': 'standard',
+ 'video_source_language': 'zh',
+ },
+ True,
+ "Unsupported source language zh.",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
+ 'three_play_turnaround': 'standard',
+ 'video_source_language': 'es',
+ 'preferred_languages': ['es', 'ur']
+ },
+ True,
+ "Invalid languages ['es', 'ur'].",
+ 400
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
+ 'three_play_turnaround': 'standard',
+ 'video_source_language': 'en',
+ 'preferred_languages': ['es', 'ur']
+ },
+ True,
+ "Invalid languages ['es', 'ur'].",
+ 400
+ ),
+ # Success
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ 'cielo24_turnaround': 'STANDARD',
+ 'video_source_language': 'es',
+ 'preferred_languages': ['en']
+ },
+ True,
+ '',
+ 200
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.THREE_PLAY_MEDIA,
+ 'three_play_turnaround': 'standard',
+ 'preferred_languages': ['en'],
+ 'video_source_language': 'en',
+ },
+ True,
+ '',
+ 200
+ )
+ )
+ @ddt.unpack
+ def test_video_transcript(self, preferences, is_video_transcript_enabled, error_message, expected_status_code):
+ """
+ Tests that transcript handler works correctly.
+ """
+ video_transcript_url = self.get_url_for_course_key(self.course.id)
+ preferences_data = {
+ 'provider': preferences.get('provider'),
+ 'cielo24_fidelity': preferences.get('cielo24_fidelity'),
+ 'cielo24_turnaround': preferences.get('cielo24_turnaround'),
+ 'three_play_turnaround': preferences.get('three_play_turnaround'),
+ 'preferred_languages': preferences.get('preferred_languages', []),
+ 'video_source_language': preferences.get('video_source_language'),
+ }
+
+ with patch(
+ 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
+ ) as video_transcript_feature:
+ video_transcript_feature.return_value = is_video_transcript_enabled
+ response = self.client.post(
+ video_transcript_url,
+ json.dumps(preferences_data),
+ content_type='application/json'
+ )
+ status_code = response.status_code
+ response = json.loads(response.content.decode('utf-8')) if is_video_transcript_enabled else response
+
+ self.assertEqual(status_code, expected_status_code)
+ self.assertEqual(response.get('error', ''), error_message)
+
+ # Remove modified and course_id fields from the response so as to check the expected transcript preferences.
+ response.get('transcript_preferences', {}).pop('modified', None)
+ response.get('transcript_preferences', {}).pop('course_id', None)
+ expected_preferences = preferences_data if is_video_transcript_enabled and not error_message else {}
+ self.assertDictEqual(response.get('transcript_preferences', {}), expected_preferences)
+
+ def test_remove_transcript_preferences(self):
+ """
+ Test that transcript handler removes transcript preferences correctly.
+ """
+ # First add course wide transcript preferences.
+ preferences = create_or_update_transcript_preferences(str(self.course.id))
+
+ # Verify transcript preferences exist
+ self.assertIsNotNone(preferences)
+
+ response = self.client.delete(
+ self.get_url_for_course_key(self.course.id),
+ content_type='application/json'
+ )
+
+ self.assertEqual(response.status_code, 204)
+
+ # Verify transcript preferences no loger exist
+ preferences = get_transcript_preferences(str(self.course.id))
+ self.assertIsNone(preferences)
+
+ def test_remove_transcript_preferences_not_found(self):
+ """
+ Test that transcript handler works correctly even when no preferences are found.
+ """
+ course_id = 'course-v1:dummy+course+id'
+ # Verify transcript preferences do not exist
+ preferences = get_transcript_preferences(course_id)
+ self.assertIsNone(preferences)
+
+ response = self.client.delete(
+ self.get_url_for_course_key(course_id),
+ content_type='application/json'
+ )
+ self.assertEqual(response.status_code, 204)
+
+ # Verify transcript preferences do not exist
+ preferences = get_transcript_preferences(course_id)
+ self.assertIsNone(preferences)
+
+ @ddt.data(
+ (
+ None,
+ False
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ 'cielo24_turnaround': 'STANDARD',
+ 'preferred_languages': ['en']
+ },
+ False
+ ),
+ (
+ {
+ 'provider': TranscriptProvider.CIELO24,
+ 'cielo24_fidelity': 'PROFESSIONAL',
+ 'cielo24_turnaround': 'STANDARD',
+ 'preferred_languages': ['en']
+ },
+ True
+ )
+ )
+ @ddt.unpack
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.get_transcript_preferences')
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ def test_transcript_preferences_metadata(self, transcript_preferences, is_video_transcript_enabled,
+ mock_boto3_resource, mock_transcript_preferences):
+ """
+ Tests that transcript preference metadata is only set if it is video transcript feature is enabled and
+ transcript preferences are already stored in the system.
+ """
+ file_name = 'test-video.mp4'
+ request_data = {'files': [{'file_name': file_name, 'content_type': 'video/mp4'}]}
+
+ mock_transcript_preferences.return_value = transcript_preferences
+
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource)
+
+ # Track generate_presigned_url calls to inspect metadata
+ presigned_url_calls = []
+
+ def mock_generate_presigned_url(operation, Params=None, ExpiresIn=None):
+ presigned_url_calls.append((operation, Params, ExpiresIn))
+ file_name = Params['Metadata']['client_video_id']
+ return f'http://example.com/url_{file_name}'
+
+ mock_s3_client.generate_presigned_url.side_effect = mock_generate_presigned_url
+
+ videos_handler_url = reverse_course_url('videos_handler', self.course.id)
+ with patch(
+ 'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
+ ) as video_transcript_feature:
+ video_transcript_feature.return_value = is_video_transcript_enabled
+ response = self.client.post(videos_handler_url, json.dumps(request_data), content_type='application/json')
+
+ self.assertEqual(response.status_code, 200)
+
+ # Ensure `transcript_preferences` was set up in metadata correctly if sent through request.
+ if is_video_transcript_enabled and transcript_preferences:
+ self.assertEqual(len(presigned_url_calls), 1)
+ metadata = presigned_url_calls[0][1]['Metadata']
+ self.assertIn('transcript_preferences', metadata)
+ self.assertEqual(metadata['transcript_preferences'], json.dumps(transcript_preferences))
+ else:
+ # If conditions aren't met, verify transcript_preferences is not in metadata
+ if presigned_url_calls:
+ metadata = presigned_url_calls[0][1]['Metadata']
+ self.assertNotIn('transcript_preferences', metadata)
+
+
+@patch.dict("django.conf.settings.FEATURES", {"ENABLE_VIDEO_UPLOAD_PIPELINE": True})
+@override_settings(VIDEO_UPLOAD_PIPELINE={"BUCKET": "test_bucket", "ROOT_PATH": "test_root"})
+class VideoUrlsCsvTestCase(
+ VideoUploadTestBase,
+ VideoStudioAccessTestsMixin,
+ VideoPipelineStudioAccessTestsMixin,
+ CourseTestCase
+):
+ """Test cases for the CSV download endpoint for video uploads"""
+
+ VIEW_NAME = "video_encodings_download"
+
+ def setUp(self):
+ super().setUp()
+ VideoUploadConfig(profile_whitelist="profile1").save()
+
+ def _check_csv_response(self, expected_profiles):
+ """
+ Check that the response is a valid CSV response containing rows
+ corresponding to previous_uploads and including the expected profiles.
+ """
+ response = self.client.get(self.url)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(
+ response["Content-Disposition"],
+ f"attachment; filename=\"{self.course.id.course}_video_urls.csv\""
+ )
+ response_content = b"".join(response.streaming_content)
+ response_reader = StringIO(response_content.decode())
+ reader = csv.DictReader(response_reader, dialect=csv.excel)
+ self.assertEqual(
+ reader.fieldnames,
+ (
+ ["Name", "Duration", "Date Added", "Video ID", "Status"] +
+ [f"{profile} URL" for profile in expected_profiles]
+ )
+ )
+ rows = list(reader)
+ self.assertEqual(len(rows), len(self.previous_uploads))
+ for i, row in enumerate(rows):
+ response_video = dict(row.items())
+ # Videos should be returned by creation date descending
+ original_video = self.previous_uploads[-(i + 1)]
+ client_video_id = original_video["client_video_id"]
+ self.assertEqual(response_video["Name"], client_video_id)
+ self.assertEqual(response_video["Duration"], str(original_video["duration"]))
+ dateutil.parser.parse(response_video["Date Added"])
+ self.assertEqual(response_video["Video ID"], original_video["edx_video_id"])
+ self.assertEqual(response_video["Status"], convert_video_status(original_video))
+ for profile in expected_profiles:
+ response_profile_url = response_video[f"{profile} URL"]
+ original_encoded_for_profile = next(
+ (
+ original_encoded
+ for original_encoded in original_video["encoded_videos"]
+ if original_encoded["profile"] == profile
+ ),
+ None
+ )
+ if original_encoded_for_profile:
+ original_encoded_for_profile_url = original_encoded_for_profile["url"]
+ self.assertEqual(response_profile_url, original_encoded_for_profile_url)
+ else:
+ self.assertEqual(response_profile_url, "")
+
+ def test_basic(self):
+ self._check_csv_response(["profile1"])
+
+ def test_profile_whitelist(self):
+ VideoUploadConfig(profile_whitelist="profile1,profile2").save()
+ self._check_csv_response(["profile1", "profile2"])
+
+ def test_non_ascii_course(self):
+ course = CourseFactory.create(
+ number="nón-äscii",
+ video_upload_pipeline={
+ "course_video_upload_token": self.test_token,
+ }
+ )
+ response = self.client.get(self.get_url_for_course_key(course.id))
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(
+ response["Content-Disposition"],
+ "attachment; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
+ )
+
+
+@ddt.ddt
+class GetVideoFeaturesTestCase(
+ CourseTestCase
+):
+ """Test cases for the get_video_features endpoint """
+ def setUp(self):
+ super().setUp()
+ self.url = self.get_url_for_course_key()
+
+ def get_url_for_course_key(self):
+ """ Helper to generate a url for a course key """
+ return reverse("video_features")
+
+ def test_basic(self):
+ """ Test for expected return keys """
+ response = self.client.get(self.get_url_for_course_key())
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(
+ set(response.json().keys()),
+ {
+ 'videoSharingEnabled',
+ 'allowThumbnailUpload',
+ }
+ )
+
+ @ddt.data(True, False)
+ def test_video_share_enabled(self, is_enabled):
+ """ Test the public video share flag """
+ self._test_video_feature(
+ PUBLIC_VIDEO_SHARE,
+ 'videoSharingEnabled',
+ override_waffle_flag,
+ is_enabled,
+ )
+
+ @ddt.data(True, False)
+ def test_video_image_upload_enabled(self, is_enabled):
+ """ Test the video image upload switch """
+ self._test_video_feature(
+ VIDEO_IMAGE_UPLOAD_ENABLED,
+ 'allowThumbnailUpload',
+ override_waffle_switch,
+ is_enabled,
+ )
+
+ def _test_video_feature(self, flag, key, override_fn, is_enabled):
+ """ Test that setting a waffle flag or switch on or off will cause the expected result """
+ with override_fn(flag, is_enabled):
+ response = self.client.get(self.get_url_for_course_key())
+
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.json()[key], is_enabled)
+
+
+class GetStorageBucketTestCase(TestCase):
+ """ This test just check that connection works and returns the bucket.
+ It does not involve any mocking and triggers errors if has any import issue.
+ """
+ @override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
+ @override_settings(VIDEO_UPLOAD_PIPELINE={
+ "VEM_S3_BUCKET": "vem_test_bucket", "BUCKET": "test_bucket", "ROOT_PATH": "test_root"
+ })
+ @patch('cms.djangoapps.contentstore.video_storage_handlers.boto3.resource')
+ def test_storage_bucket(self, mock_boto3_resource):
+ """ Test that storage service functions work correctly with boto3."""
+ # Setup boto3 mocks
+ mock_s3_client, mock_bucket, mock_s3_resource = setup_s3_mocks(mock_boto3_resource, 'vem_test_bucket')
+
+ # Test storage_service_bucket function
+ bucket = storage_service_bucket()
+ self.assertEqual(bucket.name, 'vem_test_bucket')
+ mock_s3_resource.Bucket.assert_called_once_with('vem_test_bucket')
+
+ # Test storage_service_key function
+ edx_video_id = 'dummy_video'
+ key_name = storage_service_key(bucket, file_name=edx_video_id)
+ expected_key = 'test_root/dummy_video'
+ self.assertEqual(key_name, expected_key)
+
+ # Test that we can generate presigned URL using the bucket's client
+ mock_s3_client.generate_presigned_url.return_value = (
+ 'https://vem_test_bucket.s3.amazonaws.com:443/test_root/dummy_video?signature=test'
+ )
+ upload_url = mock_s3_client.generate_presigned_url(
+ 'put_object',
+ Params={
+ 'Bucket': bucket.name,
+ 'Key': key_name,
+ 'ContentType': 'video/mp4'
+ },
+ ExpiresIn=KEY_EXPIRATION_IN_SECONDS
+ )
+
+ self.assertIn("vem_test_bucket.s3.amazonaws.com", upload_url)
+ self.assertIn("test_root/dummy_video", upload_url)
+
+
+class CourseYoutubeEdxVideoIds(ModuleStoreTestCase):
+ """
+ This test checks youtube videos in a course
+ """
+ VIEW_NAME = 'youtube_edx_video_ids'
+
+ def setUp(self):
+ super().setUp()
+ self.course = CourseFactory.create()
+ self.course_with_no_youtube_videos = CourseFactory.create()
+ self.store = modulestore()
+ self.user = UserFactory()
+ self.client.login(username=self.user.username, password='Password1234')
+
+ def get_url_for_course_key(self, course_key, kwargs=None):
+ """Return video handler URL for the given course"""
+ return reverse_course_url(self.VIEW_NAME, course_key, kwargs) # lint-amnesty, pylint: disable=no-member
+
+ def test_course_with_youtube_videos(self):
+ course_key = self.course.id
+
+ with self.store.bulk_operations(course_key):
+ chapter_loc = self.store.create_child(
+ self.user.id, self.course.usage_key, 'chapter', 'test_chapter'
+ ).usage_key
+ seq_loc = self.store.create_child(
+ self.user.id, chapter_loc, 'sequential', 'test_seq'
+ ).usage_key
+ vert_loc = self.store.create_child(self.user.id, seq_loc, 'vertical', 'test_vert').usage_key
+ self.store.create_child(
+ self.user.id,
+ vert_loc,
+ 'problem',
+ 'test_problem',
+ fields={"data": "Test"}
+ )
+ self.store.create_child(
+ self.user.id, vert_loc, 'video', fields={
+ "youtube_is_available": False,
+ "name": "sample_video",
+ "edx_video_id": "youtube_193_84709099",
+ }
+ )
+
+ response = self.client.get(self.get_url_for_course_key(course_key))
+ self.assertEqual(response.status_code, 200)
+
+ edx_video_ids = json.loads(response.content.decode('utf-8'))['edx_video_ids']
+ self.assertEqual(len(edx_video_ids), 1)
+
+ def test_course_with_no_youtube_videos(self):
+ course_key = self.course_with_no_youtube_videos.id
+
+ with self.store.bulk_operations(course_key):
+ chapter_loc = self.store.create_child(
+ self.user.id, self.course_with_no_youtube_videos.usage_key, 'chapter', 'test_chapter'
+ ).usage_key
+ seq_loc = self.store.create_child(
+ self.user.id, chapter_loc, 'sequential', 'test_seq'
+ ).usage_key
+ vert_loc = self.store.create_child(self.user.id, seq_loc, 'vertical', 'test_vert').usage_key
+ self.store.create_child(
+ self.user.id, vert_loc, 'problem', 'test_problem', fields={"data": "Test"}
+ )
+ self.store.create_child(
+ self.user.id, vert_loc, 'video', fields={
+ "youtube_id_1_0": None,
+ "name": "sample_video",
+ "edx_video_id": "no_youtube_193_84709099",
+ }
+ )
+
+ response = self.client.get(self.get_url_for_course_key(course_key))
+
+ edx_video_ids = json.loads(response.content.decode('utf-8'))['edx_video_ids']
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(len(edx_video_ids), 0)
diff --git a/cms/djangoapps/contentstore/views/tests/utils.py b/cms/djangoapps/contentstore/views/tests/utils.py
index 979f8322e9b4..6a5fa4edba97 100644
--- a/cms/djangoapps/contentstore/views/tests/utils.py
+++ b/cms/djangoapps/contentstore/views/tests/utils.py
@@ -37,7 +37,7 @@ def get_preview_html(self, xblock, view_name):
"""
Returns the HTML for the xblock when shown within a unit or container page.
"""
- preview_url = f'/xblock/{xblock.location}/{view_name}'
+ preview_url = f'/xblock/{xblock.usage_key}/{view_name}'
resp = self.client.get_json(preview_url)
self.assertEqual(resp.status_code, 200)
resp_content = json.loads(resp.content.decode('utf-8'))
diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py
index 7d4eccf7000b..963bec3f0644 100644
--- a/cms/djangoapps/contentstore/views/transcripts_ajax.py
+++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py
@@ -379,7 +379,7 @@ def check_transcripts(request): # lint-amnesty, pylint: disable=too-many-statem
if not isinstance(item.usage_key, UsageKeyV2):
filename = f'subs_{item.sub}.srt.sjson'
- content_location = StaticContent.compute_location(item.location.course_key, filename)
+ content_location = StaticContent.compute_location(item.usage_key.course_key, filename)
try:
contentstore().find(content_location).data.decode('utf-8')
transcripts_presence['current_item_subs'] = item.sub
@@ -390,7 +390,7 @@ def check_transcripts(request): # lint-amnesty, pylint: disable=too-many-statem
html5_subs = []
for html5_id in videos['html5']:
filename = f'subs_{html5_id}.srt.sjson'
- content_location = StaticContent.compute_location(item.location.course_key, filename)
+ content_location = StaticContent.compute_location(item.usage_key.course_key, filename)
try:
html5_subs.append(contentstore().find(content_location).data)
transcripts_presence['html5_local'].append(html5_id)
@@ -419,7 +419,7 @@ def _check_youtube_transcripts(transcripts_presence, youtube_id, item):
if not isinstance(item.usage_key, UsageKeyV2):
# youtube local
filename = f'subs_{youtube_id}.srt.sjson'
- content_location = StaticContent.compute_location(item.location.course_key, filename)
+ content_location = StaticContent.compute_location(item.usage_key.course_key, filename)
try:
local_transcripts = contentstore().find(content_location).data.decode('utf-8')
transcripts_presence['youtube_local'] = True
@@ -601,7 +601,7 @@ def choose_transcripts(request):
video = validated_data['video']
chosen_html5_id = validated_data['chosen_html5_id']
input_format, __, transcript_content = get_transcript_for_video(
- video.location,
+ video.usage_key,
subs_id=chosen_html5_id,
file_name=chosen_html5_id,
language='en'
@@ -655,7 +655,7 @@ def rename_transcripts(request):
try:
video = validated_data['video']
input_format, __, transcript_content = get_transcript_for_video(
- video.location,
+ video.usage_key,
subs_id=video.sub,
file_name=video.sub,
language='en'
@@ -777,7 +777,7 @@ def _get_item(request, data):
item = modulestore().get_item(usage_key)
# use the item's course_key, because the usage_key might not have the run
- if not has_course_author_access(request.user, item.location.course_key):
+ if not has_course_author_access(request.user, item.usage_key.course_key):
raise PermissionDenied()
return item
diff --git a/cms/djangoapps/contentstore/xblock_storage_handlers/view_handlers.py b/cms/djangoapps/contentstore/xblock_storage_handlers/view_handlers.py
index 9a30807b60a3..66cd3c194f4e 100644
--- a/cms/djangoapps/contentstore/xblock_storage_handlers/view_handlers.py
+++ b/cms/djangoapps/contentstore/xblock_storage_handlers/view_handlers.py
@@ -443,13 +443,13 @@ def _save_xblock(
"""
store = modulestore()
# Perform all xblock changes within a (single-versioned) transaction
- with store.bulk_operations(xblock.location.course_key):
+ with store.bulk_operations(xblock.usage_key.course_key):
# Don't allow updating an xblock and discarding changes in a single operation (unsupported by UI).
if publish == "discard_changes":
- store.revert_to_published(xblock.location, user.id)
+ store.revert_to_published(xblock.usage_key, user.id)
# Returning the same sort of result that we do for other save operations. In the future,
# we may want to return the full XBlockInfo.
- return JsonResponse({"id": str(xblock.location)})
+ return JsonResponse({"id": str(xblock.usage_key)})
old_metadata = own_metadata(xblock)
old_content = xblock.get_explicitly_set_fields_by_scope(Scope.content)
@@ -501,7 +501,7 @@ def _save_xblock(
# this is error could occur in modulestores (such as Draft) that do not support atomic write-transactions
old_children = set(xblock.children) - set(children)
if any(
- store.get_parent_location(old_child) == xblock.location
+ store.get_parent_location(old_child) == xblock.usage_key
for old_child in old_children
):
# since children are moved as part of a single transaction, orphans should not be created
@@ -549,11 +549,11 @@ def _save_xblock(
xblock = save_xblock_with_callback(xblock, user, old_metadata, old_content)
# for static tabs, their containing course also records their display name
- course = store.get_course(xblock.location.course_key)
- if xblock.location.block_type == "static_tab":
+ course = store.get_course(xblock.usage_key.course_key)
+ if xblock.usage_key.block_type == "static_tab":
# find the course's reference to this tab and update the name.
static_tab = CourseTabList.get_tab_by_slug(
- course.tabs, xblock.location.name
+ course.tabs, xblock.usage_key.name
)
# only update if changed
if static_tab:
@@ -568,7 +568,7 @@ def _save_xblock(
store.update_item(course, user.id)
result = {
- "id": str(xblock.location),
+ "id": str(xblock.usage_key),
"data": data,
"metadata": own_metadata(xblock),
}
@@ -583,16 +583,16 @@ def _save_xblock(
if is_prereq is not None:
if is_prereq:
gating_api.add_prerequisite(
- xblock.location.course_key, xblock.location
+ xblock.usage_key.course_key, xblock.usage_key
)
else:
- gating_api.remove_prerequisite(xblock.location)
+ gating_api.remove_prerequisite(xblock.usage_key)
result["is_prereq"] = is_prereq
if prereq_usage_key is not None:
gating_api.set_required_content(
- xblock.location.course_key,
- xblock.location,
+ xblock.usage_key.course_key,
+ xblock.usage_key,
prereq_usage_key,
prereq_min_score,
prereq_min_completion,
@@ -607,11 +607,11 @@ def _save_xblock(
# Make public after updating the xblock, in case the caller asked for both an update and a publish.
if publish == "make_public":
- modulestore().publish(xblock.location, user.id)
+ modulestore().publish(xblock.usage_key, user.id)
# If summary_configuration_enabled is not None, use AIAsideSummary to update it.
if xblock.category == "vertical" and summary_configuration_enabled is not None:
- AiAsideSummaryConfig(course.id).set_summary_settings(xblock.location, {
+ AiAsideSummaryConfig(course.id).set_summary_settings(xblock.usage_key, {
'enabled': summary_configuration_enabled
})
@@ -761,8 +761,8 @@ def _create_block(request):
{"error": _("Your clipboard is empty or invalid.")}, status=400
)
return JsonResponse({
- "locator": str(created_xblock.location),
- "courseKey": str(created_xblock.location.course_key),
+ "locator": str(created_xblock.usage_key),
+ "courseKey": str(created_xblock.usage_key.course_key),
"static_file_notices": asdict(notices),
"upstreamRef": str(created_xblock.upstream),
})
@@ -795,8 +795,8 @@ def _create_block(request):
)
response = {
- "locator": str(created_block.location),
- "courseKey": str(created_block.location.course_key),
+ "locator": str(created_block.usage_key),
+ "courseKey": str(created_block.usage_key.course_key),
}
# If it contains library_content_key, the block is being imported from a v2 library
# so it needs to be synced with upstream block.
@@ -807,7 +807,7 @@ def _create_block(request):
store = modulestore()
static_file_notices = sync_library_content(created_block, request, store)
except BadUpstream as exc:
- _delete_item(created_block.location, request.user)
+ _delete_item(created_block.usage_key, request.user)
log.exception(
f"Could not sync to new block at '{created_block.usage_key}' "
f"using provided library_content_key='{upstream_ref}'"
@@ -850,7 +850,7 @@ def is_source_item_in_target_parents(source_item, target_parent):
"ancestors"
]
for target_ancestor in target_ancestors:
- if str(source_item.location) == target_ancestor["id"]:
+ if str(source_item.usage_key) == target_ancestor["id"]:
return True
return False
@@ -907,11 +907,11 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
target_parent_type=target_parent_type,
)
elif (
- source_parent.location == target_parent.location
- or source_item.location in target_parent.children
+ source_parent.usage_key == target_parent.usage_key
+ or source_item.usage_key in target_parent.children
):
error = _("Item is already present in target location.")
- elif source_item.location == target_parent.location:
+ elif source_item.usage_key == target_parent.usage_key:
error = _("You can not move an item into itself.")
elif is_source_item_in_target_parents(source_item, target_parent):
error = _("You can not move an item into it's child.")
@@ -920,7 +920,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
elif source_index is None:
error = _("{source_usage_key} not found in {parent_usage_key}.").format(
source_usage_key=str(source_usage_key),
- parent_usage_key=str(source_parent.location),
+ parent_usage_key=str(source_parent.usage_key),
)
else:
try:
@@ -948,9 +948,9 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
)
store.update_item_parent(
- item_location=source_item.location,
- new_parent_location=target_parent.location,
- old_parent_location=source_parent.location,
+ item_location=source_item.usage_key,
+ new_parent_location=target_parent.usage_key,
+ old_parent_location=source_parent.usage_key,
insert_at=insert_at,
user_id=user.id,
)
@@ -958,7 +958,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
log.info(
"MOVE: %s moved from %s to %s at %d index",
str(source_usage_key),
- str(source_parent.location),
+ str(source_parent.usage_key),
str(target_parent_usage_key),
insert_at,
)
@@ -1063,16 +1063,16 @@ def get_block_info(
metadata, data, id representation of a leaf block fetcher.
:param usage_key: A UsageKey
"""
- with modulestore().bulk_operations(xblock.location.course_key):
+ with modulestore().bulk_operations(xblock.usage_key.course_key):
data = getattr(xblock, "data", "")
if rewrite_static_links:
- data = replace_static_urls(data, None, course_id=xblock.location.course_key)
+ data = replace_static_urls(data, None, course_id=xblock.usage_key.course_key)
# Pre-cache has changes for the entire course because we'll need it for the ancestor info
# Except library blocks which don't [yet] use draft/publish
- if not isinstance(xblock.location, LibraryUsageLocator):
+ if not isinstance(xblock.usage_key, LibraryUsageLocator):
modulestore().has_changes(
- modulestore().get_course(xblock.location.course_key, depth=None)
+ modulestore().get_course(xblock.usage_key.course_key, depth=None)
)
# Note that children aren't being returned until we have a use case.
@@ -1107,17 +1107,17 @@ def _get_gating_info(course, xblock):
# Cache gating prerequisites on course block so that we are not
# hitting the database for every xblock in the course
course.gating_prerequisites = gating_api.get_prerequisites(course.id)
- info["is_prereq"] = gating_api.is_prerequisite(course.id, xblock.location)
+ info["is_prereq"] = gating_api.is_prerequisite(course.id, xblock.usage_key)
info["prereqs"] = [
p
for p in course.gating_prerequisites
- if str(xblock.location) not in p["namespace"]
+ if str(xblock.usage_key) not in p["namespace"]
]
(
prereq,
prereq_min_score,
prereq_min_completion,
- ) = gating_api.get_required_content(course.id, xblock.location)
+ ) = gating_api.get_required_content(course.id, xblock.usage_key)
info["prereq"] = prereq
info["prereq_min_score"] = prereq_min_score
info["prereq_min_completion"] = prereq_min_completion
@@ -1166,7 +1166,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
... xblock_info['icon'] = xblock.icon_override
... return xblock_info
"""
- is_library_block = isinstance(xblock.location, LibraryUsageLocator)
+ is_library_block = isinstance(xblock.usage_key, LibraryUsageLocator)
is_xblock_unit = is_unit(xblock, parent_xblock)
# this should not be calculated for Sections and Subsections on Unit page or for library blocks
has_changes = None
@@ -1175,7 +1175,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
if graders is None:
if not is_library_block:
- graders = CourseGradingModel.fetch(xblock.location.course_key).graders
+ graders = CourseGradingModel.fetch(xblock.usage_key.course_key).graders
else:
graders = []
@@ -1185,7 +1185,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
# We need to load the course in order to retrieve user partition information.
# For this reason, we load the course once and re-use it when recursively loading children.
if course is None:
- course = modulestore().get_course(xblock.location.course_key)
+ course = modulestore().get_course(xblock.usage_key.course_key)
# Compute the child info first so it can be included in aggregate information for the parent
should_visit_children = include_child_info and (
@@ -1193,7 +1193,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
)
if summary_configuration is None:
- summary_configuration = AiAsideSummaryConfig(xblock.location.course_key)
+ summary_configuration = AiAsideSummaryConfig(xblock.usage_key.course_key)
if should_visit_children and xblock.has_children:
child_info = _create_xblock_child_info(
@@ -1261,13 +1261,13 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
)
xblock_info = {
- "id": str(xblock.location),
+ "id": str(xblock.usage_key),
"display_name": xblock.display_name_with_default,
"category": xblock.category,
"has_children": xblock.has_children,
}
- if course is not None and PUBLIC_VIDEO_SHARE.is_enabled(xblock.location.course_key):
+ if course is not None and PUBLIC_VIDEO_SHARE.is_enabled(xblock.usage_key.course_key):
xblock_info.update(
{
"video_sharing_enabled": True,
@@ -1493,7 +1493,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
if not is_tagging_feature_disabled():
xblock_info["course_tags_count"] = _get_course_tags_count(course.id)
- xblock_info["tag_counts_by_block"] = _get_course_block_tags(xblock.location.context_key)
+ xblock_info["tag_counts_by_block"] = _get_course_block_tags(xblock.usage_key.context_key)
xblock_info[
"has_partition_group_components"
@@ -1556,7 +1556,7 @@ def _was_xblock_ever_exam_linked_with_external(course, xblock):
Returns: bool
"""
try:
- exam = get_exam_by_content_id(course.id, xblock.location)
+ exam = get_exam_by_content_id(course.id, xblock.usage_key)
return bool("external_id" in exam and exam["external_id"])
except ProctoredExamNotFoundException:
pass
diff --git a/cms/djangoapps/contentstore/xblock_storage_handlers/xblock_helpers.py b/cms/djangoapps/contentstore/xblock_storage_handlers/xblock_helpers.py
index 82ed7297d5af..3a01a367e05a 100644
--- a/cms/djangoapps/contentstore/xblock_storage_handlers/xblock_helpers.py
+++ b/cms/djangoapps/contentstore/xblock_storage_handlers/xblock_helpers.py
@@ -31,11 +31,11 @@ def get_tags_count(xblock: XBlock, include_children=False) -> dict[str, int]:
Use `include_children` to include each children on the query.
"""
- query_list = [str(xblock.location)]
+ query_list = [str(xblock.usage_key)]
if include_children:
children = xblock.get_children()
- child_usage_keys = [str(child.location) for child in children]
+ child_usage_keys = [str(child.usage_key) for child in children]
query_list.extend(child_usage_keys)
tags_count_query = ",".join(query_list)
diff --git a/cms/djangoapps/models/settings/course_grading.py b/cms/djangoapps/models/settings/course_grading.py
index e6a0e3690c5c..63e8533a5c7f 100644
--- a/cms/djangoapps/models/settings/course_grading.py
+++ b/cms/djangoapps/models/settings/course_grading.py
@@ -284,7 +284,7 @@ def update_section_grader_type(block, grader_type, user): # lint-amnesty, pylin
del block.graded
modulestore().update_item(block, user.id)
- _grading_event_and_signal(block.location.course_key, user.id)
+ _grading_event_and_signal(block.usage_key.course_key, user.id)
return {'graderType': grader_type}
@staticmethod
diff --git a/cms/djangoapps/modulestore_migrator/tests/test_tasks.py b/cms/djangoapps/modulestore_migrator/tests/test_tasks.py
index 1f95f9d4024d..3eac5072d34d 100644
--- a/cms/djangoapps/modulestore_migrator/tests/test_tasks.py
+++ b/cms/djangoapps/modulestore_migrator/tests/test_tasks.py
@@ -1058,7 +1058,7 @@ def test_migrate_from_modulestore_success_legacy_library(self):
"""
Test successful migration from legacy library to V2 library
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
@@ -1086,8 +1086,8 @@ def test_bulk_migrate_success_legacy_libraries(self):
"""
Test successful bulk migration from legacy libraries to V2 library
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
- source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
+ source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
@@ -1121,8 +1121,8 @@ def test_bulk_migrate_create_collections(self):
"""
Test successful bulk migration from legacy libraries to V2 library with create collections
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
- source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
+ source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.usage_key.library_key)
source_3 = ModulestoreSource.objects.create(key=self.course.id)
task = bulk_migrate_from_modulestore.apply_async(
@@ -1183,7 +1183,7 @@ def test_bulk_migrate_use_previous_collection_on_skip_and_update(self, repeat_ha
"""
Test successful bulk migration from legacy libraries to V2 library using previous collection
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
@@ -1245,7 +1245,7 @@ def test_bulk_migrate_create_collection_in_different_learning_packages(self, rep
"""
Test successful bulk migration from legacy libraries to different V2 libraries
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
@@ -1310,7 +1310,7 @@ def test_bulk_migrate_create_a_new_collection_on_fork(self):
"""
Test successful bulk migration from legacy libraries to V2 library using previous collection
"""
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
@@ -1564,8 +1564,8 @@ def test_bulk_migrate_fails_on_import(self, mock_import_assets):
Test failed bulk migration from legacy libraries to V2 library
"""
mock_import_assets.side_effect = Exception("Simulated import error")
- source = ModulestoreSource.objects.create(key=self.legacy_library.location.library_key)
- source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.location.library_key)
+ source = ModulestoreSource.objects.create(key=self.legacy_library.usage_key.library_key)
+ source_2 = ModulestoreSource.objects.create(key=self.legacy_library_2.usage_key.library_key)
task = bulk_migrate_from_modulestore.apply_async(
kwargs={
diff --git a/cms/lib/xblock/authoring_mixin.py b/cms/lib/xblock/authoring_mixin.py
index 3551059cd0c9..e660e11589cf 100644
--- a/cms/lib/xblock/authoring_mixin.py
+++ b/cms/lib/xblock/authoring_mixin.py
@@ -41,7 +41,7 @@ def visibility_view(self, _context=None):
from cms.djangoapps.contentstore.utils import reverse_course_url
fragment.add_content(self.runtime.service(self, 'mako').render_cms_template('visibility_editor.html', {
'xblock': self,
- 'manage_groups_url': reverse_course_url('group_configurations_list_handler', self.location.course_key),
+ 'manage_groups_url': reverse_course_url('group_configurations_list_handler', self.usage_key.course_key),
}))
fragment.add_javascript_url(self._get_studio_resource_url('js/xblock/authoring.js'))
fragment.initialize_js('VisibilityEditorInit')
diff --git a/cms/lib/xblock/tagging/tagging.py b/cms/lib/xblock/tagging/tagging.py
index 38eef0e788e4..be2d9f5aecc6 100644
--- a/cms/lib/xblock/tagging/tagging.py
+++ b/cms/lib/xblock/tagging/tagging.py
@@ -65,7 +65,7 @@ def student_view_aside(self, block, context): # pylint: disable=unused-argument
})
fragment = Fragment(render_to_string('structured_tags_block.html', {'tags': tags,
'tags_count': len(tags),
- 'block_location': block.location}))
+ 'block_location': block.usage_key}))
fragment.add_javascript_url(self._get_studio_resource_url('js/xblock_asides/structured_tags.js'))
fragment.initialize_js('StructuredTagsInit')
return fragment
diff --git a/cms/lib/xblock/tagging/test.py b/cms/lib/xblock/tagging/test.py
index cee2bf5e000c..a4e17543c9bf 100644
--- a/cms/lib/xblock/tagging/test.py
+++ b/cms/lib/xblock/tagging/test.py
@@ -46,26 +46,26 @@ def setUp(self):
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
self.course = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="course",
display_name="Test course",
)
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name="Week 1",
publish_item=True,
start=datetime(2015, 3, 1, tzinfo=timezone.utc),
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name="Lesson 1",
publish_item=True,
start=datetime(2015, 3, 1, tzinfo=timezone.utc),
)
self.vertical = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category='vertical',
display_name='Subsection 1',
publish_item=True,
@@ -73,14 +73,14 @@ def setUp(self):
)
self.problem = BlockFactory.create(
category="problem",
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
display_name="A Problem Block",
weight=1,
user_id=self.user.id,
publish_item=False,
)
self.video = BlockFactory.create(
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
category='video',
display_name='My Video',
user_id=self.user.id
@@ -195,7 +195,7 @@ def test_handle_requests(self, aside_key_class):
"""
handler_url = reverse_usage_url(
'component_handler',
- str(aside_key_class(self.problem.location, self.aside_name)),
+ str(aside_key_class(self.problem.usage_key, self.aside_name)),
kwargs={'handler': 'save_tags'}
)
@@ -230,7 +230,7 @@ def _test_helper_func(problem_location):
content_type="application/json")
self.assertEqual(response.status_code, 200)
- tag_aside = _test_helper_func(self.problem.location)
+ tag_aside = _test_helper_func(self.problem.usage_key)
self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found")
self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value])
@@ -239,7 +239,7 @@ def _test_helper_func(problem_location):
content_type="application/json")
self.assertEqual(response.status_code, 200)
- tag_aside = _test_helper_func(self.problem.location)
+ tag_aside = _test_helper_func(self.problem.usage_key)
self.assertIsNotNone(tag_aside, "Necessary StructuredTagsAside object isn't found")
self.assertEqual(tag_aside.saved_tags[self.aside_tag_dif], [self.aside_tag_dif_value,
self.aside_tag_dif_value2])
diff --git a/cms/lib/xblock/test/test_authoring_mixin.py b/cms/lib/xblock/test/test_authoring_mixin.py
index eee86df8bf4f..e0c64d338fe6 100644
--- a/cms/lib/xblock/test/test_authoring_mixin.py
+++ b/cms/lib/xblock/test/test_authoring_mixin.py
@@ -67,9 +67,9 @@ def setUp(self):
parent=vertical,
display_name='Test Pure'
)
- self.vertical_location = vertical.location
- self.video_location = video.location
- self.pure_location = pure.location
+ self.vertical_location = vertical.usage_key
+ self.video_location = video.usage_key
+ self.pure_location = pure.usage_key
self.pet_groups = [Group(1, 'Cat Lovers'), Group(2, 'Dog Lovers')]
def create_content_groups(self, content_groups):
diff --git a/cms/lib/xblock/test/test_upstream_sync.py b/cms/lib/xblock/test/test_upstream_sync.py
index 1af3914658ce..c0b34c576309 100644
--- a/cms/lib/xblock/test/test_upstream_sync.py
+++ b/cms/lib/xblock/test/test_upstream_sync.py
@@ -200,7 +200,7 @@ def test_sync_updates_happy_path(self):
assert downstream.data == "Upstream content V2"
# Verify tags
- object_tags = tagging_api.get_object_tags(str(downstream.location))
+ object_tags = tagging_api.get_object_tags(str(downstream.usage_key))
assert len(object_tags) == len(self.upstream_tags)
for object_tag in object_tags:
assert object_tag.value in self.upstream_tags
@@ -231,7 +231,7 @@ def test_sync_updates_happy_path(self):
assert downstream.data == "Upstream content V3"
# Verify tags
- object_tags = tagging_api.get_object_tags(str(downstream.location))
+ object_tags = tagging_api.get_object_tags(str(downstream.usage_key))
assert len(object_tags) == len(new_upstream_tags)
for object_tag in object_tags:
assert object_tag.value in new_upstream_tags
@@ -588,7 +588,7 @@ def test_sync_library_block_tags(self):
sync_from_upstream_block(downstream, self.user)
# Verify tags
- object_tags = tagging_api.get_object_tags(str(downstream.location))
+ object_tags = tagging_api.get_object_tags(str(downstream.usage_key))
assert len(object_tags) == len(expected_tags)
for object_tag in object_tags:
assert object_tag.value in expected_tags
@@ -604,7 +604,7 @@ def test_sync_library_block_tags(self):
sync_from_upstream_block(downstream, self.user)
#Verify tags
- object_tags = tagging_api.get_object_tags(str(downstream.location))
+ object_tags = tagging_api.get_object_tags(str(downstream.usage_key))
assert len(object_tags) == len(new_upstream_tags)
for object_tag in object_tags:
assert object_tag.value in new_upstream_tags
diff --git a/cms/lib/xblock/upstream_sync_block.py b/cms/lib/xblock/upstream_sync_block.py
index 6b5d14ffc5ed..0e1cc4077dca 100644
--- a/cms/lib/xblock/upstream_sync_block.py
+++ b/cms/lib/xblock/upstream_sync_block.py
@@ -193,8 +193,8 @@ def _update_tags(*, upstream: XBlock, downstream: XBlock) -> None:
# For any block synced with an upstream, copy the tags as read_only
# This keeps tags added locally.
copy_tags_as_read_only(
- str(upstream.location),
- str(downstream.location),
+ str(upstream.usage_key),
+ str(downstream.usage_key),
)
diff --git a/common/djangoapps/course_modes/signals.py b/common/djangoapps/course_modes/signals.py
index 5ee83c723655..6b5281fa3707 100644
--- a/common/djangoapps/course_modes/signals.py
+++ b/common/djangoapps/course_modes/signals.py
@@ -78,6 +78,6 @@ def update_masters_access_course(sender, instance, **kwargs): # pylint: disable
if verified_id in enrollment_groups and masters_id not in enrollment_groups:
enrollment_groups.append(masters_id)
item.group_access = group_access
- log.info("Publishing %s with Master's group access", item.location)
+ log.info("Publishing %s with Master's group access", item.usage_key)
store.update_item(item, user_id)
- store.publish(item.location, user_id)
+ store.publish(item.usage_key, user_id)
diff --git a/common/djangoapps/course_modes/tests/test_signals.py b/common/djangoapps/course_modes/tests/test_signals.py
index e4323f825a25..b795b4be9f74 100644
--- a/common/djangoapps/course_modes/tests/test_signals.py
+++ b/common/djangoapps/course_modes/tests/test_signals.py
@@ -112,9 +112,9 @@ def test_masters_mode(self):
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
# create the master's mode. signal will add masters to the verified section
self.create_mode('masters', 'masters')
- verified_section_ret = self.store.get_item(verified_section.location)
- section2_ret = self.store.get_item(section2.location)
- section3_ret = self.store.get_item(section3.location)
+ verified_section_ret = self.store.get_item(verified_section.usage_key)
+ section2_ret = self.store.get_item(section2.usage_key)
+ section3_ret = self.store.get_item(section3.usage_key)
# the verified section will now also be visible to master's
assert verified_section_ret.group_access[ENROLLMENT_TRACK_PARTITION_ID] == [VERIFIED_ID, MASTERS_ID]
assert section2_ret.group_access == {}
diff --git a/common/djangoapps/student/models/user.py b/common/djangoapps/student/models/user.py
index a9055d52479c..0fe615ff6b2f 100644
--- a/common/djangoapps/student/models/user.py
+++ b/common/djangoapps/student/models/user.py
@@ -1183,7 +1183,7 @@ def user_info(email): # lint-amnesty, pylint: disable=missing-function-docstrin
print("Username", user.username)
print("E-mail", user.email)
print("Name", u_prof.name)
- print("Location", u_prof.location)
+ print("Location", u_prof.usage_key)
print("Language", u_prof.language)
return user, u_prof
diff --git a/common/djangoapps/student/tests/test_views.py b/common/djangoapps/student/tests/test_views.py
index ed8c98188a50..c838ec10f4f6 100644
--- a/common/djangoapps/student/tests/test_views.py
+++ b/common/djangoapps/student/tests/test_views.py
@@ -757,9 +757,9 @@ def test_resume_course_appears_on_dashboard(self):
block_keys = [
BlockFactory.create(
category='video',
- parent_location=course.location,
+ parent_location=course.usage_key,
display_name=f'Video {str(number)}'
- ).location
+ ).usage_key
for number in range(5)
]
@@ -857,9 +857,9 @@ def test_dashboard_with_resume_buttons_and_view_buttons(self):
block_keys = [
BlockFactory.create(
category='video',
- parent_location=course.location,
+ parent_location=course.usage_key,
display_name=f'Video {str(number)}'
- ).location
+ ).usage_key
for number in range(5)
]
last_completed_block_string = str(block_keys[-1])
diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py
index c4e5635be75a..f5aa73d74bff 100644
--- a/common/djangoapps/student/tests/tests.py
+++ b/common/djangoapps/student/tests/tests.py
@@ -345,7 +345,7 @@ def _check_verification_status_on(self, mode, value):
Check that the css class and the status message are in the dashboard html.
"""
CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
- CourseEnrollment.enroll(self.user, self.course.location.course_key, mode=mode)
+ CourseEnrollment.enroll(self.user, self.course.usage_key.course_key, mode=mode)
if mode == 'verified':
# Simulate a successful verification attempt
@@ -380,7 +380,7 @@ def _check_verification_status_off(self, mode, value):
Check that the css class and the status message are not in the dashboard html.
"""
CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
- CourseEnrollment.enroll(self.user, self.course.location.course_key, mode=mode)
+ CourseEnrollment.enroll(self.user, self.course.usage_key.course_key, mode=mode)
if mode == 'verified':
# Simulate a successful verification attempt
@@ -611,7 +611,7 @@ def setUp(self):
self.course = CourseFactory.create(org=self.org)
self.user = UserFactory.create(username='jack', email='jack@fake.edx.org', password=self.TEST_PASSWORD)
CourseModeFactory.create(mode_slug='no-id-professional', course_id=self.course.id)
- CourseEnrollment.enroll(self.user, self.course.location.course_key, mode='no-id-professional')
+ CourseEnrollment.enroll(self.user, self.course.usage_key.course_key, mode='no-id-professional')
cache.clear()
@skip_unless_lms
diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py
index 03061dcb065b..4c5fcf8f361d 100644
--- a/common/djangoapps/student/views/dashboard.py
+++ b/common/djangoapps/student/views/dashboard.py
@@ -186,11 +186,11 @@ def get_course_enrollments(user, org_whitelist, org_blacklist, course_limit=None
continue
# Filter out anything that is not in the whitelist.
- if org_whitelist and course_overview.location.org not in org_whitelist:
+ if org_whitelist and course_overview.usage_key.org not in org_whitelist:
continue
# Conversely, filter out any enrollments in the blacklist.
- elif org_blacklist and course_overview.location.org in org_blacklist:
+ elif org_blacklist and course_overview.usage_key.org in org_blacklist:
continue
# Else, include the enrollment.
diff --git a/lms/djangoapps/ccx/api/v0/tests/test_views.py b/lms/djangoapps/ccx/api/v0/tests/test_views.py
index a8c9070df038..71819c5fea24 100644
--- a/lms/djangoapps/ccx/api/v0/tests/test_views.py
+++ b/lms/djangoapps/ccx/api/v0/tests/test_views.py
@@ -50,7 +50,7 @@ def setUp(self):
"""
super().setUp()
# add some info about the course for easy access
- self.master_course_key = self.course.location.course_key
+ self.master_course_key = self.course.usage_key.course_key
self.master_course_key_str = str(self.master_course_key)
# OAUTH2 setup
# create a specific user for the application
diff --git a/lms/djangoapps/ccx/migrations/0006_set_display_name_as_override.py b/lms/djangoapps/ccx/migrations/0006_set_display_name_as_override.py
index f37c9dc3216a..a00a3be36005 100644
--- a/lms/djangoapps/ccx/migrations/0006_set_display_name_as_override.py
+++ b/lms/djangoapps/ccx/migrations/0006_set_display_name_as_override.py
@@ -40,7 +40,7 @@ def save_display_name(apps, schema_editor):
CcxFieldOverride.objects.get_or_create(
ccx=ccx,
- location=course.location,
+ location=course.usage_key,
field='display_name',
defaults={'value': serialized_display_name},
)
diff --git a/lms/djangoapps/ccx/overrides.py b/lms/djangoapps/ccx/overrides.py
index a85b83ed60ec..c5d998db2767 100644
--- a/lms/djangoapps/ccx/overrides.py
+++ b/lms/djangoapps/ccx/overrides.py
@@ -38,7 +38,7 @@ def get(self, block, name, default):
elif isinstance(identifier, UsageKey):
course_key = block.id.course_key
elif hasattr(block, 'location'):
- course_key = block.location.course_key
+ course_key = block.usage_key.course_key
else:
msg = "Unable to get course id when calculating ccx overide for block type %r"
log.error(msg, type(block))
@@ -53,7 +53,7 @@ def enabled_for(cls, block): # lint-amnesty, pylint: disable=arguments-differ
"""
CCX field overrides are enabled for CCX blocks.
"""
- return getattr(block.location, 'ccx', None) or getattr(block, 'enable_ccx', False)
+ return getattr(block.usage_key, 'ccx', None) or getattr(block, 'enable_ccx', False)
def get_current_ccx(course_key):
@@ -84,7 +84,7 @@ def get_override_for_ccx(ccx, block, name, default=None):
"""
overrides = _get_overrides_for_ccx(ccx)
- clean_ccx_key = _clean_ccx_key(block.location)
+ clean_ccx_key = _clean_ccx_key(block.usage_key)
block_overrides = overrides.get(clean_ccx_key, {})
@@ -131,7 +131,7 @@ def _get_overrides_for_ccx(ccx):
)
for override in query:
- block_overrides = overrides.setdefault(override.location, {})
+ block_overrides = overrides.setdefault(override.usage_key, {})
block_overrides[override.field] = json.loads(override.value)
block_overrides[override.field + "_id"] = override.id
block_overrides[override.field + "_instance"] = override
@@ -152,7 +152,7 @@ def override_field_for_ccx(ccx, block, name, value):
value_json = field.to_json(value)
serialized_value = json.dumps(value_json)
override_has_changes = False
- clean_ccx_key = _clean_ccx_key(block.location)
+ clean_ccx_key = _clean_ccx_key(block.usage_key)
override = get_override_for_ccx(ccx, block, name + "_instance")
if override:
@@ -161,7 +161,7 @@ def override_field_for_ccx(ccx, block, name, value):
if not override:
override, created = CcxFieldOverride.objects.get_or_create(
ccx=ccx,
- location=block.location,
+ location=block.usage_key,
field=name,
defaults={'value': serialized_value},
)
@@ -188,7 +188,7 @@ def clear_override_for_ccx(ccx, block, name):
try:
CcxFieldOverride.objects.get(
ccx=ccx,
- location=block.location,
+ location=block.usage_key,
field=name).delete()
clear_ccx_field_info_from_ccx_map(ccx, block, name)
@@ -202,7 +202,7 @@ def clear_ccx_field_info_from_ccx_map(ccx, block, name):
Remove field information from ccx overrides mapping dictionary
"""
try:
- clean_ccx_key = _clean_ccx_key(block.location)
+ clean_ccx_key = _clean_ccx_key(block.usage_key)
ccx_override_map = _get_overrides_for_ccx(ccx).setdefault(clean_ccx_key, {})
ccx_override_map.pop(name)
ccx_override_map.pop(name + "_id")
diff --git a/lms/djangoapps/ccx/tests/test_ccx_modulestore.py b/lms/djangoapps/ccx/tests/test_ccx_modulestore.py
index f5e98a942cde..17e2923c1b62 100644
--- a/lms/djangoapps/ccx/tests/test_ccx_modulestore.py
+++ b/lms/djangoapps/ccx/tests/test_ccx_modulestore.py
@@ -83,7 +83,7 @@ def test_get_course(self):
"""retrieving a course with a ccx key works"""
expected = self.get_course(self.ccx_locator.to_course_locator())
actual = self.get_course(self.ccx_locator)
- assert expected.location.course_key == actual.location.course_key.to_course_locator()
+ assert expected.usage_key.course_key == actual.usage_key.course_key.to_course_locator()
assert expected.display_name == actual.display_name
def test_get_children(self):
@@ -101,14 +101,14 @@ def test_get_children(self):
if actual is None:
self.fail('ccx children exhausted before course children')
assert expected.display_name == actual.display_name
- assert expected.location.course_key == course_key
- assert actual.location.course_key == self.ccx_locator
+ assert expected.usage_key.course_key == course_key
+ assert actual.usage_key.course_key == self.ccx_locator
def test_has_item(self):
"""can verify that a location exists, using ccx block usage key"""
for item in chain(self.chapters, self.sequentials, self.verticals, self.blocks):
block_key = self.ccx_locator.make_usage_key(
- item.location.block_type, item.location.block_id
+ item.usage_key.block_type, item.usage_key.block_id
)
assert self.store.has_item(block_key)
@@ -120,18 +120,18 @@ def test_get_item(self):
"""
for expected in chain(self.chapters, self.sequentials, self.verticals, self.blocks):
block_key = self.ccx_locator.make_usage_key(
- expected.location.block_type, expected.location.block_id
+ expected.usage_key.block_type, expected.usage_key.block_id
)
actual = self.store.get_item(block_key)
assert expected.display_name == actual.display_name
- assert expected.location == actual.location.to_block_locator()
+ assert expected.usage_key == actual.usage_key.to_block_locator()
def test_publication_api(self):
"""verify that we can correctly discern a published item by ccx key"""
with self.store.bulk_operations(self.ccx_locator):
for expected in self.blocks:
block_key = self.ccx_locator.make_usage_key(
- expected.location.block_type, expected.location.block_id
+ expected.usage_key.block_type, expected.usage_key.block_id
)
assert self.store.has_published_version(expected)
self.store.unpublish(block_key, self.user.id)
diff --git a/lms/djangoapps/ccx/tests/test_models.py b/lms/djangoapps/ccx/tests/test_models.py
index 11bd7e43d312..30740c058389 100644
--- a/lms/djangoapps/ccx/tests/test_models.py
+++ b/lms/djangoapps/ccx/tests/test_models.py
@@ -39,7 +39,7 @@ def test_ccx_course_is_correct_course(self):
"""verify that the course property of a ccx returns the right course"""
expected = self.course
actual = self.ccx.course
- assert expected.location == actual.location
+ assert expected.usage_key == actual.usage_key
def test_ccx_course_caching(self):
"""verify that caching the propery works to limit queries"""
diff --git a/lms/djangoapps/ccx/tests/test_views.py b/lms/djangoapps/ccx/tests/test_views.py
index a355a3a433c0..999c7080484f 100644
--- a/lms/djangoapps/ccx/tests/test_views.py
+++ b/lms/djangoapps/ccx/tests/test_views.py
@@ -95,7 +95,7 @@ def setup_students_and_grades(context):
max_grade=1,
student=context.student,
course_id=context.course.id,
- module_state_key=problem.location
+ module_state_key=problem.usage_key
)
StudentModuleFactory.create(
@@ -103,7 +103,7 @@ def setup_students_and_grades(context):
max_grade=1,
student=context.student2,
course_id=context.course.id,
- module_state_key=problem.location
+ module_state_key=problem.usage_key
)
task_compute_all_grades_for_course.apply_async(kwargs={'course_key': str(context.course.id)})
@@ -906,17 +906,17 @@ def test_get_ccx_schedule(self, today):
vertical = self.verticals[0]
self.hide_node(vertical)
locations = self.assert_elements_in_schedule(url, n_verticals=7)
- assert str(vertical.location) not in locations
+ assert str(vertical.usage_key) not in locations
# hide a sequential
sequential = self.sequentials[0]
self.hide_node(sequential)
locations = self.assert_elements_in_schedule(url, n_sequentials=3, n_verticals=6)
- assert str(sequential.location) not in locations
+ assert str(sequential.usage_key) not in locations
# hide a chapter
chapter = self.chapters[0]
self.hide_node(chapter)
locations = self.assert_elements_in_schedule(url, n_chapters=1, n_sequentials=2, n_verticals=4)
- assert str(chapter.location) not in locations
+ assert str(chapter.usage_key) not in locations
GET_CHILDREN = XModuleMixin.get_children
diff --git a/lms/djangoapps/ccx/views.py b/lms/djangoapps/ccx/views.py
index 7c6a75aaf6d4..6cd97d7cc262 100644
--- a/lms/djangoapps/ccx/views.py
+++ b/lms/djangoapps/ccx/views.py
@@ -260,7 +260,7 @@ def override_fields(parent, data, graded, earliest=None, ccx_ids_to_delete=None)
if ccx_ids_to_delete is None:
ccx_ids_to_delete = []
blocks = {
- str(child.location): child
+ str(child.usage_key): child
for child in parent.get_children()}
for unit in data:
@@ -413,7 +413,7 @@ def visit(node, depth=1):
start = get_date(ccx, child, 'start', node)
visited = {
- 'location': str(child.location),
+ 'location': str(child.usage_key),
'display_name': child.display_name,
'category': child.category,
'start': start,
@@ -422,7 +422,7 @@ def visit(node, depth=1):
}
else:
visited = {
- 'location': str(child.location),
+ 'location': str(child.usage_key),
'display_name': child.display_name,
'category': child.category,
'start': start,
diff --git a/lms/djangoapps/certificates/tests/test_views.py b/lms/djangoapps/certificates/tests/test_views.py
index 520baa2a8fb2..45f9fe1b847f 100644
--- a/lms/djangoapps/certificates/tests/test_views.py
+++ b/lms/djangoapps/certificates/tests/test_views.py
@@ -67,7 +67,7 @@ def setUp(self):
self.course.cert_html_view_enabled = True
self.course.save()
self.store.update_item(self.course, self.user.id)
- self.course_id = self.course.location.course_key
+ self.course_id = self.course.usage_key.course_key
self.user = UserFactory.create(
email='joe_user@edx.org',
username='joeuser',
diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py
index 1bfcd6ae2e66..02835679af5f 100644
--- a/lms/djangoapps/certificates/tests/test_webview_views.py
+++ b/lms/djangoapps/certificates/tests/test_webview_views.py
@@ -80,7 +80,7 @@ def setUp(self):
certificate_available_date=datetime.datetime.today() - datetime.timedelta(days=1),
certificates_display_behavior=CertificatesDisplayBehaviors.END_WITH_DATE
)
- self.course_id = self.course.location.course_key
+ self.course_id = self.course.usage_key.course_key
self.user = UserFactory.create(
email='joe_user@edx.org',
username='joeuser',
diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py
index bee1638342fb..2f87af717245 100644
--- a/lms/djangoapps/certificates/views/webview.py
+++ b/lms/djangoapps/certificates/views/webview.py
@@ -148,7 +148,7 @@ def _update_certificate_context(context, course, course_overview, user_certifica
certificate_type=context.get("certificate_type"))
certificate_type_description = get_certificate_description(
- user_certificate.mode, certificate_type, platform_name, course.location.course_key
+ user_certificate.mode, certificate_type, platform_name, course.usage_key.course_key
)
if certificate_type_description:
context['certificate_type_description'] = certificate_type_description
diff --git a/lms/djangoapps/course_api/blocks/tests/test_api.py b/lms/djangoapps/course_api/blocks/tests/test_api.py
index 47d0b62fa6e6..89f487ed4696 100644
--- a/lms/djangoapps/course_api/blocks/tests/test_api.py
+++ b/lms/djangoapps/course_api/blocks/tests/test_api.py
@@ -44,38 +44,38 @@ def setUp(self):
self.request.user = self.user
def test_basic(self):
- blocks = get_blocks(self.request, self.course.location, self.user)
- assert blocks['root'] == str(self.course.location)
+ blocks = get_blocks(self.request, self.course.usage_key, self.user)
+ assert blocks['root'] == str(self.course.usage_key)
# subtract for (1) the orphaned course About block and (2) the hidden Html block
assert len(blocks['blocks']) == (len(self.store.get_items(self.course.id)) - 2)
- assert str(self.html_block.location) not in blocks['blocks']
+ assert str(self.html_block.usage_key) not in blocks['blocks']
def test_no_user(self):
- blocks = get_blocks(self.request, self.course.location)
- assert str(self.html_block.location) not in blocks['blocks']
+ blocks = get_blocks(self.request, self.course.usage_key)
+ assert str(self.html_block.usage_key) not in blocks['blocks']
vertical_block = self.store.get_item(self.course.id.make_usage_key('vertical', 'vertical_x1a'))
- assert str(vertical_block.location) in blocks['blocks']
+ assert str(vertical_block.usage_key) in blocks['blocks']
def test_access_before_api_transformer_order(self):
"""
Tests the order of transformers: access checks are made before the api
transformer is applied.
"""
- blocks = get_blocks(self.request, self.course.location, self.user, nav_depth=5, requested_fields=['nav_depth'])
+ blocks = get_blocks(self.request, self.course.usage_key, self.user, nav_depth=5, requested_fields=['nav_depth'])
vertical_block = self.store.get_item(self.course.id.make_usage_key('vertical', 'vertical_x1a'))
problem_block = self.store.get_item(self.course.id.make_usage_key('problem', 'problem_x1a_1'))
- vertical_descendants = blocks['blocks'][str(vertical_block.location)]['descendants']
+ vertical_descendants = blocks['blocks'][str(vertical_block.usage_key)]['descendants']
- assert str(problem_block.location) in vertical_descendants
- assert str(self.html_block.location) not in vertical_descendants
+ assert str(problem_block.usage_key) in vertical_descendants
+ assert str(self.html_block.usage_key) not in vertical_descendants
def test_sub_structure(self):
sequential_block = self.store.get_item(self.course.id.make_usage_key('sequential', 'sequential_y1'))
- blocks = get_blocks(self.request, sequential_block.location, self.user)
- assert blocks['root'] == str(sequential_block.location)
+ blocks = get_blocks(self.request, sequential_block.usage_key, self.user)
+ assert blocks['root'] == str(sequential_block.usage_key)
assert len(blocks['blocks']) == 5
for block_type, block_name, is_inside_of_structure in (
@@ -86,15 +86,15 @@ def test_sub_structure(self):
):
block = self.store.get_item(self.course.id.make_usage_key(block_type, block_name))
if is_inside_of_structure:
- assert str(block.location) in blocks['blocks']
+ assert str(block.usage_key) in blocks['blocks']
else:
- assert str(block.location) not in blocks['blocks']
+ assert str(block.usage_key) not in blocks['blocks']
def test_filtering_by_block_types(self):
sequential_block = self.store.get_item(self.course.id.make_usage_key('sequential', 'sequential_y1'))
# not filtered blocks
- blocks = get_blocks(self.request, sequential_block.location, self.user, requested_fields=['type'])
+ blocks = get_blocks(self.request, sequential_block.usage_key, self.user, requested_fields=['type'])
assert len(blocks['blocks']) == 5
found_not_problem = False
for block in blocks['blocks'].values():
@@ -103,7 +103,7 @@ def test_filtering_by_block_types(self):
assert found_not_problem
# filtered blocks
- blocks = get_blocks(self.request, sequential_block.location, self.user,
+ blocks = get_blocks(self.request, sequential_block.usage_key, self.user,
block_types_filter=['problem'], requested_fields=['type'])
assert len(blocks['blocks']) == 3
for block in blocks['blocks'].values():
@@ -163,7 +163,7 @@ def test_video_urls_rewrite(self, video_data_patch):
}
}
blocks = get_blocks(
- self.request, self.course.location, requested_fields=['student_view_data'], student_view_data=['video']
+ self.request, self.course.usage_key, requested_fields=['student_view_data'], student_view_data=['video']
)
video_block_key = str(self.course.id.make_usage_key('video', 'sample_video'))
video_block_data = blocks['blocks'][video_block_key]
@@ -200,7 +200,7 @@ def _get_blocks(self, course, expected_mongo_queries, expected_sql_queries):
"""
with check_mongo_calls(expected_mongo_queries):
with self.assertNumQueries(expected_sql_queries, table_ignorelist=QUERY_COUNT_TABLE_IGNORELIST):
- get_blocks(self.request, course.location, self.user)
+ get_blocks(self.request, course.usage_key, self.user)
@ddt.ddt
diff --git a/lms/djangoapps/course_api/blocks/tests/test_forms.py b/lms/djangoapps/course_api/blocks/tests/test_forms.py
index 1a45b40292fe..5d6b8df4f575 100644
--- a/lms/djangoapps/course_api/blocks/tests/test_forms.py
+++ b/lms/djangoapps/course_api/blocks/tests/test_forms.py
@@ -44,7 +44,7 @@ def setUp(self):
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
CourseEnrollmentFactory.create(user=self.student2, course_id=self.course.id)
- usage_key = self.course.location
+ usage_key = self.course.usage_key
self.initial = {'requesting_user': self.student}
self.form_data = QueryDict(
urlencode({
diff --git a/lms/djangoapps/course_api/blocks/tests/test_serializers.py b/lms/djangoapps/course_api/blocks/tests/test_serializers.py
index b1b9f4cfef5a..76a31cc93fb4 100644
--- a/lms/djangoapps/course_api/blocks/tests/test_serializers.py
+++ b/lms/djangoapps/course_api/blocks/tests/test_serializers.py
@@ -49,7 +49,7 @@ def setUp(self):
)
self.block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
self.serializer_context = {
@@ -127,11 +127,11 @@ def create_staff_context(self):
"""
# Create a staff user to be able to test visible_to_staff_only
staff_user = UserFactory.create()
- CourseStaffRole(self.course.location.course_key).add_users(staff_user)
+ CourseStaffRole(self.course.usage_key.course_key).add_users(staff_user)
block_structure = get_course_blocks(
staff_user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
return {
@@ -144,7 +144,7 @@ def assert_staff_fields(self, serialized_block):
"""
Test fields accessed by a staff user
"""
- if serialized_block['id'] == str(self.html_block.location):
+ if serialized_block['id'] == str(self.html_block.usage_key):
assert serialized_block['visible_to_staff_only']
else:
assert not serialized_block['visible_to_staff_only']
diff --git a/lms/djangoapps/course_api/blocks/tests/test_views.py b/lms/djangoapps/course_api/blocks/tests/test_views.py
index f577762ad70f..c27831cd5944 100644
--- a/lms/djangoapps/course_api/blocks/tests/test_views.py
+++ b/lms/djangoapps/course_api/blocks/tests/test_views.py
@@ -48,10 +48,10 @@ def setUpClass(cls):
cls.course_usage_key = cls.store.make_course_usage_key(cls.course_key)
cls.non_orphaned_block_usage_keys = {
- str(item.location)
+ str(item.usage_key)
for item in cls.store.get_items(cls.course_key)
# remove all orphaned items in the course, except for the root 'course' block
- if cls.store.get_parent_location(item.location) or item.category == 'course'
+ if cls.store.get_parent_location(item.usage_key) or item.category == 'course'
}
def setUp(self):
@@ -135,7 +135,7 @@ def verify_response_with_requested_fields(self, response):
if xblock.has_children:
self.assertSetEqual(
- {str(child.location) for child in xblock.get_children()},
+ {str(child.usage_key) for child in xblock.get_children()},
set(block_data['children']),
)
@@ -418,10 +418,10 @@ def setUp(self):
self.query_params['course_id'] = str(self.course_key)
self.override_waffle_switch(True)
self.non_orphaned_raw_block_usage_keys = {
- item.location
+ item.usage_key
for item in self.store.get_items(self.course_key)
# remove all orphaned items in the course, except for the root 'course' block
- if self.store.get_parent_location(item.location) or item.category == 'course'
+ if self.store.get_parent_location(item.usage_key) or item.category == 'course'
}
def test_no_course_id(self):
@@ -442,7 +442,7 @@ def test_non_existent_course_anonymous(self):
def test_completion_one_unit(self):
for item in self.store.get_items(self.course_key):
if item.category == 'html':
- block_usage_key = item.location
+ block_usage_key = item.usage_key
break
submit_completions_for_testing(self.user, [block_usage_key])
@@ -525,7 +525,7 @@ def blocks_has_discussion_xblock(blocks):
return False
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id='topic_id',
discussion_category='category',
@@ -565,10 +565,10 @@ def setUpClass(cls):
cls.course_usage_key = cls.store.make_course_usage_key(cls.course_key)
cls.non_orphaned_block_usage_keys = {
- str(item.location)
+ str(item.usage_key)
for item in cls.store.get_items(cls.course_key)
# remove all orphaned items in the course, except for the root 'course' block
- if cls.store.get_parent_location(item.location) or item.category == 'course'
+ if cls.store.get_parent_location(item.usage_key) or item.category == 'course'
}
def setUp(self):
diff --git a/lms/djangoapps/course_api/blocks/transformers/tests/test_block_completion.py b/lms/djangoapps/course_api/blocks/transformers/tests/test_block_completion.py
index 1bea04b0486c..cb7234fda70b 100644
--- a/lms/djangoapps/course_api/blocks/transformers/tests/test_block_completion.py
+++ b/lms/djangoapps/course_api/blocks/transformers/tests/test_block_completion.py
@@ -70,20 +70,20 @@ def test_transform_aggregators(self):
block = BlockFactory.create(category='comp', parent=filled_aggregator)
BlockCompletion.objects.submit_completion(
user=self.user,
- block_key=block.location,
+ block_key=block.usage_key,
completion=self.COMPLETION_TEST_VALUE,
)
empty_aggregator = BlockFactory.create(category='aggregator', parent=course)
- block_structure = get_course_blocks(self.user, course.location, self.transformers)
+ block_structure = get_course_blocks(self.user, course.usage_key, self.transformers)
self._assert_block_has_proper_completion_values(
- block_structure, block.location, self.COMPLETION_TEST_VALUE, True
+ block_structure, block.usage_key, self.COMPLETION_TEST_VALUE, True
)
self._assert_block_has_proper_completion_values(
- block_structure, filled_aggregator.location, None, True
+ block_structure, filled_aggregator.usage_key, None, True
)
self._assert_block_has_proper_completion_values(
- block_structure, empty_aggregator.location, None, True
+ block_structure, empty_aggregator.usage_key, None, True
)
@XBlock.register_temp_plugin(StubExcludedXBlock, identifier='excluded')
@@ -93,9 +93,9 @@ def test_transform_gives_none_for_excluded(self):
"""
course = CourseFactory.create()
block = BlockFactory.create(category='excluded', parent=course)
- block_structure = get_course_blocks(self.user, course.location, self.transformers)
+ block_structure = get_course_blocks(self.user, course.usage_key, self.transformers)
- self._assert_block_has_proper_completion_values(block_structure, block.location, None, False)
+ self._assert_block_has_proper_completion_values(block_structure, block.usage_key, None, False)
@XBlock.register_temp_plugin(StubCompletableXBlock, identifier='comp')
def test_transform_gives_value_for_completable(self):
@@ -107,13 +107,13 @@ def test_transform_gives_value_for_completable(self):
block = BlockFactory.create(category='comp', parent=course)
BlockCompletion.objects.submit_completion(
user=self.user,
- block_key=block.location,
+ block_key=block.usage_key,
completion=self.COMPLETION_TEST_VALUE,
)
- block_structure = get_course_blocks(self.user, course.location, self.transformers)
+ block_structure = get_course_blocks(self.user, course.usage_key, self.transformers)
self._assert_block_has_proper_completion_values(
- block_structure, block.location, self.COMPLETION_TEST_VALUE, True
+ block_structure, block.usage_key, self.COMPLETION_TEST_VALUE, True
)
def test_transform_gives_zero_for_ordinary_block(self):
@@ -123,9 +123,9 @@ def test_transform_gives_zero_for_ordinary_block(self):
"""
course = CourseFactory.create()
block = BlockFactory.create(category='html', parent=course)
- block_structure = get_course_blocks(self.user, course.location, self.transformers)
+ block_structure = get_course_blocks(self.user, course.usage_key, self.transformers)
- self._assert_block_has_proper_completion_values(block_structure, block.location, 0.0, False)
+ self._assert_block_has_proper_completion_values(block_structure, block.usage_key, 0.0, False)
def _assert_block_has_proper_completion_values(
self, block_structure, block_key, expected_completion, expected_complete
diff --git a/lms/djangoapps/course_api/blocks/transformers/tests/test_milestones.py b/lms/djangoapps/course_api/blocks/transformers/tests/test_milestones.py
index 8ebd2477deef..b3a232cb20da 100644
--- a/lms/djangoapps/course_api/blocks/transformers/tests/test_milestones.py
+++ b/lms/djangoapps/course_api/blocks/transformers/tests/test_milestones.py
@@ -56,8 +56,8 @@ def setup_gated_section(self, gated_block, gating_block):
gated_block: The block that should be inaccessible until gating_block is completed
gating_block: The block that must be completed before access is granted
"""
- gating_api.add_prerequisite(self.course.id, str(gating_block.location))
- gating_api.set_required_content(self.course.id, gated_block.location, gating_block.location, 100, 0)
+ gating_api.add_prerequisite(self.course.id, str(gating_block.usage_key))
+ gating_api.set_required_content(self.course.id, gated_block.usage_key, gating_block.usage_key, 100, 0)
ALL_BLOCKS = (
'course', 'A', 'B', 'C', 'ProctoredExam', 'D', 'E', 'PracticeExam', 'F', 'G', 'H', 'I', 'TimedExam', 'J', 'K'
@@ -184,7 +184,7 @@ def test_gated(self, gated_block_ref, gating_block_ref, expected_blocks_before_c
# this call triggers reevaluation of prerequisites fulfilled by the gating block.
lms_gating_api.evaluate_prerequisite(
self.course,
- Mock(location=self.blocks[gating_block_ref].location, percent_graded=1.0),
+ Mock(location=self.blocks[gating_block_ref].usage_key, percent_graded=1.0),
self.user,
)
@@ -218,7 +218,7 @@ def test_special_exams(self):
# this call triggers reevaluation of prerequisites fulfilled by the gating block.
lms_gating_api.evaluate_prerequisite(
self.course,
- Mock(location=self.blocks['A'].location, percent_graded=1.0),
+ Mock(location=self.blocks['A'].usage_key, percent_graded=1.0),
self.user,
)
self.get_blocks_and_check_against_expected(self.user, self.ALL_BLOCKS)
@@ -230,7 +230,7 @@ def get_blocks_and_check_against_expected(self, user, expected_blocks):
"""
block_structure = get_course_blocks(
user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
assert set(block_structure.get_block_keys()) == set(self.get_block_key_set(self.blocks, *expected_blocks))
diff --git a/lms/djangoapps/course_api/tests/test_api.py b/lms/djangoapps/course_api/tests/test_api.py
index 8e4d1253f8f7..20fab98db5e4 100644
--- a/lms/djangoapps/course_api/tests/test_api.py
+++ b/lms/djangoapps/course_api/tests/test_api.py
@@ -342,8 +342,8 @@ def test_get_due_dates(self):
mock_path = 'lms.djangoapps.course_api.api.get_dates_for_course'
with mock.patch(mock_path) as mock_get_dates:
mock_get_dates.return_value = {
- (self.section_1.location, 'due'): self.section_1.due.strftime('%Y-%m-%dT%H:%M:%SZ'),
- (self.section_1.location, 'start'): self.section_1.start.strftime('%Y-%m-%dT%H:%M:%SZ'),
+ (self.section_1.usage_key, 'due'): self.section_1.due.strftime('%Y-%m-%dT%H:%M:%SZ'),
+ (self.section_1.usage_key, 'start'): self.section_1.start.strftime('%Y-%m-%dT%H:%M:%SZ'),
}
expected_due_dates = [
@@ -364,8 +364,8 @@ def test_get_due_dates_error_fetching_block(self):
with mock.patch(mock_path + 'modulestore') as mock_modulestore:
mock_modulestore.return_value.get_item.side_effect = ItemNotFoundError('whatever')
mock_get_dates.return_value = {
- (self.section_1.location, 'due'): self.section_1.due.strftime('%Y-%m-%dT%H:%M:%SZ'),
- (self.section_1.location, 'start'): self.section_1.start.strftime('%Y-%m-%dT%H:%M:%SZ'),
+ (self.section_1.usage_key, 'due'): self.section_1.due.strftime('%Y-%m-%dT%H:%M:%SZ'),
+ (self.section_1.usage_key, 'start'): self.section_1.start.strftime('%Y-%m-%dT%H:%M:%SZ'),
}
expected_due_dates = [
diff --git a/lms/djangoapps/course_blocks/tests/test_api.py b/lms/djangoapps/course_blocks/tests/test_api.py
index 62139c554982..c8cb5a1b46fd 100644
--- a/lms/djangoapps/course_blocks/tests/test_api.py
+++ b/lms/djangoapps/course_blocks/tests/test_api.py
@@ -140,7 +140,7 @@ def test_get_course_blocks(self, group_id, expected_blocks, user_known):
with patch('xmodule.modulestore.split_mongo.split.SplitModuleStoreRuntime.get_block', side_effect=side_effect):
block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
BlockStructureTransformers([]),
)
self.assertSetEqual(
diff --git a/lms/djangoapps/course_blocks/transformers/load_override_data.py b/lms/djangoapps/course_blocks/transformers/load_override_data.py
index 7f57768b5069..f4f526432f11 100644
--- a/lms/djangoapps/course_blocks/transformers/load_override_data.py
+++ b/lms/djangoapps/course_blocks/transformers/load_override_data.py
@@ -48,7 +48,7 @@ def override_xblock_fields(course_key, location_list, block_structure, user_id):
value = json.loads(student_field_override.value)
field = student_field_override.field
block_structure.override_xblock_field(
- student_field_override.location,
+ student_field_override.usage_key,
field,
value
)
diff --git a/lms/djangoapps/course_blocks/transformers/tests/helpers.py b/lms/djangoapps/course_blocks/transformers/tests/helpers.py
index fb78946280fd..b9cfc3bdc68b 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/helpers.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/helpers.py
@@ -118,13 +118,13 @@ def add_parents(self, block_hierarchy, block_map):
store = modulestore()
parents = block_hierarchy.get('#parents', [])
if parents:
- block_key = block_map[block_hierarchy['#ref']].location
+ block_key = block_map[block_hierarchy['#ref']].usage_key
# First remove the block from the course.
# It would be re-added to the course if the course was
# explicitly listed in parents.
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, block_map['course'].id):
- course = store.get_item(block_map['course'].location)
+ course = store.get_item(block_map['course'].usage_key)
if block_key in course.children:
course.children.remove(block_key)
block_map['course'] = update_block(course)
@@ -132,7 +132,7 @@ def add_parents(self, block_hierarchy, block_map):
# Add this to block to each listed parent.
for parent_ref in parents:
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course.id):
- parent_block = store.get_item(block_map[parent_ref].location)
+ parent_block = store.get_item(block_map[parent_ref].usage_key)
parent_block.children.append(block_key)
block_map[parent_ref] = update_block(parent_block)
@@ -202,7 +202,7 @@ def get_block_key_set(self, blocks, *refs):
Returns: set[UsageKey]
"""
xblocks = (blocks[ref] for ref in refs)
- return {xblock.location for xblock in xblocks} # lint-amnesty, pylint: disable=consider-using-set-comprehension
+ return {xblock.usage_key for xblock in xblocks} # lint-amnesty, pylint: disable=consider-using-set-comprehension
class BlockParentsMapTestCase(TransformerRegistryTestMixin, ModuleStoreTestCase):
@@ -231,7 +231,7 @@ def setUp(self):
# an ordered list of block locations, where the index
# corresponds to the block's index in the parents_map.
- self.xblock_keys = [self.course.location]
+ self.xblock_keys = [self.course.usage_key]
# create all other blocks in the course
for i, parents_index in enumerate(self.parents_map):
@@ -242,7 +242,7 @@ def setUp(self):
BlockFactory.create(
parent=self.get_block(parents_index[0]),
category="vertical",
- ).location
+ ).usage_key
)
# add additional parents
@@ -321,7 +321,7 @@ def _check_results(self, user, expected_accessible_blocks, blocks_with_differing
"""
self.client.login(username=user.username, password=self.password)
- block_structure = get_course_blocks(user, self.course.location, transformers)
+ block_structure = get_course_blocks(user, self.course.usage_key, transformers)
for i, xblock_key in enumerate(self.xblock_keys):
@@ -363,7 +363,7 @@ def publish_course(course):
"""
store = modulestore()
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course.id):
- store.publish(course.location, ModuleStoreEnum.UserID.test)
+ store.publish(course.usage_key, ModuleStoreEnum.UserID.test)
def create_location(org, course, run, block_type, block_id):
diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_hidden_content.py b/lms/djangoapps/course_blocks/transformers/tests/test_hidden_content.py
index f2039a7b1dce..62240c937532 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/test_hidden_content.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/test_hidden_content.py
@@ -153,7 +153,7 @@ def test_hidden_content_with_transformer_override(self):
block = self.get_block(1)
block.hide_after_due = True
update_block(block)
- set_date_for_block(self.course.id, block.location, 'due', self.DateType.PAST_DATE)
+ set_date_for_block(self.course.id, block.usage_key, 'due', self.DateType.PAST_DATE)
# Due date is in the past so some blocks are hidden
self.assert_transform_results(
@@ -164,7 +164,7 @@ def test_hidden_content_with_transformer_override(self):
)
# Set an override for the due date to be in the future
- set_date_for_block(self.course.id, block.location, 'due', self.DateType.FUTURE_DATE, user=self.student)
+ set_date_for_block(self.course.id, block.usage_key, 'due', self.DateType.FUTURE_DATE, user=self.student)
# this line is just to bust the cache for the user so it returns the updated date.
get_dates_for_course(self.course.id, user=self.student, use_cached=False)
diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_library_content.py b/lms/djangoapps/course_blocks/transformers/tests/test_library_content.py
index 5a4d7a0de11a..6cefaae327c2 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/test_library_content.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/test_library_content.py
@@ -120,7 +120,7 @@ def test_content_library(self):
"""
raw_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
transformers=BlockStructureTransformers(),
)
assert len(list(raw_block_structure.get_block_keys())) == len(self.blocks)
@@ -129,7 +129,7 @@ def test_content_library(self):
clear_course_from_cache(self.course.id)
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
@@ -154,7 +154,7 @@ def test_content_library(self):
for i in range(5):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
assert set(trans_block_structure.get_block_keys()) == self.get_block_key_set(self.blocks, 'course',
@@ -275,7 +275,7 @@ def test_content_library_randomize(self, mocked):
for i in range(5):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
children = []
@@ -327,7 +327,7 @@ def test_content_library_randomize_selected_blocks_mismatch(self, mocked):
for _ in range(5):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
children = []
@@ -350,7 +350,7 @@ def test_content_library_randomize_selected_blocks_missing(self, mocked):
for _ in range(5):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
children = []
diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_load_override_data.py b/lms/djangoapps/course_blocks/transformers/tests/test_load_override_data.py
index d0fef5065b43..1a4163c1344d 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/test_load_override_data.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/test_load_override_data.py
@@ -49,12 +49,12 @@ def setUp(self):
section = course.get_children()[0]
subsection = section.get_children()[0]
self.block = self.store.create_child(
- self.learner.id, subsection.location, 'html', 'new_component'
+ self.learner.id, subsection.usage_key, 'html', 'new_component'
)
CourseEnrollmentFactory.create(user=self.learner, course_id=self.course_key, is_active=True)
CourseEnrollmentFactory.create(user=self.learner2, course_id=self.course_key, is_active=True)
self.block = self.store.create_child(
- self.learner2.id, subsection.location, 'html', 'new_component_2'
+ self.learner2.id, subsection.usage_key, 'html', 'new_component_2'
)
@ddt.data(*REQUESTED_FIELDS)
diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py
index 468cc30c8fbf..073a955a1b04 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py
@@ -191,7 +191,7 @@ def test_user(self, group_id, expected_blocks):
block_structure1 = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
assert set(block_structure1.get_block_keys()) == set(self.get_block_key_set(self.blocks, *expected_blocks))
@@ -206,13 +206,13 @@ def test_user_randomly_assigned(self):
# calling twice should result in the same block set
block_structure1 = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
with check_mongo_calls(0):
block_structure2 = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
assert set(block_structure1.get_block_keys()) == set(block_structure2.get_block_keys())
diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py
index 410de94dc845..6db400d243f1 100644
--- a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py
+++ b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py
@@ -218,7 +218,7 @@ def test_transform(self, group_id, expected_blocks):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
self.assertSetEqual(
@@ -245,7 +245,7 @@ def test_transform_with_content_gating_partition(self):
):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
xblocks_denial_reason = [trans_block_structure.get_xblock_field(b, 'authorization_denial_reason')
@@ -264,7 +264,7 @@ def test_transform_on_inactive_partition(self):
trans_block_structure = get_course_blocks(
self.user,
- self.course.location,
+ self.course.usage_key,
self.transformers,
)
diff --git a/lms/djangoapps/course_home_api/outline/tests/test_view.py b/lms/djangoapps/course_home_api/outline/tests/test_view.py
index 74e22e5fcc4b..f048002810ab 100644
--- a/lms/djangoapps/course_home_api/outline/tests/test_view.py
+++ b/lms/djangoapps/course_home_api/outline/tests/test_view.py
@@ -293,7 +293,7 @@ def test_proctored_exam(self, mock_summary):
response = self.client.get(url)
assert response.status_code == 200
- exam_data = response.data['course_blocks']['blocks'][str(sequence.location)]
+ exam_data = response.data['course_blocks']['blocks'][str(sequence.usage_key)]
assert not exam_data['complete']
assert exam_data['description'] == 'My Exam'
assert exam_data['display_name'] == 'Test Proctored Exam'
@@ -303,14 +303,14 @@ def test_proctored_exam(self, mock_summary):
def test_assignment(self):
course = CourseFactory.create()
with self.store.bulk_operations(course.id):
- chapter = BlockFactory.create(category='chapter', parent_location=course.location)
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
sequential = BlockFactory.create(display_name='Test', category='sequential', graded=True, has_score=True,
- parent_location=chapter.location)
- BlockFactory.create(category='problem', graded=True, has_score=True, parent_location=sequential.location)
- BlockFactory.create(category='problem', graded=True, has_score=True, parent_location=sequential.location)
+ parent_location=chapter.usage_key)
+ BlockFactory.create(category='problem', graded=True, has_score=True, parent_location=sequential.usage_key)
+ BlockFactory.create(category='problem', graded=True, has_score=True, parent_location=sequential.usage_key)
sequential2 = BlockFactory.create(display_name='Ungraded', category='sequential',
- parent_location=chapter.location)
- BlockFactory.create(category='problem', parent_location=sequential2.location)
+ parent_location=chapter.usage_key)
+ BlockFactory.create(category='problem', parent_location=sequential2.usage_key)
update_outline_from_modulestore(course.id)
url = reverse('course-home:outline-tab', args=[course.id])
@@ -318,11 +318,11 @@ def test_assignment(self):
response = self.client.get(url)
assert response.status_code == 200
- exam_data = response.data['course_blocks']['blocks'][str(sequential.location)]
+ exam_data = response.data['course_blocks']['blocks'][str(sequential.usage_key)]
assert exam_data['display_name'] == 'Test (2 Questions)'
assert exam_data['icon'] == 'fa-pencil-square-o'
- ungraded_data = response.data['course_blocks']['blocks'][str(sequential2.location)]
+ ungraded_data = response.data['course_blocks']['blocks'][str(sequential2.usage_key)]
assert ungraded_data['display_name'] == 'Ungraded'
assert ungraded_data['icon'] is None
@@ -516,28 +516,28 @@ def add_blocks_to_course(self):
Add test blocks to the self course.
"""
with self.store.bulk_operations(self.course.id):
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
self.sequential = BlockFactory.create(
display_name='Test',
category='sequential',
graded=True,
has_score=True,
- parent_location=self.chapter.location
+ parent_location=self.chapter.usage_key
)
self.vertical = BlockFactory.create(
category='vertical',
graded=True,
has_score=True,
- parent_location=self.sequential.location
+ parent_location=self.sequential.usage_key
)
self.ungraded_sequential = BlockFactory.create(
display_name='Ungraded',
category='sequential',
- parent_location=self.chapter.location
+ parent_location=self.chapter.usage_key
)
self.ungraded_vertical = BlockFactory.create(
category='vertical',
- parent_location=self.ungraded_sequential.location
+ parent_location=self.ungraded_sequential.usage_key
)
update_outline_from_modulestore(self.course.id)
@@ -546,7 +546,7 @@ def create_completion(self, problem, completion):
user=self.user,
context_key=problem.context_key,
block_type='problem',
- block_key=problem.location,
+ block_key=problem.usage_key,
completion=completion,
)
@@ -561,13 +561,13 @@ def test_get_authenticated_enrolled_user(self, enrollment_mode):
response = self.client.get(self.url)
assert response.status_code == 200
- chapter_data = response.data['blocks'][str(self.chapter.location)]
- assert str(self.sequential.location) in chapter_data['children']
+ chapter_data = response.data['blocks'][str(self.chapter.usage_key)]
+ assert str(self.sequential.usage_key) in chapter_data['children']
- sequential_data = response.data['blocks'][str(self.sequential.location)]
- assert str(self.vertical.location) in sequential_data['children']
+ sequential_data = response.data['blocks'][str(self.sequential.usage_key)]
+ assert str(self.vertical.usage_key) in sequential_data['children']
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert vertical_data['children'] == []
@ddt.data(True, False)
@@ -663,7 +663,7 @@ def test_proctored_exam(self, mock_summary):
response = self.client.get(url)
assert response.status_code == 200
- exam_data = response.data['blocks'][str(sequence.location)]
+ exam_data = response.data['blocks'][str(sequence.usage_key)]
assert not exam_data['complete']
assert exam_data['display_name'] == 'Test Proctored Exam (1 Question)'
assert exam_data['special_exam_info'] == 'My Exam'
@@ -679,15 +679,15 @@ def test_assignment(self):
response = self.client.get(self.url)
assert response.status_code == 200
- exam_data = response.data['blocks'][str(self.sequential.location)]
+ exam_data = response.data['blocks'][str(self.sequential.usage_key)]
assert exam_data['display_name'] == 'Test'
assert exam_data['icon'] is None
- assert str(self.vertical.location) in exam_data['children']
+ assert str(self.vertical.usage_key) in exam_data['children']
- ungraded_data = response.data['blocks'][str(self.ungraded_sequential.location)]
+ ungraded_data = response.data['blocks'][str(self.ungraded_sequential.usage_key)]
assert ungraded_data['display_name'] == 'Ungraded'
assert ungraded_data['icon'] is None
- assert str(self.ungraded_vertical.location) in ungraded_data['children']
+ assert str(self.ungraded_vertical.usage_key) in ungraded_data['children']
@override_waffle_flag(COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, active=True)
@ddt.data(*itertools.product(
@@ -754,8 +754,8 @@ def test_empty_blocks_complete(self):
response = self.client.get(url)
assert response.status_code == 200
- sequence_data = response.data['blocks'][str(self.sequential.location)]
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ sequence_data = response.data['blocks'][str(self.sequential.usage_key)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert sequence_data['complete']
assert vertical_data['complete']
@@ -768,8 +768,8 @@ def test_blocks_complete_with_problem(self, problem_complete):
response = self.client.get(reverse('course-home:course-navigation', args=[self.course.id]))
- sequence_data = response.data['blocks'][str(self.sequential.location)]
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ sequence_data = response.data['blocks'][str(self.sequential.usage_key)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert sequence_data['complete'] == problem_complete
assert vertical_data['complete'] == problem_complete
@@ -807,8 +807,8 @@ def test_blocks_complete_with_library_content_block(
):
response = self.client.get(reverse('course-home:course-navigation', args=[self.course.id]))
- sequence_data = response.data['blocks'][str(self.sequential.location)]
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ sequence_data = response.data['blocks'][str(self.sequential.usage_key)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert sequence_data['complete'] == expected
assert vertical_data['complete'] == expected
@@ -834,8 +834,8 @@ def test_blocks_completion_stat(self):
'completion': 1,
'completable_children': 2,
}
- sequence_data = response.data['blocks'][str(self.sequential.location)]
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ sequence_data = response.data['blocks'][str(self.sequential.usage_key)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert not sequence_data['complete']
assert not vertical_data['complete']
@@ -863,8 +863,8 @@ def test_blocks_completion_stat_all_problem_completed(self):
'completion': 2,
'completable_children': 2,
}
- sequence_data = response.data['blocks'][str(self.sequential.location)]
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ sequence_data = response.data['blocks'][str(self.sequential.usage_key)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert sequence_data['complete']
assert vertical_data['complete']
@@ -886,7 +886,7 @@ def test_vertical_icon(self, block_categories, expected_icon):
BlockFactory.create(parent=self.vertical, category=category)
response = self.client.get(reverse('course-home:course-navigation', args=[self.course.id]))
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert vertical_data['icon'] == expected_icon
@@ -898,5 +898,5 @@ def test_vertical_icon_determined_by_icon_class(self):
BlockFactory.create(parent=self.vertical, category='html')
response = self.client.get(reverse('course-home:course-navigation', args=[self.course.id]))
- vertical_data = response.data['blocks'][str(self.vertical.location)]
+ vertical_data = response.data['blocks'][str(self.vertical.usage_key)]
assert vertical_data['icon'] == 'video'
diff --git a/lms/djangoapps/course_home_api/progress/serializers.py b/lms/djangoapps/course_home_api/progress/serializers.py
index 2aefe40d6a0b..b639558e1bd1 100644
--- a/lms/djangoapps/course_home_api/progress/serializers.py
+++ b/lms/djangoapps/course_home_api/progress/serializers.py
@@ -49,7 +49,7 @@ def get_override(self, subsection):
}
def get_block_key(self, subsection):
- return str(subsection.location)
+ return str(subsection.usage_key)
def get_problem_scores(self, subsection):
"""Problem scores for this subsection"""
@@ -72,7 +72,7 @@ def get_url(self, subsection):
and datetime.now(UTC) > hide_url_date):
return None
- relative_path = reverse('jump_to', args=[self.context['course_key'], subsection.location])
+ relative_path = reverse('jump_to', args=[self.context['course_key'], subsection.usage_key])
request = self.context['request']
return request.build_absolute_uri(relative_path)
@@ -81,7 +81,7 @@ def get_show_grades(self, subsection):
def get_learner_has_access(self, subsection):
course_blocks = self.context['course_blocks']
- return not course_blocks.get_xblock_field(subsection.location, 'contains_gated_content', False)
+ return not course_blocks.get_xblock_field(subsection.usage_key, 'contains_gated_content', False)
class SectionScoresSerializer(ReadOnlySerializer):
diff --git a/lms/djangoapps/course_home_api/progress/tests/test_views.py b/lms/djangoapps/course_home_api/progress/tests/test_views.py
index 79b6bb60da3c..1f5b59a20a1f 100644
--- a/lms/djangoapps/course_home_api/progress/tests/test_views.py
+++ b/lms/djangoapps/course_home_api/progress/tests/test_views.py
@@ -251,7 +251,7 @@ def test_override_is_visible(self):
params = {
"user_id": self.user.id,
- "usage_key": subsection.location,
+ "usage_key": subsection.usage_key,
"course_version": self.course.course_version,
"subtree_edited_timestamp": "2016-08-01 18:53:24.354741Z",
"earned_all": 6.0,
diff --git a/lms/djangoapps/course_wiki/tests/tests.py b/lms/djangoapps/course_wiki/tests/tests.py
index 7821f659d983..2f820ad4ccdd 100644
--- a/lms/djangoapps/course_wiki/tests/tests.py
+++ b/lms/djangoapps/course_wiki/tests/tests.py
@@ -61,7 +61,7 @@ def test_wiki_redirect(self):
# Now we test that the student will be redirected away from that page if the course doesn't exist
# We do this in the same test because we want to make sure the redirected_to is constructed correctly
# This is a location like /courses/*/wiki/* , but with an invalid course ID
- bad_course_wiki_page = redirected_to.replace(self.toy.location.course, "bad_course")
+ bad_course_wiki_page = redirected_to.replace(self.toy.usage_key.course, "bad_course")
resp = self.client.get(bad_course_wiki_page, HTTP_REFERER=referer)
assert resp.status_code == 302
diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py
index a1a46137fcca..ab37324b582d 100644
--- a/lms/djangoapps/courseware/access.py
+++ b/lms/djangoapps/courseware/access.py
@@ -208,7 +208,7 @@ def _can_view_courseware_with_prerequisites(user, course):
user (User): the user whose course access we are checking.
course (AType): the course for which we are checking access.
where AType is CourseBlock, CourseOverview, or any other
- class that represents a course and has the attributes .location
+ class that represents a course and has the attributes .usage_key
and .id.
"""
@@ -704,7 +704,7 @@ def _dispatch(table, action, user, obj):
debug("%s user %s, object %s, action %s",
'ALLOWED' if result else 'DENIED',
user,
- str(obj.location) if isinstance(obj, XBlock) else str(obj),
+ str(obj.usage_key) if isinstance(obj, XBlock) else str(obj),
action)
return result
@@ -789,7 +789,7 @@ def _has_instructor_access_to_block(user, block, course_key):
block: something that has a location attribute
"""
- return _has_instructor_access_to_location(user, block.location, course_key)
+ return _has_instructor_access_to_location(user, block.usage_key, course_key)
@function_trace('_has_staff_access_to_block')
@@ -799,7 +799,7 @@ def _has_staff_access_to_block(user, block, course_key):
block: something that has a location attribute
"""
- return _has_staff_access_to_location(user, block.location, course_key)
+ return _has_staff_access_to_location(user, block.usage_key, course_key)
def _visible_to_nonstaff_users(block, display_error_to_user=True):
@@ -828,7 +828,7 @@ def _can_access_block_with_milestones(user, block, course_key):
"""
if milestones_helpers.get_course_content_milestones(
course_key,
- str(block.location),
+ str(block.usage_key),
'requires',
user.id
):
diff --git a/lms/djangoapps/courseware/block_render.py b/lms/djangoapps/courseware/block_render.py
index 6a814fb3ef3c..eb526e4240de 100644
--- a/lms/djangoapps/courseware/block_render.py
+++ b/lms/djangoapps/courseware/block_render.py
@@ -198,7 +198,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
display_id = slugify(chapter.display_name_with_default_escaped)
local_hide_from_toc = False
if required_content:
- if str(chapter.location) not in required_content:
+ if str(chapter.usage_key) not in required_content:
local_hide_from_toc = True
# Skip the current chapter if a hide flag is tripped
@@ -274,7 +274,7 @@ def _add_timed_exam_info(user, course, section, section_context):
timed_exam_attempt_context = get_attempt_status_summary(
user.id,
str(course.id),
- str(section.location)
+ str(section.usage_key)
)
except Exception as ex: # pylint: disable=broad-except
# safety net in case something blows up in edx_proctoring
@@ -848,7 +848,7 @@ def _get_block_by_usage_key(usage_key):
'module': {
# xss-lint: disable=python-deprecated-display-name
'display_name': block.display_name_with_default_escaped,
- 'usage_key': str(block.location),
+ 'usage_key': str(block.usage_key),
}
}
diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py
index bbf9d5394705..60fb32c626ec 100644
--- a/lms/djangoapps/courseware/courses.py
+++ b/lms/djangoapps/courseware/courses.py
@@ -400,7 +400,7 @@ def get_course_about_section(request, course, section_key):
if section_key in html_sections:
try:
- loc = course.location.replace(category='about', name=section_key)
+ loc = course.usage_key.replace(category='about', name=section_key)
# Use an empty cache
field_data_cache = FieldDataCache([], course.id, request.user)
@@ -434,7 +434,7 @@ def get_course_about_section(request, course, section_key):
except ItemNotFoundError:
log.warning(
"Missing about section %s in course %s",
- section_key, str(course.location)
+ section_key, str(course.usage_key)
)
return None
@@ -895,7 +895,7 @@ def get_course_syllabus_section(course, section_key):
except ResourceNotFound:
log.exception(
"Missing syllabus section %s in course %s",
- section_key, str(course.location)
+ section_key, str(course.usage_key)
)
return "! Syllabus missing !"
@@ -988,7 +988,7 @@ def get_cms_block_link(block, page):
"""
# This is fragile, but unfortunately the problem is that within the LMS we
# can't use the reverse calls from the CMS
- return f"//{settings.CMS_BASE}/{page}/{block.location}"
+ return f"//{settings.CMS_BASE}/{page}/{block.usage_key}"
def get_studio_url(course, page):
@@ -1024,8 +1024,8 @@ def get_problems_in_section(section):
for subsection in section_block.get_children():
for vertical in subsection.get_children():
for component in vertical.get_children():
- if component.location.block_type == 'problem' and getattr(component, 'has_score', False):
- problem_blocks[str(component.location)] = component
+ if component.usage_key.block_type == 'problem' and getattr(component, 'has_score', False):
+ problem_blocks[str(component.usage_key)] = component
return problem_blocks
diff --git a/lms/djangoapps/courseware/field_overrides.py b/lms/djangoapps/courseware/field_overrides.py
index 60ffcafd25a5..122ab48a7df2 100644
--- a/lms/djangoapps/courseware/field_overrides.py
+++ b/lms/djangoapps/courseware/field_overrides.py
@@ -294,7 +294,7 @@ def _providers_for_block(cls, block):
Arguments:
block: An XBlock
"""
- course_id = str(block.location.course_key)
+ course_id = str(block.usage_key.course_key)
cache_key = ENABLED_MODULESTORE_OVERRIDE_PROVIDERS_KEY.format(course_id=course_id)
request_cache = DEFAULT_REQUEST_CACHE
diff --git a/lms/djangoapps/courseware/management/commands/dump_course_structure.py b/lms/djangoapps/courseware/management/commands/dump_course_structure.py
index a2ef76e88ea4..d77ffff5ac9c 100644
--- a/lms/djangoapps/courseware/management/commands/dump_course_structure.py
+++ b/lms/djangoapps/courseware/management/commands/dump_course_structure.py
@@ -94,8 +94,8 @@ def dump_block(block, destination=None, inherited=False, defaults=False):
filtered_metadata = {k: v for k, v in items.items() if k not in FILTER_LIST}
- destination[str(block.location)] = {
- 'category': block.location.block_type,
+ destination[str(block.usage_key)] = {
+ 'category': block.usage_key.block_type,
'children': [str(child) for child in getattr(block, 'children', [])],
'metadata': filtered_metadata,
}
@@ -117,7 +117,7 @@ def is_inherited(field):
return field.values != field.default
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
+ destination[str(block.usage_key)]['inherited_metadata'] = inherited_metadata
for child in block.get_children():
dump_block(child, destination, inherited, defaults)
diff --git a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py
index 97a20deac993..672c997ccd31 100644
--- a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py
+++ b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py
@@ -64,7 +64,7 @@ def load_courses(cls):
)
cls.discussion = BlockFactory.create(
- category='discussion', parent_location=cls.course.location
+ category='discussion', parent_location=cls.course.usage_key
)
courses = store.get_courses()
@@ -196,7 +196,7 @@ def test_dump_inherited_course_structure_with_defaults(self):
def test_export_discussion_ids(self):
output = self.call_command('dump_course_structure', str(self.course.id))
dump = json.loads(output)
- dumped_id = dump[str(self.discussion.location)]['metadata']['discussion_id']
+ dumped_id = dump[str(self.discussion.usage_key)]['metadata']['discussion_id']
assert dumped_id == self.discussion.discussion_id
def test_export_discussion_id_custom_id(self):
diff --git a/lms/djangoapps/courseware/migrations/0008_move_idde_to_edx_when.py b/lms/djangoapps/courseware/migrations/0008_move_idde_to_edx_when.py
index d0b9ea52b56e..a9d423f78d26 100644
--- a/lms/djangoapps/courseware/migrations/0008_move_idde_to_edx_when.py
+++ b/lms/djangoapps/courseware/migrations/0008_move_idde_to_edx_when.py
@@ -18,12 +18,12 @@ def move_overrides_to_edx_when(apps, schema_editor):
abs_date = date_field.from_json(json.loads(override.value))
api.set_date_for_block(
override.course_id,
- override.location,
+ override.usage_key,
'due',
abs_date,
user=override.student)
except Exception: # pylint: disable=broad-except
- log.exception("migrating %d %r: %r", override.id, override.location, override.value)
+ log.exception("migrating %d %r: %r", override.id, override.usage_key, override.value)
class Migration(migrations.Migration):
diff --git a/lms/djangoapps/courseware/model_data.py b/lms/djangoapps/courseware/model_data.py
index 59fcc725ed36..47cc281095ad 100644
--- a/lms/djangoapps/courseware/model_data.py
+++ b/lms/djangoapps/courseware/model_data.py
@@ -712,7 +712,7 @@ def add_blocks_to_cache(self, blocks):
Add all `blocks` to this FieldDataCache.
"""
if self.user.is_authenticated:
- self.scorable_locations.update(block.location for block in blocks if block.has_score)
+ self.scorable_locations.update(block.usage_key for block in blocks if block.has_score)
for scope, fields in self._fields_to_cache(blocks).items():
if scope not in self.cache:
continue
@@ -754,7 +754,7 @@ def get_child_blocks(block, depth, block_filter):
return blocks
- with modulestore().bulk_operations(block.location.course_key):
+ with modulestore().bulk_operations(block.usage_key.course_key):
blocks = get_child_blocks(block, depth, block_filter)
self.add_blocks_to_cache(blocks)
diff --git a/lms/djangoapps/courseware/student_field_overrides.py b/lms/djangoapps/courseware/student_field_overrides.py
index 2d5ad21fb985..ff1d7b2466a8 100644
--- a/lms/djangoapps/courseware/student_field_overrides.py
+++ b/lms/djangoapps/courseware/student_field_overrides.py
@@ -54,7 +54,7 @@ def _get_overrides_for_user(user, block):
):
location = block.scope_ids.usage_id.usage_key
else:
- location = block.location
+ location = block.usage_key
query = StudentFieldOverride.objects.filter(
course_id=block.scope_ids.usage_id.context_key,
@@ -77,7 +77,7 @@ def override_field_for_user(user, block, name, value):
"""
override, _ = StudentFieldOverride.objects.get_or_create(
course_id=block.scope_ids.usage_id.context_key,
- location=block.location,
+ location=block.usage_key,
student_id=user.id,
field=name)
field = block.fields[name]
@@ -96,7 +96,7 @@ def clear_override_for_user(user, block, name):
StudentFieldOverride.objects.get(
course_id=block.scope_ids.usage_id.context_key,
student_id=user.id,
- location=block.location,
+ location=block.usage_key,
field=name).delete()
except StudentFieldOverride.DoesNotExist:
pass
diff --git a/lms/djangoapps/courseware/tests/helpers.py b/lms/djangoapps/courseware/tests/helpers.py
index 4e325690cccd..4fb3c0a9da2c 100644
--- a/lms/djangoapps/courseware/tests/helpers.py
+++ b/lms/djangoapps/courseware/tests/helpers.py
@@ -77,7 +77,7 @@ def new_descriptor_runtime(self, **kwargs):
def initialize_module(self, runtime_kwargs=None, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring
kwargs.update({
- 'parent_location': self.section.location,
+ 'parent_location': self.section.usage_key,
'category': self.CATEGORY
})
@@ -94,7 +94,7 @@ def initialize_module(self, runtime_kwargs=None, **kwargs): # lint-amnesty, pyl
runtime_kwargs = {}
self.new_module_runtime(runtime=self.block.runtime, **runtime_kwargs)
- self.item_url = str(self.block.location)
+ self.item_url = str(self.block.usage_key)
def setup_course(self): # lint-amnesty, pylint: disable=missing-function-docstring
self.course = CourseFactory.create()
@@ -104,11 +104,11 @@ def setup_course(self): # lint-amnesty, pylint: disable=missing-function-docstr
modulestore().metadata_inheritance_cache_subsystem = None
chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="sequential",
)
self.section = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category="sequential"
)
diff --git a/lms/djangoapps/courseware/tests/pacts/views.py b/lms/djangoapps/courseware/tests/pacts/views.py
index 11ae2d07f7d9..711436524c45 100644
--- a/lms/djangoapps/courseware/tests/pacts/views.py
+++ b/lms/djangoapps/courseware/tests/pacts/views.py
@@ -38,12 +38,12 @@ def course_setup(self, request):
)
section = BlockFactory.create(
- parent_location=demo_course.location,
+ parent_location=demo_course.usage_key,
category="chapter",
)
BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="sequential",
display_name="basic_questions",
)
diff --git a/lms/djangoapps/courseware/tests/test_about.py b/lms/djangoapps/courseware/tests/test_about.py
index bd0c1854ab76..cd92dea2ee52 100644
--- a/lms/djangoapps/courseware/tests/test_about.py
+++ b/lms/djangoapps/courseware/tests/test_about.py
@@ -405,7 +405,7 @@ def test_html_sidebar_enabled(self, itemfactory_display_name, itemfactory_data,
if itemfactory_display_name:
BlockFactory.create(
category="about",
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name=itemfactory_display_name,
data=itemfactory_data,
)
diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py
index 8500c3fc2d7e..ebbb4ede117e 100644
--- a/lms/djangoapps/courseware/tests/test_access.py
+++ b/lms/djangoapps/courseware/tests/test_access.py
@@ -248,15 +248,15 @@ def test_student_has_access(self):
Tests course student have right access to content w/o preview.
"""
course_key = self.course.id
- chapter = BlockFactory.create(category="chapter", parent_location=self.course.location)
+ chapter = BlockFactory.create(category="chapter", parent_location=self.course.usage_key)
overview = CourseOverview.get_from_id(course_key)
- subsection = BlockFactory.create(category="sequential", parent_location=chapter.location)
- unit = BlockFactory.create(category="vertical", parent_location=subsection.location)
+ subsection = BlockFactory.create(category="sequential", parent_location=chapter.usage_key)
+ unit = BlockFactory.create(category="vertical", parent_location=subsection.usage_key)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
html_block = BlockFactory.create(
category="html",
- parent_location=unit.location,
+ parent_location=unit.usage_key,
display_name="Unpublished Block",
data='This block should not be published.
',
publish_item=False,
@@ -278,14 +278,14 @@ def test_student_has_access(self):
assert bool(access.has_access(
self.student,
'load',
- self.store.get_item(obj.location),
+ self.store.get_item(obj.usage_key),
course_key=self.course.id)
)
# If the document is not published yet, it should return an error when we try to fetch
# it from the store. This check confirms that the student would not be able to access it.
with pytest.raises(ItemNotFoundError):
- self.store.get_item(html_block.location)
+ self.store.get_item(html_block.usage_key)
def test_has_access_based_on_roles(self):
"""
@@ -322,7 +322,7 @@ def test_has_access_with_content_groups(self):
self.course.user_partitions.append(user_partition)
self.course.cohort_config = {'cohorted': True}
- chapter = BlockFactory.create(category="chapter", parent_location=self.course.location)
+ chapter = BlockFactory.create(category="chapter", parent_location=self.course.usage_key)
chapter.group_access = {partition_id: [group_0_id]}
modulestore().update_item(self.course, ModuleStoreEnum.UserID.test)
@@ -428,7 +428,7 @@ def test__has_access_to_block_staff_lock(self, visible_to_staff_only, start, exp
Tests that "visible_to_staff_only" overrides start date.
"""
expected_access = expected_error_type is None
- mock_unit = Mock(location=self.course.location, user_partitions=[])
+ mock_unit = Mock(location=self.course.usage_key, user_partitions=[])
mock_unit._class_tags = {} # Needed for detached check in _has_access_to_block
mock_unit.visible_to_staff_only = visible_to_staff_only
mock_unit.start = self.DATES[start]
@@ -460,7 +460,7 @@ def test__has_access_to_block_with_start_date(self, start, expected_error_type):
start date is in the past or not set.
"""
expected_access = expected_error_type is None
- mock_unit = Mock(location=self.course.location, user_partitions=[])
+ mock_unit = Mock(location=self.course.usage_key, user_partitions=[])
mock_unit._class_tags = {} # Needed for detached check in _has_access_to_block
mock_unit.visible_to_staff_only = False
mock_unit.start = self.DATES[start]
@@ -491,7 +491,7 @@ def test_enforce_masquerade_start_dates_flag(self, flag_active, is_masquerading,
When the flag is enabled, masquerading users see the same start date restrictions as regular students.
"""
mock_unit = Mock(
- location=self.course.location,
+ location=self.course.usage_key,
user_partitions=[],
_class_tags={},
start=self.DATES[start],
diff --git a/lms/djangoapps/courseware/tests/test_block_render.py b/lms/djangoapps/courseware/tests/test_block_render.py
index 7fedd97ed7c8..3467cb9bbcd4 100644
--- a/lms/djangoapps/courseware/tests/test_block_render.py
+++ b/lms/djangoapps/courseware/tests/test_block_render.py
@@ -562,7 +562,7 @@ def setUpClass(cls):
def setUp(self):
super().setUp()
- self.location = self.course_key.make_usage_key('chapter', 'Overview')
+ self.usage_key = self.course_key.make_usage_key('chapter', 'Overview')
self.mock_user = UserFactory.create()
self.request_factory = RequestFactoryNoCsrf()
@@ -625,7 +625,7 @@ def test_invalid_csrf_token(self):
response = render.handle_xblock_callback(
request,
str(self.course_key),
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'xmodule_handler',
'goto_position',
)
@@ -644,7 +644,7 @@ def test_valid_csrf_token(self):
response = render.handle_xblock_callback(
request,
str(self.course_key),
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'xmodule_handler',
'goto_position',
)
@@ -668,7 +668,7 @@ def test_too_many_files(self):
data={'file_id': (self._mock_file(), ) * (settings.MAX_FILEUPLOADS_PER_INPUT + 1)}
)
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': (f'Submission aborted! Maximum {settings.MAX_FILEUPLOADS_PER_INPUT:d} files may be submitted at once')}, indent=2) # pylint: disable=line-too-long
+ assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.usage_key)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': (f'Submission aborted! Maximum {settings.MAX_FILEUPLOADS_PER_INPUT:d} files may be submitted at once')}, indent=2) # pylint: disable=line-too-long
def test_too_large_file(self):
inputfile = self._mock_file(size=1 + settings.STUDENT_FILEUPLOAD_MAX_SIZE)
@@ -677,7 +677,7 @@ def test_too_large_file(self):
data={'file_id': inputfile}
)
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
+ assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.usage_key)), '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_xblock_dispatch(self):
request = self.request_factory.post('dummy_url', data={'position': 1})
@@ -685,7 +685,7 @@ def test_xblock_dispatch(self):
response = render.handle_xblock_callback(
request,
str(self.course_key),
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'xmodule_handler',
'goto_position',
)
@@ -698,7 +698,7 @@ def test_bad_course_id(self):
render.handle_xblock_callback(
request,
'bad_course_id',
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'xmodule_handler',
'goto_position',
)
@@ -722,7 +722,7 @@ def test_bad_xblock_dispatch(self):
render.handle_xblock_callback(
request,
str(self.course_key),
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'xmodule_handler',
'bad_dispatch',
)
@@ -734,7 +734,7 @@ def test_missing_handler(self):
render.handle_xblock_callback(
request,
str(self.course_key),
- quote_slashes(str(self.location)),
+ quote_slashes(str(self.usage_key)),
'bad_handler',
'bad_dispatch',
)
@@ -942,7 +942,7 @@ def test_anonymous_user_not_be_graded(self, mock_score_signal):
render.handle_xblock_callback(
request,
str(course.id),
- quote_slashes(str(block.location)),
+ quote_slashes(str(block.usage_key)),
'xmodule_handler',
'problem_check',
)
@@ -963,7 +963,7 @@ def test_will_recheck_access_handler_attribute(self, handler, will_recheck_acces
'parent': course,
}
block = BlockFactory.create(**block_kwargs)
- usage_id = str(block.location)
+ usage_id = str(block.usage_key)
# Send no special parameters, which will be invalid, but we don't care
request = self.request_factory.post('/', data='{}', content_type='application/json')
@@ -989,10 +989,10 @@ def setUpClass(cls):
def setUp(self):
super().setUp()
- self.location = str(self.course_key.make_usage_key('html', 'toyhtml'))
+ self.usage_key = str(self.course_key.make_usage_key('html', 'toyhtml'))
self.request_factory = RequestFactory()
- self.view_args = [str(self.course_key), quote_slashes(self.location), 'student_view']
+ self.view_args = [str(self.course_key), quote_slashes(self.usage_key), 'student_view']
self.xblock_view_url = reverse('xblock_view', args=self.view_args)
def test_xblock_view_handler(self):
@@ -1399,7 +1399,7 @@ def _setup_test_data(self, enrollment_mode, is_practice_exam, attempt_status):
exam_id = create_exam(
course_id=str(self.course_key),
- content_id=str(sequence.location.replace(branch=None, version=None)),
+ content_id=str(sequence.usage_key.replace(branch=None, version=None)),
exam_name='foo',
time_limit_mins=10,
is_proctored=True,
@@ -1472,8 +1472,8 @@ def setUp(self):
self.field_data_cache = FieldDataCache.cache_for_block_descendents(
self.course.id, self.request.user, self.course, depth=2
)
- gating_api.add_prerequisite(self.course.id, self.open_seq.location)
- gating_api.set_required_content(self.course.id, self.gated_seq.location, self.open_seq.location, 100)
+ gating_api.add_prerequisite(self.course.id, self.open_seq.usage_key)
+ gating_api.set_required_content(self.course.id, self.gated_seq.usage_key, self.open_seq.usage_key, 100)
def _find_url_name(self, toc, url_name):
"""
@@ -1537,7 +1537,7 @@ def setUp(self):
category='html',
data=self.content_string + self.rewrite_link + self.rewrite_bad_link + self.course_link
)
- self.location = self.block.location
+ self.usage_key = self.block.usage_key
self.field_data_cache = FieldDataCache.cache_for_block_descendents(
self.course.id,
self.user,
@@ -1548,7 +1548,7 @@ def test_xblock_display_wrapper_enabled(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
wrap_xblock_display=True,
)
@@ -1560,7 +1560,7 @@ def test_xmodule_display_wrapper_disabled(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
wrap_xblock_display=False,
)
@@ -1572,23 +1572,23 @@ def test_static_link_rewrite(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
- key = self.course.location
+ key = self.course.usage_key
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):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
- key = self.course.location
+ key = self.course.usage_key
assert f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block/file.jpg' in result_fragment.content
def test_static_asset_path_use(self):
@@ -1600,7 +1600,7 @@ def test_static_asset_path_use(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
static_asset_path="toy_course_dir",
)
@@ -1638,7 +1638,7 @@ def test_course_link_rewrite(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
@@ -1739,7 +1739,7 @@ def setUp(self):
display_name='Option Response Problem'
)
- self.location = self.block.location
+ self.usage_key = self.block.usage_key
self.field_data_cache = FieldDataCache.cache_for_block_descendents(
self.course.id,
self.user,
@@ -1751,7 +1751,7 @@ def test_staff_debug_info_disabled(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
@@ -1761,7 +1761,7 @@ def test_staff_debug_info_enabled(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
@@ -1793,7 +1793,7 @@ def test_staff_debug_info_score_for_invalid_dropdown(self):
block = render.get_block(
self.user,
self.request,
- problem_block.location,
+ problem_block.usage_key,
self.field_data_cache
)
html_fragment = block.render(STUDENT_VIEW)
@@ -1803,7 +1803,7 @@ def test_staff_debug_info_score_for_invalid_dropdown(self):
""")
- assert expected_score_override_html.format(block_id=problem_block.location.block_id) in\
+ assert expected_score_override_html.format(block_id=problem_block.usage_key.block_id) in\
html_fragment.content
@XBlock.register_temp_plugin(DetachedXBlock, identifier='detached-block')
@@ -1822,7 +1822,7 @@ def test_staff_debug_info_disabled_for_detached_blocks(self):
block = render.get_block(
self.user,
self.request,
- detached_block.location,
+ detached_block.usage_key,
field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
@@ -1833,7 +1833,7 @@ def test_histogram_disabled(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
result_fragment = block.render(STUDENT_VIEW)
@@ -1856,7 +1856,7 @@ def test_histogram_enabled_for_unscored_xblocks(self):
block = render.get_block(
self.user,
self.request,
- html_block.location,
+ html_block.usage_key,
field_data_cache,
)
block.render(STUDENT_VIEW)
@@ -1867,7 +1867,7 @@ def test_histogram_enabled_for_scored_xblocks(self):
StudentModuleFactory.create(
course_id=self.course.id,
- module_state_key=self.location,
+ module_state_key=self.usage_key,
student=UserFactory(),
grade=1,
max_grade=1,
@@ -1878,7 +1878,7 @@ def test_histogram_enabled_for_scored_xblocks(self):
block = render.get_block(
self.user,
self.request,
- self.location,
+ self.usage_key,
self.field_data_cache,
)
block.render(STUDENT_VIEW)
@@ -2063,7 +2063,7 @@ def handle_callback_and_get_context_info(self,
render.handle_xblock_callback(
self.request,
str(self.course.id),
- quote_slashes(str(block.location)),
+ quote_slashes(str(block.usage_key)),
'xmodule_handler',
'problem_check',
)
@@ -2122,12 +2122,12 @@ class TestXBlockRuntimeEvent(TestSubmittingProblems):
def setUp(self):
super().setUp()
self.homework = self.add_graded_section_to_course('homework')
- self.problem = self.add_dropdown_to_section(self.homework.location, 'p1', 1)
+ self.problem = self.add_dropdown_to_section(self.homework.usage_key, 'p1', 1)
self.grade_dict = {'value': 0.18, 'max_value': 32}
self.delete_dict = {'value': None, 'max_value': None}
def get_block_for_user(self, user):
- """Helper function to get useful block at self.location in self.course_id for user"""
+ """Helper function to get useful block at self.usage_key in self.course_id for user"""
mock_request = MagicMock()
mock_request.user = user
field_data_cache = FieldDataCache.cache_for_block_descendents(
@@ -2136,7 +2136,7 @@ def get_block_for_user(self, user):
return render.get_block(
user,
mock_request,
- self.problem.location,
+ self.problem.usage_key,
field_data_cache,
)
@@ -2149,7 +2149,7 @@ def set_block_grade_using_publish(self, grade_dict):
def test_xblock_runtime_publish(self):
"""Tests the publish mechanism"""
self.set_block_grade_using_publish(self.grade_dict)
- student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location)
+ student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.usage_key)
assert student_module.grade == self.grade_dict['value']
assert student_module.max_grade == self.grade_dict['max_value']
@@ -2157,7 +2157,7 @@ def test_xblock_runtime_publish_delete(self):
"""Test deleting the grade using the publish mechanism"""
block = self.set_block_grade_using_publish(self.grade_dict)
block.runtime.publish(block, 'grade', self.delete_dict)
- student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.location)
+ student_module = StudentModule.objects.get(student=self.student_user, module_state_key=self.problem.usage_key)
assert student_module.grade is None
assert student_module.max_grade is None
@@ -2173,7 +2173,7 @@ def test_score_change_signal(self, send_mock):
'weight': None,
'user_id': self.student_user.id,
'course_id': str(self.course.id),
- 'usage_id': str(self.problem.location),
+ 'usage_id': str(self.problem.usage_key),
'only_if_higher': None,
'modified': datetime.now().replace(tzinfo=pytz.UTC),
'score_db_table': 'csm',
@@ -2198,7 +2198,7 @@ def setUp(self):
self.anon_user = AnonymousUser()
def get_block_for_user(self, user, item=None):
- """Helper function to get useful block at self.location in self.course_id for user"""
+ """Helper function to get useful block at self.usage_key in self.course_id for user"""
mock_request = MagicMock()
mock_request.user = user
field_data_cache = FieldDataCache.cache_for_block_descendents(
@@ -2210,7 +2210,7 @@ def get_block_for_user(self, user, item=None):
return render.get_block(
user,
mock_request,
- item.location,
+ item.usage_key,
field_data_cache,
)
@@ -2285,7 +2285,7 @@ def test_event_publishing(self, mock_track_function):
course = CourseFactory()
block = BlockFactory(category='xblock', parent=course)
field_data_cache = FieldDataCache([course, block], course.id, self.mock_user)
- block = render.get_block(self.mock_user, request, block.location, field_data_cache)
+ block = render.get_block(self.mock_user, request, block.usage_key, field_data_cache)
event_type = 'event_type'
event = {'event': 'data'}
@@ -2881,7 +2881,7 @@ def test_cache(self):
def test_course_id(self):
block = BlockFactory(category="pure", parent=self.course)
- rendered_block = render.get_block(self.user, Mock(), block.location, None)
+ rendered_block = render.get_block(self.user, Mock(), block.usage_key, None)
assert str(rendered_block.scope_ids.usage_id.context_key) == self.COURSE_ID
with warnings.catch_warnings(): # For now, also test the deprecated accessor for backwards compatibility:
warnings.simplefilter("ignore", category=DeprecationWarning)
diff --git a/lms/djangoapps/courseware/tests/test_courses.py b/lms/djangoapps/courseware/tests/test_courses.py
index 72465b299ade..2e29dfee8873 100644
--- a/lms/djangoapps/courseware/tests/test_courses.py
+++ b/lms/djangoapps/courseware/tests/test_courses.py
@@ -72,7 +72,7 @@ def test_get_cms_course_block_link(self):
cms_url = f"//{CMS_BASE_TEST}/course/{str(self.course.id)}"
assert cms_url == get_cms_course_link(self.course)
- cms_url = f"//{CMS_BASE_TEST}/course/{str(self.course.location)}"
+ cms_url = f"//{CMS_BASE_TEST}/course/{str(self.course.usage_key)}"
assert cms_url == get_cms_block_link(self.course, 'course')
@ddt.data(GET_COURSE_WITH_ACCESS, GET_COURSE_OVERVIEW_WITH_ACCESS)
@@ -212,21 +212,21 @@ class MongoCourseImageTestCase(ModuleStoreTestCase):
def test_get_image_url(self):
"""Test image URL formatting."""
course = CourseFactory.create()
- key = course.location
+ key = course.usage_key
assert course_image_url(course) ==\
f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block@{course.course_image}'
def test_non_ascii_image_name(self):
# Verify that non-ascii image names are cleaned
course = CourseFactory.create(course_image='before_\N{SNOWMAN}_after.jpg')
- key = course.location
+ key = course.usage_key
assert course_image_url(course) ==\
f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block@before___after.jpg'
def test_spaces_in_image_name(self):
# Verify that image names with spaces in them are cleaned
course = CourseFactory.create(course_image='before after.jpg')
- key = course.location
+ key = course.usage_key
assert course_image_url(course) ==\
f'/asset-v1:{key.org}+{key.course}+{key.run}+type@asset+block@before_after.jpg'
@@ -421,7 +421,7 @@ def test_get_chapters(self):
course = CourseFactory()
BlockFactory(parent=course, category='chapter')
BlockFactory(parent=course, category='chapter')
- course_chapter_ids = get_course_chapter_ids(course.location.course_key)
+ course_chapter_ids = get_course_chapter_ids(course.usage_key.course_key)
assert len(course_chapter_ids) == 2
assert course_chapter_ids == [str(child) for child in course.children]
@@ -443,9 +443,9 @@ def test_completion_ignores_non_scored_items(self):
BlockFactory(parent=sequential, category='video', has_score=False)
self.override_waffle_switch(True)
- BlockCompletion.objects.submit_completion(self.user, problem.location, 1)
+ BlockCompletion.objects.submit_completion(self.user, problem.usage_key, 1)
- assignments = get_course_assignments(course.location.context_key, self.user, None)
+ assignments = get_course_assignments(course.usage_key.context_key, self.user, None)
assert len(assignments) == 1
assert assignments[0].complete
@@ -459,7 +459,7 @@ def test_completion_does_not_count_empty_sequentials(self):
chapter = BlockFactory(parent=course, category='chapter', graded=True, due=datetime.datetime.now())
BlockFactory(parent=chapter, category='sequential')
- assignments = get_course_assignments(course.location.context_key, self.user, None)
+ assignments = get_course_assignments(course.usage_key.context_key, self.user, None)
assert len(assignments) == 1
assert not assignments[0].complete
@@ -476,9 +476,9 @@ def test_completion_does_not_treat_unreleased_as_complete(self):
BlockFactory(parent=sequential, category='video', has_score=False)
self.override_waffle_switch(True)
- BlockCompletion.objects.submit_completion(self.user, problem.location, 1)
+ BlockCompletion.objects.submit_completion(self.user, problem.usage_key, 1)
- assignments = get_course_assignments(course.location.context_key, self.user, None)
+ assignments = get_course_assignments(course.usage_key.context_key, self.user, None)
assert len(assignments) == 1
assert not assignments[0].complete
@@ -588,10 +588,10 @@ def assert_ora_course_assignments(
"""
assert len(assignments) == 4
- assert assignments[0].block_key == self.subsection.location
- assert assignments[1].block_key == self.openassessment.location
- assert assignments[2].block_key == self.openassessment.location
- assert assignments[3].block_key == self.openassessment.location
+ assert assignments[0].block_key == self.subsection.usage_key
+ assert assignments[1].block_key == self.openassessment.usage_key
+ assert assignments[2].block_key == self.openassessment.usage_key
+ assert assignments[3].block_key == self.openassessment.usage_key
assert 'Submission' in assignments[1].title
assert 'Peer' in assignments[2].title
@@ -608,7 +608,7 @@ def test_ora_date_config__manual(self):
"""
self._setup_course()
self.assert_ora_course_assignments(
- get_course_assignments(self.course.location.context_key, self.user, None),
+ get_course_assignments(self.course.usage_key.context_key, self.user, None),
self.submission_due,
self.peer_due,
self.self_due
@@ -620,7 +620,7 @@ def test_ora_date_config__subsection(self):
"""
self._setup_course(date_config_type='subsection')
self.assert_ora_course_assignments(
- get_course_assignments(self.course.location.context_key, self.user, None),
+ get_course_assignments(self.course.usage_key.context_key, self.user, None),
self.subsection_due,
self.subsection_due,
self.subsection_due,
@@ -632,7 +632,7 @@ def test_ora_date_config__course_end(self):
"""
self._setup_course(date_config_type='course_end')
self.assert_ora_course_assignments(
- get_course_assignments(self.course.location.context_key, self.user, None),
+ get_course_assignments(self.course.usage_key.context_key, self.user, None),
self.course_end,
self.course_end,
self.course_end,
@@ -647,9 +647,9 @@ def test_course_end_none(self):
course_dates=(self._date(-1), None),
date_config_type='course_end'
)
- assignments = get_course_assignments(self.course.location.context_key, self.user, None)
+ assignments = get_course_assignments(self.course.usage_key.context_key, self.user, None)
assert len(assignments) == 1
- assert assignments[0].block_key == self.subsection.location
+ assert assignments[0].block_key == self.subsection.usage_key
def test_subsection_none(self):
"""
@@ -669,9 +669,9 @@ def test_subsection_none(self):
start=self._date(2),
due=self._date(3),
)
- assignments = get_course_assignments(self.course.location.context_key, self.user, None)
+ assignments = get_course_assignments(self.course.usage_key.context_key, self.user, None)
assert len(assignments) == 1
- assert assignments[0].block_key == subsection_2.location
+ assert assignments[0].block_key == subsection_2.usage_key
@ddt.data('manual', 'subsection', 'course_end')
def test_ora_steps_with_no_due_date(self, config_type):
@@ -693,9 +693,9 @@ def test_ora_steps_with_no_due_date(self, config_type):
)
# There are no dates for these other steps
- assignments = get_course_assignments(self.course.location.context_key, self.user, None)
+ assignments = get_course_assignments(self.course.usage_key.context_key, self.user, None)
assert len(assignments) == 4
- assert assignments[0].block_key == self.subsection.location
+ assert assignments[0].block_key == self.subsection.usage_key
assert 'Submission' in assignments[1].title
assert 'Peer' in assignments[2].title
assert 'Self' in assignments[3].title
diff --git a/lms/djangoapps/courseware/tests/test_date_summary.py b/lms/djangoapps/courseware/tests/test_date_summary.py
index 1762d37bdee0..62a9cae62c01 100644
--- a/lms/djangoapps/courseware/tests/test_date_summary.py
+++ b/lms/djangoapps/courseware/tests/test_date_summary.py
@@ -132,11 +132,11 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
now = datetime.now(utc)
assignment_title_html = ['']
with self.store.bulk_operations(course.id):
- section = BlockFactory.create(category='chapter', parent_location=course.location)
+ section = BlockFactory.create(category='chapter', parent_location=course.usage_key)
BlockFactory.create(
category='sequential',
display_name='Released',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now - timedelta(days=1),
due=now + timedelta(days=6),
graded=True,
@@ -145,7 +145,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
BlockFactory.create(
category='sequential',
display_name='Not released',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now + timedelta(days=1),
due=now + timedelta(days=7),
graded=True,
@@ -154,7 +154,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
BlockFactory.create(
category='sequential',
display_name='Third nearest assignment',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now + timedelta(days=1),
due=now + timedelta(days=8),
graded=True,
@@ -163,7 +163,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
BlockFactory.create(
category='sequential',
display_name='Past due date',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now - timedelta(days=14),
due=now - timedelta(days=7),
graded=True,
@@ -172,7 +172,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
BlockFactory.create(
category='sequential',
display_name='Not returned since we do not get non-graded subsections',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now + timedelta(days=1),
due=now - timedelta(days=7),
graded=False,
@@ -180,7 +180,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
BlockFactory.create(
category='sequential',
display_name='No start date',
- parent_location=section.location,
+ parent_location=section.usage_key,
start=None,
due=now + timedelta(days=9),
graded=True,
@@ -190,7 +190,7 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
category='sequential',
# Setting display name to None should set the assignment title to 'Assignment'
display_name=None,
- parent_location=section.location,
+ parent_location=section.usage_key,
start=now - timedelta(days=14),
due=now + timedelta(days=10),
graded=True,
@@ -199,9 +199,9 @@ def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many
dummy_subsection = BlockFactory.create(category='sequential', graded=True, due=now + timedelta(days=11))
# We are deleting this subsection right after creating it because we need to pass in a real
- # location object (dummy_subsection.location), but do not want this to exist inside of the modulestore
+ # location object (dummy_subsection.usage_key), but do not want this to exist inside of the modulestore
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course.id):
- self.store.delete_item(dummy_subsection.location, user.id)
+ self.store.delete_item(dummy_subsection.usage_key, user.id)
# Standard widget case where we restrict the number of assignments.
expected_blocks = (
diff --git a/lms/djangoapps/courseware/tests/test_discussion_xblock.py b/lms/djangoapps/courseware/tests/test_discussion_xblock.py
index da2a68ec1d77..a78db3d949f5 100644
--- a/lms/djangoapps/courseware/tests/test_discussion_xblock.py
+++ b/lms/djangoapps/courseware/tests/test_discussion_xblock.py
@@ -341,24 +341,24 @@ def test_discussion_render_successfully_with_orphan_parent(self):
vertical = self.store.create_child(
self.user.id,
- orphan_sequential.location,
+ orphan_sequential.usage_key,
'vertical',
- block_id=self.course.location.block_id
+ block_id=self.course.usage_key.block_id
)
discussion = self.store.create_child(
self.user.id,
- vertical.location,
+ vertical.usage_key,
'discussion',
- block_id=self.course.location.block_id
+ block_id=self.course.usage_key.block_id
)
- discussion = self.store.get_item(discussion.location)
+ discussion = self.store.get_item(discussion.usage_key)
root = self.get_root(discussion)
# Assert that orphan sequential is root of the discussion xblock.
- assert orphan_sequential.location.block_type == root.location.block_type
- assert orphan_sequential.location.block_id == root.location.block_id
+ assert orphan_sequential.usage_key.block_type == root.usage_key.block_type
+ assert orphan_sequential.usage_key.block_id == root.usage_key.block_id
# Get xblock bound to a user and a block.
discussion_xblock = get_block_for_descriptor(
@@ -406,7 +406,7 @@ def test_discussion_xblock_visibility(self):
Tests that the discussion xblock is hidden when discussion provider is openedx
"""
# Enable new OPEN_EDX provider for this course
- course_key = self.course.location.course_key
+ course_key = self.course.usage_key.course_key
DiscussionsConfiguration.objects.create(
context_key=course_key,
enabled=True,
diff --git a/lms/djangoapps/courseware/tests/test_entrance_exam.py b/lms/djangoapps/courseware/tests/test_entrance_exam.py
index 64bba8edfa52..3ad1d85acf4b 100644
--- a/lms/djangoapps/courseware/tests/test_entrance_exam.py
+++ b/lms/djangoapps/courseware/tests/test_entrance_exam.py
@@ -318,7 +318,7 @@ def test_entrance_exam_xblock_response(self):
Tests entrance exam xblock has `entrance_exam_passed` key in json response.
"""
request_factory = RequestFactoryNoCsrf()
- data = {f'input_{str(self.problem_1.location.html_id())}_2_1': 'choice_2'}
+ data = {f'input_{str(self.problem_1.usage_key.html_id())}_2_1': 'choice_2'}
request = request_factory.post(
'problem_check',
data=data
@@ -327,7 +327,7 @@ def test_entrance_exam_xblock_response(self):
response = handle_xblock_callback(
request,
str(self.course.id),
- str(self.problem_1.location),
+ str(self.problem_1.usage_key),
'xmodule_handler',
'problem_check',
)
@@ -417,7 +417,7 @@ def add_entrance_exam_milestone(course, entrance_exam):
)
add_course_content_milestone(
str(course.id),
- str(entrance_exam.location),
+ str(entrance_exam.usage_key),
milestone_relationship_types['FULFILLS'],
milestone
)
diff --git a/lms/djangoapps/courseware/tests/test_group_access.py b/lms/djangoapps/courseware/tests/test_group_access.py
index d2718ddabfa6..25eec74de6fa 100644
--- a/lms/djangoapps/courseware/tests/test_group_access.py
+++ b/lms/djangoapps/courseware/tests/test_group_access.py
@@ -133,10 +133,10 @@ def setUp(self):
vertical = BlockFactory.create(category='vertical', parent=section)
component = BlockFactory.create(category='problem', parent=vertical)
- self.chapter_location = chapter.location
- self.section_location = section.location
- self.vertical_location = vertical.location
- self.component_location = component.location
+ self.chapter_location = chapter.usage_key
+ self.section_location = section.usage_key
+ self.vertical_location = vertical.usage_key
+ self.component_location = component.usage_key
self.red_cat = UserFactory() # student in red and cat groups
self.set_user_group(self.red_cat, self.animal_partition, self.cat_group)
diff --git a/lms/djangoapps/courseware/tests/test_lti_integration.py b/lms/djangoapps/courseware/tests/test_lti_integration.py
index bdaf1a13549b..88359caa68ef 100644
--- a/lms/djangoapps/courseware/tests/test_lti_integration.py
+++ b/lms/djangoapps/courseware/tests/test_lti_integration.py
@@ -57,7 +57,7 @@ def setUp(self):
user_service = self.block.runtime.service(self.block, 'user')
user_id = str(user_service.get_current_user().opt_attrs.get(ATTR_KEY_ANONYMOUS_USER_ID))
hostname = settings.LMS_BASE
- resource_link_id = str(urllib.parse.quote(f'{hostname}-{self.block.location.html_id()}'))
+ resource_link_id = str(urllib.parse.quote(f'{hostname}-{self.block.usage_key.html_id()}'))
sourcedId = "{context}:{resource_link}:{user_id}".format(
context=urllib.parse.quote(context_id),
@@ -91,7 +91,7 @@ def setUp(self):
'display_name': self.block.display_name,
'input_fields': self.correct_headers,
'element_class': self.block.category,
- 'element_id': self.block.location.html_id(),
+ 'element_id': self.block.usage_key.html_id(),
'launch_url': 'http://www.example.com', # default value
'open_in_a_new_page': True,
'form_url': self.block.runtime.handler_url(
@@ -169,31 +169,31 @@ def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create(display_name=cls.COURSE_NAME, number=cls.COURSE_SLUG)
cls.chapter1 = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="chapter1",
category='chapter')
cls.section1 = BlockFactory.create(
- parent_location=cls.chapter1.location,
+ parent_location=cls.chapter1.usage_key,
display_name="section1",
category='sequential')
cls.chapter2 = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="chapter2",
category='chapter')
cls.section2 = BlockFactory.create(
- parent_location=cls.chapter2.location,
+ parent_location=cls.chapter2.usage_key,
display_name="section2",
category='sequential')
# creates one draft and one published lti block, in different sections
cls.lti_published = BlockFactory.create(
- parent_location=cls.section1.location,
+ parent_location=cls.section1.usage_key,
display_name="lti published",
category="lti",
location=cls.course.id.make_usage_key('lti', 'lti_published'),
)
cls.lti_draft = BlockFactory.create(
- parent_location=cls.section2.location,
+ parent_location=cls.section2.usage_key,
display_name="lti draft",
category="lti",
location=cls.course.id.make_usage_key('lti', 'lti_draft'),
diff --git a/lms/djangoapps/courseware/tests/test_masquerade.py b/lms/djangoapps/courseware/tests/test_masquerade.py
index 31fe714e2ae4..05c0b61677a6 100644
--- a/lms/djangoapps/courseware/tests/test_masquerade.py
+++ b/lms/djangoapps/courseware/tests/test_masquerade.py
@@ -50,22 +50,22 @@ def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create(number='masquerade-test', metadata={'start': datetime.now(UTC)})
cls.info_page = BlockFactory.create(
- category="course_info", parent_location=cls.course.location,
+ category="course_info", parent_location=cls.course.usage_key,
data="OOGIE BLOOGIE", display_name="updates"
)
cls.chapter = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
category="chapter",
display_name="Test Section",
)
cls.sequential_display_name = "Test Masquerade Subsection"
cls.sequential = BlockFactory.create(
- parent_location=cls.chapter.location,
+ parent_location=cls.chapter.usage_key,
category="sequential",
display_name=cls.sequential_display_name,
)
cls.vertical = BlockFactory.create(
- parent_location=cls.sequential.location,
+ parent_location=cls.sequential.usage_key,
category="vertical",
display_name="Test Unit",
)
@@ -78,7 +78,7 @@ def setUpClass(cls):
)
cls.problem_display_name = "TestMasqueradeProblem"
cls.problem = BlockFactory.create(
- parent_location=cls.vertical.location,
+ parent_location=cls.vertical.usage_key,
category='problem',
data=problem_xml,
display_name=cls.problem_display_name
@@ -99,8 +99,8 @@ def get_courseware_page(self):
'courseware_subsection',
kwargs={
'course_id': str(self.course.id),
- 'section': self.chapter.location.block_id,
- 'subsection': self.sequential.location.block_id,
+ 'section': self.chapter.usage_key.block_id,
+ 'subsection': self.sequential.usage_key.block_id,
}
)
return self.client.get(url)
@@ -145,7 +145,7 @@ def get_problem(self):
'xblock_handler',
kwargs={
'course_id': str(self.course.id),
- 'usage_id': str(self.problem.location),
+ 'usage_id': str(self.problem.usage_key),
'handler': 'xmodule_handler',
'suffix': 'problem_get'
}
diff --git a/lms/djangoapps/courseware/tests/test_services.py b/lms/djangoapps/courseware/tests/test_services.py
index b3e862142b41..61891be3884e 100644
--- a/lms/djangoapps/courseware/tests/test_services.py
+++ b/lms/djangoapps/courseware/tests/test_services.py
@@ -52,7 +52,7 @@ def setUp(self):
def _create_student_module(self, state):
StudentModuleFactory.create(
student=self.user,
- module_state_key=self.problem.location,
+ module_state_key=self.problem.usage_key,
course_id=self.course.id,
state=json.dumps(state)
)
@@ -90,7 +90,7 @@ def test_student_state(self, expected_state, should_use_email):
"""
self._create_student_module(expected_state)
state = UserStateService().get_state_as_dict(
- self._get_email_or_username(should_use_email), self.problem.location
+ self._get_email_or_username(should_use_email), self.problem.usage_key
)
self.assertDictEqual(state, expected_state)
@@ -118,7 +118,7 @@ def test_nonexistent_student_module_state(self, state_params, should_use_email):
"""
params = {
'username_or_email': self._get_email_or_username(should_use_email),
- 'block_id': self.problem.location
+ 'block_id': self.problem.usage_key
}
params.update(state_params)
self._create_student_module({'key_1': 'value_1'})
diff --git a/lms/djangoapps/courseware/tests/test_split_module.py b/lms/djangoapps/courseware/tests/test_split_module.py
index 5026f05ca221..a57acd4af548 100644
--- a/lms/djangoapps/courseware/tests/test_split_module.py
+++ b/lms/djangoapps/courseware/tests/test_split_module.py
@@ -47,12 +47,12 @@ def setUp(self):
user_partitions=[self.partition]
)
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="test chapter",
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Split Test Tests",
)
@@ -70,7 +70,7 @@ def _video(self, parent, group):
that is intended to be displayed to group ``group``.
"""
return BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
category="video",
display_name=f"Group {group} Sees This Video",
)
@@ -81,7 +81,7 @@ def _problem(self, parent, group):
that is intended to be displayed to group ``group``.
"""
return BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
category="problem",
display_name=f"Group {group} Sees This Problem",
data="No Problem Defined Yet!
",
@@ -93,7 +93,7 @@ def _html(self, parent, group):
that is intended to be displayed to group ``group``.
"""
return BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
category="html",
display_name=f"Group {group} Sees This HTML",
data=f"Some HTML for group {group}",
@@ -115,7 +115,7 @@ def _check_split_test(self, user_tag):
value=str(user_tag)
)
- resp = self.client.get(reverse('render_xblock', args=[str(self.sequential.location)]))
+ resp = self.client.get(reverse('render_xblock', args=[str(self.sequential.usage_key)]))
unicode_content = resp.content.decode(resp.charset)
# Assert we see the proper icon in the top display
@@ -167,7 +167,7 @@ def setUp(self):
c1_url = self.course.id.make_usage_key("vertical", "split_test_cond1")
split_test = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="split_test",
display_name="Split test",
user_partition_id=0,
@@ -175,7 +175,7 @@ def setUp(self):
)
cond0vert = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 0 vertical",
location=c0_url,
@@ -184,7 +184,7 @@ def setUp(self):
problem0 = self._problem(cond0vert, 0)
cond1vert = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 1 vertical",
location=c1_url,
@@ -193,13 +193,13 @@ def setUp(self):
html1 = self._html(cond1vert, 1)
self.included_usage_keys = [
- [video0.location, problem0.location],
- [video1.location, html1.location],
+ [video0.usage_key, problem0.usage_key],
+ [video1.usage_key, html1.usage_key],
]
self.excluded_usage_keys = [
- [video1.location, html1.location],
- [video0.location, problem0.location],
+ [video1.usage_key, html1.usage_key],
+ [video0.usage_key, problem0.usage_key],
]
@@ -232,7 +232,7 @@ def setUp(self):
super().setUp()
vert1 = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name="Split test vertical",
)
@@ -240,7 +240,7 @@ def setUp(self):
c1_url = self.course.id.make_usage_key("vertical", "split_test_cond1")
split_test = BlockFactory.create(
- parent_location=vert1.location,
+ parent_location=vert1.usage_key,
category="split_test",
display_name="Split test",
user_partition_id=0,
@@ -248,7 +248,7 @@ def setUp(self):
)
cond0vert = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 0 Vertical",
location=c0_url
@@ -257,7 +257,7 @@ def setUp(self):
problem0 = self._problem(cond0vert, 0)
cond1vert = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 1 Vertical",
location=c1_url
@@ -266,13 +266,13 @@ def setUp(self):
html1 = self._html(cond1vert, 1)
self.included_usage_keys = [
- [video0.location, problem0.location],
- [video1.location, html1.location],
+ [video0.usage_key, problem0.usage_key],
+ [video1.usage_key, html1.usage_key],
]
self.excluded_usage_keys = [
- [video1.location, html1.location],
- [video0.location, problem0.location],
+ [video1.usage_key, html1.usage_key],
+ [video0.usage_key, problem0.usage_key],
]
@@ -299,7 +299,7 @@ def setUpClass(cls):
)
cls.chapter = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
category="chapter",
display_name="test chapter",
)
diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py
index 1f1e35190050..dc6463487e38 100644
--- a/lms/djangoapps/courseware/tests/test_submitting_problems.py
+++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py
@@ -202,13 +202,13 @@ def add_graded_section_to_course(self, name, section_format='Homework', late=Fal
# if we don't already have a chapter create a new one
if not hasattr(self, 'chapter'):
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter'
)
if late:
section = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
display_name=name,
category='sequential',
metadata={
@@ -219,7 +219,7 @@ def add_graded_section_to_course(self, name, section_format='Homework', late=Fal
)
elif reset:
section = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
display_name=name,
category='sequential',
rerandomize='always',
@@ -231,7 +231,7 @@ def add_graded_section_to_course(self, name, section_format='Homework', late=Fal
elif showanswer:
section = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
display_name=name,
category='sequential',
showanswer='never',
@@ -243,7 +243,7 @@ def add_graded_section_to_course(self, name, section_format='Homework', late=Fal
else:
section = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
display_name=name,
category='sequential',
metadata={'graded': True, 'format': section_format}
@@ -313,7 +313,7 @@ class TestCourseGrades(TestSubmittingProblems):
def setUp(self):
super().setUp()
self.homework = self.add_graded_section_to_course('homework')
- self.problem = self.add_dropdown_to_section(self.homework.location, 'p1', 1)
+ self.problem = self.add_dropdown_to_section(self.homework.usage_key, 'p1', 1)
def _submit_correct_answer(self):
"""
@@ -370,9 +370,9 @@ def basic_setup(self, late=False, reset=False, showanswer=False):
# set up a simple course with four problems
self.homework = self.add_graded_section_to_course('homework', late=late, reset=reset, showanswer=showanswer)
- self.add_dropdown_to_section(self.homework.location, 'p1', 1)
- self.add_dropdown_to_section(self.homework.location, 'p2', 1)
- self.add_dropdown_to_section(self.homework.location, 'p3', 1)
+ self.add_dropdown_to_section(self.homework.usage_key, 'p1', 1)
+ self.add_dropdown_to_section(self.homework.usage_key, 'p2', 1)
+ self.add_dropdown_to_section(self.homework.usage_key, 'p3', 1)
self.refresh_course()
def weighted_setup(self, hw_weight=0.25, final_weight=0.75):
@@ -384,9 +384,9 @@ def weighted_setup(self, hw_weight=0.25, final_weight=0.75):
# set up a structure of 1 homework and 1 final
self.homework = self.add_graded_section_to_course('homework')
- self.problem = self.add_dropdown_to_section(self.homework.location, 'H1P1')
+ self.problem = self.add_dropdown_to_section(self.homework.usage_key, 'H1P1')
self.final = self.add_graded_section_to_course('Final Section', 'Final')
- self.final_question = self.add_dropdown_to_section(self.final.location, 'FinalQuestion')
+ self.final_question = self.add_dropdown_to_section(self.final.usage_key, 'FinalQuestion')
def set_weighted_policy(self, hw_weight=0.25, final_weight=0.75):
"""
@@ -445,12 +445,12 @@ def dropping_setup(self):
self.homework2 = self.add_graded_section_to_course('homework2')
self.homework3 = self.add_graded_section_to_course('homework3')
- self.add_dropdown_to_section(self.homework1.location, self.hw1_names[0], 1)
- self.add_dropdown_to_section(self.homework1.location, self.hw1_names[1], 1)
- self.add_dropdown_to_section(self.homework2.location, self.hw2_names[0], 1)
- self.add_dropdown_to_section(self.homework2.location, self.hw2_names[1], 1)
- self.add_dropdown_to_section(self.homework3.location, self.hw3_names[0], 1)
- self.add_dropdown_to_section(self.homework3.location, self.hw3_names[1], 1)
+ self.add_dropdown_to_section(self.homework1.usage_key, self.hw1_names[0], 1)
+ self.add_dropdown_to_section(self.homework1.usage_key, self.hw1_names[1], 1)
+ self.add_dropdown_to_section(self.homework2.usage_key, self.hw2_names[0], 1)
+ self.add_dropdown_to_section(self.homework2.usage_key, self.hw2_names[1], 1)
+ self.add_dropdown_to_section(self.homework3.usage_key, self.hw3_names[0], 1)
+ self.add_dropdown_to_section(self.homework3.usage_key, self.hw3_names[1], 1)
def test_submission_late(self):
"""Test problem for due date in the past"""
@@ -775,7 +775,7 @@ def problem_setup(self, name, files):
allowed_files=files, required_files=files,
)
BlockFactory.create(
- parent_location=self.section.location,
+ parent_location=self.section.usage_key,
category='problem',
display_name=name,
data=xmldata
@@ -922,7 +922,7 @@ def schematic_setup(self, name):
xmldata = SchematicResponseXMLFactory().build_xml(answer=script)
BlockFactory.create(
- parent_location=self.section.location,
+ parent_location=self.section.usage_key,
category='problem',
display_name=name,
data=xmldata
@@ -945,7 +945,7 @@ def custom_response_setup(self, name):
cfn_problem_xml = CustomResponseXMLFactory().build_xml(script=test_csv, cfn='test_csv', expect=expect)
BlockFactory.create(
- parent_location=self.section.location,
+ parent_location=self.section.usage_key,
category='problem',
data=cfn_problem_xml,
display_name=name
@@ -968,7 +968,7 @@ def computed_answer_setup(self, name):
computed_xml = CustomResponseXMLFactory().build_xml(answer=script)
BlockFactory.create(
- parent_location=self.section.location,
+ parent_location=self.section.usage_key,
category='problem',
data=computed_xml,
display_name=name
@@ -1101,7 +1101,7 @@ def setUp(self):
self.add_grading_policy(grading_policy)
self.homework_all = self.add_graded_section_to_course('homework1')
- self.p1_all_html_id = self.add_dropdown_to_section(self.homework_all.location, 'H1P1', 2).location.html_id()
+ self.p1_all_html_id = self.add_dropdown_to_section(self.homework_all.usage_key, 'H1P1', 2).usage_key.html_id()
self.homework_conditional = self.add_graded_section_to_course('homework2')
@@ -1120,7 +1120,7 @@ def split_setup(self, user_partition_group):
group_id_to_child[str(index)] = url
split_test = BlockFactory.create(
- parent_location=self.homework_conditional.location,
+ parent_location=self.homework_conditional.usage_key,
category="split_test",
display_name="Split test",
user_partition_id=0,
@@ -1128,14 +1128,14 @@ def split_setup(self, user_partition_group):
)
vertical_0 = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 0 vertical",
location=vertical_0_url,
)
vertical_1 = BlockFactory.create(
- parent_location=split_test.location,
+ parent_location=split_test.usage_key,
category="vertical",
display_name="Condition 1 vertical",
location=vertical_1_url,
@@ -1166,11 +1166,11 @@ def split_different_problems_setup(self, user_partition_group):
vertical_0, vertical_1 = self.split_setup(user_partition_group)
# Group 0 will have 2 problems in the section, worth a total of 4 points.
- self.add_dropdown_to_section(vertical_0.location, 'H2P1_GROUP0', 1).location.html_id()
- self.add_dropdown_to_section(vertical_0.location, 'H2P2_GROUP0', 3).location.html_id()
+ self.add_dropdown_to_section(vertical_0.usage_key, 'H2P1_GROUP0', 1).usage_key.html_id()
+ self.add_dropdown_to_section(vertical_0.usage_key, 'H2P2_GROUP0', 3).usage_key.html_id()
# Group 1 will have 1 problem in the section, worth a total of 1 point.
- self.add_dropdown_to_section(vertical_1.location, 'H2P1_GROUP1', 1).location.html_id()
+ self.add_dropdown_to_section(vertical_1.usage_key, 'H2P1_GROUP1', 1).usage_key.html_id()
# Submit answers for problem in Section 1, which is visible to all students.
self.submit_question_answer('H1P1', {'2_1': 'Correct', '2_2': 'Incorrect'})
@@ -1228,7 +1228,7 @@ def split_one_group_no_problems_setup(self, user_partition_group):
[_, vertical_1] = self.split_setup(user_partition_group)
# Group 1 will have 1 problem in the section, worth a total of 1 point.
- self.add_dropdown_to_section(vertical_1.location, 'H2P1_GROUP1', 1).location.html_id()
+ self.add_dropdown_to_section(vertical_1.usage_key, 'H2P1_GROUP1', 1).usage_key.html_id()
self.submit_question_answer('H1P1', {'2_1': 'Correct'})
diff --git a/lms/djangoapps/courseware/tests/test_tabs.py b/lms/djangoapps/courseware/tests/test_tabs.py
index e332d0de96de..7f8c360a2114 100644
--- a/lms/djangoapps/courseware/tests/test_tabs.py
+++ b/lms/djangoapps/courseware/tests/test_tabs.py
@@ -244,7 +244,7 @@ def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
cls.page = BlockFactory.create(
- category="static_tab", parent_location=cls.course.location,
+ category="static_tab", parent_location=cls.course.usage_key,
data="OOGIE BLOOGIE", display_name="new_tab"
)
cls.course.tabs.append(xmodule_tabs.CourseTab.load('static_tab', name='New Tab', url_slug='new_tab'))
@@ -348,11 +348,11 @@ def setUp(self):
self.course = CourseFactory.create()
self.extra_tab_2 = BlockFactory.create(
- category="static_tab", parent_location=self.course.location,
+ category="static_tab", parent_location=self.course.usage_key,
data="Extra Tab", display_name="Extra Tab 2"
)
self.extra_tab_3 = BlockFactory.create(
- category="static_tab", parent_location=self.course.location,
+ category="static_tab", parent_location=self.course.usage_key,
data="Extra Tab", display_name="Extra Tab 3"
)
self.setup_user()
@@ -367,7 +367,7 @@ def test_get_course_tabs_list_entrance_exam_enabled(self):
"""
entrance_exam = BlockFactory.create(
category="chapter",
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name="Entrance Exam",
is_entrance_exam=True
)
@@ -378,7 +378,7 @@ def test_get_course_tabs_list_entrance_exam_enabled(self):
}
self.user.is_staff = False
self.course.entrance_exam_enabled = True
- self.course.entrance_exam_id = str(entrance_exam.location)
+ self.course.entrance_exam_id = str(entrance_exam.usage_key)
milestone = add_milestone(milestone)
add_course_milestone(
str(self.course.id),
@@ -387,7 +387,7 @@ def test_get_course_tabs_list_entrance_exam_enabled(self):
)
add_course_content_milestone(
str(self.course.id),
- str(entrance_exam.location),
+ str(entrance_exam.usage_key),
self.relationship_types['FULFILLS'],
milestone
)
diff --git a/lms/djangoapps/courseware/tests/test_video_handlers.py b/lms/djangoapps/courseware/tests/test_video_handlers.py
index cfbafe34b676..a8c18937e9e1 100644
--- a/lms/djangoapps/courseware/tests/test_video_handlers.py
+++ b/lms/djangoapps/courseware/tests/test_video_handlers.py
@@ -252,7 +252,7 @@ def get_handler_url(self, handler, suffix):
).rstrip('/?')
def tearDown(self):
- _clear_assets(self.block.location)
+ _clear_assets(self.block.usage_key)
super().tearDown()
@@ -285,7 +285,7 @@ def setUp(self):
def test_available_translation_en(self):
good_sjson = _create_file(json.dumps(self.subs))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.sub = _get_subs_id(good_sjson.name)
request = Request.blank('/available_translations')
@@ -293,7 +293,7 @@ def test_available_translation_en(self):
assert json.loads(response.body.decode('utf-8')) == ['en']
def test_available_translation_non_en(self):
- _upload_file(_create_srt_file(), self.block.location, os.path.split(self.srt_file.name)[1])
+ _upload_file(_create_srt_file(), self.block.usage_key, os.path.split(self.srt_file.name)[1])
request = Request.blank('/available_translations')
response = self.block.transcript(request=request, dispatch='available_translations')
@@ -313,10 +313,10 @@ def test_multiple_available_translations(self, mock_get_video_transcript_content
good_sjson = _create_file(json.dumps(self.subs))
# Upload english transcript.
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
# Upload non-english transcript.
- _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1])
+ _upload_file(self.srt_file, self.block.usage_key, os.path.split(self.srt_file.name)[1])
self.block.sub = _get_subs_id(good_sjson.name)
self.block.edx_video_id = 'an-edx-video-id'
@@ -376,13 +376,13 @@ def test_val_available_translations(
for lang_code, in_content_store in dict(transcripts).items():
if in_content_store:
file_name, __ = os.path.split(self.srt_file.name)
- _upload_file(self.srt_file, self.block.location, file_name)
+ _upload_file(self.srt_file, self.block.usage_key, file_name)
transcripts[lang_code] = file_name
else:
transcripts[lang_code] = 'non_existent.srt.sjson'
if sub:
sjson_transcript = _create_file(json.dumps(self.subs))
- _upload_sjson_file(sjson_transcript, self.block.location)
+ _upload_sjson_file(sjson_transcript, self.block.usage_key)
sub = _get_subs_id(sjson_transcript.name)
mock_get_video_transcript_content.return_value = {
@@ -444,7 +444,7 @@ def setUp(self):
@ddt.data("en", "uk")
def test_available_translation_en_and_non_en(self, lang):
filename = os.path.split(self.srt_file.name)[1]
- _upload_file(self.srt_file, self.block.location, filename)
+ _upload_file(self.srt_file, self.block.usage_key, filename)
self.block.video_bumper["transcripts"][lang] = filename
request = Request.blank('/' + self.dispatch)
@@ -463,10 +463,10 @@ def test_multiple_available_translations(self, mock_get_transcript_languages):
en_translation_filename = os.path.split(en_translation.name)[1]
uk_translation_filename = os.path.split(self.srt_file.name)[1]
# Upload english transcript.
- _upload_file(en_translation, self.block.location, en_translation_filename)
+ _upload_file(en_translation, self.block.usage_key, en_translation_filename)
# Upload non-english transcript.
- _upload_file(self.srt_file, self.block.location, uk_translation_filename)
+ _upload_file(self.srt_file, self.block.usage_key, uk_translation_filename)
self.block.video_bumper["transcripts"]["en"] = en_translation_filename
self.block.video_bumper["transcripts"]["uk"] = uk_translation_filename
@@ -650,7 +650,7 @@ def test_translation_fails(self, url, dispatch, status_code):
def test_translaton_en_youtube_success(self, url, dispatch, attach):
subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]}
good_sjson = _create_file(json.dumps(subs))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
subs_id = _get_subs_id(good_sjson.name)
attach(self.block, subs_id)
@@ -667,7 +667,7 @@ def test_translation_non_en_youtube_success(self):
]
}
self.srt_file.seek(0)
- _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1])
+ _upload_file(self.srt_file, self.block.usage_key, os.path.split(self.srt_file.name)[1])
subs_id = _get_subs_id(self.srt_file.name)
# youtube 1_0 request, will generate for all speeds for existing ids
@@ -710,7 +710,7 @@ def test_translation_non_en_youtube_success(self):
@ddt.unpack
def test_translaton_en_html5_success(self, url, dispatch, attach):
good_sjson = _create_file(json.dumps(TRANSCRIPT))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
subs_id = _get_subs_id(good_sjson.name)
attach(self.block, subs_id)
@@ -728,7 +728,7 @@ def test_translaton_non_en_html5_success(self):
]
}
self.srt_file.seek(0)
- _upload_file(self.srt_file, self.block.location, os.path.split(self.srt_file.name)[1])
+ _upload_file(self.srt_file, self.block.usage_key, os.path.split(self.srt_file.name)[1])
# manually clean youtube_id_1_0, as it has default value
self.block.youtube_id_1_0 = ""
@@ -900,7 +900,7 @@ def test_translation_fails(self):
# Correct case:
filename = os.path.split(self.srt_file.name)[1]
- _upload_file(self.srt_file, self.block.location, filename)
+ _upload_file(self.srt_file, self.block.usage_key, filename)
request = Request.blank("translation?language_code=uk")
response = self.block.studio_transcript(request=request, dispatch="translation?language_code=uk")
self.srt_file.seek(0)
@@ -911,7 +911,7 @@ def test_translation_fails(self):
# Non ascii file name download:
self.srt_file.seek(0)
- _upload_file(self.srt_file, self.block.location, "塞.srt")
+ _upload_file(self.srt_file, self.block.usage_key, "塞.srt")
request = Request.blank("translation?language_code=zh")
response = self.block.studio_transcript(request=request, dispatch="translation?language_code=zh")
self.srt_file.seek(0)
@@ -1098,8 +1098,8 @@ def test_translation_delete_wo_edx_video_id(self):
request = Request(self.REQUEST_META, body=request_body.encode('utf-8'))
# upload and verify that srt file exists in assets
- _upload_file(self.SRT_FILE, self.block.location, srt_file_name_uk)
- assert _check_asset(self.block.location, srt_file_name_uk)
+ _upload_file(self.SRT_FILE, self.block.usage_key, srt_file_name_uk)
+ assert _check_asset(self.block.usage_key, srt_file_name_uk)
# verify transcripts field
assert self.block.transcripts != {}
@@ -1111,7 +1111,7 @@ def test_translation_delete_wo_edx_video_id(self):
# verify that srt file is deleted
assert self.block.transcripts == {}
- assert not _check_asset(self.block.location, srt_file_name_uk)
+ assert not _check_asset(self.block.usage_key, srt_file_name_uk)
def test_translation_delete_w_english_lang(self):
"""
@@ -1123,8 +1123,8 @@ def test_translation_delete_w_english_lang(self):
request = Request(self.REQUEST_META, body=request_body.encode('utf-8'))
# upload and verify that srt file exists in assets
- _upload_file(self.SRT_FILE, self.block.location, srt_file_name_en)
- assert _check_asset(self.block.location, srt_file_name_en)
+ _upload_file(self.SRT_FILE, self.block.usage_key, srt_file_name_en)
+ assert _check_asset(self.block.usage_key, srt_file_name_en)
# make request and verify response
response = self.block.studio_transcript(request=request, dispatch='translation')
@@ -1132,7 +1132,7 @@ def test_translation_delete_w_english_lang(self):
# verify that srt file is deleted
assert self.LANGUAGE_CODE_EN not in self.block.transcripts
- assert not _check_asset(self.block.location, srt_file_name_en)
+ assert not _check_asset(self.block.usage_key, srt_file_name_en)
def test_translation_delete_w_sub(self):
"""
@@ -1147,8 +1147,8 @@ def test_translation_delete_w_sub(self):
# lint-amnesty, pylint: disable=wrong-assert-type
# upload and verify that srt file exists in assets
- _upload_file(self.SRT_FILE, self.block.location, sub_file_name)
- assert _check_asset(self.block.location, sub_file_name)
+ _upload_file(self.SRT_FILE, self.block.usage_key, sub_file_name)
+ assert _check_asset(self.block.usage_key, sub_file_name)
# make request and verify response
response = self.block.studio_transcript(request=request, dispatch='translation')
@@ -1157,7 +1157,7 @@ def test_translation_delete_w_sub(self):
# verify that sub is empty and transcript is deleted also
assert self.block.sub == ''
# lint-amnesty, pylint: disable=wrong-assert-type
- assert not _check_asset(self.block.location, sub_file_name)
+ assert not _check_asset(self.block.usage_key, sub_file_name)
class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inherits-tests
@@ -1206,7 +1206,7 @@ def test_good_transcript(self):
}
"""))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.sub = _get_subs_id(good_sjson.name)
text, filename, mime_type = get_transcript(self.block)
@@ -1244,7 +1244,7 @@ def test_good_txt_transcript(self):
}
"""))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.sub = _get_subs_id(good_sjson.name)
text, filename, mime_type = get_transcript(self.block, output_format=Transcript.TXT)
expected_text = textwrap.dedent("""\
@@ -1285,7 +1285,7 @@ def test_en_with_empty_sub(self):
]
}
"""))
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.youtube_id_1_0 = _get_subs_id(good_sjson.name)
text, filename, mime_type = get_transcript(self.block)
@@ -1307,7 +1307,7 @@ def test_en_with_empty_sub(self):
def test_non_en_with_non_ascii_filename(self):
self.block.transcript_language = 'zh'
self.srt_file.seek(0)
- _upload_file(self.srt_file, self.block.location, "塞.srt")
+ _upload_file(self.srt_file, self.block.usage_key, "塞.srt")
transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable
text, filename, mime_type = get_transcript(self.block)
@@ -1323,7 +1323,7 @@ def test_non_en_with_non_ascii_filename(self):
def test_value_error_handled(self):
good_sjson = _create_file(content='bad content')
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.sub = _get_subs_id(good_sjson.name)
transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable
@@ -1345,7 +1345,7 @@ def test_key_error(self):
}
""")
- _upload_sjson_file(good_sjson, self.block.location)
+ _upload_sjson_file(good_sjson, self.block.usage_key)
self.block.sub = _get_subs_id(good_sjson.name)
transcripts = self.block.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable
diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py
index 5e730312fa27..0aca0622695c 100644
--- a/lms/djangoapps/courseware/tests/test_video_mongo.py
+++ b/lms/djangoapps/courseware/tests/test_video_mongo.py
@@ -93,8 +93,8 @@ def test_video_constructor(self, mock_render_django_template):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -102,7 +102,7 @@ def test_video_constructor(self, mock_render_django_template):
'is_video_from_same_origin': False,
'handout': None,
'hide_downloads': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'is_embed': False,
'metadata': json.dumps(OrderedDict({
'autoAdvance': False,
@@ -184,8 +184,8 @@ def test_video_constructor(self, mock_render_django_template):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -194,7 +194,7 @@ def test_video_constructor(self, mock_render_django_template):
'handout': None,
'hide_downloads': False,
'is_embed': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'metadata': json.dumps(OrderedDict({
'autoAdvance': False,
'saveStateEnabled': True,
@@ -270,12 +270,12 @@ def test_is_public_sharing_enabled(self, feature_enabled):
"""Test public video url."""
assert self.block.public_access is True
with self.mock_feature_toggle(enabled=feature_enabled):
- assert sharing.is_public_sharing_enabled(self.block.location, self.block.public_access) == feature_enabled
+ assert sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access) == feature_enabled
def test_is_public_sharing_enabled__not_public(self):
self.block.public_access = False
with self.mock_feature_toggle():
- assert not sharing.is_public_sharing_enabled(self.block.location, self.block.public_access)
+ assert not sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access)
@patch('openedx.core.djangoapps.video_config.sharing.get_course_video_sharing_override')
def test_is_public_sharing_enabled_by_course_override(self, mock_course_sharing_override):
@@ -286,7 +286,7 @@ def test_is_public_sharing_enabled_by_course_override(self, mock_course_sharing_
# When I try to determine if public sharing is enabled
with self.mock_feature_toggle():
- is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.location, self.block.public_access)
+ is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access)
# Then I will get that course value
self.assertTrue(is_public_sharing_enabled)
@@ -299,7 +299,7 @@ def test_is_public_sharing_disabled_by_course_override(self, mock_course_sharing
# When I try to determine if public sharing is enabled
with self.mock_feature_toggle():
- is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.location, self.block.public_access)
+ is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access)
# Then I will get that course value
self.assertFalse(is_public_sharing_enabled)
@@ -313,7 +313,7 @@ def test_is_public_sharing_enabled_per_video(self, mock_override_value, mock_cou
# When I try to determine if public sharing is enabled
with self.mock_feature_toggle():
- is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.location, self.block.public_access)
+ is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access)
# I will get the per-video value
self.assertEqual(self.block.public_access, is_public_sharing_enabled)
@@ -326,7 +326,7 @@ def test_is_public_sharing_course_not_found(self, mock_get_course):
# When I try to determine if public sharing is enabled
with self.mock_feature_toggle():
- is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.location, self.block.public_access)
+ is_public_sharing_enabled = sharing.is_public_sharing_enabled(self.block.usage_key, self.block.public_access)
# I will fall-back to per-video values
self.assertEqual(self.block.public_access, is_public_sharing_enabled)
@@ -469,8 +469,8 @@ def test_get_html_track(self, mock_render_django_template):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -478,7 +478,7 @@ def test_get_html_track(self, mock_render_django_template):
'is_video_from_same_origin': False,
'handout': None,
'hide_downloads': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'is_embed': False,
'metadata': '',
'track': None,
@@ -524,9 +524,9 @@ def test_get_html_track(self, mock_render_django_template):
'track': (
track_url if data['expected_track_url'] == 'a_sub_file.srt.sjson' else data['expected_track_url']
),
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'metadata': json.dumps(metadata)
})
@@ -604,8 +604,8 @@ def test_get_html_source(self, mock_render_django_template):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -613,7 +613,7 @@ def test_get_html_source(self, mock_render_django_template):
'is_video_from_same_origin': False,
'handout': None,
'hide_downloads': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'is_embed': False,
'metadata': self.default_metadata_dict,
'track': None,
@@ -648,9 +648,9 @@ def test_get_html_source(self, mock_render_django_template):
})
expected_context.update({
'display_name': data['name'],
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'download_video_link': data['result'].get('download_video_link'),
'metadata': json.dumps(expected_context['metadata'])
})
@@ -754,8 +754,8 @@ def test_get_html_with_mocked_edx_video_id(self, mock_render_django_template):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -764,7 +764,7 @@ def test_get_html_with_mocked_edx_video_id(self, mock_render_django_template):
'handout': None,
'hide_downloads': False,
'is_embed': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'track': None,
'transcript_download_format': 'srt',
'transcript_download_formats_list': [
@@ -810,9 +810,9 @@ def test_get_html_with_mocked_edx_video_id(self, mock_render_django_template):
'sources': data['result']['sources'],
})
expected_context.update({
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'download_video_link': data['result']['download_video_link'],
'metadata': json.dumps(expected_context['metadata'])
})
@@ -876,8 +876,8 @@ def helper_get_html_with_edx_video_id(self, data):
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -886,7 +886,7 @@ def helper_get_html_with_edx_video_id(self, data):
'handout': None,
'hide_downloads': False,
'is_embed': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'track': None,
'transcript_download_format': 'srt',
'transcript_download_formats_list': [
@@ -920,9 +920,9 @@ def helper_get_html_with_edx_video_id(self, data):
'sources': data['result']['sources'],
})
expected_context.update({
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'download_video_link': data['result']['download_video_link'],
'is_video_from_same_origin': data['result']['is_video_from_same_origin'],
'metadata': json.dumps(expected_context['metadata'])
@@ -984,8 +984,8 @@ def side_effect(*args, **kwargs): # lint-amnesty, pylint: disable=unused-argume
'autoadvance_enabled': False,
'license': None,
'bumper_metadata': 'null',
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -1031,9 +1031,9 @@ def side_effect(*args, **kwargs): # lint-amnesty, pylint: disable=unused-argume
'sources': data['result'].get('sources', []),
})
expected_context.update({
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'download_video_link': data['result'].get('download_video_link'),
'metadata': json.dumps(expected_context['metadata'])
})
@@ -1142,9 +1142,9 @@ def test_get_html_cdn_source_external_video(self, mock_render_django_template):
'sources': data['result'].get('sources', []),
})
expected_context.update({
- 'id': self.block.location.html_id(),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'id': self.block.usage_key.html_id(),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'download_video_link': data['result'].get('download_video_link'),
'metadata': json.dumps(expected_context['metadata'])
})
@@ -1515,17 +1515,17 @@ def test_editor_saved_when_html5_sub_not_exist(self):
for video.
"""
self.initialize_block(metadata=self.metadata)
- item = self.store.get_item(self.block.location)
+ item = self.store.get_item(self.block.usage_key)
with open(self.file_path, "rb") as myfile: # lint-amnesty, pylint: disable=bad-option-value, open-builtin
- save_to_store(myfile.read(), self.file_name, 'text/sjson', item.location)
+ save_to_store(myfile.read(), self.file_name, 'text/sjson', item.usage_key)
item.sub = "3_yD_cEKoCk"
# subs_video.srt.sjson does not exist before calling editor_saved function
with pytest.raises(NotFoundError):
- Transcript.get_asset(item.location, 'subs_video.srt.sjson')
+ Transcript.get_asset(item.usage_key, 'subs_video.srt.sjson')
old_metadata = own_metadata(item)
# calling editor_saved will generate new file subs_video.srt.sjson for html5_sources
item.editor_saved(self.user, old_metadata, None)
- assert isinstance(Transcript.get_asset(item.location, 'subs_3_yD_cEKoCk.srt.sjson'), StaticContent)
+ assert isinstance(Transcript.get_asset(item.usage_key, 'subs_3_yD_cEKoCk.srt.sjson'), StaticContent)
def test_editor_saved_when_youtube_and_html5_subs_exist(self):
"""
@@ -1533,14 +1533,14 @@ def test_editor_saved_when_youtube_and_html5_subs_exist(self):
sub will be generated by editor_saved function.
"""
self.initialize_block(metadata=self.metadata)
- item = self.store.get_item(self.block.location)
+ item = self.store.get_item(self.block.usage_key)
with open(self.file_path, "rb") as myfile: # lint-amnesty, pylint: disable=bad-option-value, open-builtin
- save_to_store(myfile.read(), self.file_name, 'text/sjson', item.location)
- save_to_store(myfile.read(), 'subs_video.srt.sjson', 'text/sjson', item.location)
+ save_to_store(myfile.read(), self.file_name, 'text/sjson', item.usage_key)
+ save_to_store(myfile.read(), 'subs_video.srt.sjson', 'text/sjson', item.usage_key)
item.sub = "3_yD_cEKoCk"
# subs_3_yD_cEKoCk.srt.sjson and subs_video.srt.sjson already exist
- assert isinstance(Transcript.get_asset(item.location, self.file_name), StaticContent)
- assert isinstance(Transcript.get_asset(item.location, 'subs_video.srt.sjson'), StaticContent)
+ assert isinstance(Transcript.get_asset(item.usage_key, self.file_name), StaticContent)
+ assert isinstance(Transcript.get_asset(item.usage_key, 'subs_video.srt.sjson'), StaticContent)
old_metadata = own_metadata(item)
with patch(
'openedx.core.djangoapps.video_config.services.manage_video_subtitles_save'
@@ -1558,7 +1558,7 @@ def test_editor_saved_with_unstripped_video_id(self):
'edx_video_id': unstripped_video_id
})
self.initialize_block(metadata=self.metadata)
- item = self.store.get_item(self.block.location)
+ item = self.store.get_item(self.block.usage_key)
assert item.edx_video_id == unstripped_video_id
# Now, modifying and saving the video block should strip the video id.
@@ -1574,7 +1574,7 @@ def test_editor_saved_with_yt_val_profile(self):
for a given `edx_video_id`.
"""
self.initialize_block(metadata=self.metadata)
- item = self.store.get_item(self.block.location)
+ item = self.store.get_item(self.block.usage_key)
assert item.youtube_id_1_0 == '3_yD_cEKoCk'
# Now, modify `edx_video_id` and save should override `youtube_id_1_0`.
@@ -1632,7 +1632,7 @@ def setup_val_video(self, associate_course_in_val=False):
'duration': self.TEST_DURATION,
'status': 'dummy',
'encoded_videos': [self.TEST_ENCODED_VIDEO],
- 'courses': [str(self.video.location.course_key)] if associate_course_in_val else [],
+ 'courses': [str(self.video.usage_key.course_key)] if associate_course_in_val else [],
})
self.val_video = get_video_info(self.TEST_EDX_VIDEO_ID) # pylint: disable=attribute-defined-outside-init
@@ -2393,8 +2393,8 @@ def test_bumper_metadata(
self.get_handler_url('publish_completion', ''), 'is_bumper', 1
),
})),
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'cdn_eval': False,
'cdn_exp_group': None,
'display_name': 'A Name',
@@ -2403,7 +2403,7 @@ def test_bumper_metadata(
'handout': None,
'hide_downloads': False,
'is_embed': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'metadata': json.dumps(OrderedDict({
'autoAdvance': False,
'saveStateEnabled': True,
@@ -2476,8 +2476,8 @@ def prepare_expected_context(self, autoadvanceenabled_flag, autoadvance_flag):
context = {
'autoadvance_enabled': autoadvanceenabled_flag,
- 'block_id': str(self.block.location),
- 'course_id': str(self.block.location.course_key),
+ 'block_id': str(self.block.usage_key),
+ 'course_id': str(self.block.usage_key.course_key),
'license': None,
'cdn_eval': False,
'cdn_exp_group': None,
@@ -2487,7 +2487,7 @@ def prepare_expected_context(self, autoadvanceenabled_flag, autoadvance_flag):
'handout': None,
'hide_downloads': False,
'is_embed': False,
- 'id': self.block.location.html_id(),
+ 'id': self.block.usage_key.html_id(),
'bumper_metadata': 'null',
'metadata': json.dumps(OrderedDict({
'autoAdvance': autoadvance_flag,
diff --git a/lms/djangoapps/courseware/tests/test_view_authentication.py b/lms/djangoapps/courseware/tests/test_view_authentication.py
index f9668853b244..bf247d22a445 100644
--- a/lms/djangoapps/courseware/tests/test_view_authentication.py
+++ b/lms/djangoapps/courseware/tests/test_view_authentication.py
@@ -115,15 +115,15 @@ def setUp(self):
self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course')
self.courseware_chapter = BlockFactory.create(display_name='courseware')
self.overview_chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name='Super Overview'
)
self.welcome_section = BlockFactory.create(
- parent_location=self.overview_chapter.location,
+ parent_location=self.overview_chapter.usage_key,
display_name='Super Welcome'
)
self.welcome_unit = BlockFactory.create(
- parent_location=self.welcome_section.location,
+ parent_location=self.welcome_section.usage_key,
display_name='Super Unit'
)
self.course = modulestore().get_course(self.course.id)
@@ -131,19 +131,19 @@ def setUp(self):
self.test_course = CourseFactory.create(org=self.course.id.org)
self.other_org_course = CourseFactory.create(org='Other_Org_Course')
self.sub_courseware_chapter = BlockFactory.create(
- parent_location=self.test_course.location,
+ parent_location=self.test_course.usage_key,
display_name='courseware'
)
self.sub_overview_chapter = BlockFactory.create(
- parent_location=self.sub_courseware_chapter.location,
+ parent_location=self.sub_courseware_chapter.usage_key,
display_name='Overview'
)
self.sub_welcome_section = BlockFactory.create(
- parent_location=self.sub_overview_chapter.location,
+ parent_location=self.sub_overview_chapter.usage_key,
display_name='Welcome'
)
self.sub_welcome_unit = BlockFactory.create(
- parent_location=self.sub_welcome_section.location,
+ parent_location=self.sub_welcome_section.usage_key,
display_name='New Unit'
)
self.test_course = modulestore().get_course(self.test_course.id)
diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py
index d96edb07c674..19d0d265a3f6 100644
--- a/lms/djangoapps/courseware/tests/test_views.py
+++ b/lms/djangoapps/courseware/tests/test_views.py
@@ -146,11 +146,11 @@ def test_jump_to_invalid_location(self, preview_mode, store_type):
def test_jump_to_preview_from_sequence(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)
- jumpto_url = f'/courses/{course.id}/jump_to/{sequence.location}?preview=1'
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
+ sequence = BlockFactory.create(category='sequential', parent_location=chapter.usage_key)
+ jumpto_url = f'/courses/{course.id}/jump_to/{sequence.usage_key}?preview=1'
expected_redirect_url = (
- f'http://learning-mfe/preview/course/{course.id}/{sequence.location}'
+ f'http://learning-mfe/preview/course/{course.id}/{sequence.usage_key}'
)
response = self.client.get(jumpto_url)
assert response.status_code == 302
@@ -158,12 +158,12 @@ def test_jump_to_preview_from_sequence(self):
def test_jump_to_mfe_from_sequence(self):
course = CourseFactory.create()
- chapter = BlockFactory.create(category='chapter', parent_location=course.location)
- sequence = BlockFactory.create(category='sequential', parent_location=chapter.location)
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
+ sequence = BlockFactory.create(category='sequential', parent_location=chapter.usage_key)
expected_redirect_url = (
- f'http://learning-mfe/course/{course.id}/{sequence.location}'
+ f'http://learning-mfe/course/{course.id}/{sequence.usage_key}'
)
- jumpto_url = f'/courses/{course.id}/jump_to/{sequence.location}'
+ jumpto_url = f'/courses/{course.id}/jump_to/{sequence.usage_key}'
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
@@ -171,24 +171,24 @@ def test_jump_to_mfe_from_sequence(self):
def test_jump_to_preview_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)
- block1 = BlockFactory.create(category='html', parent_location=vertical1.location)
- block2 = BlockFactory.create(category='html', parent_location=vertical2.location)
-
- jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}?preview=1'
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
+ sequence = BlockFactory.create(category='sequential', parent_location=chapter.usage_key)
+ vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.usage_key)
+ vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.usage_key)
+ block1 = BlockFactory.create(category='html', parent_location=vertical1.usage_key)
+ block2 = BlockFactory.create(category='html', parent_location=vertical2.usage_key)
+
+ jumpto_url = f'/courses/{course.id}/jump_to/{block1.usage_key}?preview=1'
expected_redirect_url = (
- f'http://learning-mfe/preview/course/{course.id}/{sequence.location}/{vertical1.location}'
+ f'http://learning-mfe/preview/course/{course.id}/{sequence.usage_key}/{vertical1.usage_key}'
)
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
- jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}?preview=1'
+ jumpto_url = f'/courses/{course.id}/jump_to/{block2.usage_key}?preview=1'
expected_redirect_url = (
- f'http://learning-mfe/preview/course/{course.id}/{sequence.location}/{vertical2.location}'
+ f'http://learning-mfe/preview/course/{course.id}/{sequence.usage_key}/{vertical2.usage_key}'
)
response = self.client.get(jumpto_url)
assert response.status_code == 302
@@ -196,25 +196,25 @@ def test_jump_to_preview_from_block(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)
- block1 = BlockFactory.create(category='html', parent_location=vertical1.location)
- block2 = BlockFactory.create(category='html', parent_location=vertical2.location)
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
+ sequence = BlockFactory.create(category='sequential', parent_location=chapter.usage_key)
+ vertical1 = BlockFactory.create(category='vertical', parent_location=sequence.usage_key)
+ vertical2 = BlockFactory.create(category='vertical', parent_location=sequence.usage_key)
+ block1 = BlockFactory.create(category='html', parent_location=vertical1.usage_key)
+ block2 = BlockFactory.create(category='html', parent_location=vertical2.usage_key)
expected_redirect_url = (
- f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical1.location}'
+ f'http://learning-mfe/course/{course.id}/{sequence.usage_key}/{vertical1.usage_key}'
)
- jumpto_url = f'/courses/{course.id}/jump_to/{block1.location}'
+ jumpto_url = f'/courses/{course.id}/jump_to/{block1.usage_key}'
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
expected_redirect_url = (
- f'http://learning-mfe/course/{course.id}/{sequence.location}/{vertical2.location}'
+ f'http://learning-mfe/course/{course.id}/{sequence.usage_key}/{vertical2.usage_key}'
)
- jumpto_url = f'/courses/{course.id}/jump_to/{block2.location}'
+ jumpto_url = f'/courses/{course.id}/jump_to/{block2.usage_key}'
response = self.client.get(jumpto_url)
assert response.status_code == 302
assert response.url == expected_redirect_url
@@ -246,40 +246,40 @@ def setUp(self):
with self.store.bulk_operations(self.course.id):
self.chapter = BlockFactory.create(
category='chapter',
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name="Chapter 1",
)
self.section = BlockFactory.create(
category='sequential',
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
due=datetime(2013, 9, 18, 11, 30, 00),
display_name='Sequential 1',
format='Homework'
)
self.vertical = BlockFactory.create(
category='vertical',
- parent_location=self.section.location,
+ parent_location=self.section.usage_key,
display_name='Vertical 1',
)
self.problem = BlockFactory.create(
category='problem',
- parent_location=self.vertical.location,
+ parent_location=self.vertical.usage_key,
display_name='Problem 1',
)
self.section2 = BlockFactory.create(
category='sequential',
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
display_name='Sequential 2',
)
self.vertical2 = BlockFactory.create(
category='vertical',
- parent_location=self.section2.location,
+ parent_location=self.section2.usage_key,
display_name='Vertical 2',
)
self.problem2 = BlockFactory.create(
category='problem',
- parent_location=self.vertical2.location,
+ parent_location=self.vertical2.usage_key,
display_name='Problem 2',
)
@@ -337,7 +337,7 @@ def test_section_redirect(self):
'courseware_section',
kwargs={
'course_id': str(self.course_key),
- 'section': str(self.chapter.location.block_id),
+ 'section': str(self.chapter.usage_key.block_id),
}
)
@@ -351,12 +351,12 @@ def test_subsection_redirect(self):
'courseware_subsection',
kwargs={
'course_id': str(self.course_key),
- 'section': str(self.chapter.location.block_id),
- 'subsection': str(self.section2.location.block_id),
+ 'section': str(self.chapter.usage_key.block_id),
+ 'subsection': str(self.section2.usage_key.block_id),
}
)
- mfe_url = make_learning_mfe_courseware_url(self.course.id, self.section2.location)
+ mfe_url = make_learning_mfe_courseware_url(self.course.id, self.section2.usage_key)
response = self.client.get(lms_url)
assert response.url == mfe_url
@@ -389,7 +389,7 @@ def _create_url_for_enroll_staff(self):
creates the courseware url and enroll staff url
"""
# create the _next parameter
- courseware_url = make_learning_mfe_courseware_url(self.course.id, self.chapter.location, self.section.location)
+ courseware_url = make_learning_mfe_courseware_url(self.course.id, self.chapter.usage_key, self.section.usage_key)
courseware_url = quote(courseware_url, safe=':/')
# create the url for enroll_staff view
enroll_url = "{enroll_url}?next={courseware_url}".format(
@@ -506,7 +506,7 @@ def test_submission_history_accepts_valid_ids(self):
url = reverse('submission_history', kwargs={
'course_id': str(self.course_key),
'learner_identifier': 'dummy',
- 'location': str(self.problem.location),
+ 'location': str(self.problem.usage_key),
})
response = self.client.get(url)
# Tests that we do not get an "Invalid x" response when passing correct arguments to view
@@ -929,15 +929,15 @@ def set_up_course(self, **course_kwargs):
"""
course = CourseFactory.create(**course_kwargs)
with self.store.bulk_operations(course.id):
- chapter = BlockFactory.create(category='chapter', parent_location=course.location)
+ chapter = BlockFactory.create(category='chapter', parent_location=course.usage_key)
section = BlockFactory.create(
category='sequential',
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
due=datetime(2013, 9, 18, 11, 30, 00),
format='homework'
)
- vertical = BlockFactory.create(category='vertical', parent_location=section.location)
- BlockFactory.create(category='problem', parent_location=vertical.location)
+ vertical = BlockFactory.create(category='vertical', parent_location=section.usage_key)
+ BlockFactory.create(category='problem', parent_location=vertical.usage_key)
course = modulestore().get_course(course.id)
assert course.get_children()[0].get_children()[0].due is not None
@@ -1067,9 +1067,9 @@ def setup_course(self, **course_options):
"""Create the test course and content, and enroll the user."""
self.create_course(**course_options, grading_policy={'GRADE_CUTOFFS': {'çü†øƒƒ': 0.75, 'Pass': 0.5}})
with self.store.bulk_operations(self.course.id):
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location)
- self.section = BlockFactory.create(category='sequential', parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.section.location)
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key)
+ self.section = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.section.usage_key)
CourseEnrollmentFactory(user=self.user, course_id=self.course.id, mode=CourseMode.HONOR)
@@ -1111,7 +1111,7 @@ def test_progress_page_xss_prevent(self, malicious_code):
self.assertNotContains(resp, malicious_code)
def test_pure_ungraded_xblock(self):
- BlockFactory.create(category='acid', parent_location=self.vertical.location)
+ BlockFactory.create(category='acid', parent_location=self.vertical.usage_key)
self._get_progress_page()
def test_student_progress_with_valid_and_invalid_id(self):
@@ -1703,11 +1703,11 @@ def setup_course(self, show_correctness='', due_date=None, graded=False, **cours
metadata['format'] = self.GRADER_TYPE
with self.store.bulk_operations(self.course.id):
- self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.location,
+ self.chapter = BlockFactory.create(category='chapter', parent_location=self.course.usage_key,
display_name="Section 1")
- self.section = BlockFactory.create(category='sequential', parent_location=self.chapter.location,
+ self.section = BlockFactory.create(category='sequential', parent_location=self.chapter.usage_key,
display_name="Subsection 1", metadata=metadata)
- self.vertical = BlockFactory.create(category='vertical', parent_location=self.section.location)
+ self.vertical = BlockFactory.create(category='vertical', parent_location=self.section.usage_key)
CourseEnrollmentFactory(user=self.user, course_id=self.course.id, mode=CourseMode.HONOR)
@@ -1720,7 +1720,7 @@ def add_problem(self):
choices=[True, False],
choice_names=['choice_0', 'choice_1']
)
- self.problem = BlockFactory.create(category='problem', parent_location=self.vertical.location, # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.problem = BlockFactory.create(category='problem', parent_location=self.vertical.usage_key, # lint-amnesty, pylint: disable=attribute-defined-outside-init
data=problem_xml, display_name='Problem 1')
# Re-fetch the course from the database
self.course = self.store.get_course(self.course.id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
@@ -2320,7 +2320,7 @@ def test_render_xblock_with_completion_service_disabled(self):
self.setup_course(ModuleStoreEnum.Type.split)
self.setup_user(admin=True, enroll=True, login=True)
- response = self.get_response(usage_key=self.html_block.location)
+ response = self.get_response(usage_key=self.html_block.usage_key)
assert response.status_code == 200
self.assertContains(response, 'data-enable-completion-on-view-service="false"')
self.assertNotContains(response, 'data-mark-completed-on-view-after-delay')
@@ -2334,7 +2334,7 @@ def test_render_xblock_with_completion_service_enabled(self):
self.setup_course(ModuleStoreEnum.Type.split)
self.setup_user(admin=False, enroll=True, login=True)
- response = self.get_response(usage_key=self.html_block.location)
+ response = self.get_response(usage_key=self.html_block.usage_key)
assert response.status_code == 200
self.assertContains(response, 'data-enable-completion-on-view-service="true"')
self.assertContains(response, 'data-mark-completed-on-view-after-delay')
@@ -2348,18 +2348,18 @@ def test_render_xblock_with_completion_service_enabled(self):
response = handle_xblock_callback(
request,
str(self.course.id),
- quote_slashes(str(self.html_block.location)),
+ quote_slashes(str(self.html_block.usage_key)),
'publish_completion',
)
assert response.status_code == 200
assert json.loads(response.content.decode('utf-8')) == {'result': 'ok'}
- response = self.get_response(usage_key=self.html_block.location)
+ response = self.get_response(usage_key=self.html_block.usage_key)
assert response.status_code == 200
self.assertContains(response, 'data-enable-completion-on-view-service="false"')
self.assertNotContains(response, 'data-mark-completed-on-view-after-delay')
- response = self.get_response(usage_key=self.problem_block.location)
+ response = self.get_response(usage_key=self.problem_block.usage_key)
assert response.status_code == 200
self.assertContains(response, 'data-enable-completion-on-view-service="false"')
self.assertNotContains(response, 'data-mark-completed-on-view-after-delay')
@@ -2399,14 +2399,14 @@ def test_rendering_descendant_of_gated_sequence(self):
# Problem and Vertical response should both redirect to the Sequential
# (where useful messaging would be).
- seq_url = reverse('render_xblock', kwargs={'usage_key_string': str(self.sequence.location)})
+ seq_url = reverse('render_xblock', kwargs={'usage_key_string': str(self.sequence.usage_key)})
for block in [self.problem_block, self.vertical_block]:
- response = self.get_response(usage_key=block.location)
+ response = self.get_response(usage_key=block.usage_key)
assert response.status_code == 302
assert response.get('Location') == seq_url
# The Sequence itself 200s (or we risk infinite redirect loops).
- assert self.get_response(usage_key=self.sequence.location).status_code == 200
+ assert self.get_response(usage_key=self.sequence.usage_key).status_code == 200
def test_rendering_descendant_of_gated_sequence_with_masquerade(self):
"""
@@ -2446,7 +2446,7 @@ def test_rendering_descendant_of_gated_sequence_with_masquerade(self):
# Problem and Vertical response should both render successfully
for block in [self.problem_block, self.vertical_block]:
- response = self.get_response(usage_key=block.location)
+ response = self.get_response(usage_key=block.usage_key)
assert response.status_code == 200
def test_render_xblock_with_course_duration_limits(self):
@@ -2462,7 +2462,7 @@ def test_render_xblock_with_course_duration_limits(self):
add_course_mode(self.course)
CourseEnrollmentFactory(user=self.user, course_id=self.course.id, mode=CourseMode.AUDIT)
- response = self.get_response(usage_key=self.vertical_block.location)
+ response = self.get_response(usage_key=self.vertical_block.usage_key)
assert response.status_code == 200
banner_text = get_expiration_banner_text(self.user, self.course)
@@ -2483,7 +2483,7 @@ def test_render_xblock_with_course_duration_limits_in_mobile_browser(self, mock_
add_course_mode(self.course)
CourseEnrollmentFactory(user=self.user, course_id=self.course.id, mode=CourseMode.AUDIT)
- response = self.get_response(usage_key=self.vertical_block.location)
+ response = self.get_response(usage_key=self.vertical_block.usage_key)
assert response.status_code == 200
banner_text = get_expiration_banner_text(self.user, self.course)
@@ -2540,9 +2540,9 @@ def test_render_descendant_of_exam_gated_by_access_token(self, exam_access_token
def _mock_unpack_jwt_fn(token, user_id):
if token == 'valid-jwt-for-exam-sequence':
- return {'content_id': str(self.sequence.location)}
+ return {'content_id': str(self.sequence.usage_key)}
elif token == 'valid-jwt-for-incorrect-sequence':
- return {'content_id': str(self.other_sequence.location)}
+ return {'content_id': str(self.other_sequence.usage_key)}
else:
raise Exception('invalid JWT')
@@ -2551,12 +2551,12 @@ def _mock_unpack_jwt_fn(token, user_id):
# Problem and Vertical response should be gated on access token
for block in [self.problem_block, self.vertical_block]:
response = self.get_response(
- usage_key=block.location, url_encoded_params=f'exam_access={exam_access_token}')
+ usage_key=block.usage_key, url_encoded_params=f'exam_access={exam_access_token}')
assert response.status_code == expected_response
# The Sequence itself should also be gated
response = self.get_response(
- usage_key=self.sequence.location, url_encoded_params=f'exam_access={exam_access_token}')
+ usage_key=self.sequence.usage_key, url_encoded_params=f'exam_access={exam_access_token}')
assert response.status_code == expected_response
@@ -2575,7 +2575,7 @@ def setup_course(self, enable_waffle=True):
self.course = CourseFactory.create(**{'start': datetime.now() - timedelta(days=1)})
chapter = BlockFactory.create(parent=self.course, category='chapter')
vertical_block = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category='vertical',
display_name="Vertical"
)
@@ -2633,7 +2633,7 @@ def test_render_xblock_with_non_video_usage_key(self, is_embed):
Verify that endpoint returns expected response if usage key block type is not `video`
"""
self.setup_course()
- response = self.get_response(usage_key=self.html_block.location, is_embed=is_embed)
+ response = self.get_response(usage_key=self.html_block.usage_key, is_embed=is_embed)
self.assertContains(response, 'Page not found', status_code=404)
@ddt.unpack
@@ -2648,8 +2648,8 @@ def test_access(self, is_waffle_enabled, is_public_video, expected_status_code):
self.setup_course(enable_waffle=is_waffle_enabled)
target_video = self.video_block_public if is_public_video else self.video_block_not_public
- response = self.get_response(usage_key=target_video.location, is_embed=False)
- embed_response = self.get_response(usage_key=target_video.location, is_embed=True)
+ response = self.get_response(usage_key=target_video.usage_key, is_embed=False)
+ embed_response = self.get_response(usage_key=target_video.usage_key, is_embed=True)
self.assertEqual(expected_status_code, response.status_code)
self.assertEqual(expected_status_code, embed_response.status_code)
@@ -2830,24 +2830,24 @@ def setUp(self):
with self.store.bulk_operations(self.course.id):
chapter = BlockFactory.create(
category='chapter',
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name="Chapter 1",
)
section = BlockFactory.create(
category='sequential',
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
due=datetime(2013, 9, 18, 11, 30, 00),
display_name='Sequential 1',
format='Homework'
)
self.math_vertical = BlockFactory.create(
category='vertical',
- parent_location=section.location,
+ parent_location=section.usage_key,
display_name='Vertical with Mathjax HTML',
)
self.no_math_vertical = BlockFactory.create(
category='vertical',
- parent_location=section.location,
+ parent_location=section.usage_key,
display_name='Vertical with No Mathjax HTML',
)
MATHJAX_TAG_PAIRS = [
@@ -2859,15 +2859,15 @@ def setUp(self):
for (i, (start_tag, end_tag)) in enumerate(MATHJAX_TAG_PAIRS):
math_html_block = BlockFactory.create(
category='html',
- parent_location=self.math_vertical.location,
+ parent_location=self.math_vertical.usage_key,
display_name=f"HTML With Mathjax {i}",
data=f"Hello Math! {start_tag}x^2 + y^2{end_tag}
",
)
- self.math_html_usage_keys.append(math_html_block.location)
+ self.math_html_usage_keys.append(math_html_block.usage_key)
self.html_without_mathjax = BlockFactory.create(
category='html',
- parent_location=self.no_math_vertical.location,
+ parent_location=self.no_math_vertical.usage_key,
display_name="HTML Without Mathjax",
data="I talk about mathjax, but I have no actual Math!
",
)
@@ -2892,7 +2892,7 @@ def test_mathjax_detection(self):
# Check the one without Math...
url = reverse("render_xblock", kwargs={
- 'usage_key_string': str(self.html_without_mathjax.location)
+ 'usage_key_string': str(self.html_without_mathjax.usage_key)
})
response = self.client.get(url)
assert response.status_code == 200
@@ -2900,7 +2900,7 @@ def test_mathjax_detection(self):
# The containing vertical should still return MathJax (for now)
url = reverse("render_xblock", kwargs={
- 'usage_key_string': str(self.no_math_vertical.location)
+ 'usage_key_string': str(self.no_math_vertical.usage_key)
})
response = self.client.get(url)
assert response.status_code == 200
@@ -2911,7 +2911,7 @@ def test_mathjax_detection_disabled(self):
"""Check that we can disable optimizations."""
self.client.login(username=self.user.username, password=TEST_PASSWORD)
url = reverse("render_xblock", kwargs={
- 'usage_key_string': str(self.html_without_mathjax.location)
+ 'usage_key_string': str(self.html_without_mathjax.usage_key)
})
response = self.client.get(url)
assert response.status_code == 200
@@ -2942,8 +2942,8 @@ def test_course_wide_resources(self, url_name, param, is_instructor, is_rendered
css = ['https://testcdn.com/css/lib.min.css', '//testcdn.com/css/lib2.css', '/test.css']
course = CourseFactory.create(course_wide_js=js, course_wide_css=css)
- chapter = BlockFactory.create(parent_location=course.location, category='chapter')
- sequence = BlockFactory.create(parent_location=chapter.location, category='sequential', display_name='Sequence')
+ chapter = BlockFactory.create(parent_location=course.usage_key, category='chapter')
+ sequence = BlockFactory.create(parent_location=chapter.usage_key, category='sequential', display_name='Sequence')
CourseOverview.load_from_module_store(course.id)
CourseEnrollmentFactory(user=user, course_id=course.id)
@@ -2955,7 +2955,7 @@ def test_course_wide_resources(self, url_name, param, is_instructor, is_rendered
if param == 'course_id':
kwargs = {'course_id': str(course.id)}
elif param == 'usage_key_string':
- kwargs = {'usage_key_string': str(sequence.location)}
+ kwargs = {'usage_key_string': str(sequence.usage_key)}
response = self.client.get(reverse(url_name, kwargs=kwargs))
content = response.content.decode('utf-8')
@@ -3002,12 +3002,12 @@ def test_get_course_and_video_block(self, is_waffle_enabled, is_public_video, mo
# get 404 unless waffle is enabled and video is public
if is_public_video and is_waffle_enabled:
- course, video_block = self.base_block.get_course_and_video_block(str(target_video.location))
+ course, video_block = self.base_block.get_course_and_video_block(str(target_video.usage_key))
assert course.id == self.course.id
- assert video_block.location == target_video.location
+ assert video_block.usage_key == target_video.usage_key
else:
with self.assertRaisesRegex(Http404, "Video not found"):
- course, video_block = self.base_block.get_course_and_video_block(str(target_video.location))
+ course, video_block = self.base_block.get_course_and_video_block(str(target_video.usage_key))
@ddt.ddt
diff --git a/lms/djangoapps/courseware/tests/test_word_cloud.py b/lms/djangoapps/courseware/tests/test_word_cloud.py
index 286ebfcde028..b2db613ba5a8 100644
--- a/lms/djangoapps/courseware/tests/test_word_cloud.py
+++ b/lms/djangoapps/courseware/tests/test_word_cloud.py
@@ -288,7 +288,7 @@ def test_word_cloud_constructor(self, mock_render_django_template):
assert fragment_content_clean == self.runtime.render_template('templates/word_cloud.html', expected_context)
else:
expected_context['ajax_url'] = self.block.ajax_url
- expected_context['element_id'] = self.block.location.html_id()
+ expected_context['element_id'] = self.block.usage_key.html_id()
assert fragment.content == self.runtime.render_template('word_cloud.html', expected_context)
diff --git a/lms/djangoapps/courseware/tests/tests.py b/lms/djangoapps/courseware/tests/tests.py
index 7b9a8962f2dd..5f4f5efd29db 100644
--- a/lms/djangoapps/courseware/tests/tests.py
+++ b/lms/djangoapps/courseware/tests/tests.py
@@ -65,24 +65,24 @@ def check_all_pages_load(self, course_key):
# Try to load each item in the course
for block in items:
- if block.location.category == 'about':
+ if block.usage_key.category == 'about':
self._assert_loads('about_course',
{'course_id': str(course_key)},
block)
- elif block.location.category == 'static_tab':
+ elif block.usage_key.category == 'static_tab':
kwargs = {'course_id': str(course_key),
- 'tab_slug': block.location.name}
+ 'tab_slug': block.usage_key.name}
self._assert_loads('static_tab', kwargs, block)
- elif block.location.category == 'course_info':
+ elif block.usage_key.category == 'course_info':
self._assert_loads('info', {'course_id': str(course_key)},
block)
else:
kwargs = {'course_id': str(course_key),
- 'location': str(block.location)}
+ 'location': str(block.usage_key)}
self._assert_loads('jump_to', kwargs, block,
expect_redirect=True,
@@ -103,7 +103,7 @@ def _assert_loads(self, django_url, kwargs, block,
if response.status_code != 200:
self.fail('Status %d for page %s' %
- (response.status_code, block.location))
+ (response.status_code, block.usage_key))
if expect_redirect:
assert response.redirect_chain[0][1] == 302
diff --git a/lms/djangoapps/courseware/testutils.py b/lms/djangoapps/courseware/testutils.py
index 5f47b258ae9f..4bd1b66cce7d 100644
--- a/lms/djangoapps/courseware/testutils.py
+++ b/lms/djangoapps/courseware/testutils.py
@@ -99,7 +99,7 @@ def setup_course(self, default_store=None):
self.course = CourseFactory.create(**self.course_options())
chapter = BlockFactory.create(parent=self.course, category='chapter')
self.vertical_block = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category='vertical',
display_name="Vertical"
)
@@ -151,7 +151,7 @@ def verify_response(self, expected_response_code=200, url_params=None, is_staff=
if url_params:
url_params = urlencode(url_params)
- response = self.get_response(self.block_to_be_tested.location, url_params)
+ response = self.get_response(self.block_to_be_tested.usage_key, url_params)
if expected_response_code == 200:
self.assertContains(response, self.html_block.data, status_code=expected_response_code)
unexpected_elements = self.block_specific_chrome_html_elements + self.COURSEWARE_CHROME_HTML_ELEMENTS
diff --git a/lms/djangoapps/courseware/views/index.py b/lms/djangoapps/courseware/views/index.py
index 1034674b7b41..f1b3775aeb6e 100644
--- a/lms/djangoapps/courseware/views/index.py
+++ b/lms/djangoapps/courseware/views/index.py
@@ -80,11 +80,11 @@ def get(self, request, course_id, section=None, subsection=None, position=None):
# location in the MFE
subsection_location = None
if section and subsection:
- section_block = course.get_child_by(lambda m: m.location.block_id == section)
+ section_block = course.get_child_by(lambda m: m.usage_key.block_id == section)
if section_block:
- subsection_block = section_block.get_child_by(lambda m: m.location.block_id == subsection)
+ subsection_block = section_block.get_child_by(lambda m: m.usage_key.block_id == subsection)
if subsection_block:
- subsection_location = subsection_block.location
+ subsection_location = subsection_block.usage_key
try:
unit_key = UsageKey.from_string(request.GET.get('activate_block_id', ''))
@@ -120,7 +120,7 @@ def save_child_position(seq_block, child_name):
child_name: url_name of the child
"""
for position, child in enumerate(seq_block.get_children(), start=1):
- if child.location.block_id == child_name:
+ if child.usage_key.block_id == child_name:
# Only save if position changed
if position != seq_block.position:
seq_block.position = position
@@ -136,7 +136,7 @@ def save_positions_recursively_up(user, request, field_data_cache, xmodule, cour
current_block = xmodule
while current_block:
- parent_location = modulestore().get_parent_location(current_block.location)
+ parent_location = modulestore().get_parent_location(current_block.usage_key)
parent = None
if parent_location:
parent_block = modulestore().get_item(parent_location)
@@ -145,11 +145,11 @@ def save_positions_recursively_up(user, request, field_data_cache, xmodule, cour
request,
parent_block,
field_data_cache,
- current_block.location.course_key,
+ current_block.usage_key.course_key,
course=course
)
if parent and hasattr(parent, 'position'):
- save_child_position(parent, current_block.location.block_id)
+ save_child_position(parent, current_block.usage_key.block_id)
current_block = parent
diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py
index 590a5f5acef4..3da6ed221003 100644
--- a/lms/djangoapps/courseware/views/views.py
+++ b/lms/djangoapps/courseware/views/views.py
@@ -432,10 +432,10 @@ def jump_to_id(request, course_id, module_id):
module_id,
course_id,
request.META.get("HTTP_REFERER", ""),
- str(items[0].location)
+ str(items[0].usage_key)
)
- return jump_to(request, course_id, str(items[0].location))
+ return jump_to(request, course_id, str(items[0].usage_key))
@ensure_csrf_cookie
@@ -1534,17 +1534,17 @@ def enclosing_sequence_for_gating_checks(block):
# will happen automatically when rendering the render_xblock view anyway,
# and we don't want weird, weird edge cases where you have nested Sequences
# (which would probably "work" in terms of OLX import).
- if block.location.block_type in seq_tags:
+ if block.usage_key.block_type in seq_tags:
return None
ancestor = block
- while ancestor and ancestor.location.block_type not in seq_tags:
+ while ancestor and ancestor.usage_key.block_type not in seq_tags:
ancestor = ancestor.get_parent() # Note: CourseBlock's parent is None
if ancestor:
# get_parent() returns a parent block instance cached on the block which does not
# have user data bound to it so we need to get it again with get_block() which will set up everything.
- return block.runtime.get_block(ancestor.location)
+ return block.runtime.get_block(ancestor.usage_key)
return None
@@ -1686,7 +1686,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True, disable_sta
return redirect(
reverse(
'render_xblock',
- kwargs={'usage_key_string': str(ancestor_sequence_block.location)}
+ kwargs={'usage_key_string': str(ancestor_sequence_block.usage_key)}
)
)
@@ -1699,7 +1699,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True, disable_sta
if course.proctoring_provider == 'lti_external':
seq_block = ancestor_sequence_block if ancestor_sequence_block else block
if getattr(seq_block, 'is_time_limited', None):
- if not _check_sequence_exam_access(request, seq_block.location):
+ if not _check_sequence_exam_access(request, seq_block.usage_key):
return HttpResponseForbidden("Access to exam content is restricted")
context = {
@@ -1765,7 +1765,7 @@ def get_optimization_flags_for_content(block, fragment):
# Only run our optimizations on the leaf HTML and ProblemBlock nodes. The
# mobile apps access these directly, and we don't have to worry about
# XBlocks that dynamically load content, like inline discussions.
- usage_key = block.location
+ usage_key = block.usage_key
# For now, confine ourselves to optimizing just the HTMLBlock
if usage_key.block_type != 'html':
@@ -1868,7 +1868,7 @@ def get_course_and_video_block(self, usage_key_string):
)
# Block must be marked as public to be viewed
- if not is_public_sharing_enabled(video_block.location, video_block.public_access):
+ if not is_public_sharing_enabled(video_block.usage_key, video_block.public_access):
raise Http404("Video not found.")
return course, video_block
@@ -1968,11 +1968,11 @@ def get_social_sharing_metadata(self, course, video_block):
'video_thumbnail': video_poster if video_poster is not None else '',
'video_embed_url': urljoin(
settings.LMS_ROOT_URL,
- reverse('render_public_video_xblock_embed', kwargs={'usage_key_string': str(video_block.location)})
+ reverse('render_public_video_xblock_embed', kwargs={'usage_key_string': str(video_block.usage_key)})
),
'video_url': urljoin(
settings.LMS_ROOT_URL,
- reverse('render_public_video_xblock', kwargs={'usage_key_string': str(video_block.location)})
+ reverse('render_public_video_xblock', kwargs={'usage_key_string': str(video_block.usage_key)})
),
}
diff --git a/lms/djangoapps/discussion/django_comment_client/base/tests_v2.py b/lms/djangoapps/discussion/django_comment_client/base/tests_v2.py
index 1f5ae7805740..3c4ade53d248 100644
--- a/lms/djangoapps/discussion/django_comment_client/base/tests_v2.py
+++ b/lms/djangoapps/discussion/django_comment_client/base/tests_v2.py
@@ -244,7 +244,7 @@ def set_up_course(self, block_count=0):
# add some discussion blocks
for i in range(block_count):
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id=f"id_module_{i}",
discussion_category=f"Category {i}",
@@ -2507,14 +2507,14 @@ def setUp(self):
UserBasedRole(user=self.staff, role=CourseStaffRole.ROLE).add_course(self.course.id)
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
self.category = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id=self.CATEGORY_ID,
discussion_category=self.PARENT_CATEGORY_NAME,
discussion_target=self.CATEGORY_NAME,
)
self.team_category = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id=self.TEAM_CATEGORY_ID,
discussion_category=self.TEAM_PARENT_CATEGORY_NAME,
diff --git a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py
index 742eb23bf5dc..c0e3a98002cc 100644
--- a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py
+++ b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py
@@ -135,14 +135,14 @@ def setUp(self):
super().setUp()
self.course = CourseFactory.create(org="TestX", number="101", display_name="Test Course")
self.discussion1 = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id="discussion1",
discussion_category="Chapter",
discussion_target="Discussion 1"
)
self.discussion2 = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id="discussion2",
discussion_category="Chapter / Section / Subsection",
@@ -169,7 +169,7 @@ def assertThreadCorrect(thread, discussion, expected_title): # pylint: disable=
"""Asserts that the given thread has the expected set of properties"""
assert set(thread.keys()) == {'commentable_id', 'courseware_url', 'courseware_title'}
assert thread.get('courseware_url') == reverse('jump_to', kwargs={'course_id': str(self.course.id),
- 'location': str(discussion.location)})
+ 'location': str(discussion.usage_key)})
assert thread.get('courseware_title') == expected_title
assertThreadCorrect(threads[0], self.discussion1, "Chapter / Discussion 1")
@@ -181,7 +181,7 @@ def test_empty_discussion_subcategory_title(self):
the divider " / " is not rendered on a post or inline discussion topic label.
"""
discussion = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id="discussion",
discussion_category="Chapter",
@@ -198,10 +198,10 @@ def test_get_accessible_discussion_xblocks(self):
course = CourseFactory.create()
# Create a discussion xblock.
- test_discussion = self.store.create_child(self.user.id, course.location, 'discussion', 'test_discussion')
+ test_discussion = self.store.create_child(self.user.id, course.usage_key, 'discussion', 'test_discussion')
# Assert that created discussion xblock is not an orphan.
- assert test_discussion.location not in self.store.get_orphans(course.id)
+ assert test_discussion.usage_key not in self.store.get_orphans(course.id)
# Assert that there is only one discussion xblock in the course at the moment.
assert len(get_accessible_discussion_xblocks(course, self.user)) == 1
@@ -229,21 +229,21 @@ def setUp(self):
self.course = CourseFactory.create(org='TestX', number='101', display_name='Test Course')
self.discussion = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id='test_discussion_id',
discussion_category='Chapter',
discussion_target='Discussion 1'
)
self.discussion2 = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id='test_discussion_id_2',
discussion_category='Chapter 2',
discussion_target='Discussion 2'
)
self.private_discussion = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id='private_discussion_id',
discussion_category='Chapter 3',
@@ -252,7 +252,7 @@ def setUp(self):
)
RequestCache.clear_all_namespaces() # clear the cache before the last course publish
self.bad_discussion = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id='bad_discussion_id',
discussion_category=None,
@@ -261,7 +261,7 @@ def setUp(self):
def test_cache_returns_correct_key(self):
usage_key = utils.get_cached_discussion_key(self.course.id, 'test_discussion_id')
- assert usage_key == self.discussion.location
+ assert usage_key == self.discussion.usage_key
def test_cache_returns_none_if_id_is_not_present(self):
usage_key = utils.get_cached_discussion_key(self.course.id, 'bogus_id')
@@ -293,9 +293,9 @@ def verify_discussion_metadata(self):
)
discussion1 = metadata[self.discussion.discussion_id]
discussion2 = metadata[self.discussion2.discussion_id]
- assert discussion1['location'] == self.discussion.location
+ assert discussion1['location'] == self.discussion.usage_key
assert discussion1['title'] == 'Chapter / Discussion 1'
- assert discussion2['location'] == self.discussion2.location
+ assert discussion2['location'] == self.discussion2.usage_key
assert discussion2['title'] == 'Chapter 2 / Discussion 2'
def test_get_discussion_id_map_from_cache(self):
@@ -379,7 +379,7 @@ def setUp(self):
def create_discussion(self, discussion_category, discussion_target, **kwargs):
self.discussion_num += 1
return BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id=f"discussion{self.discussion_num}",
discussion_category=discussion_category,
diff --git a/lms/djangoapps/discussion/django_comment_client/tests/utils.py b/lms/djangoapps/discussion/django_comment_client/tests/utils.py
index bc3fdffa11d0..73b78568d37d 100644
--- a/lms/djangoapps/discussion/django_comment_client/tests/utils.py
+++ b/lms/djangoapps/discussion/django_comment_client/tests/utils.py
@@ -122,7 +122,7 @@ def topic_name_to_id(course, name):
course and url_name).
"""
return "{course}_{run}_{name}".format(
- course=course.location.course,
+ course=course.usage_key.course,
run=course.url_name,
name=name
)
diff --git a/lms/djangoapps/discussion/django_comment_client/utils.py b/lms/djangoapps/discussion/django_comment_client/utils.py
index a0bb6b769183..b57890cd273e 100644
--- a/lms/djangoapps/discussion/django_comment_client/utils.py
+++ b/lms/djangoapps/discussion/django_comment_client/utils.py
@@ -193,7 +193,7 @@ def get_discussion_id_map_entry(xblock):
return (
xblock.discussion_id,
{
- "location": xblock.location,
+ "location": xblock.usage_key,
"title": xblock.discussion_category.split("/")[-1].strip() + (" / " + xblock.discussion_target if xblock.discussion_target else "")
}
)
diff --git a/lms/djangoapps/discussion/rest_api/tests/test_api_v2.py b/lms/djangoapps/discussion/rest_api/tests/test_api_v2.py
index df4ac947bf0d..9b8d60d55944 100644
--- a/lms/djangoapps/discussion/rest_api/tests/test_api_v2.py
+++ b/lms/djangoapps/discussion/rest_api/tests/test_api_v2.py
@@ -4063,20 +4063,20 @@ def setUp(self) -> None:
}
)
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="chapter",
display_name="Week 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category="sequential",
display_name="Lesson 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.verticals = [
BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name=f"vertical-{idx}",
start=datetime(2015, 4, 1, tzinfo=UTC),
@@ -4084,7 +4084,7 @@ def setUp(self) -> None:
for idx in range(10)
]
staff_only_unit = BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category="vertical",
display_name="staff-vertical-1",
metadata=dict(visible_to_staff_only=True),
@@ -4096,7 +4096,7 @@ def setUp(self) -> None:
topic_links = []
update_discussions_settings_from_course_task(str(self.course_key))
self.staff_only_id = (
- DiscussionTopicLink.objects.filter(usage_key__in=[staff_only_unit.location])
+ DiscussionTopicLink.objects.filter(usage_key__in=[staff_only_unit.usage_key])
.values_list(
"external_id",
flat=True,
@@ -4289,7 +4289,7 @@ def make_discussion_xblock(self, topic_id, category, subcategory, **kwargs):
Build a discussion xblock in self.course.
"""
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id=topic_id,
discussion_category=category,
diff --git a/lms/djangoapps/discussion/rest_api/tests/test_views_v2.py b/lms/djangoapps/discussion/rest_api/tests/test_views_v2.py
index 10251224ad7d..86a4ac823e91 100644
--- a/lms/djangoapps/discussion/rest_api/tests/test_views_v2.py
+++ b/lms/djangoapps/discussion/rest_api/tests/test_views_v2.py
@@ -1236,7 +1236,7 @@ def create_course(self, blocks_count, module_store, topics):
# add some discussion xblocks
for i in range(blocks_count):
BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category='discussion',
discussion_id=f'id_module_{i}',
discussion_category=f'Category {i}',
@@ -1250,7 +1250,7 @@ def make_discussion_xblock(self, topic_id, category, subcategory, **kwargs):
Build a discussion xblock in self.course
"""
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id=topic_id,
discussion_category=category,
@@ -1372,19 +1372,19 @@ def test_new_course_structure_response(self):
(For mobile compatibility)
"""
chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name="Week 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
sequential = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category='sequential',
display_name="Lesson 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
BlockFactory.create(
- parent_location=sequential.location,
+ parent_location=sequential.usage_key,
category='vertical',
display_name='vertical',
start=datetime(2015, 4, 1, tzinfo=UTC),
@@ -1433,20 +1433,20 @@ def setUp(self) -> None:
}}
)
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name="Week 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.sequential = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
display_name="Lesson 1",
start=datetime(2015, 3, 1, tzinfo=UTC),
)
self.verticals = [
BlockFactory.create(
- parent_location=self.sequential.location,
+ parent_location=self.sequential.usage_key,
category='vertical',
display_name='vertical',
start=datetime(2015, 4, 1, tzinfo=UTC),
@@ -2450,7 +2450,7 @@ def test_update_inline_discussion_settings(self):
now = datetime.now()
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id='Topic_A',
discussion_category='Chapter',
diff --git a/lms/djangoapps/discussion/tasks.py b/lms/djangoapps/discussion/tasks.py
index d483388f54ae..1c9436c101e3 100644
--- a/lms/djangoapps/discussion/tasks.py
+++ b/lms/djangoapps/discussion/tasks.py
@@ -57,7 +57,7 @@ def update_discussions_map(context):
course_key = CourseKey.from_string(context['course_id'])
discussion_blocks = get_accessible_discussion_xblocks_by_course_id(course_key, include_all=True)
discussions_id_map = {
- discussion_block.discussion_id: str(discussion_block.location)
+ discussion_block.discussion_id: str(discussion_block.usage_key)
for discussion_block in discussion_blocks
}
DiscussionsIdMapping.update_mapping(course_key, discussions_id_map)
diff --git a/lms/djangoapps/discussion/tests/test_signals.py b/lms/djangoapps/discussion/tests/test_signals.py
index d61b706292cf..e3d0e265bb21 100644
--- a/lms/djangoapps/discussion/tests/test_signals.py
+++ b/lms/djangoapps/discussion/tests/test_signals.py
@@ -97,11 +97,11 @@ def test_discussion_id_map_updates_on_publish(self):
RequestCache().clear()
discussion_id = 'discussion1'
discussion_block = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="discussion",
discussion_id=discussion_id,
)
- self._assert_discussion_id_map(course_key, {discussion_id: str(discussion_block.location)})
+ self._assert_discussion_id_map(course_key, {discussion_id: str(discussion_block.usage_key)})
def _assert_discussion_id_map(self, course_key, expected_map):
"""
diff --git a/lms/djangoapps/discussion/tests/test_views.py b/lms/djangoapps/discussion/tests/test_views.py
index 7f575b454fad..f9ace092303e 100644
--- a/lms/djangoapps/discussion/tests/test_views.py
+++ b/lms/djangoapps/discussion/tests/test_views.py
@@ -420,7 +420,7 @@ def create_divided_discussions(self):
# inline discussion
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id=topic_name_to_id(self.course, "Topic A"),
discussion_category="Chapter",
@@ -428,7 +428,7 @@ def create_divided_discussions(self):
start=datetime.now()
)
# get updated course
- self.course = self.store.get_item(self.course.location)
+ self.course = self.store.get_item(self.course.usage_key)
# course-wide discussion
discussion_topics = {
"Topic B": {"id": "Topic B"},
@@ -591,7 +591,7 @@ def test_update_inline_discussion_settings(self):
now = datetime.now()
# inline discussion
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id="Topic_A",
discussion_category="Chapter",
diff --git a/lms/djangoapps/discussion/tests/test_views_v2.py b/lms/djangoapps/discussion/tests/test_views_v2.py
index 0f268e93eb32..45ee1e452e69 100644
--- a/lms/djangoapps/discussion/tests/test_views_v2.py
+++ b/lms/djangoapps/discussion/tests/test_views_v2.py
@@ -1556,7 +1556,7 @@ def setUp(self):
self.student = UserFactory.create()
CourseEnrollmentFactory(user=self.student, course_id=self.course.id)
self.discussion1 = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="discussion",
discussion_id="discussion1",
display_name="Discussion1",
@@ -1914,7 +1914,7 @@ def setUp(self): # pylint: disable=arguments-differ
UserBasedRole(user=self.staff, role=CourseStaffRole.ROLE).add_course(self.course.id)
self.category = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='discussion',
discussion_id=self.CATEGORY_ID,
discussion_category=self.PARENT_CATEGORY_NAME,
diff --git a/lms/djangoapps/edxnotes/helpers.py b/lms/djangoapps/edxnotes/helpers.py
index 5e68ae4b2003..8ff9595c908a 100644
--- a/lms/djangoapps/edxnotes/helpers.py
+++ b/lms/djangoapps/edxnotes/helpers.py
@@ -203,13 +203,13 @@ def preprocess_collection(user, course, collection):
if not section:
log.debug("Section not found: %s", usage_key)
continue
- if section.location in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary
- usage_context = cache[section.location]
+ if section.usage_key in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary
+ usage_context = cache[section.usage_key]
usage_context.update({
"unit": get_block_context(course, unit),
})
model.update(usage_context)
- cache[usage_id] = cache[unit.location] = usage_context
+ cache[usage_id] = cache[unit.usage_key] = usage_context
filtered_collection.append(model)
continue
@@ -217,14 +217,14 @@ def preprocess_collection(user, course, collection):
if not chapter:
log.debug("Chapter not found: %s", usage_key)
continue
- if chapter.location in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary
- usage_context = cache[chapter.location]
+ if chapter.usage_key in list(cache.keys()): # lint-amnesty, pylint: disable=consider-iterating-dictionary
+ usage_context = cache[chapter.usage_key]
usage_context.update({
"unit": get_block_context(course, unit),
"section": get_block_context(course, section),
})
model.update(usage_context)
- cache[usage_id] = cache[unit.location] = cache[section.location] = usage_context
+ cache[usage_id] = cache[unit.usage_key] = cache[section.usage_key] = usage_context
filtered_collection.append(model)
continue
@@ -235,9 +235,9 @@ def preprocess_collection(user, course, collection):
}
model.update(usage_context)
if include_path_info:
- cache[section.location] = cache[chapter.location] = usage_context
+ cache[section.usage_key] = cache[chapter.usage_key] = usage_context
- cache[usage_id] = cache[unit.location] = usage_context
+ cache[usage_id] = cache[unit.usage_key] = usage_context
filtered_collection.append(model)
return filtered_collection
@@ -248,7 +248,7 @@ def get_block_context(course, block):
Returns dispay_name and url for the parent block.
"""
block_dict = {
- 'location': str(block.location),
+ 'location': str(block.usage_key),
'display_name': Text(block.display_name_with_default),
}
if block.category == 'chapter' and block.get_parent():
@@ -258,7 +258,7 @@ def get_block_context(course, block):
block_dict['index'] = get_index(block_dict['location'], course.children)
elif block.category == 'vertical':
# Use the MFE-aware URL generator instead of always using the legacy URL format
- block_dict['url'] = get_courseware_url(block.location)
+ block_dict['url'] = get_courseware_url(block.usage_key)
if block.category in ('chapter', 'sequential'):
block_dict['children'] = [str(child) for child in block.children]
diff --git a/lms/djangoapps/edxnotes/tests.py b/lms/djangoapps/edxnotes/tests.py
index 46920e927ad9..a4a944f8d489 100644
--- a/lms/djangoapps/edxnotes/tests.py
+++ b/lms/djangoapps/edxnotes/tests.py
@@ -205,32 +205,32 @@ def setUp(self):
with self.store.default_store(ModuleStoreEnum.Type.split):
ApplicationFactory(name="edx-notes")
self.course = CourseFactory.create()
- self.chapter = BlockFactory.create(category="chapter", parent_location=self.course.location)
- self.chapter_2 = BlockFactory.create(category="chapter", parent_location=self.course.location)
- self.sequential = BlockFactory.create(category="sequential", parent_location=self.chapter.location)
- self.vertical = BlockFactory.create(category="vertical", parent_location=self.sequential.location)
- self.html_block_1 = BlockFactory.create(category="html", parent_location=self.vertical.location)
- self.html_block_2 = BlockFactory.create(category="html", parent_location=self.vertical.location)
+ self.chapter = BlockFactory.create(category="chapter", parent_location=self.course.usage_key)
+ self.chapter_2 = BlockFactory.create(category="chapter", parent_location=self.course.usage_key)
+ self.sequential = BlockFactory.create(category="sequential", parent_location=self.chapter.usage_key)
+ self.vertical = BlockFactory.create(category="vertical", parent_location=self.sequential.usage_key)
+ self.html_block_1 = BlockFactory.create(category="html", parent_location=self.vertical.usage_key)
+ self.html_block_2 = BlockFactory.create(category="html", parent_location=self.vertical.usage_key)
self.vertical_with_container = BlockFactory.create(
- category='vertical', parent_location=self.sequential.location
+ category='vertical', parent_location=self.sequential.usage_key
)
self.child_container = BlockFactory.create(
- category='split_test', parent_location=self.vertical_with_container.location)
+ category='split_test', parent_location=self.vertical_with_container.usage_key)
self.child_vertical = BlockFactory.create(
- category='vertical', parent_location=self.child_container.location)
- self.child_html_block = BlockFactory.create(category="html", parent_location=self.child_vertical.location)
+ category='vertical', parent_location=self.child_container.usage_key)
+ self.child_html_block = BlockFactory.create(category="html", parent_location=self.child_vertical.usage_key)
# Read again so that children lists are accurate
- self.course = self.store.get_item(self.course.location)
- self.chapter = self.store.get_item(self.chapter.location)
- self.chapter_2 = self.store.get_item(self.chapter_2.location)
- self.sequential = self.store.get_item(self.sequential.location)
- self.vertical = self.store.get_item(self.vertical.location)
+ self.course = self.store.get_item(self.course.usage_key)
+ self.chapter = self.store.get_item(self.chapter.usage_key)
+ self.chapter_2 = self.store.get_item(self.chapter_2.usage_key)
+ self.sequential = self.store.get_item(self.sequential.usage_key)
+ self.vertical = self.store.get_item(self.vertical.usage_key)
- self.vertical_with_container = self.store.get_item(self.vertical_with_container.location)
- self.child_container = self.store.get_item(self.child_container.location)
- self.child_vertical = self.store.get_item(self.child_vertical.location)
- self.child_html_block = self.store.get_item(self.child_html_block.location)
+ self.vertical_with_container = self.store.get_item(self.vertical_with_container.usage_key)
+ self.child_container = self.store.get_item(self.child_container.usage_key)
+ self.child_vertical = self.store.get_item(self.child_vertical.usage_key)
+ self.child_html_block = self.store.get_item(self.child_html_block.usage_key)
self.user = UserFactory()
self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) # lint-amnesty, pylint: disable=protected-access
@@ -321,13 +321,13 @@ def test_get_notes_correct_data(self, mock_get):
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(),
},
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": datetime(2014, 11, 19, 8, 6, 16, 00000).isoformat(),
}
]
@@ -349,22 +349,22 @@ def test_get_notes_correct_data(self, mock_get):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
+ "location": str(self.sequential.usage_key),
"children": [
- str(self.vertical.location), str(self.vertical_with_container.location)
+ str(self.vertical.usage_key), str(self.vertical_with_container.usage_key)
]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": "Nov 19, 2014 at 08:06 UTC",
},
{
@@ -373,22 +373,22 @@ def test_get_notes_correct_data(self, mock_get):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
+ "location": str(self.sequential.usage_key),
"children": [
- str(self.vertical.location),
- str(self.vertical_with_container.location)]
+ str(self.vertical.usage_key),
+ str(self.vertical_with_container.usage_key)]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": "Nov 19, 2014 at 08:05 UTC",
},
]
@@ -426,13 +426,13 @@ def test_search_correct_data(self, mock_get):
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(),
},
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": datetime(2014, 11, 19, 8, 6, 16, 00000).isoformat(),
}
]
@@ -453,22 +453,22 @@ def test_search_correct_data(self, mock_get):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
+ "location": str(self.sequential.usage_key),
"children": [
- str(self.vertical.location),
- str(self.vertical_with_container.location)]
+ str(self.vertical.usage_key),
+ str(self.vertical_with_container.usage_key)]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": "Nov 19, 2014 at 08:06 UTC",
},
{
@@ -477,22 +477,22 @@ def test_search_correct_data(self, mock_get):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
+ "location": str(self.sequential.usage_key),
"children": [
- str(self.vertical.location),
- str(self.vertical_with_container.location)]
+ str(self.vertical.usage_key),
+ str(self.vertical_with_container.usage_key)]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": "Nov 19, 2014 at 08:05 UTC",
},
]
@@ -553,7 +553,7 @@ def test_preprocess_collection_no_item(self):
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat()
},
{
@@ -571,20 +571,20 @@ def test_preprocess_collection_no_item(self):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
- "children": [str(self.vertical.location), str(self.vertical_with_container.location)]
+ "location": str(self.sequential.usage_key),
+ "children": [str(self.vertical.usage_key), str(self.vertical_with_container.usage_key)]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000),
}]) == len(helpers.preprocess_collection(self.user, self.course, initial_collection))
@@ -596,13 +596,13 @@ def test_preprocess_collection_has_access(self):
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(),
},
{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": datetime(2014, 11, 19, 8, 6, 16, 00000).isoformat(),
},
]
@@ -615,20 +615,20 @@ def test_preprocess_collection_has_access(self):
"chapter": {
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)]
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)]
},
"section": {
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
- "children": [str(self.vertical.location), str(self.vertical_with_container.location)]
+ "location": str(self.sequential.usage_key),
+ "children": [str(self.vertical.usage_key), str(self.vertical_with_container.usage_key)]
},
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000),
}]) == len(helpers.preprocess_collection(self.user, self.course, initial_collection))
@@ -645,7 +645,7 @@ def test_preprocess_collection_no_unit(self, mock_modulestore, mock_has_access):
initial_collection = [{
"quote": "quote text",
"text": "text",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(),
}]
@@ -660,13 +660,13 @@ def test_preprocess_collection_with_disabled_tabs(self, ):
{
"quote": "quote text1",
"text": "text1",
- "usage_id": str(self.html_block_1.location),
+ "usage_id": str(self.html_block_1.usage_key),
"updated": datetime(2016, 1, 26, 8, 5, 16, 00000).isoformat(),
},
{
"quote": "quote text2",
"text": "text2",
- "usage_id": str(self.html_block_2.location),
+ "usage_id": str(self.html_block_2.usage_key),
"updated": datetime(2016, 1, 26, 9, 6, 17, 00000).isoformat(),
},
]
@@ -680,11 +680,11 @@ def test_preprocess_collection_with_disabled_tabs(self, ):
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
'text': 'text1',
'quote': 'quote text1',
- 'usage_id': str(self.html_block_1.location),
+ 'usage_id': str(self.html_block_1.usage_key),
'updated': datetime(2016, 1, 26, 8, 5, 16)
},
{
@@ -693,11 +693,11 @@ def test_preprocess_collection_with_disabled_tabs(self, ):
"unit": {
"url": self._get_unit_url(self.course, self.chapter, self.sequential),
"display_name": self.vertical.display_name_with_default,
- "location": str(self.vertical.location),
+ "location": str(self.vertical.usage_key),
},
'text': 'text2',
'quote': 'quote text2',
- 'usage_id': str(self.html_block_2.location),
+ 'usage_id': str(self.html_block_2.usage_key),
'updated': datetime(2016, 1, 26, 9, 6, 17)
}
]) == len(helpers.preprocess_collection(self.user, self.course, initial_collection))
@@ -709,8 +709,8 @@ def test_get_block_context_sequential(self):
self.assertDictEqual(
{
"display_name": self.sequential.display_name_with_default,
- "location": str(self.sequential.location),
- "children": [str(self.vertical.location), str(self.vertical_with_container.location)],
+ "location": str(self.sequential.usage_key),
+ "children": [str(self.vertical.usage_key), str(self.vertical_with_container.usage_key)],
},
helpers.get_block_context(self.course, self.sequential)
)
@@ -722,7 +722,7 @@ def test_get_block_context_html_component(self):
self.assertDictEqual(
{
"display_name": self.html_block_1.display_name_with_default,
- "location": str(self.html_block_1.location),
+ "location": str(self.html_block_1.usage_key),
},
helpers.get_block_context(self.course, self.html_block_1)
)
@@ -735,8 +735,8 @@ def test_get_block_context_chapter(self):
{
"display_name": self.chapter.display_name_with_default,
"index": 0,
- "location": str(self.chapter.location),
- "children": [str(self.sequential.location)],
+ "location": str(self.chapter.usage_key),
+ "children": [str(self.sequential.usage_key)],
},
helpers.get_block_context(self.course, self.chapter)
)
@@ -744,7 +744,7 @@ def test_get_block_context_chapter(self):
{
"display_name": self.chapter_2.display_name_with_default,
"index": 1,
- "location": str(self.chapter_2.location),
+ "location": str(self.chapter_2.usage_key),
"children": [],
},
helpers.get_block_context(self.course, self.chapter_2)
@@ -876,8 +876,8 @@ def test_get_index(self):
Tests `get_index` method returns unit url.
"""
children = self.sequential.children
- assert 0 == helpers.get_index(str(self.vertical.location), children)
- assert 1 == helpers.get_index(str(self.vertical_with_container.location), children)
+ assert 0 == helpers.get_index(str(self.vertical.usage_key), children)
+ assert 1 == helpers.get_index(str(self.vertical_with_container.usage_key), children)
@ddt.unpack
@ddt.data(
diff --git a/lms/djangoapps/gating/api.py b/lms/djangoapps/gating/api.py
index 75715124cd28..75710ce9b881 100644
--- a/lms/djangoapps/gating/api.py
+++ b/lms/djangoapps/gating/api.py
@@ -24,7 +24,7 @@ def evaluate_prerequisite(course, subsection_grade, user):
the minimum score required by dependent subsections, the related
milestone will be marked fulfilled for the user.
"""
- prereq_milestone = gating_api.get_gating_milestone(course.id, subsection_grade.location, 'fulfills')
+ prereq_milestone = gating_api.get_gating_milestone(course.id, subsection_grade.usage_key, 'fulfills')
if prereq_milestone:
gated_content_milestones = defaultdict(list)
for milestone in gating_api.find_gating_milestones(course.id, content_key=None, relationship='requires'):
@@ -37,7 +37,7 @@ def evaluate_prerequisite(course, subsection_grade, user):
for milestone in gated_content:
gating_api.update_milestone(
- milestone, subsection_grade.location, prereq_milestone, user, grade_percentage
+ milestone, subsection_grade.usage_key, prereq_milestone, user, grade_percentage
)
diff --git a/lms/djangoapps/gating/tasks.py b/lms/djangoapps/gating/tasks.py
index 750790807934..b2feb730a78a 100644
--- a/lms/djangoapps/gating/tasks.py
+++ b/lms/djangoapps/gating/tasks.py
@@ -44,7 +44,7 @@ def task_evaluate_subsection_completion_milestones(course_id, block_id, user_id)
subsection = course_structure[subsection_block]
log.debug(
"Gating: Evaluating completion milestone for subsection [%s] and user [%s]",
- str(subsection.location), user.id
+ str(subsection.usage_key), user.id
)
gating_api.evaluate_prerequisite(course, subsection, user)
except KeyError:
diff --git a/lms/djangoapps/gating/tests/test_api.py b/lms/djangoapps/gating/tests/test_api.py
index 326ea9124cf9..f9ad8ab0864c 100644
--- a/lms/djangoapps/gating/tests/test_api.py
+++ b/lms/djangoapps/gating/tests/test_api.py
@@ -41,19 +41,19 @@ def setUp(self):
# create chapter
self.chapter1 = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category='chapter',
display_name='untitled chapter 1'
)
# create sequentials
self.seq1 = BlockFactory.create(
- parent_location=self.chapter1.location,
+ parent_location=self.chapter1.usage_key,
category='sequential',
display_name='gating sequential'
)
self.seq2 = BlockFactory.create(
- parent_location=self.chapter1.location,
+ parent_location=self.chapter1.usage_key,
category='sequential',
display_name='gated sequential'
)
@@ -69,17 +69,17 @@ def setUp(self):
super().setUp()
self.user_dict = {'id': self.user.id}
self.prereq_milestone = None
- self.subsection_grade = Mock(location=self.seq1.location, percent_graded=0.5)
+ self.subsection_grade = Mock(location=self.seq1.usage_key, percent_graded=0.5)
def _setup_gating_milestone(self, min_score, min_completion):
"""
Setup a gating milestone for testing
"""
- gating_api.add_prerequisite(self.course.id, self.seq1.location)
+ gating_api.add_prerequisite(self.course.id, self.seq1.usage_key)
gating_api.set_required_content(
- self.course.id, self.seq2.location, self.seq1.location, min_score, min_completion
+ self.course.id, self.seq2.usage_key, self.seq1.usage_key, min_score, min_completion
)
- self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.location, 'fulfills')
+ self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.usage_key, 'fulfills')
@patch('openedx.core.lib.gating.api.get_subsection_completion_percentage')
@data(
@@ -122,7 +122,7 @@ def test_no_prerequisites(self, mock_score):
@patch('openedx.core.lib.gating.api.get_subsection_grade_percentage')
def test_no_gated_content(self, mock_score):
- gating_api.add_prerequisite(self.course.id, self.seq1.location)
+ gating_api.add_prerequisite(self.course.id, self.seq1.usage_key)
evaluate_prerequisite(self.course, self.subsection_grade, self.user)
assert not mock_score.called
diff --git a/lms/djangoapps/gating/tests/test_integration.py b/lms/djangoapps/gating/tests/test_integration.py
index 3b399e1b89e0..323abd38acbb 100644
--- a/lms/djangoapps/gating/tests/test_integration.py
+++ b/lms/djangoapps/gating/tests/test_integration.py
@@ -123,7 +123,7 @@ def set_up_course(cls):
display_name='problem 3',
)
# get updated course
- cls.course = cls.store.get_item(course.location)
+ cls.course = cls.store.get_item(course.usage_key)
def setup_gating_milestone(self, min_score, min_completion):
"""
@@ -131,11 +131,11 @@ def setup_gating_milestone(self, min_score, min_completion):
Gating content: seq1 (must be fulfilled before access to seq2)
Gated content: seq2 (requires completion of seq1 before access)
"""
- gating_api.add_prerequisite(self.course.id, str(self.seq1.location))
+ gating_api.add_prerequisite(self.course.id, str(self.seq1.usage_key))
gating_api.set_required_content(
- self.course.id, str(self.seq2.location), str(self.seq1.location), min_score, min_completion
+ self.course.id, str(self.seq2.usage_key), str(self.seq1.usage_key), min_score, min_completion
)
- self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.location, 'fulfills')
+ self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.usage_key, 'fulfills')
def assert_access_to_gated_content(self, user):
"""
@@ -165,7 +165,7 @@ def assert_course_grade(self, user, expected_percent):
"""
course_grade = CourseGradeFactory().read(user, self.course)
for prob in [self.gating_prob1, self.gated_prob2, self.prob3]:
- assert prob.location in course_grade.problem_scores
+ assert prob.usage_key in course_grade.problem_scores
assert course_grade.percent == expected_percent
diff --git a/lms/djangoapps/grades/context.py b/lms/djangoapps/grades/context.py
index 54a7e8f93fdb..879e019639a3 100644
--- a/lms/djangoapps/grades/context.py
+++ b/lms/djangoapps/grades/context.py
@@ -60,7 +60,7 @@ def grading_context(course, course_structure):
scored_descendants_of_subsection = []
for descendant_key in course_structure.post_order_traversal(
filter_func=possibly_scored,
- start_node=subsection.location,
+ start_node=subsection.usage_key,
):
scored_descendants_of_subsection.append(
course_structure[descendant_key],
diff --git a/lms/djangoapps/grades/course_data.py b/lms/djangoapps/grades/course_data.py
index 5464c4f88105..f360ed0faf3c 100644
--- a/lms/djangoapps/grades/course_data.py
+++ b/lms/djangoapps/grades/course_data.py
@@ -48,7 +48,7 @@ def location(self): # lint-amnesty, pylint: disable=missing-function-docstring
if structure:
self._location = structure.root_block_usage_key
elif self._course:
- self._location = self._course.location
+ self._location = self._course.usage_key
else:
self._location = modulestore().make_course_usage_key(self.course_key)
return self._location
@@ -58,7 +58,7 @@ def structure(self): # lint-amnesty, pylint: disable=missing-function-docstring
if self._structure is None:
self._structure = get_course_blocks(
self.user,
- self.location,
+ self.usage_key,
collected_block_structure=self._collected_block_structure,
)
return self._structure
@@ -90,7 +90,7 @@ def grading_policy_hash(self): # lint-amnesty, pylint: disable=missing-function
@property
def version(self):
structure = self.effective_structure
- course_block = structure[self.location] if structure else self.course
+ course_block = structure[self.usage_key] if structure else self.course
return getattr(course_block, 'course_version', None)
@property
@@ -98,7 +98,7 @@ def edited_on(self): # lint-amnesty, pylint: disable=missing-function-docstring
# get course block from structure only; subtree_edited_on field on modulestore's course block isn't optimized.
structure = self.effective_structure
if structure:
- course_block = structure[self.location]
+ course_block = structure[self.usage_key]
return getattr(course_block, 'subtree_edited_on', None)
def __str__(self):
diff --git a/lms/djangoapps/grades/course_grade.py b/lms/djangoapps/grades/course_grade.py
index 1642e7c69759..6c2e6e0b4d56 100644
--- a/lms/djangoapps/grades/course_grade.py
+++ b/lms/djangoapps/grades/course_grade.py
@@ -105,7 +105,7 @@ def graded_subsections_by_format(self, visible_grades_only=False, has_staff_acce
if subsection_grade.graded and is_visible:
graded_total = subsection_grade.graded_total
if graded_total.possible > 0:
- subsections_by_format[subsection_grade.format][subsection_grade.location] = subsection_grade
+ subsections_by_format[subsection_grade.format][subsection_grade.usage_key] = subsection_grade
return subsections_by_format
@lazy
@@ -118,7 +118,7 @@ def chapter_grades(self):
"""
course_structure = self.course_data.structure
grades = OrderedDict()
- for chapter_key in course_structure.get_children(self.course_data.location):
+ for chapter_key in course_structure.get_children(self.course_data.usage_key):
grades[chapter_key] = self._get_chapter_grade_info(course_structure[chapter_key], course_structure)
return grades
@@ -131,7 +131,7 @@ def subsection_grades(self):
subsection_grades = defaultdict(OrderedDict)
for chapter in self.chapter_grades.values():
for subsection_grade in chapter['sections']:
- subsection_grades[subsection_grade.location] = subsection_grade
+ subsection_grades[subsection_grade.usage_key] = subsection_grade
return subsection_grades
@lazy
@@ -239,7 +239,7 @@ def _get_chapter_grade_info(self, chapter, course_structure):
"""
Helper that returns a dictionary of chapter grade information.
"""
- chapter_subsection_grades = self._get_subsection_grades(course_structure, chapter.location)
+ chapter_subsection_grades = self._get_subsection_grades(course_structure, chapter.usage_key)
return {
'display_name': block_metadata_utils.display_name_with_default(chapter),
'url_name': chapter.usage_key.block_id,
diff --git a/lms/djangoapps/grades/rest_api/v1/gradebook_views.py b/lms/djangoapps/grades/rest_api/v1/gradebook_views.py
index c295563da565..019f7b0d492d 100644
--- a/lms/djangoapps/grades/rest_api/v1/gradebook_views.py
+++ b/lms/djangoapps/grades/rest_api/v1/gradebook_views.py
@@ -334,7 +334,7 @@ def _get_subsections(self, course, graded_only=False):
'assignment_type': subsection.format,
'graded': subsection.graded,
'short_label': short_label,
- 'module_id': str(subsection.location),
+ 'module_id': str(subsection.usage_key),
'display_name': subsection.display_name,
})
return subsections
@@ -450,7 +450,7 @@ def _section_breakdown(self, course, graded_subsections, course_grade):
default_labeler = get_default_short_labeler(course)
for subsection in graded_subsections:
- subsection_grade = course_grade.subsection_grade(subsection.location)
+ subsection_grade = course_grade.subsection_grade(subsection.usage_key)
short_label = default_labeler(subsection_grade.format)
attempted = False
@@ -479,7 +479,7 @@ def _section_breakdown(self, course, graded_subsections, course_grade):
'attempted': attempted,
'category': subsection_grade.format,
'label': short_label,
- 'module_id': str(subsection_grade.location),
+ 'module_id': str(subsection_grade.usage_key),
'percent': subsection_grade.percent_graded,
'score_earned': score_earned,
'score_possible': score_possible,
diff --git a/lms/djangoapps/grades/rest_api/v1/tests/mixins.py b/lms/djangoapps/grades/rest_api/v1/tests/mixins.py
index 1d3a6a0b4551..0f2d22a99064 100644
--- a/lms/djangoapps/grades/rest_api/v1/tests/mixins.py
+++ b/lms/djangoapps/grades/rest_api/v1/tests/mixins.py
@@ -129,7 +129,7 @@ def _create_test_course_with_default_grading_policy(cls, display_name, run):
chapter = BlockFactory.create(
category='chapter',
- parent_location=course.location,
+ parent_location=course.usage_key,
display_name="Chapter 1",
)
# create a problem for each type and minimum count needed by the grading policy
@@ -138,7 +138,7 @@ def _create_test_course_with_default_grading_policy(cls, display_name, run):
for num in range(min_count):
section = BlockFactory.create(
category='sequential',
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
due=datetime(2017, 12, 18, 11, 30, 00),
display_name=f'Sequential {grading_type} {num}',
format=grading_type,
@@ -146,12 +146,12 @@ def _create_test_course_with_default_grading_policy(cls, display_name, run):
)
vertical = BlockFactory.create(
category='vertical',
- parent_location=section.location,
+ parent_location=section.usage_key,
display_name=f'Vertical {grading_type} {num}',
)
BlockFactory.create(
category='problem',
- parent_location=vertical.location,
+ parent_location=vertical.usage_key,
display_name=f'Problem {grading_type} {num}',
)
diff --git a/lms/djangoapps/grades/rest_api/v1/tests/test_gradebook_views.py b/lms/djangoapps/grades/rest_api/v1/tests/test_gradebook_views.py
index 2b9f732912c0..fdf86d0c8599 100644
--- a/lms/djangoapps/grades/rest_api/v1/tests/test_gradebook_views.py
+++ b/lms/djangoapps/grades/rest_api/v1/tests/test_gradebook_views.py
@@ -86,54 +86,54 @@ def initialize_course(cls, course):
"Pass": 0.5,
}
cls.section = BlockFactory.create(
- parent_location=course.location,
+ parent_location=course.usage_key,
category="chapter",
)
cls.subsection1 = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
)
unit1 = BlockFactory.create(
- parent_location=cls.subsection1.location,
+ parent_location=cls.subsection1.usage_key,
category="vertical",
)
BlockFactory.create(
- parent_location=unit1.location,
+ parent_location=unit1.usage_key,
category="video",
)
BlockFactory.create(
- parent_location=unit1.location,
+ parent_location=unit1.usage_key,
category="problem",
)
cls.subsection2 = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
)
unit2 = BlockFactory.create(
- parent_location=cls.subsection2.location,
+ parent_location=cls.subsection2.usage_key,
category="vertical",
)
unit3 = BlockFactory.create(
- parent_location=cls.subsection2.location,
+ parent_location=cls.subsection2.usage_key,
category="vertical",
)
BlockFactory.create(
- parent_location=unit3.location,
+ parent_location=unit3.usage_key,
category="video",
)
BlockFactory.create(
- parent_location=unit3.location,
+ parent_location=unit3.usage_key,
category="video",
)
cls.homework = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
graded=True,
format='Homework',
)
cls.midterm = BlockFactory.create(
- parent_location=cls.section.location,
+ parent_location=cls.section.usage_key,
category="sequential",
graded=True,
format='Midterm Exam',
@@ -190,28 +190,28 @@ def _get_expected_data(self):
'assignment_type': None,
'display_name': self.subsection1.display_name,
'graded': False,
- 'module_id': str(self.subsection1.location),
+ 'module_id': str(self.subsection1.usage_key),
'short_label': None
},
{
'assignment_type': None,
'display_name': self.subsection2.display_name,
'graded': False,
- 'module_id': str(self.subsection2.location),
+ 'module_id': str(self.subsection2.usage_key),
'short_label': None
},
{
'assignment_type': 'Homework',
'display_name': self.homework.display_name,
'graded': True,
- 'module_id': str(self.homework.location),
+ 'module_id': str(self.homework.usage_key),
'short_label': 'HW 01',
},
{
'assignment_type': 'Midterm Exam',
'display_name': self.midterm.display_name,
'graded': True,
- 'module_id': str(self.midterm.location),
+ 'module_id': str(self.midterm.usage_key),
'short_label': 'Midterm 01',
},
],
@@ -303,19 +303,19 @@ def setUpClass(cls):
cls.chapter_1 = BlockFactory.create(
category='chapter',
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="Chapter 1",
)
cls.chapter_2 = BlockFactory.create(
category='chapter',
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="Chapter 2",
)
cls.subsections = {
- cls.chapter_1.location: [
+ cls.chapter_1.usage_key: [
BlockFactory.create(
category='sequential',
- parent_location=cls.chapter_1.location,
+ parent_location=cls.chapter_1.usage_key,
due=datetime(2017, 12, 18, 11, 30, 00),
display_name='HW 1',
format='Homework',
@@ -323,17 +323,17 @@ def setUpClass(cls):
),
BlockFactory.create(
category='sequential',
- parent_location=cls.chapter_1.location,
+ parent_location=cls.chapter_1.usage_key,
due=datetime(2017, 12, 18, 11, 30, 00),
display_name='Lab 1',
format='Lab',
graded=True,
),
],
- cls.chapter_2.location: [
+ cls.chapter_2.usage_key: [
BlockFactory.create(
category='sequential',
- parent_location=cls.chapter_2.location,
+ parent_location=cls.chapter_2.usage_key,
due=datetime(2017, 12, 18, 11, 30, 00),
display_name='HW 2',
format='Homework',
@@ -341,7 +341,7 @@ def setUpClass(cls):
),
BlockFactory.create(
category='sequential',
- parent_location=cls.chapter_2.location,
+ parent_location=cls.chapter_2.usage_key,
due=datetime(2017, 12, 18, 11, 30, 00),
display_name='Lab 2',
format='Lab',
@@ -353,7 +353,7 @@ def setUpClass(cls):
# Data about graded subsections visible to staff only
# should not be exposed via the gradebook API
cls.hidden_subsection = BlockFactory.create(
- parent_location=cls.chapter_1.location,
+ parent_location=cls.chapter_1.usage_key,
category='sequential',
graded=True,
visible_to_staff_only=True,
@@ -414,29 +414,29 @@ class GradebookViewTest(GradebookViewTestBase):
def setUpClass(cls):
super().setUpClass()
cls.mock_subsection_grades = {
- cls.subsections[cls.chapter_1.location][0].location: cls.mock_subsection_grade(
- cls.subsections[cls.chapter_1.location][0],
+ cls.subsections[cls.chapter_1.usage_key][0].usage_key: cls.mock_subsection_grade(
+ cls.subsections[cls.chapter_1.usage_key][0],
earned_all=1.0,
possible_all=2.0,
earned_graded=1.0,
possible_graded=2.0,
),
- cls.subsections[cls.chapter_1.location][1].location: cls.mock_subsection_grade(
- cls.subsections[cls.chapter_1.location][1],
+ cls.subsections[cls.chapter_1.usage_key][1].usage_key: cls.mock_subsection_grade(
+ cls.subsections[cls.chapter_1.usage_key][1],
earned_all=1.0,
possible_all=2.0,
earned_graded=1.0,
possible_graded=2.0,
),
- cls.subsections[cls.chapter_2.location][0].location: cls.mock_subsection_grade(
- cls.subsections[cls.chapter_2.location][0],
+ cls.subsections[cls.chapter_2.usage_key][0].usage_key: cls.mock_subsection_grade(
+ cls.subsections[cls.chapter_2.usage_key][0],
earned_all=1.0,
possible_all=2.0,
earned_graded=1.0,
possible_graded=2.0,
),
- cls.subsections[cls.chapter_2.location][1].location: cls.mock_subsection_grade(
- cls.subsections[cls.chapter_2.location][1],
+ cls.subsections[cls.chapter_2.usage_key][1].usage_key: cls.mock_subsection_grade(
+ cls.subsections[cls.chapter_2.usage_key][1],
earned_all=1.0,
possible_all=2.0,
earned_graded=1.0,
@@ -483,7 +483,7 @@ def expected_subsection_grades(self):
('attempted', True),
('category', 'Homework'),
('label', 'HW 01'),
- ('module_id', str(self.subsections[self.chapter_1.location][0].location)),
+ ('module_id', str(self.subsections[self.chapter_1.usage_key][0].usage_key)),
('percent', 0.5),
('score_earned', 1.0),
('score_possible', 2.0),
@@ -493,7 +493,7 @@ def expected_subsection_grades(self):
('attempted', True),
('category', 'Lab'),
('label', 'Lab 01'),
- ('module_id', str(self.subsections[self.chapter_1.location][1].location)),
+ ('module_id', str(self.subsections[self.chapter_1.usage_key][1].usage_key)),
('percent', 0.5),
('score_earned', 1.0),
('score_possible', 2.0),
@@ -503,7 +503,7 @@ def expected_subsection_grades(self):
('attempted', True),
('category', 'Homework'),
('label', 'HW 02'),
- ('module_id', str(self.subsections[self.chapter_2.location][0].location)),
+ ('module_id', str(self.subsections[self.chapter_2.usage_key][0].usage_key)),
('percent', 0.5),
('score_earned', 1.0),
('score_possible', 2.0),
@@ -513,7 +513,7 @@ def expected_subsection_grades(self):
('attempted', True),
('category', 'Lab'),
('label', 'Lab 02'),
- ('module_id', str(self.subsections[self.chapter_2.location][1].location)),
+ ('module_id', str(self.subsections[self.chapter_2.usage_key][1].usage_key)),
('percent', 0.5),
('score_earned', 1.0),
('score_possible', 2.0),
@@ -696,8 +696,8 @@ def test_gradebook_data_for_single_learner_override(self, login_method):
possible_graded_override=2.0,
)
mock_subsection_grades = {
- self.subsections[self.chapter_1.location][0].location: self.mock_subsection_grade(
- self.subsections[self.chapter_1.location][0],
+ self.subsections[self.chapter_1.usage_key][0].usage_key: self.mock_subsection_grade(
+ self.subsections[self.chapter_1.usage_key][0],
earned_all=1.0,
possible_all=2.0,
earned_graded=2.0,
@@ -705,8 +705,8 @@ def test_gradebook_data_for_single_learner_override(self, login_method):
first_attempted=None,
override=mock_override,
),
- self.subsections[self.chapter_1.location][1].location: self.mock_subsection_grade(
- self.subsections[self.chapter_1.location][1],
+ self.subsections[self.chapter_1.usage_key][1].usage_key: self.mock_subsection_grade(
+ self.subsections[self.chapter_1.usage_key][1],
earned_all=1.0,
possible_all=2.0,
earned_graded=2.0,
@@ -714,8 +714,8 @@ def test_gradebook_data_for_single_learner_override(self, login_method):
first_attempted=None,
override=mock_override,
),
- self.subsections[self.chapter_2.location][0].location: self.mock_subsection_grade(
- self.subsections[self.chapter_2.location][0],
+ self.subsections[self.chapter_2.usage_key][0].usage_key: self.mock_subsection_grade(
+ self.subsections[self.chapter_2.usage_key][0],
earned_all=1.0,
possible_all=2.0,
earned_graded=2.0,
@@ -723,8 +723,8 @@ def test_gradebook_data_for_single_learner_override(self, login_method):
first_attempted=None,
override=mock_override,
),
- self.subsections[self.chapter_2.location][1].location: self.mock_subsection_grade(
- self.subsections[self.chapter_2.location][1],
+ self.subsections[self.chapter_2.usage_key][1].usage_key: self.mock_subsection_grade(
+ self.subsections[self.chapter_2.usage_key][1],
earned_all=1.0,
possible_all=2.0,
earned_graded=2.0,
@@ -1564,7 +1564,7 @@ def test_grades_frozen(self, login_method):
post_data = [
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'grade': {}, # doesn't matter what we put here.
}
]
@@ -1588,7 +1588,7 @@ def test_user_not_enrolled(self, login_method):
post_data = [
{
'user_id': unenrolled_student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'grade': {}, # doesn't matter what we put here.
}
]
@@ -1602,7 +1602,7 @@ def test_user_not_enrolled(self, login_method):
expected_data = [
{
'user_id': unenrolled_student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'success': False,
'reason': 'CourseEnrollment matching query does not exist.',
},
@@ -1621,7 +1621,7 @@ def test_user_does_not_exist(self, login_method):
post_data = [
{
'user_id': -123,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'grade': {}, # doesn't matter what we put here.
}
]
@@ -1635,7 +1635,7 @@ def test_user_does_not_exist(self, login_method):
expected_data = [
{
'user_id': -123,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'success': False,
'reason': 'User matching query does not exist.',
},
@@ -1725,7 +1725,7 @@ def test_override_is_created(self, login_method):
post_data = [
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'grade': {
'earned_all_override': 3,
'possible_all_override': 3,
@@ -1735,7 +1735,7 @@ def test_override_is_created(self, login_method):
},
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][1].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][1].usage_key),
'grade': {
'earned_all_override': 1,
'possible_all_override': 4,
@@ -1754,13 +1754,13 @@ def test_override_is_created(self, login_method):
expected_data = [
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'success': True,
'reason': None,
},
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][1].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][1].usage_key),
'success': True,
'reason': None,
},
@@ -1771,7 +1771,7 @@ def test_override_is_created(self, login_method):
second_post_data = [
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][1].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][1].usage_key),
'grade': {
'earned_all_override': 3,
'possible_all_override': 4,
@@ -1795,12 +1795,12 @@ def test_override_is_created(self, login_method):
# didn't mock out CourseGradeFactory.read() to return a non-zero score for anything).
for usage_key, expected_grades, expected_grade_overrides in (
(
- self.subsections[self.chapter_1.location][0].location,
+ self.subsections[self.chapter_1.usage_key][0].usage_key,
GradeFields(0, 0, 0, 0),
GradeFields(3, 3, 2, 2)
),
(
- self.subsections[self.chapter_1.location][1].location,
+ self.subsections[self.chapter_1.usage_key][1].usage_key,
GradeFields(0, 0, 0, 0),
GradeFields(3, 4, 3, 4)
),
@@ -1832,7 +1832,7 @@ def test_update_failing_grade(self):
post_data = [
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][0].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][0].usage_key),
'grade': {
'earned_all_override': 0,
'possible_all_override': 3,
@@ -1842,7 +1842,7 @@ def test_update_failing_grade(self):
},
{
'user_id': self.student.id,
- 'usage_id': str(self.subsections[self.chapter_1.location][1].location),
+ 'usage_id': str(self.subsections[self.chapter_1.usage_key][1].usage_key),
'grade': {
'earned_all_override': 0,
'possible_all_override': 4,
@@ -1881,7 +1881,7 @@ def setUpClass(cls):
cls.record_a = BlockRecord(locator=cls.locator_a, weight=1, raw_possible=10, graded=False)
cls.record_b = BlockRecord(locator=cls.locator_b, weight=1, raw_possible=10, graded=True)
cls.block_records = BlockRecordList([cls.record_a, cls.record_b], cls.course_key)
- cls.usage_key = cls.subsections[cls.chapter_1.location][0].location
+ cls.usage_key = cls.subsections[cls.chapter_1.usage_key][0].usage_key
cls.user = UserFactory.create()
cls.user_id = cls.user.id
cls.params = {
@@ -2226,7 +2226,7 @@ def test_with_unauthorized_user(self):
def test_get_override_for_unreleased_block(self):
self.login_course_staff()
unreleased_subsection = BlockFactory.create(
- parent_location=self.chapter_1.location,
+ parent_location=self.chapter_1.usage_key,
category='sequential',
graded=True,
start=datetime(2999, 1, 1, tzinfo=UTC), # arbitrary future date
@@ -2237,7 +2237,7 @@ def test_get_override_for_unreleased_block(self):
bs_api.update_course_in_cache(self.course_data.course_key)
resp = self.client.get(
- self.get_url(subsection_id=unreleased_subsection.location)
+ self.get_url(subsection_id=unreleased_subsection.usage_key)
)
expected_data = {
@@ -2252,7 +2252,7 @@ def test_get_override_for_unreleased_block(self):
'user_id': self.user_id,
'override': None,
'course_id': str(self.usage_key.course_key),
- 'subsection_id': str(unreleased_subsection.location),
+ 'subsection_id': str(unreleased_subsection.usage_key),
'history': []
}
assert expected_data == resp.data
diff --git a/lms/djangoapps/grades/rest_api/v1/tests/test_grading_policy_view.py b/lms/djangoapps/grades/rest_api/v1/tests/test_grading_policy_view.py
index 0b90f7f6ed97..0ace74488fe2 100644
--- a/lms/djangoapps/grades/rest_api/v1/tests/test_grading_policy_view.py
+++ b/lms/djangoapps/grades/rest_api/v1/tests/test_grading_policy_view.py
@@ -44,7 +44,7 @@ def create_course_data(cls): # lint-amnesty, pylint: disable=missing-function-d
with cls.store.bulk_operations(cls.course.id, emit_signals=False):
cls.sequential = BlockFactory.create(
category="sequential",
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="Lesson 1",
format="Homework",
graded=True
@@ -55,7 +55,7 @@ def create_course_data(cls): # lint-amnesty, pylint: disable=missing-function-d
problem_xml = factory.build_xml(**args)
cls.problem = BlockFactory.create(
category="problem",
- parent_location=cls.sequential.location,
+ parent_location=cls.sequential.usage_key,
display_name="Problem 1",
format="Homework",
data=problem_xml,
@@ -63,13 +63,13 @@ def create_course_data(cls): # lint-amnesty, pylint: disable=missing-function-d
cls.video = BlockFactory.create(
category="video",
- parent_location=cls.sequential.location,
+ parent_location=cls.sequential.usage_key,
display_name="Video 1",
)
cls.html = BlockFactory.create(
category="html",
- parent_location=cls.sequential.location,
+ parent_location=cls.sequential.usage_key,
display_name="HTML 1",
)
diff --git a/lms/djangoapps/grades/rest_api/v1/tests/test_views.py b/lms/djangoapps/grades/rest_api/v1/tests/test_views.py
index b5a849c1ea05..2c70ae3340b2 100644
--- a/lms/djangoapps/grades/rest_api/v1/tests/test_views.py
+++ b/lms/djangoapps/grades/rest_api/v1/tests/test_views.py
@@ -582,13 +582,13 @@ def basic_setup(self, late=False, reset=False, showanswer=False):
# set up a simple course with four problems
homework = self.add_graded_section_to_course('homework', late=late, reset=reset, showanswer=showanswer)
vertical = BlockFactory.create(
- parent_location=homework.location,
+ parent_location=homework.usage_key,
category='vertical',
display_name='Subsection 1',
)
- self.add_dropdown_to_section(vertical.location, 'p1', 1)
- self.add_dropdown_to_section(vertical.location, 'p2', 1)
- self.add_dropdown_to_section(vertical.location, 'p3', 1)
+ self.add_dropdown_to_section(vertical.usage_key, 'p1', 1)
+ self.add_dropdown_to_section(vertical.usage_key, 'p2', 1)
+ self.add_dropdown_to_section(vertical.usage_key, 'p3', 1)
self.refresh_course()
diff --git a/lms/djangoapps/grades/rest_api/v1/views.py b/lms/djangoapps/grades/rest_api/v1/views.py
index b6835fd61ec4..457dfb15612e 100644
--- a/lms/djangoapps/grades/rest_api/v1/views.py
+++ b/lms/djangoapps/grades/rest_api/v1/views.py
@@ -517,7 +517,7 @@ def _get_problem_data(course_enrollment: CourseEnrollment, block):
'data': block.data
}
csm = StudentModule.objects.filter(
- module_state_key=block.location,
+ module_state_key=block.usage_key,
student=course_enrollment.user,
course_id=course_enrollment.course_id
)
diff --git a/lms/djangoapps/grades/scores.py b/lms/djangoapps/grades/scores.py
index 7a89a88c794b..412171bfc20c 100644
--- a/lms/djangoapps/grades/scores.py
+++ b/lms/djangoapps/grades/scores.py
@@ -162,7 +162,7 @@ def _get_score_from_submissions(submissions_scores, block):
Returns the score values from the submissions API if found.
"""
if submissions_scores:
- submission_value = submissions_scores.get(str(block.location))
+ submission_value = submissions_scores.get(str(block.usage_key))
if submission_value:
first_attempted = submission_value['created_at']
weighted_earned = submission_value['points_earned']
@@ -187,7 +187,7 @@ def _get_score_from_csm(csm_scores, block, weight):
# attempted. Even though the CSM persistence for this value is now
# superfluous, for backward compatibility, we continue to use its value for
# raw_possible, giving it precedence over the one in the grades data model.
- score = csm_scores.get(block.location)
+ score = csm_scores.get(block.usage_key)
has_valid_score = score and score.total is not None
if has_valid_score:
if score.correct is not None:
diff --git a/lms/djangoapps/grades/signals/handlers.py b/lms/djangoapps/grades/signals/handlers.py
index 81768ed521dc..020bffd46d40 100644
--- a/lms/djangoapps/grades/signals/handlers.py
+++ b/lms/djangoapps/grades/signals/handlers.py
@@ -154,7 +154,7 @@ def score_published_handler(sender, block, user, raw_earned, raw_possible, only_
"""
update_score = True
if only_if_higher:
- previous_score = get_score(user.id, block.location)
+ previous_score = get_score(user.id, block.usage_key)
if previous_score is not None:
prev_raw_earned, prev_raw_possible = (previous_score.grade, previous_score.max_grade)
@@ -164,13 +164,13 @@ def score_published_handler(sender, block, user, raw_earned, raw_possible, only_
log.warning(
"Grades: Rescore is not higher than previous: "
"user: {}, block: {}, previous: {}/{}, new: {}/{} ".format(
- user, block.location, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
+ user, block.usage_key, prev_raw_earned, prev_raw_possible, raw_earned, raw_possible,
)
)
if update_score:
# Set the problem score in CSM.
- score_modified_time = set_score(user.id, block.location, raw_earned, raw_possible)
+ score_modified_time = set_score(user.id, block.usage_key, raw_earned, raw_possible)
# Set the problem score on the xblock.
if isinstance(block, ScorableXBlockMixin):
@@ -183,8 +183,8 @@ def score_published_handler(sender, block, user, raw_earned, raw_possible, only_
raw_possible=raw_possible,
weight=getattr(block, 'weight', None),
user_id=user.id,
- course_id=str(block.location.course_key),
- usage_id=str(block.location),
+ course_id=str(block.usage_key.course_key),
+ usage_id=str(block.usage_key),
only_if_higher=only_if_higher,
modified=score_modified_time,
score_db_table=ScoreDatabaseTableEnum.courseware_student_module,
diff --git a/lms/djangoapps/grades/subsection_grade.py b/lms/djangoapps/grades/subsection_grade.py
index 5c6eff18f078..79157cb520eb 100644
--- a/lms/djangoapps/grades/subsection_grade.py
+++ b/lms/djangoapps/grades/subsection_grade.py
@@ -24,7 +24,7 @@ class SubsectionGradeBase(metaclass=ABCMeta):
"""
def __init__(self, subsection):
- self.location = subsection.location
+ self.usage_key = subsection.usage_key
self.display_name = block_metadata_utils.display_name_with_default(subsection)
self.url_name = subsection.usage_key.block_id
@@ -138,7 +138,7 @@ def problem_scores(self):
locations = OrderedDict() # dict of problem locations to ProblemScore
for block_key in self.course_data.structure.post_order_traversal(
filter_func=possibly_scored,
- start_node=self.location,
+ start_node=self.usage_key,
):
block = self.course_data.structure[block_key]
if getattr(block, 'has_score', False):
@@ -270,7 +270,7 @@ def __init__(self, subsection, course_structure, submissions_scores, csm_scores)
self.problem_scores = OrderedDict()
for block_key in course_structure.post_order_traversal(
filter_func=possibly_scored,
- start_node=subsection.location,
+ start_node=subsection.usage_key,
):
problem_score = self._compute_block_score(block_key, course_structure, submissions_scores, csm_scores)
if problem_score:
@@ -336,7 +336,7 @@ def _persisted_model_params(self, student):
"""
return dict(
user_id=student.id,
- usage_key=self.location,
+ usage_key=self.usage_key,
course_version=self.course_version,
subtree_edited_timestamp=self.subtree_edited_timestamp,
earned_all=self.all_total.earned,
diff --git a/lms/djangoapps/grades/subsection_grade_factory.py b/lms/djangoapps/grades/subsection_grade_factory.py
index 7e6fea6c0995..e7ad9cb87625 100644
--- a/lms/djangoapps/grades/subsection_grade_factory.py
+++ b/lms/djangoapps/grades/subsection_grade_factory.py
@@ -43,7 +43,7 @@ def create(self, subsection, read_only=False, force_calculate=False):
grade currently exists.
"""
self._log_event(
- log.debug, f"create, read_only: {read_only}, subsection: {subsection.location}", subsection,
+ log.debug, f"create, read_only: {read_only}, subsection: {subsection.usage_key}", subsection,
)
subsection_grade = self._get_bulk_cached_grade(subsection)
@@ -55,10 +55,10 @@ def create(self, subsection, read_only=False, force_calculate=False):
subsection, self.course_data.structure, self._submissions_scores, self._csm_scores,
)
if read_only:
- self._unsaved_subsection_grades[subsection_grade.location] = subsection_grade
+ self._unsaved_subsection_grades[subsection_grade.usage_key] = subsection_grade
else:
grade_model = subsection_grade.update_or_create_model(self.student)
- self._update_saved_subsection_grade(subsection.location, grade_model)
+ self._update_saved_subsection_grade(subsection.usage_key, grade_model)
return subsection_grade
def bulk_create_unsaved(self):
@@ -74,7 +74,7 @@ def update(self, subsection, only_if_higher=None, score_deleted=False, force_upd
"""
Updates the SubsectionGrade object for the student and subsection.
"""
- self._log_event(log.debug, f"update, subsection: {subsection.location}", subsection)
+ self._log_event(log.debug, f"update, subsection: {subsection.usage_key}", subsection)
calculated_grade = CreateSubsectionGrade(
subsection, self.course_data.structure, self._submissions_scores, self._csm_scores,
@@ -83,7 +83,7 @@ def update(self, subsection, only_if_higher=None, score_deleted=False, force_upd
if persist_grade:
if only_if_higher:
try:
- grade_model = PersistentSubsectionGrade.read_grade(self.student.id, subsection.location)
+ grade_model = PersistentSubsectionGrade.read_grade(self.student.id, subsection.usage_key)
except PersistentSubsectionGrade.DoesNotExist:
pass
else:
@@ -102,14 +102,14 @@ def update(self, subsection, only_if_higher=None, score_deleted=False, force_upd
score_deleted,
force_update_subsections
)
- self._update_saved_subsection_grade(subsection.location, grade_model)
+ self._update_saved_subsection_grade(subsection.usage_key, grade_model)
if settings.FEATURES.get('ENABLE_COURSE_ASSESSMENT_GRADE_CHANGE_SIGNAL'):
COURSE_ASSESSMENT_GRADE_CHANGED.send(
sender=self,
course_id=self.course_data.course_key,
user=self.student,
- subsection_id=calculated_grade.location,
+ subsection_id=calculated_grade.usage_key,
subsection_grade=calculated_grade.graded_total.earned
)
@@ -141,7 +141,7 @@ def _get_bulk_cached_grade(self, subsection):
Returns None if not found.
"""
saved_subsection_grades = self._get_bulk_cached_subsection_grades()
- grade = saved_subsection_grades.get(subsection.location)
+ grade = saved_subsection_grades.get(subsection.usage_key)
if grade:
return ReadSubsectionGrade(subsection, grade, self)
diff --git a/lms/djangoapps/grades/tests/base.py b/lms/djangoapps/grades/tests/base.py
index 03641900e1c3..0690739422c0 100644
--- a/lms/djangoapps/grades/tests/base.py
+++ b/lms/djangoapps/grades/tests/base.py
@@ -74,7 +74,7 @@ def setUpClass(cls):
category='chapter',
display_name='Test Chapter 2'
)
- cls.chapter_2.children.append(cls.sequence.location)
+ cls.chapter_2.children.append(cls.sequence.usage_key)
cls.store.update_item(cls.chapter_2, UserFactory().id)
def setUp(self):
@@ -83,7 +83,7 @@ def setUp(self):
self.request = get_mock_request(UserFactory())
self.client.login(username=self.request.user.username, password="test")
self._set_grading_policy()
- self.course_structure = get_course_blocks(self.request.user, self.course.location)
+ self.course_structure = get_course_blocks(self.request.user, self.course.usage_key)
self.course_data = CourseData(self.request.user, structure=self.course_structure)
self.subsection_grade_factory = SubsectionGradeFactory(self.request.user, self.course, self.course_structure)
CourseEnrollment.enroll(self.request.user, self.course.id)
diff --git a/lms/djangoapps/grades/tests/integration/test_access.py b/lms/djangoapps/grades/tests/integration/test_access.py
index 43323728af87..2393c4684a93 100644
--- a/lms/djangoapps/grades/tests/integration/test_access.py
+++ b/lms/djangoapps/grades/tests/integration/test_access.py
@@ -88,7 +88,7 @@ def test_subsection_access_changed(self):
self.submit_question_answer('p2', {'2_1': 'choice_choice_2'})
# check initial subsection grade
- course_structure = get_course_blocks(self.request.user, self.course.location)
+ course_structure = get_course_blocks(self.request.user, self.course.usage_key)
subsection_grade_factory = SubsectionGradeFactory(self.request.user, self.course, course_structure)
grade = subsection_grade_factory.create(self.sequence, read_only=True)
assert grade.graded_total.earned == 4.0
@@ -96,14 +96,14 @@ def test_subsection_access_changed(self):
# set a block in the subsection to be visible to staff only
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
- problem_2 = self.store.get_item(self.problem_2.location)
+ problem_2 = self.store.get_item(self.problem_2.usage_key)
problem_2.visible_to_staff_only = True
self.store.update_item(problem_2, self.instructor.id)
- self.store.publish(self.course.location, self.instructor.id)
- course_structure = get_course_blocks(self.student, self.course.location)
+ self.store.publish(self.course.usage_key, self.instructor.id)
+ course_structure = get_course_blocks(self.student, self.course.usage_key)
# ensure that problem_2 is not accessible for the student
- assert problem_2.location not in course_structure
+ assert problem_2.usage_key not in course_structure
# make sure we can still get the subsection grade
subsection_grade_factory = SubsectionGradeFactory(self.student, self.course, course_structure)
diff --git a/lms/djangoapps/grades/tests/integration/test_events.py b/lms/djangoapps/grades/tests/integration/test_events.py
index 679d84895e8d..cf869cfd0e46 100644
--- a/lms/djangoapps/grades/tests/integration/test_events.py
+++ b/lms/djangoapps/grades/tests/integration/test_events.py
@@ -94,7 +94,7 @@ def test_submit_answer(self, events_tracker):
'event_transaction_id': event_transaction_id,
'event_transaction_type': events.PROBLEM_SUBMITTED_EVENT_TYPE,
'course_id': str(self.course.id),
- 'problem_id': str(self.problem.location),
+ 'problem_id': str(self.problem.usage_key),
'weighted_earned': 2.0,
'weighted_possible': 2.0,
},
@@ -126,7 +126,7 @@ def test_delete_student_state(self, emit_signals):
reset_student_attempts(
self.course.id,
self.student,
- self.problem.location,
+ self.problem.usage_key,
self.instructor,
delete_module=True,
emit_signals_and_events=emit_signals
@@ -144,7 +144,7 @@ def test_delete_student_state(self, emit_signals):
{
'user_id': str(self.student.id),
'course_id': str(self.course.id),
- 'problem_id': str(self.problem.location),
+ 'problem_id': str(self.problem.usage_key),
'instructor_id': str(self.instructor.id),
'event_transaction_id': event_transaction_id,
'event_transaction_type': events.STATE_DELETED_EVENT_TYPE,
@@ -189,12 +189,12 @@ def test_rescoring_events(self):
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id):
self.problem.data = new_problem_xml
self.store.update_item(self.problem, self.instructor.id)
- self.store.publish(self.problem.location, self.instructor.id)
+ self.store.publish(self.problem.usage_key, self.instructor.id)
with patch('lms.djangoapps.grades.events.tracker') as events_tracker:
submit_rescore_problem_for_student(
request=get_mock_request(self.instructor),
- usage_key=self.problem.location,
+ usage_key=self.problem.usage_key,
student=self.student,
only_if_higher=False
)
@@ -216,7 +216,7 @@ def test_rescoring_events(self):
{
'course_id': str(self.course.id),
'user_id': str(self.student.id),
- 'problem_id': str(self.problem.location),
+ 'problem_id': str(self.problem.usage_key),
'new_weighted_earned': 2,
'new_weighted_possible': 2,
'only_if_higher': False,
diff --git a/lms/djangoapps/grades/tests/integration/test_problems.py b/lms/djangoapps/grades/tests/integration/test_problems.py
index 92a9f3696a43..38a1a3d85337 100644
--- a/lms/djangoapps/grades/tests/integration/test_problems.py
+++ b/lms/djangoapps/grades/tests/integration/test_problems.py
@@ -52,7 +52,7 @@ def setUp(self):
self.client.login(username=self.student.username, password=self.TEST_PASSWORD)
self.addCleanup(set_current_request, None)
self.request = get_mock_request(self.student)
- self.course_structure = get_course_blocks(self.student, self.course.location)
+ self.course_structure = get_course_blocks(self.student, self.course.usage_key)
@classmethod
def load_scoreable_course(cls):
@@ -192,7 +192,7 @@ def _get_score(self):
"""
self.submit_question_answer('problem', {'2_1': 'Correct'})
- course_structure = get_course_blocks(self.request.user, self.course.location)
+ course_structure = get_course_blocks(self.request.user, self.course.usage_key)
subsection_factory = SubsectionGradeFactory(
self.request.user,
course_structure=course_structure,
@@ -291,9 +291,9 @@ def _verify_grades(self, raw_earned, raw_possible, weight, expected_score):
for problem in self.problems:
problem.weight = weight
self.store.update_item(problem, self.user.id)
- self.store.publish(self.course.location, self.user.id)
+ self.store.publish(self.course.usage_key, self.user.id)
- course_structure = get_course_blocks(self.request.user, self.course.location)
+ course_structure = get_course_blocks(self.request.user, self.course.usage_key)
# answer all problems
for problem in self.problems:
@@ -306,7 +306,7 @@ def _verify_grades(self, raw_earned, raw_possible, weight, expected_score):
# verify all problem grades
for problem in self.problems:
- problem_score = subsection_grade.problem_scores[problem.location]
+ problem_score = subsection_grade.problem_scores[problem.usage_key]
assert isinstance(expected_score.first_attempted, type(problem_score.first_attempted))
expected_score.first_attempted = problem_score.first_attempted
assert problem_score == expected_score
diff --git a/lms/djangoapps/grades/tests/test_api.py b/lms/djangoapps/grades/tests/test_api.py
index e42e9ea56f6d..1f6068936950 100644
--- a/lms/djangoapps/grades/tests/test_api.py
+++ b/lms/djangoapps/grades/tests/test_api.py
@@ -49,7 +49,7 @@ def setUp(self):
self.grade = PersistentSubsectionGrade.update_or_create_grade(
user_id=self.user.id,
course_id=self.course.id,
- usage_key=self.subsection.location,
+ usage_key=self.subsection.usage_key,
first_attempted=None,
visible_blocks=[],
earned_all=6.0,
@@ -67,7 +67,7 @@ def test_override_subsection_grade(self, earned_graded):
api.override_subsection_grade(
self.user.id,
self.course.id,
- self.subsection.location,
+ self.subsection.usage_key,
overrider=self.overriding_user,
earned_graded=earned_graded,
comment='Test Override Comment',
@@ -75,7 +75,7 @@ def test_override_subsection_grade(self, earned_graded):
override_obj = api.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
assert override_obj is not None
assert override_obj.earned_graded_override == earned_graded
@@ -89,7 +89,7 @@ def test_override_subsection_grade(self, earned_graded):
api.override_subsection_grade(
self.user.id,
self.course.id,
- self.subsection.location,
+ self.subsection.usage_key,
overrider=self.overriding_user,
earned_graded=earned_graded,
comment='Test Override Comment 2',
@@ -97,7 +97,7 @@ def test_override_subsection_grade(self, earned_graded):
override_obj = api.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
assert override_obj is not None
@@ -135,7 +135,7 @@ def setUp(self):
self.grade = PersistentSubsectionGrade.update_or_create_grade(
user_id=self.user.id,
course_id=self.course.id,
- usage_key=self.subsection.location,
+ usage_key=self.subsection.usage_key,
first_attempted=None,
visible_blocks=[],
earned_all=6.0,
@@ -161,7 +161,7 @@ def test_clear_user_course_grades(self):
api.override_subsection_grade(
self.user.id,
self.course.id,
- self.subsection.location,
+ self.subsection.usage_key,
overrider=self.overriding_user,
earned_graded=0.0,
comment='Test Override Comment',
@@ -169,7 +169,7 @@ def test_clear_user_course_grades(self):
override_obj = api.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
course_grade = PersistentCourseGrade.read(self.user.id, self.course.id)
self.assertIsNotNone(course_grade)
@@ -184,7 +184,7 @@ def test_clear_user_course_grades(self):
api.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
def _create_and_get_user_grades(self, user_id):
@@ -192,7 +192,7 @@ def _create_and_get_user_grades(self, user_id):
api.override_subsection_grade(
user_id,
self.course.id,
- self.subsection.location,
+ self.subsection.usage_key,
overrider=self.overriding_user,
earned_graded=0.0,
comment='Test Override Comment',
@@ -200,7 +200,7 @@ def _create_and_get_user_grades(self, user_id):
return api.get_subsection_grade_override(
user_id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
def test_clear_other_user_course_grades(self):
@@ -226,7 +226,7 @@ def test_clear_other_user_course_grades(self):
after_clear_override_obj = api.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
after_clear_user_course_grade = PersistentCourseGrade.read(self.user.id, self.course.id)
with self.assertRaises(PersistentCourseGrade.DoesNotExist):
diff --git a/lms/djangoapps/grades/tests/test_course_data.py b/lms/djangoapps/grades/tests/test_course_data.py
index d71858312171..992e3e6782e8 100644
--- a/lms/djangoapps/grades/tests/test_course_data.py
+++ b/lms/djangoapps/grades/tests/test_course_data.py
@@ -29,14 +29,14 @@ def setUp(self):
self.user = UserFactory.create()
self.collected_structure = get_course_in_cache(self.course.id)
self.one_true_structure = get_course_blocks(
- self.user, self.course.location, collected_block_structure=self.collected_structure,
+ self.user, self.course.usage_key, collected_block_structure=self.collected_structure,
)
self.expected_results = {
'course': self.course,
'collected_block_structure': self.collected_structure,
'structure': self.one_true_structure,
'course_key': self.course.id,
- 'location': self.course.location,
+ 'location': self.course.usage_key,
}
@patch('lms.djangoapps.grades.course_data.get_course_blocks')
@@ -56,7 +56,7 @@ def test_fill_course_data(self, mock_get_blocks):
expected = self.expected_results[arg]
actual = getattr(course_data, arg)
if arg == 'course':
- assert expected.location == actual.location
+ assert expected.usage_key == actual.usage_key
else:
assert expected == actual
@@ -74,7 +74,7 @@ def test_properties(self):
]:
course_data = CourseData(self.user, **kwargs)
assert course_data.course_key == self.course.id
- assert course_data.location == self.course.location
+ assert course_data.usage_key == self.course.usage_key
assert course_data.structure.root_block_usage_key == self.one_true_structure.root_block_usage_key
assert course_data.course.id == self.course.id
assert course_data.version == self.course.course_version
@@ -88,7 +88,7 @@ def test_no_data(self):
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
def test_full_string(self):
- empty_structure = get_course_blocks(self.user, self.course.location)
+ empty_structure = get_course_blocks(self.user, self.course.usage_key)
assert not empty_structure
# full_string retrieves value from collected_structure when structure is empty.
diff --git a/lms/djangoapps/grades/tests/test_course_grade.py b/lms/djangoapps/grades/tests/test_course_grade.py
index a4afd554facb..491e47fca290 100644
--- a/lms/djangoapps/grades/tests/test_course_grade.py
+++ b/lms/djangoapps/grades/tests/test_course_grade.py
@@ -106,46 +106,46 @@ def tearDownClass(cls):
set_current_request(None)
def test_score_chapter(self):
- earned, possible = self.course_grade.score_for_block(self.a.location)
+ earned, possible = self.course_grade.score_for_block(self.a.usage_key)
assert earned == 9
assert possible == 24
def test_score_section_many_leaves(self):
- earned, possible = self.course_grade.score_for_block(self.b.location)
+ earned, possible = self.course_grade.score_for_block(self.b.usage_key)
assert earned == 6
assert possible == 14
def test_score_section_one_leaf(self):
- earned, possible = self.course_grade.score_for_block(self.c.location)
+ earned, possible = self.course_grade.score_for_block(self.c.usage_key)
assert earned == 3
assert possible == 10
def test_score_vertical_two_leaves(self):
- earned, possible = self.course_grade.score_for_block(self.d.location)
+ earned, possible = self.course_grade.score_for_block(self.d.usage_key)
assert earned == 5
assert possible == 10
def test_score_vertical_two_leaves_one_unscored(self):
- earned, possible = self.course_grade.score_for_block(self.e.location)
+ earned, possible = self.course_grade.score_for_block(self.e.usage_key)
assert earned == 1
assert possible == 4
def test_score_vertical_no_score(self):
- earned, possible = self.course_grade.score_for_block(self.f.location)
+ earned, possible = self.course_grade.score_for_block(self.f.usage_key)
assert earned == 0
assert possible == 0
def test_score_vertical_one_leaf(self):
- earned, possible = self.course_grade.score_for_block(self.g.location)
+ earned, possible = self.course_grade.score_for_block(self.g.usage_key)
assert earned == 3
assert possible == 10
def test_score_leaf(self):
- earned, possible = self.course_grade.score_for_block(self.h.location)
+ earned, possible = self.course_grade.score_for_block(self.h.usage_key)
assert earned == 2
assert possible == 5
def test_score_leaf_no_score(self):
- earned, possible = self.course_grade.score_for_block(self.m.location)
+ earned, possible = self.course_grade.score_for_block(self.m.usage_key)
assert earned == 0
assert possible == 0
diff --git a/lms/djangoapps/grades/tests/test_course_grade_factory.py b/lms/djangoapps/grades/tests/test_course_grade_factory.py
index b6865d225fde..387a4d4080aa 100644
--- a/lms/djangoapps/grades/tests/test_course_grade_factory.py
+++ b/lms/djangoapps/grades/tests/test_course_grade_factory.py
@@ -62,7 +62,7 @@ def _assert_grade_values(course_grade, expected_pass, expected_percent):
assert course_grade.percent == expected_percent
def _assert_section_order(course_grade):
- sections = course_grade.chapter_grades[self.chapter.location]['sections']
+ sections = course_grade.chapter_grades[self.chapter.usage_key]['sections']
assert [section.display_name for section in sections] == [
self.sequence.display_name,
self.sequence2.display_name
@@ -131,7 +131,7 @@ def test_subsection_grade(self):
with mock_get_score(1, 2):
grade_factory.update(self.request.user, self.course, force_update_subsections=True)
course_grade = grade_factory.read(self.request.user, course_structure=self.course_structure)
- subsection_grade = course_grade.subsection_grade(self.sequence.location)
+ subsection_grade = course_grade.subsection_grade(self.sequence.usage_key)
assert subsection_grade.percent_graded == 0.5
def test_subsection_type_graders(self):
@@ -141,12 +141,12 @@ def test_subsection_type_graders(self):
assert graders['NoCredit'].min_count == 0
def test_create_zero_subs_grade_for_nonzero_course_grade(self):
- subsection = self.course_structure[self.sequence.location]
+ subsection = self.course_structure[self.sequence.usage_key]
with mock_get_score(1, 2):
self.subsection_grade_factory.update(subsection)
course_grade = CourseGradeFactory().update(self.request.user, self.course)
- subsection1_grade = course_grade.subsection_grades[self.sequence.location]
- subsection2_grade = course_grade.subsection_grades[self.sequence2.location]
+ subsection1_grade = course_grade.subsection_grades[self.sequence.usage_key]
+ subsection2_grade = course_grade.subsection_grades[self.sequence2.usage_key]
assert isinstance(subsection1_grade, ReadSubsectionGrade)
assert isinstance(subsection2_grade, ZeroSubsectionGrade)
@@ -160,7 +160,7 @@ def test_iter_force_update(self, force_update):
def test_course_grade_summary(self):
with mock_get_score(1, 2):
- self.subsection_grade_factory.update(self.course_structure[self.sequence.location])
+ self.subsection_grade_factory.update(self.course_structure[self.sequence.usage_key])
course_grade = CourseGradeFactory().update(self.request.user, self.course)
subsection_grades = list(course_grade.subsection_grades.values())
@@ -189,14 +189,14 @@ def test_course_grade_summary(self):
'detail': 'Homework 1 - Test Sequential X with an & Ampersand - 50.00% (1/2)',
'label': 'HW 01',
'percent': 0.5,
- 'sequential_id': str(subsection_grades[0].location),
+ 'sequential_id': str(subsection_grades[0].usage_key),
},
{
'category': 'Homework',
'detail': 'Homework 2 - Test Sequential A - 0.00% (0/1)',
'label': 'HW 02',
'percent': 0.0,
- 'sequential_id': str(subsection_grades[1].location),
+ 'sequential_id': str(subsection_grades[1].usage_key),
},
{
'category': 'Homework',
diff --git a/lms/djangoapps/grades/tests/test_score_render.py b/lms/djangoapps/grades/tests/test_score_render.py
index 6664459a95f6..3ce03dec88ae 100644
--- a/lms/djangoapps/grades/tests/test_score_render.py
+++ b/lms/djangoapps/grades/tests/test_score_render.py
@@ -80,7 +80,7 @@ def test_load_xblock_for_external_grader(self, mock_field_data_cache, mock_modul
# Call the function
result = load_xblock_for_external_grader(
- self.anonymous_user_id, str(self.course.id), str(self.problem.location), self.course
+ self.anonymous_user_id, str(self.course.id), str(self.problem.usage_key), self.course
)
# Assertions
@@ -103,7 +103,7 @@ def test_load_xblock_for_external_grader_missing_block(self, mock_anon_user, moc
# Test that Http404 is raised
with self.assertRaises(Http404):
load_xblock_for_external_grader(
- self.anonymous_user_id, str(self.course.id), str(self.problem.location), self.course
+ self.anonymous_user_id, str(self.course.id), str(self.problem.usage_key), self.course
)
@patch("lms.djangoapps.grades.score_render.prepare_runtime_for_user")
@@ -142,7 +142,7 @@ def test_handle_external_grader_score_json_string(self, mock_load_xblock, mock_m
score_msg='{"score": 10, "feedback": "Great job!"}',
course_id=str(self.course.id),
user_id=self.anonymous_user_id,
- module_id=str(self.problem.location),
+ module_id=str(self.problem.usage_key),
submission_id="sub_123",
queue_key="key_456",
queue_name="test_queue",
@@ -188,7 +188,7 @@ def test_handle_external_grader_score_plain_text(self, mock_load_xblock, mock_mo
score_msg=plain_text,
course_id=str(self.course.id),
user_id=self.anonymous_user_id,
- module_id=str(self.problem.location),
+ module_id=str(self.problem.usage_key),
submission_id="sub_123",
queue_key="key_456",
queue_name="test_queue",
@@ -220,7 +220,7 @@ def test_handle_external_grader_score_exception(self, mock_load_xblock, mock_mod
score_msg='{"score": 10}',
course_id=str(self.course.id),
user_id=self.anonymous_user_id,
- module_id=str(self.problem.location),
+ module_id=str(self.problem.usage_key),
submission_id="sub_123",
queue_key="key_456",
queue_name="test_queue",
@@ -250,9 +250,9 @@ def test_load_xblock_for_external_grader_none_instance(
# Test that Http404 is raised
with self.assertRaises(Http404) as context:
- load_xblock_for_external_grader(self.anonymous_user_id, str(self.course.id), str(self.problem.location))
+ load_xblock_for_external_grader(self.anonymous_user_id, str(self.course.id), str(self.problem.usage_key))
- expected_msg = f"Could not bind XBlock instance for usage key: {str(self.problem.location)}"
+ expected_msg = f"Could not bind XBlock instance for usage key: {str(self.problem.usage_key)}"
self.assertEqual(str(context.exception), expected_msg)
# Verify that all mocks were called
@@ -297,7 +297,7 @@ def test_end_to_end_grading_flow(self, mock_modulestore): # pylint: disable=unu
score_msg='{"score": 1, "max_score": 1, "correct": true}',
course_id=str(self.course.id),
user_id=self.anonymous_user_id,
- module_id=str(self.problem.location),
+ module_id=str(self.problem.usage_key),
submission_id="sub_123",
queue_key="key_456",
queue_name="test_queue",
diff --git a/lms/djangoapps/grades/tests/test_scores.py b/lms/djangoapps/grades/tests/test_scores.py
index 53aa4801b463..c70ed4056698 100644
--- a/lms/djangoapps/grades/tests/test_scores.py
+++ b/lms/djangoapps/grades/tests/test_scores.py
@@ -97,7 +97,7 @@ def _create_submissions_scores(self, submission_value):
Creates a stub result from the submissions API for the given values.
"""
if submission_value.exists:
- return {str(self.location): submission_value._asdict()}
+ return {str(self.usage_key): submission_value._asdict()}
else:
return {}
@@ -108,7 +108,7 @@ def _create_csm_scores(self, csm_value):
if csm_value.exists:
stub_csm_record = namedtuple('stub_csm_record', 'correct, total, created')
return {
- self.location: stub_csm_record(
+ self.usage_key: stub_csm_record(
correct=csm_value.raw_earned,
total=csm_value.raw_possible,
created=csm_value.created
@@ -123,7 +123,7 @@ def _create_persisted_block(self, persisted_block_value):
"""
if persisted_block_value.exists:
return BlockRecord(
- self.location,
+ self.usage_key,
persisted_block_value.weight,
persisted_block_value.raw_possible,
persisted_block_value.graded,
@@ -135,7 +135,7 @@ def _create_block(self, content_block_value):
"""
Creates and returns a minimal BlockData object with the give values.
"""
- block = BlockData(self.location)
+ block = BlockData(self.usage_key)
block.display_name = self.display_name
block.weight = content_block_value.weight
@@ -289,7 +289,7 @@ def test_with_no_persisted_block(self, explicitly_graded_value):
@ddt.unpack
def test_with_persisted_block(self, persisted_block_value, block_value):
block = self._create_block(block_value)
- block_record = BlockRecord(block.location, 0, 0, persisted_block_value)
+ block_record = BlockRecord(block.usage_key, 0, 0, persisted_block_value)
assert scores._get_graded_from_block(block_record, block) == block_record.graded
@@ -306,7 +306,7 @@ def _create_block(self, raw_possible):
Creates and returns a minimal BlockData object with the give value
for raw_possible.
"""
- block = BlockData(self.location)
+ block = BlockData(self.usage_key)
block.transformer_data.get_or_create(GradesTransformer).max_score = raw_possible
return block
@@ -341,5 +341,5 @@ def test_with_no_persisted_block(self, block_r_possible, weight):
@ddt.unpack
def test_with_persisted_block(self, persisted_block_r_possible, block_r_possible, weight):
block = self._create_block(block_r_possible)
- block_record = BlockRecord(block.location, 0, persisted_block_r_possible, False)
+ block_record = BlockRecord(block.usage_key, 0, persisted_block_r_possible, False)
self._verify_score_result(block_record, block, weight, persisted_block_r_possible)
diff --git a/lms/djangoapps/grades/tests/test_services.py b/lms/djangoapps/grades/tests/test_services.py
index 07a77ff13f13..fc2313d3bd0a 100644
--- a/lms/djangoapps/grades/tests/test_services.py
+++ b/lms/djangoapps/grades/tests/test_services.py
@@ -52,7 +52,7 @@ def setUp(self):
self.grade = PersistentSubsectionGrade.update_or_create_grade(
user_id=self.user.id,
course_id=self.course.id,
- usage_key=self.subsection.location,
+ usage_key=self.subsection.usage_key,
first_attempted=None,
visible_blocks=[],
earned_all=6.0,
@@ -96,7 +96,7 @@ def test_get_subsection_grade(self):
self.assertDictEqual(self.subsection_grade_to_dict(self.service.get_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location
+ usage_key_or_id=self.subsection.usage_key
)), {
'earned_all': 6.0,
'earned_graded': 5.0
@@ -106,7 +106,7 @@ def test_get_subsection_grade(self):
self.assertDictEqual(self.subsection_grade_to_dict(self.service.get_subsection_grade(
user_id=self.user.id,
course_key_or_id=str(self.course.id),
- usage_key_or_id=str(self.subsection.location)
+ usage_key_or_id=str(self.subsection.usage_key)
)), {
'earned_all': 6.0,
'earned_graded': 5.0
@@ -118,7 +118,7 @@ def test_get_subsection_grade_override(self):
self.assertDictEqual(self.subsection_grade_override_to_dict(self.service.get_subsection_grade_override(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location
+ usage_key_or_id=self.subsection.usage_key
)), {
'earned_all_override': override.earned_all_override,
'earned_graded_override': override.earned_graded_override
@@ -135,7 +135,7 @@ def test_get_subsection_grade_override(self):
self.assertDictEqual(self.subsection_grade_override_to_dict(self.service.get_subsection_grade_override(
user_id=self.user.id,
course_key_or_id=str(self.course.id),
- usage_key_or_id=self.subsection.location
+ usage_key_or_id=self.subsection.usage_key
)), {
'earned_all_override': override.earned_all_override,
'earned_graded_override': override.earned_graded_override
@@ -163,7 +163,7 @@ def test_override_subsection_grade(self, override):
self.service.override_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location,
+ usage_key_or_id=self.subsection.usage_key,
earned_all=override['earned_all'],
earned_graded=override['earned_graded']
)
@@ -171,7 +171,7 @@ def test_override_subsection_grade(self, override):
override_obj = self.service.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection.location
+ self.subsection.usage_key
)
assert override_obj is not None
assert override_obj.earned_all_override == override['earned_all']
@@ -181,7 +181,7 @@ def test_override_subsection_grade(self, override):
sender=None,
user_id=self.user.id,
course_id=str(self.course.id),
- usage_id=str(self.subsection.location),
+ usage_id=str(self.subsection.usage_key),
only_if_higher=False,
modified=override_obj.modified,
score_deleted=False,
@@ -198,7 +198,7 @@ def test_override_subsection_grade_no_psg(self):
self.service.override_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection_without_grade.location,
+ usage_key_or_id=self.subsection_without_grade.usage_key,
earned_all=earned_all_override,
earned_graded=earned_graded_override
)
@@ -207,7 +207,7 @@ def test_override_subsection_grade_no_psg(self):
subsection_grade = self.service.get_subsection_grade(
self.user.id,
self.course.id,
- self.subsection_without_grade.location
+ self.subsection_without_grade.usage_key
)
assert subsection_grade is not None
assert 0 == subsection_grade.earned_all
@@ -217,7 +217,7 @@ def test_override_subsection_grade_no_psg(self):
override_obj = self.service.get_subsection_grade_override(
self.user.id,
self.course.id,
- self.subsection_without_grade.location
+ self.subsection_without_grade.usage_key
)
assert override_obj is not None
assert override_obj.earned_all_override == earned_all_override
@@ -227,7 +227,7 @@ def test_override_subsection_grade_no_psg(self):
sender=None,
user_id=self.user.id,
course_id=str(self.course.id),
- usage_id=str(self.subsection_without_grade.location),
+ usage_id=str(self.subsection_without_grade.usage_key),
only_if_higher=False,
modified=override_obj.modified,
score_deleted=False,
@@ -244,17 +244,17 @@ def test_undo_override_subsection_grade(self):
self.service.undo_override_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location,
+ usage_key_or_id=self.subsection.usage_key,
)
- override = self.service.get_subsection_grade_override(self.user.id, self.course.id, self.subsection.location)
+ override = self.service.get_subsection_grade_override(self.user.id, self.course.id, self.subsection.usage_key)
assert override is None
assert self.mock_signal.call_args == call(
sender=None,
user_id=self.user.id,
course_id=str(self.course.id),
- usage_id=str(self.subsection.location),
+ usage_id=str(self.subsection.usage_key),
only_if_higher=False,
modified=datetime.now().replace(tzinfo=pytz.UTC),
score_deleted=True,
@@ -274,11 +274,11 @@ def test_undo_override_subsection_grade_across_features(self):
self.service.undo_override_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location,
+ usage_key_or_id=self.subsection.usage_key,
feature=GradeOverrideFeatureEnum.proctoring,
)
- override = self.service.get_subsection_grade_override(self.user.id, self.course.id, self.subsection.location)
+ override = self.service.get_subsection_grade_override(self.user.id, self.course.id, self.subsection.usage_key)
assert override is not None
@freeze_time('2018-01-01')
@@ -293,7 +293,7 @@ def test_undo_override_subsection_grade_without_grade(self):
self.service.undo_override_subsection_grade(
user_id=self.user.id,
course_key_or_id=self.course.id,
- usage_key_or_id=self.subsection.location,
+ usage_key_or_id=self.subsection.usage_key,
)
except PersistentSubsectionGrade.DoesNotExist:
assert False, 'Exception raised unexpectedly'
diff --git a/lms/djangoapps/grades/tests/test_subsection_grade.py b/lms/djangoapps/grades/tests/test_subsection_grade.py
index 2398e7a71000..722ee1232d94 100644
--- a/lms/djangoapps/grades/tests/test_subsection_grade.py
+++ b/lms/djangoapps/grades/tests/test_subsection_grade.py
@@ -35,7 +35,7 @@ def test_create_and_read(self, mock_earned, mock_possible, expected_result):
# read from db, and ensure output matches input
saved_model = PersistentSubsectionGrade.read_grade(
user_id=self.request.user.id,
- usage_key=self.sequence.location,
+ usage_key=self.sequence.usage_key,
)
read_grade = ReadSubsectionGrade(
self.sequence,
diff --git a/lms/djangoapps/grades/tests/test_tasks.py b/lms/djangoapps/grades/tests/test_tasks.py
index 8adb98302f69..c41c0687ae4d 100644
--- a/lms/djangoapps/grades/tests/test_tasks.py
+++ b/lms/djangoapps/grades/tests/test_tasks.py
@@ -75,7 +75,7 @@ def set_up_course(self, create_multiple_subsections=False, course_end=None):
('user_id', self.user.id),
('anonymous_user_id', 5),
('course_id', str(self.course.id)),
- ('usage_id', str(self.problem.location)),
+ ('usage_id', str(self.problem.usage_key)),
('only_if_higher', None),
('modified', self.frozen_now_datetime),
('score_db_table', ScoreDatabaseTableEnum.courseware_student_module),
@@ -86,7 +86,7 @@ def set_up_course(self, create_multiple_subsections=False, course_end=None):
self.recalculate_subsection_grade_kwargs = OrderedDict([
('user_id', self.user.id),
('course_id', str(self.course.id)),
- ('usage_id', str(self.problem.location)),
+ ('usage_id', str(self.problem.usage_key)),
('anonymous_user_id', 5),
('only_if_higher', None),
('expected_modified_time', self.frozen_now_timestamp),
@@ -150,7 +150,7 @@ def test_block_structure_created_only_once(self):
self.set_up_course()
with patch(
'openedx.core.djangoapps.content.block_structure.factory.BlockStructureFactory.create_from_store',
- side_effect=BlockStructureNotFound(self.course.location),
+ side_effect=BlockStructureNotFound(self.course.usage_key),
) as mock_block_structure_create:
self._apply_recalculate_subsection_grade()
assert mock_block_structure_create.call_count == 1
@@ -196,7 +196,7 @@ def test_other_inaccessible_subsection(self, mock_subsection_signal):
# Update problem to have 2 additional sequential parents.
# So in total, 3 sequential parents, with one inaccessible.
for sequential in (accessible_seq, inaccessible_seq):
- sequential.children = [self.problem.location]
+ sequential.children = [self.problem.usage_key]
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id):
self.store.update_item(sequential, self.user.id)
@@ -205,12 +205,12 @@ def test_other_inaccessible_subsection(self, mock_subsection_signal):
self._apply_recalculate_subsection_grade()
assert mock_subsection_signal.call_count == 1
sequentials_signalled = {
- args[1]['subsection_grade'].location
+ args[1]['subsection_grade'].usage_key
for args in mock_subsection_signal.call_args_list
}
self.assertSetEqual(
sequentials_signalled,
- {self.sequential.location},
+ {self.sequential.usage_key},
)
@patch('lms.djangoapps.grades.signals.signals.SUBSECTION_SCORE_CHANGED.send')
@@ -248,7 +248,7 @@ def test_problem_block_with_restricted_access(self, mock_subsection_signal):
group_access={verified_partition.id: [verified_group.id]}
)
- self.recalculate_subsection_grade_kwargs['usage_id'] = str(restricted_problem.location)
+ self.recalculate_subsection_grade_kwargs['usage_id'] = str(restricted_problem.usage_key)
verified_partition.scheme.set_group_for_user(self.user, verified_partition, verified_group)
self._apply_recalculate_subsection_grade()
diff --git a/lms/djangoapps/grades/tests/test_transformer.py b/lms/djangoapps/grades/tests/test_transformer.py
index 7ef13e5b5b7c..f4d61dc9e485 100644
--- a/lms/djangoapps/grades/tests/test_transformer.py
+++ b/lms/djangoapps/grades/tests/test_transformer.py
@@ -207,21 +207,21 @@ def test_collect_containing_subsection(self):
'prob_BCb': {'sub_A', 'sub_B', 'sub_C'},
}
blocks = self.build_complicated_hypothetical_course()
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
for block_ref, expected_subsections in expected_subsections.items():
actual_subsections = block_structure.get_transformer_block_field(
- blocks[block_ref].location,
+ blocks[block_ref].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
'subsections',
)
- assert actual_subsections == {blocks[sub].location for sub in expected_subsections}
+ assert actual_subsections == {blocks[sub].usage_key for sub in expected_subsections}
def test_unscored_block_collection(self):
blocks = self.build_course_with_problems()
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_xblock_fields(
block_structure,
- blocks['course'].location,
+ blocks['course'].usage_key,
weight=None,
graded=False,
has_score=False,
@@ -230,7 +230,7 @@ def test_unscored_block_collection(self):
)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['course'].location,
+ blocks['course'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
max_score=None,
explicit_graded=None,
@@ -239,11 +239,11 @@ def test_unscored_block_collection(self):
def test_grades_collected_basic(self):
blocks = self.build_course_with_problems()
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_xblock_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
weight=self.problem_metadata['weight'],
graded=self.problem_metadata['graded'],
has_score=True,
@@ -252,7 +252,7 @@ def test_grades_collected_basic(self):
)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
max_score=0,
explicit_graded=True,
@@ -266,10 +266,10 @@ def test_graded_at_problem(self, graded):
if graded is not None:
problem_metadata['graded'] = graded
blocks = self.build_course_with_problems(metadata=problem_metadata)
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
explicit_graded=graded,
)
@@ -285,11 +285,11 @@ def test_collecting_staff_only_problem(self):
}
blocks = self.build_course_with_problems(metadata=problem_metadata)
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_xblock_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
weight=problem_metadata['weight'],
graded=problem_metadata['graded'],
has_score=True,
@@ -307,11 +307,11 @@ def test_max_score_collection(self):
'''
blocks = self.build_course_with_problems(data=problem_data)
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
max_score=1,
)
@@ -329,11 +329,11 @@ def test_max_score_for_multiresponse_problem(self):
'''
blocks = self.build_course_with_problems(problem_data)
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
max_score=2,
)
@@ -359,22 +359,22 @@ def test_max_score_for_invalid_dropdown_problem(self):
'''
blocks = self.build_course_with_problems(problem_data)
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
self.assert_collected_transformer_block_fields(
block_structure,
- blocks['problem'].location,
+ blocks['problem'].usage_key,
self.TRANSFORMER_CLASS_TO_TEST,
max_score=0,
)
def test_course_version_collected_in_split(self):
blocks = self.build_course_with_problems()
- block_structure = get_course_blocks(self.student, blocks['course'].location, self.transformers)
- assert block_structure.get_xblock_field(blocks['course'].location, 'course_version') is not None
+ block_structure = get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
+ assert block_structure.get_xblock_field(blocks['course'].usage_key, 'course_version') is not None
assert block_structure.get_xblock_field(
- blocks['problem'].location, 'course_version'
- ) == block_structure.get_xblock_field(blocks['course'].location, 'course_version')
+ blocks['problem'].usage_key, 'course_version'
+ ) == block_structure.get_xblock_field(blocks['course'].usage_key, 'course_version')
def test_grading_policy_collected(self):
# the calculated hash of the original and updated grading policies of the test course
@@ -384,7 +384,7 @@ def test_grading_policy_collected(self):
blocks = self.build_course_with_problems()
course_block = blocks['course']
self._validate_grading_policy_hash(
- course_block.location,
+ course_block.usage_key,
original_grading_policy_hash
)
@@ -397,14 +397,14 @@ def test_grading_policy_collected(self):
self._update_course_grading_policy(course_block, grading_policy_with_updates)
self._validate_grading_policy_hash(
- course_block.location,
+ course_block.usage_key,
updated_grading_policy_hash
)
# reset the grading policy and ensure the hash matches the original
self._update_course_grading_policy(course_block, original_grading_policy)
self._validate_grading_policy_hash(
- course_block.location,
+ course_block.usage_key,
original_grading_policy_hash
)
@@ -466,4 +466,4 @@ def test_modulestore_performance(self, store_type, max_mongo_calls, min_mongo_ca
bs_api.update_course_in_cache(blocks['course'].id)
clear_course_from_cache(blocks['course'].id)
with check_mongo_calls_range(max_mongo_calls, min_mongo_calls):
- get_course_blocks(self.student, blocks['course'].location, self.transformers)
+ get_course_blocks(self.student, blocks['course'].usage_key, self.transformers)
diff --git a/lms/djangoapps/grades/transformer.py b/lms/djangoapps/grades/transformer.py
index f322ea0162e5..0ff39fe71c84 100644
--- a/lms/djangoapps/grades/transformer.py
+++ b/lms/djangoapps/grades/transformer.py
@@ -150,9 +150,9 @@ def _collect_max_score(cls, block_structure, block):
`transformer_block_field` associated with the `GradesTransformer`.
"""
max_score = block.max_score()
- block_structure.set_transformer_block_field(block.location, cls, 'max_score', max_score)
+ block_structure.set_transformer_block_field(block.usage_key, cls, 'max_score', max_score)
if max_score is None:
- log.warning(f"GradesTransformer: max_score is None for {block.location}")
+ log.warning(f"GradesTransformer: max_score is None for {block.usage_key}")
@classmethod
def _collect_grading_policy_hash(cls, block_structure):
@@ -163,7 +163,7 @@ def _collect_grading_policy_hash(cls, block_structure):
course_location = block_structure.root_block_usage_key
course_block = block_structure.get_xblock(course_location)
block_structure.set_transformer_block_field(
- course_block.location,
+ course_block.usage_key,
cls,
"grading_policy_hash",
cls.grading_policy_hash(course_block),
diff --git a/lms/djangoapps/instructor/ora.py b/lms/djangoapps/instructor/ora.py
index 6198aa4c3b64..344332952f41 100644
--- a/lms/djangoapps/instructor/ora.py
+++ b/lms/djangoapps/instructor/ora.py
@@ -42,7 +42,7 @@ def get_open_response_assessment_list(course):
ora_grading_base_url = getattr(settings, 'ORA_GRADING_MICROFRONTEND_URL', None)
for block in openassessment_blocks:
- block_id = str(block.location)
+ block_id = str(block.usage_key)
parent_id = block.parent
# Cache parent lookups to avoid repeated modulestore calls
diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py
index 4d9f6f83b9e8..f20921929f97 100644
--- a/lms/djangoapps/instructor/tests/test_api.py
+++ b/lms/djangoapps/instructor/tests/test_api.py
@@ -402,7 +402,7 @@ def setUpClass(cls):
publish_item=True,
)
- cls.problem_urlname = str(cls.problem.location)
+ cls.problem_urlname = str(cls.problem.usage_key)
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=False)
@classmethod
@@ -418,7 +418,7 @@ def setUp(self):
_module = StudentModule.objects.create(
student=self.user,
course_id=self.course.id,
- module_state_key=self.problem.location,
+ module_state_key=self.problem.usage_key,
state=json.dumps({'attempts': 10}),
)
@@ -442,7 +442,7 @@ def setUp(self):
('get_students_who_may_enroll', {}),
('get_proctored_exam_results', {}),
('get_problem_responses', {}),
- ('instructor_api_v1:generate_problem_responses', {"problem_locations": [str(self.problem.location)]}),
+ ('instructor_api_v1:generate_problem_responses', {"problem_locations": [str(self.problem.usage_key)]}),
('export_ora2_data', {}),
('export_ora2_submission_files', {}),
('export_ora2_summary', {}),
@@ -3450,13 +3450,13 @@ def setUp(self):
ee_module_to_reset1 = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
- module_state_key=self.ee_problem_1.location,
+ module_state_key=self.ee_problem_1.usage_key,
state=json.dumps({'attempts': 10, 'done': True}),
)
ee_module_to_reset2 = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
- module_state_key=self.ee_problem_2.location,
+ module_state_key=self.ee_problem_2.usage_key,
state=json.dumps({'attempts': 10, 'done': True}),
)
self.ee_modules = [ee_module_to_reset1.module_state_key, ee_module_to_reset2.module_state_key]
@@ -4244,7 +4244,7 @@ def get_extended_due(course, unit, user):
Gets the overridden due date for the given user on the given unit. Returns
`None` if there is no override set.
"""
- location = str(unit.location)
+ location = str(unit.usage_key)
dates = get_overrides_for_user(course.id, user)
for override in dates:
if str(override['location']) == location:
@@ -4258,7 +4258,7 @@ def get_date_for_block(course, unit, user, use_cached=False):
Returns `None` if there is no date set.
Differs from edx-when's get_date_for_block only in that we skip the cache when `use_cached` is `False` (default).
"""
- return get_dates_for_course(course.id, user=user, use_cached=use_cached).get((unit.location, 'due'), None)
+ return get_dates_for_course(course.id, user=user, use_cached=use_cached).get((unit.usage_key, 'due'), None)
class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
@@ -4278,15 +4278,15 @@ def setUpClass(cls):
cls.week2 = BlockFactory.create(due=cls.due)
cls.week3 = BlockFactory.create() # No due date
cls.course.children = [
- str(cls.week1.location),
- str(cls.week2.location),
- str(cls.week3.location)
+ str(cls.week1.usage_key),
+ str(cls.week2.usage_key),
+ str(cls.week3.usage_key)
]
cls.homework = BlockFactory.create(
- parent_location=cls.week1.location,
+ parent_location=cls.week1.usage_key,
due=cls.due
)
- cls.week1.children = [str(cls.homework.location)]
+ cls.week1.children = [str(cls.homework.usage_key)]
def setUp(self):
"""
@@ -4299,46 +4299,46 @@ def setUp(self):
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week2.location).save()
+ module_state_key=self.week2.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week3.location).save()
+ module_state_key=self.week3.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
user2 = UserFactory.create()
StudentModule(
state='{}',
student_id=user2.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user2.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
user3 = UserFactory.create()
StudentModule(
state='{}',
student_id=user3.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user3.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
self.user1 = user1
self.user2 = user2
@@ -4353,7 +4353,7 @@ def test_change_due_date(self):
due_date = datetime.datetime(2013, 12, 30, tzinfo=UTC)
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 200, response.content
@@ -4366,7 +4366,7 @@ def test_change_due_date_with_reason(self):
due_date = datetime.datetime(2013, 12, 30, tzinfo=UTC)
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '12/30/2013 00:00',
'reason': 'Testing reason.' # this is optional field.
})
@@ -4380,7 +4380,7 @@ def test_reset_due_date_with_reason(self):
url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'reason': 'Testing reason.' # this is optional field.
})
assert response.status_code == 200
@@ -4390,7 +4390,7 @@ def test_change_to_invalid_due_date(self):
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '01/01/2009 00:00'
})
assert response.status_code == 400, response.content
@@ -4400,7 +4400,7 @@ def test_change_nonexistent_due_date(self):
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week3.location),
+ 'url': str(self.week3.usage_key),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 400, response.content
@@ -4410,7 +4410,7 @@ def test_change_to_invalid_username(self):
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': 'invalid_username',
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '12/30/2026 02:00'
})
assert response.status_code == 404, response.content
@@ -4420,7 +4420,7 @@ def test_change_to_invalid_due_date_format(self):
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '12/30/2kkk 00:00:00'
})
assert response.status_code == 400, response.content
@@ -4442,7 +4442,7 @@ def test_reset_date(self):
url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
})
assert response.status_code == 200, response.content
assert self.due == get_extended_due(self.course, self.week1, self.user1)
@@ -4452,19 +4452,19 @@ def test_reset_date_only_in_edx_when(self):
# Start with a unit that only has a date in edx-when
assert get_date_for_block(self.course, self.week3, self.user1) is None
original_due = datetime.datetime(2010, 4, 1, tzinfo=UTC)
- set_date_for_block(self.course.id, self.week3.location, 'due', original_due)
+ set_date_for_block(self.course.id, self.week3.usage_key, 'due', original_due)
assert get_date_for_block(self.course, self.week3, self.user1) == original_due
# set override, confirm it took
override = datetime.datetime(2010, 7, 1, tzinfo=UTC)
- set_date_for_block(self.course.id, self.week3.location, 'due', override, user=self.user1)
+ set_date_for_block(self.course.id, self.week3.usage_key, 'due', override, user=self.user1)
assert get_date_for_block(self.course, self.week3, self.user1) == override
# Now test that we noticed the edx-when date
url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week3.location),
+ 'url': str(self.week3.usage_key),
})
self.assertContains(response, 'Successfully reset due date for student')
# This operation regenerates the cache, so we can use cached results from edx-when.
@@ -4474,7 +4474,7 @@ def test_show_unit_extensions(self):
self.test_change_due_date()
url = reverse('show_unit_extensions',
kwargs={'course_id': str(self.course.id)})
- response = self.client.post(url, {'url': str(self.week1.location)})
+ response = self.client.post(url, {'url': str(self.week1.usage_key)})
assert response.status_code == 200, response.content
assert json.loads(response.content.decode('utf-8')) ==\
{'data': [{'Extended Due Date': '2013-12-30 00:00',
@@ -4512,15 +4512,15 @@ def setUpClass(cls):
cls.week2 = BlockFactory.create(due=cls.due)
cls.week3 = BlockFactory.create() # No due date
cls.course.children = [
- str(cls.week1.location),
- str(cls.week2.location),
- str(cls.week3.location)
+ str(cls.week1.usage_key),
+ str(cls.week2.usage_key),
+ str(cls.week3.usage_key)
]
cls.homework = BlockFactory.create(
- parent_location=cls.week1.location,
+ parent_location=cls.week1.usage_key,
due=cls.due
)
- cls.week1.children = [str(cls.homework.location)]
+ cls.week1.children = [str(cls.homework.usage_key)]
def setUp(self):
"""
@@ -4536,22 +4536,22 @@ def setUp(self):
state='{}',
student_id=self.user1.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=self.user1.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
StudentModule(
state='{}',
student_id=self.user2.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=self.user2.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
CourseEnrollmentFactory.create(user=self.user1, course_id=self.course.id)
CourseEnrollmentFactory.create(user=self.user2, course_id=self.course.id)
@@ -4565,7 +4565,7 @@ def test_change_due_date_v2_success(self):
due_date = datetime.datetime(2013, 12, 30, tzinfo=UTC)
response = self.client.post(url, json.dumps({
'email_or_username': self.user1.username,
- 'block_id': str(self.homework.location),
+ 'block_id': str(self.homework.usage_key),
'due_datetime': '12/30/2013 00:00',
'reason': 'Testing V2 API.'
}), content_type='application/json')
@@ -4582,7 +4582,7 @@ def test_change_due_date_v2_with_email(self):
due_date = datetime.datetime(2013, 12, 30, tzinfo=UTC)
response = self.client.post(url, json.dumps({
'email_or_username': self.user1.email,
- 'block_id': str(self.homework.location),
+ 'block_id': str(self.homework.usage_key),
'due_datetime': '12/30/2013 00:00',
'reason': 'Testing V2 API with email.'
}), content_type='application/json')
@@ -4598,7 +4598,7 @@ def test_change_due_date_v2_invalid_user(self):
url = reverse('instructor_api_v2:change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, json.dumps({
'email_or_username': 'nonexistent@example.com',
- 'block_id': str(self.homework.location),
+ 'block_id': str(self.homework.usage_key),
'due_datetime': '12/30/2013 00:00'
}), content_type='application/json')
@@ -4623,7 +4623,7 @@ def test_change_due_date_v2_invalid_date_format(self):
# V2 API accepts form data as well
response = self.client.post(url, {
'email_or_username': self.user1.username,
- 'block_id': self.homework.location,
+ 'block_id': self.homework.usage_key,
'due_datetime': 'invalid-date-format'
})
@@ -4647,7 +4647,7 @@ def test_change_due_date_v2_unenrolled_user(self):
# V2 API accepts form data
response = self.client.post(url, {
'email_or_username': unenrolled_user.username,
- 'block_id': self.homework.location,
+ 'block_id': self.homework.usage_key,
'due_datetime': '12/30/2013 00:00'
})
@@ -4659,7 +4659,7 @@ def test_change_due_date_v2_json_content_type(self):
# Send as form data instead of JSON
response = self.client.post(url, {
'email_or_username': self.user1.username,
- 'block_id': self.homework.location,
+ 'block_id': self.homework.usage_key,
'due_datetime': '12/30/2013 00:00'
})
@@ -4689,61 +4689,61 @@ def setUp(self):
self.week2 = BlockFactory.create(due=self.due)
self.week3 = BlockFactory.create() # No due date
self.course.children = [
- self.week1.location,
- self.week2.location,
- self.week3.location
+ self.week1.usage_key,
+ self.week2.usage_key,
+ self.week3.usage_key
]
self.homework = BlockFactory.create(
- parent_location=self.week1.location,
+ parent_location=self.week1.usage_key,
due=self.due
)
- self.week1.children = [self.homework.location]
+ self.week1.children = [self.homework.usage_key]
user1 = UserFactory.create()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week2.location).save()
+ module_state_key=self.week2.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.week3.location).save()
+ module_state_key=self.week3.usage_key).save()
StudentModule(
state='{}',
student_id=user1.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
user2 = UserFactory.create()
StudentModule(
state='{}',
student_id=user2.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user2.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
user3 = UserFactory.create()
StudentModule(
state='{}',
student_id=user3.id,
course_id=self.course.id,
- module_state_key=self.week1.location).save()
+ module_state_key=self.week1.usage_key).save()
StudentModule(
state='{}',
student_id=user3.id,
course_id=self.course.id,
- module_state_key=self.homework.location).save()
+ module_state_key=self.homework.usage_key).save()
self.user1 = user1
self.user2 = user2
@@ -4763,7 +4763,7 @@ def test_reset_extension_to_deleted_date(self):
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 200, response.content
@@ -4777,7 +4777,7 @@ def test_reset_extension_to_deleted_date(self):
url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': str(self.week1.location),
+ 'url': str(self.week1.usage_key),
})
assert response.status_code == 200, response.content
assert self.due == get_extended_due(self.course, self.week1, self.user1)
diff --git a/lms/djangoapps/instructor/tests/test_api_v2.py b/lms/djangoapps/instructor/tests/test_api_v2.py
index fd6505a2bf5d..08ab4b41655c 100644
--- a/lms/djangoapps/instructor/tests/test_api_v2.py
+++ b/lms/djangoapps/instructor/tests/test_api_v2.py
@@ -668,7 +668,7 @@ def setUpClass(cls):
category='problem',
display_name='Test Problem'
)
- cls.problem_location = str(cls.problem.location)
+ cls.problem_location = str(cls.problem.usage_key)
def setUp(self):
super().setUp()
@@ -1020,8 +1020,8 @@ def test_get_graded_subsections_with_mocked_units(self, mock_get_units):
# Mock a unit with due date
mock_unit = Mock()
mock_unit.display_name = 'Mocked Assignment'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@mock')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@mock')
mock_get_units.return_value = [mock_unit]
self.client.force_authenticate(user=self.instructor)
@@ -1042,8 +1042,8 @@ def test_get_graded_subsections_title_fallback(self, mock_get_units, mock_title_
"""
# Mock a unit without display_name
mock_unit = Mock()
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@fallback')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@fallback')
mock_get_units.return_value = [mock_unit]
mock_title_or_url.return_value = 'block-v1:Test+Course+2024+type@sequential+block@fallback'
@@ -1090,14 +1090,14 @@ def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
- cls.course_key = cls.course.location.course_key
+ cls.course_key = cls.course.usage_key.course_key
cls.ora_block = BlockFactory.create(
category="openassessment",
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="test",
)
- cls.ora_usage_key = str(cls.ora_block.location)
+ cls.ora_usage_key = str(cls.ora_block.usage_key)
cls.password = "password"
cls.staff = StaffFactory(course_key=cls.course_key, password=cls.password)
@@ -1157,7 +1157,7 @@ def test_get_assessment_list_includes_staff_ora_grading_url_for_non_team_assignm
mock_store = Mock()
mock_assessment_block = Mock(
- location=self.ora_block.location,
+ location=self.ora_block.usage_key,
parent=Mock(),
teams_enabled=False,
assessment_steps=["staff-assessment"],
@@ -1189,7 +1189,7 @@ def test_get_assessment_list_includes_staff_ora_grading_url_for_team_assignment(
mock_store = Mock()
mock_assessment_block = Mock(
- location=self.ora_block.location,
+ location=self.ora_block.usage_key,
parent=Mock(),
teams_enabled=True,
display_name="Team Assignment",
@@ -1254,7 +1254,7 @@ def test_pagination_of_assessments(self):
for i in range(15):
BlockFactory.create(
category="openassessment",
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name=f"test_{i}",
)
@@ -1274,7 +1274,7 @@ def test_no_assessments(self):
"""Test response when there are no ORA assessments."""
# Create a new course with no ORA blocks
empty_course = CourseFactory.create()
- empty_course_key = empty_course.location.course_key
+ empty_course_key = empty_course.usage_key.course_key
empty_staff = StaffFactory(course_key=empty_course_key, password="password")
# Log in as staff for the empty course
@@ -1338,7 +1338,7 @@ def test_get_ora_summary(self):
BlockFactory.create(
category="openassessment",
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name="test2",
)
@@ -1517,9 +1517,9 @@ def test_get_unit_extensions(self):
date3 = datetime(2024, 12, 31, 23, 59, 59, tzinfo=UTC)
items = [
- (self.subsection.location, {'due': date1}), # Homework 1
- (self.vertical.location, {'due': date2}), # Test Vertical (Should be ignored)
- (self.problem.location, {'due': date3}), # Test Problem (Should be ignored)
+ (self.subsection.usage_key, {'due': date1}), # Homework 1
+ (self.vertical.usage_key, {'due': date2}), # Test Vertical (Should be ignored)
+ (self.problem.usage_key, {'due': date3}), # Test Problem (Should be ignored)
]
set_dates_for_course(self.course_key, items)
@@ -1529,10 +1529,10 @@ def test_get_unit_extensions(self):
override3 = datetime(2025, 12, 31, 23, 59, 59, tzinfo=UTC)
# Single override per user
# Only return the top-level override per user, in this case the subsection level
- set_date_for_block(self.course_key, self.subsection.location, 'due', override1, user=self.student1)
- set_date_for_block(self.course_key, self.subsection.location, 'due', override2, user=self.student2)
+ set_date_for_block(self.course_key, self.subsection.usage_key, 'due', override1, user=self.student1)
+ set_date_for_block(self.course_key, self.subsection.usage_key, 'due', override2, user=self.student2)
# Multiple overrides per user
- set_date_for_block(self.course_key, self.subsection.location, 'due', override3, user=self.student2)
+ set_date_for_block(self.course_key, self.subsection.usage_key, 'due', override3, user=self.student2)
self.client.force_authenticate(user=self.staff)
response = self.client.get(self._get_url())
@@ -1577,8 +1577,8 @@ def test_filter_by_email_or_username(self, filter_value, is_username, mock_get_u
# Mock units with due dates
mock_unit = Mock()
mock_unit.display_name = 'Homework 1'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
mock_get_units.return_value = [mock_unit]
# Mock location for dictionary lookup
@@ -1620,8 +1620,8 @@ def test_filter_by_block_id(self, mock_get_units, mock_find_unit, mock_get_overr
# Mock unit
mock_unit = Mock()
mock_unit.display_name = 'Homework 1'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
mock_find_unit.return_value = mock_unit
mock_get_units.return_value = [mock_unit]
@@ -1629,7 +1629,7 @@ def test_filter_by_block_id(self, mock_get_units, mock_find_unit, mock_get_overr
# Mock block-specific overrides data (username, full_name, email, location, due_date)
extended_date = datetime(2025, 1, 15, 23, 59, 59, tzinfo=UTC)
mock_get_overrides_block.return_value = [
- ('student1', 'John Doe', extended_date, 'john@example.com', mock_unit.location),
+ ('student1', 'John Doe', extended_date, 'john@example.com', mock_unit.usage_key),
]
self.client.force_authenticate(user=self.instructor)
@@ -1678,16 +1678,16 @@ def test_combined_filters(self, mock_find_unit, mock_get_overrides_block):
# Mock unit
mock_unit = Mock()
mock_unit.display_name = 'Homework 1'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
mock_find_unit.return_value = mock_unit
# Mock block-specific overrides data
extended_date = datetime(2025, 1, 15, 23, 59, 59, tzinfo=UTC)
mock_get_overrides_block.return_value = [
- ('student1', 'John Doe', extended_date, 'john@example.com', mock_unit.location),
- ('student2', 'Jane Smith', extended_date, 'jane@example.com', mock_unit.location),
+ ('student1', 'John Doe', extended_date, 'john@example.com', mock_unit.usage_key),
+ ('student2', 'Jane Smith', extended_date, 'jane@example.com', mock_unit.usage_key),
]
self.client.force_authenticate(user=self.instructor)
@@ -1723,8 +1723,8 @@ def test_pagination_parameters(self, mock_get_units, mock_get_overrides):
# Mock units with due dates
mock_unit = Mock()
mock_unit.display_name = 'Homework 1'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
mock_get_units.return_value = [mock_unit]
# Mock location for dictionary lookup
@@ -1792,8 +1792,8 @@ def test_extension_data_structure(self, mock_title_or_url, mock_get_units, mock_
# Mock units with due dates
mock_unit = Mock()
mock_unit.display_name = 'Homework 1'
- mock_unit.location = Mock()
- mock_unit.location.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
+ mock_unit.usage_key = Mock()
+ mock_unit.usage_key.__str__ = Mock(return_value='block-v1:Test+Course+2024+type@sequential+block@hw1')
mock_get_units.return_value = [mock_unit]
mock_title_or_url.return_value = 'Homework 1'
diff --git a/lms/djangoapps/instructor/tests/test_enrollment.py b/lms/djangoapps/instructor/tests/test_enrollment.py
index d9615bf49b57..e56b2c48244f 100644
--- a/lms/djangoapps/instructor/tests/test_enrollment.py
+++ b/lms/djangoapps/instructor/tests/test_enrollment.py
@@ -379,7 +379,7 @@ def setUpClass(cls):
org='course',
run='id',
)
- cls.course_key = cls.course.location.course_key # lint-amnesty, pylint: disable=no-member
+ cls.course_key = cls.course.usage_key.course_key # lint-amnesty, pylint: disable=no-member
with cls.store.bulk_operations(cls.course.id, emit_signals=False): # lint-amnesty, pylint: disable=no-member
cls.chapter = BlockFactory.create(
category='chapter',
@@ -419,19 +419,19 @@ def setUp(self):
StudentModule.objects.create(
student=self.user,
course_id=self.course_key,
- module_state_key=self.parent.location,
+ module_state_key=self.parent.usage_key,
state=parent_state,
)
StudentModule.objects.create(
student=self.user,
course_id=self.course_key,
- module_state_key=self.child.location,
+ module_state_key=self.child.usage_key,
state=child_state,
)
StudentModule.objects.create(
student=self.user,
course_id=self.course_key,
- module_state_key=self.unrelated.location,
+ module_state_key=self.unrelated.usage_key,
state=unrelated_state,
)
@@ -554,25 +554,25 @@ def setup_team(self):
StudentModule.objects.create(
student=self.user,
course_id=self.course_key,
- module_state_key=self.team_enabled_ora.location,
+ module_state_key=self.team_enabled_ora.usage_key,
state=team_state,
)
StudentModule.objects.create(
student=self.teammate_a,
course_id=self.course_key,
- module_state_key=self.team_enabled_ora.location,
+ module_state_key=self.team_enabled_ora.usage_key,
state=team_state,
)
StudentModule.objects.create(
student=self.teammate_b,
course_id=self.course_key,
- module_state_key=self.team_enabled_ora.location,
+ module_state_key=self.team_enabled_ora.usage_key,
state=team_state,
)
def test_reset_team_attempts(self):
self.setup_team()
- team_ora_location = self.team_enabled_ora.location
+ team_ora_location = self.team_enabled_ora.usage_key
# All teammates should have a student module (except lazy_teammate)
assert self.get_student_module(self.user, team_ora_location) is not None
assert self.get_student_module(self.teammate_a, team_ora_location) is not None
@@ -600,7 +600,7 @@ def _assert_student_module(user):
@patch('lms.djangoapps.grades.signals.handlers.PROBLEM_WEIGHTED_SCORE_CHANGED.send')
def test_delete_team_attempts(self, _mock_signal):
self.setup_team()
- team_ora_location = self.team_enabled_ora.location
+ team_ora_location = self.team_enabled_ora.usage_key
# All teammates should have a student module (except lazy_teammate)
assert self.get_student_module(self.user, team_ora_location) is not None
assert self.get_student_module(self.teammate_a, team_ora_location) is not None
@@ -620,7 +620,7 @@ def test_delete_team_attempts(self, _mock_signal):
@patch('lms.djangoapps.grades.signals.handlers.PROBLEM_WEIGHTED_SCORE_CHANGED.send')
def test_delete_team_attempts_no_team_fallthrough(self, _mock_signal):
self.setup_team()
- team_ora_location = self.team_enabled_ora.location
+ team_ora_location = self.team_enabled_ora.usage_key
# Remove self.user from the team
CourseTeamMembership.objects.get(user=self.user, team=self.team).delete()
@@ -657,57 +657,57 @@ def get_state(self, location):
return self.get_student_module(self.user, location).state
def test_reset_student_attempts_children(self):
- parent_state = json.loads(self.get_state(self.parent.location))
+ parent_state = json.loads(self.get_state(self.parent.usage_key))
assert parent_state['attempts'] == 32
assert parent_state['otherstuff'] == 'alsorobots'
- child_state = json.loads(self.get_state(self.child.location))
+ child_state = json.loads(self.get_state(self.child.usage_key))
assert child_state['attempts'] == 10
assert child_state['whatever'] == 'things'
- unrelated_state = json.loads(self.get_state(self.unrelated.location))
+ unrelated_state = json.loads(self.get_state(self.unrelated.usage_key))
assert unrelated_state['attempts'] == 12
assert unrelated_state['brains'] == 'zombie'
- reset_student_attempts(self.course_key, self.user, self.parent.location, requesting_user=self.user)
+ reset_student_attempts(self.course_key, self.user, self.parent.usage_key, requesting_user=self.user)
- parent_state = json.loads(self.get_state(self.parent.location))
- assert json.loads(self.get_state(self.parent.location))['attempts'] == 0
+ parent_state = json.loads(self.get_state(self.parent.usage_key))
+ assert json.loads(self.get_state(self.parent.usage_key))['attempts'] == 0
assert parent_state['otherstuff'] == 'alsorobots'
- child_state = json.loads(self.get_state(self.child.location))
+ child_state = json.loads(self.get_state(self.child.usage_key))
assert child_state['attempts'] == 0
assert child_state['whatever'] == 'things'
- unrelated_state = json.loads(self.get_state(self.unrelated.location))
+ unrelated_state = json.loads(self.get_state(self.unrelated.usage_key))
assert unrelated_state['attempts'] == 12
assert unrelated_state['brains'] == 'zombie'
def test_delete_submission_scores_attempts_children(self):
- parent_state = json.loads(self.get_state(self.parent.location))
+ parent_state = json.loads(self.get_state(self.parent.usage_key))
assert parent_state['attempts'] == 32
assert parent_state['otherstuff'] == 'alsorobots'
- child_state = json.loads(self.get_state(self.child.location))
+ child_state = json.loads(self.get_state(self.child.usage_key))
assert child_state['attempts'] == 10
assert child_state['whatever'] == 'things'
- unrelated_state = json.loads(self.get_state(self.unrelated.location))
+ unrelated_state = json.loads(self.get_state(self.unrelated.usage_key))
assert unrelated_state['attempts'] == 12
assert unrelated_state['brains'] == 'zombie'
reset_student_attempts(
self.course_key,
self.user,
- self.parent.location,
+ self.parent.usage_key,
requesting_user=self.user,
delete_module=True,
)
- self.assertRaises(StudentModule.DoesNotExist, self.get_state, self.parent.location)
- self.assertRaises(StudentModule.DoesNotExist, self.get_state, self.child.location)
+ self.assertRaises(StudentModule.DoesNotExist, self.get_state, self.parent.usage_key)
+ self.assertRaises(StudentModule.DoesNotExist, self.get_state, self.child.usage_key)
- unrelated_state = json.loads(self.get_state(self.unrelated.location))
+ unrelated_state = json.loads(self.get_state(self.unrelated.usage_key))
assert unrelated_state['attempts'] == 12
assert unrelated_state['brains'] == 'zombie'
@@ -765,7 +765,7 @@ def _get_subsection_grade_and_verify(self, all_earned, all_possible, graded_earn
subsection_grade_factory = SubsectionGradeFactory(
self.user,
self.course,
- get_course_blocks(self.user, self.course.location)
+ get_course_blocks(self.user, self.course.usage_key)
)
grade = subsection_grade_factory.create(self.sequence)
assert grade.all_total.earned == all_earned
@@ -775,7 +775,7 @@ def _get_subsection_grade_and_verify(self, all_earned, all_possible, graded_earn
@patch('crum.get_current_request')
def test_delete_student_state(self, _crum_mock):
- problem_location = self.problem.location
+ problem_location = self.problem.usage_key
self._get_subsection_grade_and_verify(0, 1, 0, 1)
answer_problem(course=self.course, request=self.request, problem=self.problem, score=1, max_value=1)
self._get_subsection_grade_and_verify(1, 1, 1, 1)
diff --git a/lms/djangoapps/instructor/tests/test_reports_api_v2.py b/lms/djangoapps/instructor/tests/test_reports_api_v2.py
index e7904bcbfc08..3bf9ad480afe 100644
--- a/lms/djangoapps/instructor/tests/test_reports_api_v2.py
+++ b/lms/djangoapps/instructor/tests/test_reports_api_v2.py
@@ -387,11 +387,11 @@ def test_generate_problem_responses_with_location(self, mock_modulestore, mock_s
"""
# Mock a problem block instead of creating real ones
mock_problem = Mock()
- mock_problem.location = Mock()
+ mock_problem.usage_key = Mock()
mock_store = Mock()
mock_store.get_item.return_value = mock_problem
- mock_store.make_course_usage_key.return_value = self.course.location
+ mock_store.make_course_usage_key.return_value = self.course.usage_key
mock_modulestore.return_value = mock_store
mock_submit.return_value = None
diff --git a/lms/djangoapps/instructor/tests/test_services.py b/lms/djangoapps/instructor/tests/test_services.py
index 7080b58bba81..58d2858b4f68 100644
--- a/lms/djangoapps/instructor/tests/test_services.py
+++ b/lms/djangoapps/instructor/tests/test_services.py
@@ -46,7 +46,7 @@ def setUp(self):
self.module_to_reset = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
- module_state_key=self.problem.location,
+ module_state_key=self.problem.usage_key,
state=json.dumps({'attempts': 2}),
)
@@ -64,7 +64,7 @@ def test_reset_student_attempts_delete(self, mock_completion_task, _mock_signal)
self.service.delete_student_attempt(
self.student.username,
str(self.course.id),
- str(self.subsection.location),
+ str(self.subsection.usage_key),
requesting_user=self.student,
)
@@ -73,7 +73,7 @@ def test_reset_student_attempts_delete(self, mock_completion_task, _mock_signal)
module_state_key=self.module_to_reset.module_state_key).count() == 0
# Assert we send update completion with 0.0
- mock_completion_task.assert_called_once_with((self.student.username, str(self.subsection.location), 0.0))
+ mock_completion_task.assert_called_once_with((self.student.username, str(self.subsection.usage_key), 0.0))
def test_reset_bad_content_id(self):
"""
@@ -109,7 +109,7 @@ def test_reset_non_existing_attempt(self):
result = self.service.delete_student_attempt( # lint-amnesty, pylint: disable=assignment-from-none
self.student.username,
str(self.course.id),
- str(self.problem_2.location),
+ str(self.problem_2.usage_key),
requesting_user=self.student,
)
assert result is None
@@ -119,8 +119,8 @@ def test_complete_student_attempt_success(self, mock_completion_task):
"""
Assert update_exam_completion task is triggered
"""
- self.service.complete_student_attempt(self.student.username, str(self.subsection.location))
- mock_completion_task.assert_called_once_with((self.student.username, str(self.subsection.location), 1.0))
+ self.service.complete_student_attempt(self.student.username, str(self.subsection.usage_key))
+ mock_completion_task.assert_called_once_with((self.student.username, str(self.subsection.usage_key), 1.0))
def test_is_user_staff(self):
"""
diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
index 4c1a691f6018..76d46895777c 100644
--- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
+++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
@@ -34,17 +34,17 @@ def setUpClass(cls):
# Now give it some content
with cls.store.bulk_operations(cls.course.id, emit_signals=False):
chapter = BlockFactory.create(
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
category="sequential",
)
section = BlockFactory.create(
- parent_location=chapter.location,
+ parent_location=chapter.usage_key,
category="sequential",
metadata={'graded': True, 'format': 'Homework'}
)
cls.items = [
BlockFactory.create(
- parent_location=section.location,
+ parent_location=section.usage_key,
category="problem",
data=StringResponseXMLFactory().build_xml(answer='foo'),
metadata={'rerandomize': 'always'}
@@ -68,7 +68,7 @@ def setUp(self):
max_grade=1,
student=user,
course_id=self.course.id,
- module_state_key=item.location
+ module_state_key=item.usage_key
)
task_compute_all_grades_for_course.apply_async(kwargs={'course_key': str(self.course.id)})
diff --git a/lms/djangoapps/instructor/tests/test_tasks.py b/lms/djangoapps/instructor/tests/test_tasks.py
index 4c6f9016f4fa..d87868ba67df 100644
--- a/lms/djangoapps/instructor/tests/test_tasks.py
+++ b/lms/djangoapps/instructor/tests/test_tasks.py
@@ -48,7 +48,7 @@ def setUp(self):
self.module_to_reset = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
- module_state_key=self.problem.location,
+ module_state_key=self.problem.usage_key,
state=json.dumps({'attempts': 2}),
)
@@ -72,12 +72,12 @@ def test_update_completion_success(self, mock_submit):
BlockFactory.create(parent=unit, category='discussion')
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
- update_exam_completion_task(self.student.username, str(subsection.location), 1.0)
+ update_exam_completion_task(self.student.username, str(subsection.usage_key), 1.0)
# Only Completable leaf blocks should have completion published
assert mock_submit.call_count == 2
- mock_submit.assert_any_call(user=self.student, block_key=video.location, completion=1.0)
- mock_submit.assert_any_call(user=self.student, block_key=problem.location, completion=1.0)
+ mock_submit.assert_any_call(user=self.student, block_key=video.usage_key, completion=1.0)
+ mock_submit.assert_any_call(user=self.student, block_key=problem.usage_key, completion=1.0)
@mock.patch('completion.handlers.BlockCompletion.objects.submit_completion')
def test_update_completion_delete(self, mock_submit):
@@ -85,12 +85,12 @@ def test_update_completion_delete(self, mock_submit):
Test update completion with a value of 0.0
"""
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
- update_exam_completion_task(self.student.username, str(self.subsection.location), 0.0)
+ update_exam_completion_task(self.student.username, str(self.subsection.usage_key), 0.0)
# Assert we send completion == 0.0 for both problems
assert mock_submit.call_count == 2
- mock_submit.assert_any_call(user=self.student, block_key=self.problem.location, completion=0.0)
- mock_submit.assert_any_call(user=self.student, block_key=self.problem_2.location, completion=0.0)
+ mock_submit.assert_any_call(user=self.student, block_key=self.problem.usage_key, completion=0.0)
+ mock_submit.assert_any_call(user=self.student, block_key=self.problem_2.usage_key, completion=0.0)
@mock.patch('completion.handlers.BlockCompletion.objects.submit_completion')
def test_update_completion_split_test(self, mock_submit):
@@ -133,7 +133,7 @@ def test_update_completion_split_test(self, mock_submit):
BlockFactory.create(parent=cond1vert, category='html')
with override_waffle_switch(ENABLE_COMPLETION_TRACKING_SWITCH, True):
- update_exam_completion_task(self.student.username, str(subsection.location), 1.0)
+ update_exam_completion_task(self.student.username, str(subsection.usage_key), 1.0)
# Only the group the user was assigned to should have completion published.
# Either cond0vert's children or cond1vert's children
@@ -145,7 +145,7 @@ def test_update_completion_bad_user(self, mock_logger):
Assert a bad user raises error and returns None
"""
username = 'bad_user'
- block_id = str(self.problem.location)
+ block_id = str(self.problem.usage_key)
update_exam_completion_task(username, block_id, 1.0)
mock_logger.assert_called_once_with(
self.complete_error_prefix.format(user=username, content_id=block_id) + 'User does not exist!'
@@ -182,8 +182,8 @@ def test_update_completion_failed_module(self, mock_logger):
"""
username = self.student.username
with mock.patch('lms.djangoapps.instructor.tasks.get_block_for_descriptor', return_value=None):
- update_exam_completion_task(username, str(self.course.location), 1.0)
+ update_exam_completion_task(username, str(self.course.usage_key), 1.0)
mock_logger.assert_called_once_with(
- self.complete_error_prefix.format(user=username, content_id=self.course.location) +
+ self.complete_error_prefix.format(user=username, content_id=self.course.usage_key) +
'Block unable to be created from descriptor!'
)
diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py
index 243f2afec467..2d8dc0d0cdcc 100644
--- a/lms/djangoapps/instructor/tests/test_tools.py
+++ b/lms/djangoapps/instructor/tests/test_tools.py
@@ -113,15 +113,15 @@ def setUpClass(cls):
cls.homework = BlockFactory.create(parent=cls.week1)
# get updated course
- cls.course = cls.store.get_item(course.location)
+ cls.course = cls.store.get_item(course.usage_key)
def test_find_unit_success(self):
"""
Test finding a nested unit.
"""
- url = str(self.homework.location)
+ url = str(self.homework.usage_key)
found_unit = tools.find_unit(self.course, url)
- assert found_unit.location == self.homework.location
+ assert found_unit.usage_key == self.homework.usage_key
def test_find_unit_notfound(self):
"""
@@ -151,13 +151,13 @@ def setUp(self):
due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
set_dates_for_course(course.id, [
- (week1.location, {'due': due}),
- (week2.location, {'due': due}),
- (child.location, {'due': due}),
+ (week1.usage_key, {'due': due}),
+ (week2.usage_key, {'due': due}),
+ (child.usage_key, {'due': due}),
])
# get updated course
- self.course = self.store.get_item(course.location)
+ self.course = self.store.get_item(course.usage_key)
self.week1 = week1
self.week2 = week2
@@ -167,7 +167,7 @@ def urls(seq):
"""
URLs for sequence of nodes.
"""
- return sorted(str(i.location) for i in seq)
+ return sorted(str(i.usage_key) for i in seq)
assert urls(tools.get_units_with_due_date(self.course)) == urls((self.week1, self.week2))
@@ -189,7 +189,7 @@ def mock_location_text(self):
return 'test:hello'
unit = mock.Mock(display_name=None)
- unit.location.__str__ = mock_location_text
+ unit.usage_key.__str__ = mock_location_text
assert tools.title_or_url(unit) == 'test:hello'
@@ -224,9 +224,9 @@ def setUp(self):
user = UserFactory.create()
# get updated course
- self.course = self.store.get_item(course.location)
- self.week1 = self.store.get_item(week1.location)
- self.homework = self.store.get_item(homework.location)
+ self.course = self.store.get_item(course.usage_key)
+ self.week1 = self.store.get_item(week1.usage_key)
+ self.homework = self.store.get_item(homework.usage_key)
self.assignment = assignment
self.week2 = week2
self.week3 = week3
@@ -341,7 +341,7 @@ def setUp(self):
user1 = UserFactory.create()
user2 = UserFactory.create()
# get updated course
- self.course = self.store.get_item(course.location)
+ self.course = self.store.get_item(course.usage_key)
self.week1 = week1
self.homework = homework
self.week2 = week2
diff --git a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
index e48098b9ef80..008d124cf999 100644
--- a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
+++ b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
@@ -564,7 +564,7 @@ def test_open_response_assessment_page(self):
response = self.client.get(self.url)
self.assertNotContains(response, ora_section)
- BlockFactory.create(parent_location=self.course.location, category="openassessment")
+ BlockFactory.create(parent_location=self.course.usage_key, category="openassessment")
response = self.client.get(self.url)
self.assertContains(response, ora_section)
@@ -575,7 +575,7 @@ def test_open_response_assessment_page_orphan(self):
"""
# create non-orphaned openassessment block
BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="openassessment",
)
# create orphan
@@ -635,7 +635,7 @@ def test_spoc_gradebook_mongo_calls(self):
"""
# prepare course structure
course = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
category="course",
display_name="Test course",
)
@@ -685,7 +685,7 @@ def test_spoc_gradebook_mongo_calls(self):
max_grade=1,
student=j,
course_id=self.course.id,
- module_state_key=problem.location
+ module_state_key=problem.usage_key
)
# check MongoDB calls count
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index 09b91d362b28..286e15d95dc7 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -3176,9 +3176,9 @@ def _display_unit(unit):
"""
name = getattr(unit, 'display_name', None)
if name:
- return f'{name} ({str(unit.location)})'
+ return f'{name} ({str(unit.usage_key)})'
else:
- return str(unit.location)
+ return str(unit.usage_key)
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
@@ -3268,7 +3268,7 @@ def post(self, request, course_id):
version = getattr(course, 'course_version', None)
- original_due_date = get_date_for_block(course_id, unit.location, published_version=version)
+ original_due_date = get_date_for_block(course_id, unit.usage_key, published_version=version)
try:
set_due_date_extension(course, unit, student, None, request.user, reason=reason)
diff --git a/lms/djangoapps/instructor/views/api_v2.py b/lms/djangoapps/instructor/views/api_v2.py
index dd399dcb064a..6a566e7b89dd 100644
--- a/lms/djangoapps/instructor/views/api_v2.py
+++ b/lms/djangoapps/instructor/views/api_v2.py
@@ -374,7 +374,7 @@ def get(self, request, course_id):
formated_subsections = {"items": [
{
"display_name": title_or_url(unit),
- "subsection_id": str(unit.location)
+ "subsection_id": str(unit.usage_key)
} for unit in graded_subsections]}
return Response(formated_subsections, status=status.HTTP_200_OK)
@@ -496,13 +496,13 @@ def get_queryset(self):
block_id_filter = self.request.query_params.get("block_id")
units = get_units_with_due_date(course)
- units_dict = {str(u.location): u for u in units}
+ units_dict = {str(u.usage_key): u for u in units}
# Fetch and normalize overrides
if block_id_filter:
try:
unit = find_unit(course, block_id_filter)
- query_data = edx_when_api.get_overrides_for_block(course.id, unit.location)
+ query_data = edx_when_api.get_overrides_for_block(course.id, unit.usage_key)
unit_due_date_extensions = [
UnitDueDateExtension.from_block_tuple(row, unit)
for row in query_data
diff --git a/lms/djangoapps/instructor/views/gradebook_api.py b/lms/djangoapps/instructor/views/gradebook_api.py
index b4de0b73e627..c3aff591dd41 100644
--- a/lms/djangoapps/instructor/views/gradebook_api.py
+++ b/lms/djangoapps/instructor/views/gradebook_api.py
@@ -87,7 +87,7 @@ def get_grade_book_page(request, course, course_key):
# Apply limit on queryset only if total number of students are greater then MAX_STUDENTS_PER_PAGE_GRADE_BOOK.
enrolled_students = enrolled_students[offset: offset + MAX_STUDENTS_PER_PAGE_GRADE_BOOK]
- with modulestore().bulk_operations(course.location.course_key):
+ with modulestore().bulk_operations(course.usage_key.course_key):
student_info = [
{
'username': student.username,
diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py
index 2cc86c42464b..44df7c67769e 100644
--- a/lms/djangoapps/instructor/views/instructor_dashboard.py
+++ b/lms/djangoapps/instructor/views/instructor_dashboard.py
@@ -617,7 +617,7 @@ def _section_extensions(course):
section_data = {
'section_key': 'extensions',
'section_display_name': _('Extensions'),
- 'units_with_due_dates': [(title_or_url(unit), str(unit.location))
+ 'units_with_due_dates': [(title_or_url(unit), str(unit.usage_key))
for unit in get_units_with_due_date(course)],
'change_due_date_url': reverse('change_due_date', kwargs={'course_id': str(course.id)}),
'reset_due_date_url': reverse('reset_due_date', kwargs={'course_id': str(course.id)}),
@@ -770,7 +770,7 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
for block in openassessment_blocks:
block_parent_id = str(block.parent)
- result_item_id = str(block.location)
+ result_item_id = str(block.usage_key)
if block_parent_id not in parents:
parents[block_parent_id] = modulestore().get_item(block.parent)
assessment_name = _("Team") + " : " + block.display_name if block.teams_enabled else block.display_name
@@ -782,18 +782,18 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
'staff_assessment': 'staff-assessment' in block.assessment_steps,
'peer_assessment': 'peer-assessment' in block.assessment_steps,
'team_assignment': block.teams_enabled,
- 'url_base': reverse('xblock_view', args=[course.id, block.location, 'student_view']),
- 'url_grade_available_responses': reverse('xblock_view', args=[course.id, block.location,
+ 'url_base': reverse('xblock_view', args=[course.id, block.usage_key, 'student_view']),
+ 'url_grade_available_responses': reverse('xblock_view', args=[course.id, block.usage_key,
'grade_available_responses_view']),
'url_waiting_step_details': reverse(
'xblock_view',
- args=[course.id, block.location, 'waiting_step_details_view'],
+ args=[course.id, block.usage_key, 'waiting_step_details_view'],
),
})
openassessment_block = openassessment_blocks[0]
block, __ = get_block_by_usage_id(
- request, str(course_key), str(openassessment_block.location),
+ request, str(course_key), str(openassessment_block.usage_key),
disable_staff_debug_info=True, course=course
)
section_data = {
diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py
index 8b32e019db02..cd969206ddfc 100644
--- a/lms/djangoapps/instructor/views/tools.py
+++ b/lms/djangoapps/instructor/views/tools.py
@@ -102,7 +102,7 @@ def find(node, url):
"""
Find node in course tree for url.
"""
- if str(node.location) == url:
+ if str(node.usage_key) == url:
return node
for child in node.get_children():
found = find(child, url)
@@ -137,7 +137,7 @@ def visit(node):
`units` if it does. Otherwise recurses into children to search for
nodes with due dates.
"""
- if (node.location, 'due') in course_dates:
+ if (node.usage_key, 'due') in course_dates:
units.append(node)
else:
for child in node.get_children():
@@ -154,7 +154,7 @@ def title_or_url(node):
"""
title = getattr(node, 'display_name', None)
if not title:
- title = str(node.location)
+ title = str(node.usage_key)
return title
@@ -183,7 +183,7 @@ def visit(node):
`blocks_to_set` if it does. And recurses into children to search for
nodes with due dates.
"""
- if (node.location, 'due') in course_dates:
+ if (node.usage_key, 'due') in course_dates:
blocks_to_set.add(node)
for child in node.get_children():
visit(child)
@@ -193,14 +193,14 @@ def visit(node):
if due_date:
try:
api.set_date_for_block(
- course.id, block.location, 'due', due_date, user=student, reason=reason, actor=actor
+ course.id, block.usage_key, 'due', due_date, user=student, reason=reason, actor=actor
)
except api.MissingDateError as ex:
- raise DashboardError(_("Unit {0} has no due date to extend.").format(unit.location)) from ex
+ raise DashboardError(_("Unit {0} has no due date to extend.").format(unit.usage_key)) from ex
except api.InvalidDateError as ex:
raise DashboardError(_("An extended due date must be later than the original due date.")) from ex
else:
- api.set_date_for_block(course.id, block.location, 'due', None, user=student, reason=reason, actor=actor)
+ api.set_date_for_block(course.id, block.usage_key, 'due', None, user=student, reason=reason, actor=actor)
# edx-proctoring is checking cached course dates, so the overrides made above will not be enforced until the
# TieredCache is reloaded. This can lead to situations when a student's extension is revoked, but they can still
@@ -220,7 +220,7 @@ def dump_block_extensions(course, unit):
"""
header = [_("Username"), _("Full Name"), _("Extended Due Date")]
data = []
- for username, fullname, due_date, *unused in api.get_overrides_for_block(course.id, unit.location):
+ for username, fullname, due_date, *unused in api.get_overrides_for_block(course.id, unit.usage_key):
due_date = due_date.strftime('%Y-%m-%d %H:%M')
data.append(dict(list(zip(header, (username, fullname, due_date)))))
data.sort(key=operator.itemgetter(_("Username")))
@@ -240,7 +240,7 @@ def dump_student_extensions(course, student):
data = []
header = [_("Unit"), _("Extended Due Date")]
units = get_units_with_due_date(course)
- units = {u.location: u for u in units}
+ units = {u.usage_key: u for u in units}
query = api.get_overrides_for_user(course.id, student)
for override in query:
location = override['location'].replace(course_key=course.id)
diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py
index edbe6b4f2e80..9298b9b11ad7 100644
--- a/lms/djangoapps/instructor_task/tasks_helper/grades.py
+++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py
@@ -139,7 +139,7 @@ def graded_assignments(self):
subsection_index=subsection_index,
subsection_name=subsection.display_name,
)
- graded_subsections_map[subsection.location] = header_name
+ graded_subsections_map[subsection.usage_key] = header_name
average_header = f"{assignment_type_name}"
@@ -221,7 +221,7 @@ def graded_scorable_blocks_header(self):
subsection_index=subsection_index,
subsection_name=subsection_info['subsection_block'].display_name,
)
- scorable_blocks_map[scorable_block.location] = [header_name + " (Earned)",
+ scorable_blocks_map[scorable_block.usage_key] = [header_name + " (Earned)",
header_name + " (Possible)"]
return scorable_blocks_map
diff --git a/lms/djangoapps/instructor_task/tests/test_api.py b/lms/djangoapps/instructor_task/tests/test_api.py
index beeb9e1c4222..5327af460593 100644
--- a/lms/djangoapps/instructor_task/tests/test_api.py
+++ b/lms/djangoapps/instructor_task/tests/test_api.py
@@ -135,7 +135,7 @@ def test_submit_nonrescorable_modules(self):
# confirm that a rescore of an existent but unscorable module returns an exception
# (Note that it is easier to test a scoreable but non-rescorable module in test_tasks,
# where we are creating real modules.)
- problem_url = self.problem_section.location
+ problem_url = self.problem_section.usage_key
request = None
with pytest.raises(NotImplementedError):
submit_rescore_problem_for_student(request, problem_url, self.student)
diff --git a/lms/djangoapps/instructor_task/tests/test_base.py b/lms/djangoapps/instructor_task/tests/test_base.py
index 518862bb4242..266a7280994f 100644
--- a/lms/djangoapps/instructor_task/tests/test_base.py
+++ b/lms/djangoapps/instructor_task/tests/test_base.py
@@ -139,13 +139,13 @@ def add_course_content(self):
"""
# Add a chapter to the course
self.chapter = BlockFactory.create(
- parent_location=self.course.location,
+ parent_location=self.course.usage_key,
display_name=TEST_CHAPTER_NAME,
)
# add a sequence to the course to which the problems can be added
self.problem_section = BlockFactory.create(
- parent_location=self.chapter.location,
+ parent_location=self.chapter.usage_key,
category='sequential',
metadata={'graded': True, 'format': 'Homework'},
display_name=TEST_SECTION_NAME,
@@ -235,7 +235,7 @@ def define_option_problem(self, problem_url_name, parent=None, **kwargs):
factory = OptionResponseXMLFactory()
factory_args = self._option_problem_factory_args()
problem_xml = factory.build_xml(**factory_args)
- return BlockFactory.create(parent_location=parent.location,
+ return BlockFactory.create(parent_location=parent.usage_key,
parent=parent,
category="problem",
display_name=problem_url_name,
@@ -258,8 +258,8 @@ def get_student_module(self, username, block):
"""Get StudentModule object for test course, given the `username` and the problem's `block`."""
return StudentModule.objects.get(course_id=self.course.id,
student=User.objects.get(username=username),
- module_type=block.location.block_type,
- module_state_key=block.location,
+ module_type=block.usage_key.block_type,
+ module_state_key=block.usage_key,
)
def submit_student_answer(self, username, problem_url_name, responses):
diff --git a/lms/djangoapps/instructor_task/tests/test_integration.py b/lms/djangoapps/instructor_task/tests/test_integration.py
index bc3a229a0ad3..6974529bc41b 100644
--- a/lms/djangoapps/instructor_task/tests/test_integration.py
+++ b/lms/djangoapps/instructor_task/tests/test_integration.py
@@ -138,7 +138,7 @@ def check_state(self, user, block, expected_score, expected_max_score, expected_
expected_subsection_grade = expected_score
course_grade = CourseGradeFactory().read(user, self.course)
- grade = course_grade.graded_subsections_by_format()['Homework'][self.problem_section.location].graded_total
+ grade = course_grade.graded_subsections_by_format()['Homework'][self.problem_section.usage_key].graded_total
assert grade.earned == expected_subsection_grade
def submit_rescore_all_student_answers(self, instructor, problem_url_name, only_if_higher=False):
@@ -329,7 +329,7 @@ def define_code_response_problem(self, problem_url_name):
answer_display="answer",
grader_payload=grader_payload,
num_responses=2)
- BlockFactory.create(parent_location=self.problem_section.location,
+ BlockFactory.create(parent_location=self.problem_section.usage_key,
category="problem",
display_name=str(problem_url_name),
data=problem_xml)
@@ -377,16 +377,16 @@ def check_func(expect, answer_given):
InstructorTaskModuleTestCase.problem_location(problem_url_name)
)
block.data = problem_xml
- with self.module_store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, block.location.course_key): # lint-amnesty, pylint: disable=line-too-long
+ with self.module_store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, block.usage_key.course_key): # lint-amnesty, pylint: disable=line-too-long
self.module_store.update_item(block, self.user.id)
- self.module_store.publish(block.location, self.user.id)
+ self.module_store.publish(block.usage_key, self.user.id)
else:
# Use "per-student" rerandomization so that check-problem can be called more than once.
# Using "always" means we cannot check a problem twice, but we want to call once to get the
# correct answer, and call a second time with that answer to confirm it's graded as correct.
# Per-student rerandomization will at least generate different seeds for different users, so
# we get a little more test coverage.
- BlockFactory.create(parent_location=self.problem_section.location,
+ BlockFactory.create(parent_location=self.problem_section.usage_key,
category="problem",
display_name=str(problem_url_name),
data=problem_xml,
@@ -507,7 +507,7 @@ def test_reset_failure(self):
def test_reset_non_problem(self):
"""confirm that a non-problem can still be successfully reset"""
- location = self.problem_section.location
+ location = self.problem_section.usage_key
instructor_task = self.reset_problem_attempts('instructor', location)
instructor_task = InstructorTask.objects.get(id=instructor_task.id)
assert instructor_task.task_state == SUCCESS
@@ -571,7 +571,7 @@ def test_delete_failure(self):
def test_delete_non_problem(self):
"""confirm that a non-problem can still be successfully deleted"""
- location = self.problem_section.location
+ location = self.problem_section.usage_key
instructor_task = self.delete_problem_state('instructor', location)
instructor_task = InstructorTask.objects.get(id=instructor_task.id)
assert instructor_task.task_state == SUCCESS
diff --git a/lms/djangoapps/instructor_task/tests/test_tasks.py b/lms/djangoapps/instructor_task/tests/test_tasks.py
index fe5dca573e98..f7962525ae8e 100644
--- a/lms/djangoapps/instructor_task/tests/test_tasks.py
+++ b/lms/djangoapps/instructor_task/tests/test_tasks.py
@@ -53,7 +53,7 @@ def setUp(self):
super().setUp()
self.initialize_course()
self.instructor = self.create_instructor('instructor')
- self.location = self.problem_location(PROBLEM_URL_NAME)
+ self.usage_key = self.problem_location(PROBLEM_URL_NAME)
def _create_input_entry(
self, student_ident=None, use_problem_url=True, course_id=None, only_if_higher=False, score=None
@@ -62,7 +62,7 @@ def _create_input_entry(
task_id = str(uuid4())
task_input = {'only_if_higher': only_if_higher}
if use_problem_url:
- task_input['problem_url'] = self.location
+ task_input['problem_url'] = self.usage_key
if student_ident is not None:
task_input['student'] = student_ident
if score is not None:
@@ -155,7 +155,7 @@ def _create_students_with_state(self, num_students, state=None, grade=0, max_gra
for student in enrolled_students:
StudentModuleFactory.create(
course_id=self.course.id,
- module_state_key=self.location,
+ module_state_key=self.usage_key,
student=student,
grade=grade,
max_grade=max_grade,
@@ -181,7 +181,7 @@ def _assert_num_attempts(self, students, num_attempts):
for student in students:
module = StudentModule.objects.get(course_id=self.course.id,
student=student,
- module_state_key=self.location)
+ module_state_key=self.usage_key)
state = json.loads(module.state)
assert state['attempts'] == num_attempts
@@ -435,7 +435,7 @@ def test_rescoring_unrescorable(self):
output = json.loads(entry.task_output)
assert output['exception'] == 'ExceptionWithTraceback'
assert 'Specified module {} of type {} does not support rescoring.'.format(
- self.location,
+ self.usage_key,
mock_instance.__class__,
) in output['message']
@@ -548,7 +548,7 @@ def _test_reset_with_student(self, use_email):
for student in students:
module = StudentModule.objects.get(course_id=self.course.id,
student=student,
- module_state_key=self.location)
+ module_state_key=self.usage_key)
state = json.loads(module.state)
assert state['attempts'] == initial_attempts
@@ -574,7 +574,7 @@ def _test_reset_with_student(self, use_email):
for index, student in enumerate(students):
module = StudentModule.objects.get(course_id=self.course.id,
student=student,
- module_state_key=self.location)
+ module_state_key=self.usage_key)
state = json.loads(module.state)
if index == 3:
assert state['attempts'] == 0
@@ -621,14 +621,14 @@ def test_delete_with_some_state(self):
for student in students:
StudentModule.objects.get(course_id=self.course.id,
student=student,
- module_state_key=self.location)
+ module_state_key=self.usage_key)
self._test_run_with_task(delete_problem_state, 'deleted', num_students)
# confirm that no state can be found anymore:
for student in students:
with pytest.raises(StudentModule.DoesNotExist):
StudentModule.objects.get(course_id=self.course.id,
student=student,
- module_state_key=self.location)
+ module_state_key=self.usage_key)
class TestCertificateGenerationnstructorTask(TestInstructorTasks):
diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
index 1447a66e9b87..ad128dd468c7 100644
--- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
+++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
@@ -523,7 +523,7 @@ def test_build_student_data_limit(self):
student_data, _ = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(self.course.location)],
+ usage_key_str_list=[str(self.course.usage_key)],
)
assert len(student_data) == 4
@@ -561,7 +561,7 @@ def _fake_get_course_blocks(_user, _usage_key, transformers=None, **_kwargs):
ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(problem.location)],
+ usage_key_str_list=[str(problem.usage_key)],
)
transformers = captured.get('transformers')
@@ -585,7 +585,7 @@ def test_build_student_data_for_block_without_generate_report_data(self, mock_li
student_data, student_data_keys_list = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(problem.location)],
+ usage_key_str_list=[str(problem.usage_key)],
)
assert len(student_data) == 1
assert_dict_contains_subset(
@@ -619,7 +619,7 @@ def test_build_student_data_for_block_with_mock_generate_report_data(self, mock_
student_data, student_data_keys_list = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(self.course.location)],
+ usage_key_str_list=[str(self.course.usage_key)],
)
assert len(student_data) == 2
assert_dict_contains_subset(
@@ -668,7 +668,7 @@ def test_build_student_data_for_block_with_ordered_generate_report_data(self, mo
student_data, student_data_keys_list = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(self.course.location)],
+ usage_key_str_list=[str(self.course.usage_key)],
)
assert len(student_data) == 2
assert_dict_contains_subset(
@@ -708,7 +708,7 @@ def test_build_student_data_for_block_with_real_generate_report_data(self):
student_data, student_data_keys_list = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(self.course.location)],
+ usage_key_str_list=[str(self.course.usage_key)],
)
assert len(student_data) == 1
assert_dict_contains_subset(
@@ -740,7 +740,7 @@ def test_build_student_data_for_multiple_problems(self):
student_data, _ = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(problem1.location), str(problem2.location)],
+ usage_key_str_list=[str(problem1.usage_key), str(problem2.usage_key)],
)
assert len(student_data) == 2
for idx in range(1, 3):
@@ -773,12 +773,12 @@ def test_build_student_data_with_filter(self, filters, filtered_count):
for idx in range(1, 6):
self.define_option_problem(f'Problem{idx}')
item = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
parent=self.problem_section,
display_name=f"Item{idx}",
data=''
)
- StudentModule.save_state(self.student, self.course.id, item.location, {})
+ StudentModule.save_state(self.student, self.course.id, item.usage_key, {})
for idx in range(1, 6):
self.submit_student_answer(self.student.username, f'Problem{idx}', ['Option 1'])
@@ -786,7 +786,7 @@ def test_build_student_data_with_filter(self, filters, filtered_count):
student_data, _ = ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(self.course.location)],
+ usage_key_str_list=[str(self.course.usage_key)],
filter_types=filters,
)
assert len(student_data) == filtered_count
@@ -807,14 +807,14 @@ def test_build_student_data_for_block_with_generate_report_data_not_implemented(
ProblemResponses._build_student_data(
user_id=self.instructor.id,
course_key=self.course.id,
- usage_key_str_list=[str(problem.location)],
+ usage_key_str_list=[str(problem.usage_key)],
)
mock_generate_report_data.assert_called_with(ANY, ANY)
mock_list_problem_responses.assert_called_with(self.course.id, ANY, ANY)
def test_success(self):
task_input = {
- 'problem_locations': str(self.course.location),
+ 'problem_locations': str(self.course.usage_key),
'user_id': self.instructor.id
}
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
@@ -917,7 +917,7 @@ def test_no_problems(self, use_tempfile, _):
@ddt.data(True, False)
def test_single_problem(self, use_tempfile, _):
vertical = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
category='vertical',
metadata={'graded': True},
display_name='Problem Vertical'
@@ -966,7 +966,7 @@ def test_single_problem_verified_student_only(self, use_tempfile, _):
):
student_verified = self.create_student('user_verified', mode='verified')
vertical = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
category='vertical',
metadata={'graded': True},
display_name='Problem Vertical'
@@ -991,7 +991,7 @@ def test_inactive_enrollment_included(self, use_tempfile, _):
"""
inactive_student = self.create_student('inactive-student', 'inactive@example.com', enrollment_active=False)
vertical = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
category='vertical',
metadata={'graded': True},
display_name='Problem Vertical'
@@ -1145,11 +1145,11 @@ def test_problem_grade_report_valid_columns_order(self):
problem_section_format = 'Homework %d' % i
problem_vertical_name = 'Problem Unit %d' % i
- chapter = BlockFactory.create(parent_location=self.course.location,
+ chapter = BlockFactory.create(parent_location=self.course.usage_key,
display_name=chapter_name)
# Add a sequence to the course to which the problems can be added
- problem_section = BlockFactory.create(parent_location=chapter.location,
+ problem_section = BlockFactory.create(parent_location=chapter.usage_key,
category='sequential',
metadata={'graded': True,
'format': problem_section_format},
@@ -1157,7 +1157,7 @@ def test_problem_grade_report_valid_columns_order(self):
# Create a vertical
problem_vertical = BlockFactory.create(
- parent_location=problem_section.location,
+ parent_location=problem_section.usage_key,
category='vertical',
display_name=problem_vertical_name
)
@@ -1191,7 +1191,7 @@ def setUp(self):
# construct cohorted problems to work on.
self.add_course_content()
vertical = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
category='vertical',
metadata={'graded': True},
display_name='Problem Vertical'
@@ -2014,7 +2014,7 @@ def test_course_grade_with_verified_student_only(self, _get_current_task):
student_1 = self.create_student('user_honor')
student_verified = self.create_student('user_verified', mode='verified')
vertical = BlockFactory.create(
- parent_location=self.problem_section.location,
+ parent_location=self.problem_section.usage_key,
category='vertical',
metadata={'graded': True},
display_name='Problem Vertical'
@@ -2082,7 +2082,7 @@ def create_problem(self, problem_display_name='test_problem', parent=None):
args = {'choices': [False, True, False]}
problem_xml = factory.build_xml(**args)
BlockFactory.create(
- parent_location=parent.location,
+ parent_location=parent.usage_key,
parent=parent,
category="problem",
display_name=problem_display_name,
diff --git a/lms/djangoapps/learner_home/test_views.py b/lms/djangoapps/learner_home/test_views.py
index 8722629371cc..3e0218999071 100644
--- a/lms/djangoapps/learner_home/test_views.py
+++ b/lms/djangoapps/learner_home/test_views.py
@@ -518,7 +518,7 @@ def setUpClass(cls):
# Set up a course
cls.course = CourseFactory.create()
- cls.course_key = cls.course.location.course_key
+ cls.course_key = cls.course.usage_key.course_key
# Set up a user
cls.username = "alan"
diff --git a/lms/djangoapps/lti_provider/outcomes.py b/lms/djangoapps/lti_provider/outcomes.py
index 3d5d39bfb3cd..883e24837f48 100644
--- a/lms/djangoapps/lti_provider/outcomes.py
+++ b/lms/djangoapps/lti_provider/outcomes.py
@@ -112,7 +112,7 @@ def get_assignments_for_problem(problem_block, user_id, course_key):
locations = []
current_block = problem_block
while current_block:
- locations.append(current_block.location)
+ locations.append(current_block.usage_key)
current_block = current_block.get_parent()
assignments = GradedAssignment.objects.filter(
user=user_id, course_key=course_key, usage_key__in=locations
diff --git a/lms/djangoapps/lti_provider/tests/test_outcomes.py b/lms/djangoapps/lti_provider/tests/test_outcomes.py
index 36840689a5f7..4dacc7c09d9f 100644
--- a/lms/djangoapps/lti_provider/tests/test_outcomes.py
+++ b/lms/djangoapps/lti_provider/tests/test_outcomes.py
@@ -338,7 +338,7 @@ def create_graded_assignment(self, desc, result_id, outcome_service):
assignment = GradedAssignment(
user=self.user,
course_key=self.course.id,
- usage_key=desc.location,
+ usage_key=desc.usage_key,
outcome_service=outcome_service,
lis_result_sourcedid=result_id,
version_number=0
diff --git a/lms/djangoapps/lti_provider/tests/test_tasks.py b/lms/djangoapps/lti_provider/tests/test_tasks.py
index 059aaeb9d6a4..ecb01bd202b7 100644
--- a/lms/djangoapps/lti_provider/tests/test_tasks.py
+++ b/lms/djangoapps/lti_provider/tests/test_tasks.py
@@ -98,7 +98,7 @@ class SendCompositeOutcomeTest(BaseOutcomeTest):
def setUp(self):
super().setUp()
self.block = MagicMock()
- self.block.location = BlockUsageLocator(
+ self.block.usage_key = BlockUsageLocator(
course_key=self.course_key,
block_type='problem',
block_id='problem',
diff --git a/lms/djangoapps/mobile_api/course_info/views.py b/lms/djangoapps/mobile_api/course_info/views.py
index fc818c646825..26fd0312d39c 100644
--- a/lms/djangoapps/mobile_api/course_info/views.py
+++ b/lms/djangoapps/mobile_api/course_info/views.py
@@ -395,7 +395,7 @@ def _extend_sequential_info_with_assignment_progress(
subsection_grades, section_breakdown = (
get_assignments_grades(requested_user, course_id, BLOCK_STRUCTURE_CACHE_TIMEOUT)
)
- grades_with_locations = {str(grade.location): grade for grade in subsection_grades}
+ grades_with_locations = {str(grade.usage_key): grade for grade in subsection_grades}
id_to_label = self._id_to_label(section_breakdown)
for block_id, block_info in blocks_info_data.items():
diff --git a/lms/djangoapps/mobile_api/tests/test_milestones.py b/lms/djangoapps/mobile_api/tests/test_milestones.py
index 2ecd7a0e3870..3160d550f7e6 100644
--- a/lms/djangoapps/mobile_api/tests/test_milestones.py
+++ b/lms/djangoapps/mobile_api/tests/test_milestones.py
@@ -118,7 +118,7 @@ def _add_entrance_exam(self):
add_entrance_exam_milestone(self.course, self.entrance_exam)
self.course.entrance_exam_minimum_score_pct = 0.50
- self.course.entrance_exam_id = str(self.entrance_exam.location)
+ self.course.entrance_exam_id = str(self.entrance_exam.usage_key)
self.store.update_item(self.course, self.user.id)
def _add_prerequisite_course(self):
diff --git a/lms/djangoapps/mobile_api/users/tests.py b/lms/djangoapps/mobile_api/users/tests.py
index 7c4b3e437de5..ed738e86bc7a 100644
--- a/lms/djangoapps/mobile_api/users/tests.py
+++ b/lms/djangoapps/mobile_api/users/tests.py
@@ -555,7 +555,7 @@ def test_student_have_progress_in_old_course_and_enroll_newest_course(self):
StudentModule.objects.create(
student=self.user,
course_id=old_course.id,
- module_state_key=old_course.location,
+ module_state_key=old_course.usage_key,
)
response = self.api_response(api_version=API_V4)
@@ -635,7 +635,7 @@ def test_do_progress_in_not_mobile_available_course(self):
StudentModule.objects.create(
student=self.user,
course_id=not_mobile_available.id,
- module_state_key=not_mobile_available.location,
+ module_state_key=not_mobile_available.usage_key,
)
response = self.api_response(api_version=API_V4)
@@ -710,15 +710,15 @@ def test_course_status_in_primary_obj_when_student_have_progress(
display_name="problem",
)
self.enroll(course.id)
- get_last_completed_block_mock.return_value = problem.location
+ get_last_completed_block_mock.return_value = problem.usage_key
expected_course_status = {
- 'last_visited_module_id': str(subsection.location),
+ 'last_visited_module_id': str(subsection.usage_key),
'last_visited_module_path': [
- str(course.location),
- str(section.location),
- str(subsection.location),
+ str(course.usage_key),
+ str(section.usage_key),
+ str(subsection.usage_key),
],
- 'last_visited_block_id': str(problem.location),
+ 'last_visited_block_id': str(problem.usage_key),
'last_visited_unit_display_name': vertical.display_name,
}
@@ -1162,16 +1162,16 @@ def test_success_v0(self):
self.login_and_enroll()
response = self.api_response(api_version=API_V05)
- assert response.data['last_visited_module_id'] == str(self.sub_section.location)
- assert response.data['last_visited_module_path'] == [str(block.location) for block in
+ assert response.data['last_visited_module_id'] == str(self.sub_section.usage_key)
+ assert response.data['last_visited_module_path'] == [str(block.usage_key) for block in
[self.sub_section, self.section, self.course]]
def test_success_v1(self):
self.override_waffle_switch(True)
self.login_and_enroll()
- submit_completions_for_testing(self.user, [self.unit.location])
+ submit_completions_for_testing(self.user, [self.unit.usage_key])
response = self.api_response(api_version=API_V1)
- assert response.data['last_visited_block_id'] == str(self.unit.location)
+ assert response.data['last_visited_block_id'] == str(self.unit.usage_key)
# Since we are testing an non atomic view in atomic test case, therefore we are expecting error on failures
def api_atomic_response(self, reverse_args=None, data=None, **kwargs):
@@ -1228,8 +1228,8 @@ def url_method(self, url, **kwargs): # pylint: disable=arguments-differ
def test_success(self):
self.login_and_enroll()
- response = self.api_response(data={"last_visited_module_id": str(self.other_unit.location)})
- assert response.data['last_visited_module_id'] == str(self.other_sub_section.location)
+ response = self.api_response(data={"last_visited_module_id": str(self.other_unit.usage_key)})
+ assert response.data['last_visited_module_id'] == str(self.other_sub_section.usage_key)
def test_invalid_block(self):
self.login_and_enroll()
@@ -1247,7 +1247,7 @@ def test_no_timezone(self):
past_date = datetime.datetime.now()
response = self.api_response(
data={
- "last_visited_module_id": str(self.other_unit.location),
+ "last_visited_module_id": str(self.other_unit.usage_key),
"modification_date": past_date.isoformat()
},
expected_response_code=400
@@ -1262,16 +1262,16 @@ def _date_sync(self, date, initial_unit, update_unit, expected_subsection):
self.login_and_enroll()
# save something so we have an initial date
- self.api_response(data={"last_visited_module_id": str(initial_unit.location)})
+ self.api_response(data={"last_visited_module_id": str(initial_unit.usage_key)})
# now actually update it
response = self.api_response(
data={
- "last_visited_module_id": str(update_unit.location),
+ "last_visited_module_id": str(update_unit.usage_key),
"modification_date": date.isoformat()
}
)
- assert response.data['last_visited_module_id'] == str(expected_subsection.location)
+ assert response.data['last_visited_module_id'] == str(expected_subsection.usage_key)
def test_old_date(self):
self.login_and_enroll()
@@ -1287,11 +1287,11 @@ def test_no_initial_date(self):
self.login_and_enroll()
response = self.api_response(
data={
- "last_visited_module_id": str(self.other_unit.location),
+ "last_visited_module_id": str(self.other_unit.usage_key),
"modification_date": timezone.now().isoformat()
}
)
- assert response.data['last_visited_module_id'] == str(self.other_sub_section.location)
+ assert response.data['last_visited_module_id'] == str(self.other_sub_section.usage_key)
def test_invalid_date(self):
self.login_and_enroll()
@@ -1535,7 +1535,7 @@ def test_different_completion_dates(self, completed_days_ago: int, recently_acti
user=self.user,
context_key=course.context_key,
block_type='course',
- block_key=section.location,
+ block_key=section.usage_key,
completion=0.5,
)
completion.created = datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=completed_days_ago)
diff --git a/lms/djangoapps/mobile_api/users/views.py b/lms/djangoapps/mobile_api/users/views.py
index 324db83a374c..5b46a8d3fc22 100644
--- a/lms/djangoapps/mobile_api/users/views.py
+++ b/lms/djangoapps/mobile_api/users/views.py
@@ -183,7 +183,7 @@ def _get_course_info(self, request, course):
Returns the course status
"""
path = self._last_visited_block_path(request, course)
- path_ids = [str(block.location) for block in path]
+ path_ids = [str(block.usage_key) for block in path]
return Response({
"last_visited_module_id": path_ids[0],
"last_visited_module_path": path_ids,
@@ -208,7 +208,7 @@ def _update_last_visited_module_id(self, request, course, module_key, modificati
key = KeyValueStore.Key(
scope=Scope.user_state,
user_id=request.user.id,
- block_scope_id=course.location,
+ block_scope_id=course.usage_key,
field_name='position'
)
original_store_date = field_data_cache.last_modified(key)
diff --git a/lms/djangoapps/ora_staff_grader/tests/test_views.py b/lms/djangoapps/ora_staff_grader/tests/test_views.py
index 2f27a8059077..8df54f0667e5 100644
--- a/lms/djangoapps/ora_staff_grader/tests/test_views.py
+++ b/lms/djangoapps/ora_staff_grader/tests/test_views.py
@@ -49,14 +49,14 @@ def setUpClass(cls):
cls.api_url = reverse(cls.view_name)
cls.course = CourseFactory.create()
- cls.course_key = cls.course.location.course_key
+ cls.course_key = cls.course.usage_key.course_key
cls.ora_block = BlockFactory.create(
category="openassessment",
- parent_location=cls.course.location,
+ parent_location=cls.course.usage_key,
display_name="test",
)
- cls.ora_usage_key = str(cls.ora_block.location)
+ cls.ora_usage_key = str(cls.ora_block.usage_key)
cls.password = "password"
cls.staff = StaffFactory(course_key=cls.course_key, password=cls.password)
diff --git a/lms/djangoapps/program_enrollments/rest_api/v1/tests/test_views.py b/lms/djangoapps/program_enrollments/rest_api/v1/tests/test_views.py
index 174d3ad198ff..9fa04522eed7 100644
--- a/lms/djangoapps/program_enrollments/rest_api/v1/tests/test_views.py
+++ b/lms/djangoapps/program_enrollments/rest_api/v1/tests/test_views.py
@@ -1929,11 +1929,11 @@ def test_due_dates(self, now_time, course_in_progress):
mock_path = 'lms.djangoapps.course_api.api.get_dates_for_course'
with mock.patch(mock_path) as mock_get_dates, freeze_time(now_time):
mock_get_dates.return_value = {
- (section_1.location, 'due'): section_1.due,
- (section_1.location, 'start'): section_1.start,
- (subsection_1.location, 'due'): subsection_1.due,
- (subsection_2.location, 'due'): subsection_2.due,
- (unit_1.location, 'due'): unit_1.due,
+ (section_1.usage_key, 'due'): section_1.due,
+ (section_1.usage_key, 'start'): section_1.start,
+ (subsection_1.usage_key, 'due'): subsection_1.due,
+ (subsection_2.usage_key, 'due'): subsection_2.due,
+ (unit_1.usage_key, 'due'): unit_1.due,
}
self.log_in()
diff --git a/lms/djangoapps/staticbook/tests.py b/lms/djangoapps/staticbook/tests.py
index 919ee16c4fef..d8676b62ea84 100644
--- a/lms/djangoapps/staticbook/tests.py
+++ b/lms/djangoapps/staticbook/tests.py
@@ -210,7 +210,7 @@ def test_static_url_map_contentstore(self):
response = self.client.get(url)
self.assertNotContains(response, 'file={}'.format(PORTABLE_PDF_BOOK['chapters'][0]['url']))
self.assertContains(response, 'file=/asset-v1:{0.org}+{0.course}+{0.run}+type@asset+block/{1}'.format(
- self.course.location,
+ self.course.usage_key,
PORTABLE_PDF_BOOK['chapters'][0]['url'].replace('/static/', '')))
def test_static_url_map_static_asset_path(self):
@@ -222,7 +222,7 @@ def test_static_url_map_static_asset_path(self):
response = self.client.get(url)
self.assertNotContains(response, 'file={}'.format(PORTABLE_PDF_BOOK['chapters'][0]['url']))
self.assertNotContains(response, 'file=/c4x/{0.org}/{0.course}/asset/{1}'.format(
- self.course.location,
+ self.course.usage_key,
PORTABLE_PDF_BOOK['chapters'][0]['url'].replace('/static/', '')))
self.assertContains(response, 'file=/static/awesomesauce/{}'.format(
PORTABLE_PDF_BOOK['chapters'][0]['url'].replace('/static/', '')))
diff --git a/lms/djangoapps/support/tests/test_tasks.py b/lms/djangoapps/support/tests/test_tasks.py
index 65add3079335..44c03e1cd0ca 100644
--- a/lms/djangoapps/support/tests/test_tasks.py
+++ b/lms/djangoapps/support/tests/test_tasks.py
@@ -84,14 +84,14 @@ def basic_setup(self):
# set up a simple course with four problems
homework = self.add_graded_section_to_course('homework')
vertical = BlockFactory.create(
- parent_location=homework.location,
+ parent_location=homework.usage_key,
category='vertical',
display_name='Unit 1',
)
- self.p1 = self.add_dropdown_to_section(vertical.location, 'p1', 1)
- self.p2 = self.add_dropdown_to_section(vertical.location, 'p2', 1)
- self.p3 = self.add_dropdown_to_section(vertical.location, 'p3', 1)
+ self.p1 = self.add_dropdown_to_section(vertical.usage_key, 'p1', 1)
+ self.p2 = self.add_dropdown_to_section(vertical.usage_key, 'p2', 1)
+ self.p3 = self.add_dropdown_to_section(vertical.usage_key, 'p3', 1)
video_sample_xml = """
').format(
msg=str(error)
@@ -1097,12 +1097,12 @@ def handle_problem_html_error(self, err):
`err` is the Exception encountered while rendering the problem HTML.
"""
problem_display_name = self.display_name_with_default
- problem_location = str(self.location)
+ problem_location = str(self.usage_key)
log.exception("ProblemGetHtmlError: %r, %r, %s", problem_display_name, problem_location, str(err))
if self.debug:
msg = HTML("[courseware.capa.capa_block] Failed to generate HTML for problem {url}").format(
- url=str(self.location)
+ url=str(self.usage_key)
)
msg += HTML("Error:
{msg}").format(msg=str(err))
msg += HTML("{tb}").format(tb=traceback.format_exc())
@@ -1223,7 +1223,7 @@ def get_demand_hint(self, hint_index):
# Log this demand-hint request. Note that this only logs the last hint requested (although now
# all previously shown hints are still displayed).
event_info = {}
- event_info["module_id"] = str(self.location)
+ event_info["module_id"] = str(self.usage_key)
event_info["hint_index"] = hint_index
event_info["hint_len"] = len(demand_hints)
event_info["hint_text"] = get_inner_html_from_xpath(demand_hints[hint_index])
@@ -1292,8 +1292,8 @@ def get_problem_html(self, encapsulate=True, submit_notification=False): # pyli
context = {
"problem": content,
- "id": str(self.location),
- "short_id": self.location.html_id(),
+ "id": str(self.usage_key),
+ "short_id": self.usage_key.html_id(),
"submit_button": submit_button,
"submit_button_submitting": submit_button_submitting,
"should_enable_submit_button": should_enable_submit_button,
@@ -1316,7 +1316,7 @@ def get_problem_html(self, encapsulate=True, submit_notification=False): # pyli
if encapsulate:
html = HTML('{html}
').format(
- id=self.location.html_id(), ajax_url=self.ajax_url, html=HTML(html)
+ id=self.usage_key.html_id(), ajax_url=self.ajax_url, html=HTML(html)
)
# Now do all the substitutions which the LMS block_render normally does, but
@@ -1598,7 +1598,7 @@ def get_answer(self, _data):
(and also screen reader text).
"""
event_info = {}
- event_info["problem_id"] = str(self.location)
+ event_info["problem_id"] = str(self.usage_key)
self.publish_unmasked("showanswer", event_info)
if not self.answer_available():
raise NotFoundError("Answer is not available")
@@ -1747,7 +1747,7 @@ def submit_problem( # pylint: disable=too-many-statements,too-many-branches,too
"""
event_info = {}
event_info["state"] = self.lcp.get_state()
- event_info["problem_id"] = str(self.location)
+ event_info["problem_id"] = str(self.usage_key)
self.lcp.has_saved_answers = False
answers = self.make_dict_of_responses(data)
@@ -1766,7 +1766,7 @@ def submit_problem( # pylint: disable=too-many-statements,too-many-branches,too
if self.closed():
log.error(
"ProblemClosedError: Problem %s, close date: %s, due:%s, is_past_due: %s, attempts: %s/%s,",
- str(self.location),
+ str(self.usage_key),
self.close_date,
self.due,
self.is_past_due(),
@@ -2080,7 +2080,7 @@ def save_problem(self, data):
"""
event_info = {}
event_info["state"] = self.lcp.get_state()
- event_info["problem_id"] = str(self.location)
+ event_info["problem_id"] = str(self.usage_key)
answers = self.make_dict_of_responses(data)
event_info["answers"] = answers
@@ -2132,7 +2132,7 @@ def reset_problem(self, _data):
"""
event_info = {}
event_info["old_state"] = self.lcp.get_state()
- event_info["problem_id"] = str(self.location)
+ event_info["problem_id"] = str(self.usage_key)
_ = self.runtime.service(self, "i18n").gettext
if self.closed():
@@ -2196,7 +2196,7 @@ def rescore(self, only_if_higher=False):
Returns the error messages for exceptions occurring while performing
the rescoring, rather than throwing them.
"""
- event_info = {"state": self.lcp.get_state(), "problem_id": str(self.location)}
+ event_info = {"state": self.lcp.get_state(), "problem_id": str(self.usage_key)}
_ = self.runtime.service(self, "i18n").gettext
diff --git a/xmodule/conditional_block.py b/xmodule/conditional_block.py
index 78a5b8c1c1c9..df0828000d71 100644
--- a/xmodule/conditional_block.py
+++ b/xmodule/conditional_block.py
@@ -180,7 +180,7 @@ def __init__(self, *args, **kwargs):
# for old-style course locators. However, this is the implementation of
# CourseLocator.make_usage_key_from_deprecated_string, which was previously
# being called in this location.
- BlockUsageLocator.from_string(item).replace(run=self.location.course_key.run)
+ BlockUsageLocator.from_string(item).replace(run=self.usage_key.course_key.run)
for item in ConditionalBlock.parse_sources(self.xml_attributes)
]
@@ -222,9 +222,9 @@ def student_view(self, _context):
return fragment
def get_html(self):
- required_html_ids = [block.location.html_id() for block in self.get_required_blocks]
+ required_html_ids = [block.usage_key.html_id() for block in self.get_required_blocks]
return self.runtime.service(self, 'mako').render_lms_template('conditional_ajax.html', {
- 'element_id': self.location.html_id(),
+ 'element_id': self.usage_key.html_id(),
'ajax_url': self.ajax_url,
'depends': ';'.join(required_html_ids)
})
@@ -235,7 +235,7 @@ def author_view(self, context):
"""
fragment = Fragment()
root_xblock = context.get('root_xblock')
- is_root = root_xblock and root_xblock.location == self.location
+ is_root = root_xblock and root_xblock.usage_key == self.usage_key
if is_root:
# User has clicked the "View" link. Show a preview of all possible children:
self.render_children(context, fragment, can_reorder=True, can_add=True)
@@ -350,7 +350,7 @@ def definition_from_xml(cls, xml_object, system):
def definition_to_xml(self, resource_fs):
xml_object = etree.Element(self._tag_name)
for child in self.get_children():
- if child.location not in self.show_tag_list:
+ if child.usage_key not in self.show_tag_list:
self.runtime.add_block_as_child_node(child, xml_object)
if self.show_tag_list:
@@ -369,7 +369,7 @@ def definition_to_xml(self, resource_fs):
def validate(self):
validation = super().validate()
if not self.sources_list:
- conditional_validation = StudioValidation(self.location)
+ conditional_validation = StudioValidation(self.usage_key)
conditional_validation.add(
StudioValidationMessage(
StudioValidationMessage.NOT_CONFIGURED,
diff --git a/xmodule/course_block.py b/xmodule/course_block.py
index 17dc4d877be7..5e62ba64f717 100644
--- a/xmodule/course_block.py
+++ b/xmodule/course_block.py
@@ -1105,7 +1105,7 @@ def __init__(self, *args, **kwargs):
self._gating_prerequisites = None
if self.wiki_slug is None:
- self.wiki_slug = self.location.course
+ self.wiki_slug = self.usage_key.course
if self.due_date_display_format is None and self.show_timezone is False:
# For existing courses with show_timezone set to False (and no due_date_display_format specified),
@@ -1129,7 +1129,7 @@ def __init__(self, *args, **kwargs):
self.set_grading_policy(self.grading_policy)
if not self.discussion_topics:
- self.discussion_topics = {_('General'): {'id': self.location.html_id()}}
+ self.discussion_topics = {_('General'): {'id': self.usage_key.html_id()}}
try:
if not getattr(self, "tabs", []):
@@ -1434,7 +1434,7 @@ def make_id(org, course, url_name):
@property
def id(self):
"""Return the course_id for this course"""
- return self.location.course_key
+ return self.usage_key.course_key
@property
def start_date_is_still_default(self):
@@ -1502,7 +1502,7 @@ def number(self):
"Intro to Computer Science" with the course key "edX/CS-101/2014", the
course number would be "CS-101"
"""
- return course_metadata_utils.number_for_course_location(self.location)
+ return course_metadata_utils.number_for_course_location(self.usage_key)
@property
def display_number_with_default(self):
@@ -1516,7 +1516,7 @@ def display_number_with_default(self):
@property
def org(self):
- return self.location.org
+ return self.usage_key.org
@property
def display_org_with_default(self):
@@ -1543,7 +1543,7 @@ def clean_id(self, padding_char='='):
Returns a unique deterministic base32-encoded ID for the course.
The optional padding_char parameter allows you to override the "=" character used for padding.
"""
- return course_metadata_utils.clean_course_key(self.location.course_key, padding_char)
+ return course_metadata_utils.clean_course_key(self.usage_key.course_key, padding_char)
@property
def teams_enabled(self):
@@ -1637,7 +1637,7 @@ def __init__(self, course_locator, display_name="Empty", display_coursenumber=No
self.display_name = display_name
self.id = course_locator # pylint: disable=invalid-name
- self.location = course_locator.make_usage_key('course', 'course')
+ self.usage_key = course_locator.make_usage_key('course', 'course')
self.end = end
if end is not None and not isinstance(end, datetime):
self.end = dateutil.parser.parse(end)
@@ -1650,7 +1650,7 @@ def display_org_with_default(self):
"""
if self.display_organization:
return self.display_organization
- return self.location.org
+ return self.usage_key.org
@property
def display_number_with_default(self):
@@ -1660,7 +1660,7 @@ def display_number_with_default(self):
"""
if self.display_coursenumber:
return self.display_coursenumber
- return self.location.course
+ return self.usage_key.course
def has_ended(self):
"""
diff --git a/xmodule/error_block.py b/xmodule/error_block.py
index 51c895a3e864..9d235e4e8628 100644
--- a/xmodule/error_block.py
+++ b/xmodule/error_block.py
@@ -144,7 +144,7 @@ def from_block(cls, block, error_msg=None):
block.runtime,
str(block),
error_msg,
- location=block.location,
+ location=block.usage_key,
for_parent=block.get_parent() if block.has_cached_parent else None
)
diff --git a/xmodule/exceptions.py b/xmodule/exceptions.py
index 678cab6f23a0..454b146f0cf6 100644
--- a/xmodule/exceptions.py
+++ b/xmodule/exceptions.py
@@ -14,7 +14,7 @@ class InvalidVersionError(Exception):
"""
def __init__(self, location):
super().__init__()
- self.location = location
+ self.usage_key = location
class SerializationError(Exception):
@@ -23,7 +23,7 @@ class SerializationError(Exception):
"""
def __init__(self, location, msg):
super().__init__(msg)
- self.location = location
+ self.usage_key = location
class UndefinedContext(Exception):
diff --git a/xmodule/graders.py b/xmodule/graders.py
index 0a559e470aa2..b482c1b2e8a4 100644
--- a/xmodule/graders.py
+++ b/xmodule/graders.py
@@ -383,7 +383,7 @@ def grade(self, grade_sheet, generate_random_scores=False):
earned = scores[i].graded_total.earned
possible = scores[i].graded_total.possible
section_name = scores[i].display_name
- sequential_id = str(scores[i].location)
+ sequential_id = str(scores[i].usage_key)
percentage = scores[i].percent_graded
summary_format = "{section_type} {index} - {name} - {percent:.2%} ({earned:.3n}/{possible:.3n})"
@@ -428,7 +428,7 @@ def grade(self, grade_sheet, generate_random_scores=False):
total_label = f"{self.short_label}"
breakdown = [{'percent': total_percent, 'label': total_label,
'detail': total_detail, 'category': self.category, 'prominent': True,
- 'sequential_id': str(scores[0].location) if scores else None}, ]
+ 'sequential_id': str(scores[0].usage_key) if scores else None}, ]
else:
# Translators: "Homework Average = 0%"
total_detail = _("{section_type} Average = {percent:.2%}").format(
diff --git a/xmodule/html_block.py b/xmodule/html_block.py
index 27a2b51e4a31..f4a0f6c068a0 100644
--- a/xmodule/html_block.py
+++ b/xmodule/html_block.py
@@ -214,7 +214,7 @@ def get_context(self):
# Add some specific HTML rendering context when editing HTML blocks where we pass
# the root /c4x/ url for assets. This allows client-side substitutions to occur.
_context.update({
- 'base_asset_url': StaticContent.get_base_url_path_for_course_assets(self.location.course_key),
+ 'base_asset_url': StaticContent.get_base_url_path_for_course_assets(self.usage_key.course_key),
'enable_latex_compiler': self.use_latex_compiler,
'editor': self.editor
})
diff --git a/xmodule/library_content_block.py b/xmodule/library_content_block.py
index 6f583d8beff2..4a851da577a9 100644
--- a/xmodule/library_content_block.py
+++ b/xmodule/library_content_block.py
@@ -153,7 +153,7 @@ def author_view(self, context):
return super().author_view(context)
fragment = Fragment()
root_xblock = context.get('root_xblock')
- is_root = root_xblock and root_xblock.location == self.location
+ is_root = root_xblock and root_xblock.usage_key == self.usage_key
try:
is_updating = self.get_tools().are_children_syncing(self)
except LibraryToolsUnavailable:
@@ -590,7 +590,7 @@ def __init__(self, library_locator, display_name):
self.display_name = display_name if display_name else _("Empty")
self.id = library_locator # pylint: disable=invalid-name
- self.location = library_locator.make_usage_key('library', 'library')
+ self.usage_key = library_locator.make_usage_key('library', 'library')
@property
def display_org_with_default(self):
@@ -598,7 +598,7 @@ def display_org_with_default(self):
Org display names are not implemented. This just provides API compatibility with CourseBlock.
Always returns the raw 'org' field from the key.
"""
- return self.location.library_key.org
+ return self.usage_key.library_key.org
@property
def display_number_with_default(self):
@@ -606,4 +606,4 @@ def display_number_with_default(self):
Display numbers are not implemented. This just provides API compatibility with CourseBlock.
Always returns the raw 'library' field from the key.
"""
- return self.location.library_key.library
+ return self.usage_key.library_key.library
diff --git a/xmodule/library_root_xblock.py b/xmodule/library_root_xblock.py
index cfe2ba6276af..05f3f788f75a 100644
--- a/xmodule/library_root_xblock.py
+++ b/xmodule/library_root_xblock.py
@@ -89,7 +89,7 @@ def render_children(self, context, fragment, can_reorder=False, can_add=False):
child = self.runtime.get_block(child_key)
child_view_name = StudioEditableBlock.get_preview_view_name(child)
- if str(child.location) == force_render:
+ if str(child.usage_key) == force_render:
child_context['show_preview'] = True
if child_context['show_preview']:
@@ -99,7 +99,7 @@ def render_children(self, context, fragment, can_reorder=False, can_add=False):
fragment.add_fragment_resources(rendered_child)
contents.append({
- 'id': str(child.location),
+ 'id': str(child.usage_key),
'content': rendered_child.content,
})
diff --git a/xmodule/library_tools.py b/xmodule/library_tools.py
index eca227dd47f4..74677ffeabb7 100644
--- a/xmodule/library_tools.py
+++ b/xmodule/library_tools.py
@@ -54,15 +54,15 @@ def get_latest_library_version(self, library_id: str | LibraryLocator) -> str |
return None
if not library:
return None
- # We need to know the library's version so ensure it's set in library.location.library_key.version_guid
- assert library.location.library_key.version_guid is not None
- return str(library.location.library_key.version_guid)
+ # We need to know the library's version so ensure it's set in library.usage_key.library_key.version_guid
+ assert library.usage_key.library_key.version_guid is not None
+ return str(library.usage_key.library_key.version_guid)
def can_use_library_content(self, block):
"""
Determines whether a modulestore holding a course_id supports libraries.
"""
- return self.store.check_supports(block.location.course_key, 'copy_from_template')
+ return self.store.check_supports(block.usage_key.course_key, 'copy_from_template')
def trigger_library_sync(self, dest_block: LegacyLibraryContentBlock, library_version: str | None) -> None:
"""
@@ -159,6 +159,6 @@ def list_available_libraries(self):
"""
user = User.objects.get(id=self.user_id)
return [
- (lib.location.library_key.replace(version_guid=None, branch=None), lib.display_name)
+ (lib.usage_key.library_key.replace(version_guid=None, branch=None), lib.display_name)
for lib in self.store.get_library_summaries()
]
diff --git a/xmodule/lti_block.py b/xmodule/lti_block.py
index 2984cb09d88a..07701c87026f 100644
--- a/xmodule/lti_block.py
+++ b/xmodule/lti_block.py
@@ -507,7 +507,7 @@ def get_context(self):
# These parameters do not participate in OAuth signing.
'launch_url': self.launch_url.strip(),
- 'element_id': self.location.html_id(),
+ 'element_id': self.usage_key.html_id(),
'element_class': self.category,
'open_in_a_new_page': self.open_in_a_new_page,
'display_name': self.display_name,
@@ -595,7 +595,7 @@ def get_resource_link_id(self):
i4x-2-3-lti-31de800015cf4afb973356dbe81496df this part of resource_link_id:
makes resource_link_id to be unique among courses inside same system.
"""
- return str(parse.quote(f"{settings.LMS_BASE}-{self.location.html_id()}"))
+ return str(parse.quote(f"{settings.LMS_BASE}-{self.usage_key.html_id()}"))
def get_lis_result_sourcedid(self):
"""
@@ -727,8 +727,8 @@ def oauth_params(self, custom_parameters, client_key, client_secret):
# Stubbing headers for now:
log.info(
"LTI block %s in course %s does not have oauth parameters correctly configured.",
- self.location,
- self.location.course_key,
+ self.usage_key,
+ self.usage_key.course_key,
)
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
diff --git a/xmodule/modulestore/__init__.py b/xmodule/modulestore/__init__.py
index 3446a4c8c61b..1cd9b520b30d 100644
--- a/xmodule/modulestore/__init__.py
+++ b/xmodule/modulestore/__init__.py
@@ -1393,7 +1393,7 @@ def create_child(self, user_id, parent_usage_key, block_type, block_id=None, fie
"""
item = self.create_item(user_id, parent_usage_key.course_key, block_type, block_id=block_id, fields=fields, **kwargs) # lint-amnesty, pylint: disable=line-too-long
parent = self.get_item(parent_usage_key)
- parent.children.append(item.location)
+ parent.children.append(item.usage_key)
self.update_item(parent, user_id)
def _flag_library_updated_event(self, library_key):
diff --git a/xmodule/modulestore/draft_and_published.py b/xmodule/modulestore/draft_and_published.py
index d69e06763cdc..7810fd9db7f6 100644
--- a/xmodule/modulestore/draft_and_published.py
+++ b/xmodule/modulestore/draft_and_published.py
@@ -162,26 +162,26 @@ def update_item_parent(self, item_location, new_parent_location, old_parent_loca
return
# Remove item from the list of children of old parent.
- if source_item.location in old_parent_item.children:
- old_parent_item.children.remove(source_item.location)
+ if source_item.usage_key in old_parent_item.children:
+ old_parent_item.children.remove(source_item.usage_key)
self.update_item(old_parent_item, user_id) # pylint: disable=no-member
log.info(
'%s removed from %s children',
- str(source_item.location),
- str(old_parent_item.location)
+ str(source_item.usage_key),
+ str(old_parent_item.usage_key)
)
# Add item to new parent at particular location.
- if source_item.location not in new_parent_item.children:
+ if source_item.usage_key not in new_parent_item.children:
if insert_at is not None:
- new_parent_item.children.insert(insert_at, source_item.location)
+ new_parent_item.children.insert(insert_at, source_item.usage_key)
else:
- new_parent_item.children.append(source_item.location)
+ new_parent_item.children.append(source_item.usage_key)
self.update_item(new_parent_item, user_id) # pylint: disable=no-member
log.info(
'%s added to %s children',
- str(source_item.location),
- str(new_parent_item.location)
+ str(source_item.usage_key),
+ str(new_parent_item.usage_key)
)
# Update parent attribute of the item block
@@ -189,10 +189,10 @@ def update_item_parent(self, item_location, new_parent_location, old_parent_loca
self.update_item(source_item, user_id) # pylint: disable=no-member
log.info(
'%s parent updated to %s',
- str(source_item.location),
- str(new_parent_item.location)
+ str(source_item.usage_key),
+ str(new_parent_item.usage_key)
)
- return source_item.location
+ return source_item.usage_key
class UnsupportedRevisionError(ValueError):
diff --git a/xmodule/modulestore/inheritance.py b/xmodule/modulestore/inheritance.py
index a41bf84d99d8..16e96f891f84 100644
--- a/xmodule/modulestore/inheritance.py
+++ b/xmodule/modulestore/inheritance.py
@@ -387,7 +387,7 @@ def default(self, block, name):
# from parent as '_copy_from_templates' puts fields into
# defaults.
if ancestor and \
- ancestor.location.block_type == 'library_content' and \
+ ancestor.usage_key.block_type == 'library_content' and \
self.has_default_value(name):
return super().default(block, name)
diff --git a/xmodule/modulestore/mixed.py b/xmodule/modulestore/mixed.py
index b196eb2ea417..f6cddf2138e1 100644
--- a/xmodule/modulestore/mixed.py
+++ b/xmodule/modulestore/mixed.py
@@ -352,7 +352,7 @@ def get_library_summaries(self, **kwargs):
continue
# fetch library summaries and filter out any duplicated entry across/within stores
for library_summary in store.get_library_summaries(**kwargs):
- library_id = self._clean_locator_for_mapping(library_summary.location)
+ library_id = self._clean_locator_for_mapping(library_summary.usage_key)
if library_id not in library_summaries:
library_summaries[library_id] = library_summary
return list(library_summaries.values())
@@ -368,7 +368,7 @@ def get_libraries(self, **kwargs):
continue
# filter out ones which were fetched from earlier stores but locations may not be ==
for library in store.get_libraries(**kwargs):
- library_id = self._clean_locator_for_mapping(library.location)
+ library_id = self._clean_locator_for_mapping(library.usage_key)
if library_id not in libraries:
# library is indeed unique. save it in result
libraries[library_id] = library
@@ -766,9 +766,9 @@ def send_created_event():
XBLOCK_CREATED.send_event(
time=datetime.now(timezone.utc),
xblock_info=XBlockData(
- usage_key=xblock.location.for_branch(None),
+ usage_key=xblock.usage_key.for_branch(None),
block_type=block_type,
- version=xblock.location
+ version=xblock.usage_key
)
)
@@ -805,9 +805,9 @@ def send_created_event():
XBLOCK_CREATED.send_event(
time=datetime.now(timezone.utc),
xblock_info=XBlockData(
- usage_key=xblock.location.for_branch(None),
+ usage_key=xblock.usage_key.for_branch(None),
block_type=block_type,
- version=xblock.location
+ version=xblock.usage_key
)
)
@@ -840,7 +840,7 @@ def update_item(self, xblock, user_id, allow_not_found=False, **kwargs): # lint
Update the xblock persisted to be the same as the given for all types of fields
(content, children, and metadata) attribute the change to the given user.
"""
- course_key = xblock.location.course_key
+ course_key = xblock.usage_key.course_key
store = self._verify_modulestore_support(course_key, 'update_item')
xblock = store.update_item(xblock, user_id, allow_not_found, **kwargs)
@@ -850,9 +850,9 @@ def send_updated_event():
XBLOCK_UPDATED.send_event(
time=datetime.now(timezone.utc),
xblock_info=XBlockData(
- usage_key=xblock.location.for_branch(None),
- block_type=xblock.location.block_type,
- version=xblock.location
+ usage_key=xblock.usage_key.for_branch(None),
+ block_type=xblock.usage_key.block_type,
+ version=xblock.usage_key
)
)
@@ -1031,7 +1031,7 @@ def has_changes(self, xblock):
:param xblock: the block to check
:return: True if the draft and published versions differ
"""
- store = self._verify_modulestore_support(xblock.location.course_key, 'has_changes')
+ store = self._verify_modulestore_support(xblock.usage_key.course_key, 'has_changes')
return store.has_changes(xblock)
def check_supports(self, course_key, method):
diff --git a/xmodule/modulestore/mongo/draft.py b/xmodule/modulestore/mongo/draft.py
index 78031d04cf2a..fb9fbfd6ae05 100644
--- a/xmodule/modulestore/mongo/draft.py
+++ b/xmodule/modulestore/mongo/draft.py
@@ -35,8 +35,8 @@ def wrap_draft(item):
Sets `item.is_draft` to `True` if the item is DRAFT, and `False` otherwise.
Sets the item's location to the non-draft location in either case.
"""
- item.is_draft = (item.location.branch == MongoRevisionKey.draft)
- item.location = item.location.replace(revision=MongoRevisionKey.published)
+ item.is_draft = (item.usage_key.branch == MongoRevisionKey.draft)
+ item.usage_key = item.usage_key.replace(revision=MongoRevisionKey.published)
return item
@@ -256,7 +256,7 @@ def create_xblock(self, runtime, course_key, block_type, block_id=None, fields=N
new_block = super().create_xblock( # lint-amnesty, pylint: disable=super-with-arguments
runtime, course_key, block_type, block_id, fields, **kwargs
)
- new_block.location = self.for_branch_setting(new_block.location)
+ new_block.usage_key = self.for_branch_setting(new_block.usage_key)
return wrap_draft(new_block)
def get_items(self, course_key, revision=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
@@ -288,11 +288,11 @@ def draft_items():
def published_items(draft_items):
# filters out items that are not already in draft_items
- draft_items_locations = {item.location for item in draft_items}
+ draft_items_locations = {item.usage_key for item in draft_items}
return [
item for item in
base_get_items(MongoRevisionKey.published)
- if item.location not in draft_items_locations
+ if item.usage_key not in draft_items_locations
]
if revision == ModuleStoreEnum.RevisionOption.draft_only:
@@ -355,7 +355,7 @@ def has_published_version(self, xblock):
published version is up to date.
"""
if getattr(xblock, 'is_draft', False):
- published_xblock_location = as_published(xblock.location)
+ published_xblock_location = as_published(xblock.usage_key)
try:
xblock.runtime.lookup_item(published_xblock_location)
except ItemNotFoundError:
diff --git a/xmodule/modulestore/search.py b/xmodule/modulestore/search.py
index fc065078968b..6b4c88f5e544 100644
--- a/xmodule/modulestore/search.py
+++ b/xmodule/modulestore/search.py
@@ -158,7 +158,7 @@ def is_child_appendable(child_instance):
for child in section_desc.get_children():
if not is_child_appendable(child):
continue
- child_locs.append(child.location)
+ child_locs.append(child.usage_key)
return child_locs
diff --git a/xmodule/modulestore/split_mongo/runtime.py b/xmodule/modulestore/split_mongo/runtime.py
index 2ebd6fe805d4..9b98cc8fba94 100644
--- a/xmodule/modulestore/split_mongo/runtime.py
+++ b/xmodule/modulestore/split_mongo/runtime.py
@@ -337,10 +337,10 @@ def get_subtree_edited_by(self, xblock):
"""
# pylint: disable=protected-access
if not hasattr(xblock, '_subtree_edited_by'):
- block_data = self.module_data[BlockKey.from_usage_key(xblock.location)]
+ block_data = self.module_data[BlockKey.from_usage_key(xblock.usage_key)]
if block_data.edit_info._subtree_edited_by is None:
self._compute_subtree_edited_internal(
- block_data, xblock.location.course_key
+ block_data, xblock.usage_key.course_key
)
xblock._subtree_edited_by = block_data.edit_info._subtree_edited_by
@@ -352,10 +352,10 @@ def get_subtree_edited_on(self, xblock):
"""
# pylint: disable=protected-access
if not hasattr(xblock, '_subtree_edited_on'):
- block_data = self.module_data[BlockKey.from_usage_key(xblock.location)]
+ block_data = self.module_data[BlockKey.from_usage_key(xblock.usage_key)]
if block_data.edit_info._subtree_edited_on is None:
self._compute_subtree_edited_internal(
- block_data, xblock.location.course_key
+ block_data, xblock.usage_key.course_key
)
xblock._subtree_edited_on = block_data.edit_info._subtree_edited_on
diff --git a/xmodule/modulestore/split_mongo/split.py b/xmodule/modulestore/split_mongo/split.py
index aeacac25333e..8f4775149a14 100644
--- a/xmodule/modulestore/split_mongo/split.py
+++ b/xmodule/modulestore/split_mongo/split.py
@@ -1717,7 +1717,7 @@ def create_child(self, user_id, parent_usage_key, block_type, block_id=None, fie
return xblock
# don't version the structure as create_item handled that already.
- new_structure = self._lookup_course(xblock.location.course_key).structure
+ new_structure = self._lookup_course(xblock.usage_key.course_key).structure
# add new block as child and update parent's version
block_id = BlockKey.from_usage_key(parent_usage_key)
@@ -1728,11 +1728,11 @@ def create_child(self, user_id, parent_usage_key, block_type, block_id=None, fie
# Originally added to support entrance exams (settings.FEATURES.get('ENTRANCE_EXAMS'))
if kwargs.get('position') is None:
- parent.fields.setdefault('children', []).append(BlockKey.from_usage_key(xblock.location))
+ parent.fields.setdefault('children', []).append(BlockKey.from_usage_key(xblock.usage_key))
else:
parent.fields.setdefault('children', []).insert(
kwargs.get('position'),
- BlockKey.from_usage_key(xblock.location)
+ BlockKey.from_usage_key(xblock.usage_key)
)
if parent.edit_info.update_version != new_structure['_id']:
@@ -1954,7 +1954,7 @@ def update_item(self, block, user_id, allow_not_found=False, force=False, **kwar
if definition_locator is None and not allow_not_found:
raise AttributeError("block is missing expected definition_locator from caching descriptor system")
return self._update_item_from_fields(
- user_id, block.location.course_key, BlockKey.from_usage_key(block.location),
+ user_id, block.usage_key.course_key, BlockKey.from_usage_key(block.usage_key),
partitioned_fields, definition_locator, allow_not_found, force, **kwargs
) or block
@@ -2137,7 +2137,7 @@ def persist_xblock_dag(self, xblock, user_id, force=False):
:param user_id: who's doing the change
"""
# find course_index entry if applicable and structures entry
- course_key = xblock.location.course_key
+ course_key = xblock.usage_key.course_key
with self.bulk_operations(course_key):
index_entry = self._get_index_if_valid(course_key, force)
structure = self._lookup_course(course_key).structure
@@ -2150,10 +2150,10 @@ def persist_xblock_dag(self, xblock, user_id, force=False):
# update the index entry if appropriate
if index_entry is not None:
- self._update_head(course_key, index_entry, xblock.location.branch, new_id)
+ self._update_head(course_key, index_entry, xblock.usage_key.branch, new_id)
# fetch and return the new item--fetching is unnecessary but a good qc step
- return self.get_item(xblock.location.for_version(new_id))
+ return self.get_item(xblock.usage_key.for_version(new_id))
else:
return xblock
@@ -2194,7 +2194,7 @@ def _persist_subdag(self, course_key, xblock, user_id, structure_blocks, new_id)
if isinstance(child.block_id, LocalId):
child_block = xblock.runtime.get_block(child)
is_updated = self._persist_subdag(course_key, child_block, user_id, structure_blocks, new_id) or is_updated # lint-amnesty, pylint: disable=line-too-long
- children.append(BlockKey.from_usage_key(child_block.location))
+ children.append(BlockKey.from_usage_key(child_block.usage_key))
else:
children.append(BlockKey.from_usage_key(child))
is_updated = is_updated or structure_blocks[block_key].fields['children'] != children
diff --git a/xmodule/modulestore/split_mongo/split_draft.py b/xmodule/modulestore/split_mongo/split_draft.py
index 62ee4166df9d..6a8c8137832e 100644
--- a/xmodule/modulestore/split_mongo/split_draft.py
+++ b/xmodule/modulestore/split_mongo/split_draft.py
@@ -41,7 +41,7 @@ def create_course(self, org, course, run, user_id, skip_auto_publish=False, **kw
)
if master_branch == ModuleStoreEnum.BranchName.draft and not skip_auto_publish:
# any other value is hopefully only cloning or doing something which doesn't want this value add
- self._auto_publish_no_children(item.location, item.location.block_type, user_id, **kwargs)
+ self._auto_publish_no_children(item.usage_key, item.usage_key.block_type, user_id, **kwargs)
# create any other necessary things as a side effect: ensure they populate the draft branch
# and rely on auto publish to populate the published branch: split's create course doesn't
@@ -141,12 +141,12 @@ def copy_from_template(self, source_keys, dest_key, user_id, **kwargs): # lint-
return new_keys
def update_item(self, block, user_id, allow_not_found=False, force=False, asides=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
- old_block_locn = block.location
- block.location = self._map_revision_to_branch(old_block_locn)
- emit_signals = block.location.branch == ModuleStoreEnum.BranchName.published \
- or block.location.block_type in DIRECT_ONLY_CATEGORIES
+ old_block_locn = block.usage_key
+ block.usage_key = self._map_revision_to_branch(old_block_locn)
+ emit_signals = block.usage_key.branch == ModuleStoreEnum.BranchName.published \
+ or block.usage_key.block_type in DIRECT_ONLY_CATEGORIES
- with self.bulk_operations(block.location.course_key, emit_signals=emit_signals):
+ with self.bulk_operations(block.usage_key.course_key, emit_signals=emit_signals):
item = super().update_item(
block,
user_id,
@@ -155,8 +155,8 @@ def update_item(self, block, user_id, allow_not_found=False, force=False, asides
asides=asides,
**kwargs
)
- self._auto_publish_no_children(item.location, item.location.block_type, user_id, **kwargs)
- block.location = old_block_locn
+ self._auto_publish_no_children(item.usage_key, item.usage_key.block_type, user_id, **kwargs)
+ block.usage_key = old_block_locn
return item
def create_item(self, user_id, course_key, block_type, block_id=None, # pylint: disable=W0221
@@ -174,7 +174,7 @@ def create_item(self, user_id, course_key, block_type, block_id=None, # pyli
force=force, **kwargs
)
if not skip_auto_publish:
- self._auto_publish_no_children(item.location, item.location.block_type, user_id, **kwargs)
+ self._auto_publish_no_children(item.usage_key, item.usage_key.block_type, user_id, **kwargs)
return item
def create_child(
@@ -188,8 +188,8 @@ def create_child(
fields=fields, asides=asides, **kwargs
)
# Publish both the child and the parent, if the child is a direct-only category
- self._auto_publish_no_children(item.location, item.location.block_type, user_id, **kwargs)
- self._auto_publish_no_children(parent_usage_key, item.location.block_type, user_id, **kwargs)
+ self._auto_publish_no_children(item.usage_key, item.usage_key.block_type, user_id, **kwargs)
+ self._auto_publish_no_children(parent_usage_key, item.usage_key.block_type, user_id, **kwargs)
return item
def delete_item(self, location, user_id, revision=None, skip_auto_publish=False, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
@@ -337,7 +337,7 @@ def has_changes(self, xblock):
:return: True if the draft and published versions differ
"""
def get_course(branch_name):
- return self._lookup_course(xblock.location.course_key.for_branch(branch_name)).structure
+ return self._lookup_course(xblock.usage_key.course_key.for_branch(branch_name)).structure
def get_block(course_structure, block_key):
return self._get_block_from_structure(course_structure, block_key)
@@ -365,7 +365,7 @@ def has_changes_subtree(block_key):
return False
- return has_changes_subtree(BlockKey.from_usage_key(xblock.location))
+ return has_changes_subtree(BlockKey.from_usage_key(xblock.usage_key))
def publish(self, location, user_id, blacklist=None, **kwargs): # lint-amnesty, pylint: disable=arguments-differ
"""
@@ -538,11 +538,11 @@ def convert_to_draft(self, location, user_id):
def _get_head(self, xblock, branch):
""" Gets block at the head of specified branch """
try:
- course_structure = self._lookup_course(xblock.location.course_key.for_branch(branch)).structure
+ course_structure = self._lookup_course(xblock.usage_key.course_key.for_branch(branch)).structure
except ItemNotFoundError:
# There is no published version xblock container, e.g. Library
return None
- return self._get_block_from_structure(course_structure, BlockKey.from_usage_key(xblock.location))
+ return self._get_block_from_structure(course_structure, BlockKey.from_usage_key(xblock.usage_key))
def _get_version(self, block):
"""
@@ -575,7 +575,7 @@ def import_xblock(self, user_id, course_key, block_type, block_id, fields=None,
# Importing the block and publishing the block links the draft & published blocks' version history.
draft_block = self.import_xblock(user_id, draft_course, block_type, block_id, fields,
runtime, **kwargs)
- return self.publish(draft_block.location.version_agnostic(), user_id, blacklist=EXCLUDE_ALL, **kwargs) # lint-amnesty, pylint: disable=line-too-long
+ return self.publish(draft_block.usage_key.version_agnostic(), user_id, blacklist=EXCLUDE_ALL, **kwargs) # lint-amnesty, pylint: disable=line-too-long
# do the import
partitioned_fields = self.partition_fields_by_scope(block_type, fields)
diff --git a/xmodule/modulestore/tests/factories.py b/xmodule/modulestore/tests/factories.py
index ca2f838238b0..711f7f7e1909 100644
--- a/xmodule/modulestore/tests/factories.py
+++ b/xmodule/modulestore/tests/factories.py
@@ -144,7 +144,7 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum
else:
new_course = store.create_course(org, number, run, user_id, fields=kwargs)
- last_course.loc = new_course.location
+ last_course.loc = new_course.usage_key
return new_course
@@ -174,12 +174,12 @@ def create_sub_tree(parent_loc, block_info):
fields=block_info.fields,
)
for tree in block_info.sub_tree:
- create_sub_tree(block.location, tree)
+ create_sub_tree(block.usage_key, tree)
for tree in block_info_tree:
- create_sub_tree(course.location, tree)
+ create_sub_tree(course.usage_key, tree)
- store.publish(course.location, user_id)
+ store.publish(course.usage_key, user_id)
return course
@@ -329,7 +329,7 @@ def parent_location(self): # lint-amnesty, pylint: disable=missing-function-doc
if parent is None:
return default_location
- return parent.location
+ return parent.usage_key
@classmethod
@strip_key
@@ -409,7 +409,7 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum
block = store.create_child(
user_id,
- parent.location,
+ parent.usage_key,
location.block_type,
block_id=location.block_id,
metadata=metadata,
@@ -441,7 +441,7 @@ def _create(cls, target_class, **kwargs): # lint-amnesty, pylint: disable=argum
parent.children.append(location)
store.update_item(parent, user_id)
if publish_item:
- published_parent = store.publish(parent.location, user_id)
+ published_parent = store.publish(parent.usage_key, user_id)
# block is last child of parent
return published_parent.get_children()[-1]
else:
diff --git a/xmodule/modulestore/tests/test_libraries.py b/xmodule/modulestore/tests/test_libraries.py
index 2a82db889b5f..58d3731cf57d 100644
--- a/xmodule/modulestore/tests/test_libraries.py
+++ b/xmodule/modulestore/tests/test_libraries.py
@@ -82,20 +82,20 @@ def test_block_with_children(self):
# In the library, create a vertical block with a child:
vert_block = BlockFactory.create(
category="vertical",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
modulestore=self.store,
)
child_block = BlockFactory.create(
category="html",
- parent_location=vert_block.location,
+ parent_location=vert_block.usage_key,
user_id=self.user_id,
publish_item=False,
metadata={"data": "Hello world", },
modulestore=self.store,
)
- assert child_block.parent.replace(version_guid=None, branch=None) == vert_block.location
+ assert child_block.parent.replace(version_guid=None, branch=None) == vert_block.usage_key
def test_update_item(self):
"""
@@ -105,21 +105,21 @@ def test_update_item(self):
block = BlockFactory.create(
category="html",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
metadata={"data": "Hello world", },
modulestore=self.store,
)
- block_key = block.location
+ block_key = block.usage_key
block.data = "NEW"
- old_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).location.version_guid
+ old_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).usage_key.version_guid
self.store.update_item(block, self.user_id)
# Reload block from the modulestore
block = self.store.get_item(block_key)
assert block.data == 'NEW'
- assert block.location == block_key
- new_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).location.version_guid
+ assert block.usage_key == block_key
+ new_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).usage_key.version_guid
assert old_version != new_version
def test_delete_item(self):
@@ -127,17 +127,17 @@ def test_delete_item(self):
Test to make sure delete_item() works on blocks in a library
"""
library = LibraryFactory.create(modulestore=self.store)
- lib_key = library.location.library_key
+ lib_key = library.usage_key.library_key
block = BlockFactory.create(
category="html",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
modulestore=self.store,
)
library = self.store.get_library(lib_key)
assert len(library.children) == 1
- self.store.delete_item(block.location, self.user_id)
+ self.store.delete_item(block.usage_key, self.user_id)
library = self.store.get_library(lib_key)
assert len(library.children) == 0
@@ -149,20 +149,20 @@ def test_get_library_non_existent(self):
def test_get_library_keys(self):
""" Test get_library_keys() """
libraries = [LibraryFactory.create(modulestore=self.store) for _ in range(3)]
- lib_keys_expected = {lib.location.library_key for lib in libraries}
+ lib_keys_expected = {lib.usage_key.library_key for lib in libraries}
lib_keys_actual = set(self.store.get_library_keys())
assert lib_keys_expected == lib_keys_actual
def test_get_libraries(self):
""" Test get_libraries() """
libraries = [LibraryFactory.create(modulestore=self.store) for _ in range(3)]
- lib_dict = {lib.location.library_key: lib for lib in libraries}
+ lib_dict = {lib.usage_key.library_key: lib for lib in libraries}
lib_list = self.store.get_libraries()
assert len(lib_list) == len(libraries)
for lib in lib_list:
- assert lib.location.library_key in lib_dict
+ assert lib.usage_key.library_key in lib_dict
def test_strip(self):
"""
@@ -170,30 +170,30 @@ def test_strip(self):
branch and version info by default.
"""
# Create a library
- lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
+ lib_key = LibraryFactory.create(modulestore=self.store).usage_key.library_key
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key)
- assert lib.location.version_guid is None
- assert lib.location.branch is None
- assert lib.location.library_key.version_guid is None
- assert lib.location.library_key.branch is None
+ assert lib.usage_key.version_guid is None
+ assert lib.usage_key.branch is None
+ assert lib.usage_key.library_key.version_guid is None
+ assert lib.usage_key.library_key.branch is None
def test_get_lib_version(self):
"""
Test that we can get version data about a library from get_library()
"""
# Create a library
- lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
+ lib_key = LibraryFactory.create(modulestore=self.store).usage_key.library_key
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
- version = lib.location.library_key.version_guid
+ version = lib.usage_key.library_key.version_guid
assert isinstance(version, ObjectId)
def test_xblock_in_lib_have_published_version_returns_false(self):
library = LibraryFactory.create(modulestore=self.store)
block = BlockFactory.create(
category="html",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
modulestore=self.store,
diff --git a/xmodule/modulestore/tests/test_mixed_modulestore.py b/xmodule/modulestore/tests/test_mixed_modulestore.py
index 8c74419a0b7b..ef8ad0ec63ab 100644
--- a/xmodule/modulestore/tests/test_mixed_modulestore.py
+++ b/xmodule/modulestore/tests/test_mixed_modulestore.py
@@ -234,14 +234,14 @@ def _create_course(self, course_key, asides=None):
with self.store.bulk_operations(course_key):
self.course = self.store.create_course(course_key.org, course_key.course, course_key.run, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
if isinstance(self.course.id, CourseLocator):
- self.course_locations[self.MONGO_COURSEID] = self.course.location
+ self.course_locations[self.MONGO_COURSEID] = self.course.usage_key
else:
assert self.course.id == course_key
# create chapter
- chapter = self.store.create_child(self.user_id, self.course.location, 'chapter',
+ chapter = self.store.create_child(self.user_id, self.course.usage_key, 'chapter',
block_id='Overview', asides=asides)
- self.writable_chapter_location = chapter.location
+ self.writable_chapter_location = chapter.usage_key
def _create_block_hierarchy(self):
"""
@@ -295,13 +295,13 @@ def create_sub_tree(parent, block_info):
recursive function that creates the given block and its descendants
"""
block = self.store.create_child(
- self.user_id, parent.location,
+ self.user_id, parent.usage_key,
block_info.category, block_id=block_info.display_name,
fields={'display_name': block_info.display_name},
)
for tree in block_info.sub_tree:
create_sub_tree(block, tree)
- setattr(self, block_info.field_name, block.location)
+ setattr(self, block_info.field_name, block.usage_key)
with self.store.bulk_operations(self.course.id):
for tree in trees:
@@ -526,7 +526,7 @@ def test_course_version_on_block(self, default_ms):
assert block.course_version == course_version
# ensure that when the block is retrieved from the runtime cache,
# the course version is still present
- cached_block = course.runtime.get_block(block.location)
+ cached_block = course.runtime.get_block(block.usage_key)
assert cached_block.course_version == block.course_version
@ddt.data((ModuleStoreEnum.Type.split, 2, False))
@@ -556,9 +556,9 @@ def test_get_items_include_orphans(self, default_ms, expected_items_in_tree, orp
items = self.store.get_items(course_key)
# Check items found are either course or about type
- assert {'course', 'about'}.issubset({item.location.block_type for item in items}) # pylint: disable=line-too-long
+ assert {'course', 'about'}.issubset({item.usage_key.block_type for item in items}) # pylint: disable=line-too-long
# Assert that about is a detached category found in get_items
- assert [item.location.block_type for item in items if item.location.block_type == 'about'][0]\
+ assert [item.usage_key.block_type for item in items if item.usage_key.block_type == 'about'][0]\
in DETACHED_XBLOCK_TYPES
assert len(items) == 2
@@ -577,16 +577,16 @@ def test_get_items_include_orphans(self, default_ms, expected_items_in_tree, orp
# Check now `get_items` retrieves an extra item added above which is an orphan.
items = self.store.get_items(course_key)
- assert orphan in [item.location for item in items]
+ assert orphan in [item.usage_key for item in items]
assert len(items) == 3
# Check now `get_items` with `include_orphans` kwarg does not retrieves an orphan block.
items_in_tree = self.store.get_items(course_key, include_orphans=False)
# Check that course and about blocks are found in get_items
- assert {'course', 'about'}.issubset({item.location.block_type for item in items_in_tree})
+ assert {'course', 'about'}.issubset({item.usage_key.block_type for item in items_in_tree})
# Check orphan is found or not - this is based on mongo/split modulestore. It should be found in mongo.
- assert (orphan in [item.location for item in items_in_tree]) == orphan_in_items
+ assert (orphan in [item.usage_key for item in items_in_tree]) == orphan_in_items
assert len(items_in_tree) == expected_items_in_tree
# split:
@@ -653,18 +653,18 @@ def test_has_changes(self, default_ms):
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
- newXBlock = self.store.publish(xblock.location, self.user_id)
+ newXBlock = self.store.publish(xblock.usage_key, self.user_id)
assert not self.store.has_changes(newXBlock)
# Change the component, then check that there now are changes
- component = self.store.get_item(xblock.location)
+ component = self.store.get_item(xblock.usage_key)
component.display_name = 'Changed Display Name'
component = self.store.update_item(component, self.user_id)
assert self.store.has_changes(component)
# Publish and verify again
- component = self.store.publish(component.location, self.user_id)
+ component = self.store.publish(component.usage_key, self.user_id)
assert not self.store.has_changes(component)
@ddt.data(ModuleStoreEnum.Type.split)
@@ -688,15 +688,15 @@ def test_unit_stuck_in_draft_mode(self, default_ms):
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
- component = self.store.publish(xblock.location, self.user_id)
+ component = self.store.publish(xblock.usage_key, self.user_id)
assert not self.store.has_changes(component)
- self.store.revert_to_published(component.location, self.user_id)
- component = self.store.get_item(component.location)
+ self.store.revert_to_published(component.usage_key, self.user_id)
+ component = self.store.get_item(component.usage_key)
assert not self.store.has_changes(component)
# Publish and verify again
- component = self.store.publish(component.location, self.user_id)
+ component = self.store.publish(component.usage_key, self.user_id)
assert not self.store.has_changes(component)
@ddt.data(ModuleStoreEnum.Type.split)
@@ -720,16 +720,16 @@ def test_unit_stuck_in_published_mode(self, default_ms):
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
- component = self.store.publish(xblock.location, self.user_id)
+ component = self.store.publish(xblock.usage_key, self.user_id)
assert not self.store.has_changes(component)
# Discard changes and verify that there are no changes
- self.store.revert_to_published(component.location, self.user_id)
- component = self.store.get_item(component.location)
+ self.store.revert_to_published(component.usage_key, self.user_id)
+ component = self.store.get_item(component.usage_key)
assert not self.store.has_changes(component)
# Change the component, then check that there now are changes
- component = self.store.get_item(component.location)
+ component = self.store.get_item(component.usage_key)
component.display_name = 'Changed Display Name'
self.store.update_item(component, self.user_id)
@@ -755,29 +755,29 @@ def test_unit_stuck_in_published_mode_after_delete(self, default_ms):
)
component = self.store.create_child(
self.user_id,
- vertical.location,
+ vertical.usage_key,
'html',
block_id='html_component'
)
# publish vertical changes
- self.store.publish(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
+ self.store.publish(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
# Change a component, then check that there now are changes
- component = self.store.get_item(component.location)
+ component = self.store.get_item(component.usage_key)
component.display_name = 'Changed Display Name'
self.store.update_item(component, self.user_id)
- assert self._has_changes(vertical.location)
+ assert self._has_changes(vertical.usage_key)
# Discard changes and verify that there are no changes
- self.store.revert_to_published(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
+ self.store.revert_to_published(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
# Delete the component and verify that the unit has changes
- self.store.delete_item(component.location, self.user_id)
- vertical = self.store.get_item(vertical.location)
- assert self._has_changes(vertical.location)
+ self.store.delete_item(component.usage_key, self.user_id)
+ vertical = self.store.get_item(vertical.usage_key)
+ assert self._has_changes(vertical.usage_key)
@ddt.data(ModuleStoreEnum.Type.split)
def test_publish_automatically_after_delete_unit(self, default_ms):
@@ -789,16 +789,16 @@ def test_publish_automatically_after_delete_unit(self, default_ms):
test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id)
# create sequential and vertical to test against
- sequential = self.store.create_child(self.user_id, test_course.location, 'sequential', 'test_sequential')
- vertical = self.store.create_child(self.user_id, sequential.location, 'vertical', 'test_vertical')
+ sequential = self.store.create_child(self.user_id, test_course.usage_key, 'sequential', 'test_sequential')
+ vertical = self.store.create_child(self.user_id, sequential.usage_key, 'vertical', 'test_vertical')
# publish sequential changes
- self.store.publish(sequential.location, self.user_id)
- assert not self._has_changes(sequential.location)
+ self.store.publish(sequential.usage_key, self.user_id)
+ assert not self._has_changes(sequential.usage_key)
# delete vertical and check sequential has no changes
- self.store.delete_item(vertical.location, self.user_id)
- assert not self._has_changes(sequential.location)
+ self.store.delete_item(vertical.usage_key, self.user_id)
+ assert not self._has_changes(sequential.usage_key)
@ddt.data(ModuleStoreEnum.Type.split)
def test_course_create_event(self, default_ms):
@@ -839,14 +839,14 @@ def test_xblock_create_event(self, default_ms):
test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id)
# create sequential to test against
- sequential = self.store.create_child(self.user_id, test_course.location, 'sequential', 'test_sequential')
+ sequential = self.store.create_child(self.user_id, test_course.usage_key, 'sequential', 'test_sequential')
event_receiver.assert_called()
assert event_receiver.call_args.kwargs['signal'] == XBLOCK_CREATED
- assert event_receiver.call_args.kwargs['xblock_info'].usage_key == sequential.location
- assert event_receiver.call_args.kwargs['xblock_info'].block_type == sequential.location.block_type
- assert event_receiver.call_args.kwargs['xblock_info'].version.for_branch(None) == sequential.location
+ assert event_receiver.call_args.kwargs['xblock_info'].usage_key == sequential.usage_key
+ assert event_receiver.call_args.kwargs['xblock_info'].block_type == sequential.usage_key.block_type
+ assert event_receiver.call_args.kwargs['xblock_info'].version.for_branch(None) == sequential.usage_key
@ddt.data(ModuleStoreEnum.Type.split)
def test_xblock_update_event(self, default_ms):
@@ -861,7 +861,7 @@ def test_xblock_update_event(self, default_ms):
test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id)
# create sequential to test against
- sequential = self.store.create_child(self.user_id, test_course.location, 'sequential', 'test_sequential')
+ sequential = self.store.create_child(self.user_id, test_course.usage_key, 'sequential', 'test_sequential')
# Change the xblock
sequential.display_name = 'Updated Display Name'
@@ -870,9 +870,9 @@ def test_xblock_update_event(self, default_ms):
event_receiver.assert_called()
assert event_receiver.call_args.kwargs['signal'] == XBLOCK_UPDATED
- assert event_receiver.call_args.kwargs['xblock_info'].usage_key == sequential.location
- assert event_receiver.call_args.kwargs['xblock_info'].block_type == sequential.location.block_type
- assert event_receiver.call_args.kwargs['xblock_info'].version.for_branch(None) == sequential.location
+ assert event_receiver.call_args.kwargs['xblock_info'].usage_key == sequential.usage_key
+ assert event_receiver.call_args.kwargs['xblock_info'].block_type == sequential.usage_key.block_type
+ assert event_receiver.call_args.kwargs['xblock_info'].version.for_branch(None) == sequential.usage_key
@ddt.data(ModuleStoreEnum.Type.split)
def test_xblock_publish_event(self, default_ms):
@@ -886,11 +886,11 @@ def test_xblock_publish_event(self, default_ms):
test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id)
# create sequential and vertical to test against
- sequential = self.store.create_child(self.user_id, test_course.location, 'sequential', 'test_sequential')
- self.store.create_child(self.user_id, sequential.location, 'vertical', 'test_vertical')
+ sequential = self.store.create_child(self.user_id, test_course.usage_key, 'sequential', 'test_sequential')
+ self.store.create_child(self.user_id, sequential.usage_key, 'vertical', 'test_vertical')
# publish sequential changes
- self.store.publish(sequential.location, self.user_id)
+ self.store.publish(sequential.usage_key, self.user_id)
event_receiver.assert_called()
assert_dict_contains_subset(
@@ -899,8 +899,8 @@ def test_xblock_publish_event(self, default_ms):
"signal": XBLOCK_PUBLISHED,
"sender": None,
"xblock_info": XBlockData(
- usage_key=sequential.location,
- block_type=sequential.location.block_type,
+ usage_key=sequential.usage_key,
+ block_type=sequential.usage_key.block_type,
),
},
event_receiver.call_args.kwargs,
@@ -918,14 +918,14 @@ def test_xblock_delete_event(self, default_ms):
test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id)
# create sequential and vertical to test against
- sequential = self.store.create_child(self.user_id, test_course.location, 'sequential', 'test_sequential')
- vertical = self.store.create_child(self.user_id, sequential.location, 'vertical', 'test_vertical')
+ sequential = self.store.create_child(self.user_id, test_course.usage_key, 'sequential', 'test_sequential')
+ vertical = self.store.create_child(self.user_id, sequential.usage_key, 'vertical', 'test_vertical')
# publish sequential changes
- self.store.publish(sequential.location, self.user_id)
+ self.store.publish(sequential.usage_key, self.user_id)
# delete vertical
- self.store.delete_item(vertical.location, self.user_id)
+ self.store.delete_item(vertical.usage_key, self.user_id)
event_receiver.assert_called()
assert_dict_contains_subset(
@@ -934,8 +934,8 @@ def test_xblock_delete_event(self, default_ms):
"signal": XBLOCK_DELETED,
"sender": None,
"xblock_info": XBlockData(
- usage_key=vertical.location,
- block_type=vertical.location.block_type,
+ usage_key=vertical.usage_key,
+ block_type=vertical.usage_key.block_type,
),
},
event_receiver.call_args.kwargs,
@@ -1078,23 +1078,23 @@ def test_has_changes_non_direct_only_children(self, default_ms):
)
child = self.store.create_child(
self.user_id,
- parent.location,
+ parent.usage_key,
'html',
block_id='child',
)
- self.store.publish(parent.location, self.user_id)
+ self.store.publish(parent.usage_key, self.user_id)
# Verify that there are no changes
- assert not self._has_changes(parent.location)
- assert not self._has_changes(child.location)
+ assert not self._has_changes(parent.usage_key)
+ assert not self._has_changes(child.usage_key)
# Change the child
child.display_name = 'Changed Display Name'
self.store.update_item(child, user_id=self.user_id)
# Verify that both parent and child have changes
- assert self._has_changes(parent.location)
- assert self._has_changes(child.location)
+ assert self._has_changes(parent.usage_key)
+ assert self._has_changes(child.usage_key)
@ddt.data(*itertools.product(
(ModuleStoreEnum.Type.split,),
@@ -1165,17 +1165,17 @@ def test_delete_private_vertical(self, default_ms, num_mysql, max_find, max_send
)
private_leaf = self.store.create_child(
# don't use course_location as it may not be the repr
- self.user_id, private_vert.location, 'html', block_id='private_leaf'
+ self.user_id, private_vert.usage_key, 'html', block_id='private_leaf'
)
# verify pre delete state (just to verify that the test is valid)
- if hasattr(private_vert.location, 'version_guid'):
+ if hasattr(private_vert.usage_key, 'version_guid'):
# change to the HEAD version
- vert_loc = private_vert.location.for_version(private_leaf.location.version_guid)
+ vert_loc = private_vert.usage_key.for_version(private_leaf.usage_key.version_guid)
else:
- vert_loc = private_vert.location
+ vert_loc = private_vert.usage_key
assert self.store.has_item(vert_loc)
- assert self.store.has_item(private_leaf.location)
+ assert self.store.has_item(private_leaf.usage_key)
course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key, 0)
assert vert_loc in course.children
@@ -1183,13 +1183,13 @@ def test_delete_private_vertical(self, default_ms, num_mysql, max_find, max_send
with check_mongo_calls(max_find, max_send), self.assertNumQueries(num_mysql):
self.store.delete_item(vert_loc, self.user_id)
course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key, 0)
- if hasattr(private_vert.location, 'version_guid'):
+ if hasattr(private_vert.usage_key, 'version_guid'):
# change to the HEAD version
- vert_loc = private_vert.location.for_version(course.location.version_guid)
- leaf_loc = private_leaf.location.for_version(course.location.version_guid)
+ vert_loc = private_vert.usage_key.for_version(course.usage_key.version_guid)
+ leaf_loc = private_leaf.usage_key.for_version(course.usage_key.version_guid)
else:
- vert_loc = private_vert.location
- leaf_loc = private_leaf.location
+ vert_loc = private_vert.usage_key
+ leaf_loc = private_leaf.usage_key
assert not self.store.has_item(vert_loc)
assert not self.store.has_item(leaf_loc)
assert vert_loc not in course.children
@@ -1214,23 +1214,23 @@ def test_delete_draft_vertical(self, default_ms, num_mysql, max_find, max_send):
self.user_id, self.course_locations[self.MONGO_COURSEID], 'vertical', block_id='publish'
)
private_leaf = self.store.create_child(
- self.user_id, private_vert.location, 'html', block_id='bug_leaf'
+ self.user_id, private_vert.usage_key, 'html', block_id='bug_leaf'
)
# verify that an error is raised when the revision is not valid
with pytest.raises(UnsupportedRevisionError):
self.store.delete_item(
- private_leaf.location,
+ private_leaf.usage_key,
self.user_id,
revision=ModuleStoreEnum.RevisionOption.draft_preferred
)
- self.store.publish(private_vert.location, self.user_id)
+ self.store.publish(private_vert.usage_key, self.user_id)
private_leaf.display_name = 'change me'
private_leaf = self.store.update_item(private_leaf, self.user_id)
# test succeeds if delete succeeds w/o error
with check_mongo_calls(max_find, max_send), self.assertNumQueries(num_mysql):
- self.store.delete_item(private_leaf.location, self.user_id)
+ self.store.delete_item(private_leaf.usage_key, self.user_id)
# Split:
# mysql: 3 selects on SplitModulestoreCourseIndex - 1 to get all courses, 2 to get specific course (this query is
@@ -1244,7 +1244,7 @@ def test_get_courses(self, default_ms, num_mysql, max_find, max_send):
# we should have one course across all stores
with check_mongo_calls(max_find, max_send), self.assertNumQueries(num_mysql):
courses = self.store.get_courses()
- course_ids = [course.location for course in courses]
+ course_ids = [course.usage_key for course in courses]
assert len(courses) == 1, f'Not one course: {course_ids}'
assert self.course_locations[self.MONGO_COURSEID] in course_ids
@@ -1267,7 +1267,7 @@ def test_create_child_detached_tabs(self, default_ms):
# create a static tab of the course
self.store.create_child(
self.user_id,
- self.course.location,
+ self.course.usage_key,
'static_tab'
)
@@ -1298,16 +1298,16 @@ def test_get_library(self, default_ms):
self.initdb(default_ms)
with self.store.default_store(ModuleStoreEnum.Type.split): # The CMS also wraps create_library like this
library = self.store.create_library("org", "lib", self.user_id, {"display_name": "Test Library"})
- library_key = library.location.library_key
+ library_key = library.usage_key.library_key
assert isinstance(library_key, LibraryLocator)
# Now load with get_library and make sure it works:
library = self.store.get_library(library_key)
- assert library.location.library_key == library_key
+ assert library.usage_key.library_key == library_key
# Clear the mappings so we can test get_library code path without mapping set:
self.store.mappings.clear()
library = self.store.get_library(library_key)
- assert library.location.library_key == library_key
+ assert library.usage_key.library_key == library_key
# notice this doesn't test getting a public item via draft_preferred which draft would have 2 hits (split
# still only 2)
@@ -1348,7 +1348,7 @@ def verify_item_parent(self, item_location, expected_parent_location, old_parent
old_parent = self.store.get_item(old_parent_location)
expected_parent = self.store.get_item(expected_parent_location)
- assert expected_parent_location == source_item.get_parent().location
+ assert expected_parent_location == source_item.get_parent().usage_key
# If an item is reverted, it means it's actual parent was the one that is the current parent now
# i.e expected_parent_location otherwise old_parent_location.
@@ -1356,9 +1356,9 @@ def verify_item_parent(self, item_location, expected_parent_location, old_parent
# Check parent locations wrt branches
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
- assert expected_parent_location == self.store.get_item(item_location).get_parent().location
+ assert expected_parent_location == self.store.get_item(item_location).get_parent().usage_key
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- assert published_parent_location == self.store.get_item(item_location).get_parent().location
+ assert published_parent_location == self.store.get_item(item_location).get_parent().usage_key
# Make location specific to published branch for verify_get_parent_locations_results call.
published_parent_location = published_parent_location.for_branch(ModuleStoreEnum.BranchName.published)
@@ -1387,7 +1387,7 @@ def test_update_item_parent(self, store_type):
self._create_block_hierarchy()
# Publish the course.
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1414,7 +1414,7 @@ def test_move_revert(self, store_type):
self._create_block_hierarchy()
# Publish the course
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1451,7 +1451,7 @@ def test_move_delete_revert(self, store_type):
self._create_block_hierarchy()
# Publish the course
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1492,7 +1492,7 @@ def test_move_revert_move(self, store_type):
self._create_block_hierarchy()
# Publish the course
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1541,7 +1541,7 @@ def test_move_edited_revert(self, store_type):
self._create_block_hierarchy()
# Publish the course.
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1590,7 +1590,7 @@ def test_move_1_moved_1_unchanged(self, store_type):
problem_item2 = self.store.create_child(self.user_id, self.vertical_x1a, 'problem', 'Problem_Item2') # lint-amnesty, pylint: disable=no-member
# Publish the course.
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
new_parent_location = self.vertical_y1a # lint-amnesty, pylint: disable=no-member
@@ -1609,9 +1609,9 @@ def test_move_1_moved_1_unchanged(self, store_type):
)
# Check that problem_item2 is still present in vertical_x1a
- problem_item2 = self.store.get_item(problem_item2.location)
+ problem_item2 = self.store.get_item(problem_item2.usage_key)
assert problem_item2.parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
- assert problem_item2.location in problem_item2.get_parent().children
+ assert problem_item2.usage_key in problem_item2.get_parent().children
@ddt.data(ModuleStoreEnum.Type.split)
def test_move_1_moved_1_edited(self, store_type):
@@ -1628,13 +1628,13 @@ def test_move_1_moved_1_edited(self, store_type):
orig_display_name = problem_item2.display_name
# Publish the course.
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Edit problem_item2.
problem_item2.display_name = 'updated'
self.store.update_item(problem_item2, self.user_id)
- updated_problem2 = self.store.get_item(problem_item2.location)
+ updated_problem2 = self.store.get_item(problem_item2.usage_key)
assert updated_problem2.display_name == 'updated'
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1657,7 +1657,7 @@ def test_move_1_moved_1_edited(self, store_type):
self.store.revert_to_published(old_parent_location, self.user_id)
# Check that problem_item2 has the original name back.
- reverted_problem2 = self.store.get_item(problem_item2.location)
+ reverted_problem2 = self.store.get_item(problem_item2.usage_key)
assert orig_display_name == reverted_problem2.display_name
@ddt.data(ModuleStoreEnum.Type.split)
@@ -1675,10 +1675,10 @@ def test_move_1_moved_1_deleted(self, store_type):
orig_display_name = problem_item2.display_name # lint-amnesty, pylint: disable=unused-variable
# Publish the course.
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
# Now delete other problem problem_item2.
- self.store.delete_item(problem_item2.location, self.user_id)
+ self.store.delete_item(problem_item2.usage_key, self.user_id)
# Move child problem_x1a_1 to vertical_y1a.
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
@@ -1701,9 +1701,9 @@ def test_move_1_moved_1_deleted(self, store_type):
self.store.revert_to_published(old_parent_location, self.user_id)
# Check that problem_item2 is also back in vertical_x1a
- problem_item2 = self.store.get_item(problem_item2.location)
+ problem_item2 = self.store.get_item(problem_item2.usage_key)
assert problem_item2.parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
- assert problem_item2.location in problem_item2.get_parent().children
+ assert problem_item2.usage_key in problem_item2.get_parent().children
@ddt.data(ModuleStoreEnum.Type.split)
def test_get_parent_locations_moved_child(self, default_ms):
@@ -1711,7 +1711,7 @@ def test_get_parent_locations_moved_child(self, default_ms):
self._create_block_hierarchy()
# publish the course
- self.course = self.store.publish(self.course.location, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.course = self.store.publish(self.course.usage_key, self.user_id) # lint-amnesty, pylint: disable=attribute-defined-outside-init
with self.store.bulk_operations(self.course.id):
# make drafts of verticals
@@ -1726,9 +1726,9 @@ def test_get_parent_locations_moved_child(self, default_ms):
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
old_parent = self.store.get_item(child_to_move_location).get_parent()
- assert old_parent_location == old_parent.location
+ assert old_parent_location == old_parent.usage_key
- child_to_move_contextualized = child_to_move_location.map_into_course(old_parent.location.course_key)
+ child_to_move_contextualized = child_to_move_location.map_into_course(old_parent.usage_key.course_key)
old_parent.children.remove(child_to_move_contextualized)
self.store.update_item(old_parent, self.user_id)
@@ -1737,9 +1737,9 @@ def test_get_parent_locations_moved_child(self, default_ms):
self.store.update_item(new_parent, self.user_id)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
- assert new_parent_location == self.store.get_item(child_to_move_location).get_parent().location
+ assert new_parent_location == self.store.get_item(child_to_move_location).get_parent().usage_key
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- assert old_parent_location == self.store.get_item(child_to_move_location).get_parent().location
+ assert old_parent_location == self.store.get_item(child_to_move_location).get_parent().usage_key
old_parent_published_location = old_parent_location.for_branch(ModuleStoreEnum.BranchName.published)
self.verify_get_parent_locations_results([
(child_to_move_location, new_parent_location, None),
@@ -1748,7 +1748,7 @@ def test_get_parent_locations_moved_child(self, default_ms):
])
# publish the course again
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
new_parent_published_location = new_parent_location.for_branch(ModuleStoreEnum.BranchName.published)
self.verify_get_parent_locations_results([
(child_to_move_location, new_parent_location, None),
@@ -1825,7 +1825,7 @@ def test_revert_to_published_root_draft(self, default_ms):
vertical = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
vertical_children_num = len(vertical.children)
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
assert not self._has_changes(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
# delete leaf problem (will make parent vertical a draft)
@@ -1853,7 +1853,7 @@ def test_revert_to_published_root_published(self, default_ms):
"""
self.initdb(default_ms)
self._create_block_hierarchy()
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
problem = self.store.get_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
orig_display_name = problem.display_name
@@ -1873,7 +1873,7 @@ def test_revert_to_published_no_draft(self, default_ms):
"""
self.initdb(default_ms)
self._create_block_hierarchy()
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
orig_vertical = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.store.revert_to_published(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
@@ -1911,7 +1911,7 @@ def test_reset_course_to_version(self):
# Set up test course.
self.initdb(ModuleStoreEnum.Type.split) # Old Mongo does not support this operation.
self._create_block_hierarchy()
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
# Get children of a vertical as a set.
# We will use this set as a basis for content comparision in this test.
@@ -1920,14 +1920,14 @@ def test_reset_course_to_version(self):
# Find the version_guid of our course by diving into Split Mongo.
split = self._get_split_modulestore()
- course_index = split.get_course_index(self.course.location.course_key)
+ course_index = split.get_course_index(self.course.usage_key.course_key)
log.warning(f"Banana course index: {course_index}")
original_version_guid = course_index["versions"]["published-branch"]
# Reset course to currently-published version.
# This should be a no-op.
self.store.reset_course_to_version(
- self.course.location.course_key,
+ self.course.usage_key.course_key,
original_version_guid,
self.user_id,
)
@@ -1937,7 +1937,7 @@ def test_reset_course_to_version(self):
# Delete a problem from the vertical and publish.
# Vertical should have one less problem than before.
self.store.delete_item(self.problem_x1a_1, self.user_id) # lint-amnesty, pylint: disable=no-member
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
modified_vertical = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
assert set(modified_vertical.children) == (
original_vertical_children - {self.problem_x1a_1} # lint-amnesty, pylint: disable=no-member
@@ -1952,14 +1952,14 @@ def test_reset_course_to_version(self):
'problem',
block_id='new_child1',
)
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
self.store.create_child(
self.user_id,
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
'problem',
block_id='new_child2',
)
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
# Add another child, but don't publish.
# We want to make sure that this works with a dirty draft branch.
@@ -1973,7 +1973,7 @@ def test_reset_course_to_version(self):
# Reset course to original version.
# The restored vertical should have the same children as it did originally.
self.store.reset_course_to_version(
- self.course.location.course_key,
+ self.course.usage_key.course_key,
original_version_guid,
self.user_id,
)
@@ -2039,7 +2039,7 @@ def test_create_item_populates_edited_info(self, default_ms):
self.initdb(default_ms)
block = self.store.create_item(
self.user_id,
- self.course.location.course_key,
+ self.course.usage_key.course_key,
'problem'
)
assert self.user_id == block.edited_by
@@ -2050,7 +2050,7 @@ def test_create_item_populates_subtree_edited_info(self, default_ms):
self.initdb(default_ms)
block = self.store.create_item(
self.user_id,
- self.course.location.course_key,
+ self.course.usage_key.course_key,
'problem'
)
assert self.user_id == block.subtree_edited_by
@@ -2092,7 +2092,7 @@ def test_unpublish(self, default_ms, num_mysql, max_find, max_send):
self._create_block_hierarchy()
# publish
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
published_xblock = self.store.get_item(
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
revision=ModuleStoreEnum.RevisionOption.published_only
@@ -2128,7 +2128,7 @@ def test_has_published_version(self, default_ms, mysql_queries, max_find, max_se
# start off as Private
item = self.store.create_child(self.user_id, self.writable_chapter_location, 'problem', 'test_compute_publish_state') # lint-amnesty, pylint: disable=line-too-long
- item_location = item.location
+ item_location = item.usage_key
with self.assertNumQueries(mysql_queries), check_mongo_calls(max_find, max_send):
assert not self.store.has_published_version(item)
@@ -2185,19 +2185,19 @@ def check_node(location_key, after, before, edited_by, subtree_after, subtree_be
# Create a dummy vertical & html to test against
component = self.store.create_child(
self.user_id,
- test_course.location,
+ test_course.usage_key,
'vertical',
block_id='test_vertical'
)
child = self.store.create_child(
self.user_id,
- component.location,
+ component.usage_key,
'html',
block_id='test_html'
)
sibling = self.store.create_child(
self.user_id,
- component.location,
+ component.usage_key,
'html',
block_id='test_html_no_change'
)
@@ -2205,7 +2205,7 @@ def check_node(location_key, after, before, edited_by, subtree_after, subtree_be
after_create = datetime.datetime.now(ZoneInfo("UTC"))
# Verify that all nodes were last edited in the past by create_user
for block in [component, child, sibling]:
- check_node(block.location, None, after_create, self.user_id, None, after_create, self.user_id)
+ check_node(block.usage_key, None, after_create, self.user_id, None, after_create, self.user_id)
# Change the component, then check that there now are changes
component.display_name = 'Changed Display Name'
@@ -2214,25 +2214,25 @@ def check_node(location_key, after, before, edited_by, subtree_after, subtree_be
with self.store.bulk_operations(test_course.id): # TNL-764 bulk ops disabled ancestor updates
component = self.store.update_item(component, editing_user)
after_edit = datetime.datetime.now(ZoneInfo("UTC"))
- check_node(component.location, after_create, after_edit, editing_user, after_create, after_edit, editing_user)
+ check_node(component.usage_key, after_create, after_edit, editing_user, after_create, after_edit, editing_user)
# but child didn't change
- check_node(child.location, None, after_create, self.user_id, None, after_create, self.user_id)
+ check_node(child.usage_key, None, after_create, self.user_id, None, after_create, self.user_id)
# Change the child
- child = self.store.get_item(child.location)
+ child = self.store.get_item(child.usage_key)
child.display_name = 'Changed Display Name'
self.store.update_item(child, user_id=editing_user)
after_edit = datetime.datetime.now(ZoneInfo("UTC"))
# Verify that child was last edited between after_create and after_edit by edit_user
- check_node(child.location, after_create, after_edit, editing_user, after_create, after_edit, editing_user)
+ check_node(child.usage_key, after_create, after_edit, editing_user, after_create, after_edit, editing_user)
# Verify that ancestors edit info is unchanged, but their subtree edit info matches child
- check_node(test_course.location, None, after_create, self.user_id, after_create, after_edit, editing_user)
+ check_node(test_course.usage_key, None, after_create, self.user_id, after_create, after_edit, editing_user)
# Verify that others have unchanged edit info
- check_node(sibling.location, None, after_create, self.user_id, None, after_create, self.user_id)
+ check_node(sibling.usage_key, None, after_create, self.user_id, None, after_create, self.user_id)
@ddt.data(ModuleStoreEnum.Type.split)
def test_update_edit_info(self, default_ms):
@@ -2246,7 +2246,7 @@ def test_update_edit_info(self, default_ms):
# Create a dummy component to test against
component = self.store.create_child(
self.user_id,
- test_course.location,
+ test_course.usage_key,
'vertical',
)
@@ -2258,7 +2258,7 @@ def test_update_edit_info(self, default_ms):
# Change the component
component.display_name = 'Changed'
self.store.update_item(component, edit_user)
- updated_component = self.store.get_item(component.location)
+ updated_component = self.store.get_item(component.usage_key)
# Verify the ordering of edit times and that dummy_user made the edit
assert old_edited_on < updated_component.edited_on
@@ -2278,14 +2278,14 @@ def test_update_published_info(self, default_ms):
# Create a dummy component to test against
component = self.store.create_child(
self.user_id,
- test_course.location,
+ test_course.usage_key,
'vertical',
)
# Store the current time, then publish
old_time = datetime.datetime.now(ZoneInfo("UTC"))
- self.store.publish(component.location, publish_user)
- updated_component = self.store.get_item(component.location)
+ self.store.publish(component.usage_key, publish_user)
+ updated_component = self.store.get_item(component.usage_key)
# Verify the time order and that publish_user caused publication
assert old_time <= updated_component.published_on
@@ -2294,7 +2294,7 @@ def test_update_published_info(self, default_ms):
# Verify that changing the item doesn't unset the published info
updated_component.display_name = 'changed'
self.store.update_item(updated_component, self.user_id)
- updated_component = self.store.get_item(updated_component.location)
+ updated_component = self.store.get_item(updated_component.usage_key)
assert old_time <= updated_component.published_on
assert updated_component.published_by == publish_user
@@ -2316,17 +2316,17 @@ def test_auto_publish(self, default_ms):
test_course_key = test_course.id
# test create_item of direct-only category to make sure we are autopublishing
- chapter = self.store.create_child(self.user_id, test_course.location, 'chapter', 'Overview')
+ chapter = self.store.create_child(self.user_id, test_course.usage_key, 'chapter', 'Overview')
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- assert chapter.location in self.store.get_item(test_course.location).children
+ assert chapter.usage_key in self.store.get_item(test_course.usage_key).children
assert self.store.has_published_version(chapter)
- chapter_location = chapter.location
+ chapter_location = chapter.usage_key
# test create_child of direct-only category to make sure we are autopublishing
sequential = self.store.create_child(self.user_id, chapter_location, 'sequential', 'Sequence')
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- assert sequential.location in self.store.get_item(chapter_location).children
+ assert sequential.usage_key in self.store.get_item(chapter_location).children
assert self.store.has_published_version(sequential)
# test update_item of direct-only category to make sure we are autopublishing
@@ -2335,10 +2335,10 @@ def test_auto_publish(self, default_ms):
assert self.store.has_published_version(sequential)
# test delete_item of direct-only category to make sure we are autopublishing
- self.store.delete_item(sequential.location, self.user_id, revision=ModuleStoreEnum.RevisionOption.all)
+ self.store.delete_item(sequential.usage_key, self.user_id, revision=ModuleStoreEnum.RevisionOption.all)
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- assert sequential.location not in self.store.get_item(chapter_location).children
- chapter = self.store.get_item(chapter.location.for_branch(None))
+ assert sequential.usage_key not in self.store.get_item(chapter_location).children
+ chapter = self.store.get_item(chapter.usage_key.for_branch(None))
assert self.store.has_published_version(chapter)
# test create_child of NOT direct-only category to make sure we aren't autopublishing
@@ -2355,8 +2355,8 @@ def test_auto_publish(self, default_ms):
assert not self.store.has_published_version(problem_item)
# test delete_item of NOT direct-only category to make sure we aren't autopublishing
- self.store.delete_item(problem_child.location, self.user_id)
- chapter = self.store.get_item(chapter.location.for_branch(None))
+ self.store.delete_item(problem_child.usage_key, self.user_id)
+ chapter = self.store.get_item(chapter.usage_key.for_branch(None))
assert self.store.has_published_version(chapter)
@ddt.data(ModuleStoreEnum.Type.split)
@@ -2644,7 +2644,7 @@ def test_course_publish_signal_direct_firing(self, default):
signal_handler.send.assert_called_with('course_published', course_key=course.id)
signal_handler.reset_mock()
- self.store.publish(block.location, self.user_id)
+ self.store.publish(block.usage_key, self.user_id)
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@ddt.data(ModuleStoreEnum.Type.split)
@@ -2740,30 +2740,30 @@ def test_course_publish_signal_publish_firing(self, default):
signal_handler.send.assert_called_with('course_published', course_key=course.id)
signal_handler.reset_mock()
- subsection = self.store.create_child(self.user_id, section.location, 'sequential')
+ subsection = self.store.create_child(self.user_id, section.usage_key, 'sequential')
signal_handler.send.assert_called_with('course_published', course_key=course.id)
# 'units' and 'blocks' are draftable types
signal_handler.reset_mock()
- unit = self.store.create_child(self.user_id, subsection.location, 'vertical')
+ unit = self.store.create_child(self.user_id, subsection.usage_key, 'vertical')
signal_handler.send.assert_not_called()
- block = self.store.create_child(self.user_id, unit.location, 'problem')
+ block = self.store.create_child(self.user_id, unit.usage_key, 'problem')
signal_handler.send.assert_not_called()
self.store.update_item(block, self.user_id)
signal_handler.send.assert_not_called()
signal_handler.reset_mock()
- self.store.publish(unit.location, self.user_id)
+ self.store.publish(unit.usage_key, self.user_id)
signal_handler.send.assert_called_with('course_published', course_key=course.id)
signal_handler.reset_mock()
- self.store.unpublish(unit.location, self.user_id)
+ self.store.unpublish(unit.usage_key, self.user_id)
signal_handler.send.assert_called_with('course_published', course_key=course.id)
signal_handler.reset_mock()
- self.store.delete_item(unit.location, self.user_id)
+ self.store.delete_item(unit.usage_key, self.user_id)
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@ddt.data(ModuleStoreEnum.Type.split)
@@ -2803,7 +2803,7 @@ def test_bulk_course_publish_signal_direct_firing(self, default):
self.store.update_item(block, self.user_id)
signal_handler.send.assert_not_called()
- self.store.publish(block.location, self.user_id)
+ self.store.publish(block.usage_key, self.user_id)
signal_handler.send.assert_not_called()
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@@ -2840,20 +2840,20 @@ def test_bulk_course_publish_signal_publish_firing(self, default):
section = self.store.create_item(self.user_id, course_key, 'chapter')
signal_handler.send.assert_not_called()
- subsection = self.store.create_child(self.user_id, section.location, 'sequential')
+ subsection = self.store.create_child(self.user_id, section.usage_key, 'sequential')
signal_handler.send.assert_not_called()
# 'units' and 'blocks' are draftable types
- unit = self.store.create_child(self.user_id, subsection.location, 'vertical')
+ unit = self.store.create_child(self.user_id, subsection.usage_key, 'vertical')
signal_handler.send.assert_not_called()
- block = self.store.create_child(self.user_id, unit.location, 'problem')
+ block = self.store.create_child(self.user_id, unit.usage_key, 'problem')
signal_handler.send.assert_not_called()
self.store.update_item(block, self.user_id)
signal_handler.send.assert_not_called()
- self.store.publish(unit.location, self.user_id)
+ self.store.publish(unit.usage_key, self.user_id)
signal_handler.send.assert_not_called()
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@@ -2861,11 +2861,11 @@ def test_bulk_course_publish_signal_publish_firing(self, default):
# Test editing draftable block type without publish
signal_handler.reset_mock()
with self.store.bulk_operations(course_key):
- unit = self.store.create_child(self.user_id, subsection.location, 'vertical')
+ unit = self.store.create_child(self.user_id, subsection.usage_key, 'vertical')
signal_handler.send.assert_not_called()
- block = self.store.create_child(self.user_id, unit.location, 'problem')
+ block = self.store.create_child(self.user_id, unit.usage_key, 'problem')
signal_handler.send.assert_not_called()
- self.store.publish(unit.location, self.user_id)
+ self.store.publish(unit.usage_key, self.user_id)
signal_handler.send.assert_not_called()
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@@ -2914,32 +2914,32 @@ def test_delete_published_item_orphans(self, default_store):
course_locator = self.course.id
chapter = self.store.create_child(
- self.user_id, self.course.location, 'chapter', block_id='section_one'
+ self.user_id, self.course.usage_key, 'chapter', block_id='section_one'
)
sequential = self.store.create_child(
- self.user_id, chapter.location, 'sequential', block_id='subsection_one'
+ self.user_id, chapter.usage_key, 'sequential', block_id='subsection_one'
)
vertical = self.store.create_child(
- self.user_id, sequential.location, 'vertical', block_id='moon_unit'
+ self.user_id, sequential.usage_key, 'vertical', block_id='moon_unit'
)
problem = self.store.create_child(
- self.user_id, vertical.location, 'problem', block_id='problem'
+ self.user_id, vertical.usage_key, 'problem', block_id='problem'
)
- self.store.publish(chapter.location, self.user_id)
+ self.store.publish(chapter.usage_key, self.user_id)
# Verify that there are no changes
- assert not self._has_changes(chapter.location)
- assert not self._has_changes(sequential.location)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(problem.location)
+ assert not self._has_changes(chapter.usage_key)
+ assert not self._has_changes(sequential.usage_key)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(problem.usage_key)
# No orphans in course
course_orphans = self.store.get_orphans(course_locator)
assert len(course_orphans) == 0
- self.store.delete_item(vertical.location, self.user_id)
+ self.store.delete_item(vertical.usage_key, self.user_id)
# No orphans in course after delete, except
# in old mongo, which still creates orphans
@@ -2968,27 +2968,27 @@ def test_delete_draft_item_orphans(self, default_store):
course_locator = self.course.id
chapter = self.store.create_child(
- self.user_id, self.course.location, 'chapter', block_id='section_one'
+ self.user_id, self.course.usage_key, 'chapter', block_id='section_one'
)
sequential = self.store.create_child(
- self.user_id, chapter.location, 'sequential', block_id='subsection_one'
+ self.user_id, chapter.usage_key, 'sequential', block_id='subsection_one'
)
vertical = self.store.create_child(
- self.user_id, sequential.location, 'vertical', block_id='moon_unit'
+ self.user_id, sequential.usage_key, 'vertical', block_id='moon_unit'
)
problem = self.store.create_child(
- self.user_id, vertical.location, 'problem', block_id='problem'
+ self.user_id, vertical.usage_key, 'problem', block_id='problem'
)
- self.store.publish(chapter.location, self.user_id)
+ self.store.publish(chapter.usage_key, self.user_id)
# Verify that there are no changes
- assert not self._has_changes(chapter.location)
- assert not self._has_changes(sequential.location)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(problem.location)
+ assert not self._has_changes(chapter.usage_key)
+ assert not self._has_changes(sequential.usage_key)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(problem.usage_key)
# No orphans in course
course_orphans = self.store.get_orphans(course_locator)
@@ -2996,10 +2996,10 @@ def test_delete_draft_item_orphans(self, default_store):
problem.display_name = 'changed'
problem = self.store.update_item(problem, self.user_id)
- assert self._has_changes(vertical.location)
- assert self._has_changes(problem.location)
+ assert self._has_changes(vertical.usage_key)
+ assert self._has_changes(problem.usage_key)
- self.store.delete_item(vertical.location, self.user_id)
+ self.store.delete_item(vertical.usage_key, self.user_id)
# No orphans in course after delete, except
# in old mongo, which still creates them
course_orphans = self.store.get_orphans(course_locator)
@@ -3089,14 +3089,14 @@ def test_draft_has_changes_before_export_and_after_import(self, default_ms):
block_id='test_vertical'
)
# Not yet published, so changes are present
- assert self._has_changes(draft_xblock.location)
+ assert self._has_changes(draft_xblock.usage_key)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
)
# Verify that the imported block still is a draft, i.e. has changes.
- assert self._has_changes(draft_xblock.location)
+ assert self._has_changes(draft_xblock.usage_key)
@ddt.data(ModuleStoreEnum.Type.split)
def test_published_has_changes_before_export_and_after_import(self, default_ms):
@@ -3112,10 +3112,10 @@ def test_published_has_changes_before_export_and_after_import(self, default_ms):
'vertical',
block_id='test_vertical'
)
- self.store.publish(published_xblock.location, self.user_id)
+ self.store.publish(published_xblock.usage_key, self.user_id)
# Retrieve the published block and make sure it's published.
- assert not self._has_changes(published_xblock.location)
+ assert not self._has_changes(published_xblock.usage_key)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
@@ -3123,7 +3123,7 @@ def test_published_has_changes_before_export_and_after_import(self, default_ms):
# Get the published xblock from the imported course.
# Verify that it still is published, i.e. has no changes.
- assert not self._has_changes(published_xblock.location)
+ assert not self._has_changes(published_xblock.usage_key)
@ddt.data(ModuleStoreEnum.Type.split)
def test_changed_published_has_changes_before_export_and_after_import(self, default_ms):
@@ -3139,13 +3139,13 @@ def test_changed_published_has_changes_before_export_and_after_import(self, defa
'vertical',
block_id='test_vertical'
)
- self.store.publish(published_xblock.location, self.user_id)
+ self.store.publish(published_xblock.usage_key, self.user_id)
# Retrieve the published block and make sure it's published.
- assert not self._has_changes(published_xblock.location)
+ assert not self._has_changes(published_xblock.usage_key)
updated_display_name = 'Changed Display Name'
- component = self.store.get_item(published_xblock.location)
+ component = self.store.get_item(published_xblock.usage_key)
component.display_name = updated_display_name
component = self.store.update_item(component, self.user_id)
assert self.store.has_changes(component)
@@ -3156,11 +3156,11 @@ def test_changed_published_has_changes_before_export_and_after_import(self, defa
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
- assert self._has_changes(published_xblock.location)
+ assert self._has_changes(published_xblock.usage_key)
# Verify that the changes in the draft vertical still exist.
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, source_course_key):
- component = self.store.get_item(published_xblock.location)
+ component = self.store.get_item(published_xblock.usage_key)
assert component.display_name == updated_display_name
@ddt.data(ModuleStoreEnum.Type.split)
@@ -3172,28 +3172,28 @@ def test_seq_with_unpublished_vertical_has_changes_before_export_and_after_impor
# create chapter
chapter = self.store.create_child(
- self.user_id, self.course.location, 'chapter', block_id='section_one'
+ self.user_id, self.course.usage_key, 'chapter', block_id='section_one'
)
- self.store.publish(chapter.location, self.user_id)
+ self.store.publish(chapter.usage_key, self.user_id)
# create sequential
sequential = self.store.create_child(
- self.user_id, chapter.location, 'sequential', block_id='subsection_one'
+ self.user_id, chapter.usage_key, 'sequential', block_id='subsection_one'
)
- self.store.publish(sequential.location, self.user_id)
+ self.store.publish(sequential.usage_key, self.user_id)
# create vertical - don't publish it!
vertical = self.store.create_child(
- self.user_id, sequential.location, 'vertical', block_id='moon_unit'
+ self.user_id, sequential.usage_key, 'vertical', block_id='moon_unit'
)
# Retrieve the published block and make sure it's published.
# Chapter is published - but the changes in vertical below means it "has_changes".
- assert self._has_changes(chapter.location)
+ assert self._has_changes(chapter.usage_key)
# Sequential is published - but the changes in vertical below means it "has_changes".
- assert self._has_changes(sequential.location)
+ assert self._has_changes(sequential.usage_key)
# Vertical is unpublished - so it "has_changes".
- assert self._has_changes(vertical.location)
+ assert self._has_changes(vertical.usage_key)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
@@ -3201,9 +3201,9 @@ def test_seq_with_unpublished_vertical_has_changes_before_export_and_after_impor
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
- assert self._has_changes(chapter.location)
- assert self._has_changes(sequential.location)
- assert self._has_changes(vertical.location)
+ assert self._has_changes(chapter.usage_key)
+ assert self._has_changes(sequential.usage_key)
+ assert self._has_changes(vertical.usage_key)
@ddt.data(ModuleStoreEnum.Type.split)
def test_vertical_with_draft_and_published_unit_has_changes_before_export_and_after_import(self, default_ms):
@@ -3214,56 +3214,56 @@ def test_vertical_with_draft_and_published_unit_has_changes_before_export_and_af
# create chapter
chapter = self.store.create_child(
- self.user_id, self.course.location, 'chapter', block_id='section_one'
+ self.user_id, self.course.usage_key, 'chapter', block_id='section_one'
)
- self.store.publish(chapter.location, self.user_id)
+ self.store.publish(chapter.usage_key, self.user_id)
# create sequential
sequential = self.store.create_child(
- self.user_id, chapter.location, 'sequential', block_id='subsection_one'
+ self.user_id, chapter.usage_key, 'sequential', block_id='subsection_one'
)
- self.store.publish(sequential.location, self.user_id)
+ self.store.publish(sequential.usage_key, self.user_id)
# create vertical
vertical = self.store.create_child(
- self.user_id, sequential.location, 'vertical', block_id='moon_unit'
+ self.user_id, sequential.usage_key, 'vertical', block_id='moon_unit'
)
# Vertical has changes until it is actually published.
- assert self._has_changes(vertical.location)
- self.store.publish(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
+ assert self._has_changes(vertical.usage_key)
+ self.store.publish(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
# create unit
unit = self.store.create_child(
- self.user_id, vertical.location, 'html', block_id='html_unit'
+ self.user_id, vertical.usage_key, 'html', block_id='html_unit'
)
# Vertical has a new child -and- unit is unpublished. So both have changes.
- assert self._has_changes(vertical.location)
- assert self._has_changes(unit.location)
+ assert self._has_changes(vertical.usage_key)
+ assert self._has_changes(unit.usage_key)
# Publishing the vertical also publishes its unit child.
- self.store.publish(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(unit.location)
+ self.store.publish(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(unit.usage_key)
# Publishing the unit separately has no effect on whether it has changes - it's already published.
- self.store.publish(unit.location, self.user_id)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(unit.location)
+ self.store.publish(unit.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(unit.usage_key)
# Retrieve the published block and make sure it's published.
- self.store.publish(chapter.location, self.user_id)
- assert not self._has_changes(chapter.location)
- assert not self._has_changes(sequential.location)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(unit.location)
+ self.store.publish(chapter.usage_key, self.user_id)
+ assert not self._has_changes(chapter.usage_key)
+ assert not self._has_changes(sequential.usage_key)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(unit.usage_key)
# Now make changes to the unit - but don't publish them.
- component = self.store.get_item(unit.location)
+ component = self.store.get_item(unit.usage_key)
updated_display_name = 'Changed Display Name'
component.display_name = updated_display_name
component = self.store.update_item(component, self.user_id)
- assert self._has_changes(component.location)
+ assert self._has_changes(component.usage_key)
# Export the course - then import the course export.
self._export_import_course_round_trip(
@@ -3272,19 +3272,19 @@ def test_vertical_with_draft_and_published_unit_has_changes_before_export_and_af
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
- assert self._has_changes(chapter.location)
- assert self._has_changes(sequential.location)
- assert self._has_changes(vertical.location)
- assert self._has_changes(unit.location)
+ assert self._has_changes(chapter.usage_key)
+ assert self._has_changes(sequential.usage_key)
+ assert self._has_changes(vertical.usage_key)
+ assert self._has_changes(unit.usage_key)
# Verify that the changes in the draft unit still exist.
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, source_course_key):
- component = self.store.get_item(unit.location)
+ component = self.store.get_item(unit.usage_key)
assert component.display_name == updated_display_name
# Verify that the draft changes don't exist in the published unit - it still uses the default name.
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, source_course_key):
- component = self.store.get_item(unit.location)
+ component = self.store.get_item(unit.usage_key)
assert component.display_name == 'Text'
@ddt.data(ModuleStoreEnum.Type.split)
@@ -3296,39 +3296,39 @@ def test_vertical_with_published_unit_remains_published_before_export_and_after_
# create chapter
chapter = self.store.create_child(
- self.user_id, self.course.location, 'chapter', block_id='section_one'
+ self.user_id, self.course.usage_key, 'chapter', block_id='section_one'
)
- self.store.publish(chapter.location, self.user_id)
+ self.store.publish(chapter.usage_key, self.user_id)
# create sequential
sequential = self.store.create_child(
- self.user_id, chapter.location, 'sequential', block_id='subsection_one'
+ self.user_id, chapter.usage_key, 'sequential', block_id='subsection_one'
)
- self.store.publish(sequential.location, self.user_id)
+ self.store.publish(sequential.usage_key, self.user_id)
# create vertical
vertical = self.store.create_child(
- self.user_id, sequential.location, 'vertical', block_id='moon_unit'
+ self.user_id, sequential.usage_key, 'vertical', block_id='moon_unit'
)
# Vertical has changes until it is actually published.
- assert self._has_changes(vertical.location)
- self.store.publish(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
+ assert self._has_changes(vertical.usage_key)
+ self.store.publish(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
# create unit
unit = self.store.create_child(
- self.user_id, vertical.location, 'html', block_id='html_unit'
+ self.user_id, vertical.usage_key, 'html', block_id='html_unit'
)
# Now make changes to the unit.
updated_display_name = 'Changed Display Name'
unit.display_name = updated_display_name
unit = self.store.update_item(unit, self.user_id)
- assert self._has_changes(unit.location)
+ assert self._has_changes(unit.usage_key)
# Publishing the vertical also publishes its unit child.
- self.store.publish(vertical.location, self.user_id)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(unit.location)
+ self.store.publish(vertical.usage_key, self.user_id)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(unit.usage_key)
# Export the course - then import the course export.
self._export_import_course_round_trip(
@@ -3337,14 +3337,14 @@ def test_vertical_with_published_unit_remains_published_before_export_and_after_
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
- assert not self._has_changes(chapter.location)
- assert not self._has_changes(sequential.location)
- assert not self._has_changes(vertical.location)
- assert not self._has_changes(unit.location)
+ assert not self._has_changes(chapter.usage_key)
+ assert not self._has_changes(sequential.usage_key)
+ assert not self._has_changes(vertical.usage_key)
+ assert not self._has_changes(unit.usage_key)
# Verify that the published changes exist in the published unit.
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, source_course_key):
- component = self.store.get_item(unit.location)
+ component = self.store.get_item(unit.usage_key)
assert component.display_name == updated_display_name
@ddt.data(ModuleStoreEnum.Type.split)
@@ -3394,7 +3394,7 @@ def check_block(block):
check_block(courses[0])
# create a new block and ensure its aside magically appears with the right fields
- new_chapter = self.store.create_child(self.user_id, courses[0].location, 'chapter', 'new_chapter')
+ new_chapter = self.store.create_child(self.user_id, courses[0].usage_key, 'chapter', 'new_chapter')
asides = new_chapter.runtime.get_asides(new_chapter)
assert len(asides) == 1, f'Found {asides} asides but expected only test_aside'
@@ -3409,7 +3409,7 @@ def check_block(block):
chapter_aside.data_field = 'new value'
self.store.update_item(new_chapter, self.user_id, asides=[chapter_aside])
- new_chapter = self.store.get_item(new_chapter.location)
+ new_chapter = self.store.get_item(new_chapter.usage_key)
chapter_aside = new_chapter.runtime.get_asides(new_chapter)[0]
assert 'new value' == chapter_aside.data_field
@@ -3417,7 +3417,7 @@ def check_block(block):
chapter_aside.data_field = 'another one value'
self.store.update_item(new_chapter, self.user_id, asides=[chapter_aside])
- new_chapter2 = self.store.get_item(new_chapter.location)
+ new_chapter2 = self.store.get_item(new_chapter.usage_key)
chapter_aside2 = new_chapter2.runtime.get_asides(new_chapter2)[0]
assert 'another one value' == chapter_aside2.data_field
@@ -3540,7 +3540,7 @@ def test_export_course_after_creating_new_items_with_asides(self, default_store)
# create new chapter and modify aside for it
new_chapter_display_name = 'New Chapter'
- new_chapter = self.store.create_child(self.user_id, courses[0].location, 'chapter', 'new_chapter')
+ new_chapter = self.store.create_child(self.user_id, courses[0].usage_key, 'chapter', 'new_chapter')
new_chapter.display_name = new_chapter_display_name
asides = new_chapter.runtime.get_asides(new_chapter)
@@ -3553,7 +3553,7 @@ def test_export_course_after_creating_new_items_with_asides(self, default_store)
# create new problem and modify aside for it
sequence = courses[0].get_children()[0].get_children()[0]
new_problem_display_name = 'New Problem'
- new_problem = self.store.create_child(self.user_id, sequence.location, 'problem', 'new_problem')
+ new_problem = self.store.create_child(self.user_id, sequence.usage_key, 'problem', 'new_problem')
new_problem.display_name = new_problem_display_name
asides = new_problem.runtime.get_asides(new_problem)
@@ -3692,7 +3692,7 @@ def _check_asides(asides, field11, field12, field21, field22):
assert asides[1].field22 == field22
# get saved item and check asides
- component = self.store.get_item(published_xblock.location)
+ component = self.store.get_item(published_xblock.usage_key)
asides = component.runtime.get_asides(component)
_check_asides(asides, 'new_value11', 'new_value12', 'new_value21', 'aside2_default_value2')
@@ -3703,7 +3703,7 @@ def _check_asides(asides, field11, field12, field21, field22):
cached_asides = component.runtime.get_asides(component)
_check_asides(cached_asides, 'other_value11', 'new_value12', 'new_value21', 'aside2_default_value2')
- new_component = self.store.get_item(published_xblock.location)
+ new_component = self.store.get_item(published_xblock.usage_key)
new_asides = new_component.runtime.get_asides(new_component)
_check_asides(new_asides, 'other_value11', 'new_value12', 'new_value21', 'aside2_default_value2')
@@ -3789,7 +3789,7 @@ def test_delete_item_with_asides(self, default_store):
assert asides[0].field12 == 'new_value12'
# remove item
- self.store.delete_item(published_xblock.location, self.user_id)
+ self.store.delete_item(published_xblock.usage_key, self.user_id)
# create item again
published_xblock2 = self.store.create_item(
@@ -3835,7 +3835,7 @@ def _check_asides(item):
# start off as Private
item = self.store.create_child(self.user_id, self.writable_chapter_location, 'problem',
'test_compute_publish_state', asides=[aside1])
- item_location = item.location
+ item_location = item.usage_key
with check_mongo_calls(max_find, max_send):
assert not self.store.has_published_version(item)
_check_asides(item)
diff --git a/xmodule/modulestore/tests/test_mongo_call_count.py b/xmodule/modulestore/tests/test_mongo_call_count.py
index 341c3b35e580..15f01b36ed6a 100644
--- a/xmodule/modulestore/tests/test_mongo_call_count.py
+++ b/xmodule/modulestore/tests/test_mongo_call_count.py
@@ -175,5 +175,5 @@ def test_lazy_when_course_previously_cached(self, store_builder, num_mongo_calls
course = modulestore.get_course(course_key, depth=0, lazy=True)
# and then subsequently retrieved with the lazy and depth=None values
- course = modulestore.get_item(course.location, depth=None, lazy=False)
+ course = modulestore.get_item(course.usage_key, depth=None, lazy=False)
self._traverse_blocks_in_course(course, access_all_block_fields=True)
diff --git a/xmodule/modulestore/tests/test_publish.py b/xmodule/modulestore/tests/test_publish.py
index e07f98579081..04b1dd25a51a 100644
--- a/xmodule/modulestore/tests/test_publish.py
+++ b/xmodule/modulestore/tests/test_publish.py
@@ -86,7 +86,7 @@ def _create_binary_structure_items(parent_type, block_type, num_items, child_blo
parent_item = getattr(self, parent_id)
block_id = _make_block_id(block_type, idx)
setattr(self, block_id, BlockFactory.create(
- parent_location=parent_item.location,
+ parent_location=parent_item.usage_key,
category=block_type,
modulestore=store,
publish_item=False,
@@ -433,7 +433,7 @@ def publish(self, block_list):
self.course.id.make_usage_key(block_type=block_type, block_id=block_id)
)
# Publish the draft item to the published branch.
- self.store.publish(test_item.location, self.user_id)
+ self.store.publish(test_item.usage_key, self.user_id)
# Since the elemental operation is now complete, shift to the post-operation export directory name.
self.export_dir = self._make_new_export_dir_name()
@@ -448,7 +448,7 @@ def unpublish(self, block_list):
self.course.id.make_usage_key(block_type=block_type, block_id=block_id)
)
# Unpublish the draft item from the published branch.
- self.store.unpublish(test_item.location, self.user_id)
+ self.store.unpublish(test_item.usage_key, self.user_id)
# Since the elemental operation is now complete, shift to the post-operation export directory name.
self.export_dir = self._make_new_export_dir_name()
@@ -463,7 +463,7 @@ def delete_item(self, block_list, revision):
self.course.id.make_usage_key(block_type=block_type, block_id=block_id)
)
# Delete the item from the specified branch.
- self.store.delete_item(test_item.location, self.user_id, revision=revision)
+ self.store.delete_item(test_item.usage_key, self.user_id, revision=revision)
# Since the elemental operation is now complete, shift to the post-operation export directory name.
self.export_dir = self._make_new_export_dir_name()
@@ -478,7 +478,7 @@ def convert_to_draft(self, block_list):
self.course.id.make_usage_key(block_type=block_type, block_id=block_id)
)
# Convert the item from the specified branch from published to draft.
- self.store.convert_to_draft(test_item.location, self.user_id)
+ self.store.convert_to_draft(test_item.usage_key, self.user_id)
# Since the elemental operation is now complete, shift to the post-operation export directory name.
self.export_dir = self._make_new_export_dir_name()
@@ -493,7 +493,7 @@ def revert_to_published(self, block_list):
self.course.id.make_usage_key(block_type=block_type, block_id=block_id)
)
# Revert the item from the specified branch from draft to published.
- self.store.revert_to_published(test_item.location, self.user_id)
+ self.store.revert_to_published(test_item.usage_key, self.user_id)
# Since the elemental operation is now complete, shift to the post-operation export directory name.
self.export_dir = self._make_new_export_dir_name()
diff --git a/xmodule/modulestore/tests/test_split_copy_from_template.py b/xmodule/modulestore/tests/test_split_copy_from_template.py
index 3fc0bcd85a72..1def4a2b337c 100644
--- a/xmodule/modulestore/tests/test_split_copy_from_template.py
+++ b/xmodule/modulestore/tests/test_split_copy_from_template.py
@@ -39,23 +39,23 @@ def test_copy_from_template(self, source_type):
if source_type == LibraryFactory:
source_container = self.store.get_library(
- source_container.location.library_key, remove_version=False, remove_branch=False
+ source_container.usage_key.library_key, remove_version=False, remove_branch=False
)
else:
source_container = self.store.get_course(
- source_container.location.course_key, remove_version=False, remove_branch=False
+ source_container.usage_key.course_key, remove_version=False, remove_branch=False
)
# Inherit the vertical and the problem from the library into the course:
source_keys = [source_container.children[0]]
- new_blocks = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
+ new_blocks = self.store.copy_from_template(source_keys, dest_key=course.usage_key, user_id=self.user_id)
assert len(new_blocks) == 1
- course = self.store.get_course(course.location.course_key) # Reload from modulestore
+ course = self.store.get_course(course.usage_key.course_key) # Reload from modulestore
assert len(course.children) == 1
vertical_block_course = self.store.get_item(course.children[0])
- assert new_blocks[0] == vertical_block_course.location
+ assert new_blocks[0] == vertical_block_course.usage_key
problem_block_course = self.store.get_item(vertical_block_course.children[0])
assert problem_block_course.display_name == problem_library_display_name
@@ -76,10 +76,10 @@ def test_copy_from_template(self, source_type):
extra_block = self.make_block("html", vertical_block_course)
# Repeat the copy_from_template():
- new_blocks2 = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
+ new_blocks2 = self.store.copy_from_template(source_keys, dest_key=course.usage_key, user_id=self.user_id)
assert new_blocks == new_blocks2
# Reload problem_block_course:
- problem_block_course = self.store.get_item(problem_block_course.location)
+ problem_block_course = self.store.get_item(problem_block_course.usage_key)
assert problem_block_course.display_name == new_display_name
assert problem_block_course.weight == new_weight
@@ -87,7 +87,7 @@ def test_copy_from_template(self, source_type):
vertical_block_course = self.store.get_item(new_blocks2[0])
assert len(vertical_block_course.children) == 1
with pytest.raises(ItemNotFoundError):
- self.store.get_item(extra_block.location)
+ self.store.get_item(extra_block.usage_key)
def test_copy_from_template_publish(self):
"""
@@ -100,14 +100,14 @@ def test_copy_from_template_publish(self):
self.make_block("problem", source_library, display_name=display_name_expected)
# Reload source_library since we need its branch and version to use copy_from_template:
source_library = self.store.get_library(
- source_library.location.library_key, remove_version=False, remove_branch=False
+ source_library.usage_key.library_key, remove_version=False, remove_branch=False
)
# And a course with a vertical:
course = CourseFactory.create(modulestore=self.store)
self.make_block("vertical", course)
problem_key_in_course = self.store.copy_from_template(
- source_library.children, dest_key=course.location, user_id=self.user_id
+ source_library.children, dest_key=course.usage_key, user_id=self.user_id
)[0]
# We do the following twice because different methods get used inside
@@ -140,12 +140,12 @@ def test_copy_from_template_auto_publish(self):
# Reload source_course since we need its branch and version to use copy_from_template:
source_course = self.store.get_course(
- source_course.location.course_key, remove_version=False, remove_branch=False
+ source_course.usage_key.course_key, remove_version=False, remove_branch=False
)
# Inherit the vertical and the problem from the library into the course:
- source_keys = [block.location for block in [about, chapter, html]]
- block_keys = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
+ source_keys = [block.usage_key for block in [about, chapter, html]]
+ block_keys = self.store.copy_from_template(source_keys, dest_key=course.usage_key, user_id=self.user_id)
assert len(block_keys) == len(source_keys)
# Build dict of the new blocks in 'course', keyed by category (which is a unique key in our case)
@@ -161,7 +161,7 @@ def test_copy_from_template_auto_publish(self):
def published_version_exists(block):
""" Does a published version of block exist? """
try:
- self.store.get_item(block.location.for_branch(ModuleStoreEnum.BranchName.published))
+ self.store.get_item(block.usage_key.for_branch(ModuleStoreEnum.BranchName.published))
return True
except ItemNotFoundError:
return False
diff --git a/xmodule/modulestore/tests/test_split_modulestore.py b/xmodule/modulestore/tests/test_split_modulestore.py
index 09278ff5e8f0..f9460544c9d2 100644
--- a/xmodule/modulestore/tests/test_split_modulestore.py
+++ b/xmodule/modulestore/tests/test_split_modulestore.py
@@ -464,11 +464,11 @@ def bootstrapDB(split_store): # pylint: disable=invalid-name
for revision in course_spec.get('revisions', []):
for (block_type, block_id), fields in revision.get('update', {}).items():
# cheat since course is most frequent
- if course.location.block_id == block_id:
+ if course.usage_key.block_id == block_id:
block = course
else:
# not easy to figure out the category but get_item won't care
- block_usage = BlockUsageLocator.make_relative(course.location, block_type, block_id)
+ block_usage = BlockUsageLocator.make_relative(course.usage_key, block_type, block_id)
block = split_store.get_item(block_usage)
for key, value in fields.items():
setattr(block, key, value)
@@ -477,10 +477,10 @@ def bootstrapDB(split_store): # pylint: disable=invalid-name
for spec in revision.get('create', []):
if spec['parent'] in new_ele_dict:
parent = new_ele_dict.get(spec['parent'])
- elif spec['parent'] == course.location.block_id:
+ elif spec['parent'] == course.usage_key.block_id:
parent = course
else:
- block_usage = BlockUsageLocator.make_relative(course.location, spec['parent_type'], spec['parent']) # lint-amnesty, pylint: disable=line-too-long
+ block_usage = BlockUsageLocator.make_relative(course.usage_key, spec['parent_type'], spec['parent']) # lint-amnesty, pylint: disable=line-too-long
parent = split_store.get_item(block_usage)
block_id = LocalId(spec['id'])
child = split_store.create_xblock(
@@ -518,7 +518,7 @@ def findByIdInResult(self, collection, _id): # pylint: disable=invalid-name
matches the _id.
"""
for element in collection:
- if element.location.block_id == _id:
+ if element.usage_key.block_id == _id:
return element
@@ -570,7 +570,7 @@ def test_get_courses(self):
assert len(courses) == 3, 'Wrong number of courses'
# check metadata -- NOTE no promised order
course = self.findByIdInResult(courses, "head12345")
- assert course.location.org == 'testx'
+ assert course.usage_key.org == 'testx'
assert course.category == 'course', 'wrong category'
assert len(course.tabs) == 5, 'wrong number of tabs'
assert course.display_name == 'The Ancient Greek Hero', 'wrong display name'
@@ -623,8 +623,8 @@ def _verify_published_course(courses_published):
assert len(courses_published) == 1, len(courses_published)
course = self.findByIdInResult(courses_published, "head23456")
assert course is not None, 'published courses'
- assert course.location.course_key.org == 'testx'
- assert course.location.course_key.course == 'wonderful'
+ assert course.usage_key.course_key.org == 'testx'
+ assert course.usage_key.course_key.course == 'wonderful'
assert course.category == 'course', 'wrong category'
assert len(course.tabs) == 3, 'wrong number of tabs'
assert course.display_name == 'The most wonderful course', course.display_name
@@ -650,11 +650,11 @@ def test_get_course(self):
'''
locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT)
head_course = modulestore().get_course(locator)
- assert head_course.location.version_guid != head_course.previous_version
+ assert head_course.usage_key.version_guid != head_course.previous_version
locator = CourseLocator(version_guid=head_course.previous_version)
course = modulestore().get_course(locator)
- assert course.location.course_key.org is None
- assert course.location.version_guid == head_course.previous_version
+ assert course.usage_key.course_key.org is None
+ assert course.usage_key.version_guid == head_course.previous_version
assert course.category == 'course'
assert len(course.tabs) == 5
assert course.display_name == 'The Ancient Greek Hero'
@@ -668,9 +668,9 @@ def test_get_course(self):
locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT)
course = modulestore().get_course(locator)
- assert course.location.course_key.org == 'testx'
- assert course.location.course_key.course == 'GreekHero'
- assert course.location.course_key.run == 'run'
+ assert course.usage_key.course_key.org == 'testx'
+ assert course.usage_key.course_key.course == 'GreekHero'
+ assert course.usage_key.course_key.run == 'run'
assert course.category == 'course'
assert len(course.tabs) == 5
assert course.display_name == 'The Ancient Greek Hero'
@@ -682,11 +682,11 @@ def test_get_course(self):
locator = CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_PUBLISHED)
course = modulestore().get_course(locator)
- published_version = course.location.version_guid
+ published_version = course.usage_key.version_guid
locator = CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_DRAFT)
course = modulestore().get_course(locator)
- assert course.location.version_guid != published_version
+ assert course.usage_key.version_guid != published_version
def test_get_course_negative(self):
# Now negative testing
@@ -878,7 +878,7 @@ def _get_structure(self, course):
Helper function to get a structure from a course.
"""
return modulestore().db_connection.get_structure(
- course.location.as_object_id(course.location.version_guid)
+ course.usage_key.as_object_id(course.usage_key.version_guid)
)
@@ -898,10 +898,10 @@ def test_has_item(self):
course = modulestore().get_course(course_locator)
previous_version = course.previous_version
# positive tests of various forms
- locator = course.location.map_into_course(CourseLocator(version_guid=previous_version))
+ locator = course.usage_key.map_into_course(CourseLocator(version_guid=previous_version))
assert modulestore().has_item(locator), ("couldn't find in %s" % previous_version)
- locator = course.location.version_agnostic()
+ locator = course.usage_key.version_agnostic()
assert modulestore().has_item(locator)
assert not modulestore()\
.has_item(BlockUsageLocator(locator.course_key.for_branch(BRANCH_NAME_PUBLISHED),
@@ -945,7 +945,7 @@ def test_get_item(self):
previous_version = course.previous_version
# positive tests of various forms
- locator = course.location.map_into_course(CourseLocator(version_guid=previous_version))
+ locator = course.usage_key.map_into_course(CourseLocator(version_guid=previous_version))
block = modulestore().get_item(locator)
assert isinstance(block, CourseBlock)
assert isinstance(modulestore().get_item(locator), CourseBlock)
@@ -954,9 +954,9 @@ def verify_greek_hero(block):
"""
Check contents of block
"""
- assert block.location.org == 'testx'
- assert block.location.course == 'GreekHero'
- assert block.location.run == 'run'
+ assert block.usage_key.org == 'testx'
+ assert block.usage_key.course == 'GreekHero'
+ assert block.usage_key.run == 'run'
assert len(block.tabs) == 5, 'wrong number of tabs'
assert block.display_name == 'The Ancient Greek Hero'
assert block.advertised_start == 'Fall 2013'
@@ -967,11 +967,11 @@ def verify_greek_hero(block):
block.grade_cutoffs, {"Pass": 0.45},
)
- verify_greek_hero(modulestore().get_item(course.location))
+ verify_greek_hero(modulestore().get_item(course.usage_key))
# try to look up other branches
with pytest.raises(ItemNotFoundError):
- modulestore().get_item(course.location.for_branch(BRANCH_NAME_PUBLISHED))
+ modulestore().get_item(course.usage_key.for_branch(BRANCH_NAME_PUBLISHED))
def test_get_non_root(self):
# not a course obj
@@ -979,8 +979,8 @@ def test_get_non_root(self):
CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT), 'chapter', 'chapter1'
)
block = modulestore().get_item(locator)
- assert block.location.org == 'testx'
- assert block.location.course == 'GreekHero'
+ assert block.usage_key.org == 'testx'
+ assert block.usage_key.course == 'GreekHero'
assert block.category == 'chapter'
assert block.display_name == 'Hercules'
assert block.edited_by == TEST_ASSISTANT_USER_ID
@@ -1106,8 +1106,8 @@ def test_get_children(self):
]
for child in children:
assert child.category == 'chapter'
- assert child.location.block_id in expected_ids
- expected_ids.remove(child.location.block_id)
+ assert child.usage_key.block_id in expected_ids
+ expected_ids.remove(child.usage_key.block_id)
assert len(expected_ids) == 0
@@ -1158,15 +1158,15 @@ def test_create_minimal_item(self):
fields={'display_name': 'new sequential'}
)
# check that course version changed and course's previous is the other one
- assert new_block.location.course == 'GreekHero'
- assert new_block.location.version_guid != premod_course.location.version_guid
+ assert new_block.usage_key.course == 'GreekHero'
+ assert new_block.usage_key.version_guid != premod_course.usage_key.version_guid
assert locator.version_guid is None,\
'Version inadvertently filled in' # lint-amnesty, pylint: disable=no-member
current_course = modulestore().get_course(locator)
- assert new_block.location.version_guid == current_course.location.version_guid
+ assert new_block.usage_key.version_guid == current_course.usage_key.version_guid
- history_info = modulestore().get_course_history_info(current_course.location.course_key)
- assert history_info['previous_version'] == premod_course.location.version_guid
+ history_info = modulestore().get_course_history_info(current_course.usage_key.course_key)
+ assert history_info['previous_version'] == premod_course.usage_key.version_guid
assert history_info['original_version'] == premod_history['original_version']
assert history_info['edited_by'] == 'user123'
# check block's info: category, definition_locator, and display_name
@@ -1174,8 +1174,8 @@ def test_create_minimal_item(self):
assert new_block.definition_locator is not None
assert new_block.display_name == 'new sequential'
# check that block does not exist in previous version
- locator = new_block.location.map_into_course(
- CourseLocator(version_guid=premod_course.location.version_guid)
+ locator = new_block.usage_key.map_into_course(
+ CourseLocator(version_guid=premod_course.usage_key.version_guid)
)
with pytest.raises(ItemNotFoundError):
modulestore().get_item(locator)
@@ -1201,9 +1201,9 @@ def test_create_parented_item(self):
definition_locator=original.definition_locator
)
# check that course version changed and course's previous is the other one
- assert new_block.location.version_guid != premod_course.location.version_guid
+ assert new_block.usage_key.version_guid != premod_course.usage_key.version_guid
parent = modulestore().get_item(locator)
- assert new_block.location.version_agnostic() in version_agnostic(parent.children)
+ assert new_block.usage_key.version_agnostic() in version_agnostic(parent.children)
assert new_block.definition_locator.definition_id == original.definition_locator.definition_id
def test_unique_naming(self):
@@ -1235,9 +1235,9 @@ def test_unique_naming(self):
)
# check that course version changed and course's previous is the other one
parent = modulestore().get_item(locator)
- assert new_block.location.block_id != another_block.location.block_id
- assert new_block.location.version_agnostic() in version_agnostic(parent.children)
- assert another_block.location.version_agnostic() in version_agnostic(parent.children)
+ assert new_block.usage_key.block_id != another_block.usage_key.block_id
+ assert new_block.usage_key.version_agnostic() in version_agnostic(parent.children)
+ assert another_block.usage_key.version_agnostic() in version_agnostic(parent.children)
assert new_block.data == new_payload
assert another_block.data == another_payload
# check definition histories
@@ -1262,7 +1262,7 @@ def test_encoded_naming(self):
)
# check that course version changed and course's previous is the other one
new_block = modulestore().get_item(chapter_locator)
- assert new_block.location.block_id == 'foo.bar_-~:0'
+ assert new_block.usage_key.block_id == 'foo.bar_-~:0'
# hardcode to ensure BUL init didn't change
# now try making that a parent of something
new_payload = "empty"
@@ -1274,7 +1274,7 @@ def test_encoded_naming(self):
)
# check that course version changed and course's previous is the other one
new_block = modulestore().get_item(problem_locator)
- assert new_block.location.block_id == problem_locator.block_id
+ assert new_block.usage_key.block_id == problem_locator.block_id
chapter = modulestore().get_item(chapter_locator)
assert problem_locator in version_agnostic(chapter.children)
@@ -1288,7 +1288,7 @@ def test_create_bulk_operations(self):
with modulestore().bulk_operations(course_key):
new_course = modulestore().create_course('test_org', 'test_transaction', 'test_run', user, BRANCH_NAME_DRAFT) # lint-amnesty, pylint: disable=line-too-long
new_course_locator = new_course.id
- index_history_info = modulestore().get_course_history_info(new_course.location.course_key)
+ index_history_info = modulestore().get_course_history_info(new_course.usage_key.course_key)
course_block_prev_version = new_course.previous_version
course_block_update_version = new_course.update_version
assert new_course_locator.version_guid is not None, 'Want to test a definite version'
@@ -1296,39 +1296,39 @@ def test_create_bulk_operations(self):
# positive simple case: no force, add chapter
new_ele = modulestore().create_child(
- user, new_course.location, 'chapter',
+ user, new_course.usage_key, 'chapter',
fields={'display_name': 'chapter 1'},
)
# version info shouldn't change
assert new_ele.update_version == course_block_update_version
- assert new_ele.update_version == new_ele.location.version_guid
+ assert new_ele.update_version == new_ele.usage_key.version_guid
refetch_course = modulestore().get_course(versionless_course_locator)
- assert refetch_course.location.version_guid == new_course.location.version_guid
+ assert refetch_course.usage_key.version_guid == new_course.usage_key.version_guid
assert refetch_course.previous_version == course_block_prev_version
assert refetch_course.update_version == course_block_update_version
- refetch_index_history_info = modulestore().get_course_history_info(refetch_course.location.course_key)
+ refetch_index_history_info = modulestore().get_course_history_info(refetch_course.usage_key.course_key)
assert refetch_index_history_info == index_history_info
- assert new_ele.location.version_agnostic() in version_agnostic(refetch_course.children)
+ assert new_ele.usage_key.version_agnostic() in version_agnostic(refetch_course.children)
# try to create existing item
with pytest.raises(DuplicateItemError):
_fail = modulestore().create_child(
- user, new_course.location, 'chapter',
- block_id=new_ele.location.block_id,
+ user, new_course.usage_key, 'chapter',
+ block_id=new_ele.usage_key.block_id,
fields={'display_name': 'chapter 2'},
)
# start a new transaction
with modulestore().bulk_operations(course_key):
new_ele = modulestore().create_child(
- user, new_course.location, 'chapter',
+ user, new_course.usage_key, 'chapter',
fields={'display_name': 'chapter 2'},
)
- transaction_guid = new_ele.location.version_guid
+ transaction_guid = new_ele.usage_key.version_guid
# ensure force w/ continue gives exception
with pytest.raises(VersionConflictError):
_fail = modulestore().create_child(
- user, new_course.location, 'chapter',
+ user, new_course.usage_key, 'chapter',
fields={'display_name': 'chapter 2'},
force=True
)
@@ -1336,22 +1336,22 @@ def test_create_bulk_operations(self):
# ensure trying to continue the old one gives exception
with pytest.raises(VersionConflictError):
_fail = modulestore().create_child(
- user, new_course.location, 'chapter',
+ user, new_course.usage_key, 'chapter',
fields={'display_name': 'chapter 3'},
)
# add new child to old parent in continued (leave off version_guid)
- course_block_locator = new_course.location.version_agnostic()
+ course_block_locator = new_course.usage_key.version_agnostic()
new_ele = modulestore().create_child(
user, course_block_locator, 'chapter',
fields={'display_name': 'chapter 4'},
)
assert new_ele.update_version != course_block_update_version
- assert new_ele.location.version_guid == transaction_guid
+ assert new_ele.usage_key.version_guid == transaction_guid
# check children, previous_version
refetch_course = modulestore().get_course(versionless_course_locator)
- assert new_ele.location.version_agnostic() in version_agnostic(refetch_course.children)
+ assert new_ele.usage_key.version_agnostic() in version_agnostic(refetch_course.children)
assert refetch_course.previous_version == course_block_update_version
assert refetch_course.update_version == transaction_guid
@@ -1396,7 +1396,7 @@ def test_update_metadata(self):
)
problem = modulestore().get_item(locator)
pre_def_id = problem.definition_locator.definition_id
- pre_version_guid = problem.location.version_guid
+ pre_version_guid = problem.usage_key.version_guid
assert pre_def_id is not None
assert pre_version_guid is not None
assert problem.max_attempts != 4, 'Invalidates rest of test'
@@ -1406,17 +1406,17 @@ def test_update_metadata(self):
updated_problem = modulestore().update_item(problem, self.user_id)
# check that course version changed and course's previous is the other one
assert updated_problem.definition_locator.definition_id == pre_def_id
- assert updated_problem.location.version_guid != pre_version_guid
+ assert updated_problem.usage_key.version_guid != pre_version_guid
assert updated_problem.max_attempts == 4
# refetch to ensure original didn't change
- original_location = problem.location.map_into_course(CourseLocator(version_guid=pre_version_guid))
+ original_location = problem.usage_key.map_into_course(CourseLocator(version_guid=pre_version_guid))
problem = modulestore().get_item(original_location)
assert problem.max_attempts != 4, 'original changed'
current_course = modulestore().get_course(locator.course_key)
- assert updated_problem.location.version_guid == current_course.location.version_guid
+ assert updated_problem.usage_key.version_guid == current_course.usage_key.version_guid
- history_info = modulestore().get_course_history_info(current_course.location.course_key)
+ history_info = modulestore().get_course_history_info(current_course.usage_key.course_key)
assert history_info['previous_version'] == pre_version_guid
assert history_info['edited_by'] == self.user_id
@@ -1429,7 +1429,7 @@ def test_update_children(self):
)
block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id
- pre_version_guid = block.location.version_guid
+ pre_version_guid = block.usage_key.version_guid
# reorder children
assert len(block.children) > 0, 'meaningless test'
@@ -1438,7 +1438,7 @@ def test_update_children(self):
updated_problem = modulestore().update_item(block, self.user_id)
# check that course version changed and course's previous is the other one
assert updated_problem.definition_locator.definition_id == pre_def_id
- assert updated_problem.location.version_guid != pre_version_guid
+ assert updated_problem.usage_key.version_guid != pre_version_guid
assert version_agnostic(updated_problem.children) == version_agnostic(block.children)
assert moved_child not in version_agnostic(updated_problem.children)
locator = locator.course_key.make_usage_key('chapter', "chapter1")
@@ -1456,14 +1456,14 @@ def test_update_definition(self):
)
block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id
- pre_version_guid = block.location.version_guid
+ pre_version_guid = block.usage_key.version_guid
block.grading_policy['GRADER'][0]['min_count'] = 13
block.save() # decache model changes
updated_block = modulestore().update_item(block, self.user_id)
assert updated_block.definition_locator.definition_id != pre_def_id
- assert updated_block.location.version_guid != pre_version_guid
+ assert updated_block.usage_key.version_guid != pre_version_guid
assert updated_block.grading_policy['GRADER'][0]['min_count'] == 13
def test_update_manifold(self):
@@ -1498,7 +1498,7 @@ def test_update_manifold(self):
# now begin the test
block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id
- pre_version_guid = block.location.version_guid
+ pre_version_guid = block.usage_key.version_guid
assert block.grading_policy['GRADER'][0]['min_count'] != 13
block.grading_policy['GRADER'][0]['min_count'] = 13
@@ -1508,7 +1508,7 @@ def test_update_manifold(self):
block.save() # decache model changes
updated_block = modulestore().update_item(block, self.user_id)
assert updated_block.definition_locator.definition_id != pre_def_id
- assert updated_block.location.version_guid != pre_version_guid
+ assert updated_block.usage_key.version_guid != pre_version_guid
assert updated_block.grading_policy['GRADER'][0]['min_count'] == 13
assert updated_block.children[0].version_agnostic() == block.children[0].version_agnostic()
assert updated_block.advertised_start == 'Soon'
@@ -1516,12 +1516,12 @@ def test_update_manifold(self):
def test_delete_item(self):
course = self.create_course_for_deletion()
with pytest.raises(ValueError):
- modulestore().delete_item(course.location, self.user_id)
+ modulestore().delete_item(course.usage_key, self.user_id)
reusable_location = course.id.version_agnostic().for_branch(BRANCH_NAME_DRAFT)
# delete a leaf
problems = modulestore().get_items(reusable_location, qualifiers={'category': 'problem'})
- locn_to_del = problems[0].location
+ locn_to_del = problems[0].usage_key
new_course_loc = modulestore().delete_item(locn_to_del, self.user_id)
deleted = locn_to_del.version_agnostic()
assert not modulestore().has_item(deleted)
@@ -1531,11 +1531,11 @@ def test_delete_item(self):
modulestore().delete_item(deleted, self.user_id)
assert modulestore().has_item(locn_to_del.course_agnostic())
- assert new_course_loc.version_guid != course.location.version_guid
+ assert new_course_loc.version_guid != course.usage_key.version_guid
# delete a subtree
nodes = modulestore().get_items(reusable_location, qualifiers={'category': 'chapter'})
- new_course_loc = modulestore().delete_item(nodes[0].location, self.user_id)
+ new_course_loc = modulestore().delete_item(nodes[0].usage_key, self.user_id)
# check subtree
def check_subtree(node):
@@ -1543,7 +1543,7 @@ def check_subtree(node):
Check contents of subtree recursively
"""
if node:
- node_loc = node.location
+ node_loc = node.usage_key
assert not modulestore().has_item(node_loc.version_agnostic())
assert modulestore().has_item(node_loc.course_agnostic())
if node.has_children:
@@ -1556,7 +1556,7 @@ def create_course_for_deletion(self):
Create a course we can delete
"""
course = modulestore().create_course('nihilx', 'deletion', 'run', TEST_USER_ID, BRANCH_NAME_DRAFT)
- root = course.location.version_agnostic().for_branch(BRANCH_NAME_DRAFT)
+ root = course.usage_key.version_agnostic().for_branch(BRANCH_NAME_DRAFT)
for _ in range(4):
self.create_subtree_for_deletion(root, ['chapter', 'vertical', 'problem'])
return modulestore().get_item(root)
@@ -1570,7 +1570,7 @@ def create_subtree_for_deletion(self, parent, category_queue):
node = modulestore().create_child(
TEST_USER_ID, parent.version_agnostic(), category_queue[0]
)
- node_loc = node.location.map_into_course(parent.course_key)
+ node_loc = node.usage_key.map_into_course(parent.course_key)
for _ in range(4):
self.create_subtree_for_deletion(node_loc, category_queue[1:])
@@ -1589,13 +1589,13 @@ def test_split_modulestore_create_child_with_position(self):
versionless_course_locator = new_course_locator.version_agnostic()
first_child = store.create_child(
self.user_id,
- new_course.location,
+ new_course.usage_key,
"chapter"
)
refetch_course = store.get_course(versionless_course_locator)
second_child = store.create_child(
self.user_id,
- refetch_course.location,
+ refetch_course.usage_key,
"chapter",
position=0
)
@@ -1603,8 +1603,8 @@ def test_split_modulestore_create_child_with_position(self):
# First child should have been moved to second position, and better child takes the lead
refetch_course = store.get_course(versionless_course_locator)
children = refetch_course.get_children()
- assert str(children[1].location) == str(first_child.location)
- assert str(children[0].location) == str(second_child.location)
+ assert str(children[1].usage_key) == str(first_child.usage_key)
+ assert str(children[0].usage_key) == str(second_child.usage_key)
# Clean up the data so we don't break other tests which apparently expect a particular state
store.delete_course(refetch_course.id, user)
@@ -1622,7 +1622,7 @@ def test_simple_creation(self):
new_course = modulestore().create_course(
'test_org', 'test_course', 'test_run', TEST_USER_ID, BRANCH_NAME_DRAFT
)
- new_locator = new_course.location
+ new_locator = new_course.usage_key
# check index entry
index_info = modulestore().get_course_index_info(new_locator.course_key)
assert index_info['org'] == 'test_org'
@@ -1652,7 +1652,7 @@ def test_cloned_course(self):
new_draft = modulestore().create_course(
'best', 'leech', 'leech_run', TEST_OTHER_USER_ID, BRANCH_NAME_DRAFT,
versions_dict=original_index['versions'])
- new_draft_locator = new_draft.location
+ new_draft_locator = new_draft.usage_key
self.assertRegex(new_draft_locator.org, 'best')
# the edited_by and other meta fields on the new course will be the original author not this one
assert new_draft.edited_by == TEST_USER_ID
@@ -1664,12 +1664,12 @@ def test_cloned_course(self):
new_published_locator = new_draft_locator.course_key.for_branch(BRANCH_NAME_PUBLISHED)
new_published = modulestore().get_course(new_published_locator)
assert new_published.edited_by == TEST_USER_ID
- assert new_published.location.version_guid == original_index['versions'][BRANCH_NAME_PUBLISHED]
+ assert new_published.usage_key.version_guid == original_index['versions'][BRANCH_NAME_PUBLISHED]
# changing this course will not change the original course
- # using new_draft.location will insert the chapter under the course root
+ # using new_draft.usage_key will insert the chapter under the course root
new_item = modulestore().create_child(
- TEST_OTHER_USER_ID, new_draft.location, 'chapter',
+ TEST_OTHER_USER_ID, new_draft.usage_key, 'chapter',
fields={'display_name': 'new chapter'}
)
new_draft_locator = new_draft_locator.course_key.version_agnostic()
@@ -1677,13 +1677,13 @@ def test_cloned_course(self):
assert new_index['versions'][BRANCH_NAME_DRAFT] != original_index['versions'][BRANCH_NAME_DRAFT]
new_draft = modulestore().get_course(new_draft_locator)
assert new_item.edited_by == TEST_OTHER_USER_ID
- assert new_item.location.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
- assert new_draft.location.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
+ assert new_item.usage_key.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
+ assert new_draft.usage_key.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
structure_info = modulestore().get_course_history_info(new_draft_locator)
assert structure_info['edited_by'] == TEST_OTHER_USER_ID
original_course = modulestore().get_course(original_locator)
- assert original_course.location.version_guid == original_index['versions'][BRANCH_NAME_DRAFT]
+ assert original_course.usage_key.version_guid == original_index['versions'][BRANCH_NAME_DRAFT]
def test_derived_course(self):
"""
@@ -1702,7 +1702,7 @@ def test_derived_course(self):
versions_dict={BRANCH_NAME_DRAFT: original_index['versions'][BRANCH_NAME_DRAFT]},
fields=fields
)
- new_draft_locator = new_draft.location
+ new_draft_locator = new_draft.usage_key
self.assertRegex(new_draft_locator.org, 'counter')
# the edited_by and other meta fields on the new course will be the original author not this one
assert new_draft.edited_by == TEST_OTHER_USER_ID
@@ -1731,13 +1731,13 @@ def test_update_course_index(self):
versions[BRANCH_NAME_DRAFT] = head_course.previous_version
modulestore().update_course_index(None, course_info)
course = modulestore().get_course(locator)
- assert course.location.version_guid == versions[BRANCH_NAME_DRAFT]
+ assert course.usage_key.version_guid == versions[BRANCH_NAME_DRAFT]
# an allowed but not recommended way to publish a course
versions[BRANCH_NAME_PUBLISHED] = versions[BRANCH_NAME_DRAFT]
modulestore().update_course_index(None, course_info)
course = modulestore().get_course(locator.for_branch(BRANCH_NAME_PUBLISHED))
- assert course.location.version_guid == versions[BRANCH_NAME_DRAFT]
+ assert course.usage_key.version_guid == versions[BRANCH_NAME_DRAFT]
def test_create_with_root(self):
"""
@@ -1748,11 +1748,11 @@ def test_create_with_root(self):
'test_org', 'test_transaction', 'test_run', user, BRANCH_NAME_DRAFT,
root_block_id='top', root_category='chapter'
)
- assert new_course.location.block_id == 'top'
+ assert new_course.usage_key.block_id == 'top'
assert new_course.category == 'chapter'
# look at db to verify
db_structure = modulestore().db_connection.get_structure(
- new_course.location.as_object_id(new_course.location.version_guid)
+ new_course.usage_key.as_object_id(new_course.usage_key.version_guid)
)
assert db_structure is not None, "Didn't find course"
assert BlockKey('course', 'course') not in db_structure['blocks']
@@ -1766,7 +1766,7 @@ def test_create_id_dupe(self):
user = random.getrandbits(32)
courses = modulestore().get_courses(BRANCH_NAME_DRAFT)
with pytest.raises(DuplicateCourseError):
- dupe_course_key = courses[0].location.course_key
+ dupe_course_key = courses[0].usage_key.course_key
modulestore().create_course(
dupe_course_key.org, dupe_course_key.course, dupe_course_key.run, user, BRANCH_NAME_DRAFT
)
@@ -1848,15 +1848,15 @@ def test_inheritance_not_saved(self):
chapter.visible_to_staff_only = True
modulestore().update_item(chapter, self.user_id)
- problem = modulestore().get_item(problem.location.version_agnostic())
+ problem = modulestore().get_item(problem.usage_key.version_agnostic())
assert problem.visible_to_staff_only
# unset on parent, retrieve child, verify unset
- chapter = modulestore().get_item(chapter.location.version_agnostic())
+ chapter = modulestore().get_item(chapter.usage_key.version_agnostic())
del chapter.visible_to_staff_only
modulestore().update_item(chapter, self.user_id)
- problem = modulestore().get_item(problem.location.version_agnostic())
+ problem = modulestore().get_item(problem.usage_key.version_agnostic())
assert not problem.visible_to_staff_only
def test_dynamic_inheritance(self):
@@ -1869,7 +1869,7 @@ def test_dynamic_inheritance(self):
chapter.visible_to_staff_only = True
orphan_problem = modulestore().create_item(self.user_id, course_key, 'problem')
assert not orphan_problem.visible_to_staff_only
- parented_problem = modulestore().create_child(self.user_id, chapter.location.version_agnostic(), 'problem') # lint-amnesty, pylint: disable=unused-variable
+ parented_problem = modulestore().create_child(self.user_id, chapter.usage_key.version_agnostic(), 'problem') # lint-amnesty, pylint: disable=unused-variable
# FIXME LMS-11376
# self.assertTrue(parented_problem.visible_to_staff_only)
@@ -1912,22 +1912,22 @@ def test_publish_safe(self):
expected.remove(BlockKey.from_usage_key(chapter1))
# check that it's not in published course
with pytest.raises(ItemNotFoundError):
- modulestore().get_item(new_block.location.map_into_course(dest_course))
+ modulestore().get_item(new_block.usage_key.map_into_course(dest_course))
# publish it
- modulestore().copy(self.user_id, source_course, dest_course, [new_block.location], None)
- expected.append(BlockKey.from_usage_key(new_block.location))
+ modulestore().copy(self.user_id, source_course, dest_course, [new_block.usage_key], None)
+ expected.append(BlockKey.from_usage_key(new_block.usage_key))
# check that it is in the published course and that its parent is the chapter
- pub_block = modulestore().get_item(new_block.location.map_into_course(dest_course))
- assert modulestore().get_parent_location(pub_block.location).block_id == chapter1.block_id
+ pub_block = modulestore().get_item(new_block.usage_key.map_into_course(dest_course))
+ assert modulestore().get_parent_location(pub_block.usage_key).block_id == chapter1.block_id
# ensure intentionally orphaned blocks work (e.g., course_info)
new_block = modulestore().create_item(
self.user_id, source_course, "course_info", block_id="handouts"
)
# publish it
- modulestore().copy(self.user_id, source_course, dest_course, [new_block.location], None)
- expected.append(BlockKey.from_usage_key(new_block.location))
+ modulestore().copy(self.user_id, source_course, dest_course, [new_block.usage_key], None)
+ expected.append(BlockKey.from_usage_key(new_block.usage_key))
# check that it is in the published course (no error means it worked)
- pub_block = modulestore().get_item(new_block.location.map_into_course(dest_course))
+ pub_block = modulestore().get_item(new_block.usage_key.map_into_course(dest_course))
self._check_course(source_course, dest_course, expected, unexpected)
def test_exceptions(self):
@@ -1973,7 +1973,7 @@ def test_move_delete(self):
chapter1 = modulestore().get_item(source_course.make_usage_key("chapter", "chapter1"))
chapter3 = modulestore().get_item(source_course.make_usage_key("chapter", "chapter3"))
chapter1.children.append(problem1)
- chapter3.children.remove(problem1.map_into_course(chapter3.location.course_key))
+ chapter3.children.remove(problem1.map_into_course(chapter3.usage_key.course_key))
modulestore().delete_item(source_course.make_usage_key("problem", "problem3_2"), self.user_id)
modulestore().copy(self.user_id, source_course, dest_course, [head], [chapter2])
expected = [
@@ -1998,7 +1998,7 @@ def _check_course(self, source_course_loc, dest_course_loc, expected_blocks, une
assert source.update_version == pub_copy.source_version,\
f"Versions don't match for {expected}: {source.update_version} != {pub_copy.update_version}"
assert self.user_id == pub_copy.edited_by,\
- f'{pub_copy.location} edited_by {pub_copy.edited_by} not {self.user_id}'
+ f'{pub_copy.usage_key} edited_by {pub_copy.edited_by} not {self.user_id}'
for field in source.fields.values():
if field.name == 'children':
self._compare_children(field.read_from(source), field.read_from(pub_copy), unexpected_blocks)
diff --git a/xmodule/modulestore/tests/test_xml.py b/xmodule/modulestore/tests/test_xml.py
index b22e3938b23c..df0f95230607 100644
--- a/xmodule/modulestore/tests/test_xml.py
+++ b/xmodule/modulestore/tests/test_xml.py
@@ -68,7 +68,7 @@ def test_get_courses_for_wiki(self):
for course in store.get_courses():
course_locations = store.get_courses_for_wiki(course.wiki_slug)
assert len(course_locations) == 1
- assert course.location.course_key in course_locations
+ assert course.usage_key.course_key in course_locations
course_locations = store.get_courses_for_wiki('no_such_wiki')
assert len(course_locations) == 0
@@ -104,7 +104,7 @@ def test_branch_setting(self):
# XML store allows published_only branch setting
with store.branch_setting(ModuleStoreEnum.Branch.published_only, course.id):
- store.get_item(course.location)
+ store.get_item(course.usage_key)
# XML store does NOT allow draft_preferred branch setting
with pytest.raises(ValueError):
@@ -133,8 +133,8 @@ def test_dag_course(self, mock_logging):
parent = shared_item.get_parent()
assert parent is not None, 'get_parent failed to return a value'
parent_loc = course_key.make_usage_key('vertical', 'vertical_test')
- assert parent.location == parent_loc
- assert shared_item.location in [x.location for x in parent.get_children()]
+ assert parent.usage_key == parent_loc
+ assert shared_item.usage_key in [x.usage_key for x in parent.get_children()]
# ensure it's still a child of the other parent even tho it doesn't claim the other parent as its parent
other_parent_loc = course_key.make_usage_key('vertical', 'zeta')
other_parent = store.get_item(other_parent_loc)
diff --git a/xmodule/modulestore/tests/test_xml_importer.py b/xmodule/modulestore/tests/test_xml_importer.py
index 9568686d98fa..043e179bfb92 100644
--- a/xmodule/modulestore/tests/test_xml_importer.py
+++ b/xmodule/modulestore/tests/test_xml_importer.py
@@ -175,7 +175,7 @@ def _check_explicitly_set(self, block, scope, expected_explicitly_set_fields, sh
def test_update_locations_native_xblock(self):
""" Update locations updates location and keeps values and "is_set_on" status """
# Set the XBlock's location
- self.xblock.location = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
+ self.xblock.usage_key = BlockUsageLocator(CourseLocator("org", "import", "run"), "category", "stubxblock")
# Explicitly set the content, settings and children fields
self.xblock.test_content_field = 'Explicitly set'
@@ -186,12 +186,12 @@ def test_update_locations_native_xblock(self):
self.xblock.save()
# Update location
- target_location = self.xblock.location.replace(revision='draft')
+ target_location = self.xblock.usage_key.replace(revision='draft')
_update_block_location(self.xblock, target_location)
new_version = self.xblock # _update_block_location updates in-place
# Check the XBlock's location
- assert new_version.location == target_location
+ assert new_version.usage_key == target_location
# Check the values of the fields.
# The content, settings and children fields should be preserved
diff --git a/xmodule/modulestore/tests/utils.py b/xmodule/modulestore/tests/utils.py
index 8cac4bf72831..786099991d28 100644
--- a/xmodule/modulestore/tests/utils.py
+++ b/xmodule/modulestore/tests/utils.py
@@ -111,7 +111,7 @@ def make_block(self, category, parent_block, **kwargs):
return BlockFactory.create(
category=category,
parent=parent_block,
- parent_location=parent_block.location,
+ parent_location=parent_block.usage_key,
modulestore=self.store,
**extra
)
@@ -140,7 +140,7 @@ def descend(parent, stack):
user_id=user_id
)
self.populated_usage_keys.setdefault(xblock_type, []).append(
- child.location
+ child.usage_key
)
descend(child, stack[1:])
diff --git a/xmodule/modulestore/xml.py b/xmodule/modulestore/xml.py
index 679612fde679..ef3729c65f18 100644
--- a/xmodule/modulestore/xml.py
+++ b/xmodule/modulestore/xml.py
@@ -329,7 +329,7 @@ def fallback_name(orig_name=None):
for child in block.get_children():
# parent is alphabetically least
if child.parent is None or child.parent > block.scope_ids.usage_id:
- child.parent = block.location
+ child.parent = block.usage_key
child.save()
# After setting up the block, save any changes that we have
@@ -972,7 +972,7 @@ def get_courses_for_wiki(self, wiki_slug, **kwargs):
:return: list of course locations
"""
courses = self.get_courses()
- return [course.location.course_key for course in courses if course.wiki_slug == wiki_slug]
+ return [course.usage_key.course_key for course in courses if course.wiki_slug == wiki_slug]
def heartbeat(self):
"""
@@ -1051,7 +1051,7 @@ def get_library(self, library_id, depth=0, **kwargs): # pylint: disable=unused-
"""
assert isinstance(library_id, LibraryLocator)
for library in self.get_courses(**kwargs):
- if library.location.library_key == library_id:
+ if library.usage_key.library_key == library_id:
return library
return None
@@ -1060,7 +1060,7 @@ def id_from_block(block):
"""
Get the Library Key from the Library block.
"""
- return block.location.library_key
+ return block.usage_key.library_key
def get_orphans(self, course_key, **kwargs):
"""
diff --git a/xmodule/modulestore/xml_exporter.py b/xmodule/modulestore/xml_exporter.py
index eb6341defad0..7d65cee17a7f 100644
--- a/xmodule/modulestore/xml_exporter.py
+++ b/xmodule/modulestore/xml_exporter.py
@@ -56,7 +56,7 @@ def _export_drafts(modulestore, course_key, export_fs, xml_centric_course_key):
for draft_block in draft_blocks:
parent_loc = modulestore.get_parent_location(
- draft_block.location,
+ draft_block.usage_key,
revision=ModuleStoreEnum.RevisionOption.draft_preferred
)
@@ -67,8 +67,8 @@ def _export_drafts(modulestore, course_key, export_fs, xml_centric_course_key):
draft_node = draft_node_constructor(
draft_block,
- location=draft_block.location,
- url=str(draft_block.location),
+ location=draft_block.usage_key,
+ url=str(draft_block.usage_key),
parent_location=parent_loc,
parent_url=parent_url,
)
@@ -94,9 +94,9 @@ def _export_drafts(modulestore, course_key, export_fs, xml_centric_course_key):
parent = modulestore.get_item(draft_node.parent_location)
# Don't try to export orphaned items
- if draft_node.module.location not in parent.children:
+ if draft_node.module.usage_key not in parent.children:
continue
- index = parent.children.index(draft_node.module.location)
+ index = parent.children.index(draft_node.module.usage_key)
draft_node.module.xml_attributes['index_in_children_list'] = str(index)
draft_node.module.runtime.export_fs = draft_course_dir
@@ -278,7 +278,7 @@ def process_extra(self, root, courselike, root_courselike_dir, xml_centric_cours
'about', 'about', '.html'
)
- course_policy_dir_name = courselike.location.run
+ course_policy_dir_name = courselike.usage_key.run
course_run_policy_dir = policies_dir.makedir(course_policy_dir_name, recreate=True)
# export the grading policy
@@ -289,7 +289,7 @@ def process_extra(self, root, courselike, root_courselike_dir, xml_centric_cours
# export all of the course metadata in policy.json
set_custom_attribute("export_policy_started", str(courselike))
with course_run_policy_dir.open('policy.json', 'wb') as course_policy:
- policy = {'course/' + courselike.location.run: own_metadata(courselike)}
+ policy = {'course/' + courselike.usage_key.run: own_metadata(courselike)}
course_policy.write(dumps(policy, cls=EdxJSONEncoder, sort_keys=True, indent=4).encode('utf-8'))
set_custom_attribute("export_drafts_started", str(courselike))
@@ -408,7 +408,7 @@ def _export_field_content(xblock_item, item_dir):
for field_name in block_data:
if field_name not in DEFAULT_CONTENT_FIELDS:
# filename format: {dirname}.{field_name}.json
- with item_dir.open('{}.{}.{}'.format(xblock_item.location.block_id, field_name, 'json'),
+ with item_dir.open('{}.{}.{}'.format(xblock_item.usage_key.block_id, field_name, 'json'),
'wb') as field_content_file:
field_content_file.write(dumps(block_data.get(field_name, {}), cls=EdxJSONEncoder,
sort_keys=True, indent=4).encode('utf-8'))
@@ -421,7 +421,7 @@ def export_extra_content(export_fs, modulestore, source_course_key, dest_course_
item_dir = export_fs.makedir(dirname, recreate=True)
for item in items:
adapt_references(item, dest_course_key, export_fs)
- with item_dir.open(item.location.block_id + file_suffix, 'wb') as item_file:
+ with item_dir.open(item.usage_key.block_id + file_suffix, 'wb') as item_file:
item_file.write(item.data.encode('utf8'))
# export content fields other then metadata and data in json format in current directory
diff --git a/xmodule/modulestore/xml_importer.py b/xmodule/modulestore/xml_importer.py
index 8ee98a8b7c43..3e8eb76c2f00 100644
--- a/xmodule/modulestore/xml_importer.py
+++ b/xmodule/modulestore/xml_importer.py
@@ -493,7 +493,7 @@ def recursive_build(self, source_courselike, courselike, courselike_key, dest_id
target modulestore.
"""
all_locs = set(self.xml_module_store.modules[courselike_key].keys())
- all_locs.remove(source_courselike.location)
+ all_locs.remove(source_courselike.usage_key)
def depth_first(subtree):
"""
@@ -502,13 +502,13 @@ def depth_first(subtree):
if subtree.has_children:
for child in subtree.get_children():
try:
- all_locs.remove(child.location)
+ all_locs.remove(child.usage_key)
except KeyError:
# tolerate same child occurring under 2 parents such as in
# ContentStoreTest.test_image_import
pass
if self.verbose:
- log.debug('importing block location %s', child.location)
+ log.debug('importing block location %s', child.usage_key)
try:
_update_and_import_block(
@@ -522,9 +522,9 @@ def depth_first(subtree):
)
except Exception:
log.exception(
- f'Course import {dest_id}: failed to import block location {child.location}'
+ f'Course import {dest_id}: failed to import block location {child.usage_key}'
)
- raise BlockFailedToImport(child.display_name, child.location) # pylint: disable=raise-missing-from
+ raise BlockFailedToImport(child.display_name, child.usage_key) # pylint: disable=raise-missing-from
depth_first(child)
@@ -549,7 +549,7 @@ def depth_first(subtree):
f'Course import {dest_id}: failed to import block location {leftover}'
)
# pylint: disable=raise-missing-from
- raise BlockFailedToImport(leftover.display_name, leftover.location)
+ raise BlockFailedToImport(leftover.display_name, leftover.usage_key)
def post_course_import(self, dest_id):
"""
@@ -760,7 +760,7 @@ def get_dest_id(self, courselike_key):
runtime = None
if existing_lib:
- dest_id = existing_lib.location.library_key
+ dest_id = existing_lib.usage_key.library_key
runtime = existing_lib.runtime
if self.create_if_not_present and not existing_lib:
@@ -842,7 +842,7 @@ def _update_and_import_block( # pylint: disable=too-many-statements
Update all the block reference fields to the destination course id,
then import the block into the destination course.
"""
- logging.debug('processing import of blocks %s...', str(block.location))
+ logging.debug('processing import of blocks %s...', str(block.usage_key))
def _update_block_references(block, source_course_id, dest_course_id):
"""
@@ -909,13 +909,13 @@ def _convert_ref_fields_to_new_namespace(reference):
fields = _update_block_references(block, source_course_id, dest_course_id)
asides = block.get_asides() if isinstance(block, XModuleMixin) else None
- if block.location.block_type == 'library_content':
+ if block.usage_key.block_type == 'library_content':
with store.branch_setting(branch_setting=ModuleStoreEnum.Branch.published_only):
- lib_content_block_already_published = store.has_item(block.location)
+ lib_content_block_already_published = store.has_item(block.usage_key)
block = store.import_xblock(
- user_id, dest_course_id, block.location.block_type,
- block.location.block_id, fields, runtime, asides=asides
+ user_id, dest_course_id, block.usage_key.block_type,
+ block.usage_key.block_id, fields, runtime, asides=asides
)
# TODO: Move this code once the following condition is met.
@@ -926,7 +926,7 @@ def _convert_ref_fields_to_new_namespace(reference):
# Special case handling for library content blocks. The fact that this is
# in Modulestore code is _bad_ and breaks abstraction barriers, but is too
# much work to factor out at this point.
- if block.location.block_type == 'library_content':
+ if block.usage_key.block_type == 'library_content':
# If library exists, update source_library_version and children
# according to this existing library and library content block.
if block.source_library_id and store.get_library(block.source_library_key):
@@ -965,7 +965,7 @@ def _convert_ref_fields_to_new_namespace(reference):
else:
# Publish it if importing the course for branch setting published_only.
if store.get_branch_setting() == ModuleStoreEnum.Branch.published_only:
- store.publish(block.location, user_id)
+ store.publish(block.usage_key, user_id)
return block
@@ -1015,7 +1015,7 @@ def _import_course_draft(
def _import_block(block):
# IMPORTANT: Be sure to update the block location in the NEW namespace
- block_location = block.location.map_into_course(target_id)
+ block_location = block.usage_key.map_into_course(target_id)
# Update the block's location to DRAFT revision
# We need to call this method (instead of updating the location directly)
# to ensure that pure XBlock field data is updated correctly.
@@ -1029,7 +1029,7 @@ def _import_block(block):
# in the list of children since they would have been
# filtered out from the non-draft store export.
if parent_url is not None and index is not None:
- course_key = block.location.course_key
+ course_key = block.usage_key.course_key
parent_location = UsageKey.from_string(parent_url).map_into_course(course_key)
# IMPORTANT: Be sure to update the parent in the NEW namespace
@@ -1037,8 +1037,8 @@ def _import_block(block):
parent = store.get_item(parent_location, depth=0)
- non_draft_location = block.location.map_into_course(target_id)
- if not any(child.block_id == block.location.block_id for child in parent.children):
+ non_draft_location = block.usage_key.map_into_course(target_id)
+ if not any(child.block_id == block.usage_key.block_id for child in parent.children):
parent.children.insert(index, non_draft_location)
store.update_item(parent, user_id)
@@ -1081,11 +1081,11 @@ def _import_block(block):
# aka sequential), so we have to replace the location.name
# with the XML filename that is part of the pack
filename, __ = os.path.splitext(filename)
- block.location = block.location.replace(name=filename)
+ block.usage_key = block.usage_key.replace(name=filename)
index = index_in_children_list(block)
parent_url = get_parent_url(block, xml)
- draft_url = str(block.location)
+ draft_url = str(block.usage_key)
draft = draft_node_constructor(
block=block, url=draft_url, parent_url=parent_url, index=index
@@ -1120,7 +1120,7 @@ def check_block_metadata_editability(block):
we can't support editing. However we always allow 'display_name'
and 'xml_attributes'
"""
- allowed = allowed_metadata_by_category(block.location.block_type)
+ allowed = allowed_metadata_by_category(block.usage_key.block_type)
if '*' in allowed:
# everything is allowed
return 0
@@ -1134,7 +1134,7 @@ def check_block_metadata_editability(block):
print(
": found non-editable metadata on {url}. "
"These metadata keys are not supported = {keys}".format(
- url=str(block.location), keys=illegal_keys
+ url=str(block.usage_key), keys=illegal_keys
)
)
@@ -1195,7 +1195,7 @@ def validate_no_non_editable_metadata(module_store, course_id, category): # lin
err_cnt = 0
for block_loc in module_store.modules[course_id]:
block = module_store.modules[course_id][block_loc]
- if block.location.block_type == category:
+ if block.usage_key.block_type == category:
err_cnt = err_cnt + check_block_metadata_editability(block)
return err_cnt
@@ -1208,7 +1208,7 @@ def validate_category_hierarchy( # lint-amnesty, pylint: disable=missing-functi
parents = []
# get all blocks of parent_category
for block in module_store.modules[course_id].values():
- if block.location.block_type == parent_category:
+ if block.usage_key.block_type == parent_category:
parents.append(block)
for parent in parents:
@@ -1218,7 +1218,7 @@ def validate_category_hierarchy( # lint-amnesty, pylint: disable=missing-functi
print(
"ERROR: child {child} of parent {parent} was expected to be "
"category of {expected} but was {actual}".format(
- child=child_loc, parent=parent.location,
+ child=child_loc, parent=parent.usage_key,
expected=expected_child_category,
actual=child_loc.block_type
)
@@ -1264,7 +1264,7 @@ def validate_course_policy(module_store, course_id):
# is there a reliable way to get the block location just given the course_id?
warn_cnt = 0
for block in module_store.modules[course_id].values():
- if block.location.block_type == 'course':
+ if block.usage_key.block_type == 'course':
if not block._field_data.has(block, 'rerandomize'): # lint-amnesty, pylint: disable=protected-access
warn_cnt += 1
print(
@@ -1407,7 +1407,7 @@ def _update_block_location(block, new_location):
list(block.get_explicitly_set_fields_by_scope(Scope.children).keys())
)
- block.location = new_location
+ block.usage_key = new_location
# Pure XBlocks store the field data in a key-value store
# in which one component of the key is the XBlock's location (equivalent to "scope_ids").
diff --git a/xmodule/poll_block.py b/xmodule/poll_block.py
index 004572faf7d1..6cc5f14dd658 100644
--- a/xmodule/poll_block.py
+++ b/xmodule/poll_block.py
@@ -140,8 +140,8 @@ def student_view(self, _context):
"""
fragment = Fragment()
params = {
- 'element_id': self.location.html_id(),
- 'element_class': self.location.block_type,
+ 'element_id': self.usage_key.html_id(),
+ 'element_class': self.usage_key.block_type,
'ajax_url': self.ajax_url,
'configuration_json': self.dump_poll(),
}
diff --git a/xmodule/raw_block.py b/xmodule/raw_block.py
index 6ee1852a9a5a..5c633325a266 100644
--- a/xmodule/raw_block.py
+++ b/xmodule/raw_block.py
@@ -41,8 +41,8 @@ def definition_to_xml(self, resource_fs): # pylint: disable=unused-argument
if not self.data:
log.warning(
"Could not serialize %s: No XBlock installed for '%s' tag.",
- self.location,
- self.location.block_type,
+ self.usage_key,
+ self.usage_key.block_type,
)
return None
@@ -55,10 +55,10 @@ def definition_to_xml(self, resource_fs): # pylint: disable=unused-argument
lines = self.data.split("\n")
line, offset = err.position
msg = (
- f"Unable to create xml for block {self.location}. "
+ f"Unable to create xml for block {self.usage_key}. "
f"Context: '{lines[line - 1][offset - 40 : offset + 40]}'"
)
- raise SerializationError(self.location, msg) from err
+ raise SerializationError(self.usage_key, msg) from err
@classmethod
def parse_xml_new_runtime(cls, node, runtime, keys):
diff --git a/xmodule/seq_block.py b/xmodule/seq_block.py
index 5c353161024e..ebf9096ddddc 100644
--- a/xmodule/seq_block.py
+++ b/xmodule/seq_block.py
@@ -571,12 +571,12 @@ def _get_render_metadata(self, context, children, prereq_met, prereq_meta_info,
params = {
'items': blocks,
- 'element_id': self.location.html_id(),
- 'item_id': str(self.location),
+ 'element_id': self.usage_key.html_id(),
+ 'item_id': str(self.usage_key),
'is_time_limited': self.is_time_limited,
'is_proctored': self.is_proctored_enabled,
'position': self.position,
- 'tag': self.location.block_type,
+ 'tag': self.usage_key.block_type,
'next_url': context.get('next_url'),
'prev_url': context.get('prev_url'),
'banner_text': banner_text,
@@ -647,7 +647,7 @@ def _is_gate_fulfilled(self):
if gating_service:
user_id = self.runtime.service(self, 'user').get_current_user().opt_attrs.get(ATTR_KEY_USER_ID)
fulfilled = gating_service.is_gate_fulfilled(
- self.scope_ids.usage_id.context_key, self.location, user_id
+ self.scope_ids.usage_id.context_key, self.usage_key, user_id
)
return fulfilled
@@ -663,7 +663,7 @@ def _required_prereq(self):
gating_service = self.runtime.service(self, 'gating')
if gating_service:
milestone = gating_service.required_prereq(
- self.scope_ids.usage_id.context_key, self.location, 'requires'
+ self.scope_ids.usage_id.context_key, self.usage_key, 'requires'
)
return milestone
@@ -728,7 +728,7 @@ def _compute_is_prereq_met(self, recalc_on_unmet):
gating_service = self.runtime.service(self, 'gating')
if gating_service:
user_id = self.runtime.service(self, 'user').get_current_user().opt_attrs.get(ATTR_KEY_USER_ID)
- return gating_service.compute_is_prereq_met(self.location, user_id, recalc_on_unmet)
+ return gating_service.compute_is_prereq_met(self.usage_key, user_id, recalc_on_unmet)
return True, {}
@@ -819,7 +819,7 @@ def _render_student_view_for_blocks(self, context, children, fragment, view=STUD
# context['item_url'] = '/my/item/path/{usage_key}/whatever'
block_info['href'] = context.get('item_url', '').format(usage_key=usage_id)
if is_user_authenticated:
- if block.location.block_type == 'vertical' and completion_service:
+ if block.usage_key.block_type == 'vertical' and completion_service:
block_info['complete'] = completion_service.vertical_is_complete(block)
contents.append(block_info)
@@ -837,7 +837,7 @@ def _locations_in_subtree(self, node):
while stack:
curr = stack.pop()
- locations.append(curr.location)
+ locations.append(curr.usage_key)
if curr.has_children:
stack.extend(curr.get_children())
@@ -847,7 +847,7 @@ def _capture_basic_metrics(self):
"""
Capture basic information about this sequence in telemetry.
"""
- set_custom_attribute('seq.block_id', str(self.location))
+ set_custom_attribute('seq.block_id', str(self.usage_key))
set_custom_attribute('seq.display_name', self.display_name or '')
set_custom_attribute('seq.position', self.position)
set_custom_attribute('seq.is_time_limited', self.is_time_limited)
@@ -882,7 +882,7 @@ def _capture_current_unit_metrics(self, children):
if 1 <= self.position <= len(children):
# Basic info about the Unit...
current = children[self.position - 1]
- set_custom_attribute('seq.current.block_id', str(current.location))
+ set_custom_attribute('seq.current.block_id', str(current.usage_key))
set_custom_attribute('seq.current.display_name', current.display_name or '')
# Examining all blocks inside the Unit (or split_test, conditional, etc.)
@@ -918,7 +918,7 @@ def _time_limited_student_view(self):
user_is_staff = current_user.opt_attrs.get(ATTR_KEY_USER_IS_STAFF)
user_role_in_course = 'staff' if user_is_staff else 'student'
course_id = self.scope_ids.usage_id.context_key
- content_id = self.location
+ content_id = self.usage_key
course = self._get_course()
# LTI exam tools are not managed by the edx-proctoring library
diff --git a/xmodule/split_test_block.py b/xmodule/split_test_block.py
index f259ef40e7bb..326fdf4be93e 100644
--- a/xmodule/split_test_block.py
+++ b/xmodule/split_test_block.py
@@ -185,7 +185,7 @@ def child(self):
except AttributeError:
log.warning(
"Error while getting block instance for descriptor with location: [%s]",
- self.location
+ self.usage_key
)
return None
@@ -196,7 +196,7 @@ def get_child_block_by_location(self, location):
If none match, return None
"""
for child in self.get_children():
- if child.location == location:
+ if child.usage_key == location:
return child
return None
@@ -232,13 +232,13 @@ def get_child_blocks(self):
except NoSuchServiceError:
log.warning(
"Error while getting user service in runtime with location: [%s]",
- self.location
+ self.usage_key
)
return []
except ValueError:
log.warning(
"Error while getting group ID for partition with location: [%s]",
- self.location
+ self.usage_key
)
return []
@@ -293,7 +293,7 @@ def _staff_view(self, context):
updated_group_id = [g_id for g_id, loc in self.group_id_to_child.items() if loc == child_location][0]
inactive_contents.append({
'group_name': _('{group_name} (inactive)').format(group_name=group_name),
- 'id': str(child.location),
+ 'id': str(child.usage_key),
'content': rendered_child.content,
'group_id': updated_group_id,
})
@@ -301,7 +301,7 @@ def _staff_view(self, context):
active_contents.append({
'group_name': group_name,
- 'id': str(child.location),
+ 'id': str(child.usage_key),
'content': rendered_child.content,
'group_id': updated_group_id,
})
@@ -325,7 +325,7 @@ def author_view(self, context):
"""
fragment = Fragment()
root_xblock = context.get('root_xblock')
- is_root = root_xblock and root_xblock.location == self.location
+ is_root = root_xblock and root_xblock.usage_key == self.usage_key
active_groups_preview = None
inactive_groups_preview = None
@@ -415,7 +415,7 @@ def log_child_render(self, request, suffix=''): # lint-amnesty, pylint: disable
except Exception:
log.info(
"Can't get usage_id of Nonetype object in course {course_key}".format(
- course_key=str(self.location.course_key)
+ course_key=str(self.usage_key.course_key)
)
)
raise
@@ -440,7 +440,7 @@ def get_data_for_vertical(self, vertical):
for group in user_partition.groups:
group_id = str(group.id)
child_location = self.group_id_to_child.get(group_id, None)
- if child_location == vertical.location:
+ if child_location == vertical.usage_key:
return (group.name, group.id)
return (None, None)
@@ -576,7 +576,7 @@ def get_child_block(location):
Returns the child block which matches the specified location, or None if one is not found.
"""
for child in children:
- if child.location == location:
+ if child.usage_key == location:
return child
return None
@@ -627,7 +627,7 @@ def validate_split_test(self):
(not including superclass validation messages).
"""
_ = self.runtime.service(self, "i18n").ugettext
- split_validation = StudioValidation(self.location)
+ split_validation = StudioValidation(self.usage_key)
if self.user_partition_id < 0:
split_validation.add(
StudioValidationMessage(
@@ -722,13 +722,13 @@ def group_configuration_url(self): # lint-amnesty, pylint: disable=missing-func
assert hasattr(self.runtime, 'modulestore') and hasattr(self.runtime.modulestore, 'get_course'), \
"modulestore has to be available"
- course_block = self.runtime.modulestore.get_course(self.location.course_key)
+ course_block = self.runtime.modulestore.get_course(self.usage_key.course_key)
group_configuration_url = None
if 'split_test' in course_block.advanced_modules:
user_partition = self.get_selected_partition()
if user_partition:
group_configuration_url = "{url}#{configuration_id}".format(
- url='/group_configurations/' + str(self.location.course_key),
+ url='/group_configurations/' + str(self.usage_key.course_key),
configuration_id=str(user_partition.id)
)
@@ -745,11 +745,11 @@ def _create_vertical_for_group(self, group, user_id):
assert hasattr(self.runtime, 'modulestore') and hasattr(self.runtime.modulestore, 'create_item'), \
"editor_saved should only be called when a mutable modulestore is available"
modulestore = self.runtime.modulestore
- dest_usage_key = self.location.replace(category="vertical", name=uuid4().hex)
+ dest_usage_key = self.usage_key.replace(category="vertical", name=uuid4().hex)
metadata = {'display_name': DEFAULT_GROUP_NAME.format(group_id=group.id)}
modulestore.create_item(
user_id,
- self.location.course_key,
+ self.usage_key.course_key,
dest_usage_key.block_type,
block_id=dest_usage_key.block_id,
definition_data=None,
diff --git a/xmodule/studio_editable.py b/xmodule/studio_editable.py
index d190c966cab8..05de7b58c5ba 100644
--- a/xmodule/studio_editable.py
+++ b/xmodule/studio_editable.py
@@ -25,13 +25,13 @@ def render_children(self, context, fragment, can_reorder=False, can_add=False):
for child in self.get_children(): # pylint: disable=no-member
if can_reorder:
- context['reorderable_items'].add(child.location)
+ context['reorderable_items'].add(child.usage_key)
context['can_add'] = can_add
rendered_child = child.render(StudioEditableBlock.get_preview_view_name(child), context)
fragment.add_fragment_resources(rendered_child)
contents.append({
- 'id': str(child.location),
+ 'id': str(child.usage_key),
'content': rendered_child.content
})
diff --git a/xmodule/template_block.py b/xmodule/template_block.py
index 37d2fac905a6..12ae41eb9ec8 100644
--- a/xmodule/template_block.py
+++ b/xmodule/template_block.py
@@ -90,7 +90,7 @@ def render_template(self, system, xml_data):
params = dict(list(xmltree.items()))
# cdodge: look up the template as a module
- template_loc = self.location.replace(category='custom_tag_template', name=template_name)
+ template_loc = self.usage_key.replace(category='custom_tag_template', name=template_name)
try:
template_block = system.get_block(template_loc)
template_block_data = template_block.data
diff --git a/xmodule/templates.py b/xmodule/templates.py
index ccbf6a80a207..1e06a407c0ec 100644
--- a/xmodule/templates.py
+++ b/xmodule/templates.py
@@ -30,7 +30,7 @@ def all_templates():
course = CourseFactory.create()
for category, _ in XBlock.load_classes():
- loaded_block = BlockFactory.create(category=category, parent_location=course.location)
+ loaded_block = BlockFactory.create(category=category, parent_location=course.usage_key)
if not hasattr(loaded_block, 'templates'):
continue
templates[category] = loaded_block.templates()
diff --git a/xmodule/tests/__init__.py b/xmodule/tests/__init__.py
index 4833c4cf0c24..4afae5a2f705 100644
--- a/xmodule/tests/__init__.py
+++ b/xmodule/tests/__init__.py
@@ -439,24 +439,24 @@ def _assertCoursesEqual(self, expected_items, actual_items, actual_course_key, e
def map_key(usage_key):
return (usage_key.block_type, usage_key.block_id)
actual_item_map = {
- map_key(item.location): item
+ map_key(item.usage_key): item
for item in actual_items
}
# Split Mongo and Old-Mongo disagree about what the block_id of courses is, so skip those in
# this comparison
self.assertCountEqual(
- [map_key(item.location) for item in expected_items if item.scope_ids.block_type != 'course'],
+ [map_key(item.usage_key) for item in expected_items if item.scope_ids.block_type != 'course'],
[key for key in actual_item_map.keys() if key[0] != 'course'],
)
for expected_item in expected_items:
- actual_item_location = actual_course_key.make_usage_key(expected_item.category, expected_item.location.block_id) # lint-amnesty, pylint: disable=line-too-long
+ actual_item_location = actual_course_key.make_usage_key(expected_item.category, expected_item.usage_key.block_id) # lint-amnesty, pylint: disable=line-too-long
# split and old mongo use different names for the course root but we don't know which
# modulestore actual's come from here; so, assume old mongo and if that fails, assume split
- if expected_item.location.block_type == 'course':
+ if expected_item.usage_key.block_type == 'course':
actual_item_location = actual_item_location.replace(name=actual_item_location.run)
actual_item = actual_item_map.get(map_key(actual_item_location))
# must be split
- if actual_item is None and expected_item.location.block_type == 'course':
+ if actual_item is None and expected_item.usage_key.block_type == 'course':
actual_item_location = actual_item_location.replace(name='course')
actual_item = actual_item_map.get(map_key(actual_item_location))
# Formatting the message slows down tests of large courses significantly, so only do it if it would be used
@@ -478,12 +478,12 @@ def map_key(usage_key):
assert expected_item.has_children == actual_item.has_children
if expected_item.has_children:
expected_children = [
- (expected_item_child.location.block_type, expected_item_child.location.block_id)
+ (expected_item_child.usage_key.block_type, expected_item_child.usage_key.block_id)
# get_children() rather than children to strip privates from public parents
for expected_item_child in expected_item.get_children()
]
actual_children = [
- (item_child.location.block_type, item_child.location.block_id)
+ (item_child.usage_key.block_type, item_child.usage_key.block_id)
# get_children() rather than children to strip privates from public parents
for item_child in actual_item.get_children()
]
diff --git a/xmodule/tests/test_capa_block.py b/xmodule/tests/test_capa_block.py
index 61c66eefe467..86ff15925be3 100644
--- a/xmodule/tests/test_capa_block.py
+++ b/xmodule/tests/test_capa_block.py
@@ -2440,7 +2440,7 @@ def test_demand_hint_logging(self):
mock_publish.assert_called_with(
block,
"edx.problem.hint.demandhint_displayed",
- {"hint_index": 0, "module_id": str(block.location), "hint_text": "Demand 1", "hint_len": 2},
+ {"hint_index": 0, "module_id": str(block.usage_key), "hint_text": "Demand 1", "hint_len": 2},
)
def test_input_state_consistency(self):
@@ -2847,7 +2847,7 @@ def test_problem_no_display_name(self, display_name, render_template):
block.get_problem_html()
render_args, _ = render_template.call_args
context = render_args[1]
- assert context["problem"]["name"] == block.location.block_type
+ assert context["problem"]["name"] == block.usage_key.block_type
@ddt.ddt
diff --git a/xmodule/tests/test_conditional.py b/xmodule/tests/test_conditional.py
index 8eb9e9ac071d..cb00fbf04d5d 100644
--- a/xmodule/tests/test_conditional.py
+++ b/xmodule/tests/test_conditional.py
@@ -83,7 +83,7 @@ def create(system, source_is_error_block=False, source_visible_to_staff_only=Fal
)
else:
source_block = Mock(name='source_block')
- source_block.location = source_location
+ source_block.usage_key = source_location
source_block.visible_to_staff_only = source_visible_to_staff_only
source_block.runtime = system
@@ -96,7 +96,7 @@ def create(system, source_is_error_block=False, source_visible_to_staff_only=Fal
child_block.student_view = child_block._xmodule.student_view # lint-amnesty, pylint: disable=protected-access
child_block.runtime = system
child_block.render = lambda view, context=None: system.render(child_block, view, context)
- child_block.location = source_location.replace(category='html', name='child')
+ child_block.usage_key = source_location.replace(category='html', name='child')
def visible_to_nonstaff_users(desc):
"""
@@ -107,7 +107,7 @@ def visible_to_nonstaff_users(desc):
def load_item(usage_id, for_parent=None): # pylint: disable=unused-argument
"""Test-only implementation of load_item that simply returns static xblocks."""
return {
- child_block.location: child_block,
+ child_block.usage_key: child_block,
source_location: source_block
}.get(usage_id)
@@ -121,7 +121,7 @@ def load_item(usage_id, for_parent=None): # pylint: disable=unused-argument
'conditional_attr': 'attempted',
'conditional_value': 'true',
'xml_attributes': {'attempted': 'true'},
- 'children': [child_block.location],
+ 'children': [child_block.usage_key],
})
cond_block = ConditionalBlock(
@@ -291,7 +291,7 @@ def test_conditional_block_with_empty_sources_list(self):
dummy_scope_ids,
)
- new_run = conditional.location.course_key.run # lint-amnesty, pylint: disable=unused-variable
+ new_run = conditional.usage_key.course_key.run # lint-amnesty, pylint: disable=unused-variable
assert conditional.sources_list[0] == BlockUsageLocator.from_string(conditional.xml_attributes['sources'])\
.replace(run=dummy_location.course_key.run)
diff --git a/xmodule/tests/test_content.py b/xmodule/tests/test_content.py
index 0b566153ad7d..347b8a3d4f17 100644
--- a/xmodule/tests/test_content.py
+++ b/xmodule/tests/test_content.py
@@ -56,7 +56,7 @@ class Content:
A class with location and content_type members
"""
def __init__(self, location, content_type):
- self.location = location
+ self.usage_key = location
self.content_type = content_type
self.data = None
diff --git a/xmodule/tests/test_course_block.py b/xmodule/tests/test_course_block.py
index a7ef4181a24d..25ba75f8636a 100644
--- a/xmodule/tests/test_course_block.py
+++ b/xmodule/tests/test_course_block.py
@@ -251,12 +251,12 @@ def test_start_date_is_default(self):
def test_display_organization(self):
block = get_dummy_course(start='2012-12-02T12:00', is_new=True)
- assert block.location.org != block.display_org_with_default
+ assert block.usage_key.org != block.display_org_with_default
assert block.display_org_with_default == f'{ORG}_display'
def test_display_coursenumber(self):
block = get_dummy_course(start='2012-12-02T12:00', is_new=True)
- assert block.location.course != block.display_number_with_default
+ assert block.usage_key.course != block.display_number_with_default
assert block.display_number_with_default == f'{COURSE}_display'
def test_is_newish(self):
diff --git a/xmodule/tests/test_course_metadata_utils.py b/xmodule/tests/test_course_metadata_utils.py
index 68e7aaf1bcda..d7430e3ee312 100644
--- a/xmodule/tests/test_course_metadata_utils.py
+++ b/xmodule/tests/test_course_metadata_utils.py
@@ -133,7 +133,7 @@ def noop_gettext(text): # lint-amnesty, pylint: disable=unused-variable
TestScenario((self.html_course,), "Intro to html
"),
]),
FunctionTest(number_for_course_location, [
- TestScenario((self.html_course.location,), "CS-203"),
+ TestScenario((self.html_course.usage_key,), "CS-203"),
]),
FunctionTest(has_course_started, [
TestScenario((self.html_course.start,), False),
diff --git a/xmodule/tests/test_error_block.py b/xmodule/tests/test_error_block.py
index b585b1c439ea..796a0f93e4d9 100644
--- a/xmodule/tests/test_error_block.py
+++ b/xmodule/tests/test_error_block.py
@@ -20,7 +20,7 @@ def setUp(self):
super().setUp()
self.system = get_test_system()
self.course_id = CourseLocator('org', 'course', 'run')
- self.location = self.course_id.make_usage_key('foo', 'bar')
+ self.usage_key = self.course_id.make_usage_key('foo', 'bar')
self.valid_xml = "ABC \N{SNOWMAN}"
self.error_msg = "Error"
diff --git a/xmodule/tests/test_export.py b/xmodule/tests/test_export.py
index 7e201d4c1d97..c3b857250a75 100644
--- a/xmodule/tests/test_export.py
+++ b/xmodule/tests/test_export.py
@@ -32,7 +32,7 @@ def strip_filenames(block):
"""
Recursively strips 'filename' from all children's definitions.
"""
- print(f"strip filename from {str(block.location)}")
+ print(f"strip filename from {str(block.usage_key)}")
if block._field_data.has(block, 'filename'): # lint-amnesty, pylint: disable=protected-access
block._field_data.delete(block, 'filename') # lint-amnesty, pylint: disable=protected-access
diff --git a/xmodule/tests/test_graders.py b/xmodule/tests/test_graders.py
index ef37234a2d3d..97cdd693c075 100644
--- a/xmodule/tests/test_graders.py
+++ b/xmodule/tests/test_graders.py
@@ -72,7 +72,7 @@ class MockGrade:
def __init__(self, graded_total, location, display_name):
self.graded_total = graded_total
self.display_name = display_name
- self.location = location
+ self.usage_key = location
@property
def percent_graded(self):
diff --git a/xmodule/tests/test_import.py b/xmodule/tests/test_import.py
index c92801ad22e9..db0aaeb6ecb2 100644
--- a/xmodule/tests/test_import.py
+++ b/xmodule/tests/test_import.py
@@ -105,7 +105,7 @@ def assert_xblocks_are_good(self, block):
"",
"",
)
- @patch('xmodule.x_module.XModuleMixin.location')
+ @patch('xmodule.x_module.XModuleMixin.usage_key')
def test_parsing_pure_xblock(self, xml, mock_location):
system = self.get_system(load_error_blocks=False)
block = system.process_xml(xml)
@@ -137,7 +137,7 @@ def test_unique_url_names(self):
block1 = system.process_xml(bad_xml)
block2 = system.process_xml(bad_xml2)
- assert block1.location != block2.location
+ assert block1.usage_key != block2.usage_key
# Check that each vertical gets its very own url_name
bad_xml = ''''''
@@ -146,7 +146,7 @@ def test_unique_url_names(self):
block1 = system.process_xml(bad_xml)
block2 = system.process_xml(bad_xml2)
- assert block1.location != block2.location
+ assert block1.usage_key != block2.usage_key
def test_reimport(self):
'''Make sure an already-exported error xml tag loads properly'''
@@ -428,7 +428,7 @@ def test_metadata_inherit(self):
def check_for_key(key, node, value):
"recursive check for presence of key"
- print(f"Checking {str(node.location)}")
+ print(f"Checking {str(node.usage_key)}")
assert getattr(node, key) == value
for c in node.get_children():
check_for_key(key, c, value)
@@ -515,9 +515,9 @@ def test_colon_in_url_name(self):
ch2 = chapters[1]
assert ch2.url_name == 'secret:magic'
- print("Ch2 location: ", ch2.location)
+ print("Ch2 location: ", ch2.usage_key)
- also_ch2 = modulestore.get_item(ch2.location)
+ also_ch2 = modulestore.get_item(ch2.usage_key)
assert ch2 == also_ch2
print("making sure html loaded")
diff --git a/xmodule/tests/test_library_content.py b/xmodule/tests/test_library_content.py
index d1b0d4422b50..3424c6424984 100644
--- a/xmodule/tests/test_library_content.py
+++ b/xmodule/tests/test_library_content.py
@@ -60,7 +60,7 @@ def setUp(self):
"library_content",
self.vertical,
max_count=1,
- source_library_id=str(self.library.location.library_key)
+ source_library_id=str(self.library.usage_key.library_key)
)
self.lc_block.runtime._services.update({'library_tools': self.tools}) # pylint: disable=protected-access
@@ -73,18 +73,18 @@ def _sync_lc_block_from_library(self, upgrade_to_latest=False):
"""
self.store.update_item(self.lc_block, self.user_id)
self.lc_block.sync_from_library(upgrade_to_latest=upgrade_to_latest)
- self.lc_block = self.store.get_item(self.lc_block.location)
+ self.lc_block = self.store.get_item(self.lc_block.usage_key)
def _bind_course_block(self, block):
"""
Bind a block (part of self.course) so we can access student-specific data.
"""
- prepare_block_runtime(block.runtime, course_id=block.location.course_key)
+ prepare_block_runtime(block.runtime, course_id=block.usage_key.course_key)
block.runtime._services.update({'library_tools': self.tools}) # pylint: disable=protected-access
def get_block(descriptor):
"""Mocks module_system get_block function"""
- prepare_block_runtime(descriptor.runtime, course_id=block.location.course_key)
+ prepare_block_runtime(descriptor.runtime, course_id=block.usage_key.course_key)
descriptor.runtime.get_block_for_descriptor = get_block
descriptor.bind_for_student(self.user_id)
return descriptor
@@ -126,7 +126,7 @@ def test_initial_sync_from_library(self):
"""
Test that a lc block starts without children, but is correctly populated upon first sync.
"""
- source_library_key = self.library.location.library_key
+ source_library_key = self.library.usage_key.library_key
# Normally the children get added when the "source_libraries" setting
# is updated, but the way we do it through a factory doesn't do that.
@@ -167,7 +167,7 @@ def setUp(self):
self.lc_block.runtime.export_fs = self.export_fs # pylint: disable=protected-access
# Prepare runtime for the import.
- self.runtime = DummyModuleStoreRuntime(load_error_blocks=True, course_id=self.lc_block.location.course_key)
+ self.runtime = DummyModuleStoreRuntime(load_error_blocks=True, course_id=self.lc_block.usage_key.course_key)
self.runtime.resources_fs = self.export_fs
self.id_generator = Mock()
@@ -250,7 +250,7 @@ def _add_problems_to_library(self):
self.problem_type_lookup = {}
for problem_type in self.problem_types:
block = self.make_block("problem", self.library, data=self._get_capa_problem_type_xml(*problem_type))
- self.problem_type_lookup[block.location] = problem_type
+ self.problem_type_lookup[block.usage_key] = problem_type
def test_children_seen_by_a_user(self):
"""
@@ -290,7 +290,7 @@ def test_validation_of_course_libraries(self):
assert 'invalid' in result.summary.text
# When source_library_id is set but the block hasn't been synced, the summary should say so:
- self.lc_block.source_library_id = str(self.library.location.library_key)
+ self.lc_block.source_library_id = str(self.library.usage_key.library_key)
self.lc_block.source_library_version = None
result = self.lc_block.validate()
assert not result
@@ -572,7 +572,7 @@ def _assert_event_was_published(self, event_type):
assert len(self.publisher.call_args[0]) == 3 # pylint:disable=unsubscriptable-object
_, event_name, event_data = self.publisher.call_args[0] # pylint:disable=unsubscriptable-object
assert event_name == f'edx.librarycontentblock.content.{event_type}'
- assert event_data['location'] == str(self.lc_block.location)
+ assert event_data['location'] == str(self.lc_block.usage_key)
return event_data
def test_assigned_event(self):
@@ -581,17 +581,17 @@ def test_assigned_event(self):
"""
# In the beginning was the lc_block and it assigned one child to the student:
child = self.lc_block.get_child_blocks()[0]
- child_lib_location, child_lib_version = self.store.get_block_original_usage(child.location)
+ child_lib_location, child_lib_version = self.store.get_block_original_usage(child.usage_key)
assert isinstance(child_lib_version, ObjectId)
event_data = self._assert_event_was_published("assigned")
block_info = {
- "usage_key": str(child.location),
+ "usage_key": str(child.usage_key),
"original_usage_key": str(child_lib_location),
"original_usage_version": str(child_lib_version),
"descendants": [],
}
assert event_data ==\
- {'location': str(self.lc_block.location),
+ {'location': str(self.lc_block.usage_key),
'added': [block_info],
'result': [block_info],
'previous_count': 0, 'max_count': 1}
@@ -601,9 +601,9 @@ def test_assigned_event(self):
self.lc_block.max_count = 2
children = self.lc_block.get_child_blocks()
assert len(children) == 2
- child, new_child = children if children[0].location == child.location else reversed(children)
+ child, new_child = children if children[0].usage_key == child.usage_key else reversed(children)
event_data = self._assert_event_was_published("assigned")
- assert event_data['added'][0]['usage_key'] == str(new_child.location)
+ assert event_data['added'][0]['usage_key'] == str(new_child.usage_key)
assert len(event_data['result']) == 2
assert event_data['previous_count'] == 1
assert event_data['max_count'] == 2
@@ -612,9 +612,9 @@ def test_assigned_event_published(self):
"""
Same as test_assigned_event but uses the published branch
"""
- self.store.publish(self.course.location, self.user_id)
+ self.store.publish(self.course.usage_key, self.user_id)
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
- self.lc_block = self.store.get_item(self.lc_block.location)
+ self.lc_block = self.store.get_item(self.lc_block.usage_key)
self._bind_course_block(self.lc_block)
self.lc_block.runtime.publish = self.publisher
self.test_assigned_event()
@@ -624,7 +624,7 @@ def test_assigned_descendants(self):
Test the "assigned" event emitted includes descendant block information.
"""
# Replace the blocks in the library with a block that has descendants:
- with self.store.bulk_operations(self.library.location.library_key):
+ with self.store.bulk_operations(self.library.usage_key.library_key):
self.library.children = []
main_vertical = self.make_block("vertical", self.library)
inner_vertical = self.make_block("vertical", main_vertical)
@@ -654,9 +654,9 @@ def test_assigned_descendants(self):
# Check that "descendants" is a flat, unordered list of all of main_vertical's descendants:
descendants_expected = (
- (inner_vertical.location, course_usage_inner_vertical),
- (html_block.location, course_usage_html),
- (problem_block.location, course_usage_problem),
+ (inner_vertical.usage_key, course_usage_inner_vertical),
+ (html_block.usage_key, course_usage_html),
+ (problem_block.usage_key, course_usage_problem),
)
descendant_data_expected = {}
for lib_key, course_usage_key in descendants_expected:
@@ -703,10 +703,10 @@ def test_removed_invalid(self):
# To cause an "invalid" event, we delete all blocks from the content library
# except for one of the two already assigned to the student:
- keep_block_key = initial_blocks_assigned[0].location
+ keep_block_key = initial_blocks_assigned[0].usage_key
keep_block_lib_usage_key, keep_block_lib_version = self.store.get_block_original_usage(keep_block_key)
assert keep_block_lib_usage_key is not None
- deleted_block_key = initial_blocks_assigned[1].location
+ deleted_block_key = initial_blocks_assigned[1].usage_key
self.library.children = [keep_block_lib_usage_key]
self.store.update_item(self.library, self.user_id)
self.store.update_item(self.lc_block, self.user_id)
@@ -757,7 +757,7 @@ def setUp(self):
self.library_v2 = lib_api.ContentLibrary.objects.get(slug="mylib")
api.start_migration_to_library(
user=user,
- source_key=self.library.location.library_key,
+ source_key=self.library.usage_key.library_key,
target_library_key=self.library_v2.library_key,
target_collection_slug=None,
composition_level=CompositionLevel.Component,
diff --git a/xmodule/tests/test_library_root.py b/xmodule/tests/test_library_root.py
index bcc2b6af7174..a8b73f61b322 100644
--- a/xmodule/tests/test_library_root.py
+++ b/xmodule/tests/test_library_root.py
@@ -37,13 +37,13 @@ def test_library_author_view(self):
# Add one HTML block to the library:
BlockFactory.create(
category="html",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
modulestore=self.store,
data=message
)
- library = self.store.get_library(library.location.library_key)
+ library = self.store.get_library(library.usage_key.library_key)
context = {'reorderable_items': set(), }
# Patch the HTML block to always render "Hello world"
@@ -62,7 +62,7 @@ def test_library_author_view_with_paging(self):
blocks = [
BlockFactory.create(
category="html",
- parent_location=library.location,
+ parent_location=library.usage_key,
user_id=self.user_id,
publish_item=False,
modulestore=self.store,
@@ -70,7 +70,7 @@ def test_library_author_view_with_paging(self):
)
for i in range(5)
]
- library = self.store.get_library(library.location.library_key)
+ library = self.store.get_library(library.usage_key.library_key)
def render_and_check_contents(page, page_size):
""" Renders block and asserts on returned content """
diff --git a/xmodule/tests/test_library_tools.py b/xmodule/tests/test_library_tools.py
index 30b007c3d963..3a2955e1480c 100644
--- a/xmodule/tests/test_library_tools.py
+++ b/xmodule/tests/test_library_tools.py
@@ -55,19 +55,19 @@ def test_get_latest_library_version(self):
Covers getting results for either string library key or LibraryLocator.
"""
- lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
+ lib_key = LibraryFactory.create(modulestore=self.store).usage_key.library_key
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
# check the result using the LibraryLocator
assert isinstance(lib_key, LibraryLocator)
result = self.tools.get_latest_library_version(lib_key)
assert result
- assert result == str(lib.location.library_key.version_guid)
+ assert result == str(lib.usage_key.library_key.version_guid)
# the same check for string representation of the LibraryLocator
str_key = str(lib_key)
result = self.tools.get_latest_library_version(str_key)
assert result
- assert result == str(lib.location.library_key.version_guid)
+ assert result == str(lib.usage_key.library_key.version_guid)
@ddt.data(
'library-v1:Fake+Key',
@@ -92,10 +92,10 @@ def test_update_children(self):
"library_content",
course,
max_count=1,
- source_library_id=str(library.location.library_key)
+ source_library_id=str(library.usage_key.library_key)
)
assert len(content_block.children) == 0
self.tools.trigger_library_sync(content_block, library_version=None)
- content_block = self.store.get_item(content_block.location)
+ content_block = self.store.get_item(content_block.usage_key)
assert len(content_block.children) == 1
diff --git a/xmodule/tests/test_lti_unit.py b/xmodule/tests/test_lti_unit.py
index 316ff58f4384..695d3b59e28d 100644
--- a/xmodule/tests/test_lti_unit.py
+++ b/xmodule/tests/test_lti_unit.py
@@ -325,8 +325,8 @@ def mock_handler_url(block, handler_name, **kwargs): # pylint: disable=unused-a
assert real_outcome_service_url == (mock_url_prefix + test_service_name)
def test_resource_link_id(self):
- with patch('xmodule.lti_block.LTIBlock.location', new_callable=PropertyMock):
- self.xblock.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df'
+ with patch('xmodule.lti_block.LTIBlock.usage_key', new_callable=PropertyMock):
+ self.xblock.usage_key.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df'
expected_resource_link_id = str(parse.quote(self.unquoted_resource_link_id))
real_resource_link_id = self.xblock.get_resource_link_id()
assert real_resource_link_id == expected_resource_link_id
diff --git a/xmodule/tests/test_randomize_block.py b/xmodule/tests/test_randomize_block.py
index feffd7d2f12a..44870ec2520c 100644
--- a/xmodule/tests/test_randomize_block.py
+++ b/xmodule/tests/test_randomize_block.py
@@ -42,13 +42,13 @@ def _bind_module_system(self, block, user_id):
Bind module system to block so we can access student-specific data.
"""
user = Mock(name='get_test_system.user', id=user_id, is_staff=False)
- prepare_block_runtime(block.runtime, course_id=block.location.course_key, user=user)
+ prepare_block_runtime(block.runtime, course_id=block.usage_key.course_key, user=user)
def test_xml_export_import_cycle(self):
"""
Test the export-import cycle.
"""
- randomize_block = self.store.get_item(self.randomize_block.location)
+ randomize_block = self.store.get_item(self.randomize_block.usage_key)
expected_olx = (
'\n'
@@ -78,7 +78,7 @@ def test_xml_export_import_cycle(self):
# And compare.
assert exported_olx == expected_olx
- runtime = DummyModuleStoreRuntime(load_error_blocks=True, course_id=randomize_block.location.course_key)
+ runtime = DummyModuleStoreRuntime(load_error_blocks=True, course_id=randomize_block.usage_key.course_key)
runtime.resources_fs = export_fs
# Now import it.
@@ -94,7 +94,7 @@ def test_children_seen_by_a_user(self):
"""
Test that each student sees only one block as a child of the LibraryContent block.
"""
- randomize_block = self.store.get_item(self.randomize_block.location)
+ randomize_block = self.store.get_item(self.randomize_block.usage_key)
self._bind_module_system(randomize_block, 3)
# Make sure the runtime knows that the block's children vary per-user:
@@ -110,6 +110,6 @@ def test_children_seen_by_a_user(self):
assert len(randomize_block.get_content_titles()) == 3
# Bind to another user and check a different child block is displayed to user.
- randomize_block = self.store.get_item(self.randomize_block.location)
+ randomize_block = self.store.get_item(self.randomize_block.usage_key)
self._bind_module_system(randomize_block, 1)
assert randomize_block.get_child_blocks()[0].display_name == 'Hello HTML 2'
diff --git a/xmodule/tests/test_sequence.py b/xmodule/tests/test_sequence.py
index c299f7bed0d7..2b3e47da92b2 100644
--- a/xmodule/tests/test_sequence.py
+++ b/xmodule/tests/test_sequence.py
@@ -96,7 +96,7 @@ def _set_up_block(self, parent, index_in_parent):
block.runtime._services['bookmarks'] = Mock() # pylint: disable=protected-access
block.runtime._services['user'] = StubUserService(user=Mock()) # pylint: disable=protected-access
- block.parent = parent.location
+ block.parent = parent.usage_key
return block
def _set_up_module_system(self, block):
@@ -153,7 +153,7 @@ def test_render_student_view(self, view):
view=view
)
self._assert_view_at_position(html, expected_position=1)
- assert str(self.sequence_3_1.location) in html
+ assert str(self.sequence_3_1.usage_key) in html
assert "'gated': False" in html
assert "'next_url': 'NextSequential'" in html
assert "'prev_url': 'PrevSequential'" in html
@@ -298,7 +298,7 @@ def _assert_prereq(self, html, sequence):
html = self.get_context_dict_from_string(html)
assert 'This section is a prerequisite. You must complete this section in order to unlock additional content.' == html['banner_text']
assert not html['gated_content']['gated']
- assert str(sequence.location) == html['item_id']
+ assert str(sequence.usage_key) == html['item_id']
assert html['gated_content']['prereq_url'] is None
assert html['gated_content']['prereq_section_name'] is None
assert 'NextSequential' == html['next_url']
@@ -311,7 +311,7 @@ def _assert_ungated(self, html, sequence):
assert 'seq_block.html' in html
assert "'banner_text': None" in html
assert "'gated': False" in html
- assert str(sequence.location) in html
+ assert str(sequence.usage_key) in html
assert "'prereq_url': None" in html
assert "'prereq_section_name': None" in html
assert "'next_url': 'NextSequential'" in html
@@ -372,7 +372,7 @@ def test_xblock_handler_get_completion_success(self):
return_value=Mock(vertical_is_complete=Mock(return_value=True))
)
for child in self.sequence_3_1.get_children():
- usage_key = str(child.location)
+ usage_key = str(child.usage_key)
request = RequestFactory().post(
'/',
data=json.dumps({'usage_key': usage_key}),
@@ -398,7 +398,7 @@ def test_handle_ajax_get_completion_success(self):
return_value=Mock(vertical_is_complete=Mock(return_value=True))
)
for child in self.sequence_3_1.get_children():
- usage_key = str(child.location)
+ usage_key = str(child.usage_key)
completion_return = self.sequence_3_1.handle_ajax('get_completion', {'usage_key': usage_key})
assert json.loads(completion_return) == {'complete': True}
self.sequence_3_1.runtime._services['completion'] = None # pylint: disable=protected-access
diff --git a/xmodule/tests/test_split_test_block.py b/xmodule/tests/test_split_test_block.py
index 7acbaa25f6ba..0c8ec4ab5a8b 100644
--- a/xmodule/tests/test_split_test_block.py
+++ b/xmodule/tests/test_split_test_block.py
@@ -538,8 +538,8 @@ def setUp(self):
for i in range(1, 3)
]
self.split_test_block.group_id_to_child = {
- '0': self.child_blocks[0].location,
- '1': self.child_blocks[1].location,
+ '0': self.child_blocks[0].usage_key,
+ '1': self.child_blocks[1].usage_key,
}
self.store.update_item(self.split_test_block, self.user_id)
@@ -547,19 +547,19 @@ def test_xml_export_import_cycle(self):
"""
Test the export-import cycle.
"""
- split_test_block = self.store.get_item(self.split_test_block.location)
+ split_test_block = self.store.get_item(self.split_test_block.usage_key)
expected_olx = (
'\n'
- ' \n'
- ' \n'
+ '