Commit b80aad23 by Don Mitchell

Merge pull request #528 from edx/dhm/rename_revision

Rename CourseLocator.revision to branch
parents 59c367b8 68e1bcf4
......@@ -127,7 +127,7 @@ class TemplateTests(unittest.TestCase):
persistent_factories.ItemFactory.create(display_name='chapter 1',
parent_location=test_course.location)
id_locator = CourseLocator(course_id=test_course.location.course_id, revision='draft')
id_locator = CourseLocator(course_id=test_course.location.course_id, branch='draft')
guid_locator = CourseLocator(version_guid=test_course.location.version_guid)
# verify it can be retireved by id
self.assertIsInstance(modulestore('split').get_course(id_locator), CourseDescriptor)
......
......@@ -45,7 +45,7 @@ class Locator(object):
def __repr__(self):
'''
repr(self) returns something like this: CourseLocator("edu.mit.eecs.6002x")
repr(self) returns something like this: CourseLocator("mit.eecs.6002x")
'''
classname = self.__class__.__name__
if classname.find('.') != -1:
......@@ -54,13 +54,13 @@ class Locator(object):
def __str__(self):
'''
str(self) returns something like this: "edu.mit.eecs.6002x"
str(self) returns something like this: "mit.eecs.6002x"
'''
return unicode(self).encode('utf8')
def __unicode__(self):
'''
unicode(self) returns something like this: "edu.mit.eecs.6002x"
unicode(self) returns something like this: "mit.eecs.6002x"
'''
return self.url()
......@@ -89,15 +89,15 @@ class CourseLocator(Locator):
"""
Examples of valid CourseLocator specifications:
CourseLocator(version_guid=ObjectId('519665f6223ebd6980884f2b'))
CourseLocator(course_id='edu.mit.eecs.6002x')
CourseLocator(course_id='edu.mit.eecs.6002x;published')
CourseLocator(course_id='edu.mit.eecs.6002x', revision='published')
CourseLocator(course_id='mit.eecs.6002x')
CourseLocator(course_id='mit.eecs.6002x;published')
CourseLocator(course_id='mit.eecs.6002x', branch='published')
CourseLocator(url='edx://@519665f6223ebd6980884f2b')
CourseLocator(url='edx://edu.mit.eecs.6002x')
CourseLocator(url='edx://edu.mit.eecs.6002x;published')
CourseLocator(url='edx://mit.eecs.6002x')
CourseLocator(url='edx://mit.eecs.6002x;published')
Should have at lease a specific course_id (id for the course as if it were a project w/
versions) with optional 'revision' (must be 'draft', 'published', or None),
versions) with optional 'branch',
or version_guid (which points to a specific version). Can contain both in which case
the persistence layer may raise exceptions if the given version != the current such version
of the course.
......@@ -106,7 +106,7 @@ class CourseLocator(Locator):
# Default values
version_guid = None
course_id = None
revision = None
branch = None
def __unicode__(self):
"""
......@@ -114,8 +114,8 @@ class CourseLocator(Locator):
"""
if self.course_id:
result = self.course_id
if self.revision:
result += ';' + self.revision
if self.branch:
result += ';' + self.branch
return result
elif self.version_guid:
return '@' + str(self.version_guid)
......@@ -131,7 +131,7 @@ class CourseLocator(Locator):
# -- unused args which are used via inspect
# pylint: disable= W0613
def validate_args(self, url, version_guid, course_id, revision):
def validate_args(self, url, version_guid, course_id, branch):
"""
Validate provided arguments.
"""
......@@ -144,12 +144,12 @@ class CourseLocator(Locator):
def is_fully_specified(self):
"""
Returns True if either version_guid is specified, or course_id+revision
Returns True if either version_guid is specified, or course_id+branch
are specified.
This should always return True, since this should be validated in the constructor.
"""
return self.version_guid is not None \
or (self.course_id is not None and self.revision is not None)
or (self.course_id is not None and self.branch is not None)
def set_course_id(self, new):
"""
......@@ -158,12 +158,12 @@ class CourseLocator(Locator):
"""
self.set_property('course_id', new)
def set_revision(self, new):
def set_branch(self, new):
"""
Initialize revision to new value.
If revision has already been initialized to a different value, raise an exception.
Initialize branch to new value.
If branch has already been initialized to a different value, raise an exception.
"""
self.set_property('revision', new)
self.set_property('branch', new)
def set_version_guid(self, new):
"""
......@@ -181,29 +181,29 @@ class CourseLocator(Locator):
"""
return CourseLocator(course_id=self.course_id,
version_guid=self.version_guid,
revision=self.revision)
branch=self.branch)
def __init__(self, url=None, version_guid=None, course_id=None, revision=None):
def __init__(self, url=None, version_guid=None, course_id=None, branch=None):
"""
Construct a CourseLocator
Caller may provide url (but no other parameters).
Caller may provide version_guid (but no other parameters).
Caller may provide course_id (optionally provide revision).
Caller may provide course_id (optionally provide branch).
Resulting CourseLocator will have either a version_guid property
or a course_id (with optional revision) property, or both.
or a course_id (with optional branch) property, or both.
version_guid must be an instance of bson.objectid.ObjectId or None
url, course_id, and revision must be strings or None
url, course_id, and branch must be strings or None
"""
self.validate_args(url, version_guid, course_id, revision)
self.validate_args(url, version_guid, course_id, branch)
if url:
self.init_from_url(url)
if version_guid:
self.init_from_version_guid(version_guid)
if course_id or revision:
self.init_from_course_id(course_id, revision)
if course_id or branch:
self.init_from_course_id(course_id, branch)
assert self.version_guid or self.course_id, \
"Either version_guid or course_id should be set."
......@@ -223,7 +223,7 @@ class CourseLocator(Locator):
def init_from_url(self, url):
"""
url must be a string beginning with 'edx://' and containing
either a valid version_guid or course_id (with optional revision)
either a valid version_guid or course_id (with optional branch)
If a block ('#HW3') is present, it is ignored.
"""
if isinstance(url, Locator):
......@@ -237,7 +237,7 @@ class CourseLocator(Locator):
self.set_version_guid(self.as_object_id(new_guid))
else:
self.set_course_id(parse['id'])
self.set_revision(parse['revision'])
self.set_branch(parse['branch'])
def init_from_version_guid(self, version_guid):
"""
......@@ -251,14 +251,14 @@ class CourseLocator(Locator):
'%s is not an instance of ObjectId' % version_guid
self.set_version_guid(version_guid)
def init_from_course_id(self, course_id, explicit_revision=None):
def init_from_course_id(self, course_id, explicit_branch=None):
"""
Course_id is a string like 'edu.mit.eecs.6002x' or 'edu.mit.eecs.6002x;published'.
Course_id is a string like 'mit.eecs.6002x' or 'mit.eecs.6002x;published'.
Revision (optional) is a string like 'published'.
It may be provided explicitly (explicit_revision) or embedded into course_id.
If revision is part of course_id ("...;published"), parse it out separately.
If revision is provided both ways, that's ok as long as they are the same value.
It may be provided explicitly (explicit_branch) or embedded into course_id.
If branch is part of course_id ("...;published"), parse it out separately.
If branch is provided both ways, that's ok as long as they are the same value.
If a block ('#HW3') is a part of course_id, it is ignored.
......@@ -272,11 +272,11 @@ class CourseLocator(Locator):
parse = parse_course_id(course_id)
assert parse, 'Could not parse "%s" as a course_id' % course_id
self.set_course_id(parse['id'])
rev = parse['revision']
rev = parse['branch']
if rev:
self.set_revision(rev)
if explicit_revision:
self.set_revision(explicit_revision)
self.set_branch(rev)
if explicit_branch:
self.set_branch(explicit_branch)
def version(self):
"""
......@@ -305,37 +305,37 @@ class BlockUsageLocator(CourseLocator):
the defined element in the course. Courses can be a version of an offering, the
current draft head, or the current production version.
Locators can contain both a version and a course_id w/ revision. The split mongo functions
may raise errors if these conflict w/ the current db state (i.e., the course's revision !=
Locators can contain both a version and a course_id w/ branch. The split mongo functions
may raise errors if these conflict w/ the current db state (i.e., the course's branch !=
the version_guid)
Locations can express as urls as well as dictionaries. They consist of
course_identifier: course_guid | version_guid
block : guid
revision : 'draft' | 'published' (optional)
branch : string
"""
# Default value
usage_id = None
def __init__(self, url=None, version_guid=None, course_id=None,
revision=None, usage_id=None):
branch=None, usage_id=None):
"""
Construct a BlockUsageLocator
Caller may provide url, version_guid, or course_id, and optionally provide revision.
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 url or course_id. If omitted, the locator is created but it
has not yet been initialized.
Resulting BlockUsageLocator will have a usage_id property.
It will have either a version_guid property or a course_id (with optional revision) 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
url, course_id, revision, and usage_id must be strings or None
url, course_id, branch, and usage_id must be strings or None
"""
self.validate_args(url, version_guid, course_id, revision)
self.validate_args(url, version_guid, course_id, branch)
if url:
self.init_block_ref_from_url(url)
if course_id:
......@@ -346,7 +346,7 @@ class BlockUsageLocator(CourseLocator):
url=url,
version_guid=version_guid,
course_id=course_id,
revision=revision)
branch=branch)
def is_initialized(self):
"""
......@@ -366,11 +366,11 @@ class BlockUsageLocator(CourseLocator):
"""
if self.course_id and self.version_guid:
return BlockUsageLocator(version_guid=self.version_guid,
revision=self.revision,
branch=self.branch,
usage_id=self.usage_id)
else:
return BlockUsageLocator(course_id=self.course_id,
revision=self.revision,
branch=self.branch,
usage_id=self.usage_id)
def set_usage_id(self, new):
......
......@@ -20,7 +20,7 @@ def parse_url(string):
with key 'version_guid' and the value,
If it can be parsed as a course_id, returns a dict
with keys 'id' and 'revision' (value of 'revision' may be None),
with keys 'id' and 'branch' (value of 'branch' may be None),
"""
match = URL_RE.match(string)
......@@ -69,14 +69,14 @@ def parse_guid(string):
return None
COURSE_ID_RE = re.compile(r'^(?P<id>(\w+)(\.\w+\w*)*)(;(?P<revision>\w+))?(#(?P<block>\w+))?$', re.IGNORECASE)
COURSE_ID_RE = re.compile(r'^(?P<id>(\w+)(\.\w+\w*)*)(;(?P<branch>\w+))?(#(?P<block>\w+))?$', re.IGNORECASE)
def parse_course_id(string):
r"""
A course_id has a main id component.
There may also be an optional revision (;published or ;draft).
There may also be an optional branch (;published or ;draft).
There may also be an optional block (#HW3 or #Quiz2).
Examples of valid course_ids:
......@@ -89,11 +89,11 @@ def parse_course_id(string):
Syntax:
course_id = main_id [; revision] [# block]
course_id = main_id [; branch] [# block]
main_id = name [. name]*
revision = name
branch = name
block = name
......@@ -104,8 +104,8 @@ def parse_course_id(string):
and the underscore. (see definition of \w in python regular expressions,
at http://docs.python.org/dev/library/re.html)
If string is a course_id, returns a dict with keys 'id', 'revision', and 'block'.
Revision is optional: if missing returned_dict['revision'] is None.
If string is a course_id, returns a dict with keys 'id', 'branch', and 'block'.
Revision is optional: if missing returned_dict['branch'] is None.
Block is optional: if missing returned_dict['block'] is None.
Else returns None.
"""
......
......@@ -81,7 +81,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
version_guid=course_entry_override['_id'],
usage_id=usage_id,
course_id=course_entry_override.get('course_id'),
revision=course_entry_override.get('revision')
branch=course_entry_override.get('branch')
)
kvs = SplitMongoKVS(
......
......@@ -186,8 +186,8 @@ class SplitMongoModuleStore(ModuleStoreBase):
return the CourseDescriptor! It returns the actual db json from
structures.
Semantics: if course_id and revision given, then it will get that revision. If
also give a version_guid, it will see if the current head of that revision == that guid. If not
Semantics: if course_id and branch given, then it will get that branch. If
also give a version_guid, it will see if the current head of that branch == that guid. If not
it raises VersionConflictError (the version now differs from what it was when you got your
reference)
......@@ -198,19 +198,19 @@ class SplitMongoModuleStore(ModuleStoreBase):
if not course_locator.is_fully_specified():
raise InsufficientSpecificationError('Not fully specified: %s' % course_locator)
if course_locator.course_id is not None and course_locator.revision is not None:
if course_locator.course_id is not None and course_locator.branch is not None:
# use the course_id
index = self.course_index.find_one({'_id': course_locator.course_id})
if index is None:
raise ItemNotFoundError(course_locator)
if course_locator.revision not in index['versions']:
if course_locator.branch not in index['versions']:
raise ItemNotFoundError(course_locator)
version_guid = index['versions'][course_locator.revision]
version_guid = index['versions'][course_locator.branch]
if course_locator.version_guid is not None and version_guid != course_locator.version_guid:
# This may be a bit too touchy but it's hard to infer intent
raise VersionConflictError(course_locator, CourseLocator(course_locator, version_guid=version_guid))
else:
# TODO should this raise an exception if revision was provided?
# TODO should this raise an exception if branch was provided?
version_guid = course_locator.version_guid
# cast string to ObjectId if necessary
......@@ -223,29 +223,29 @@ class SplitMongoModuleStore(ModuleStoreBase):
if course_locator.course_id:
entry['course_id'] = course_locator.course_id
entry['revision'] = course_locator.revision
entry['branch'] = course_locator.branch
return entry
def get_courses(self, revision, qualifiers=None):
def get_courses(self, branch, qualifiers=None):
'''
Returns a list of course descriptors matching any given qualifiers.
qualifiers should be a dict of keywords matching the db fields or any
legal query for mongo to use against the active_versions collection.
Note, this is to find the current head of the named revision type
Note, this is to find the current head of the named branch type
(e.g., 'draft'). To get specific versions via guid use get_course.
'''
if qualifiers is None:
qualifiers = {}
qualifiers.update({"versions.{}".format(revision): {"$exists": True}})
qualifiers.update({"versions.{}".format(branch): {"$exists": True}})
matching = self.course_index.find(qualifiers)
# collect ids and then query for those
version_guids = []
id_version_map = {}
for course_entry in matching:
version_guid = course_entry['versions'][revision]
version_guid = course_entry['versions'][branch]
version_guids.append(version_guid)
id_version_map[version_guid] = course_entry['_id']
......@@ -667,7 +667,7 @@ class SplitMongoModuleStore(ModuleStoreBase):
# update the index entry if appropriate
if index_entry is not None:
self._update_head(index_entry, course_or_parent_locator.revision, new_id)
self._update_head(index_entry, course_or_parent_locator.branch, new_id)
course_parent = course_or_parent_locator.as_course_locator()
else:
course_parent = None
......@@ -786,7 +786,7 @@ class SplitMongoModuleStore(ModuleStoreBase):
'edited_on': datetime.datetime.utcnow(),
'versions': versions_dict}
new_id = self.course_index.insert(index_entry)
return self.get_course(CourseLocator(course_id=new_id, revision=master_version))
return self.get_course(CourseLocator(course_id=new_id, branch=master_version))
def update_item(self, descriptor, user_id, force=False):
"""
......@@ -835,7 +835,7 @@ class SplitMongoModuleStore(ModuleStoreBase):
# update the index entry if appropriate
if index_entry is not None:
self._update_head(index_entry, descriptor.location.revision, new_id)
self._update_head(index_entry, descriptor.location.branch, new_id)
# fetch and return the new item--fetching is unnecessary but a good qc step
return self.get_item(BlockUsageLocator(descriptor.location, version_guid=new_id))
......@@ -876,7 +876,7 @@ class SplitMongoModuleStore(ModuleStoreBase):
# update the index entry if appropriate
if index_entry is not None:
self._update_head(index_entry, xblock.location.revision, new_id)
self._update_head(index_entry, xblock.location.branch, new_id)
# fetch and return the new item--fetching is unnecessary but a good qc step
return self.get_item(BlockUsageLocator(xblock.location, version_guid=new_id))
......@@ -1028,9 +1028,9 @@ class SplitMongoModuleStore(ModuleStoreBase):
# update the index entry if appropriate
if index_entry is not None:
self._update_head(index_entry, usage_locator.revision, new_id)
self._update_head(index_entry, usage_locator.branch, new_id)
result.course_id = usage_locator.course_id
result.revision = usage_locator.revision
result.branch = usage_locator.branch
return result
......@@ -1186,19 +1186,19 @@ class SplitMongoModuleStore(ModuleStoreBase):
:param locator:
"""
if locator.course_id is None or locator.revision is None:
if locator.course_id is None or locator.branch is None:
return None
else:
index_entry = self.course_index.find_one({'_id': locator.course_id})
if (locator.version_guid is not None
and index_entry['versions'][locator.revision] != locator.version_guid
and index_entry['versions'][locator.branch] != locator.version_guid
and not force):
raise VersionConflictError(
locator,
CourseLocator(
course_id=index_entry['_id'],
version_guid=index_entry['versions'][locator.revision],
revision=locator.revision))
version_guid=index_entry['versions'][locator.branch],
branch=locator.branch))
else:
return index_entry
......@@ -1227,9 +1227,9 @@ class SplitMongoModuleStore(ModuleStoreBase):
return False
def _update_head(self, index_entry, revision, new_id):
def _update_head(self, index_entry, branch, new_id):
"""
Update the active index for the given course's revision to point to new_id
Update the active index for the given course's branch to point to new_id
:param index_entry:
:param course_locator:
......@@ -1237,4 +1237,4 @@ class SplitMongoModuleStore(ModuleStoreBase):
"""
self.course_index.update(
{"_id": index_entry["_id"]},
{"$set": {"versions.{}".format(revision): new_id}})
{"$set": {"versions.{}".format(branch): new_id}})
......@@ -4,12 +4,10 @@ Created on Mar 14, 2013
@author: dmitchell
'''
from unittest import TestCase
from nose.plugins.skip import SkipTest
from bson.objectid import ObjectId
from xmodule.modulestore.locator import Locator, CourseLocator, BlockUsageLocator
from xmodule.modulestore.exceptions import InvalidLocationError, \
InsufficientSpecificationError, OverSpecificationError
from xmodule.modulestore.exceptions import InsufficientSpecificationError, OverSpecificationError
class LocatorTest(TestCase):
......@@ -21,30 +19,30 @@ class LocatorTest(TestCase):
self.assertRaises(
OverSpecificationError,
CourseLocator,
url='edx://edu.mit.eecs.6002x',
course_id='edu.harvard.history',
revision='published',
url='edx://mit.eecs.6002x',
course_id='harvard.history',
branch='published',
version_guid=ObjectId())
self.assertRaises(
OverSpecificationError,
CourseLocator,
url='edx://edu.mit.eecs.6002x',
course_id='edu.harvard.history',
url='edx://mit.eecs.6002x',
course_id='harvard.history',
version_guid=ObjectId())
self.assertRaises(
OverSpecificationError,
CourseLocator,
url='edx://edu.mit.eecs.6002x;published',
revision='draft')
url='edx://mit.eecs.6002x;published',
branch='draft')
self.assertRaises(
OverSpecificationError,
CourseLocator,
course_id='edu.mit.eecs.6002x;published',
revision='draft')
course_id='mit.eecs.6002x;published',
branch='draft')
def test_course_constructor_underspecified(self):
self.assertRaises(InsufficientSpecificationError, CourseLocator)
self.assertRaises(InsufficientSpecificationError, CourseLocator, revision='published')
self.assertRaises(InsufficientSpecificationError, CourseLocator, branch='published')
def test_course_constructor_bad_version_guid(self):
self.assertRaises(ValueError, CourseLocator, version_guid="012345")
......@@ -73,467 +71,128 @@ class LocatorTest(TestCase):
"""
Test all sorts of badly-formed course_ids (and urls with those course_ids)
"""
for bad_id in ('edu.mit.',
' edu.mit.eecs',
'edu.mit.eecs ',
'@edu.mit.eecs',
'#edu.mit.eecs',
'edu.mit.ee cs',
'edu.mit.ee,cs',
'edu.mit.ee/cs',
'edu.mit.ee$cs',
'edu.mit.ee&cs',
'edu.mit.ee()cs',
for bad_id in ('mit.',
' mit.eecs',
'mit.eecs ',
'@mit.eecs',
'#mit.eecs',
'mit.ee cs',
'mit.ee,cs',
'mit.ee/cs',
'mit.ee$cs',
'mit.ee&cs',
'mit.ee()cs',
';this',
'edu.mit.eecs;',
'edu.mit.eecs;this;that',
'edu.mit.eecs;this;',
'edu.mit.eecs;this ',
'edu.mit.eecs;th%is ',
'mit.eecs;',
'mit.eecs;this;that',
'mit.eecs;this;',
'mit.eecs;this ',
'mit.eecs;th%is ',
):
self.assertRaises(AssertionError, CourseLocator, course_id=bad_id)
self.assertRaises(AssertionError, CourseLocator, url='edx://' + bad_id)
def test_course_constructor_bad_url(self):
for bad_url in ('edx://',
'edx:/edu.mit.eecs',
'http://edu.mit.eecs',
'edu.mit.eecs',
'edx//edu.mit.eecs'):
'edx:/mit.eecs',
'http://mit.eecs',
'mit.eecs',
'edx//mit.eecs'):
self.assertRaises(AssertionError, CourseLocator, url=bad_url)
def test_course_constructor_redundant_001(self):
testurn = 'edu.mit.eecs.6002x'
testurn = 'mit.eecs.6002x'
testobj = CourseLocator(course_id=testurn, url='edx://' + testurn)
self.check_course_locn_fields(testobj, 'course_id', course_id=testurn)
def test_course_constructor_redundant_002(self):
testurn = 'edu.mit.eecs.6002x;published'
expected_urn = 'edu.mit.eecs.6002x'
testurn = 'mit.eecs.6002x;published'
expected_urn = 'mit.eecs.6002x'
expected_rev = 'published'
testobj = CourseLocator(course_id=testurn, url='edx://' + testurn)
self.check_course_locn_fields(testobj, 'course_id',
course_id=expected_urn,
revision=expected_rev)
branch=expected_rev)
def test_course_constructor_course_id_no_revision(self):
testurn = 'edu.mit.eecs.6002x'
def test_course_constructor_course_id_no_branch(self):
testurn = 'mit.eecs.6002x'
testobj = CourseLocator(course_id=testurn)
self.check_course_locn_fields(testobj, 'course_id', course_id=testurn)
self.assertEqual(testobj.course_id, testurn)
self.assertEqual(str(testobj), testurn)
self.assertEqual(testobj.url(), 'edx://' + testurn)
def test_course_constructor_course_id_with_revision(self):
testurn = 'edu.mit.eecs.6002x;published'
expected_id = 'edu.mit.eecs.6002x'
expected_revision = 'published'
def test_course_constructor_course_id_with_branch(self):
testurn = 'mit.eecs.6002x;published'
expected_id = 'mit.eecs.6002x'
expected_branch = 'published'
testobj = CourseLocator(course_id=testurn)
self.check_course_locn_fields(testobj, 'course_id with revision',
self.check_course_locn_fields(testobj, 'course_id with branch',
course_id=expected_id,
revision=expected_revision,
branch=expected_branch,
)
self.assertEqual(testobj.course_id, expected_id)
self.assertEqual(testobj.revision, expected_revision)
self.assertEqual(testobj.branch, expected_branch)
self.assertEqual(str(testobj), testurn)
self.assertEqual(testobj.url(), 'edx://' + testurn)
def test_course_constructor_course_id_separate_revision(self):
test_id = 'edu.mit.eecs.6002x'
test_revision = 'published'
expected_urn = 'edu.mit.eecs.6002x;published'
testobj = CourseLocator(course_id=test_id, revision=test_revision)
self.check_course_locn_fields(testobj, 'course_id with separate revision',
def test_course_constructor_course_id_separate_branch(self):
test_id = 'mit.eecs.6002x'
test_branch = 'published'
expected_urn = 'mit.eecs.6002x;published'
testobj = CourseLocator(course_id=test_id, branch=test_branch)
self.check_course_locn_fields(testobj, 'course_id with separate branch',
course_id=test_id,
revision=test_revision,
branch=test_branch,
)
self.assertEqual(testobj.course_id, test_id)
self.assertEqual(testobj.revision, test_revision)
self.assertEqual(testobj.branch, test_branch)
self.assertEqual(str(testobj), expected_urn)
self.assertEqual(testobj.url(), 'edx://' + expected_urn)
def test_course_constructor_course_id_repeated_revision(self):
def test_course_constructor_course_id_repeated_branch(self):
"""
The same revision appears in the course_id and the revision field.
The same branch appears in the course_id and the branch field.
"""
test_id = 'edu.mit.eecs.6002x;published'
test_revision = 'published'
expected_id = 'edu.mit.eecs.6002x'
expected_urn = 'edu.mit.eecs.6002x;published'
testobj = CourseLocator(course_id=test_id, revision=test_revision)
self.check_course_locn_fields(testobj, 'course_id with repeated revision',
test_id = 'mit.eecs.6002x;published'
test_branch = 'published'
expected_id = 'mit.eecs.6002x'
expected_urn = 'mit.eecs.6002x;published'
testobj = CourseLocator(course_id=test_id, branch=test_branch)
self.check_course_locn_fields(testobj, 'course_id with repeated branch',
course_id=expected_id,
revision=test_revision,
branch=test_branch,
)
self.assertEqual(testobj.course_id, expected_id)
self.assertEqual(testobj.revision, test_revision)
self.assertEqual(testobj.branch, test_branch)
self.assertEqual(str(testobj), expected_urn)
self.assertEqual(testobj.url(), 'edx://' + expected_urn)
def test_block_constructor(self):
testurn = 'edu.mit.eecs.6002x;published#HW3'
expected_id = 'edu.mit.eecs.6002x'
expected_revision = 'published'
testurn = 'mit.eecs.6002x;published#HW3'
expected_id = 'mit.eecs.6002x'
expected_branch = 'published'
expected_block_ref = 'HW3'
testobj = BlockUsageLocator(course_id=testurn)
self.check_block_locn_fields(testobj, 'test_block constructor',
course_id=expected_id,
revision=expected_revision,
branch=expected_branch,
block=expected_block_ref)
self.assertEqual(str(testobj), testurn)
self.assertEqual(testobj.url(), 'edx://' + testurn)
# ------------------------------------------------------------
# Disabled tests
def test_course_urls(self):
'''
Test constructor and property accessors.
'''
raise SkipTest()
self.assertRaises(TypeError, CourseLocator, 'empty constructor')
# url inits
testurn = 'edx://org/course/category/name'
self.assertRaises(InvalidLocationError, CourseLocator, url=testurn)
testurn = 'unknown/versionid/blockid'
self.assertRaises(InvalidLocationError, CourseLocator, url=testurn)
testurn = 'cvx/versionid'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, 'versionid')
self.assertEqual(testobj, CourseLocator(testobj),
'initialization from another instance')
testurn = 'cvx/versionid/'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, 'versionid')
testurn = 'cvx/versionid/blockid'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, 'versionid')
testurn = 'cvx/versionid/blockid/extraneousstuff?including=args'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, 'versionid')
testurn = 'cvx://versionid/blockid'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, 'versionid')
testurn = 'crx/courseid/blockid'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, course_id='courseid')
testurn = 'crx/courseid@revision/blockid'
testobj = CourseLocator(testurn)
self.check_course_locn_fields(testobj, testurn, course_id='courseid',
revision='revision')
self.assertEqual(testobj, CourseLocator(testobj),
'run initialization from another instance')
def test_course_keyword_setters(self):
raise SkipTest()
# arg list inits
testobj = CourseLocator(version_guid='versionid')
self.check_course_locn_fields(testobj, 'versionid arg', 'versionid')
testobj = CourseLocator(course_id='courseid')
self.check_course_locn_fields(testobj, 'courseid arg',
course_id='courseid')
testobj = CourseLocator(course_id='courseid', revision='rev')
self.check_course_locn_fields(testobj, 'rev arg',
course_id='courseid',
revision='rev')
# ignores garbage
testobj = CourseLocator(course_id='courseid', revision='rev',
potato='spud')
self.check_course_locn_fields(testobj, 'extra keyword arg',
course_id='courseid',
revision='rev')
# url w/ keyword override
testurn = 'crx/courseid@revision/blockid'
testobj = CourseLocator(testurn, revision='rev')
self.check_course_locn_fields(testobj, 'rev override',
course_id='courseid',
revision='rev')
def test_course_dict(self):
raise SkipTest()
# dict init w/ keyword overwrites
testobj = CourseLocator({"version_guid": 'versionid'})
self.check_course_locn_fields(testobj, 'versionid dict', 'versionid')
testobj = CourseLocator({"course_id": 'courseid'})
self.check_course_locn_fields(testobj, 'courseid dict',
course_id='courseid')
testobj = CourseLocator({"course_id": 'courseid', "revision": 'rev'})
self.check_course_locn_fields(testobj, 'rev dict',
course_id='courseid',
revision='rev')
# ignores garbage
testobj = CourseLocator({"course_id": 'courseid', "revision": 'rev',
"potato": 'spud'})
self.check_course_locn_fields(testobj, 'extra keyword dict',
course_id='courseid',
revision='rev')
testobj = CourseLocator({"course_id": 'courseid', "revision": 'rev'},
revision='alt')
self.check_course_locn_fields(testobj, 'rev dict',
course_id='courseid',
revision='alt')
# urn init w/ dict & keyword overwrites
testobj = CourseLocator('crx/notcourse@notthis',
{"course_id": 'courseid'},
revision='alt')
self.check_course_locn_fields(testobj, 'rev dict',
course_id='courseid',
revision='alt')
def test_url(self):
'''
Ensure CourseLocator generates expected urls.
'''
raise SkipTest()
testobj = CourseLocator(version_guid='versionid')
self.assertEqual(testobj.url(), 'cvx/versionid', 'versionid')
self.assertEqual(testobj, CourseLocator(testobj.url()),
'versionid conversion through url')
testobj = CourseLocator(course_id='courseid')
self.assertEqual(testobj.url(), 'crx/courseid', 'courseid')
self.assertEqual(testobj, CourseLocator(testobj.url()),
'courseid conversion through url')
testobj = CourseLocator(course_id='courseid', revision='rev')
self.assertEqual(testobj.url(), 'crx/courseid@rev', 'rev')
self.assertEqual(testobj, CourseLocator(testobj.url()),
'rev conversion through url')
def test_html(self):
'''
Ensure CourseLocator generates expected urls.
'''
raise SkipTest()
testobj = CourseLocator(version_guid='versionid')
self.assertEqual(testobj.html_id(), 'cvx/versionid', 'versionid')
self.assertEqual(testobj, CourseLocator(testobj.html_id()),
'versionid conversion through html_id')
testobj = CourseLocator(course_id='courseid')
self.assertEqual(testobj.html_id(), 'crx/courseid', 'courseid')
self.assertEqual(testobj, CourseLocator(testobj.html_id()),
'courseid conversion through html_id')
testobj = CourseLocator(course_id='courseid', revision='rev')
self.assertEqual(testobj.html_id(), 'crx/courseid%40rev', 'rev')
self.assertEqual(testobj, CourseLocator(testobj.html_id()),
'rev conversion through html_id')
def test_block_locator(self):
'''
Test constructor and property accessors.
'''
raise SkipTest()
self.assertIsInstance(BlockUsageLocator(), BlockUsageLocator,
'empty constructor')
# url inits
testurn = 'edx://org/course/category/name'
self.assertRaises(InvalidLocationError, BlockUsageLocator, testurn)
testurn = 'unknown/versionid/blockid'
self.assertRaises(InvalidLocationError, BlockUsageLocator, testurn)
testurn = 'cvx/versionid'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, 'versionid')
self.assertEqual(testobj, BlockUsageLocator(testobj),
'initialization from another instance')
testurn = 'cvx/versionid/'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, 'versionid')
testurn = 'cvx/versionid/blockid'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, 'versionid',
block='blockid')
testurn = 'cvx/versionid/blockid/extraneousstuff?including=args'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, 'versionid',
block='blockid')
testurn = 'cvx://versionid/blockid'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, 'versionid',
block='blockid')
testurn = 'crx/courseid/blockid'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, course_id='courseid',
block='blockid')
testurn = 'crx/courseid@revision/blockid'
testobj = BlockUsageLocator(testurn)
self.check_block_locn_fields(testobj, testurn, course_id='courseid',
revision='revision', block='blockid')
self.assertEqual(testobj, BlockUsageLocator(testobj),
'run initialization from another instance')
def test_block_keyword_init(self):
# arg list inits
raise SkipTest()
testobj = BlockUsageLocator(version_guid='versionid')
self.check_block_locn_fields(testobj, 'versionid arg', 'versionid')
testobj = BlockUsageLocator(version_guid='versionid', usage_id='myblock')
self.check_block_locn_fields(testobj, 'versionid arg', 'versionid',
block='myblock')
testobj = BlockUsageLocator(course_id='courseid')
self.check_block_locn_fields(testobj, 'courseid arg',
course_id='courseid')
testobj = BlockUsageLocator(course_id='courseid', revision='rev')
self.check_block_locn_fields(testobj, 'rev arg',
course_id='courseid',
revision='rev')
# ignores garbage
testobj = BlockUsageLocator(course_id='courseid', revision='rev',
usage_id='this_block', potato='spud')
self.check_block_locn_fields(testobj, 'extra keyword arg',
course_id='courseid', block='this_block', revision='rev')
# url w/ keyword override
testurn = 'crx/courseid@revision/blockid'
testobj = BlockUsageLocator(testurn, revision='rev')
self.check_block_locn_fields(testobj, 'rev override',
course_id='courseid', block='blockid',
revision='rev')
def test_block_keywords(self):
# dict init w/ keyword overwrites
raise SkipTest()
testobj = BlockUsageLocator({"version_guid": 'versionid',
'usage_id': 'dictblock'})
self.check_block_locn_fields(testobj, 'versionid dict', 'versionid',
block='dictblock')
testobj = BlockUsageLocator({"course_id": 'courseid',
'usage_id': 'dictblock'})
self.check_block_locn_fields(testobj, 'courseid dict',
block='dictblock', course_id='courseid')
testobj = BlockUsageLocator({"course_id": 'courseid', "revision": 'rev',
'usage_id': 'dictblock'})
self.check_block_locn_fields(testobj, 'rev dict',
course_id='courseid', block='dictblock',
revision='rev')
# ignores garbage
testobj = BlockUsageLocator({"course_id": 'courseid', "revision": 'rev',
'usage_id': 'dictblock', "potato": 'spud'})
self.check_block_locn_fields(testobj, 'extra keyword dict',
course_id='courseid', block='dictblock',
revision='rev')
testobj = BlockUsageLocator({"course_id": 'courseid', "revision": 'rev',
'usage_id': 'dictblock'}, revision='alt', usage_id='anotherblock')
self.check_block_locn_fields(testobj, 'rev dict',
course_id='courseid', block='anotherblock',
revision='alt')
# urn init w/ dict & keyword overwrites
testobj = BlockUsageLocator('crx/notcourse@notthis/northis',
{"course_id": 'courseid'}, revision='alt', usage_id='anotherblock')
self.check_block_locn_fields(testobj, 'rev dict',
course_id='courseid', block='anotherblock',
revision='alt')
def test_ensure_fully_specd(self):
'''
Test constructor and property accessors.
'''
raise SkipTest()
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, BlockUsageLocator())
# url inits
testurn = 'edx://org/course/category/name'
self.assertRaises(InvalidLocationError,
BlockUsageLocator.ensure_fully_specified, testurn)
testurn = 'unknown/versionid/blockid'
self.assertRaises(InvalidLocationError,
BlockUsageLocator.ensure_fully_specified, testurn)
testurn = 'cvx/versionid'
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, testurn)
testurn = 'cvx/versionid/'
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, testurn)
testurn = 'cvx/versionid/blockid'
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
testurn = 'cvx/versionid/blockid/extraneousstuff?including=args'
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
testurn = 'cvx://versionid/blockid'
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
testurn = 'crx/courseid/blockid'
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
testurn = 'crx/courseid@revision/blockid'
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
def test_ensure_fully_via_keyword(self):
# arg list inits
raise SkipTest()
testobj = BlockUsageLocator(version_guid='versionid')
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, testobj)
testurn = 'crx/courseid@revision/blockid'
testobj = BlockUsageLocator(version_guid='versionid', usage_id='myblock')
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
testobj = BlockUsageLocator(course_id='courseid')
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, testobj)
testobj = BlockUsageLocator(course_id='courseid', revision='rev')
self.assertRaises(InsufficientSpecificationError,
BlockUsageLocator.ensure_fully_specified, testobj)
testobj = BlockUsageLocator(course_id='courseid', revision='rev',
usage_id='this_block')
self.assertIsInstance(BlockUsageLocator.ensure_fully_specified(testurn),
BlockUsageLocator, testurn)
# ------------------------------------------------------------------
# Utilities
def check_course_locn_fields(self, testobj, msg, version_guid=None,
course_id=None, revision=None):
course_id=None, branch=None):
self.assertEqual(testobj.version_guid, version_guid, msg)
self.assertEqual(testobj.course_id, course_id, msg)
self.assertEqual(testobj.revision, revision, msg)
self.assertEqual(testobj.branch, branch, msg)
def check_block_locn_fields(self, testobj, msg, version_guid=None,
course_id=None, revision=None, block=None):
course_id=None, branch=None, block=None):
self.check_course_locn_fields(testobj, msg, version_guid, course_id,
revision)
branch)
self.assertEqual(testobj.usage_id, block)
......@@ -136,8 +136,8 @@ class SplitModuleCourseTests(SplitModuleTest):
self.assertEqual(str(course.previous_version), self.GUID_D1)
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.45})
def test_revision_requests(self):
# query w/ revision qualifier (both draft and published)
def test_branch_requests(self):
# query w/ branch qualifier (both draft and published)
courses_published = modulestore().get_courses('published')
self.assertEqual(len(courses_published), 1, len(courses_published))
course = self.findByIdInResult(courses_published, "head23456")
......@@ -189,7 +189,7 @@ class SplitModuleCourseTests(SplitModuleTest):
self.assertEqual(course.edited_by, "testassist@edx.org")
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.55})
locator = CourseLocator(course_id='GreekHero', revision='draft')
locator = CourseLocator(course_id='GreekHero', branch='draft')
course = modulestore().get_course(locator)
self.assertEqual(course.location.course_id, "GreekHero")
self.assertEqual(str(course.location.version_guid), self.GUID_D0)
......@@ -202,12 +202,12 @@ class SplitModuleCourseTests(SplitModuleTest):
self.assertEqual(course.edited_by, "testassist@edx.org")
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.45})
locator = CourseLocator(course_id='wonderful', revision='published')
locator = CourseLocator(course_id='wonderful', branch='published')
course = modulestore().get_course(locator)
self.assertEqual(course.location.course_id, "wonderful")
self.assertEqual(str(course.location.version_guid), self.GUID_P)
locator = CourseLocator(course_id='wonderful', revision='draft')
locator = CourseLocator(course_id='wonderful', branch='draft')
course = modulestore().get_course(locator)
self.assertEqual(str(course.location.version_guid), self.GUID_D2)
......@@ -216,10 +216,10 @@ class SplitModuleCourseTests(SplitModuleTest):
self.assertRaises(InsufficientSpecificationError,
modulestore().get_course, CourseLocator(course_id='edu.meh.blah'))
self.assertRaises(ItemNotFoundError,
modulestore().get_course, CourseLocator(course_id='nosuchthing', revision='draft'))
modulestore().get_course, CourseLocator(course_id='nosuchthing', branch='draft'))
self.assertRaises(ItemNotFoundError,
modulestore().get_course,
CourseLocator(course_id='GreekHero', revision='published'))
CourseLocator(course_id='GreekHero', branch='published'))
def test_course_successors(self):
"""
......@@ -257,7 +257,7 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertTrue(modulestore().has_item(locator),
"couldn't find in %s" % self.GUID_D1)
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', revision='draft')
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', branch='draft')
self.assertTrue(
modulestore().has_item(locator),
"couldn't find in 12345"
......@@ -265,7 +265,7 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertTrue(
modulestore().has_item(BlockUsageLocator(
course_id=locator.course_id,
revision='draft',
branch='draft',
usage_id=locator.usage_id
)),
"couldn't find in draft 12345"
......@@ -273,38 +273,38 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertFalse(
modulestore().has_item(BlockUsageLocator(
course_id=locator.course_id,
revision='published',
branch='published',
usage_id=locator.usage_id)),
"found in published 12345"
)
locator.revision = 'draft'
locator.branch = 'draft'
self.assertTrue(
modulestore().has_item(locator),
"not found in draft 12345"
)
# not a course obj
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', revision='draft')
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', branch='draft')
self.assertTrue(
modulestore().has_item(locator),
"couldn't find chapter1"
)
# in published course
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", revision='draft')
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='draft')
self.assertTrue(modulestore().has_item(BlockUsageLocator(course_id=locator.course_id,
usage_id=locator.usage_id,
revision='published')),
branch='published')),
"couldn't find in 23456")
locator.revision = 'published'
locator.branch = 'published'
self.assertTrue(modulestore().has_item(locator), "couldn't find in 23456")
def test_negative_has_item(self):
# negative tests--not found
# no such course or block
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", revision='draft')
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", branch='draft')
self.assertFalse(modulestore().has_item(locator))
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", revision='draft')
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", branch='draft')
self.assertFalse(modulestore().has_item(locator))
# negative tests--insufficient specification
......@@ -323,7 +323,7 @@ class SplitModuleItemTests(SplitModuleTest):
block = modulestore().get_item(locator)
self.assertIsInstance(block, CourseDescriptor)
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', revision='draft')
locator = BlockUsageLocator(course_id='GreekHero', usage_id='head12345', branch='draft')
block = modulestore().get_item(locator)
self.assertEqual(block.location.course_id, "GreekHero")
# look at this one in detail
......@@ -338,13 +338,13 @@ class SplitModuleItemTests(SplitModuleTest):
block.grade_cutoffs, {"Pass": 0.45},
)
# try to look up other revisions
# try to look up other branches
self.assertRaises(ItemNotFoundError,
modulestore().get_item,
BlockUsageLocator(course_id=locator.as_course_locator(),
usage_id=locator.usage_id,
revision='published'))
locator.revision = 'draft'
branch='published'))
locator.branch = 'draft'
self.assertIsInstance(
modulestore().get_item(locator),
CourseDescriptor
......@@ -352,7 +352,7 @@ class SplitModuleItemTests(SplitModuleTest):
def test_get_non_root(self):
# not a course obj
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', revision='draft')
locator = BlockUsageLocator(course_id='GreekHero', usage_id='chapter1', branch='draft')
block = modulestore().get_item(locator)
self.assertEqual(block.location.course_id, "GreekHero")
self.assertEqual(block.category, 'chapter')
......@@ -361,7 +361,7 @@ class SplitModuleItemTests(SplitModuleTest):
self.assertEqual(block.edited_by, "testassist@edx.org")
# in published course
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", revision='published')
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='published')
self.assertIsInstance(
modulestore().get_item(locator),
CourseDescriptor
......@@ -369,10 +369,10 @@ class SplitModuleItemTests(SplitModuleTest):
# negative tests--not found
# no such course or block
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", revision='draft')
locator = BlockUsageLocator(course_id="doesnotexist", usage_id="head23456", branch='draft')
with self.assertRaises(ItemNotFoundError):
modulestore().get_item(locator)
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", revision='draft')
locator = BlockUsageLocator(course_id="wonderful", usage_id="doesnotexist", branch='draft')
with self.assertRaises(ItemNotFoundError):
modulestore().get_item(locator)
......@@ -380,7 +380,7 @@ class SplitModuleItemTests(SplitModuleTest):
with self.assertRaises(InsufficientSpecificationError):
modulestore().get_item(BlockUsageLocator(version_guid=self.GUID_D1))
with self.assertRaises(InsufficientSpecificationError):
modulestore().get_item(BlockUsageLocator(course_id='GreekHero', revision='draft'))
modulestore().get_item(BlockUsageLocator(course_id='GreekHero', branch='draft'))
# pylint: disable=W0212
def test_matching(self):
......@@ -411,7 +411,7 @@ class SplitModuleItemTests(SplitModuleTest):
def test_get_items(self):
'''
get_items(locator, qualifiers, [revision])
get_items(locator, qualifiers, [branch])
'''
locator = CourseLocator(version_guid=self.GUID_D0)
# get all modules
......@@ -436,9 +436,9 @@ class SplitModuleItemTests(SplitModuleTest):
def test_get_parents(self):
'''
get_parent_locations(locator, [usage_id], [revision]): [BlockUsageLocator]
get_parent_locations(locator, [usage_id], [branch]): [BlockUsageLocator]
'''
locator = CourseLocator(course_id="GreekHero", revision='draft')
locator = CourseLocator(course_id="GreekHero", branch='draft')
parents = modulestore().get_parent_locations(locator, usage_id='chapter1')
self.assertEqual(len(parents), 1)
self.assertEqual(parents[0].usage_id, 'head12345')
......@@ -454,7 +454,7 @@ class SplitModuleItemTests(SplitModuleTest):
"""
Test the existing get_children method on xdescriptors
"""
locator = BlockUsageLocator(course_id="GreekHero", usage_id="head12345", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="head12345", branch='draft')
block = modulestore().get_item(locator)
children = block.get_children()
expected_ids = [
......@@ -497,7 +497,7 @@ class TestItemCrud(SplitModuleTest):
metadata=None): new_desciptor
"""
# grab link to course to ensure new versioning works
locator = CourseLocator(course_id="GreekHero", revision='draft')
locator = CourseLocator(course_id="GreekHero", branch='draft')
premod_course = modulestore().get_course(locator)
premod_time = datetime.datetime.now(UTC) - datetime.timedelta(seconds=1)
# add minimal one w/o a parent
......@@ -534,7 +534,7 @@ class TestItemCrud(SplitModuleTest):
"""
Test create_item w/ specifying the parent of the new item
"""
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", revision='draft')
locator = BlockUsageLocator(course_id="wonderful", usage_id="head23456", branch='draft')
premod_course = modulestore().get_course(locator)
category = 'chapter'
new_module = modulestore().create_item(
......@@ -554,7 +554,7 @@ class TestItemCrud(SplitModuleTest):
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.
"""
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", revision='draft')
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", branch='draft')
category = 'problem'
premod_time = datetime.datetime.now(UTC) - datetime.timedelta(seconds=1)
new_payload = "<problem>empty</problem>"
......@@ -592,7 +592,7 @@ class TestItemCrud(SplitModuleTest):
"""
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", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem3_2", branch='draft')
problem = modulestore().get_item(locator)
pre_def_id = problem.definition_locator.definition_id
pre_version_guid = problem.location.version_guid
......@@ -629,7 +629,7 @@ class TestItemCrud(SplitModuleTest):
"""
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", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="chapter3", branch='draft')
block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id
pre_version_guid = block.location.version_guid
......@@ -653,7 +653,7 @@ class TestItemCrud(SplitModuleTest):
"""
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", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="head12345", branch='draft')
block = modulestore().get_item(locator)
pre_def_id = block.definition_locator.definition_id
pre_version_guid = block.location.version_guid
......@@ -670,7 +670,7 @@ class TestItemCrud(SplitModuleTest):
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
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", revision='draft')
locator = BlockUsageLocator(course_id="contender", usage_id="head345679", branch='draft')
category = 'problem'
new_payload = "<problem>empty</problem>"
modulestore().create_item(
......@@ -714,14 +714,14 @@ class TestItemCrud(SplitModuleTest):
reusable_location = BlockUsageLocator(
course_id=course.location.course_id,
usage_id=course.location.usage_id,
revision='draft')
branch='draft')
# delete a leaf
problems = modulestore().get_items(reusable_location, {'category': 'problem'})
locn_to_del = problems[0].location
new_course_loc = modulestore().delete_item(locn_to_del, 'deleting_user')
deleted = BlockUsageLocator(course_id=reusable_location.course_id,
revision=reusable_location.revision,
branch=reusable_location.branch,
usage_id=locn_to_del.usage_id)
self.assertFalse(modulestore().has_item(deleted))
self.assertRaises(VersionConflictError, modulestore().has_item, locn_to_del)
......@@ -743,7 +743,7 @@ class TestItemCrud(SplitModuleTest):
self.assertFalse(modulestore().has_item(
BlockUsageLocator(
course_id=node_loc.course_id,
revision=node_loc.revision,
branch=node_loc.branch,
usage_id=node.location.usage_id)))
locator = BlockUsageLocator(
version_guid=node.location.version_guid,
......@@ -759,7 +759,7 @@ class TestItemCrud(SplitModuleTest):
root = BlockUsageLocator(
course_id=course.location.course_id,
usage_id=course.location.usage_id,
revision='draft')
branch='draft')
for _ in range(4):
self.create_subtree_for_deletion(root, ['chapter', 'vertical', 'problem'])
return modulestore().get_item(root)
......@@ -814,7 +814,7 @@ class TestCourseCreation(SplitModuleTest):
Test making a course which points to an existing draft and published but not making any changes to either.
"""
pre_time = datetime.datetime.now(UTC)
original_locator = CourseLocator(course_id="wonderful", revision='draft')
original_locator = CourseLocator(course_id="wonderful", branch='draft')
original_index = modulestore().get_course_index_info(original_locator)
new_draft = modulestore().create_course(
'leech', 'best_course', 'leech_master', id_root='best',
......@@ -831,7 +831,7 @@ class TestCourseCreation(SplitModuleTest):
self.assertLessEqual(new_index["edited_on"], datetime.datetime.now(UTC))
self.assertEqual(new_index['edited_by'], 'leech_master')
new_published_locator = CourseLocator(course_id=new_draft_locator.course_id, revision='published')
new_published_locator = CourseLocator(course_id=new_draft_locator.course_id, branch='published')
new_published = modulestore().get_course(new_published_locator)
self.assertEqual(new_published.edited_by, 'test@edx.org')
self.assertLess(new_published.edited_on, pre_time)
......@@ -870,7 +870,7 @@ class TestCourseCreation(SplitModuleTest):
Create a new course which overrides metadata and course_data
"""
pre_time = datetime.datetime.now(UTC)
original_locator = CourseLocator(course_id="contender", revision='draft')
original_locator = CourseLocator(course_id="contender", branch='draft')
original = modulestore().get_course(original_locator)
original_index = modulestore().get_course_index_info(original_locator)
data_payload = {}
......@@ -909,7 +909,7 @@ class TestCourseCreation(SplitModuleTest):
"""
Test changing the org, pretty id, etc of a course. Test that it doesn't allow changing the id, etc.
"""
locator = CourseLocator(course_id="GreekHero", revision='draft')
locator = CourseLocator(course_id="GreekHero", branch='draft')
modulestore().update_course_index(locator, {'org': 'funkyU'})
course_info = modulestore().get_course_index_info(locator)
self.assertEqual(course_info['org'], 'funkyU')
......@@ -945,7 +945,7 @@ class TestCourseCreation(SplitModuleTest):
# an allowed but not recommended way to publish a course
versions['published'] = self.GUID_D1
modulestore().update_course_index(locator, {'versions': versions}, update_versions=True)
course = modulestore().get_course(CourseLocator(course_id=locator.course_id, revision="published"))
course = modulestore().get_course(CourseLocator(course_id=locator.course_id, branch="published"))
self.assertEqual(str(course.location.version_guid), self.GUID_D1)
......@@ -959,11 +959,11 @@ class TestInheritance(SplitModuleTest):
"""
# Note, not testing value where defined (course) b/c there's no
# defined accessor for it on CourseDescriptor.
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem3_2", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem3_2", branch='draft')
node = modulestore().get_item(locator)
# inherited
self.assertEqual(node.graceperiod, datetime.timedelta(hours=2))
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem1", revision='draft')
locator = BlockUsageLocator(course_id="GreekHero", usage_id="problem1", branch='draft')
node = modulestore().get_item(locator)
# overridden
self.assertEqual(node.graceperiod, datetime.timedelta(hours=4))
......
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