refactor: convert course_module term to course_block
This commit is contained in:
@@ -111,9 +111,9 @@ class AdvancedCourseSettingsView(DeveloperErrorViewMixin, APIView):
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
if not has_studio_read_access(request.user, course_key):
|
||||
self.permission_denied(request)
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
return Response(CourseMetadata.fetch_all(
|
||||
course_module,
|
||||
course_block,
|
||||
filter_fields=filter_query_data.cleaned_data['filter_fields'],
|
||||
))
|
||||
|
||||
@@ -174,6 +174,6 @@ class AdvancedCourseSettingsView(DeveloperErrorViewMixin, APIView):
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
if not has_studio_write_access(request.user, course_key):
|
||||
self.permission_denied(request)
|
||||
course_module = modulestore().get_course(course_key)
|
||||
updated_data = update_course_advanced_settings(course_module, request.data, request.user)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
updated_data = update_course_advanced_settings(course_block, request.data, request.user)
|
||||
return Response(updated_data)
|
||||
|
||||
@@ -81,8 +81,8 @@ class CourseTabListView(DeveloperErrorViewMixin, APIView):
|
||||
if not has_studio_read_access(request.user, course_key):
|
||||
self.permission_denied(request)
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
tabs_to_render = get_course_tabs(course_module, request.user)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
tabs_to_render = get_course_tabs(course_block, request.user)
|
||||
return Response(CourseTabSerializer(tabs_to_render, many=True).data)
|
||||
|
||||
|
||||
@@ -147,12 +147,12 @@ class CourseTabSettingsView(DeveloperErrorViewMixin, APIView):
|
||||
tab_id_locator = TabIDLocatorSerializer(data=request.query_params)
|
||||
tab_id_locator.is_valid(raise_exception=True)
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
serializer = CourseTabUpdateSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
edit_tab_handler(
|
||||
course_module,
|
||||
course_block,
|
||||
{
|
||||
"tab_id_locator": tab_id_locator.data,
|
||||
**serializer.data,
|
||||
@@ -216,11 +216,11 @@ class CourseTabReorderView(DeveloperErrorViewMixin, APIView):
|
||||
if not has_studio_write_access(request.user, course_key):
|
||||
self.permission_denied(request)
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
tab_id_locators = TabIDLocatorSerializer(data=request.data, many=True)
|
||||
tab_id_locators.is_valid(raise_exception=True)
|
||||
reorder_tabs_handler(
|
||||
course_module,
|
||||
course_block,
|
||||
tab_id_locators.validated_data,
|
||||
request.user,
|
||||
)
|
||||
|
||||
@@ -77,7 +77,7 @@ class ProctoringExamSettingsTestMixin():
|
||||
response = self.make_request()
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
def test_404_no_course_module(self):
|
||||
def test_404_no_course_block(self):
|
||||
course_id = 'course-v1:edX+ToyX_Nonexistent_Course+Toy_Course'
|
||||
self.client.login(username=self.global_staff, password=self.password)
|
||||
response = self.make_request(course_id=course_id)
|
||||
|
||||
@@ -92,8 +92,8 @@ class ProctoredExamSettingsView(APIView):
|
||||
def get(self, request, course_id):
|
||||
""" GET handler """
|
||||
with modulestore().bulk_operations(CourseKey.from_string(course_id)):
|
||||
course_module = self._get_and_validate_course_access(request.user, course_id)
|
||||
course_metadata = CourseMetadata().fetch_all(course_module)
|
||||
course_block = self._get_and_validate_course_access(request.user, course_id)
|
||||
course_metadata = CourseMetadata().fetch_all(course_block)
|
||||
proctored_exam_settings = self._get_proctored_exam_setting_values(course_metadata)
|
||||
|
||||
data = {}
|
||||
@@ -123,8 +123,8 @@ class ProctoredExamSettingsView(APIView):
|
||||
return Response(status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
with modulestore().bulk_operations(CourseKey.from_string(course_id)):
|
||||
course_module = self._get_and_validate_course_access(request.user, course_id)
|
||||
course_metadata = CourseMetadata().fetch_all(course_module)
|
||||
course_block = self._get_and_validate_course_access(request.user, course_id)
|
||||
course_metadata = CourseMetadata().fetch_all(course_block)
|
||||
|
||||
models_to_update = {}
|
||||
for setting_key, value in exam_config.data.items():
|
||||
@@ -133,9 +133,9 @@ class ProctoredExamSettingsView(APIView):
|
||||
models_to_update[setting_key] = copy.deepcopy(model)
|
||||
models_to_update[setting_key]['value'] = value
|
||||
|
||||
# validate data formats and update the course module object
|
||||
# validate data formats and update the course block object
|
||||
is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
|
||||
course_module,
|
||||
course_block,
|
||||
models_to_update,
|
||||
user=request.user,
|
||||
)
|
||||
@@ -148,7 +148,7 @@ class ProctoredExamSettingsView(APIView):
|
||||
)
|
||||
|
||||
# save to mongo
|
||||
modulestore().update_item(course_module, request.user.id)
|
||||
modulestore().update_item(course_block, request.user.id)
|
||||
|
||||
# merge updated settings with all existing settings.
|
||||
# do this because fields that could not be modified are excluded from the result
|
||||
@@ -171,14 +171,14 @@ class ProctoredExamSettingsView(APIView):
|
||||
"""
|
||||
Check if course_id exists and is accessible by the user.
|
||||
|
||||
Returns a course_module object
|
||||
Returns a course_block object
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
course_module = get_course_and_check_access(course_key, user)
|
||||
course_block = get_course_and_check_access(course_key, user)
|
||||
|
||||
if not course_module:
|
||||
if not course_block:
|
||||
raise NotFound(
|
||||
f'Course with course_id {course_id} does not exist.'
|
||||
)
|
||||
|
||||
return course_module
|
||||
return course_block
|
||||
|
||||
@@ -167,7 +167,7 @@ def rerun_course(source_course_key_string, destination_course_key_string, user_i
|
||||
# cleanup any remnants of the course
|
||||
modulestore().delete_course(destination_course_key, user_id)
|
||||
except ItemNotFoundError:
|
||||
# it's possible there was an error even before the course module was created
|
||||
# it's possible there was an error even before the course block was created
|
||||
pass
|
||||
|
||||
return "exception: " + str(exc)
|
||||
@@ -335,13 +335,13 @@ def export_olx(self, user_id, course_key_string, language):
|
||||
return
|
||||
|
||||
|
||||
def create_export_tarball(course_module, course_key, context, status=None):
|
||||
def create_export_tarball(course_block, course_key, context, status=None):
|
||||
"""
|
||||
Generates the export tarball, or returns None if there was an error.
|
||||
|
||||
Updates the context with any error information if applicable.
|
||||
"""
|
||||
name = course_module.url_name
|
||||
name = course_block.url_name
|
||||
export_file = NamedTemporaryFile(prefix=name + '.', suffix=".tar.gz") # lint-amnesty, pylint: disable=consider-using-with
|
||||
root_dir = path(mkdtemp())
|
||||
|
||||
@@ -349,7 +349,7 @@ def create_export_tarball(course_module, course_key, context, status=None):
|
||||
if isinstance(course_key, LibraryLocator):
|
||||
export_library_to_xml(modulestore(), contentstore(), course_key, root_dir, name)
|
||||
else:
|
||||
export_course_to_xml(modulestore(), contentstore(), course_module.id, root_dir, name)
|
||||
export_course_to_xml(modulestore(), contentstore(), course_block.id, root_dir, name)
|
||||
|
||||
if status:
|
||||
status.set_state('Compressing')
|
||||
|
||||
@@ -348,7 +348,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
# check for policy.json
|
||||
self.assertTrue(filesystem.exists('policy.json'))
|
||||
|
||||
# compare what's on disk to what we have in the course module
|
||||
# compare what's on disk to what we have in the course block
|
||||
with filesystem.open('policy.json', 'r') as course_policy:
|
||||
on_disk = loads(course_policy.read())
|
||||
self.assertIn('course/2012_Fall', on_disk)
|
||||
@@ -1195,8 +1195,8 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
"""Test new course creation and verify default language"""
|
||||
test_course_data = self.assert_created_course()
|
||||
course_id = _get_course_id(self.store, test_course_data)
|
||||
course_module = self.store.get_course(course_id)
|
||||
self.assertEqual(course_module.language, 'hr')
|
||||
course_block = self.store.get_course(course_id)
|
||||
self.assertEqual(course_block.language, 'hr')
|
||||
|
||||
def test_create_course_with_dots(self):
|
||||
"""Test new course creation with dots in the name"""
|
||||
@@ -1617,12 +1617,12 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
#
|
||||
|
||||
# first check PDF textbooks, to make sure the url paths got updated
|
||||
course_module = self.store.get_course(target_id)
|
||||
course_block = self.store.get_course(target_id)
|
||||
|
||||
self.assertEqual(len(course_module.pdf_textbooks), 1)
|
||||
self.assertEqual(len(course_module.pdf_textbooks[0]["chapters"]), 2)
|
||||
self.assertEqual(course_module.pdf_textbooks[0]["chapters"][0]["url"], '/static/Chapter1.pdf')
|
||||
self.assertEqual(course_module.pdf_textbooks[0]["chapters"][1]["url"], '/static/Chapter2.pdf')
|
||||
self.assertEqual(len(course_block.pdf_textbooks), 1)
|
||||
self.assertEqual(len(course_block.pdf_textbooks[0]["chapters"]), 2)
|
||||
self.assertEqual(course_block.pdf_textbooks[0]["chapters"][0]["url"], '/static/Chapter1.pdf')
|
||||
self.assertEqual(course_block.pdf_textbooks[0]["chapters"][1]["url"], '/static/Chapter2.pdf')
|
||||
|
||||
def test_import_into_new_course_id_wiki_slug_renamespacing(self):
|
||||
# If reimporting into the same course do not change the wiki_slug.
|
||||
@@ -1634,14 +1634,14 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
'run': target_id.run
|
||||
}
|
||||
_create_course(self, target_id, course_data)
|
||||
course_module = self.store.get_course(target_id)
|
||||
course_module.wiki_slug = 'toy'
|
||||
course_module.save()
|
||||
course_block = self.store.get_course(target_id)
|
||||
course_block.wiki_slug = 'toy'
|
||||
course_block.save()
|
||||
|
||||
# Import a course with wiki_slug == location.course
|
||||
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id)
|
||||
course_module = self.store.get_course(target_id)
|
||||
self.assertEqual(course_module.wiki_slug, 'toy')
|
||||
course_block = self.store.get_course(target_id)
|
||||
self.assertEqual(course_block.wiki_slug, 'toy')
|
||||
|
||||
# But change the wiki_slug if it is a different course.
|
||||
target_id = self.store.make_course_key('MITx', '111', '2013_Spring')
|
||||
@@ -1655,13 +1655,13 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
# Import a course with wiki_slug == location.course
|
||||
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id)
|
||||
course_module = self.store.get_course(target_id)
|
||||
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
|
||||
course_block = self.store.get_course(target_id)
|
||||
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
|
||||
|
||||
# Now try importing a course with wiki_slug == '{0}.{1}.{2}'.format(location.org, location.course, location.run)
|
||||
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['two_toys'], target_id=target_id)
|
||||
course_module = self.store.get_course(target_id)
|
||||
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
|
||||
course_block = self.store.get_course(target_id)
|
||||
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
|
||||
|
||||
def test_import_metadata_with_attempts_empty_string(self):
|
||||
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['simple'], create_if_not_present=True)
|
||||
@@ -1797,8 +1797,8 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
course_key = _get_course_id(self.store, self.course_data)
|
||||
_create_course(self, course_key, self.course_data)
|
||||
course_module = self.store.get_course(course_key)
|
||||
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
|
||||
course_block = self.store.get_course(course_key)
|
||||
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
|
||||
|
||||
def test_course_handler_with_invalid_course_key_string(self):
|
||||
"""Test viewing the course overview page with invalid course id"""
|
||||
|
||||
@@ -850,7 +850,7 @@ class TestLibrarySearchIndexer(MixedWithOptionsTestCase):
|
||||
|
||||
class GroupConfigurationSearchSplit(CourseTestCase, MixedWithOptionsTestCase):
|
||||
"""
|
||||
Tests indexing of content groups on course modules using split modulestore.
|
||||
Tests indexing of content groups on course blocks using split modulestore.
|
||||
"""
|
||||
CREATE_USER = True
|
||||
INDEX_NAME = CoursewareSearchIndexer.INDEX_NAME
|
||||
|
||||
@@ -33,7 +33,7 @@ class TestExportGit(CourseTestCase):
|
||||
Setup test course, user, and url.
|
||||
"""
|
||||
super().setUp()
|
||||
self.course_module = modulestore().get_course(self.course.id)
|
||||
self.course_block = modulestore().get_course(self.course.id)
|
||||
self.test_url = reverse_course_url('export_git', self.course.id)
|
||||
|
||||
def make_bare_repo_with_course(self, repo_name):
|
||||
@@ -55,8 +55,8 @@ class TestExportGit(CourseTestCase):
|
||||
|
||||
subprocess.check_output(['git', '--bare', 'init', ], cwd=bare_repo_dir)
|
||||
self.populate_course()
|
||||
self.course_module.giturl = f'file://{bare_repo_dir}'
|
||||
modulestore().update_item(self.course_module, self.user.id)
|
||||
self.course_block.giturl = f'file://{bare_repo_dir}'
|
||||
modulestore().update_item(self.course_block, self.user.id)
|
||||
|
||||
def test_giturl_missing(self):
|
||||
"""
|
||||
@@ -81,8 +81,8 @@ class TestExportGit(CourseTestCase):
|
||||
"""
|
||||
Test failed course export response.
|
||||
"""
|
||||
self.course_module.giturl = 'foobar'
|
||||
modulestore().update_item(self.course_module, self.user.id)
|
||||
self.course_block.giturl = 'foobar'
|
||||
modulestore().update_item(self.course_block, self.user.id)
|
||||
|
||||
response = self.client.get(f'{self.test_url}?action=push')
|
||||
self.assertContains(response, 'Export Failed:')
|
||||
@@ -91,8 +91,8 @@ class TestExportGit(CourseTestCase):
|
||||
"""
|
||||
Regression test for making sure errors are properly stringified
|
||||
"""
|
||||
self.course_module.giturl = 'foobar'
|
||||
modulestore().update_item(self.course_module, self.user.id)
|
||||
self.course_block.giturl = 'foobar'
|
||||
modulestore().update_item(self.course_block, self.user.id)
|
||||
|
||||
response = self.client.get(f'{self.test_url}?action=push')
|
||||
self.assertNotContains(response, 'django.utils.functional.__proxy__')
|
||||
@@ -123,11 +123,11 @@ class TestExportGit(CourseTestCase):
|
||||
repo_name = 'dirty_repo1'
|
||||
self.make_bare_repo_with_course(repo_name)
|
||||
git_export_utils.export_to_git(self.course.id,
|
||||
self.course_module.giturl, self.user)
|
||||
self.course_block.giturl, self.user)
|
||||
|
||||
# Make arbitrary change to course to make diff
|
||||
self.course_module.matlab_api_key = 'something'
|
||||
modulestore().update_item(self.course_module, self.user.id)
|
||||
self.course_block.matlab_api_key = 'something'
|
||||
modulestore().update_item(self.course_block, self.user.id)
|
||||
# Touch a file in the directory, export again, and make sure
|
||||
# the test file is gone
|
||||
repo_dir = os.path.join(
|
||||
@@ -138,5 +138,5 @@ class TestExportGit(CourseTestCase):
|
||||
open(test_file, 'a').close()
|
||||
self.assertTrue(os.path.isfile(test_file))
|
||||
git_export_utils.export_to_git(self.course.id,
|
||||
self.course_module.giturl, self.user)
|
||||
self.course_block.giturl, self.user)
|
||||
self.assertFalse(os.path.isfile(test_file))
|
||||
|
||||
@@ -102,11 +102,11 @@ def _asset_index(request, course_key):
|
||||
|
||||
Supports start (0-based index into the list of assets) and max query parameters.
|
||||
'''
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
|
||||
return render_to_response('asset_index.html', {
|
||||
'language_code': request.LANGUAGE_CODE,
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'max_file_size_in_mbs': settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB,
|
||||
'chunk_size_in_mbs': settings.UPLOAD_CHUNK_SIZE_IN_MB,
|
||||
'max_file_size_redirect_url': settings.MAX_ASSET_UPLOAD_FILE_SIZE_URL,
|
||||
|
||||
@@ -63,12 +63,12 @@ LOGGER = logging.getLogger(__name__)
|
||||
def _get_course_and_check_access(course_key, user, depth=0):
|
||||
"""
|
||||
Internal method used to calculate and return the locator and
|
||||
course module for the view functions in this file.
|
||||
course block for the view functions in this file.
|
||||
"""
|
||||
if not has_studio_write_access(user, course_key):
|
||||
raise PermissionDenied()
|
||||
course_module = modulestore().get_course(course_key, depth=depth)
|
||||
return course_module
|
||||
course_block = modulestore().get_course(course_key, depth=depth)
|
||||
return course_block
|
||||
|
||||
|
||||
def _delete_asset(course_key, asset_key_string):
|
||||
|
||||
@@ -27,9 +27,9 @@ def checklists_handler(request, course_key_string=None):
|
||||
if not has_course_author_access(request.user, course_key):
|
||||
raise PermissionDenied()
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
return render_to_response('checklists.html', {
|
||||
'language_code': request.LANGUAGE_CODE,
|
||||
'context_course': course_module,
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
|
||||
'context_course': course_block,
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
})
|
||||
|
||||
@@ -149,13 +149,13 @@ class AccessListFallback(Exception):
|
||||
|
||||
def get_course_and_check_access(course_key, user, depth=0):
|
||||
"""
|
||||
Function used to calculate and return the locator and course module
|
||||
Function used to calculate and return the locator and course block
|
||||
for the view functions in this file.
|
||||
"""
|
||||
if not has_studio_read_access(user, course_key):
|
||||
raise PermissionDenied()
|
||||
course_module = modulestore().get_course(course_key, depth=depth)
|
||||
return course_module
|
||||
course_block = modulestore().get_course(course_key, depth=depth)
|
||||
return course_block
|
||||
|
||||
|
||||
def reindex_course_and_check_access(course_key, user):
|
||||
@@ -285,8 +285,8 @@ def course_handler(request, course_key_string=None):
|
||||
if request.method == 'GET':
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user, depth=None)
|
||||
return JsonResponse(_course_outline_json(request, course_module))
|
||||
course_block = get_course_and_check_access(course_key, request.user, depth=None)
|
||||
return JsonResponse(_course_outline_json(request, course_block))
|
||||
elif request.method == 'POST': # not sure if this is only post. If one will have ids, it goes after access
|
||||
return _create_or_rerun_course(request)
|
||||
elif not has_studio_write_access(request.user, CourseKey.from_string(course_key_string)):
|
||||
@@ -322,11 +322,11 @@ def course_rerun_handler(request, course_key_string):
|
||||
raise PermissionDenied()
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user, depth=3)
|
||||
course_block = get_course_and_check_access(course_key, request.user, depth=3)
|
||||
if request.method == 'GET':
|
||||
return render_to_response('course-create-rerun.html', {
|
||||
'source_course_key': course_key,
|
||||
'display_name': course_module.display_name,
|
||||
'display_name': course_block.display_name,
|
||||
'user': request.user,
|
||||
'course_creator_status': _get_course_creator_status(request.user),
|
||||
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False)
|
||||
@@ -362,16 +362,16 @@ def course_search_index_handler(request, course_key_string):
|
||||
}), content_type=content_type, status=200)
|
||||
|
||||
|
||||
def _course_outline_json(request, course_module):
|
||||
def _course_outline_json(request, course_block):
|
||||
"""
|
||||
Returns a JSON representation of the course module and recursively all of its children.
|
||||
Returns a JSON representation of the course block and recursively all of its children.
|
||||
"""
|
||||
is_concise = request.GET.get('format') == 'concise'
|
||||
include_children_predicate = lambda xblock: not xblock.category == 'vertical'
|
||||
if is_concise:
|
||||
include_children_predicate = lambda xblock: xblock.has_children
|
||||
return create_xblock_info(
|
||||
course_module,
|
||||
course_block,
|
||||
include_child_info=True,
|
||||
course_outline=False if is_concise else True, # lint-amnesty, pylint: disable=simplifiable-if-expression
|
||||
include_children_predicate=include_children_predicate,
|
||||
@@ -640,12 +640,12 @@ def _get_rerun_link_for_item(course_key):
|
||||
return reverse_course_url('course_rerun_handler', course_key)
|
||||
|
||||
|
||||
def _deprecated_blocks_info(course_module, deprecated_block_types):
|
||||
def _deprecated_blocks_info(course_block, deprecated_block_types):
|
||||
"""
|
||||
Returns deprecation information about `deprecated_block_types`
|
||||
|
||||
Arguments:
|
||||
course_module (CourseBlock): course object
|
||||
course_block (CourseBlock): course object
|
||||
deprecated_block_types (list): list of deprecated blocks types
|
||||
|
||||
Returns:
|
||||
@@ -656,14 +656,14 @@ def _deprecated_blocks_info(course_module, deprecated_block_types):
|
||||
"""
|
||||
data = {
|
||||
'deprecated_enabled_block_types': [
|
||||
block_type for block_type in course_module.advanced_modules if block_type in deprecated_block_types
|
||||
block_type for block_type in course_block.advanced_modules if block_type in deprecated_block_types
|
||||
],
|
||||
'blocks': [],
|
||||
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_module.id)
|
||||
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_block.id)
|
||||
}
|
||||
|
||||
deprecated_blocks = modulestore().get_items(
|
||||
course_module.id,
|
||||
course_block.id,
|
||||
qualifiers={
|
||||
'category': re.compile('^' + '$|^'.join(deprecated_block_types) + '$')
|
||||
}
|
||||
@@ -689,21 +689,21 @@ def course_index(request, course_key):
|
||||
# A depth of None implies the whole course. The course outline needs this in order to compute has_changes.
|
||||
# A unit may not have a draft version, but one of its components could, and hence the unit itself has changes.
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user, depth=None)
|
||||
if not course_module:
|
||||
course_block = get_course_and_check_access(course_key, request.user, depth=None)
|
||||
if not course_block:
|
||||
raise Http404
|
||||
lms_link = get_lms_link_for_item(course_module.location)
|
||||
lms_link = get_lms_link_for_item(course_block.location)
|
||||
reindex_link = None
|
||||
if settings.FEATURES.get('ENABLE_COURSEWARE_INDEX', False):
|
||||
if GlobalStaff().has_user(request.user):
|
||||
reindex_link = f"/course/{str(course_key)}/search_reindex"
|
||||
sections = course_module.get_children()
|
||||
course_structure = _course_outline_json(request, course_module)
|
||||
sections = course_block.get_children()
|
||||
course_structure = _course_outline_json(request, course_block)
|
||||
locator_to_show = request.GET.get('show', None)
|
||||
|
||||
course_release_date = (
|
||||
get_default_time_display(course_module.start)
|
||||
if course_module.start != DEFAULT_START_DATE
|
||||
get_default_time_display(course_block.start)
|
||||
if course_block.start != DEFAULT_START_DATE
|
||||
else _("Set Date")
|
||||
)
|
||||
|
||||
@@ -715,16 +715,16 @@ def course_index(request, course_key):
|
||||
current_action = None
|
||||
|
||||
deprecated_block_names = [block.name for block in deprecated_xblocks()]
|
||||
deprecated_blocks_info = _deprecated_blocks_info(course_module, deprecated_block_names)
|
||||
deprecated_blocks_info = _deprecated_blocks_info(course_block, deprecated_block_names)
|
||||
|
||||
frontend_app_publisher_url = configuration_helpers.get_value_for_org(
|
||||
course_module.location.org,
|
||||
course_block.location.org,
|
||||
'FRONTEND_APP_PUBLISHER_URL',
|
||||
settings.FEATURES.get('FRONTEND_APP_PUBLISHER_URL', False)
|
||||
)
|
||||
# gather any errors in the currently stored proctoring settings.
|
||||
advanced_dict = CourseMetadata.fetch(course_module)
|
||||
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_module, advanced_dict, request.user)
|
||||
advanced_dict = CourseMetadata.fetch(course_block)
|
||||
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_block, advanced_dict, request.user)
|
||||
|
||||
configuration = DiscussionsConfiguration.get(course_key)
|
||||
provider = configuration.provider_type
|
||||
@@ -733,7 +733,7 @@ def course_index(request, course_key):
|
||||
|
||||
return render_to_response('course_outline.html', {
|
||||
'language_code': request.LANGUAGE_CODE,
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'lms_link': lms_link,
|
||||
'sections': sections,
|
||||
'course_structure': course_structure,
|
||||
@@ -751,8 +751,8 @@ def course_index(request, course_key):
|
||||
},
|
||||
) if current_action else None,
|
||||
'frontend_app_publisher_url': frontend_app_publisher_url,
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
|
||||
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_module.id),
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_block.id),
|
||||
'proctoring_errors': proctoring_errors,
|
||||
})
|
||||
|
||||
@@ -1068,17 +1068,17 @@ def course_info_handler(request, course_key_string):
|
||||
raise Http404 # lint-amnesty, pylint: disable=raise-missing-from
|
||||
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user)
|
||||
if not course_module:
|
||||
course_block = get_course_and_check_access(course_key, request.user)
|
||||
if not course_block:
|
||||
raise Http404
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
|
||||
return render_to_response(
|
||||
'course_info.html',
|
||||
{
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'updates_url': reverse_course_url('course_info_update_handler', course_key),
|
||||
'handouts_locator': course_key.make_usage_key('course_info', 'handouts'),
|
||||
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_module.id),
|
||||
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_block.id),
|
||||
}
|
||||
)
|
||||
else:
|
||||
@@ -1153,24 +1153,24 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
credit_eligibility_enabled = settings.FEATURES.get('ENABLE_CREDIT_ELIGIBILITY', False)
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user)
|
||||
course_block = get_course_and_check_access(course_key, request.user)
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
|
||||
upload_asset_url = reverse_course_url('assets_handler', course_key)
|
||||
|
||||
# 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_module.location.org,
|
||||
course_block.location.org,
|
||||
'ENABLE_PUBLISHER',
|
||||
settings.FEATURES.get('ENABLE_PUBLISHER', False)
|
||||
)
|
||||
marketing_enabled = configuration_helpers.get_value_for_org(
|
||||
course_module.location.org,
|
||||
course_block.location.org,
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
)
|
||||
enable_extended_course_details = configuration_helpers.get_value_for_org(
|
||||
course_module.location.org,
|
||||
course_block.location.org,
|
||||
'ENABLE_EXTENDED_COURSE_DETAILS',
|
||||
settings.FEATURES.get('ENABLE_EXTENDED_COURSE_DETAILS', False)
|
||||
)
|
||||
@@ -1178,7 +1178,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
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_module.location.org,
|
||||
course_block.location.org,
|
||||
'EDITABLE_SHORT_DESCRIPTION',
|
||||
settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
|
||||
)
|
||||
@@ -1188,12 +1188,12 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
upgrade_deadline = (verified_mode and verified_mode.expiration_datetime and
|
||||
verified_mode.expiration_datetime.isoformat())
|
||||
settings_context = {
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'course_locator': course_key,
|
||||
'lms_link_for_about_page': get_link_for_about_page(course_module),
|
||||
'course_image_url': course_image_url(course_module, 'course_image'),
|
||||
'banner_image_url': course_image_url(course_module, 'banner_image'),
|
||||
'video_thumbnail_image_url': course_image_url(course_module, 'video_thumbnail_image'),
|
||||
'lms_link_for_about_page': get_link_for_about_page(course_block),
|
||||
'course_image_url': course_image_url(course_block, 'course_image'),
|
||||
'banner_image_url': course_image_url(course_block, 'banner_image'),
|
||||
'video_thumbnail_image_url': course_image_url(course_block, 'video_thumbnail_image'),
|
||||
'details_url': reverse_course_url('settings_handler', course_key),
|
||||
'about_page_editable': about_page_editable,
|
||||
'marketing_enabled': marketing_enabled,
|
||||
@@ -1210,7 +1210,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
'is_entrance_exams_enabled': core_toggles.ENTRANCE_EXAMS.is_enabled(),
|
||||
'enable_extended_course_details': enable_extended_course_details,
|
||||
'upgrade_deadline': upgrade_deadline,
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
}
|
||||
if is_prerequisite_courses_enabled():
|
||||
courses, in_process_course_actions = get_courses_accessible_to_user(request)
|
||||
@@ -1232,7 +1232,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
|
||||
# if 'minimum_grade_credit' of a course is not set or 0 then
|
||||
# show warning message to course author.
|
||||
show_min_grade_warning = False if course_module.minimum_grade_credit > 0 else True # lint-amnesty, pylint: disable=simplifiable-if-expression
|
||||
show_min_grade_warning = False if course_block.minimum_grade_credit > 0 else True # lint-amnesty, pylint: disable=simplifiable-if-expression
|
||||
settings_context.update(
|
||||
{
|
||||
'is_credit_course': True,
|
||||
@@ -1278,7 +1278,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
|
||||
# We have to be careful that we're only executing the following logic if we actually
|
||||
# need to create or delete an entrance exam from the specified course
|
||||
if core_toggles.ENTRANCE_EXAMS.is_enabled():
|
||||
course_entrance_exam_present = course_module.entrance_exam_enabled
|
||||
course_entrance_exam_present = course_block.entrance_exam_enabled
|
||||
entrance_exam_enabled = request.json.get('entrance_exam_enabled', '') == 'true'
|
||||
ee_min_score_pct = request.json.get('entrance_exam_minimum_score_pct', None)
|
||||
# If the entrance exam box on the settings screen has been checked...
|
||||
@@ -1328,17 +1328,17 @@ def grading_handler(request, course_key_string, grader_index=None):
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user)
|
||||
course_block = get_course_and_check_access(course_key, request.user)
|
||||
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
|
||||
course_details = CourseGradingModel.fetch(course_key)
|
||||
return render_to_response('settings_graders.html', {
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'course_locator': course_key,
|
||||
'course_details': course_details,
|
||||
'grading_url': reverse_course_url('grading_handler', course_key),
|
||||
'is_credit_course': is_credit_course(course_key),
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
})
|
||||
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
|
||||
if request.method == 'GET':
|
||||
@@ -1371,7 +1371,7 @@ def grading_handler(request, course_key_string, grader_index=None):
|
||||
return JsonResponse()
|
||||
|
||||
|
||||
def _refresh_course_tabs(user: User, course_module: CourseBlock):
|
||||
def _refresh_course_tabs(user: User, course_block: CourseBlock):
|
||||
"""
|
||||
Automatically adds/removes tabs if changes to the course require them.
|
||||
|
||||
@@ -1392,19 +1392,19 @@ def _refresh_course_tabs(user: User, course_module: CourseBlock):
|
||||
elif not tab_enabled and has_tab:
|
||||
tabs.remove(tab_panel)
|
||||
|
||||
course_tabs = copy.copy(course_module.tabs)
|
||||
course_tabs = copy.copy(course_block.tabs)
|
||||
|
||||
# Additionally update any tabs that are provided by non-dynamic course views
|
||||
for tab_type in CourseTabPluginManager.get_tab_types():
|
||||
if not tab_type.is_dynamic and tab_type.is_default:
|
||||
tab_enabled = tab_type.is_enabled(course_module, user=user)
|
||||
tab_enabled = tab_type.is_enabled(course_block, user=user)
|
||||
update_tab(course_tabs, tab_type, tab_enabled)
|
||||
|
||||
CourseTabList.validate_tabs(course_tabs)
|
||||
|
||||
# Save the tabs into the course if they have been changed
|
||||
if course_tabs != course_module.tabs:
|
||||
course_module.tabs = course_tabs
|
||||
if course_tabs != course_block.tabs:
|
||||
course_block.tabs = course_tabs
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -1423,42 +1423,42 @@ def advanced_settings_handler(request, course_key_string):
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user)
|
||||
course_block = get_course_and_check_access(course_key, request.user)
|
||||
|
||||
advanced_dict = CourseMetadata.fetch(course_module)
|
||||
advanced_dict = CourseMetadata.fetch(course_block)
|
||||
if settings.FEATURES.get('DISABLE_MOBILE_COURSE_AVAILABLE', False):
|
||||
advanced_dict.get('mobile_available')['deprecated'] = True
|
||||
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
|
||||
publisher_enabled = configuration_helpers.get_value_for_org(
|
||||
course_module.location.org,
|
||||
course_block.location.org,
|
||||
'ENABLE_PUBLISHER',
|
||||
settings.FEATURES.get('ENABLE_PUBLISHER', False)
|
||||
)
|
||||
# gather any errors in the currently stored proctoring settings.
|
||||
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_module, advanced_dict, request.user)
|
||||
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_block, advanced_dict, request.user)
|
||||
|
||||
return render_to_response('settings_advanced.html', {
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'advanced_dict': advanced_dict,
|
||||
'advanced_settings_url': reverse_course_url('advanced_settings_handler', course_key),
|
||||
'publisher_enabled': publisher_enabled,
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
'proctoring_errors': proctoring_errors,
|
||||
})
|
||||
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
|
||||
if request.method == 'GET':
|
||||
return JsonResponse(CourseMetadata.fetch(course_module))
|
||||
return JsonResponse(CourseMetadata.fetch(course_block))
|
||||
else:
|
||||
try:
|
||||
return JsonResponse(
|
||||
update_course_advanced_settings(course_module, request.json, request.user)
|
||||
update_course_advanced_settings(course_block, request.json, request.user)
|
||||
)
|
||||
except ValidationError as err:
|
||||
return JsonResponseBadRequest(err.detail)
|
||||
|
||||
|
||||
def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user: User) -> Dict:
|
||||
def update_course_advanced_settings(course_block: CourseBlock, data: Dict, user: User) -> Dict:
|
||||
"""
|
||||
Helper function to update course advanced settings from API data.
|
||||
|
||||
@@ -1466,7 +1466,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
|
||||
it to the course advanced settings.
|
||||
|
||||
Args:
|
||||
course_module (CourseBlock): The course run object on which to operate.
|
||||
course_block (CourseBlock): The course run object on which to operate.
|
||||
data (Dict): JSON data as found the ``request.data``
|
||||
user (User): The user performing the operation
|
||||
|
||||
@@ -1474,10 +1474,10 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
|
||||
Dict: The updated data after applying changes based on supplied data.
|
||||
"""
|
||||
try:
|
||||
# validate data formats and update the course module.
|
||||
# validate data formats and update the course block.
|
||||
# Note: don't update mongo yet, but wait until after any tabs are changed
|
||||
is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
|
||||
course_module,
|
||||
course_block,
|
||||
data,
|
||||
user=user,
|
||||
)
|
||||
@@ -1487,7 +1487,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
|
||||
|
||||
try:
|
||||
# update the course tabs if required by any setting changes
|
||||
_refresh_course_tabs(user, course_module)
|
||||
_refresh_course_tabs(user, course_block)
|
||||
except InvalidTabsException as err:
|
||||
log.exception(str(err))
|
||||
response_message = [
|
||||
@@ -1499,7 +1499,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
|
||||
raise ValidationError(response_message) from err
|
||||
|
||||
# now update mongo
|
||||
modulestore().update_item(course_module, user.id)
|
||||
modulestore().update_item(course_block, user.id)
|
||||
|
||||
return updated_data
|
||||
|
||||
@@ -1665,8 +1665,8 @@ def textbooks_detail_handler(request, course_key_string, textbook_id):
|
||||
course_key = CourseKey.from_string(course_key_string)
|
||||
store = modulestore()
|
||||
with store.bulk_operations(course_key):
|
||||
course_module = get_course_and_check_access(course_key, request.user)
|
||||
matching_id = [tb for tb in course_module.pdf_textbooks
|
||||
course_block = get_course_and_check_access(course_key, request.user)
|
||||
matching_id = [tb for tb in course_block.pdf_textbooks
|
||||
if str(tb.get("id")) == str(textbook_id)]
|
||||
if matching_id:
|
||||
textbook = matching_id[0]
|
||||
@@ -1684,23 +1684,23 @@ def textbooks_detail_handler(request, course_key_string, textbook_id):
|
||||
return JsonResponse({"error": str(err)}, status=400)
|
||||
new_textbook["id"] = textbook_id
|
||||
if textbook:
|
||||
i = course_module.pdf_textbooks.index(textbook)
|
||||
new_textbooks = course_module.pdf_textbooks[0:i]
|
||||
i = course_block.pdf_textbooks.index(textbook)
|
||||
new_textbooks = course_block.pdf_textbooks[0:i]
|
||||
new_textbooks.append(new_textbook)
|
||||
new_textbooks.extend(course_module.pdf_textbooks[i + 1:])
|
||||
course_module.pdf_textbooks = new_textbooks
|
||||
new_textbooks.extend(course_block.pdf_textbooks[i + 1:])
|
||||
course_block.pdf_textbooks = new_textbooks
|
||||
else:
|
||||
course_module.pdf_textbooks.append(new_textbook)
|
||||
store.update_item(course_module, request.user.id)
|
||||
course_block.pdf_textbooks.append(new_textbook)
|
||||
store.update_item(course_block, request.user.id)
|
||||
return JsonResponse(new_textbook, status=201)
|
||||
elif request.method == 'DELETE':
|
||||
if not textbook:
|
||||
return JsonResponse(status=404)
|
||||
i = course_module.pdf_textbooks.index(textbook)
|
||||
remaining_textbooks = course_module.pdf_textbooks[0:i]
|
||||
remaining_textbooks.extend(course_module.pdf_textbooks[i + 1:])
|
||||
course_module.pdf_textbooks = remaining_textbooks
|
||||
store.update_item(course_module, request.user.id)
|
||||
i = course_block.pdf_textbooks.index(textbook)
|
||||
remaining_textbooks = course_block.pdf_textbooks[0:i]
|
||||
remaining_textbooks.extend(course_block.pdf_textbooks[i + 1:])
|
||||
course_block.pdf_textbooks = remaining_textbooks
|
||||
store.update_item(course_block, request.user.id)
|
||||
return JsonResponse()
|
||||
|
||||
|
||||
|
||||
@@ -30,18 +30,18 @@ def export_git(request, course_key_string):
|
||||
if not has_course_author_access(request.user, course_key):
|
||||
raise PermissionDenied()
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
failed = False
|
||||
|
||||
log.debug('export_git course_module=%s', course_module)
|
||||
log.debug('export_git course_block=%s', course_block)
|
||||
|
||||
msg = ""
|
||||
if 'action' in request.GET and course_module.giturl:
|
||||
if 'action' in request.GET and course_block.giturl:
|
||||
if request.GET['action'] == 'push':
|
||||
try:
|
||||
git_export_utils.export_to_git(
|
||||
course_module.id,
|
||||
course_module.giturl,
|
||||
course_block.id,
|
||||
course_block.giturl,
|
||||
request.user,
|
||||
)
|
||||
msg = _('Course successfully exported to git repository')
|
||||
@@ -50,7 +50,7 @@ def export_git(request, course_key_string):
|
||||
msg = str(ex)
|
||||
|
||||
return render_to_response('export_git.html', {
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'msg': msg,
|
||||
'failed': failed,
|
||||
})
|
||||
|
||||
@@ -254,7 +254,7 @@ def create_xblock(parent_locator, user, category, display_name, boilerplate=None
|
||||
user
|
||||
)
|
||||
|
||||
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course module, so
|
||||
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course block, so
|
||||
# if we add one then we need to also add it to the policy information (i.e. metadata)
|
||||
# we should remove this once we can break this reference from the course to static tabs
|
||||
if category == 'static_tab':
|
||||
|
||||
@@ -979,7 +979,7 @@ def _delete_item(usage_key, user):
|
||||
store = modulestore()
|
||||
|
||||
with store.bulk_operations(usage_key.course_key):
|
||||
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course module, so
|
||||
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course block, so
|
||||
# if we add one then we need to also add it to the policy information (i.e. metadata)
|
||||
# we should remove this once we can break this reference from the course to static tabs
|
||||
if usage_key.block_type == 'static_tab':
|
||||
@@ -1105,7 +1105,7 @@ def _get_gating_info(course, xblock):
|
||||
info = {}
|
||||
if xblock.category == 'sequential' and course.enable_subsection_gating:
|
||||
if not hasattr(course, 'gating_prerequisites'):
|
||||
# Cache gating prerequisites on course module so that we are not
|
||||
# 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)
|
||||
|
||||
@@ -106,7 +106,7 @@ def update_tabs_handler(course_item: CourseBlock, tabs_data: Dict, user: User) -
|
||||
Helper to handle updates to course tabs based on API data.
|
||||
|
||||
Args:
|
||||
course_item (CourseBlock): Course module whose tabs need to be updated
|
||||
course_item (CourseBlock): Course block whose tabs need to be updated
|
||||
tabs_data (Dict): JSON formatted data for updating or reordering tabs.
|
||||
user (User): The user performing the operation.
|
||||
"""
|
||||
|
||||
@@ -525,9 +525,9 @@ class TestCourseOutline(CourseTestCase):
|
||||
self.assert_correct_json_response(child_response, is_concise)
|
||||
|
||||
def test_course_outline_initial_state(self):
|
||||
course_module = modulestore().get_item(self.course.location)
|
||||
course_block = modulestore().get_item(self.course.location)
|
||||
course_structure = create_xblock_info(
|
||||
course_module,
|
||||
course_block,
|
||||
include_child_info=True,
|
||||
include_children_predicate=lambda xblock: not xblock.category == 'vertical'
|
||||
)
|
||||
@@ -543,7 +543,7 @@ class TestCourseOutline(CourseTestCase):
|
||||
self.assertIn(str(self.sequential.location), expanded_locators)
|
||||
self.assertIn(str(self.vertical.location), expanded_locators)
|
||||
|
||||
def _create_test_data(self, course_module, create_blocks=False, publish=True, block_types=None):
|
||||
def _create_test_data(self, course_block, create_blocks=False, publish=True, block_types=None):
|
||||
"""
|
||||
Create data for test.
|
||||
"""
|
||||
@@ -558,7 +558,7 @@ class TestCourseOutline(CourseTestCase):
|
||||
if not publish:
|
||||
self.store.unpublish(self.vertical.location, self.user.id)
|
||||
|
||||
course_module.advanced_modules.extend(block_types)
|
||||
course_block.advanced_modules.extend(block_types)
|
||||
|
||||
def _verify_deprecated_info(self, course_id, advanced_modules, info, deprecated_block_types):
|
||||
"""
|
||||
@@ -594,12 +594,12 @@ class TestCourseOutline(CourseTestCase):
|
||||
"""
|
||||
Verify deprecated warning info.
|
||||
"""
|
||||
course_module = modulestore().get_item(self.course.location)
|
||||
self._create_test_data(course_module, create_blocks=True, block_types=block_types, publish=publish)
|
||||
info = _deprecated_blocks_info(course_module, block_types)
|
||||
course_block = modulestore().get_item(self.course.location)
|
||||
self._create_test_data(course_block, create_blocks=True, block_types=block_types, publish=publish)
|
||||
info = _deprecated_blocks_info(course_block, block_types)
|
||||
self._verify_deprecated_info(
|
||||
course_module.id,
|
||||
course_module.advanced_modules,
|
||||
course_block.id,
|
||||
course_block.advanced_modules,
|
||||
info,
|
||||
block_types
|
||||
)
|
||||
@@ -611,17 +611,17 @@ class TestCourseOutline(CourseTestCase):
|
||||
(["a", "b", "c"], ["d", "e", "f"])
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_verify_warn_only_on_enabled_modules(self, enabled_block_types, deprecated_block_types):
|
||||
def test_verify_warn_only_on_enabled_blocks(self, enabled_block_types, deprecated_block_types):
|
||||
"""
|
||||
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_module = modulestore().get_item(self.course.location)
|
||||
self._create_test_data(course_module, create_blocks=True, block_types=enabled_block_types)
|
||||
info = _deprecated_blocks_info(course_module, deprecated_block_types)
|
||||
course_block = modulestore().get_item(self.course.location)
|
||||
self._create_test_data(course_block, create_blocks=True, block_types=enabled_block_types)
|
||||
info = _deprecated_blocks_info(course_block, deprecated_block_types)
|
||||
self._verify_deprecated_info(
|
||||
course_module.id,
|
||||
course_module.advanced_modules,
|
||||
course_block.id,
|
||||
course_block.advanced_modules,
|
||||
info,
|
||||
expected_block_types
|
||||
)
|
||||
|
||||
@@ -79,7 +79,7 @@ def _manage_users(request, course_key):
|
||||
if not user_perms & STUDIO_VIEW_USERS:
|
||||
raise PermissionDenied()
|
||||
|
||||
course_module = modulestore().get_course(course_key)
|
||||
course_block = modulestore().get_course(course_key)
|
||||
instructors = set(CourseInstructorRole(course_key).users_with_role())
|
||||
# the page only lists staff and assumes they're a superset of instructors. Do a union to ensure.
|
||||
staff = set(CourseStaffRole(course_key).users_with_role()).union(instructors)
|
||||
@@ -91,7 +91,7 @@ def _manage_users(request, course_key):
|
||||
formatted_users.append(user_with_role(user, 'staff'))
|
||||
|
||||
return render_to_response('manage_users.html', {
|
||||
'context_course': course_module,
|
||||
'context_course': course_block,
|
||||
'show_transfer_ownership_hint': request.user in instructors and len(instructors) == 1,
|
||||
'users': formatted_users,
|
||||
'allow_actions': bool(user_perms & STUDIO_EDIT_ROLES),
|
||||
|
||||
Reference in New Issue
Block a user