Commit b7765902 by Don Mitchell

Rename BlockUsageLocator's block_id field from usage_id

usage_id implies self-sufficiency. The block_id is relative to its structure.
parent 3cf75198
...@@ -64,7 +64,7 @@ class TemplateTests(unittest.TestCase): ...@@ -64,7 +64,7 @@ class TemplateTests(unittest.TestCase):
self.assertIsInstance(test_chapter, SequenceDescriptor) self.assertIsInstance(test_chapter, SequenceDescriptor)
# refetch parent which should now point to child # refetch parent which should now point to child
test_course = modulestore('split').get_course(test_chapter.location) test_course = modulestore('split').get_course(test_chapter.location)
self.assertIn(test_chapter.location.usage_id, test_course.children) self.assertIn(test_chapter.location.block_id, test_course.children)
def test_temporary_xblocks(self): def test_temporary_xblocks(self):
""" """
...@@ -166,7 +166,7 @@ class TemplateTests(unittest.TestCase): ...@@ -166,7 +166,7 @@ class TemplateTests(unittest.TestCase):
second_problem = persistent_factories.ItemFactory.create( second_problem = persistent_factories.ItemFactory.create(
display_name='problem 2', display_name='problem 2',
parent_location=BlockUsageLocator(updated_loc, usage_id=sub.location.usage_id), parent_location=BlockUsageLocator(updated_loc, block_id=sub.location.block_id),
user_id='testbot', category='problem', user_id='testbot', category='problem',
data="<problem></problem>" data="<problem></problem>"
) )
......
...@@ -51,7 +51,7 @@ def assets_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -51,7 +51,7 @@ def assets_handler(request, tag=None, course_id=None, branch=None, version_guid=
DELETE DELETE
json: delete an asset json: delete an asset
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
......
...@@ -36,7 +36,7 @@ def checklists_handler(request, tag=None, course_id=None, branch=None, version_g ...@@ -36,7 +36,7 @@ def checklists_handler(request, tag=None, course_id=None, branch=None, version_g
POST or PUT POST or PUT
json: updates the checked state for items within a particular checklist. checklist_index is required. json: updates the checked state for items within a particular checklist. checklist_index is required.
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
......
...@@ -62,7 +62,7 @@ def subsection_handler(request, tag=None, course_id=None, branch=None, version_g ...@@ -62,7 +62,7 @@ def subsection_handler(request, tag=None, course_id=None, branch=None, version_g
json: not currently supported json: not currently supported
""" """
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
try: try:
old_location, course, item, lms_link = _get_item_in_course(request, locator) old_location, course, item, lms_link = _get_item_in_course(request, locator)
except ItemNotFoundError: except ItemNotFoundError:
...@@ -151,7 +151,7 @@ def unit_handler(request, tag=None, course_id=None, branch=None, version_guid=No ...@@ -151,7 +151,7 @@ def unit_handler(request, tag=None, course_id=None, branch=None, version_guid=No
json: not currently supported json: not currently supported
""" """
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
try: try:
old_location, course, item, lms_link = _get_item_in_course(request, locator) old_location, course, item, lms_link = _get_item_in_course(request, locator)
except ItemNotFoundError: except ItemNotFoundError:
......
...@@ -11,7 +11,7 @@ from django.utils.translation import ugettext as _ ...@@ -11,7 +11,7 @@ from django.utils.translation import ugettext as _
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django_future.csrf import ensure_csrf_cookie from django_future.csrf import ensure_csrf_cookie
from django.conf import settings from django.conf import settings
from django.views.decorators.http import require_http_methods, require_POST from django.views.decorators.http import require_http_methods
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.http import HttpResponseBadRequest, HttpResponseNotFound
...@@ -60,12 +60,12 @@ __all__ = ['course_info_handler', 'course_handler', 'course_info_update_handler' ...@@ -60,12 +60,12 @@ __all__ = ['course_info_handler', 'course_handler', 'course_info_update_handler'
'textbooks_list_handler', 'textbooks_detail_handler'] 'textbooks_list_handler', 'textbooks_detail_handler']
def _get_locator_and_course(course_id, branch, version_guid, usage_id, user, depth=0): def _get_locator_and_course(course_id, branch, version_guid, block_id, user, depth=0):
""" """
Internal method used to calculate and return the locator and course module Internal method used to calculate and return the locator and course module
for the view functions in this file. for the view functions in this file.
""" """
locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=usage_id) locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block_id)
if not has_access(user, locator): if not has_access(user, locator):
raise PermissionDenied() raise PermissionDenied()
course_location = loc_mapper().translate_locator_to_location(locator) course_location = loc_mapper().translate_locator_to_location(locator)
...@@ -104,7 +104,7 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -104,7 +104,7 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid=
return create_new_course(request) return create_new_course(request)
elif not has_access( elif not has_access(
request.user, request.user,
BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
): ):
raise PermissionDenied() raise PermissionDenied()
elif request.method == 'PUT': elif request.method == 'PUT':
...@@ -366,7 +366,7 @@ def course_info_update_handler(request, tag=None, course_id=None, branch=None, v ...@@ -366,7 +366,7 @@ def course_info_update_handler(request, tag=None, course_id=None, branch=None, v
""" """
if 'application/json' not in request.META.get('HTTP_ACCEPT', 'application/json'): if 'application/json' not in request.META.get('HTTP_ACCEPT', 'application/json'):
return HttpResponseBadRequest("Only supports json requests") return HttpResponseBadRequest("Only supports json requests")
updates_locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) updates_locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
updates_location = loc_mapper().translate_locator_to_location(updates_locator) updates_location = loc_mapper().translate_locator_to_location(updates_locator)
if provided_id == '': if provided_id == '':
provided_id = None provided_id = None
......
...@@ -60,7 +60,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -60,7 +60,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid=
POST or PUT POST or PUT
json: import a course via the .tar.gz file specified in request.FILES json: import a course via the .tar.gz file specified in request.FILES
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
...@@ -271,7 +271,7 @@ def import_status_handler(request, tag=None, course_id=None, branch=None, versio ...@@ -271,7 +271,7 @@ def import_status_handler(request, tag=None, course_id=None, branch=None, versio
3 : Importing to mongo 3 : Importing to mongo
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
...@@ -302,7 +302,7 @@ def export_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -302,7 +302,7 @@ def export_handler(request, tag=None, course_id=None, branch=None, version_guid=
If the tar.gz file has been requested but the export operation fails, an HTML page will be returned If the tar.gz file has been requested but the export operation fails, an HTML page will be returned
which describes the error. which describes the error.
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
......
...@@ -79,7 +79,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -79,7 +79,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
The locator (and old-style id) for the created xblock (minus children) is returned. The locator (and old-style id) for the created xblock (minus children) is returned.
""" """
if course_id is not None: if course_id is not None:
locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, locator): if not has_access(request.user, locator):
raise PermissionDenied() raise PermissionDenied()
old_location = loc_mapper().translate_locator_to_location(locator) old_location = loc_mapper().translate_locator_to_location(locator)
...@@ -330,7 +330,7 @@ def orphan_handler(request, tag=None, course_id=None, branch=None, version_guid= ...@@ -330,7 +330,7 @@ def orphan_handler(request, tag=None, course_id=None, branch=None, version_guid=
:param request: :param request:
:param course_id: Locator syntax course_id :param course_id: Locator syntax course_id
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
# DHM: when split becomes back-end, move or conditionalize this conversion # DHM: when split becomes back-end, move or conditionalize this conversion
old_location = loc_mapper().translate_locator_to_location(location) old_location = loc_mapper().translate_locator_to_location(location)
if request.method == 'GET': if request.method == 'GET':
......
...@@ -62,7 +62,7 @@ def tabs_handler(request, tag=None, course_id=None, branch=None, version_guid=No ...@@ -62,7 +62,7 @@ def tabs_handler(request, tag=None, course_id=None, branch=None, version_guid=No
Creating a tab, deleting a tab, or changing its contents is not supported through this method. Creating a tab, deleting a tab, or changing its contents is not supported through this method.
Instead use the general xblock URL (see item.xblock_handler). Instead use the general xblock URL (see item.xblock_handler).
""" """
locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) locator = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, locator): if not has_access(request.user, locator):
raise PermissionDenied() raise PermissionDenied()
......
...@@ -52,7 +52,7 @@ def course_team_handler(request, tag=None, course_id=None, branch=None, version_ ...@@ -52,7 +52,7 @@ def course_team_handler(request, tag=None, course_id=None, branch=None, version_
DELETE: DELETE:
json: remove a particular course team member from the course team (email is required). json: remove a particular course team member from the course team (email is required).
""" """
location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, usage_id=block) location = BlockUsageLocator(course_id=course_id, branch=branch, version_guid=version_guid, block_id=block)
if not has_access(request.user, location): if not has_access(request.user, location):
raise PermissionDenied() raise PermissionDenied()
......
...@@ -6,7 +6,7 @@ import re ...@@ -6,7 +6,7 @@ import re
import pymongo import pymongo
import bson.son import bson.son
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, DuplicateItemError from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
from xmodule.modulestore.locator import BlockUsageLocator from xmodule.modulestore.locator import BlockUsageLocator
from xmodule.modulestore import Location from xmodule.modulestore import Location
import urllib import urllib
...@@ -157,27 +157,27 @@ class LocMapperStore(object): ...@@ -157,27 +157,27 @@ class LocMapperStore(object):
entry = item entry = item
break break
usage_id = entry['block_map'].get(self._encode_for_mongo(location.name)) block_id = entry['block_map'].get(self._encode_for_mongo(location.name))
if usage_id is None: if block_id is None:
if add_entry_if_missing: if add_entry_if_missing:
usage_id = self._add_to_block_map(location, location_id, entry['block_map']) block_id = self._add_to_block_map(location, location_id, entry['block_map'])
else: else:
raise ItemNotFoundError(location) raise ItemNotFoundError(location)
elif isinstance(usage_id, dict): elif isinstance(block_id, dict):
# name is not unique, look through for the right category # name is not unique, look through for the right category
if location.category in usage_id: if location.category in block_id:
usage_id = usage_id[location.category] block_id = block_id[location.category]
elif add_entry_if_missing: elif add_entry_if_missing:
usage_id = self._add_to_block_map(location, location_id, entry['block_map']) block_id = self._add_to_block_map(location, location_id, entry['block_map'])
else: else:
raise ItemNotFoundError() raise ItemNotFoundError()
else: else:
raise InvalidLocationError() raise InvalidLocationError()
published_usage = BlockUsageLocator( published_usage = BlockUsageLocator(
course_id=entry['course_id'], branch=entry['prod_branch'], usage_id=usage_id) course_id=entry['course_id'], branch=entry['prod_branch'], block_id=block_id)
draft_usage = BlockUsageLocator( draft_usage = BlockUsageLocator(
course_id=entry['course_id'], branch=entry['draft_branch'], usage_id=usage_id) course_id=entry['course_id'], branch=entry['draft_branch'], block_id=block_id)
if published: if published:
result = published_usage result = published_usage
else: else:
...@@ -192,7 +192,7 @@ class LocMapperStore(object): ...@@ -192,7 +192,7 @@ class LocMapperStore(object):
Returns an old style Location for the given Locator if there's an appropriate entry in the Returns an old style Location for the given Locator if there's an appropriate entry in the
mapping collection. Note, it requires that the course was previously mapped (a side effect of mapping collection. Note, it requires that the course was previously mapped (a side effect of
translate_location or explicitly via create_map_entry) and translate_location or explicitly via create_map_entry) and
the block's usage_id was previously stored in the the block's block_id was previously stored in the
map (a side effect of translate_location or via add|update_block_location). map (a side effect of translate_location or via add|update_block_location).
If get_course, then rather than finding the map for this locator, it finds the 'course' root If get_course, then rather than finding the map for this locator, it finds the 'course' root
...@@ -201,7 +201,7 @@ class LocMapperStore(object): ...@@ -201,7 +201,7 @@ class LocMapperStore(object):
If there are no matches, it returns None. If there are no matches, it returns None.
If there's more than one location to locator mapping to the same course_id, it looks for the first If there's more than one location to locator mapping to the same course_id, it looks for the first
one with a mapping for the block usage_id and picks that arbitrary course location. one with a mapping for the block block_id and picks that arbitrary course location.
:param locator: a BlockUsageLocator :param locator: a BlockUsageLocator
""" """
...@@ -215,14 +215,14 @@ class LocMapperStore(object): ...@@ -215,14 +215,14 @@ class LocMapperStore(object):
# This does not require that the course exist in any modulestore # This does not require that the course exist in any modulestore
# only that it has a mapping entry. # only that it has a mapping entry.
maps = self.location_map.find({'course_id': locator.course_id}) maps = self.location_map.find({'course_id': locator.course_id})
# look for one which maps to this block usage_id # look for one which maps to this block block_id
if maps.count() == 0: if maps.count() == 0:
return None return None
result = None result = None
for candidate in maps: for candidate in maps:
old_course_id = self._generate_location_course_id(candidate['_id']) old_course_id = self._generate_location_course_id(candidate['_id'])
for old_name, cat_to_usage in candidate['block_map'].iteritems(): for old_name, cat_to_usage in candidate['block_map'].iteritems():
for category, usage_id in cat_to_usage.iteritems(): for category, block_id in cat_to_usage.iteritems():
# cache all entries and then figure out if we have the one we want # cache all entries and then figure out if we have the one we want
# Always return revision=None because the # Always return revision=None because the
# old draft module store wraps locations as draft before # old draft module store wraps locations as draft before
...@@ -235,16 +235,16 @@ class LocMapperStore(object): ...@@ -235,16 +235,16 @@ class LocMapperStore(object):
self._decode_from_mongo(old_name), self._decode_from_mongo(old_name),
None) None)
published_locator = BlockUsageLocator( published_locator = BlockUsageLocator(
candidate['course_id'], branch=candidate['prod_branch'], usage_id=usage_id candidate['course_id'], branch=candidate['prod_branch'], block_id=block_id
) )
draft_locator = BlockUsageLocator( draft_locator = BlockUsageLocator(
candidate['course_id'], branch=candidate['draft_branch'], usage_id=usage_id candidate['course_id'], branch=candidate['draft_branch'], block_id=block_id
) )
self._cache_location_map_entry(old_course_id, location, published_locator, draft_locator) self._cache_location_map_entry(old_course_id, location, published_locator, draft_locator)
if get_course and category == 'course': if get_course and category == 'course':
result = location result = location
elif not get_course and usage_id == locator.usage_id: elif not get_course and block_id == locator.block_id:
result = location result = location
if result is not None: if result is not None:
return result return result
...@@ -257,13 +257,13 @@ class LocMapperStore(object): ...@@ -257,13 +257,13 @@ class LocMapperStore(object):
# The downside is that if there's more than one course mapped to from the same org/course root # The downside is that if there's more than one course mapped to from the same org/course root
# the block ids will likely be out of sync and collide from an id perspective. HOWEVER, # the block ids will likely be out of sync and collide from an id perspective. HOWEVER,
# if there are few == org/course roots or their content is unrelated, this will work well. # if there are few == org/course roots or their content is unrelated, this will work well.
usage_id = self._verify_uniqueness(location.category + location.name[:3], block_map) block_id = self._verify_uniqueness(location.category + location.name[:3], block_map)
else: else:
usage_id = location.name block_id = location.name
encoded_location_name = self._encode_for_mongo(location.name) encoded_location_name = self._encode_for_mongo(location.name)
block_map.setdefault(encoded_location_name, {})[location.category] = usage_id block_map.setdefault(encoded_location_name, {})[location.category] = block_id
self.location_map.update(location_id, {'$set': {'block_map': block_map}}) self.location_map.update(location_id, {'$set': {'block_map': block_map}})
return usage_id return block_id
def _interpret_location_course_id(self, course_id, location): def _interpret_location_course_id(self, course_id, location):
""" """
......
...@@ -257,7 +257,7 @@ class CourseLocator(Locator): ...@@ -257,7 +257,7 @@ class CourseLocator(Locator):
Returns a copy of itself (downcasting) as a CourseLocator. Returns a copy of itself (downcasting) as a CourseLocator.
The copy has the same CourseLocator fields as the original. The copy has the same CourseLocator fields as the original.
The copy does not include subclass information, such as The copy does not include subclass information, such as
a usage_id (a property of BlockUsageLocator). a block_id (a property of BlockUsageLocator).
""" """
return CourseLocator(course_id=self.course_id, return CourseLocator(course_id=self.course_id,
version_guid=self.version_guid, version_guid=self.version_guid,
...@@ -390,23 +390,23 @@ class BlockUsageLocator(CourseLocator): ...@@ -390,23 +390,23 @@ class BlockUsageLocator(CourseLocator):
""" """
# Default value # Default value
usage_id = None block_id = None
def __init__(self, url=None, version_guid=None, course_id=None, def __init__(self, url=None, version_guid=None, course_id=None,
branch=None, usage_id=None): branch=None, block_id=None):
""" """
Construct a BlockUsageLocator Construct a BlockUsageLocator
Caller may provide url, version_guid, or course_id, and optionally provide branch. Caller may provide url, version_guid, or course_id, and optionally provide branch.
The usage_id may be specified, either explictly or as part of The block_id may be specified, either explictly or as part of
the url or course_id. If omitted, the locator is created but it the url or course_id. If omitted, the locator is created but it
has not yet been initialized. has not yet been initialized.
Resulting BlockUsageLocator will have a usage_id property. Resulting BlockUsageLocator will have a block_id property.
It will have either a version_guid property or a course_id (with optional branch) property, or both. It will have either a version_guid property or a course_id (with optional branch) property, or both.
version_guid must be an instance of bson.objectid.ObjectId or None version_guid must be an instance of bson.objectid.ObjectId or None
url, course_id, branch, and usage_id must be strings or None url, course_id, branch, and block_id must be strings or None
""" """
self._validate_args(url, version_guid, course_id) self._validate_args(url, version_guid, course_id)
...@@ -414,8 +414,8 @@ class BlockUsageLocator(CourseLocator): ...@@ -414,8 +414,8 @@ class BlockUsageLocator(CourseLocator):
self.init_block_ref_from_str(url) self.init_block_ref_from_str(url)
if course_id: if course_id:
self.init_block_ref_from_course_id(course_id) self.init_block_ref_from_course_id(course_id)
if usage_id: if block_id:
self.init_block_ref(usage_id) self.init_block_ref(block_id)
super(BlockUsageLocator, self).__init__( super(BlockUsageLocator, self).__init__(
url=url, url=url,
version_guid=version_guid, version_guid=version_guid,
...@@ -425,9 +425,9 @@ class BlockUsageLocator(CourseLocator): ...@@ -425,9 +425,9 @@ class BlockUsageLocator(CourseLocator):
def is_initialized(self): def is_initialized(self):
""" """
Returns True if usage_id has been initialized, else returns False Returns True if block_id has been initialized, else returns False
""" """
return self.usage_id is not None return self.block_id is not None
def version_agnostic(self): def version_agnostic(self):
""" """
...@@ -442,18 +442,18 @@ class BlockUsageLocator(CourseLocator): ...@@ -442,18 +442,18 @@ class BlockUsageLocator(CourseLocator):
if self.version_guid: if self.version_guid:
return BlockUsageLocator(version_guid=self.version_guid, return BlockUsageLocator(version_guid=self.version_guid,
branch=self.branch, branch=self.branch,
usage_id=self.usage_id) block_id=self.block_id)
else: else:
return BlockUsageLocator(course_id=self.course_id, return BlockUsageLocator(course_id=self.course_id,
branch=self.branch, branch=self.branch,
usage_id=self.usage_id) block_id=self.block_id)
def set_usage_id(self, new): def set_usage_id(self, new):
""" """
Initialize usage_id to new value. Initialize block_id to new value.
If usage_id has already been initialized to a different value, raise an exception. If block_id has already been initialized to a different value, raise an exception.
""" """
self.set_property('usage_id', new) self.set_property('block_id', new)
def init_block_ref(self, block_ref): def init_block_ref(self, block_ref):
if isinstance(block_ref, LocalId): if isinstance(block_ref, LocalId):
...@@ -468,8 +468,8 @@ class BlockUsageLocator(CourseLocator): ...@@ -468,8 +468,8 @@ class BlockUsageLocator(CourseLocator):
""" """
Create a block locator from the given string which may be a url or just the repr (no tag) Create a block locator from the given string which may be a url or just the repr (no tag)
""" """
if hasattr(value, 'usage_id'): if hasattr(value, 'block_id'):
self.init_block_ref(value.usage_id) self.init_block_ref(value.block_id)
return return
if not isinstance(value, basestring): if not isinstance(value, basestring):
return None return None
...@@ -493,7 +493,7 @@ class BlockUsageLocator(CourseLocator): ...@@ -493,7 +493,7 @@ class BlockUsageLocator(CourseLocator):
Return a string representing this location. Return a string representing this location.
""" """
rep = super(BlockUsageLocator, self).__unicode__() rep = super(BlockUsageLocator, self).__unicode__()
return rep + '/' + BLOCK_PREFIX + unicode(self.usage_id) return rep + '/' + BLOCK_PREFIX + unicode(self.block_id)
class DefinitionLocator(Locator): class DefinitionLocator(Locator):
......
...@@ -50,7 +50,7 @@ class SplitMigrator(object): ...@@ -50,7 +50,7 @@ class SplitMigrator(object):
course_location.org, original_course.display_name, course_location.org, original_course.display_name,
user_id, id_root=new_course_id, user_id, id_root=new_course_id,
fields=self._get_json_fields_translate_children(original_course, old_course_id, True), fields=self._get_json_fields_translate_children(original_course, old_course_id, True),
root_usage_id=new_course_root_locator.usage_id, root_block_id=new_course_root_locator.block_id,
master_branch=new_course_root_locator.branch master_branch=new_course_root_locator.branch
) )
...@@ -74,13 +74,13 @@ class SplitMigrator(object): ...@@ -74,13 +74,13 @@ class SplitMigrator(object):
# don't copy the course again. No drafts should get here but check # don't copy the course again. No drafts should get here but check
if module.location != old_course_loc and not getattr(module, 'is_draft', False): if module.location != old_course_loc and not getattr(module, 'is_draft', False):
# create split_xblock using split.create_item # create split_xblock using split.create_item
# where usage_id is computed by translate_location_to_locator # where block_id is computed by translate_location_to_locator
new_locator = self.loc_mapper.translate_location( new_locator = self.loc_mapper.translate_location(
old_course_id, module.location, True, add_entry_if_missing=True old_course_id, module.location, True, add_entry_if_missing=True
) )
_new_module = self.split_modulestore.create_item( _new_module = self.split_modulestore.create_item(
course_version_locator, module.category, user_id, course_version_locator, module.category, user_id,
usage_id=new_locator.usage_id, block_id=new_locator.block_id,
fields=self._get_json_fields_translate_children(module, old_course_id, True), fields=self._get_json_fields_translate_children(module, old_course_id, True),
continue_version=True continue_version=True
) )
...@@ -130,18 +130,18 @@ class SplitMigrator(object): ...@@ -130,18 +130,18 @@ class SplitMigrator(object):
# create a new course version just in case the current head is also the prod head # create a new course version just in case the current head is also the prod head
_new_module = self.split_modulestore.create_item( _new_module = self.split_modulestore.create_item(
new_draft_course_loc, module.category, user_id, new_draft_course_loc, module.category, user_id,
usage_id=new_locator.usage_id, block_id=new_locator.block_id,
fields=self._get_json_fields_translate_children(module, old_course_id, True) fields=self._get_json_fields_translate_children(module, old_course_id, True)
) )
awaiting_adoption[module.location] = new_locator.usage_id awaiting_adoption[module.location] = new_locator.block_id
for draft_location, new_usage_id in awaiting_adoption.iteritems(): for draft_location, new_block_id in awaiting_adoption.iteritems():
for parent_loc in self.draft_modulestore.get_parent_locations(draft_location, old_course_id): for parent_loc in self.draft_modulestore.get_parent_locations(draft_location, old_course_id):
old_parent = self.draft_modulestore.get_item(parent_loc) old_parent = self.draft_modulestore.get_item(parent_loc)
new_parent = self.split_modulestore.get_item( new_parent = self.split_modulestore.get_item(
self.loc_mapper.translate_location(old_course_id, old_parent.location, False) self.loc_mapper.translate_location(old_course_id, old_parent.location, False)
) )
# this only occurs if the parent was also awaiting adoption # this only occurs if the parent was also awaiting adoption
if new_usage_id in new_parent.children: if new_block_id in new_parent.children:
break break
# find index for module: new_parent may be missing quite a few of old_parent's children # find index for module: new_parent may be missing quite a few of old_parent's children
new_parent_cursor = 0 new_parent_cursor = 0
...@@ -152,15 +152,15 @@ class SplitMigrator(object): ...@@ -152,15 +152,15 @@ class SplitMigrator(object):
sibling_loc = self.loc_mapper.translate_location(old_course_id, Location(old_child_loc), False) sibling_loc = self.loc_mapper.translate_location(old_course_id, Location(old_child_loc), False)
# sibling may move cursor # sibling may move cursor
for idx in range(new_parent_cursor, len(new_parent.children)): for idx in range(new_parent_cursor, len(new_parent.children)):
if new_parent.children[idx] == sibling_loc.usage_id: if new_parent.children[idx] == sibling_loc.block_id:
new_parent_cursor = idx + 1 new_parent_cursor = idx + 1
break break
new_parent.children.insert(new_parent_cursor, new_usage_id) new_parent.children.insert(new_parent_cursor, new_block_id)
new_parent = self.split_modulestore.update_item(new_parent, user_id) new_parent = self.split_modulestore.update_item(new_parent, user_id)
def _get_json_fields_translate_children(self, xblock, old_course_id, published): def _get_json_fields_translate_children(self, xblock, old_course_id, published):
""" """
Return the json repr for explicitly set fields but convert all children to their usage_id's Return the json repr for explicitly set fields but convert all children to their block_id's
""" """
fields = self.get_json_fields_explicitly_set(xblock) fields = self.get_json_fields_explicitly_set(xblock)
# this will too generously copy the children even for ones that don't exist in the published b/c the old mongo # this will too generously copy the children even for ones that don't exist in the published b/c the old mongo
...@@ -169,7 +169,7 @@ class SplitMigrator(object): ...@@ -169,7 +169,7 @@ class SplitMigrator(object):
fields['children'] = [ fields['children'] = [
self.loc_mapper.translate_location( self.loc_mapper.translate_location(
old_course_id, Location(child), published, add_entry_if_missing=True old_course_id, Location(child), published, add_entry_if_missing=True
).usage_id ).block_id
for child in fields['children']] for child in fields['children']]
return fields return fields
......
...@@ -47,26 +47,26 @@ class CachingDescriptorSystem(MakoDescriptorSystem): ...@@ -47,26 +47,26 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
self.default_class = default_class self.default_class = default_class
self.local_modules = {} self.local_modules = {}
def _load_item(self, usage_id, course_entry_override=None): def _load_item(self, block_id, course_entry_override=None):
if isinstance(usage_id, BlockUsageLocator) and isinstance(usage_id.usage_id, LocalId): if isinstance(block_id, BlockUsageLocator) and isinstance(block_id.block_id, LocalId):
try: try:
return self.local_modules[usage_id] return self.local_modules[block_id]
except KeyError: except KeyError:
raise ItemNotFoundError raise ItemNotFoundError
json_data = self.module_data.get(usage_id) json_data = self.module_data.get(block_id)
if json_data is None: if json_data is None:
# deeper than initial descendant fetch or doesn't exist # deeper than initial descendant fetch or doesn't exist
self.modulestore.cache_items(self, [usage_id], lazy=self.lazy) self.modulestore.cache_items(self, [block_id], lazy=self.lazy)
json_data = self.module_data.get(usage_id) json_data = self.module_data.get(block_id)
if json_data is None: if json_data is None:
raise ItemNotFoundError(usage_id) raise ItemNotFoundError(block_id)
class_ = XModuleDescriptor.load_class( class_ = XModuleDescriptor.load_class(
json_data.get('category'), json_data.get('category'),
self.default_class self.default_class
) )
return self.xblock_from_json(class_, usage_id, json_data, course_entry_override) return self.xblock_from_json(class_, block_id, json_data, course_entry_override)
# xblock's runtime does not always pass enough contextual information to figure out # xblock's runtime does not always pass enough contextual information to figure out
# which named container (course x branch) or which parent is requesting an item. Because split allows # which named container (course x branch) or which parent is requesting an item. Because split allows
...@@ -79,7 +79,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem): ...@@ -79,7 +79,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
# low; thus, the course_entry is most likely correct. If the thread is looking at > 1 named container # low; thus, the course_entry is most likely correct. If the thread is looking at > 1 named container
# pointing to the same structure, the access is likely to be chunky enough that the last known container # pointing to the same structure, the access is likely to be chunky enough that the last known container
# is the intended one when not given a course_entry_override; thus, the caching of the last branch/course_id. # is the intended one when not given a course_entry_override; thus, the caching of the last branch/course_id.
def xblock_from_json(self, class_, usage_id, json_data, course_entry_override=None): def xblock_from_json(self, class_, block_id, json_data, course_entry_override=None):
if course_entry_override is None: if course_entry_override is None:
course_entry_override = self.course_entry course_entry_override = self.course_entry
else: else:
...@@ -91,12 +91,12 @@ class CachingDescriptorSystem(MakoDescriptorSystem): ...@@ -91,12 +91,12 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
definition_id = self.modulestore.definition_locator(definition) definition_id = self.modulestore.definition_locator(definition)
# If no usage id is provided, generate an in-memory id # If no usage id is provided, generate an in-memory id
if usage_id is None: if block_id is None:
usage_id = LocalId() block_id = LocalId()
block_locator = BlockUsageLocator( block_locator = BlockUsageLocator(
version_guid=course_entry_override['structure']['_id'], version_guid=course_entry_override['structure']['_id'],
usage_id=usage_id, block_id=block_id,
course_id=course_entry_override.get('course_id'), course_id=course_entry_override.get('course_id'),
branch=course_entry_override.get('branch') branch=course_entry_override.get('branch')
) )
...@@ -121,7 +121,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem): ...@@ -121,7 +121,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
self, self,
BlockUsageLocator( BlockUsageLocator(
version_guid=course_entry_override['structure']['_id'], version_guid=course_entry_override['structure']['_id'],
usage_id=usage_id block_id=block_id
), ),
error_msg=exc_info_to_str(sys.exc_info()) error_msg=exc_info_to_str(sys.exc_info())
) )
...@@ -136,7 +136,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem): ...@@ -136,7 +136,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
module.save() module.save()
# If this is an in-memory block, store it in this system # If this is an in-memory block, store it in this system
if isinstance(block_locator.usage_id, LocalId): if isinstance(block_locator.block_id, LocalId):
self.local_modules[block_locator] = module self.local_modules[block_locator] = module
return module return module
...@@ -11,7 +11,7 @@ Representation: ...@@ -11,7 +11,7 @@ Representation:
** 'versions': versions_dict: {branch_id: structure_id, ...} ** 'versions': versions_dict: {branch_id: structure_id, ...}
* structure: * structure:
** '_id': an ObjectId (guid), ** '_id': an ObjectId (guid),
** 'root': root_usage_id (string of key in 'blocks' for the root of this structure, ** 'root': root_block_id (string of key in 'blocks' for the root of this structure,
** 'previous_version': the structure from which this one was derived. For published courses, this ** 'previous_version': the structure from which this one was derived. For published courses, this
points to the previously published version of the structure not the draft published to this. points to the previously published version of the structure not the draft published to this.
** 'original_version': the original structure id in the previous_version relation. Is a pseudo object ** 'original_version': the original structure id in the previous_version relation. Is a pseudo object
...@@ -130,20 +130,20 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -130,20 +130,20 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# the split mongo store is used for item creation as well as item persistence # the split mongo store is used for item creation as well as item persistence
self.mixologist = Mixologist(self.xblock_mixins) self.mixologist = Mixologist(self.xblock_mixins)
def cache_items(self, system, base_usage_ids, depth=0, lazy=True): def cache_items(self, system, base_block_ids, depth=0, lazy=True):
''' '''
Handles caching of items once inheritance and any other one time Handles caching of items once inheritance and any other one time
per course per fetch operations are done. per course per fetch operations are done.
:param system: a CachingDescriptorSystem :param system: a CachingDescriptorSystem
:param base_usage_ids: list of usage_ids to fetch :param base_block_ids: list of block_ids to fetch
:param depth: how deep below these to prefetch :param depth: how deep below these to prefetch
:param lazy: whether to fetch definitions or use placeholders :param lazy: whether to fetch definitions or use placeholders
''' '''
new_module_data = {} new_module_data = {}
for usage_id in base_usage_ids: for block_id in base_block_ids:
new_module_data = self.descendants( new_module_data = self.descendants(
system.course_entry['structure']['blocks'], system.course_entry['structure']['blocks'],
usage_id, block_id,
depth, depth,
new_module_data new_module_data
) )
...@@ -167,7 +167,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -167,7 +167,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
system.module_data.update(new_module_data) system.module_data.update(new_module_data)
return system.module_data return system.module_data
def _load_items(self, course_entry, usage_ids, depth=0, lazy=True): def _load_items(self, course_entry, block_ids, depth=0, lazy=True):
''' '''
Load & cache the given blocks from the course. Prefetch down to the Load & cache the given blocks from the course. Prefetch down to the
given depth. Load the definitions into each block if lazy is False; given depth. Load the definitions into each block if lazy is False;
...@@ -187,8 +187,8 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -187,8 +187,8 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
mixins=self.xblock_mixins mixins=self.xblock_mixins
) )
self._add_cache(course_entry['structure']['_id'], system) self._add_cache(course_entry['structure']['_id'], system)
self.cache_items(system, usage_ids, depth, lazy) self.cache_items(system, block_ids, depth, lazy)
return [system.load_item(usage_id, course_entry) for usage_id in usage_ids] return [system.load_item(block_id, course_entry) for block_id in block_ids]
def _get_cache(self, course_version_guid): def _get_cache(self, course_version_guid):
""" """
...@@ -333,7 +333,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -333,7 +333,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
the course or the block w/in the course do not exist for the given version. the course or the block w/in the course do not exist for the given version.
raises InsufficientSpecificationError if the locator does not id a block raises InsufficientSpecificationError if the locator does not id a block
""" """
if block_location.usage_id is None: if block_location.block_id is None:
raise InsufficientSpecificationError(block_location) raise InsufficientSpecificationError(block_location)
try: try:
course_structure = self._lookup_course(block_location)['structure'] course_structure = self._lookup_course(block_location)['structure']
...@@ -341,7 +341,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -341,7 +341,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# this error only occurs if the course does not exist # this error only occurs if the course does not exist
return False return False
return course_structure['blocks'].get(block_location.usage_id) is not None return course_structure['blocks'].get(block_location.block_id) is not None
def get_item(self, location, depth=0): def get_item(self, location, depth=0):
""" """
...@@ -365,7 +365,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -365,7 +365,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
if not location.is_initialized(): if not location.is_initialized():
raise InsufficientSpecificationError("Not yet initialized: %s" % location) raise InsufficientSpecificationError("Not yet initialized: %s" % location)
course = self._lookup_course(location) course = self._lookup_course(location)
items = self._load_items(course, [location.usage_id], depth, lazy=True) items = self._load_items(course, [location.block_id], depth, lazy=True)
if len(items) == 0: if len(items) == 0:
raise ItemNotFoundError(location) raise ItemNotFoundError(location)
return items[0] return items[0]
...@@ -397,9 +397,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -397,9 +397,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
qualifiers = {} qualifiers = {}
course = self._lookup_course(locator) course = self._lookup_course(locator)
items = [] items = []
for usage_id, value in course['structure']['blocks'].iteritems(): for block_id, value in course['structure']['blocks'].iteritems():
if self._block_matches(value, qualifiers): if self._block_matches(value, qualifiers):
items.append(usage_id) items.append(block_id)
if len(items) > 0: if len(items) > 0:
return self._load_items(course, items, 0, lazy=True) return self._load_items(course, items, 0, lazy=True)
...@@ -421,16 +421,16 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -421,16 +421,16 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def get_parent_locations(self, locator, course_id=None): def get_parent_locations(self, locator, course_id=None):
''' '''
Return the locations (Locators w/ usage_ids) for the parents of this location in this Return the locations (Locators w/ block_ids) for the parents of this location in this
course. Could use get_items(location, {'children': usage_id}) but this is slightly faster. course. Could use get_items(location, {'children': block_id}) but this is slightly faster.
NOTE: the locator must contain the usage_id, and this code does not actually ensure usage_id exists NOTE: the locator must contain the block_id, and this code does not actually ensure block_id exists
:param locator: BlockUsageLocator restricting search scope :param locator: BlockUsageLocator restricting search scope
:param usage_id: ignored. Only included for API compatibility. Specify the usage_id within the locator. :param course_id: ignored. Only included for API compatibility. Specify the course_id within the locator.
''' '''
course = self._lookup_course(locator) course = self._lookup_course(locator)
items = self._get_parents_from_structure(locator.usage_id, course['structure']) items = self._get_parents_from_structure(locator.block_id, course['structure'])
return [BlockUsageLocator(url=locator.as_course_locator(), usage_id=parent_id) return [BlockUsageLocator(url=locator.as_course_locator(), block_id=parent_id)
for parent_id in items] for parent_id in items]
def get_orphans(self, course_id, detached_categories, branch): def get_orphans(self, course_id, detached_categories, branch):
...@@ -447,7 +447,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -447,7 +447,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
if block_data['category'] in detached_categories: if block_data['category'] in detached_categories:
items.discard(block_id) items.discard(block_id)
return [ return [
BlockUsageLocator(course_id=course_id, branch=branch, usage_id=block_id) BlockUsageLocator(course_id=course_id, branch=branch, block_id=block_id)
for block_id in items for block_id in items
] ]
...@@ -547,25 +547,25 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -547,25 +547,25 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
''' '''
# version_agnostic means we don't care if the head and version don't align, trust the version # version_agnostic means we don't care if the head and version don't align, trust the version
course_struct = self._lookup_course(block_locator.version_agnostic())['structure'] course_struct = self._lookup_course(block_locator.version_agnostic())['structure']
usage_id = block_locator.usage_id block_id = block_locator.block_id
update_version_field = 'blocks.{}.edit_info.update_version'.format(usage_id) update_version_field = 'blocks.{}.edit_info.update_version'.format(block_id)
all_versions_with_block = self.db_connection.find_matching_structures({'original_version': course_struct['original_version'], all_versions_with_block = self.db_connection.find_matching_structures({'original_version': course_struct['original_version'],
update_version_field: {'$exists': True}}) update_version_field: {'$exists': True}})
# find (all) root versions and build map previous: [successors] # find (all) root versions and build map previous: [successors]
possible_roots = [] possible_roots = []
result = {} result = {}
for version in all_versions_with_block: for version in all_versions_with_block:
if version['_id'] == version['blocks'][usage_id]['edit_info']['update_version']: if version['_id'] == version['blocks'][block_id]['edit_info']['update_version']:
if version['blocks'][usage_id]['edit_info'].get('previous_version') is None: if version['blocks'][block_id]['edit_info'].get('previous_version') is None:
possible_roots.append(version['blocks'][usage_id]['edit_info']['update_version']) possible_roots.append(version['blocks'][block_id]['edit_info']['update_version'])
else: else:
result.setdefault(version['blocks'][usage_id]['edit_info']['previous_version'], set()).add( result.setdefault(version['blocks'][block_id]['edit_info']['previous_version'], set()).add(
version['blocks'][usage_id]['edit_info']['update_version']) version['blocks'][block_id]['edit_info']['update_version'])
# more than one possible_root means usage was added and deleted > 1x. # more than one possible_root means usage was added and deleted > 1x.
if len(possible_roots) > 1: if len(possible_roots) > 1:
# find the history segment including block_locator's version # find the history segment including block_locator's version
element_to_find = course_struct['blocks'][usage_id]['edit_info']['update_version'] element_to_find = course_struct['blocks'][block_id]['edit_info']['update_version']
if element_to_find in possible_roots: if element_to_find in possible_roots:
possible_roots = [element_to_find] possible_roots = [element_to_find]
for possibility in possible_roots: for possibility in possible_roots:
...@@ -576,9 +576,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -576,9 +576,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return None return None
# convert the results value sets to locators # convert the results value sets to locators
for k, versions in result.iteritems(): for k, versions in result.iteritems():
result[k] = [BlockUsageLocator(version_guid=version, usage_id=usage_id) result[k] = [BlockUsageLocator(version_guid=version, block_id=block_id)
for version in versions] for version in versions]
return VersionTree(BlockUsageLocator(version_guid=possible_roots[0], usage_id=usage_id), result) return VersionTree(BlockUsageLocator(version_guid=possible_roots[0], block_id=block_id), result)
def get_definition_successors(self, definition_locator, version_history_depth=1): def get_definition_successors(self, definition_locator, version_history_depth=1):
''' '''
...@@ -646,7 +646,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -646,7 +646,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
else: else:
return definition_locator, False return definition_locator, False
def _generate_usage_id(self, course_blocks, category): def _generate_block_id(self, course_blocks, category):
""" """
Generate a somewhat readable block id unique w/in this course using the category Generate a somewhat readable block id unique w/in this course using the category
:param course_blocks: the current list of blocks. :param course_blocks: the current list of blocks.
...@@ -687,7 +687,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -687,7 +687,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# validation behavior a responsibility of the model layer rather than the persistence layer. # validation behavior a responsibility of the model layer rather than the persistence layer.
def create_item( def create_item(
self, course_or_parent_locator, category, user_id, self, course_or_parent_locator, category, user_id,
usage_id=None, definition_locator=None, fields=None, block_id=None, definition_locator=None, fields=None,
force=False, continue_version=False force=False, continue_version=False
): ):
""" """
...@@ -712,7 +712,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -712,7 +712,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
to the existing definition. If fields contains Scope.content and definition_locator is not None, then to the existing definition. If fields contains Scope.content and definition_locator is not None, then
the Scope.content fields are assumed to be a new payload for definition_locator. the Scope.content fields are assumed to be a new payload for definition_locator.
:param usage_id: if provided, must not already exist in the structure. Provides the block id for the :param block_id: if provided, must not already exist in the structure. Provides the block id for the
new item in this structure. Otherwise, one is computed using the category appended w/ a few digits. new item in this structure. Otherwise, one is computed using the category appended w/ a few digits.
:param continue_version: continue changing the current structure at the head of the course. Very dangerous :param continue_version: continue changing the current structure at the head of the course. Very dangerous
...@@ -755,18 +755,18 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -755,18 +755,18 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
new_id = new_structure['_id'] new_id = new_structure['_id']
# generate usage id # generate usage id
if usage_id is not None: if block_id is not None:
if usage_id in new_structure['blocks']: if block_id in new_structure['blocks']:
raise DuplicateItemError(usage_id, self, 'structures') raise DuplicateItemError(block_id, self, 'structures')
else: else:
new_usage_id = usage_id new_block_id = block_id
else: else:
new_usage_id = self._generate_usage_id(new_structure['blocks'], category) new_block_id = self._generate_block_id(new_structure['blocks'], category)
block_fields = partitioned_fields.get(Scope.settings, {}) block_fields = partitioned_fields.get(Scope.settings, {})
if Scope.children in partitioned_fields: if Scope.children in partitioned_fields:
block_fields.update(partitioned_fields[Scope.children]) block_fields.update(partitioned_fields[Scope.children])
new_structure['blocks'][new_usage_id] = { new_structure['blocks'][new_block_id] = {
"category": category, "category": category,
"definition": definition_locator.definition_id, "definition": definition_locator.definition_id,
"fields": block_fields, "fields": block_fields,
...@@ -780,9 +780,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -780,9 +780,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# if given parent, add new block as child and update parent's version # if given parent, add new block as child and update parent's version
parent = None parent = None
if isinstance(course_or_parent_locator, BlockUsageLocator) and course_or_parent_locator.usage_id is not None: if isinstance(course_or_parent_locator, BlockUsageLocator) and course_or_parent_locator.block_id is not None:
parent = new_structure['blocks'][course_or_parent_locator.usage_id] parent = new_structure['blocks'][course_or_parent_locator.block_id]
parent['fields'].setdefault('children', []).append(new_usage_id) parent['fields'].setdefault('children', []).append(new_block_id)
if not continue_version or parent['edit_info']['update_version'] != structure['_id']: if not continue_version or parent['edit_info']['update_version'] != structure['_id']:
parent['edit_info']['edited_on'] = datetime.datetime.now(UTC) parent['edit_info']['edited_on'] = datetime.datetime.now(UTC)
parent['edit_info']['edited_by'] = user_id parent['edit_info']['edited_by'] = user_id
...@@ -806,13 +806,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -806,13 +806,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# reconstruct the new_item from the cache # reconstruct the new_item from the cache
return self.get_item(BlockUsageLocator(course_id=course_parent, return self.get_item(BlockUsageLocator(course_id=course_parent,
usage_id=new_usage_id, block_id=new_block_id,
version_guid=new_id)) version_guid=new_id))
def create_course( def create_course(
self, org, prettyid, user_id, id_root=None, fields=None, self, org, prettyid, user_id, id_root=None, fields=None,
master_branch='draft', versions_dict=None, root_category='course', master_branch='draft', versions_dict=None, root_category='course',
root_usage_id='course' root_block_id='course'
): ):
""" """
Create a new entry in the active courses index which points to an existing or new structure. Returns Create a new entry in the active courses index which points to an existing or new structure. Returns
...@@ -870,7 +870,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -870,7 +870,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
self.db_connection.insert_definition(definition_entry) self.db_connection.insert_definition(definition_entry)
draft_structure = self._new_structure( draft_structure = self._new_structure(
user_id, root_usage_id, root_category, block_fields, definition_id user_id, root_block_id, root_category, block_fields, definition_id
) )
new_id = draft_structure['_id'] new_id = draft_structure['_id']
...@@ -944,7 +944,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -944,7 +944,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
descriptor.definition_locator, is_updated = self.update_definition_from_data( descriptor.definition_locator, is_updated = self.update_definition_from_data(
descriptor.definition_locator, descriptor.get_explicitly_set_fields_by_scope(Scope.content), user_id) descriptor.definition_locator, descriptor.get_explicitly_set_fields_by_scope(Scope.content), user_id)
# check children # check children
original_entry = original_structure['blocks'][descriptor.location.usage_id] original_entry = original_structure['blocks'][descriptor.location.block_id]
if (not is_updated and descriptor.has_children if (not is_updated and descriptor.has_children
and not self._xblock_lists_equal(original_entry['fields']['children'], descriptor.children)): and not self._xblock_lists_equal(original_entry['fields']['children'], descriptor.children)):
is_updated = True is_updated = True
...@@ -958,12 +958,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -958,12 +958,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# if updated, rev the structure # if updated, rev the structure
if is_updated: if is_updated:
new_structure = self._version_structure(original_structure, user_id) new_structure = self._version_structure(original_structure, user_id)
block_data = new_structure['blocks'][descriptor.location.usage_id] block_data = new_structure['blocks'][descriptor.location.block_id]
block_data["definition"] = descriptor.definition_locator.definition_id block_data["definition"] = descriptor.definition_locator.definition_id
block_data["fields"] = descriptor.get_explicitly_set_fields_by_scope(Scope.settings) block_data["fields"] = descriptor.get_explicitly_set_fields_by_scope(Scope.settings)
if descriptor.has_children: if descriptor.has_children:
block_data['fields']["children"] = [self._usage_id(child) for child in descriptor.children] block_data['fields']["children"] = [self._block_id(child) for child in descriptor.children]
new_id = new_structure['_id'] new_id = new_structure['_id']
block_data['edit_info'] = { block_data['edit_info'] = {
...@@ -990,7 +990,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -990,7 +990,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
create or update the xblock and all of its children. The xblock's location must specify a course. create or update the xblock and all of its children. The xblock's location must specify a course.
If it doesn't specify a usage_id, then it's presumed to be new and need creation. This function If it doesn't specify a usage_id, then it's presumed to be new and need creation. This function
descends the children performing the same operation for any that are xblocks. Any children which descends the children performing the same operation for any that are xblocks. Any children which
are usage_ids just update the children pointer. are block_ids just update the children pointer.
All updates go into the same course version (bulk updater). All updates go into the same course version (bulk updater).
...@@ -1020,7 +1020,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1020,7 +1020,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return self.get_item( return self.get_item(
BlockUsageLocator( BlockUsageLocator(
course_id=xblock.location.course_id, course_id=xblock.location.course_id,
usage_id=xblock.location.usage_id, block_id=xblock.location.block_id,
branch=xblock.location.branch, branch=xblock.location.branch,
version_guid=new_id version_guid=new_id
) )
...@@ -1039,38 +1039,38 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1039,38 +1039,38 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
xblock.definition_locator, is_updated = self.update_definition_from_data( xblock.definition_locator, is_updated = self.update_definition_from_data(
xblock.definition_locator, new_def_data, user_id) xblock.definition_locator, new_def_data, user_id)
if isinstance(xblock.scope_ids.usage_id.usage_id, LocalId): if isinstance(xblock.scope_ids.usage_id.block_id, LocalId):
# generate an id # generate an id
is_new = True is_new = True
is_updated = True is_updated = True
usage_id = self._generate_usage_id(structure_blocks, xblock.category) block_id = self._generate_block_id(structure_blocks, xblock.category)
xblock.scope_ids.usage_id.usage_id = usage_id xblock.scope_ids.usage_id.block_id = block_id
else: else:
is_new = False is_new = False
usage_id = xblock.location.usage_id block_id = xblock.location.block_id
if (not is_updated and xblock.has_children if (not is_updated and xblock.has_children
and not self._xblock_lists_equal(structure_blocks[usage_id]['fields']['children'], xblock.children)): and not self._xblock_lists_equal(structure_blocks[block_id]['fields']['children'], xblock.children)):
is_updated = True is_updated = True
children = [] children = []
if xblock.has_children: if xblock.has_children:
for child in xblock.children: for child in xblock.children:
if isinstance(child.usage_id, LocalId): if isinstance(child.block_id, LocalId):
child_block = xblock.system.get_block(child) child_block = xblock.system.get_block(child)
is_updated = self._persist_subdag(child_block, user_id, structure_blocks, new_id) or is_updated is_updated = self._persist_subdag(child_block, user_id, structure_blocks, new_id) or is_updated
children.append(child_block.location.usage_id) children.append(child_block.location.block_id)
else: else:
children.append(child) children.append(child)
block_fields = xblock.get_explicitly_set_fields_by_scope(Scope.settings) block_fields = xblock.get_explicitly_set_fields_by_scope(Scope.settings)
if not is_new and not is_updated: if not is_new and not is_updated:
is_updated = self._compare_settings(block_fields, structure_blocks[usage_id]['fields']) is_updated = self._compare_settings(block_fields, structure_blocks[block_id]['fields'])
if children: if children:
block_fields['children'] = children block_fields['children'] = children
if is_updated: if is_updated:
previous_version = None if is_new else structure_blocks[usage_id]['edit_info'].get('update_version') previous_version = None if is_new else structure_blocks[block_id]['edit_info'].get('update_version')
structure_blocks[usage_id] = { structure_blocks[block_id] = {
"category": xblock.category, "category": xblock.category,
"definition": xblock.definition_locator.definition_id, "definition": xblock.definition_locator.definition_id,
"fields": block_fields, "fields": block_fields,
...@@ -1214,7 +1214,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1214,7 +1214,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
""" """
assert isinstance(usage_locator, BlockUsageLocator) and usage_locator.is_initialized() assert isinstance(usage_locator, BlockUsageLocator) and usage_locator.is_initialized()
original_structure = self._lookup_course(usage_locator)['structure'] original_structure = self._lookup_course(usage_locator)['structure']
if original_structure['root'] == usage_locator.usage_id: if original_structure['root'] == usage_locator.block_id:
raise ValueError("Cannot delete the root of a course") raise ValueError("Cannot delete the root of a course")
index_entry = self._get_index_if_valid(usage_locator, force) index_entry = self._get_index_if_valid(usage_locator, force)
new_structure = self._version_structure(original_structure, user_id) new_structure = self._version_structure(original_structure, user_id)
...@@ -1222,22 +1222,22 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1222,22 +1222,22 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
new_id = new_structure['_id'] new_id = new_structure['_id']
parents = self.get_parent_locations(usage_locator) parents = self.get_parent_locations(usage_locator)
for parent in parents: for parent in parents:
parent_block = new_blocks[parent.usage_id] parent_block = new_blocks[parent.block_id]
parent_block['fields']['children'].remove(usage_locator.usage_id) parent_block['fields']['children'].remove(usage_locator.block_id)
parent_block['edit_info']['edited_on'] = datetime.datetime.now(UTC) parent_block['edit_info']['edited_on'] = datetime.datetime.now(UTC)
parent_block['edit_info']['edited_by'] = user_id parent_block['edit_info']['edited_by'] = user_id
parent_block['edit_info']['previous_version'] = parent_block['edit_info']['update_version'] parent_block['edit_info']['previous_version'] = parent_block['edit_info']['update_version']
parent_block['edit_info']['update_version'] = new_id parent_block['edit_info']['update_version'] = new_id
# remove subtree # remove subtree
def remove_subtree(usage_id): def remove_subtree(block_id):
for child in new_blocks[usage_id]['fields'].get('children', []): for child in new_blocks[block_id]['fields'].get('children', []):
remove_subtree(child) remove_subtree(child)
del new_blocks[usage_id] del new_blocks[block_id]
if delete_children: if delete_children:
remove_subtree(usage_locator.usage_id) remove_subtree(usage_locator.block_id)
else: else:
del new_blocks[usage_locator.usage_id] del new_blocks[usage_locator.block_id]
# update index if appropriate and structures # update index if appropriate and structures
self.db_connection.insert_structure(new_structure) self.db_connection.insert_structure(new_structure)
...@@ -1307,22 +1307,22 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1307,22 +1307,22 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# migration where the old mongo published had pointers to privates # migration where the old mongo published had pointers to privates
pass pass
def descendants(self, block_map, usage_id, depth, descendent_map): def descendants(self, block_map, block_id, depth, descendent_map):
""" """
adds block and its descendants out to depth to descendent_map adds block and its descendants out to depth to descendent_map
Depth specifies the number of levels of descendants to return Depth specifies the number of levels of descendants to return
(0 => this usage only, 1 => this usage and its children, etc...) (0 => this usage only, 1 => this usage and its children, etc...)
A depth of None returns all descendants A depth of None returns all descendants
""" """
if usage_id not in block_map: if block_id not in block_map:
return descendent_map return descendent_map
if usage_id not in descendent_map: if block_id not in descendent_map:
descendent_map[usage_id] = block_map[usage_id] descendent_map[block_id] = block_map[block_id]
if depth is None or depth > 0: if depth is None or depth > 0:
depth = depth - 1 if depth is not None else None depth = depth - 1 if depth is not None else None
for child in block_map[usage_id]['fields'].get('children', []): for child in block_map[block_id]['fields'].get('children', []):
descendent_map = self.descendants(block_map, child, depth, descendent_map = self.descendants(block_map, child, depth,
descendent_map) descendent_map)
...@@ -1343,7 +1343,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1343,7 +1343,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def internal_clean_children(self, course_locator): def internal_clean_children(self, course_locator):
""" """
Only intended for rather low level methods to use. Goes through the children attrs of Only intended for rather low level methods to use. Goes through the children attrs of
each block removing any whose usage_id is not a member of the course. Does not generate each block removing any whose block_id is not a member of the course. Does not generate
a new version of the course but overwrites the existing one. a new version of the course but overwrites the existing one.
:param course_locator: the course to clean :param course_locator: the course to clean
...@@ -1352,7 +1352,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1352,7 +1352,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
for block in original_structure['blocks'].itervalues(): for block in original_structure['blocks'].itervalues():
if 'fields' in block and 'children' in block['fields']: if 'fields' in block and 'children' in block['fields']:
block['fields']["children"] = [ block['fields']["children"] = [
usage_id for usage_id in block['fields']["children"] if usage_id in original_structure['blocks'] block_id for block_id in block['fields']["children"] if block_id in original_structure['blocks']
] ]
self.db_connection.update_structure(original_structure) self.db_connection.update_structure(original_structure)
# clear cache again b/c inheritance may be wrong over orphans # clear cache again b/c inheritance may be wrong over orphans
...@@ -1402,17 +1402,17 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1402,17 +1402,17 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return False return False
for ele_a, ele_b in zip(lista, listb): for ele_a, ele_b in zip(lista, listb):
if ele_a != ele_b: if ele_a != ele_b:
if self._usage_id(ele_a) != self._usage_id(ele_b): if self._block_id(ele_a) != self._block_id(ele_b):
return False return False
return True return True
def _usage_id(self, xblock_or_id): def _block_id(self, xblock_or_id):
""" """
arg is either an xblock or an id. If an xblock, get the usage_id from its location. Otherwise, return itself. arg is either an xblock or an id. If an xblock, get the block_id from its location. Otherwise, return itself.
:param xblock_or_id: :param xblock_or_id:
""" """
if isinstance(xblock_or_id, XModuleDescriptor): if isinstance(xblock_or_id, XModuleDescriptor):
return xblock_or_id.location.usage_id return xblock_or_id.location.block_id
else: else:
return xblock_or_id return xblock_or_id
...@@ -1523,7 +1523,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1523,7 +1523,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
""" """
return SPLIT_MONGO_MODULESTORE_TYPE return SPLIT_MONGO_MODULESTORE_TYPE
def _new_structure(self, user_id, root_usage_id, def _new_structure(self, user_id, root_block_id,
root_category=None, block_fields=None, definition_id=None): root_category=None, block_fields=None, definition_id=None):
""" """
Internal function: create a structure element with no previous version. Must provide the root id Internal function: create a structure element with no previous version. Must provide the root id
...@@ -1533,13 +1533,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1533,13 +1533,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
new_id = ObjectId() new_id = ObjectId()
if root_category is not None: if root_category is not None:
blocks = { blocks = {
root_usage_id: self._new_block(user_id, root_category, block_fields, definition_id, new_id) root_block_id: self._new_block(user_id, root_category, block_fields, definition_id, new_id)
} }
else: else:
blocks = {} blocks = {}
return { return {
'_id': new_id, '_id': new_id,
'root': root_usage_id, 'root': root_block_id,
'previous_version': None, 'previous_version': None,
'original_version': new_id, 'original_version': new_id,
'edited_by': user_id, 'edited_by': user_id,
...@@ -1547,14 +1547,14 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ...@@ -1547,14 +1547,14 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
'blocks': blocks 'blocks': blocks
} }
def _get_parents_from_structure(self, usage_id, structure): def _get_parents_from_structure(self, block_id, structure):
""" """
Given a structure, find all of usage_id's parents in that structure Given a structure, find all of block_id's parents in that structure
""" """
items = [] items = []
for parent_id, value in structure['blocks'].iteritems(): for parent_id, value in structure['blocks'].iteritems():
for child_id in value['fields'].get('children', []): for child_id in value['fields'].get('children', []):
if usage_id == child_id: if block_id == child_id:
items.append(parent_id) items.append(parent_id)
return items return items
......
...@@ -76,9 +76,9 @@ class TestLocationMapper(unittest.TestCase): ...@@ -76,9 +76,9 @@ class TestLocationMapper(unittest.TestCase):
self.assertEqual(entry['block_map'], block_map) self.assertEqual(entry['block_map'], block_map)
def translate_n_check(self, location, old_style_course_id, new_style_course_id, usage_id, branch, add_entry=False): def translate_n_check(self, location, old_style_course_id, new_style_course_id, block_id, branch, add_entry=False):
""" """
Request translation, check course_id, usage_id, and branch Request translation, check course_id, block_id, and branch
""" """
prob_locator = loc_mapper().translate_location( prob_locator = loc_mapper().translate_location(
old_style_course_id, old_style_course_id,
...@@ -87,7 +87,7 @@ class TestLocationMapper(unittest.TestCase): ...@@ -87,7 +87,7 @@ class TestLocationMapper(unittest.TestCase):
add_entry_if_missing=add_entry add_entry_if_missing=add_entry
) )
self.assertEqual(prob_locator.course_id, new_style_course_id) self.assertEqual(prob_locator.course_id, new_style_course_id)
self.assertEqual(prob_locator.usage_id, usage_id) self.assertEqual(prob_locator.block_id, block_id)
self.assertEqual(prob_locator.branch, branch) self.assertEqual(prob_locator.branch, branch)
def test_translate_location_read_only(self): def test_translate_location_read_only(self):
...@@ -243,7 +243,7 @@ class TestLocationMapper(unittest.TestCase): ...@@ -243,7 +243,7 @@ class TestLocationMapper(unittest.TestCase):
new_style_course_id = '{}.geek_dept.{}.baz_run'.format(org, course) new_style_course_id = '{}.geek_dept.{}.baz_run'.format(org, course)
prob_locator = BlockUsageLocator( prob_locator = BlockUsageLocator(
course_id=new_style_course_id, course_id=new_style_course_id,
usage_id='problem2', block_id='problem2',
branch='published' branch='published'
) )
prob_location = loc_mapper().translate_locator_to_location(prob_locator) prob_location = loc_mapper().translate_locator_to_location(prob_locator)
...@@ -267,21 +267,21 @@ class TestLocationMapper(unittest.TestCase): ...@@ -267,21 +267,21 @@ class TestLocationMapper(unittest.TestCase):
self.assertEqual(prob_location, Location('i4x', org, course, 'course', 'baz_run', None)) self.assertEqual(prob_location, Location('i4x', org, course, 'course', 'baz_run', None))
# explicit branch # explicit branch
prob_locator = BlockUsageLocator( prob_locator = BlockUsageLocator(
course_id=prob_locator.course_id, branch='draft', usage_id=prob_locator.usage_id course_id=prob_locator.course_id, branch='draft', block_id=prob_locator.block_id
) )
prob_location = loc_mapper().translate_locator_to_location(prob_locator) prob_location = loc_mapper().translate_locator_to_location(prob_locator)
# Even though the problem was set as draft, we always return revision=None to work # Even though the problem was set as draft, we always return revision=None to work
# with old mongo/draft modulestores. # with old mongo/draft modulestores.
self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123', None)) self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123', None))
prob_locator = BlockUsageLocator( prob_locator = BlockUsageLocator(
course_id=new_style_course_id, usage_id='problem2', branch='production' course_id=new_style_course_id, block_id='problem2', branch='production'
) )
prob_location = loc_mapper().translate_locator_to_location(prob_locator) prob_location = loc_mapper().translate_locator_to_location(prob_locator)
self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123', None)) self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123', None))
# same for chapter except chapter cannot be draft in old system # same for chapter except chapter cannot be draft in old system
chap_locator = BlockUsageLocator( chap_locator = BlockUsageLocator(
course_id=new_style_course_id, course_id=new_style_course_id,
usage_id='chapter48f', block_id='chapter48f',
branch='production' branch='production'
) )
chap_location = loc_mapper().translate_locator_to_location(chap_locator) chap_location = loc_mapper().translate_locator_to_location(chap_locator)
...@@ -291,7 +291,7 @@ class TestLocationMapper(unittest.TestCase): ...@@ -291,7 +291,7 @@ class TestLocationMapper(unittest.TestCase):
chap_location = loc_mapper().translate_locator_to_location(chap_locator) chap_location = loc_mapper().translate_locator_to_location(chap_locator)
self.assertEqual(chap_location, Location('i4x', org, course, 'chapter', '48f23a10395384929234')) self.assertEqual(chap_location, Location('i4x', org, course, 'chapter', '48f23a10395384929234'))
chap_locator = BlockUsageLocator( chap_locator = BlockUsageLocator(
course_id=new_style_course_id, usage_id='chapter48f', branch='production' course_id=new_style_course_id, block_id='chapter48f', branch='production'
) )
chap_location = loc_mapper().translate_locator_to_location(chap_locator) chap_location = loc_mapper().translate_locator_to_location(chap_locator)
self.assertEqual(chap_location, Location('i4x', org, course, 'chapter', '48f23a10395384929234')) self.assertEqual(chap_location, Location('i4x', org, course, 'chapter', '48f23a10395384929234'))
...@@ -300,7 +300,7 @@ class TestLocationMapper(unittest.TestCase): ...@@ -300,7 +300,7 @@ class TestLocationMapper(unittest.TestCase):
prob_locator2 = BlockUsageLocator( prob_locator2 = BlockUsageLocator(
course_id=new_style_course_id, course_id=new_style_course_id,
branch='draft', branch='draft',
usage_id='problem3' block_id='problem3'
) )
prob_location = loc_mapper().translate_locator_to_location(prob_locator2) prob_location = loc_mapper().translate_locator_to_location(prob_locator2)
self.assertIsNone(prob_location, 'Found non-existent problem') self.assertIsNone(prob_location, 'Found non-existent problem')
...@@ -325,7 +325,7 @@ class TestLocationMapper(unittest.TestCase): ...@@ -325,7 +325,7 @@ class TestLocationMapper(unittest.TestCase):
prob_locator = BlockUsageLocator( prob_locator = BlockUsageLocator(
course_id=new_style_course_id, course_id=new_style_course_id,
branch='production', branch='production',
usage_id='problem3' block_id='problem3'
) )
prob_location = loc_mapper().translate_locator_to_location(prob_locator) prob_location = loc_mapper().translate_locator_to_location(prob_locator)
self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123')) self.assertEqual(prob_location, Location('i4x', org, course, 'problem', 'abc123'))
......
...@@ -255,9 +255,9 @@ class LocatorTest(TestCase): ...@@ -255,9 +255,9 @@ class LocatorTest(TestCase):
""" """
course_id = 'mit.eecs-1' course_id = 'mit.eecs-1'
branch = 'foo' branch = 'foo'
usage_id = 'problem:with-colon~2' block_id = 'problem:with-colon~2'
testobj = BlockUsageLocator(course_id=course_id, branch=branch, usage_id=usage_id) testobj = BlockUsageLocator(course_id=course_id, branch=branch, block_id=block_id)
self.check_block_locn_fields(testobj, 'Cannot handle colon', course_id=course_id, branch=branch, block=usage_id) self.check_block_locn_fields(testobj, 'Cannot handle colon', course_id=course_id, branch=branch, block=block_id)
def test_repr(self): def test_repr(self):
testurn = 'mit.eecs.6002x/' + BRANCH_PREFIX + 'published/' + BLOCK_PREFIX + 'HW3' testurn = 'mit.eecs.6002x/' + BRANCH_PREFIX + 'published/' + BLOCK_PREFIX + 'HW3'
...@@ -275,7 +275,7 @@ class LocatorTest(TestCase): ...@@ -275,7 +275,7 @@ class LocatorTest(TestCase):
self.assertEqual(location, Locator.to_locator_or_location(list(location_tuple))) self.assertEqual(location, Locator.to_locator_or_location(list(location_tuple)))
self.assertEqual(location, Locator.to_locator_or_location(location.dict())) self.assertEqual(location, Locator.to_locator_or_location(location.dict()))
locator = BlockUsageLocator(course_id='foo.bar', branch='alpha', usage_id='deep') locator = BlockUsageLocator(course_id='foo.bar', branch='alpha', block_id='deep')
self.assertEqual(locator, Locator.to_locator_or_location(locator)) self.assertEqual(locator, Locator.to_locator_or_location(locator))
self.assertEqual(locator.as_course_locator(), Locator.to_locator_or_location(locator.as_course_locator())) self.assertEqual(locator.as_course_locator(), Locator.to_locator_or_location(locator.as_course_locator()))
self.assertEqual(location, Locator.to_locator_or_location(location.url())) self.assertEqual(location, Locator.to_locator_or_location(location.url()))
...@@ -347,4 +347,4 @@ class LocatorTest(TestCase): ...@@ -347,4 +347,4 @@ class LocatorTest(TestCase):
""" """
self.check_course_locn_fields(testobj, msg, version_guid, course_id, self.check_course_locn_fields(testobj, msg, version_guid, course_id,
branch) branch)
self.assertEqual(testobj.usage_id, block) self.assertEqual(testobj.block_id, block)
...@@ -87,14 +87,14 @@ class TestOrphan(unittest.TestCase): ...@@ -87,14 +87,14 @@ class TestOrphan(unittest.TestCase):
course_or_parent_locator = BlockUsageLocator( course_or_parent_locator = BlockUsageLocator(
course_id=self.split_course_id, course_id=self.split_course_id,
branch='draft', branch='draft',
usage_id=parent_name block_id=parent_name
) )
else: else:
course_or_parent_locator = CourseLocator( course_or_parent_locator = CourseLocator(
course_id='test_org.test_course.runid', course_id='test_org.test_course.runid',
branch='draft', branch='draft',
) )
self.split_mongo.create_item(course_or_parent_locator, category, self.userid, usage_id=name, fields=fields) self.split_mongo.create_item(course_or_parent_locator, category, self.userid, block_id=name, fields=fields)
def _create_course(self): def _create_course(self):
""" """
...@@ -114,7 +114,7 @@ class TestOrphan(unittest.TestCase): ...@@ -114,7 +114,7 @@ class TestOrphan(unittest.TestCase):
fields.update(data) fields.update(data)
# split requires the course to be created separately from creating items # split requires the course to be created separately from creating items
self.split_mongo.create_course( self.split_mongo.create_course(
'test_org', 'my course', self.userid, self.split_course_id, fields=fields, root_usage_id='runid' 'test_org', 'my course', self.userid, self.split_course_id, fields=fields, root_block_id='runid'
) )
self.course_location = Location('i4x', 'test_org', 'test_course', 'course', 'runid') self.course_location = Location('i4x', 'test_org', 'test_course', 'course', 'runid')
self.old_mongo.create_and_save_xmodule(self.course_location, data, metadata) self.old_mongo.create_and_save_xmodule(self.course_location, data, metadata)
...@@ -150,9 +150,9 @@ class TestOrphan(unittest.TestCase): ...@@ -150,9 +150,9 @@ class TestOrphan(unittest.TestCase):
""" """
orphans = self.split_mongo.get_orphans(self.split_course_id, ['static_tab', 'about', 'course_info'], 'draft') orphans = self.split_mongo.get_orphans(self.split_course_id, ['static_tab', 'about', 'course_info'], 'draft')
self.assertEqual(len(orphans), 3, "Wrong # {}".format(orphans)) self.assertEqual(len(orphans), 3, "Wrong # {}".format(orphans))
location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', usage_id='OrphanChapter') location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', block_id='OrphanChapter')
self.assertIn(location, orphans) self.assertIn(location, orphans)
location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', usage_id='OrphanVert') location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', block_id='OrphanVert')
self.assertIn(location, orphans) self.assertIn(location, orphans)
location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', usage_id='OrphanHtml') location = BlockUsageLocator(course_id=self.split_course_id, branch='draft', block_id='OrphanHtml')
self.assertIn(location, orphans) self.assertIn(location, orphans)
...@@ -105,7 +105,7 @@ class SplitModuleTest(unittest.TestCase): ...@@ -105,7 +105,7 @@ class SplitModuleTest(unittest.TestCase):
matches the _id. matches the _id.
""" """
for element in collection: for element in collection:
if element.location.usage_id == _id: if element.location.block_id == _id:
return element return element
...@@ -267,11 +267,11 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -267,11 +267,11 @@ class SplitModuleItemTests(SplitModuleTest):
''' '''
course_id = 'GreekHero' course_id = 'GreekHero'
# positive tests of various forms # positive tests of various forms
locator = BlockUsageLocator(version_guid=self.GUID_D1, usage_id='head12345') locator = BlockUsageLocator(version_guid=self.GUID_D1, block_id='head12345')
self.assertTrue(modulestore().has_item(course_id, locator), self.assertTrue(modulestore().has_item(course_id, locator),
"couldn't find in %s" % self.GUID_D1) "couldn't find in %s" % self.GUID_D1)
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', branch='draft') locator = BlockUsageLocator(course_id='GreekHero', block_id='head12345', branch='draft')
self.assertTrue( self.assertTrue(
modulestore().has_item(locator.course_id, locator), modulestore().has_item(locator.course_id, locator),
"couldn't find in 12345" "couldn't find in 12345"
...@@ -280,7 +280,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -280,7 +280,7 @@ class SplitModuleItemTests(SplitModuleTest):
modulestore().has_item(locator.course_id, BlockUsageLocator( modulestore().has_item(locator.course_id, BlockUsageLocator(
course_id=locator.course_id, course_id=locator.course_id,
branch='draft', branch='draft',
usage_id=locator.usage_id block_id=locator.block_id
)), )),
"couldn't find in draft 12345" "couldn't find in draft 12345"
) )
...@@ -288,7 +288,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -288,7 +288,7 @@ class SplitModuleItemTests(SplitModuleTest):
modulestore().has_item(locator.course_id, BlockUsageLocator( modulestore().has_item(locator.course_id, BlockUsageLocator(
course_id=locator.course_id, course_id=locator.course_id,
branch='published', branch='published',
usage_id=locator.usage_id)), block_id=locator.block_id)),
"found in published 12345" "found in published 12345"
) )
locator.branch = 'draft' locator.branch = 'draft'
...@@ -298,18 +298,18 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -298,18 +298,18 @@ class SplitModuleItemTests(SplitModuleTest):
) )
# not a course obj # not a course obj
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', branch='draft') locator = BlockUsageLocator(course_id='GreekHero', block_id='chapter1', branch='draft')
self.assertTrue( self.assertTrue(
modulestore().has_item(locator.course_id, locator), modulestore().has_item(locator.course_id, locator),
"couldn't find chapter1" "couldn't find chapter1"
) )
# in published course # in published course
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='draft') locator = BlockUsageLocator(course_id="wonderful", block_id="head23456", branch='draft')
self.assertTrue( self.assertTrue(
modulestore().has_item( modulestore().has_item(
locator.course_id, locator.course_id,
BlockUsageLocator(course_id=locator.course_id, usage_id=locator.usage_id, branch='published') BlockUsageLocator(course_id=locator.course_id, block_id=locator.block_id, branch='published')
), "couldn't find in 23456" ), "couldn't find in 23456"
) )
locator.branch = 'published' locator.branch = 'published'
...@@ -319,9 +319,9 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -319,9 +319,9 @@ class SplitModuleItemTests(SplitModuleTest):
# negative tests--not found # negative tests--not found
# no such course or block # no such course or block
course_id = 'GreekHero' course_id = 'GreekHero'
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", branch='draft') locator = BlockUsageLocator(course_id="doesnotexist", block_id="head23456", branch='draft')
self.assertFalse(modulestore().has_item(course_id, locator)) self.assertFalse(modulestore().has_item(course_id, locator))
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", branch='draft') locator = BlockUsageLocator(course_id="wonderful", block_id="doesnotexist", branch='draft')
self.assertFalse(modulestore().has_item(course_id, locator)) self.assertFalse(modulestore().has_item(course_id, locator))
# negative tests--insufficient specification # negative tests--insufficient specification
...@@ -336,7 +336,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -336,7 +336,7 @@ class SplitModuleItemTests(SplitModuleTest):
get_item(blocklocator) get_item(blocklocator)
''' '''
# positive tests of various forms # positive tests of various forms
locator = BlockUsageLocator(version_guid=self.GUID_D1, usage_id='head12345') locator = BlockUsageLocator(version_guid=self.GUID_D1, block_id='head12345')
block = modulestore().get_item(locator) block = modulestore().get_item(locator)
self.assertIsInstance(block, CourseDescriptor) self.assertIsInstance(block, CourseDescriptor)
# get_instance just redirects to get_item, ignores course_id # get_instance just redirects to get_item, ignores course_id
...@@ -355,7 +355,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -355,7 +355,7 @@ class SplitModuleItemTests(SplitModuleTest):
block.grade_cutoffs, {"Pass": 0.45}, block.grade_cutoffs, {"Pass": 0.45},
) )
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', branch='draft') locator = BlockUsageLocator(course_id='GreekHero', block_id='head12345', branch='draft')
verify_greek_hero(modulestore().get_item(locator)) verify_greek_hero(modulestore().get_item(locator))
# get_instance just redirects to get_item, ignores course_id # get_instance just redirects to get_item, ignores course_id
verify_greek_hero(modulestore().get_instance("course_id", locator)) verify_greek_hero(modulestore().get_instance("course_id", locator))
...@@ -364,7 +364,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -364,7 +364,7 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertRaises(ItemNotFoundError, self.assertRaises(ItemNotFoundError,
modulestore().get_item, modulestore().get_item,
BlockUsageLocator(course_id=locator.as_course_locator(), BlockUsageLocator(course_id=locator.as_course_locator(),
usage_id=locator.usage_id, block_id=locator.block_id,
branch='published')) branch='published'))
locator.branch = 'draft' locator.branch = 'draft'
self.assertIsInstance( self.assertIsInstance(
...@@ -374,7 +374,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -374,7 +374,7 @@ class SplitModuleItemTests(SplitModuleTest):
def test_get_non_root(self): def test_get_non_root(self):
# not a course obj # not a course obj
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', branch='draft') locator = BlockUsageLocator(course_id='GreekHero', block_id='chapter1', branch='draft')
block = modulestore().get_item(locator) block = modulestore().get_item(locator)
self.assertEqual(block.location.course_id, "GreekHero") self.assertEqual(block.location.course_id, "GreekHero")
self.assertEqual(block.category, 'chapter') self.assertEqual(block.category, 'chapter')
...@@ -383,7 +383,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -383,7 +383,7 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertEqual(block.edited_by, "testassist@edx.org") self.assertEqual(block.edited_by, "testassist@edx.org")
# in published course # in published course
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='published') locator = BlockUsageLocator(course_id="wonderful", block_id="head23456", branch='published')
self.assertIsInstance( self.assertIsInstance(
modulestore().get_item(locator), modulestore().get_item(locator),
CourseDescriptor CourseDescriptor
...@@ -391,10 +391,10 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -391,10 +391,10 @@ class SplitModuleItemTests(SplitModuleTest):
# negative tests--not found # negative tests--not found
# no such course or block # no such course or block
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", branch='draft') locator = BlockUsageLocator(course_id="doesnotexist", block_id="head23456", branch='draft')
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
modulestore().get_item(locator) modulestore().get_item(locator)
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", branch='draft') locator = BlockUsageLocator(course_id="wonderful", block_id="doesnotexist", branch='draft')
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
modulestore().get_item(locator) modulestore().get_item(locator)
...@@ -457,22 +457,22 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -457,22 +457,22 @@ class SplitModuleItemTests(SplitModuleTest):
matches = modulestore().get_items(locator, qualifiers={'fields': {'children': 'chapter2'}}) matches = modulestore().get_items(locator, qualifiers={'fields': {'children': 'chapter2'}})
self.assertEqual(len(matches), 1) self.assertEqual(len(matches), 1)
self.assertEqual(matches[0].location.usage_id, 'head12345') self.assertEqual(matches[0].location.block_id, 'head12345')
def test_get_parents(self): def test_get_parents(self):
''' '''
get_parent_locations(locator, [usage_id], [branch]): [BlockUsageLocator] get_parent_locations(locator, [block_id], [branch]): [BlockUsageLocator]
''' '''
locator = BlockUsageLocator(course_id="GreekHero", branch='draft', usage_id='chapter1') locator = BlockUsageLocator(course_id="GreekHero", branch='draft', block_id='chapter1')
parents = modulestore().get_parent_locations(locator) parents = modulestore().get_parent_locations(locator)
self.assertEqual(len(parents), 1) self.assertEqual(len(parents), 1)
self.assertEqual(parents[0].usage_id, 'head12345') self.assertEqual(parents[0].block_id, 'head12345')
self.assertEqual(parents[0].course_id, "GreekHero") self.assertEqual(parents[0].course_id, "GreekHero")
locator.usage_id = 'chapter2' locator.block_id = 'chapter2'
parents = modulestore().get_parent_locations(locator) parents = modulestore().get_parent_locations(locator)
self.assertEqual(len(parents), 1) self.assertEqual(len(parents), 1)
self.assertEqual(parents[0].usage_id, 'head12345') self.assertEqual(parents[0].block_id, 'head12345')
locator.usage_id = 'nosuchblock' locator.block_id = 'nosuchblock'
parents = modulestore().get_parent_locations(locator) parents = modulestore().get_parent_locations(locator)
self.assertEqual(len(parents), 0) self.assertEqual(len(parents), 0)
...@@ -480,7 +480,7 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -480,7 +480,7 @@ class SplitModuleItemTests(SplitModuleTest):
""" """
Test the existing get_children method on xdescriptors Test the existing get_children method on xdescriptors
""" """
locator = BlockUsageLocator(course_id="GreekHero", usage_id="head12345", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="head12345", branch='draft')
block = modulestore().get_item(locator) block = modulestore().get_item(locator)
children = block.get_children() children = block.get_children()
expected_ids = [ expected_ids = [
...@@ -488,8 +488,8 @@ class SplitModuleItemTests(SplitModuleTest): ...@@ -488,8 +488,8 @@ class SplitModuleItemTests(SplitModuleTest):
] ]
for child in children: for child in children:
self.assertEqual(child.category, "chapter") self.assertEqual(child.category, "chapter")
self.assertIn(child.location.usage_id, expected_ids) self.assertIn(child.location.block_id, expected_ids)
expected_ids.remove(child.location.usage_id) expected_ids.remove(child.location.block_id)
self.assertEqual(len(expected_ids), 0) self.assertEqual(len(expected_ids), 0)
...@@ -551,7 +551,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -551,7 +551,7 @@ class TestItemCrud(SplitModuleTest):
# check that block does not exist in previous version # check that block does not exist in previous version
locator = BlockUsageLocator( locator = BlockUsageLocator(
version_guid=premod_course.location.version_guid, version_guid=premod_course.location.version_guid,
usage_id=new_module.location.usage_id block_id=new_module.location.block_id
) )
self.assertRaises(ItemNotFoundError, modulestore().get_item, locator) self.assertRaises(ItemNotFoundError, modulestore().get_item, locator)
...@@ -559,7 +559,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -559,7 +559,7 @@ class TestItemCrud(SplitModuleTest):
""" """
Test create_item w/ specifying the parent of the new item Test create_item w/ specifying the parent of the new item
""" """
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='draft') locator = BlockUsageLocator(course_id="wonderful", block_id="head23456", branch='draft')
premod_course = modulestore().get_course(locator) premod_course = modulestore().get_course(locator)
category = 'chapter' category = 'chapter'
new_module = modulestore().create_item( new_module = modulestore().create_item(
...@@ -570,16 +570,16 @@ class TestItemCrud(SplitModuleTest): ...@@ -570,16 +570,16 @@ class TestItemCrud(SplitModuleTest):
# check that course version changed and course's previous is the other one # check that course version changed and course's previous is the other one
self.assertNotEqual(new_module.location.version_guid, premod_course.location.version_guid) self.assertNotEqual(new_module.location.version_guid, premod_course.location.version_guid)
parent = modulestore().get_item(locator) parent = modulestore().get_item(locator)
self.assertIn(new_module.location.usage_id, parent.children) self.assertIn(new_module.location.block_id, parent.children)
self.assertEqual(str(new_module.definition_locator.definition_id), "cd00000000000000dddd0022") self.assertEqual(str(new_module.definition_locator.definition_id), "cd00000000000000dddd0022")
def test_unique_naming(self): def test_unique_naming(self):
""" """
Check that 2 modules of same type get unique usage_ids. Also check that if creation provides Check that 2 modules of same type get unique block_ids. Also check that if creation provides
a definition id and new def data that it branches the definition in the db. a definition id and new def data that it branches the definition in the db.
Actually, this tries to test all create_item features not tested above. Actually, this tries to test all create_item features not tested above.
""" """
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", branch='draft') locator = BlockUsageLocator(course_id="contender", block_id="head345679", branch='draft')
category = 'problem' category = 'problem'
premod_time = datetime.datetime.now(UTC) - datetime.timedelta(seconds=1) premod_time = datetime.datetime.now(UTC) - datetime.timedelta(seconds=1)
new_payload = "<problem>empty</problem>" new_payload = "<problem>empty</problem>"
...@@ -595,9 +595,9 @@ class TestItemCrud(SplitModuleTest): ...@@ -595,9 +595,9 @@ class TestItemCrud(SplitModuleTest):
) )
# check that course version changed and course's previous is the other one # check that course version changed and course's previous is the other one
parent = modulestore().get_item(locator) parent = modulestore().get_item(locator)
self.assertNotEqual(new_module.location.usage_id, another_module.location.usage_id) self.assertNotEqual(new_module.location.block_id, another_module.location.block_id)
self.assertIn(new_module.location.usage_id, parent.children) self.assertIn(new_module.location.block_id, parent.children)
self.assertIn(another_module.location.usage_id, parent.children) self.assertIn(another_module.location.block_id, parent.children)
self.assertEqual(new_module.data, new_payload) self.assertEqual(new_module.data, new_payload)
self.assertEqual(another_module.data, another_payload) self.assertEqual(another_module.data, another_payload)
# check definition histories # check definition histories
...@@ -641,13 +641,13 @@ class TestItemCrud(SplitModuleTest): ...@@ -641,13 +641,13 @@ class TestItemCrud(SplitModuleTest):
self.assertEqual(refetch_course.update_version, course_block_update_version) self.assertEqual(refetch_course.update_version, course_block_update_version)
refetch_index_history_info = modulestore().get_course_history_info(refetch_course.location) refetch_index_history_info = modulestore().get_course_history_info(refetch_course.location)
self.assertEqual(refetch_index_history_info, index_history_info) self.assertEqual(refetch_index_history_info, index_history_info)
self.assertIn(new_ele.location.usage_id, refetch_course.children) self.assertIn(new_ele.location.block_id, refetch_course.children)
# try to create existing item # try to create existing item
with self.assertRaises(DuplicateItemError): with self.assertRaises(DuplicateItemError):
_fail = modulestore().create_item( _fail = modulestore().create_item(
new_course.location, 'chapter', user, new_course.location, 'chapter', user,
usage_id=new_ele.location.usage_id, block_id=new_ele.location.block_id,
fields={'display_name': 'chapter 2'}, fields={'display_name': 'chapter 2'},
continue_version=True continue_version=True
) )
...@@ -678,7 +678,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -678,7 +678,7 @@ class TestItemCrud(SplitModuleTest):
# add new child to old parent in continued (leave off version_guid) # add new child to old parent in continued (leave off version_guid)
course_module_locator = BlockUsageLocator( course_module_locator = BlockUsageLocator(
course_id=new_course.location.course_id, course_id=new_course.location.course_id,
usage_id=new_course.location.usage_id, block_id=new_course.location.block_id,
branch=new_course.location.branch branch=new_course.location.branch
) )
new_ele = modulestore().create_item( new_ele = modulestore().create_item(
...@@ -691,7 +691,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -691,7 +691,7 @@ class TestItemCrud(SplitModuleTest):
# check children, previous_version # check children, previous_version
refetch_course = modulestore().get_course(versionless_course_locator) refetch_course = modulestore().get_course(versionless_course_locator)
self.assertIn(new_ele.location.usage_id, refetch_course.children) self.assertIn(new_ele.location.block_id, refetch_course.children)
self.assertEqual(refetch_course.previous_version, course_block_update_version) self.assertEqual(refetch_course.previous_version, course_block_update_version)
self.assertEqual(refetch_course.update_version, transaction_guid) self.assertEqual(refetch_course.update_version, transaction_guid)
...@@ -699,7 +699,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -699,7 +699,7 @@ class TestItemCrud(SplitModuleTest):
""" """
test updating an items metadata ensuring the definition doesn't version but the course does if it should test updating an items metadata ensuring the definition doesn't version but the course does if it should
""" """
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem3_2", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="problem3_2", branch='draft')
problem = modulestore().get_item(locator) problem = modulestore().get_item(locator)
pre_def_id = problem.definition_locator.definition_id pre_def_id = problem.definition_locator.definition_id
pre_version_guid = problem.location.version_guid pre_version_guid = problem.location.version_guid
...@@ -718,7 +718,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -718,7 +718,7 @@ class TestItemCrud(SplitModuleTest):
# refetch to ensure original didn't change # refetch to ensure original didn't change
original_location = BlockUsageLocator( original_location = BlockUsageLocator(
version_guid=pre_version_guid, version_guid=pre_version_guid,
usage_id=problem.location.usage_id block_id=problem.location.block_id
) )
problem = modulestore().get_item(original_location) problem = modulestore().get_item(original_location)
self.assertNotEqual(problem.max_attempts, 4, "original changed") self.assertNotEqual(problem.max_attempts, 4, "original changed")
...@@ -737,7 +737,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -737,7 +737,7 @@ class TestItemCrud(SplitModuleTest):
""" """
test updating an item's children ensuring the definition doesn't version but the course does if it should test updating an item's children ensuring the definition doesn't version but the course does if it should
""" """
locator = BlockUsageLocator(course_id="GreekHero", usage_id="chapter3", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="chapter3", branch='draft')
block = modulestore().get_item(locator) block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id pre_def_id = block.definition_locator.definition_id
pre_version_guid = block.location.version_guid pre_version_guid = block.location.version_guid
...@@ -752,7 +752,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -752,7 +752,7 @@ class TestItemCrud(SplitModuleTest):
self.assertNotEqual(updated_problem.location.version_guid, pre_version_guid) self.assertNotEqual(updated_problem.location.version_guid, pre_version_guid)
self.assertEqual(updated_problem.children, block.children) self.assertEqual(updated_problem.children, block.children)
self.assertNotIn(moved_child, updated_problem.children) self.assertNotIn(moved_child, updated_problem.children)
locator.usage_id = "chapter1" locator.block_id = "chapter1"
other_block = modulestore().get_item(locator) other_block = modulestore().get_item(locator)
other_block.children.append(moved_child) other_block.children.append(moved_child)
other_block.save() # decache model changes other_block.save() # decache model changes
...@@ -763,7 +763,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -763,7 +763,7 @@ class TestItemCrud(SplitModuleTest):
""" """
test updating an item's definition: ensure it gets versioned as well as the course getting versioned test updating an item's definition: ensure it gets versioned as well as the course getting versioned
""" """
locator = BlockUsageLocator(course_id="GreekHero", usage_id="head12345", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="head12345", branch='draft')
block = modulestore().get_item(locator) block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id pre_def_id = block.definition_locator.definition_id
pre_version_guid = block.location.version_guid pre_version_guid = block.location.version_guid
...@@ -781,7 +781,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -781,7 +781,7 @@ class TestItemCrud(SplitModuleTest):
Test updating metadata, children, and definition in a single call ensuring all the versioning occurs Test updating metadata, children, and definition in a single call ensuring all the versioning occurs
""" """
# first add 2 children to the course for the update to manipulate # first add 2 children to the course for the update to manipulate
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", branch='draft') locator = BlockUsageLocator(course_id="contender", block_id="head345679", branch='draft')
category = 'problem' category = 'problem'
new_payload = "<problem>empty</problem>" new_payload = "<problem>empty</problem>"
modulestore().create_item( modulestore().create_item(
...@@ -823,7 +823,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -823,7 +823,7 @@ class TestItemCrud(SplitModuleTest):
'deleting_user') 'deleting_user')
reusable_location = BlockUsageLocator( reusable_location = BlockUsageLocator(
course_id=course.location.course_id, course_id=course.location.course_id,
usage_id=course.location.usage_id, block_id=course.location.block_id,
branch='draft') branch='draft')
# delete a leaf # delete a leaf
...@@ -832,12 +832,12 @@ class TestItemCrud(SplitModuleTest): ...@@ -832,12 +832,12 @@ class TestItemCrud(SplitModuleTest):
new_course_loc = modulestore().delete_item(locn_to_del, 'deleting_user', delete_children=False) new_course_loc = modulestore().delete_item(locn_to_del, 'deleting_user', delete_children=False)
deleted = BlockUsageLocator(course_id=reusable_location.course_id, deleted = BlockUsageLocator(course_id=reusable_location.course_id,
branch=reusable_location.branch, branch=reusable_location.branch,
usage_id=locn_to_del.usage_id) block_id=locn_to_del.block_id)
self.assertFalse(modulestore().has_item(reusable_location.course_id, deleted)) self.assertFalse(modulestore().has_item(reusable_location.course_id, deleted))
self.assertRaises(VersionConflictError, modulestore().has_item, reusable_location.course_id, locn_to_del) self.assertRaises(VersionConflictError, modulestore().has_item, reusable_location.course_id, locn_to_del)
locator = BlockUsageLocator( locator = BlockUsageLocator(
version_guid=locn_to_del.version_guid, version_guid=locn_to_del.version_guid,
usage_id=locn_to_del.usage_id block_id=locn_to_del.block_id
) )
self.assertTrue(modulestore().has_item(reusable_location.course_id, locator)) self.assertTrue(modulestore().has_item(reusable_location.course_id, locator))
self.assertNotEqual(new_course_loc.version_guid, course.location.version_guid) self.assertNotEqual(new_course_loc.version_guid, course.location.version_guid)
...@@ -854,10 +854,10 @@ class TestItemCrud(SplitModuleTest): ...@@ -854,10 +854,10 @@ class TestItemCrud(SplitModuleTest):
BlockUsageLocator( BlockUsageLocator(
course_id=node_loc.course_id, course_id=node_loc.course_id,
branch=node_loc.branch, branch=node_loc.branch,
usage_id=node.location.usage_id))) block_id=node.location.block_id)))
locator = BlockUsageLocator( locator = BlockUsageLocator(
version_guid=node.location.version_guid, version_guid=node.location.version_guid,
usage_id=node.location.usage_id) block_id=node.location.block_id)
self.assertTrue(modulestore().has_item(reusable_location.course_id, locator)) self.assertTrue(modulestore().has_item(reusable_location.course_id, locator))
if node.has_children: if node.has_children:
for sub in node.get_children(): for sub in node.get_children():
...@@ -868,7 +868,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -868,7 +868,7 @@ class TestItemCrud(SplitModuleTest):
course = modulestore().create_course('nihilx', 'deletion', 'deleting_user') course = modulestore().create_course('nihilx', 'deletion', 'deleting_user')
root = BlockUsageLocator( root = BlockUsageLocator(
course_id=course.location.course_id, course_id=course.location.course_id,
usage_id=course.location.usage_id, block_id=course.location.block_id,
branch='draft') branch='draft')
for _ in range(4): for _ in range(4):
self.create_subtree_for_deletion(root, ['chapter', 'vertical', 'problem']) self.create_subtree_for_deletion(root, ['chapter', 'vertical', 'problem'])
...@@ -878,7 +878,7 @@ class TestItemCrud(SplitModuleTest): ...@@ -878,7 +878,7 @@ class TestItemCrud(SplitModuleTest):
if not category_queue: if not category_queue:
return return
node = modulestore().create_item(parent, category_queue[0], 'deleting_user') node = modulestore().create_item(parent, category_queue[0], 'deleting_user')
node_loc = BlockUsageLocator(parent.as_course_locator(), usage_id=node.location.usage_id) node_loc = BlockUsageLocator(parent.as_course_locator(), block_id=node.location.block_id)
for _ in range(4): for _ in range(4):
self.create_subtree_for_deletion(node_loc, category_queue[1:]) self.create_subtree_for_deletion(node_loc, category_queue[1:])
...@@ -971,7 +971,7 @@ class TestCourseCreation(SplitModuleTest): ...@@ -971,7 +971,7 @@ class TestCourseCreation(SplitModuleTest):
self.assertFalse( self.assertFalse(
modulestore().has_item(new_draft_locator.course_id, BlockUsageLocator( modulestore().has_item(new_draft_locator.course_id, BlockUsageLocator(
original_locator, original_locator,
usage_id=new_item.location.usage_id block_id=new_item.location.block_id
)) ))
) )
...@@ -1051,9 +1051,9 @@ class TestCourseCreation(SplitModuleTest): ...@@ -1051,9 +1051,9 @@ class TestCourseCreation(SplitModuleTest):
user = random.getrandbits(32) user = random.getrandbits(32)
new_course = modulestore().create_course( new_course = modulestore().create_course(
'test_org', 'test_transaction', user, 'test_org', 'test_transaction', user,
root_usage_id='top', root_category='chapter' root_block_id='top', root_category='chapter'
) )
self.assertEqual(new_course.location.usage_id, 'top') self.assertEqual(new_course.location.block_id, 'top')
self.assertEqual(new_course.category, 'chapter') self.assertEqual(new_course.category, 'chapter')
# look at db to verify # look at db to verify
db_structure = modulestore().db_connection.get_structure( db_structure = modulestore().db_connection.get_structure(
...@@ -1076,11 +1076,11 @@ class TestInheritance(SplitModuleTest): ...@@ -1076,11 +1076,11 @@ class TestInheritance(SplitModuleTest):
""" """
# Note, not testing value where defined (course) b/c there's no # Note, not testing value where defined (course) b/c there's no
# defined accessor for it on CourseDescriptor. # defined accessor for it on CourseDescriptor.
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem3_2", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="problem3_2", branch='draft')
node = modulestore().get_item(locator) node = modulestore().get_item(locator)
# inherited # inherited
self.assertEqual(node.graceperiod, datetime.timedelta(hours=2)) self.assertEqual(node.graceperiod, datetime.timedelta(hours=2))
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem1", branch='draft') locator = BlockUsageLocator(course_id="GreekHero", block_id="problem1", branch='draft')
node = modulestore().get_item(locator) node = modulestore().get_item(locator)
# overridden # overridden
self.assertEqual(node.graceperiod, datetime.timedelta(hours=4)) self.assertEqual(node.graceperiod, datetime.timedelta(hours=4))
...@@ -1117,24 +1117,24 @@ class TestPublish(SplitModuleTest): ...@@ -1117,24 +1117,24 @@ class TestPublish(SplitModuleTest):
expected.remove("chapter1") expected.remove("chapter1")
# check that it's not in published course # check that it's not in published course
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
modulestore().get_item(self._usage(dest_course, new_module.location.usage_id)) modulestore().get_item(self._usage(dest_course, new_module.location.block_id))
# publish it # publish it
modulestore().xblock_publish(self.user, source_course, dest_course, [new_module.location.usage_id], None) modulestore().xblock_publish(self.user, source_course, dest_course, [new_module.location.block_id], None)
expected.append(new_module.location.usage_id) expected.append(new_module.location.block_id)
# check that it is in the published course and that its parent is the chapter # check that it is in the published course and that its parent is the chapter
pub_module = modulestore().get_item(self._usage(dest_course, new_module.location.usage_id)) pub_module = modulestore().get_item(self._usage(dest_course, new_module.location.block_id))
self.assertEqual( self.assertEqual(
modulestore().get_parent_locations(pub_module.location)[0].usage_id, "chapter1" modulestore().get_parent_locations(pub_module.location)[0].block_id, "chapter1"
) )
# ensure intentionally orphaned blocks work (e.g., course_info) # ensure intentionally orphaned blocks work (e.g., course_info)
new_module = modulestore().create_item( new_module = modulestore().create_item(
source_course, "course_info", self.user, usage_id="handouts" source_course, "course_info", self.user, block_id="handouts"
) )
# publish it # publish it
modulestore().xblock_publish(self.user, source_course, dest_course, [new_module.location.usage_id], None) modulestore().xblock_publish(self.user, source_course, dest_course, [new_module.location.block_id], None)
expected.append(new_module.location.usage_id) expected.append(new_module.location.block_id)
# check that it is in the published course (no error means it worked) # check that it is in the published course (no error means it worked)
pub_module = modulestore().get_item(self._usage(dest_course, new_module.location.usage_id)) pub_module = modulestore().get_item(self._usage(dest_course, new_module.location.block_id))
self._check_course( self._check_course(
source_course, dest_course, expected, ["chapter2", "chapter3", "problem1", "problem3_2"] source_course, dest_course, expected, ["chapter2", "chapter3", "problem1", "problem3_2"]
) )
...@@ -1200,7 +1200,7 @@ class TestPublish(SplitModuleTest): ...@@ -1200,7 +1200,7 @@ class TestPublish(SplitModuleTest):
""" """
Generate a BlockUsageLocator for the combo of the course location and block id Generate a BlockUsageLocator for the combo of the course location and block id
""" """
return BlockUsageLocator(course_id=course_loc.course_id, branch=course_loc.branch, usage_id=block_id) return BlockUsageLocator(course_id=course_loc.course_id, branch=course_loc.branch, block_id=block_id)
def _compare_children(self, source_children, dest_children, unexpected): def _compare_children(self, source_children, dest_children, unexpected):
""" """
......
...@@ -168,7 +168,7 @@ class XModuleMixin(XBlockMixin): ...@@ -168,7 +168,7 @@ class XModuleMixin(XBlockMixin):
if isinstance(self.location, Location): if isinstance(self.location, Location):
return self.location.name return self.location.name
elif isinstance(self.location, BlockUsageLocator): elif isinstance(self.location, BlockUsageLocator):
return self.location.usage_id return self.location.block_id
else: else:
raise InsufficientSpecificationError() raise InsufficientSpecificationError()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment