Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f5f24fcc
Commit
f5f24fcc
authored
Dec 23, 2013
by
Don Mitchell
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2022 from edx/dhm/locator_course_id
Change course_id to package_id
parents
c3fbdd68
b7368ef6
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
403 additions
and
409 deletions
+403
-409
cms/djangoapps/auth/authz.py
+8
-10
cms/djangoapps/contentstore/tests/test_crud.py
+2
-2
cms/djangoapps/contentstore/tests/test_permissions.py
+2
-3
cms/djangoapps/contentstore/views/assets.py
+2
-2
cms/djangoapps/contentstore/views/checklist.py
+2
-2
cms/djangoapps/contentstore/views/component.py
+4
-4
cms/djangoapps/contentstore/views/course.py
+24
-26
cms/djangoapps/contentstore/views/import_export.py
+8
-8
cms/djangoapps/contentstore/views/item.py
+8
-8
cms/djangoapps/contentstore/views/tabs.py
+2
-2
cms/djangoapps/contentstore/views/user.py
+2
-2
common/lib/xmodule/xmodule/course_module.py
+1
-2
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
+22
-22
common/lib/xmodule/xmodule/modulestore/locator.py
+65
-65
common/lib/xmodule/xmodule/modulestore/parsers.py
+9
-9
common/lib/xmodule/xmodule/modulestore/split_migrator.py
+11
-11
common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py
+5
-5
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+35
-35
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
+33
-33
common/lib/xmodule/xmodule/modulestore/tests/test_locators.py
+53
-53
common/lib/xmodule/xmodule/modulestore/tests/test_orphan.py
+8
-8
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
+86
-86
lms/djangoapps/courseware/roles.py
+11
-11
No files found.
cms/djangoapps/auth/authz.py
View file @
f5f24fcc
...
@@ -37,23 +37,21 @@ def get_all_course_role_groupnames(location, role, use_filter=True):
...
@@ -37,23 +37,21 @@ def get_all_course_role_groupnames(location, role, use_filter=True):
'''
'''
location
=
Locator
.
to_locator_or_location
(
location
)
location
=
Locator
.
to_locator_or_location
(
location
)
# hack: check for existence of a group name in the legacy LMS format <role>_<course>
# if it exists, then use that one, otherwise use a <role>_<course_id> which contains
# more information
groupnames
=
[]
groupnames
=
[]
try
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course_id
))
except
InvalidLocationError
:
# will occur on old locations where location is not of category course
pass
if
isinstance
(
location
,
Location
):
if
isinstance
(
location
,
Location
):
# least preferred role_course format
try
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course
))
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course_id
))
except
InvalidLocationError
:
# will occur on old locations where location is not of category course
pass
try
:
try
:
locator
=
loc_mapper
()
.
translate_location
(
location
.
course_id
,
location
,
False
,
False
)
locator
=
loc_mapper
()
.
translate_location
(
location
.
course_id
,
location
,
False
,
False
)
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
locator
.
cours
e_id
))
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
locator
.
packag
e_id
))
except
(
InvalidLocationError
,
ItemNotFoundError
):
except
(
InvalidLocationError
,
ItemNotFoundError
):
pass
pass
# least preferred role_course format for legacy reasons
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course
))
elif
isinstance
(
location
,
CourseLocator
):
elif
isinstance
(
location
,
CourseLocator
):
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
package_id
))
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
,
get_course
=
True
)
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
,
get_course
=
True
)
if
old_location
:
if
old_location
:
# the slashified version of the course_id (myu/mycourse/myrun)
# the slashified version of the course_id (myu/mycourse/myrun)
...
...
cms/djangoapps/contentstore/tests/test_crud.py
View file @
f5f24fcc
...
@@ -136,13 +136,13 @@ class TemplateTests(unittest.TestCase):
...
@@ -136,13 +136,13 @@ class TemplateTests(unittest.TestCase):
persistent_factories
.
ItemFactory
.
create
(
display_name
=
'chapter 1'
,
persistent_factories
.
ItemFactory
.
create
(
display_name
=
'chapter 1'
,
parent_location
=
test_course
.
location
)
parent_location
=
test_course
.
location
)
id_locator
=
CourseLocator
(
course_id
=
test_course
.
location
.
cours
e_id
,
branch
=
'draft'
)
id_locator
=
CourseLocator
(
package_id
=
test_course
.
location
.
packag
e_id
,
branch
=
'draft'
)
guid_locator
=
CourseLocator
(
version_guid
=
test_course
.
location
.
version_guid
)
guid_locator
=
CourseLocator
(
version_guid
=
test_course
.
location
.
version_guid
)
# verify it can be retireved by id
# verify it can be retireved by id
self
.
assertIsInstance
(
modulestore
(
'split'
)
.
get_course
(
id_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
modulestore
(
'split'
)
.
get_course
(
id_locator
),
CourseDescriptor
)
# and by guid
# and by guid
self
.
assertIsInstance
(
modulestore
(
'split'
)
.
get_course
(
guid_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
modulestore
(
'split'
)
.
get_course
(
guid_locator
),
CourseDescriptor
)
modulestore
(
'split'
)
.
delete_course
(
id_locator
.
cours
e_id
)
modulestore
(
'split'
)
.
delete_course
(
id_locator
.
packag
e_id
)
# test can no longer retrieve by id
# test can no longer retrieve by id
self
.
assertRaises
(
ItemNotFoundError
,
modulestore
(
'split'
)
.
get_course
,
id_locator
)
self
.
assertRaises
(
ItemNotFoundError
,
modulestore
(
'split'
)
.
get_course
,
id_locator
)
# but can by guid
# but can by guid
...
...
cms/djangoapps/contentstore/tests/test_permissions.py
View file @
f5f24fcc
...
@@ -90,7 +90,7 @@ class TestCourseAccess(ModuleStoreTestCase):
...
@@ -90,7 +90,7 @@ class TestCourseAccess(ModuleStoreTestCase):
# first check the groupname for the course creator.
# first check the groupname for the course creator.
self
.
assertTrue
(
self
.
assertTrue
(
self
.
user
.
groups
.
filter
(
self
.
user
.
groups
.
filter
(
name
=
"{}_{}"
.
format
(
INSTRUCTOR_ROLE_NAME
,
self
.
course_locator
.
cours
e_id
)
name
=
"{}_{}"
.
format
(
INSTRUCTOR_ROLE_NAME
,
self
.
course_locator
.
packag
e_id
)
)
.
exists
(),
)
.
exists
(),
"Didn't add creator as instructor."
"Didn't add creator as instructor."
)
)
...
@@ -124,4 +124,4 @@ class TestCourseAccess(ModuleStoreTestCase):
...
@@ -124,4 +124,4 @@ class TestCourseAccess(ModuleStoreTestCase):
for
role
in
[
INSTRUCTOR_ROLE_NAME
,
STAFF_ROLE_NAME
]:
for
role
in
[
INSTRUCTOR_ROLE_NAME
,
STAFF_ROLE_NAME
]:
for
user
in
user_by_role
[
role
]:
for
user
in
user_by_role
[
role
]:
self
.
assertTrue
(
has_access
(
user
,
copy_course_locator
),
"{} no copy access"
.
format
(
user
))
self
.
assertTrue
(
has_access
(
user
,
copy_course_locator
),
"{} no copy access"
.
format
(
user
))
self
.
assertTrue
(
has_access
(
user
,
copy_course_location
),
"{} no copy access"
.
format
(
user
))
self
.
assertTrue
(
has_access
(
user
,
copy_course_location
),
"{} no copy access"
.
format
(
user
))
\ No newline at end of file
cms/djangoapps/contentstore/views/assets.py
View file @
f5f24fcc
...
@@ -34,7 +34,7 @@ __all__ = ['assets_handler']
...
@@ -34,7 +34,7 @@ __all__ = ['assets_handler']
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
def
assets_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
asset_id
=
None
):
def
assets_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
asset_id
=
None
):
"""
"""
The restful handler for assets.
The restful handler for assets.
It allows retrieval of all the assets (as an HTML page), as well as uploading new assets,
It allows retrieval of all the assets (as an HTML page), as well as uploading new assets,
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
...
cms/djangoapps/contentstore/views/checklist.py
View file @
f5f24fcc
...
@@ -26,7 +26,7 @@ __all__ = ['checklists_handler']
...
@@ -26,7 +26,7 @@ __all__ = ['checklists_handler']
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
def
checklists_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
checklist_index
=
None
):
def
checklists_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
checklist_index
=
None
):
"""
"""
The restful handler for checklists.
The restful handler for checklists.
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
...
cms/djangoapps/contentstore/views/component.py
View file @
f5f24fcc
...
@@ -56,7 +56,7 @@ ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules'
...
@@ -56,7 +56,7 @@ ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules'
@require_http_methods
([
"GET"
])
@require_http_methods
([
"GET"
])
@login_required
@login_required
def
subsection_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
subsection_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for subsection-specific requests.
The restful handler for subsection-specific requests.
...
@@ -65,7 +65,7 @@ def subsection_handler(request, tag=None, course_id=None, branch=None, version_g
...
@@ -65,7 +65,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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
:
...
@@ -145,7 +145,7 @@ def _load_mixed_class(category):
...
@@ -145,7 +145,7 @@ def _load_mixed_class(category):
@require_http_methods
([
"GET"
])
@require_http_methods
([
"GET"
])
@login_required
@login_required
def
unit_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
unit_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for unit-specific requests.
The restful handler for unit-specific requests.
...
@@ -154,7 +154,7 @@ def unit_handler(request, tag=None, course_id=None, branch=None, version_guid=No
...
@@ -154,7 +154,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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
:
...
...
cms/djangoapps/contentstore/views/course.py
View file @
f5f24fcc
...
@@ -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
(
cours
e_id
,
branch
,
version_guid
,
block_id
,
user
,
depth
=
0
):
def
_get_locator_and_course
(
packag
e_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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block_id
)
locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
)
...
@@ -75,7 +75,7 @@ def _get_locator_and_course(course_id, branch, version_guid, block_id, user, dep
...
@@ -75,7 +75,7 @@ def _get_locator_and_course(course_id, branch, version_guid, block_id, user, dep
# pylint: disable=unused-argument
# pylint: disable=unused-argument
@login_required
@login_required
def
course_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
course_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for course specific requests.
The restful handler for course specific requests.
It provides the course tree with the necessary information for identifying and labeling the parts. The root
It provides the course tree with the necessary information for identifying and labeling the parts. The root
...
@@ -93,7 +93,7 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -93,7 +93,7 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid=
index entry.
index entry.
PUT
PUT
json: update this course (index entry not xblock) such as repointing head, changing display name, org,
json: update this course (index entry not xblock) such as repointing head, changing display name, org,
cours
e_id, prettyid. Return same json as above.
packag
e_id, prettyid. Return same json as above.
DELETE
DELETE
json: delete this branch from this course (leaving off /branch/draft would imply delete the course)
json: delete this branch from this course (leaving off /branch/draft would imply delete the course)
"""
"""
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
BlockUsageLocator
(
package_id
=
packag
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
):
):
raise
PermissionDenied
()
raise
PermissionDenied
()
elif
request
.
method
==
'PUT'
:
elif
request
.
method
==
'PUT'
:
...
@@ -114,10 +114,10 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -114,10 +114,10 @@ def course_handler(request, tag=None, course_id=None, branch=None, version_guid=
else
:
else
:
return
HttpResponseBadRequest
()
return
HttpResponseBadRequest
()
elif
request
.
method
==
'GET'
:
# assume html
elif
request
.
method
==
'GET'
:
# assume html
if
cours
e_id
is
None
:
if
packag
e_id
is
None
:
return
course_listing
(
request
)
return
course_listing
(
request
)
else
:
else
:
return
course_index
(
request
,
cours
e_id
,
branch
,
version_guid
,
block
)
return
course_index
(
request
,
packag
e_id
,
branch
,
version_guid
,
block
)
else
:
else
:
return
HttpResponseNotFound
()
return
HttpResponseNotFound
()
...
@@ -157,9 +157,7 @@ def course_listing(request):
...
@@ -157,9 +157,7 @@ def course_listing(request):
course
.
display_name
,
course
.
display_name
,
# note, couldn't get django reverse to work; so, wrote workaround
# note, couldn't get django reverse to work; so, wrote workaround
course_loc
.
url_reverse
(
'course/'
,
''
),
course_loc
.
url_reverse
(
'course/'
,
''
),
get_lms_link_for_item
(
get_lms_link_for_item
(
course
.
location
),
course
.
location
),
course
.
display_org_with_default
,
course
.
display_org_with_default
,
course
.
display_number_with_default
,
course
.
display_number_with_default
,
course
.
location
.
name
course
.
location
.
name
...
@@ -175,14 +173,14 @@ def course_listing(request):
...
@@ -175,14 +173,14 @@ def course_listing(request):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
def
course_index
(
request
,
cours
e_id
,
branch
,
version_guid
,
block
):
def
course_index
(
request
,
packag
e_id
,
branch
,
version_guid
,
block
):
"""
"""
Display an editable course overview.
Display an editable course overview.
org, course, name: Attributes of the Location for the item to edit
org, course, name: Attributes of the Location for the item to edit
"""
"""
locator
,
course
=
_get_locator_and_course
(
locator
,
course
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
,
depth
=
3
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
,
depth
=
3
)
)
lms_link
=
get_lms_link_for_item
(
course
.
location
)
lms_link
=
get_lms_link_for_item
(
course
.
location
)
sections
=
course
.
get_children
()
sections
=
course
.
get_children
()
...
@@ -315,13 +313,13 @@ def create_new_course(request):
...
@@ -315,13 +313,13 @@ def create_new_course(request):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
([
"GET"
])
@require_http_methods
([
"GET"
])
def
course_info_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
course_info_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
GET
GET
html: return html for editing the course info handouts and updates.
html: return html for editing the course info handouts and updates.
"""
"""
__
,
course_module
=
_get_locator_and_course
(
__
,
course_module
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
'text/html'
):
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
'text/html'
):
handouts_old_location
=
course_module
.
location
.
replace
(
category
=
'course_info'
,
name
=
'handouts'
)
handouts_old_location
=
course_module
.
location
.
replace
(
category
=
'course_info'
,
name
=
'handouts'
)
...
@@ -352,7 +350,7 @@ def course_info_handler(request, tag=None, course_id=None, branch=None, version_
...
@@ -352,7 +350,7 @@ def course_info_handler(request, tag=None, course_id=None, branch=None, version_
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@expect_json
@expect_json
def
course_info_update_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
def
course_info_update_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
provided_id
=
None
):
provided_id
=
None
):
"""
"""
restful CRUD operations on course_info updates.
restful CRUD operations on course_info updates.
...
@@ -366,7 +364,7 @@ def course_info_update_handler(request, tag=None, course_id=None, branch=None, v
...
@@ -366,7 +364,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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
updates_locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
...
@@ -400,7 +398,7 @@ def course_info_update_handler(request, tag=None, course_id=None, branch=None, v
...
@@ -400,7 +398,7 @@ def course_info_update_handler(request, tag=None, course_id=None, branch=None, v
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"PUT"
,
"POST"
))
@require_http_methods
((
"GET"
,
"PUT"
,
"POST"
))
@expect_json
@expect_json
def
settings_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
settings_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
Course settings for dates and about pages
Course settings for dates and about pages
GET
GET
...
@@ -410,7 +408,7 @@ def settings_handler(request, tag=None, course_id=None, branch=None, version_gui
...
@@ -410,7 +408,7 @@ def settings_handler(request, tag=None, course_id=None, branch=None, version_gui
json: update the Course and About xblocks through the CourseDetails model
json: update the Course and About xblocks through the CourseDetails model
"""
"""
locator
,
course_module
=
_get_locator_and_course
(
locator
,
course_module
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
upload_asset_url
=
locator
.
url_reverse
(
'assets/'
)
upload_asset_url
=
locator
.
url_reverse
(
'assets/'
)
...
@@ -444,7 +442,7 @@ def settings_handler(request, tag=None, course_id=None, branch=None, version_gui
...
@@ -444,7 +442,7 @@ def settings_handler(request, tag=None, course_id=None, branch=None, version_gui
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@expect_json
@expect_json
def
grading_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
grader_index
=
None
):
def
grading_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
grader_index
=
None
):
"""
"""
Course Grading policy configuration
Course Grading policy configuration
GET
GET
...
@@ -456,7 +454,7 @@ def grading_handler(request, tag=None, course_id=None, branch=None, version_guid
...
@@ -456,7 +454,7 @@ def grading_handler(request, tag=None, course_id=None, branch=None, version_guid
json w/ grader_index: create or update the specific grader (create if index out of range)
json w/ grader_index: create or update the specific grader (create if index out of range)
"""
"""
locator
,
course_module
=
_get_locator_and_course
(
locator
,
course_module
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
...
@@ -550,7 +548,7 @@ def _config_course_advanced_components(request, course_module):
...
@@ -550,7 +548,7 @@ def _config_course_advanced_components(request, course_module):
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@expect_json
@expect_json
def
advanced_settings_handler
(
request
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
tag
=
None
):
def
advanced_settings_handler
(
request
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
tag
=
None
):
"""
"""
Course settings configuration
Course settings configuration
GET
GET
...
@@ -562,7 +560,7 @@ def advanced_settings_handler(request, course_id=None, branch=None, version_guid
...
@@ -562,7 +560,7 @@ def advanced_settings_handler(request, course_id=None, branch=None, version_guid
of keys whose values to unset: i.e., revert to default
of keys whose values to unset: i.e., revert to default
"""
"""
locator
,
course_module
=
_get_locator_and_course
(
locator
,
course_module
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
if
'text/html'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
)
and
request
.
method
==
'GET'
:
...
@@ -652,7 +650,7 @@ def assign_textbook_id(textbook, used_ids=()):
...
@@ -652,7 +650,7 @@ def assign_textbook_id(textbook, used_ids=()):
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
def
textbooks_list_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
textbooks_list_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
A RESTful handler for textbook collections.
A RESTful handler for textbook collections.
...
@@ -665,7 +663,7 @@ def textbooks_list_handler(request, tag=None, course_id=None, branch=None, versi
...
@@ -665,7 +663,7 @@ def textbooks_list_handler(request, tag=None, course_id=None, branch=None, versi
json: overwrite all textbooks in the course with the given list
json: overwrite all textbooks in the course with the given list
"""
"""
locator
,
course
=
_get_locator_and_course
(
locator
,
course
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
store
=
get_modulestore
(
course
.
location
)
store
=
get_modulestore
(
course
.
location
)
...
@@ -729,7 +727,7 @@ def textbooks_list_handler(request, tag=None, course_id=None, branch=None, versi
...
@@ -729,7 +727,7 @@ def textbooks_list_handler(request, tag=None, course_id=None, branch=None, versi
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
def
textbooks_detail_handler
(
request
,
tid
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
textbooks_detail_handler
(
request
,
tid
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
JSON API endpoint for manipulating a textbook via its internal ID.
JSON API endpoint for manipulating a textbook via its internal ID.
Used by the Backbone application.
Used by the Backbone application.
...
@@ -742,7 +740,7 @@ def textbooks_detail_handler(request, tid, tag=None, course_id=None, branch=None
...
@@ -742,7 +740,7 @@ def textbooks_detail_handler(request, tid, tag=None, course_id=None, branch=None
json: remove textbook
json: remove textbook
"""
"""
__
,
course
=
_get_locator_and_course
(
__
,
course
=
_get_locator_and_course
(
cours
e_id
,
branch
,
version_guid
,
block
,
request
.
user
packag
e_id
,
branch
,
version_guid
,
block
,
request
.
user
)
)
store
=
get_modulestore
(
course
.
location
)
store
=
get_modulestore
(
course
.
location
)
matching_id
=
[
tb
for
tb
in
course
.
pdf_textbooks
matching_id
=
[
tb
for
tb
in
course
.
pdf_textbooks
...
...
cms/djangoapps/contentstore/views/import_export.py
View file @
f5f24fcc
...
@@ -50,7 +50,7 @@ CONTENT_RE = re.compile(r"(?P<start>\d{1,11})-(?P<stop>\d{1,11})/(?P<end>\d{1,11
...
@@ -50,7 +50,7 @@ CONTENT_RE = re.compile(r"(?P<start>\d{1,11})-(?P<stop>\d{1,11})/(?P<end>\d{1,11
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
def
import_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
import_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for importing a course.
The restful handler for importing a course.
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
@@ -148,7 +148,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -148,7 +148,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid=
# Use sessions to keep info about import progress
# Use sessions to keep info about import progress
session_status
=
request
.
session
.
setdefault
(
"import_status"
,
{})
session_status
=
request
.
session
.
setdefault
(
"import_status"
,
{})
key
=
location
.
cours
e_id
+
filename
key
=
location
.
packag
e_id
+
filename
session_status
[
key
]
=
1
session_status
[
key
]
=
1
request
.
session
.
modified
=
True
request
.
session
.
modified
=
True
...
@@ -261,7 +261,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -261,7 +261,7 @@ def import_handler(request, tag=None, course_id=None, branch=None, version_guid=
@require_GET
@require_GET
@ensure_csrf_cookie
@ensure_csrf_cookie
@login_required
@login_required
def
import_status_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
filename
=
None
):
def
import_status_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
filename
=
None
):
"""
"""
Returns an integer corresponding to the status of a file import. These are:
Returns an integer corresponding to the status of a file import. These are:
...
@@ -271,13 +271,13 @@ def import_status_handler(request, tag=None, course_id=None, branch=None, versio
...
@@ -271,13 +271,13 @@ 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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
try
:
try
:
session_status
=
request
.
session
[
"import_status"
]
session_status
=
request
.
session
[
"import_status"
]
status
=
session_status
[
location
.
cours
e_id
+
filename
]
status
=
session_status
[
location
.
packag
e_id
+
filename
]
except
KeyError
:
except
KeyError
:
status
=
0
status
=
0
...
@@ -287,7 +287,7 @@ def import_status_handler(request, tag=None, course_id=None, branch=None, versio
...
@@ -287,7 +287,7 @@ def import_status_handler(request, tag=None, course_id=None, branch=None, versio
@ensure_csrf_cookie
@ensure_csrf_cookie
@login_required
@login_required
@require_http_methods
((
"GET"
,))
@require_http_methods
((
"GET"
,))
def
export_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
export_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for exporting a course.
The restful handler for exporting a course.
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
...
cms/djangoapps/contentstore/views/item.py
View file @
f5f24fcc
...
@@ -47,7 +47,7 @@ CREATE_IF_NOT_FOUND = ['course_info']
...
@@ -47,7 +47,7 @@ CREATE_IF_NOT_FOUND = ['course_info']
@require_http_methods
((
"DELETE"
,
"GET"
,
"PUT"
,
"POST"
))
@require_http_methods
((
"DELETE"
,
"GET"
,
"PUT"
,
"POST"
))
@login_required
@login_required
@expect_json
@expect_json
def
xblock_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
xblock_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for xblock requests.
The restful handler for xblock requests.
...
@@ -78,8 +78,8 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -78,8 +78,8 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
:boilerplate: template name for populating fields, optional
:boilerplate: template name for populating fields, optional
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
cours
e_id
is
not
None
:
if
packag
e_id
is
not
None
:
locator
=
BlockUsageLocator
(
course_id
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
)
...
@@ -117,7 +117,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -117,7 +117,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
delete_all_versions
=
str_to_bool
(
request
.
REQUEST
.
get
(
'all_versions'
,
'False'
))
delete_all_versions
=
str_to_bool
(
request
.
REQUEST
.
get
(
'all_versions'
,
'False'
))
return
_delete_item_at_location
(
old_location
,
delete_children
,
delete_all_versions
)
return
_delete_item_at_location
(
old_location
,
delete_children
,
delete_all_versions
)
else
:
# Since we have a
cours
e_id, we are updating an existing xblock.
else
:
# Since we have a
packag
e_id, we are updating an existing xblock.
return
_save_item
(
return
_save_item
(
request
,
request
,
locator
,
locator
,
...
@@ -133,7 +133,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -133,7 +133,7 @@ def xblock_handler(request, tag=None, course_id=None, branch=None, version_guid=
return
_create_item
(
request
)
return
_create_item
(
request
)
else
:
else
:
return
HttpResponseBadRequest
(
return
HttpResponseBadRequest
(
"Only instance creation is supported without a
cours
e_id."
,
"Only instance creation is supported without a
packag
e_id."
,
content_type
=
"text/plain"
content_type
=
"text/plain"
)
)
...
@@ -319,7 +319,7 @@ def _delete_item_at_location(item_location, delete_children=False, delete_all_ve
...
@@ -319,7 +319,7 @@ def _delete_item_at_location(item_location, delete_children=False, delete_all_ve
# pylint: disable=W0613
# pylint: disable=W0613
@login_required
@login_required
@require_http_methods
((
"GET"
,
"DELETE"
))
@require_http_methods
((
"GET"
,
"DELETE"
))
def
orphan_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
orphan_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
View for handling orphan related requests. GET gets all of the current orphans.
View for handling orphan related requests. GET gets all of the current orphans.
DELETE removes all orphans (requires is_staff access)
DELETE removes all orphans (requires is_staff access)
...
@@ -328,9 +328,9 @@ def orphan_handler(request, tag=None, course_id=None, branch=None, version_guid=
...
@@ -328,9 +328,9 @@ def orphan_handler(request, tag=None, course_id=None, branch=None, version_guid=
from the root via children
from the root via children
:param request:
:param request:
:param
course_id: Locator syntax cours
e_id
:param
package_id: Locator syntax packag
e_id
"""
"""
location
=
BlockUsageLocator
(
course_id
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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'
:
...
...
cms/djangoapps/contentstore/views/tabs.py
View file @
f5f24fcc
...
@@ -48,7 +48,7 @@ def initialize_course_tabs(course):
...
@@ -48,7 +48,7 @@ def initialize_course_tabs(course):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
))
def
tabs_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
def
tabs_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
):
"""
"""
The restful handler for static tabs.
The restful handler for static tabs.
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
locator
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
...
cms/djangoapps/contentstore/views/user.py
View file @
f5f24fcc
...
@@ -40,7 +40,7 @@ def request_course_creator(request):
...
@@ -40,7 +40,7 @@ def request_course_creator(request):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
@require_http_methods
((
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
))
def
course_team_handler
(
request
,
tag
=
None
,
cours
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
email
=
None
):
def
course_team_handler
(
request
,
tag
=
None
,
packag
e_id
=
None
,
branch
=
None
,
version_guid
=
None
,
block
=
None
,
email
=
None
):
"""
"""
The restful handler for course team users.
The restful handler for course team users.
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
version_guid
=
version_guid
,
block_id
=
block
)
location
=
BlockUsageLocator
(
package_id
=
packag
e_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
()
...
...
common/lib/xmodule/xmodule/course_module.py
View file @
f5f24fcc
...
@@ -17,7 +17,6 @@ from xblock.fields import Scope, List, String, Dict, Boolean
...
@@ -17,7 +17,6 @@ from xblock.fields import Scope, List, String, Dict, Boolean
from
.fields
import
Date
from
.fields
import
Date
from
xmodule.modulestore.locator
import
CourseLocator
from
xmodule.modulestore.locator
import
CourseLocator
from
django.utils.timezone
import
UTC
from
django.utils.timezone
import
UTC
from
xmodule.util
import
date_utils
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -400,7 +399,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
...
@@ -400,7 +399,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
if
isinstance
(
self
.
location
,
Location
):
if
isinstance
(
self
.
location
,
Location
):
self
.
wiki_slug
=
self
.
location
.
course
self
.
wiki_slug
=
self
.
location
.
course
elif
isinstance
(
self
.
location
,
CourseLocator
):
elif
isinstance
(
self
.
location
,
CourseLocator
):
self
.
wiki_slug
=
self
.
location
.
cours
e_id
or
self
.
display_name
self
.
wiki_slug
=
self
.
location
.
packag
e_id
or
self
.
display_name
if
self
.
due_date_display_format
is
None
and
self
.
show_timezone
is
False
:
if
self
.
due_date_display_format
is
None
and
self
.
show_timezone
is
False
:
# For existing courses with show_timezone set to False (and no due_date_display_format specified),
# For existing courses with show_timezone set to False (and no due_date_display_format specified),
...
...
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
View file @
f5f24fcc
...
@@ -51,21 +51,21 @@ class LocMapperStore(object):
...
@@ -51,21 +51,21 @@ class LocMapperStore(object):
self
.
cache
=
cache
self
.
cache
=
cache
# location_map functions
# location_map functions
def
create_map_entry
(
self
,
course_location
,
cours
e_id
=
None
,
draft_branch
=
'draft'
,
prod_branch
=
'published'
,
def
create_map_entry
(
self
,
course_location
,
packag
e_id
=
None
,
draft_branch
=
'draft'
,
prod_branch
=
'published'
,
block_map
=
None
):
block_map
=
None
):
"""
"""
Add a new entry to map this course_location to the new style CourseLocator.
course_id. If cours
e_id is not
Add a new entry to map this course_location to the new style CourseLocator.
package_id. If packag
e_id is not
provided, it creates the default map of using org.course.name from the location
(just like course_id)
if
provided, it creates the default map of using org.course.name from the location if
the location.category = 'course'; otherwise, it uses org.course.
the location.category = 'course'; otherwise, it uses org.course.
You can create more than one mapping to the
You can create more than one mapping to the
same
cours
e_id target. In that case, the reverse translate will be arbitrary (no guarantee of which wins).
same
packag
e_id target. In that case, the reverse translate will be arbitrary (no guarantee of which wins).
The use
The use
case for more than one mapping is to map both org/course/run and org/course to the same new
cours
e_id thus
case for more than one mapping is to map both org/course/run and org/course to the same new
packag
e_id thus
making a default for org/course. When querying for just org/course, the translator will prefer any entry
making a default for org/course. When querying for just org/course, the translator will prefer any entry
which does not have a name in the _id; otherwise, it will return an arbitrary match.
which does not have a name in the _id; otherwise, it will return an arbitrary match.
Note: the opposite is not true. That is, it never makes sense to use 2 different CourseLocator.
cours
e_id
Note: the opposite is not true. That is, it never makes sense to use 2 different CourseLocator.
packag
e_id
keys to index the same old Locator org/course/.. pattern. There's no checking to ensure you don't do this.
keys to index the same old Locator org/course/.. pattern. There's no checking to ensure you don't do this.
NOTE: if there's already an entry w the given course_location, this may either overwrite that entry or
NOTE: if there's already an entry w the given course_location, this may either overwrite that entry or
...
@@ -74,8 +74,8 @@ class LocMapperStore(object):
...
@@ -74,8 +74,8 @@ class LocMapperStore(object):
:param course_location: a Location preferably whose category is 'course'. Unlike the other
:param course_location: a Location preferably whose category is 'course'. Unlike the other
map methods, this one doesn't take the old-style course_id. It should be called with
map methods, this one doesn't take the old-style course_id. It should be called with
a course location not a block location; however, if called w/ a non-course Location, it creates
a course location not a block location; however, if called w/ a non-course Location, it creates
a "default" map for the org/course pair to a new
cours
e_id.
a "default" map for the org/course pair to a new
packag
e_id.
:param
course_id: the CourseLocator style cours
e_id
:param
package_id: the CourseLocator style packag
e_id
:param draft_branch: the branch name to assign for drafts. This is hardcoded because old mongo had
:param draft_branch: the branch name to assign for drafts. This is hardcoded because old mongo had
a fixed notion that there was 2 and only 2 versions for modules: draft and production. The old mongo
a fixed notion that there was 2 and only 2 versions for modules: draft and production. The old mongo
did not, however, require that a draft version exist. The new one, however, does require a draft to
did not, however, require that a draft version exist. The new one, however, does require a draft to
...
@@ -86,11 +86,11 @@ class LocMapperStore(object):
...
@@ -86,11 +86,11 @@ class LocMapperStore(object):
:param block_map: an optional map to specify preferred names for blocks where the keys are the
:param block_map: an optional map to specify preferred names for blocks where the keys are the
Location block names and the values are the BlockUsageLocator.block_id.
Location block names and the values are the BlockUsageLocator.block_id.
"""
"""
if
cours
e_id
is
None
:
if
packag
e_id
is
None
:
if
course_location
.
category
==
'course'
:
if
course_location
.
category
==
'course'
:
cours
e_id
=
"{0.org}.{0.course}.{0.name}"
.
format
(
course_location
)
packag
e_id
=
"{0.org}.{0.course}.{0.name}"
.
format
(
course_location
)
else
:
else
:
cours
e_id
=
"{0.org}.{0.course}"
.
format
(
course_location
)
packag
e_id
=
"{0.org}.{0.course}"
.
format
(
course_location
)
# very like _interpret_location_id but w/o the _id
# very like _interpret_location_id but w/o the _id
location_id
=
self
.
_construct_location_son
(
location_id
=
self
.
_construct_location_son
(
course_location
.
org
,
course_location
.
course
,
course_location
.
org
,
course_location
.
course
,
...
@@ -99,12 +99,12 @@ class LocMapperStore(object):
...
@@ -99,12 +99,12 @@ class LocMapperStore(object):
self
.
location_map
.
insert
({
self
.
location_map
.
insert
({
'_id'
:
location_id
,
'_id'
:
location_id
,
'course_id'
:
cours
e_id
,
'course_id'
:
packag
e_id
,
'draft_branch'
:
draft_branch
,
'draft_branch'
:
draft_branch
,
'prod_branch'
:
prod_branch
,
'prod_branch'
:
prod_branch
,
'block_map'
:
block_map
or
{},
'block_map'
:
block_map
or
{},
})
})
return
cours
e_id
return
packag
e_id
def
translate_location
(
self
,
old_style_course_id
,
location
,
published
=
True
,
add_entry_if_missing
=
True
):
def
translate_location
(
self
,
old_style_course_id
,
location
,
published
=
True
,
add_entry_if_missing
=
True
):
"""
"""
...
@@ -174,9 +174,9 @@ class LocMapperStore(object):
...
@@ -174,9 +174,9 @@ class LocMapperStore(object):
raise
InvalidLocationError
()
raise
InvalidLocationError
()
published_usage
=
BlockUsageLocator
(
published_usage
=
BlockUsageLocator
(
cours
e_id
=
entry
[
'course_id'
],
branch
=
entry
[
'prod_branch'
],
block_id
=
block_id
)
packag
e_id
=
entry
[
'course_id'
],
branch
=
entry
[
'prod_branch'
],
block_id
=
block_id
)
draft_usage
=
BlockUsageLocator
(
draft_usage
=
BlockUsageLocator
(
cours
e_id
=
entry
[
'course_id'
],
branch
=
entry
[
'draft_branch'
],
block_id
=
block_id
)
packag
e_id
=
entry
[
'course_id'
],
branch
=
entry
[
'draft_branch'
],
block_id
=
block_id
)
if
published
:
if
published
:
result
=
published_usage
result
=
published_usage
else
:
else
:
...
@@ -199,13 +199,13 @@ class LocMapperStore(object):
...
@@ -199,13 +199,13 @@ 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
cours
e_id, it looks for the first
If there's more than one location to locator mapping to the same
packag
e_id, it looks for the first
one with a mapping for the block block_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
"""
"""
if
get_course
:
if
get_course
:
cached_value
=
self
.
_get_course_location_from_cache
(
locator
.
cours
e_id
)
cached_value
=
self
.
_get_course_location_from_cache
(
locator
.
packag
e_id
)
else
:
else
:
cached_value
=
self
.
_get_location_from_cache
(
locator
)
cached_value
=
self
.
_get_location_from_cache
(
locator
)
if
cached_value
:
if
cached_value
:
...
@@ -213,7 +213,7 @@ class LocMapperStore(object):
...
@@ -213,7 +213,7 @@ 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
.
cours
e_id
})
maps
=
self
.
location_map
.
find
({
'course_id'
:
locator
.
packag
e_id
})
# look for one which maps to this block block_id
# look for one which maps to this block block_id
if
maps
.
count
()
==
0
:
if
maps
.
count
()
==
0
:
return
None
return
None
...
@@ -365,12 +365,12 @@ class LocMapperStore(object):
...
@@ -365,12 +365,12 @@ class LocMapperStore(object):
"""
"""
return
self
.
cache
.
get
(
unicode
(
locator
))
return
self
.
cache
.
get
(
unicode
(
locator
))
def
_get_course_location_from_cache
(
self
,
locator_
cours
e_id
):
def
_get_course_location_from_cache
(
self
,
locator_
packag
e_id
):
"""
"""
See if the
cours
e_id is in the cache. If so, return the mapped location to the
See if the
packag
e_id is in the cache. If so, return the mapped location to the
course root.
course root.
"""
"""
return
self
.
cache
.
get
(
'courseId+{}'
.
format
(
locator_
cours
e_id
))
return
self
.
cache
.
get
(
'courseId+{}'
.
format
(
locator_
packag
e_id
))
def
_cache_location_map_entry
(
self
,
old_course_id
,
location
,
published_usage
,
draft_usage
):
def
_cache_location_map_entry
(
self
,
old_course_id
,
location
,
published_usage
,
draft_usage
):
"""
"""
...
@@ -380,7 +380,7 @@ class LocMapperStore(object):
...
@@ -380,7 +380,7 @@ class LocMapperStore(object):
"""
"""
setmany
=
{}
setmany
=
{}
if
location
.
category
==
'course'
:
if
location
.
category
==
'course'
:
setmany
[
'courseId+{}'
.
format
(
published_usage
.
cours
e_id
)]
=
location
setmany
[
'courseId+{}'
.
format
(
published_usage
.
packag
e_id
)]
=
location
setmany
[
unicode
(
published_usage
)]
=
location
setmany
[
unicode
(
published_usage
)]
=
location
setmany
[
unicode
(
draft_usage
)]
=
location
setmany
[
unicode
(
draft_usage
)]
=
location
setmany
[
'{}+{}'
.
format
(
old_course_id
,
location
.
url
())]
=
(
published_usage
,
draft_usage
)
setmany
[
'{}+{}'
.
format
(
old_course_id
,
location
.
url
())]
=
(
published_usage
,
draft_usage
)
...
...
common/lib/xmodule/xmodule/modulestore/locator.py
View file @
f5f24fcc
...
@@ -12,7 +12,7 @@ from bson.errors import InvalidId
...
@@ -12,7 +12,7 @@ from bson.errors import InvalidId
from
xmodule.modulestore.exceptions
import
InsufficientSpecificationError
,
OverSpecificationError
from
xmodule.modulestore.exceptions
import
InsufficientSpecificationError
,
OverSpecificationError
from
.parsers
import
parse_url
,
parse_
cours
e_id
,
parse_block_ref
from
.parsers
import
parse_url
,
parse_
packag
e_id
,
parse_block_ref
from
.parsers
import
BRANCH_PREFIX
,
BLOCK_PREFIX
,
VERSION_PREFIX
from
.parsers
import
BRANCH_PREFIX
,
BLOCK_PREFIX
,
VERSION_PREFIX
import
re
import
re
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
...
@@ -149,15 +149,15 @@ class CourseLocator(Locator):
...
@@ -149,15 +149,15 @@ class CourseLocator(Locator):
"""
"""
Examples of valid CourseLocator specifications:
Examples of valid CourseLocator specifications:
CourseLocator(version_guid=ObjectId('519665f6223ebd6980884f2b'))
CourseLocator(version_guid=ObjectId('519665f6223ebd6980884f2b'))
CourseLocator(
cours
e_id='mit.eecs.6002x')
CourseLocator(
packag
e_id='mit.eecs.6002x')
CourseLocator(
cours
e_id='mit.eecs.6002x/branch/published')
CourseLocator(
packag
e_id='mit.eecs.6002x/branch/published')
CourseLocator(
cours
e_id='mit.eecs.6002x', branch='published')
CourseLocator(
packag
e_id='mit.eecs.6002x', branch='published')
CourseLocator(url='edx://version/519665f6223ebd6980884f2b')
CourseLocator(url='edx://version/519665f6223ebd6980884f2b')
CourseLocator(url='edx://mit.eecs.6002x')
CourseLocator(url='edx://mit.eecs.6002x')
CourseLocator(url='edx://mit.eecs.6002x/branch/published')
CourseLocator(url='edx://mit.eecs.6002x/branch/published')
CourseLocator(url='edx://mit.eecs.6002x/branch/published/version/519665f6223ebd6980884f2b')
CourseLocator(url='edx://mit.eecs.6002x/branch/published/version/519665f6223ebd6980884f2b')
Should have at lease a specific
cours
e_id (id for the course as if it were a project w/
Should have at lease a specific
packag
e_id (id for the course as if it were a project w/
versions) with optional 'branch',
versions) with optional 'branch',
or version_guid (which points to a specific version). Can contain both in which case
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
the persistence layer may raise exceptions if the given version != the current such version
...
@@ -166,47 +166,47 @@ class CourseLocator(Locator):
...
@@ -166,47 +166,47 @@ class CourseLocator(Locator):
# Default values
# Default values
version_guid
=
None
version_guid
=
None
cours
e_id
=
None
packag
e_id
=
None
branch
=
None
branch
=
None
def
__init__
(
self
,
url
=
None
,
version_guid
=
None
,
cours
e_id
=
None
,
branch
=
None
):
def
__init__
(
self
,
url
=
None
,
version_guid
=
None
,
packag
e_id
=
None
,
branch
=
None
):
"""
"""
Construct a CourseLocator
Construct a CourseLocator
Caller may provide url (but no other parameters).
Caller may provide url (but no other parameters).
Caller may provide version_guid (but no other parameters).
Caller may provide version_guid (but no other parameters).
Caller may provide
cours
e_id (optionally provide branch).
Caller may provide
packag
e_id (optionally provide branch).
Resulting CourseLocator will have either a version_guid property
Resulting CourseLocator will have either a version_guid property
or a
cours
e_id (with optional branch) property, or both.
or a
packag
e_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,
cours
e_id, and branch must be strings or None
url,
packag
e_id, and branch must be strings or None
"""
"""
self
.
_validate_args
(
url
,
version_guid
,
cours
e_id
)
self
.
_validate_args
(
url
,
version_guid
,
packag
e_id
)
if
url
:
if
url
:
self
.
init_from_url
(
url
)
self
.
init_from_url
(
url
)
if
version_guid
:
if
version_guid
:
self
.
init_from_version_guid
(
version_guid
)
self
.
init_from_version_guid
(
version_guid
)
if
cours
e_id
or
branch
:
if
packag
e_id
or
branch
:
self
.
init_from_
course_id
(
cours
e_id
,
branch
)
self
.
init_from_
package_id
(
packag
e_id
,
branch
)
if
self
.
version_guid
is
None
and
self
.
cours
e_id
is
None
:
if
self
.
version_guid
is
None
and
self
.
packag
e_id
is
None
:
raise
ValueError
(
"Either version_guid or
cours
e_id should be set: {}"
.
format
(
url
))
raise
ValueError
(
"Either version_guid or
packag
e_id should be set: {}"
.
format
(
url
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
"""
"""
Return a string representing this location.
Return a string representing this location.
"""
"""
if
self
.
cours
e_id
:
if
self
.
packag
e_id
:
result
=
self
.
cours
e_id
result
=
self
.
packag
e_id
if
self
.
branch
:
if
self
.
branch
:
result
+=
'/'
+
BRANCH_PREFIX
+
self
.
branch
result
+=
'/'
+
BRANCH_PREFIX
+
self
.
branch
return
result
return
result
elif
self
.
version_guid
:
elif
self
.
version_guid
:
return
VERSION_PREFIX
+
str
(
self
.
version_guid
)
return
VERSION_PREFIX
+
str
(
self
.
version_guid
)
else
:
else
:
# raise InsufficientSpecificationError("missing
cours
e_id or version_guid")
# raise InsufficientSpecificationError("missing
packag
e_id or version_guid")
return
'<InsufficientSpecificationError: missing
cours
e_id or version_guid>'
return
'<InsufficientSpecificationError: missing
packag
e_id or version_guid>'
def
url
(
self
):
def
url
(
self
):
"""
"""
...
@@ -214,29 +214,29 @@ class CourseLocator(Locator):
...
@@ -214,29 +214,29 @@ class CourseLocator(Locator):
"""
"""
return
'edx://'
+
unicode
(
self
)
return
'edx://'
+
unicode
(
self
)
def
_validate_args
(
self
,
url
,
version_guid
,
cours
e_id
):
def
_validate_args
(
self
,
url
,
version_guid
,
packag
e_id
):
"""
"""
Validate provided arguments. Internal use only which is why it checks for each
Validate provided arguments. Internal use only which is why it checks for each
arg and doesn't use keyword
arg and doesn't use keyword
"""
"""
if
not
any
((
url
,
version_guid
,
cours
e_id
)):
if
not
any
((
url
,
version_guid
,
packag
e_id
)):
raise
InsufficientSpecificationError
(
"Must provide one of url, version_guid,
cours
e_id"
)
raise
InsufficientSpecificationError
(
"Must provide one of url, version_guid,
packag
e_id"
)
def
is_fully_specified
(
self
):
def
is_fully_specified
(
self
):
"""
"""
Returns True if either version_guid is specified, or
cours
e_id+branch
Returns True if either version_guid is specified, or
packag
e_id+branch
are specified.
are specified.
This should always return True, since this should be validated in the constructor.
This should always return True, since this should be validated in the constructor.
"""
"""
return
(
self
.
version_guid
is
not
None
or
return
(
self
.
version_guid
is
not
None
or
(
self
.
cours
e_id
is
not
None
and
self
.
branch
is
not
None
))
(
self
.
packag
e_id
is
not
None
and
self
.
branch
is
not
None
))
def
set_
cours
e_id
(
self
,
new
):
def
set_
packag
e_id
(
self
,
new
):
"""
"""
Initialize
cours
e_id to new value.
Initialize
packag
e_id to new value.
If
cours
e_id has already been initialized to a different value, raise an exception.
If
packag
e_id has already been initialized to a different value, raise an exception.
"""
"""
self
.
set_property
(
'
cours
e_id'
,
new
)
self
.
set_property
(
'
packag
e_id'
,
new
)
def
set_branch
(
self
,
new
):
def
set_branch
(
self
,
new
):
"""
"""
...
@@ -259,7 +259,7 @@ class CourseLocator(Locator):
...
@@ -259,7 +259,7 @@ class CourseLocator(Locator):
The copy does not include subclass information, such as
The copy does not include subclass information, such as
a block_id (a property of BlockUsageLocator).
a block_id (a property of BlockUsageLocator).
"""
"""
return
CourseLocator
(
course_id
=
self
.
cours
e_id
,
return
CourseLocator
(
package_id
=
self
.
packag
e_id
,
version_guid
=
self
.
version_guid
,
version_guid
=
self
.
version_guid
,
branch
=
self
.
branch
)
branch
=
self
.
branch
)
...
@@ -285,7 +285,7 @@ class CourseLocator(Locator):
...
@@ -285,7 +285,7 @@ class CourseLocator(Locator):
def
init_from_url
(
self
,
url
):
def
init_from_url
(
self
,
url
):
"""
"""
url must be a string beginning with 'edx://' and containing
url must be a string beginning with 'edx://' and containing
either a valid version_guid or
cours
e_id (with optional branch), or both.
either a valid version_guid or
packag
e_id (with optional branch), or both.
"""
"""
if
isinstance
(
url
,
Locator
):
if
isinstance
(
url
,
Locator
):
parse
=
url
.
__dict__
parse
=
url
.
__dict__
...
@@ -298,7 +298,7 @@ class CourseLocator(Locator):
...
@@ -298,7 +298,7 @@ class CourseLocator(Locator):
self
.
_set_value
(
self
.
_set_value
(
parse
,
'version_guid'
,
lambda
(
new_guid
):
self
.
set_version_guid
(
self
.
as_object_id
(
new_guid
))
parse
,
'version_guid'
,
lambda
(
new_guid
):
self
.
set_version_guid
(
self
.
as_object_id
(
new_guid
))
)
)
self
.
_set_value
(
parse
,
'
course_id'
,
self
.
set_cours
e_id
)
self
.
_set_value
(
parse
,
'
package_id'
,
self
.
set_packag
e_id
)
self
.
_set_value
(
parse
,
'branch'
,
self
.
set_branch
)
self
.
_set_value
(
parse
,
'branch'
,
self
.
set_branch
)
def
init_from_version_guid
(
self
,
version_guid
):
def
init_from_version_guid
(
self
,
version_guid
):
...
@@ -313,29 +313,29 @@ class CourseLocator(Locator):
...
@@ -313,29 +313,29 @@ class CourseLocator(Locator):
raise
TypeError
(
'
%
s is not an instance of ObjectId'
%
version_guid
)
raise
TypeError
(
'
%
s is not an instance of ObjectId'
%
version_guid
)
self
.
set_version_guid
(
version_guid
)
self
.
set_version_guid
(
version_guid
)
def
init_from_
course_id
(
self
,
cours
e_id
,
explicit_branch
=
None
):
def
init_from_
package_id
(
self
,
packag
e_id
,
explicit_branch
=
None
):
"""
"""
Cours
e_id is a CourseLocator or a string like 'mit.eecs.6002x' or 'mit.eecs.6002x/branch/published'.
packag
e_id is a CourseLocator or a string like 'mit.eecs.6002x' or 'mit.eecs.6002x/branch/published'.
Revision (optional) is a string like 'published'.
Revision (optional) is a string like 'published'.
It may be provided explicitly (explicit_branch) or embedded into
cours
e_id.
It may be provided explicitly (explicit_branch) or embedded into
packag
e_id.
If branch is part of
cours
e_id (".../branch/published"), parse it out separately.
If branch is part of
packag
e_id (".../branch/published"), parse it out separately.
If branch is provided both ways, that's ok as long as they are the same value.
If branch is provided both ways, that's ok as long as they are the same value.
If a block ('/block/HW3') is a part of
cours
e_id, it is ignored.
If a block ('/block/HW3') is a part of
packag
e_id, it is ignored.
"""
"""
if
cours
e_id
:
if
packag
e_id
:
if
isinstance
(
cours
e_id
,
CourseLocator
):
if
isinstance
(
packag
e_id
,
CourseLocator
):
course_id
=
course_id
.
cours
e_id
package_id
=
package_id
.
packag
e_id
if
not
cours
e_id
:
if
not
packag
e_id
:
raise
ValueError
(
"
%
s does not have a valid
course_id"
%
cours
e_id
)
raise
ValueError
(
"
%
s does not have a valid
package_id"
%
packag
e_id
)
parse
=
parse_
course_id
(
cours
e_id
)
parse
=
parse_
package_id
(
packag
e_id
)
if
not
parse
or
parse
[
'
cours
e_id'
]
is
None
:
if
not
parse
or
parse
[
'
packag
e_id'
]
is
None
:
raise
ValueError
(
'Could not parse "
%
s" as a
course_id'
%
cours
e_id
)
raise
ValueError
(
'Could not parse "
%
s" as a
package_id'
%
packag
e_id
)
self
.
set_
course_id
(
parse
[
'cours
e_id'
])
self
.
set_
package_id
(
parse
[
'packag
e_id'
])
rev
=
parse
[
'branch'
]
rev
=
parse
[
'branch'
]
if
rev
:
if
rev
:
self
.
set_branch
(
rev
)
self
.
set_branch
(
rev
)
...
@@ -357,7 +357,7 @@ class CourseLocator(Locator):
...
@@ -357,7 +357,7 @@ class CourseLocator(Locator):
the name although that's mutable. We should also clearly define the purpose and restrictions of this
the name although that's mutable. We should also clearly define the purpose and restrictions of this
(e.g., I'm assuming periods are fine).
(e.g., I'm assuming periods are fine).
"""
"""
return
self
.
cours
e_id
return
self
.
packag
e_id
def
_set_value
(
self
,
parse
,
key
,
setter
):
def
_set_value
(
self
,
parse
,
key
,
setter
):
"""
"""
...
@@ -379,12 +379,12 @@ class BlockUsageLocator(CourseLocator):
...
@@ -379,12 +379,12 @@ class BlockUsageLocator(CourseLocator):
the defined element in the course. Courses can be a version of an offering, the
the defined element in the course. Courses can be a version of an offering, the
current draft head, or the current production version.
current draft head, or the current production version.
Locators can contain both a version and a
cours
e_id w/ branch. The split mongo functions
Locators can contain both a version and a
packag
e_id w/ branch. The split mongo functions
may raise errors if these conflict w/ the current db state (i.e., the course's branch !=
may raise errors if these conflict w/ the current db state (i.e., the course's branch !=
the version_guid)
the version_guid)
Locations can express as urls as well as dictionaries. They consist of
Locations can express as urls as well as dictionaries. They consist of
cours
e_identifier: course_guid | version_guid
packag
e_identifier: course_guid | version_guid
block : guid
block : guid
branch : string
branch : string
"""
"""
...
@@ -392,34 +392,34 @@ class BlockUsageLocator(CourseLocator):
...
@@ -392,34 +392,34 @@ class BlockUsageLocator(CourseLocator):
# Default value
# Default value
block_id
=
None
block_id
=
None
def
__init__
(
self
,
url
=
None
,
version_guid
=
None
,
cours
e_id
=
None
,
def
__init__
(
self
,
url
=
None
,
version_guid
=
None
,
packag
e_id
=
None
,
branch
=
None
,
block_id
=
None
):
branch
=
None
,
block_id
=
None
):
"""
"""
Construct a BlockUsageLocator
Construct a BlockUsageLocator
Caller may provide url, version_guid, or
cours
e_id, and optionally provide branch.
Caller may provide url, version_guid, or
packag
e_id, and optionally provide branch.
The block_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
cours
e_id. If omitted, the locator is created but it
the url or
packag
e_id. If omitted, the locator is created but it
has not yet been initialized.
has not yet been initialized.
Resulting BlockUsageLocator will have a block_id property.
Resulting BlockUsageLocator will have a block_id property.
It will have either a version_guid property or a
cours
e_id (with optional branch) property, or both.
It will have either a version_guid property or a
packag
e_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,
cours
e_id, branch, and block_id must be strings or None
url,
packag
e_id, branch, and block_id must be strings or None
"""
"""
self
.
_validate_args
(
url
,
version_guid
,
cours
e_id
)
self
.
_validate_args
(
url
,
version_guid
,
packag
e_id
)
if
url
:
if
url
:
self
.
init_block_ref_from_str
(
url
)
self
.
init_block_ref_from_str
(
url
)
if
cours
e_id
:
if
packag
e_id
:
self
.
init_block_ref_from_
course_id
(
cours
e_id
)
self
.
init_block_ref_from_
package_id
(
packag
e_id
)
if
block_id
:
if
block_id
:
self
.
init_block_ref
(
block_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
,
course_id
=
cours
e_id
,
package_id
=
packag
e_id
,
branch
=
branch
branch
=
branch
)
)
...
@@ -432,7 +432,7 @@ class BlockUsageLocator(CourseLocator):
...
@@ -432,7 +432,7 @@ class BlockUsageLocator(CourseLocator):
def
version_agnostic
(
self
):
def
version_agnostic
(
self
):
"""
"""
Returns a copy of itself.
Returns a copy of itself.
If both version_guid and
course_id are known, use a blank cours
e_id in the copy.
If both version_guid and
package_id are known, use a blank packag
e_id in the copy.
We don't care if the locator's version is not the current head; so, avoid version conflict
We don't care if the locator's version is not the current head; so, avoid version conflict
by reducing info.
by reducing info.
...
@@ -444,7 +444,7 @@ class BlockUsageLocator(CourseLocator):
...
@@ -444,7 +444,7 @@ class BlockUsageLocator(CourseLocator):
branch
=
self
.
branch
,
branch
=
self
.
branch
,
block_id
=
self
.
block_id
)
block_id
=
self
.
block_id
)
else
:
else
:
return
BlockUsageLocator
(
course_id
=
self
.
cours
e_id
,
return
BlockUsageLocator
(
package_id
=
self
.
packag
e_id
,
branch
=
self
.
branch
,
branch
=
self
.
branch
,
block_id
=
self
.
block_id
)
block_id
=
self
.
block_id
)
...
@@ -478,13 +478,13 @@ class BlockUsageLocator(CourseLocator):
...
@@ -478,13 +478,13 @@ class BlockUsageLocator(CourseLocator):
raise
ValueError
(
'Could not parse "
%
s" as a url'
%
value
)
raise
ValueError
(
'Could not parse "
%
s" as a url'
%
value
)
self
.
_set_value
(
parse
,
'block'
,
self
.
set_block_id
)
self
.
_set_value
(
parse
,
'block'
,
self
.
set_block_id
)
def
init_block_ref_from_
course_id
(
self
,
cours
e_id
):
def
init_block_ref_from_
package_id
(
self
,
packag
e_id
):
if
isinstance
(
cours
e_id
,
CourseLocator
):
if
isinstance
(
packag
e_id
,
CourseLocator
):
course_id
=
course_id
.
cours
e_id
package_id
=
package_id
.
packag
e_id
assert
course_id
,
"
%
s does not have a valid cours
e_id"
assert
package_id
,
"
%
s does not have a valid packag
e_id"
parse
=
parse_
course_id
(
cours
e_id
)
parse
=
parse_
package_id
(
packag
e_id
)
if
parse
is
None
:
if
parse
is
None
:
raise
ValueError
(
'Could not parse "
%
s" as a
course_id'
%
cours
e_id
)
raise
ValueError
(
'Could not parse "
%
s" as a
package_id'
%
packag
e_id
)
self
.
_set_value
(
parse
,
'block'
,
self
.
set_block_id
)
self
.
_set_value
(
parse
,
'block'
,
self
.
set_block_id
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
...
...
common/lib/xmodule/xmodule/modulestore/parsers.py
View file @
f5f24fcc
...
@@ -11,7 +11,7 @@ ALLOWED_ID_CHARS = r'[a-zA-Z0-9_\-~.:]'
...
@@ -11,7 +11,7 @@ ALLOWED_ID_CHARS = r'[a-zA-Z0-9_\-~.:]'
URL_RE_SOURCE
=
r"""
URL_RE_SOURCE
=
r"""
(?P<tag>edx://)?
(?P<tag>edx://)?
((?P<
cours
e_id>{ALLOWED_ID_CHARS}+)/?)?
((?P<
packag
e_id>{ALLOWED_ID_CHARS}+)/?)?
({BRANCH_PREFIX}(?P<branch>{ALLOWED_ID_CHARS}+)/?)?
({BRANCH_PREFIX}(?P<branch>{ALLOWED_ID_CHARS}+)/?)?
({VERSION_PREFIX}(?P<version_guid>[A-F0-9]+)/?)?
({VERSION_PREFIX}(?P<version_guid>[A-F0-9]+)/?)?
({BLOCK_PREFIX}(?P<block>{ALLOWED_ID_CHARS}+))?
({BLOCK_PREFIX}(?P<block>{ALLOWED_ID_CHARS}+))?
...
@@ -26,7 +26,7 @@ URL_RE = re.compile('^' + URL_RE_SOURCE + '$', re.IGNORECASE | re.VERBOSE)
...
@@ -26,7 +26,7 @@ URL_RE = re.compile('^' + URL_RE_SOURCE + '$', re.IGNORECASE | re.VERBOSE)
def
parse_url
(
string
,
tag_optional
=
False
):
def
parse_url
(
string
,
tag_optional
=
False
):
"""
"""
A url usually begins with 'edx://' (case-insensitive match),
A url usually begins with 'edx://' (case-insensitive match),
followed by either a version_guid or a
cours
e_id. If tag_optional, then
followed by either a version_guid or a
packag
e_id. If tag_optional, then
the url does not have to start with the tag and edx will be assumed.
the url does not have to start with the tag and edx will be assumed.
Examples:
Examples:
...
@@ -38,10 +38,10 @@ def parse_url(string, tag_optional=False):
...
@@ -38,10 +38,10 @@ def parse_url(string, tag_optional=False):
This returns None if string cannot be parsed.
This returns None if string cannot be parsed.
If it can be parsed as a version_guid with no preceding
cours
e_id, returns a dict
If it can be parsed as a version_guid with no preceding
packag
e_id, returns a dict
with key 'version_guid' and the value,
with key 'version_guid' and the value,
If it can be parsed as a
cours
e_id, returns a dict
If it can be parsed as a
packag
e_id, returns a dict
with key 'id' and optional keys 'branch' and 'version_guid'.
with key 'id' and optional keys 'branch' and 'version_guid'.
"""
"""
...
@@ -69,15 +69,15 @@ def parse_block_ref(string):
...
@@ -69,15 +69,15 @@ def parse_block_ref(string):
return
None
return
None
def
parse_
cours
e_id
(
string
):
def
parse_
packag
e_id
(
string
):
r"""
r"""
A
cours
e_id has a main id component.
A
packag
e_id has a main id component.
There may also be an optional branch (/branch/published or /branch/draft).
There may also be an optional branch (/branch/published or /branch/draft).
There may also be an optional version (/version/519665f6223ebd6980884f2b).
There may also be an optional version (/version/519665f6223ebd6980884f2b).
There may also be an optional block (/block/HW3 or /block/Quiz2).
There may also be an optional block (/block/HW3 or /block/Quiz2).
Examples of valid
cours
e_ids:
Examples of valid
packag
e_ids:
'mit.eecs.6002x'
'mit.eecs.6002x'
'mit.eecs.6002x/branch/published'
'mit.eecs.6002x/branch/published'
...
@@ -88,7 +88,7 @@ def parse_course_id(string):
...
@@ -88,7 +88,7 @@ def parse_course_id(string):
Syntax:
Syntax:
cours
e_id = main_id [/branch/ branch] [/version/ version ] [/block/ block]
packag
e_id = main_id [/branch/ branch] [/version/ version ] [/block/ block]
main_id = name [. name]*
main_id = name [. name]*
...
@@ -98,7 +98,7 @@ def parse_course_id(string):
...
@@ -98,7 +98,7 @@ def parse_course_id(string):
name = ALLOWED_ID_CHARS
name = ALLOWED_ID_CHARS
If string is a
cours
e_id, returns a dict with keys 'id', 'branch', and 'block'.
If string is a
packag
e_id, returns a dict with keys 'id', 'branch', and 'block'.
Revision is optional: if missing returned_dict['branch'] is None.
Revision is optional: if missing returned_dict['branch'] is None.
Block is optional: if missing returned_dict['block'] is None.
Block is optional: if missing returned_dict['block'] is None.
Else returns None.
Else returns None.
...
...
common/lib/xmodule/xmodule/modulestore/split_migrator.py
View file @
f5f24fcc
...
@@ -23,41 +23,41 @@ class SplitMigrator(object):
...
@@ -23,41 +23,41 @@ class SplitMigrator(object):
self
.
draft_modulestore
=
draft_modulestore
self
.
draft_modulestore
=
draft_modulestore
self
.
loc_mapper
=
loc_mapper
self
.
loc_mapper
=
loc_mapper
def
migrate_mongo_course
(
self
,
course_location
,
user_id
,
new_
cours
e_id
=
None
):
def
migrate_mongo_course
(
self
,
course_location
,
user_id
,
new_
packag
e_id
=
None
):
"""
"""
Create a new course in split_mongo representing the published and draft versions of the course from the
Create a new course in split_mongo representing the published and draft versions of the course from the
original mongo store. And return the new_
cours
e_id (which the caller can also get by calling
original mongo store. And return the new_
packag
e_id (which the caller can also get by calling
self.loc_mapper.translate_location(old_course_location)
self.loc_mapper.translate_location(old_course_location)
If the new course already exists, this raises DuplicateItemError
If the new course already exists, this raises DuplicateItemError
:param course_location: a Location whose category is 'course' and points to the course
:param course_location: a Location whose category is 'course' and points to the course
:param user_id: the user whose action is causing this migration
:param user_id: the user whose action is causing this migration
:param new_
course_id: (optional) the Locator.cours
e_id for the new course. Defaults to
:param new_
package_id: (optional) the Locator.packag
e_id for the new course. Defaults to
whatever translate_location_to_locator returns
whatever translate_location_to_locator returns
"""
"""
new_
course_id
=
self
.
loc_mapper
.
create_map_entry
(
course_location
,
course_id
=
new_cours
e_id
)
new_
package_id
=
self
.
loc_mapper
.
create_map_entry
(
course_location
,
package_id
=
new_packag
e_id
)
old_course_id
=
course_location
.
course_id
old_course_id
=
course_location
.
course_id
# the only difference in data between the old and split_mongo xblocks are the locations;
# the only difference in data between the old and split_mongo xblocks are the locations;
# so, any field which holds a location must change to a Locator; otherwise, the persistence
# so, any field which holds a location must change to a Locator; otherwise, the persistence
# layer and kvs's know how to store it.
# layer and kvs's know how to store it.
# locations are in location, children, conditionals, course.tab
# locations are in location, children, conditionals, course.tab
# create the course: set fields to explicitly_set for each scope, id_root = new_
cours
e_id, master_branch = 'production'
# create the course: set fields to explicitly_set for each scope, id_root = new_
packag
e_id, master_branch = 'production'
original_course
=
self
.
direct_modulestore
.
get_item
(
course_location
)
original_course
=
self
.
direct_modulestore
.
get_item
(
course_location
)
new_course_root_locator
=
self
.
loc_mapper
.
translate_location
(
old_course_id
,
course_location
)
new_course_root_locator
=
self
.
loc_mapper
.
translate_location
(
old_course_id
,
course_location
)
new_course
=
self
.
split_modulestore
.
create_course
(
new_course
=
self
.
split_modulestore
.
create_course
(
course_location
.
org
,
original_course
.
display_name
,
course_location
.
org
,
original_course
.
display_name
,
user_id
,
id_root
=
new_
cours
e_id
,
user_id
,
id_root
=
new_
packag
e_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_block_id
=
new_course_root_locator
.
block_id
,
root_block_id
=
new_course_root_locator
.
block_id
,
master_branch
=
new_course_root_locator
.
branch
master_branch
=
new_course_root_locator
.
branch
)
)
self
.
_copy_published_modules_to_course
(
new_course
,
course_location
,
old_course_id
,
user_id
)
self
.
_copy_published_modules_to_course
(
new_course
,
course_location
,
old_course_id
,
user_id
)
self
.
_add_draft_modules_to_course
(
new_
cours
e_id
,
old_course_id
,
course_location
,
user_id
)
self
.
_add_draft_modules_to_course
(
new_
packag
e_id
,
old_course_id
,
course_location
,
user_id
)
return
new_
cours
e_id
return
new_
packag
e_id
def
_copy_published_modules_to_course
(
self
,
new_course
,
old_course_loc
,
old_course_id
,
user_id
):
def
_copy_published_modules_to_course
(
self
,
new_course
,
old_course_loc
,
old_course_id
,
user_id
):
"""
"""
...
@@ -94,13 +94,13 @@ class SplitMigrator(object):
...
@@ -94,13 +94,13 @@ class SplitMigrator(object):
# children which meant some pointers were to non-existent locations in 'direct'
# children which meant some pointers were to non-existent locations in 'direct'
self
.
split_modulestore
.
internal_clean_children
(
course_version_locator
)
self
.
split_modulestore
.
internal_clean_children
(
course_version_locator
)
def
_add_draft_modules_to_course
(
self
,
new_
cours
e_id
,
old_course_id
,
old_course_loc
,
user_id
):
def
_add_draft_modules_to_course
(
self
,
new_
packag
e_id
,
old_course_id
,
old_course_loc
,
user_id
):
"""
"""
update each draft. Create any which don't exist in published and attach to their parents.
update each draft. Create any which don't exist in published and attach to their parents.
"""
"""
# each true update below will trigger a new version of the structure. We may want to just have one new version
# each true update below will trigger a new version of the structure. We may want to just have one new version
# but that's for a later date.
# but that's for a later date.
new_draft_course_loc
=
CourseLocator
(
course_id
=
new_cours
e_id
,
branch
=
'draft'
)
new_draft_course_loc
=
CourseLocator
(
package_id
=
new_packag
e_id
,
branch
=
'draft'
)
# to prevent race conditions of grandchilden being added before their parents and thus having no parent to
# to prevent race conditions of grandchilden being added before their parents and thus having no parent to
# add to
# add to
awaiting_adoption
=
{}
awaiting_adoption
=
{}
...
@@ -112,7 +112,7 @@ class SplitMigrator(object):
...
@@ -112,7 +112,7 @@ class SplitMigrator(object):
new_locator
=
self
.
loc_mapper
.
translate_location
(
new_locator
=
self
.
loc_mapper
.
translate_location
(
old_course_id
,
module
.
location
,
False
,
add_entry_if_missing
=
True
old_course_id
,
module
.
location
,
False
,
add_entry_if_missing
=
True
)
)
if
self
.
split_modulestore
.
has_item
(
new_
cours
e_id
,
new_locator
):
if
self
.
split_modulestore
.
has_item
(
new_
packag
e_id
,
new_locator
):
# was in 'direct' so draft is a new version
# was in 'direct' so draft is a new version
split_module
=
self
.
split_modulestore
.
get_item
(
new_locator
)
split_module
=
self
.
split_modulestore
.
get_item
(
new_locator
)
# need to remove any no-longer-explicitly-set values and add/update any now set values.
# need to remove any no-longer-explicitly-set values and add/update any now set values.
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py
View file @
f5f24fcc
...
@@ -27,9 +27,9 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -27,9 +27,9 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
modulestore: the module store that can be used to retrieve additional
modulestore: the module store that can be used to retrieve additional
modules
modules
course_entry: the originally fetched enveloped course_structure w/ branch and
cours
e_id info.
course_entry: the originally fetched enveloped course_structure w/ branch and
packag
e_id info.
Callers to _load_item provide an override but that function ignores the provided structure and
Callers to _load_item provide an override but that function ignores the provided structure and
only looks at the branch and
cours
e_id
only looks at the branch and
packag
e_id
module_data: a dict mapping Location -> json that was cached from the
module_data: a dict mapping Location -> json that was cached from the
underlying modulestore
underlying modulestore
...
@@ -78,14 +78,14 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -78,14 +78,14 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
# the thread is working with more than one named container pointing to the same specific structure is
# the thread is working with more than one named container pointing to the same specific structure is
# 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/
cours
e_id.
# is the intended one when not given a course_entry_override; thus, the caching of the last branch/
packag
e_id.
def
xblock_from_json
(
self
,
class_
,
block_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
:
# most recent retrieval is most likely the right one for next caller (see comment above fn)
# most recent retrieval is most likely the right one for next caller (see comment above fn)
self
.
course_entry
[
'branch'
]
=
course_entry_override
[
'branch'
]
self
.
course_entry
[
'branch'
]
=
course_entry_override
[
'branch'
]
self
.
course_entry
[
'
course_id'
]
=
course_entry_override
[
'cours
e_id'
]
self
.
course_entry
[
'
package_id'
]
=
course_entry_override
[
'packag
e_id'
]
# most likely a lazy loader or the id directly
# most likely a lazy loader or the id directly
definition
=
json_data
.
get
(
'definition'
,
{})
definition
=
json_data
.
get
(
'definition'
,
{})
definition_id
=
self
.
modulestore
.
definition_locator
(
definition
)
definition_id
=
self
.
modulestore
.
definition_locator
(
definition
)
...
@@ -97,7 +97,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -97,7 +97,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
block_locator
=
BlockUsageLocator
(
block_locator
=
BlockUsageLocator
(
version_guid
=
course_entry_override
[
'structure'
][
'_id'
],
version_guid
=
course_entry_override
[
'structure'
][
'_id'
],
block_id
=
block_id
,
block_id
=
block_id
,
course_id
=
course_entry_override
.
get
(
'cours
e_id'
),
package_id
=
course_entry_override
.
get
(
'packag
e_id'
),
branch
=
course_entry_override
.
get
(
'branch'
)
branch
=
course_entry_override
.
get
(
'branch'
)
)
)
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
f5f24fcc
...
@@ -3,7 +3,7 @@ Provides full versioning CRUD and representation for collections of xblocks (e.g
...
@@ -3,7 +3,7 @@ Provides full versioning CRUD and representation for collections of xblocks (e.g
Representation:
Representation:
* course_index: a dictionary:
* course_index: a dictionary:
** '_id':
cours
e_id (e.g., myu.mydept.mycourse.myrun),
** '_id':
packag
e_id (e.g., myu.mydept.mycourse.myrun),
** 'org': the org's id. Only used for searching not identity,
** 'org': the org's id. Only used for searching not identity,
** 'prettyid': a vague to-be-determined field probably more useful to storing searchable tags,
** 'prettyid': a vague to-be-determined field probably more useful to storing searchable tags,
** 'edited_by': user_id of user who created the original entry,
** 'edited_by': user_id of user who created the original entry,
...
@@ -227,7 +227,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -227,7 +227,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return the CourseDescriptor! It returns the actual db json from
return the CourseDescriptor! It returns the actual db json from
structures.
structures.
Semantics: if
cours
e_id and branch given, then it will get that branch. If
Semantics: if
packag
e_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
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
it raises VersionConflictError (the version now differs from what it was when you got your
reference)
reference)
...
@@ -239,9 +239,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -239,9 +239,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
if
not
course_locator
.
is_fully_specified
():
if
not
course_locator
.
is_fully_specified
():
raise
InsufficientSpecificationError
(
'Not fully specified:
%
s'
%
course_locator
)
raise
InsufficientSpecificationError
(
'Not fully specified:
%
s'
%
course_locator
)
if
course_locator
.
cours
e_id
is
not
None
and
course_locator
.
branch
is
not
None
:
if
course_locator
.
packag
e_id
is
not
None
and
course_locator
.
branch
is
not
None
:
# use the
cours
e_id
# use the
packag
e_id
index
=
self
.
db_connection
.
get_course_index
(
course_locator
.
cours
e_id
)
index
=
self
.
db_connection
.
get_course_index
(
course_locator
.
packag
e_id
)
if
index
is
None
:
if
index
is
None
:
raise
ItemNotFoundError
(
course_locator
)
raise
ItemNotFoundError
(
course_locator
)
if
course_locator
.
branch
not
in
index
[
'versions'
]:
if
course_locator
.
branch
not
in
index
[
'versions'
]:
...
@@ -258,11 +258,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -258,11 +258,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
version_guid
=
course_locator
.
as_object_id
(
version_guid
)
version_guid
=
course_locator
.
as_object_id
(
version_guid
)
entry
=
self
.
db_connection
.
get_structure
(
version_guid
)
entry
=
self
.
db_connection
.
get_structure
(
version_guid
)
# b/c more than one course can use same structure, the '
cours
e_id' and 'branch' are not intrinsic to structure
# b/c more than one course can use same structure, the '
packag
e_id' and 'branch' are not intrinsic to structure
# and the one assoc'd w/ it by another fetch may not be the one relevant to this fetch; so,
# and the one assoc'd w/ it by another fetch may not be the one relevant to this fetch; so,
# add it in the envelope for the structure.
# add it in the envelope for the structure.
envelope
=
{
envelope
=
{
'
course_id'
:
course_locator
.
cours
e_id
,
'
package_id'
:
course_locator
.
packag
e_id
,
'branch'
:
course_locator
.
branch
,
'branch'
:
course_locator
.
branch
,
'structure'
:
entry
,
'structure'
:
entry
,
}
}
...
@@ -300,7 +300,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -300,7 +300,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
result
=
[]
result
=
[]
for
entry
in
course_entries
:
for
entry
in
course_entries
:
envelope
=
{
envelope
=
{
'
cours
e_id'
:
id_version_map
[
entry
[
'_id'
]],
'
packag
e_id'
:
id_version_map
[
entry
[
'_id'
]],
'branch'
:
branch
,
'branch'
:
branch
,
'structure'
:
entry
,
'structure'
:
entry
,
}
}
...
@@ -327,7 +327,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -327,7 +327,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
'''
'''
return
self
.
get_course
(
location
)
return
self
.
get_course
(
location
)
def
has_item
(
self
,
cours
e_id
,
block_location
):
def
has_item
(
self
,
packag
e_id
,
block_location
):
"""
"""
Returns True if location exists in its course. Returns false if
Returns True if location exists in its course. Returns false if
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.
...
@@ -433,13 +433,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -433,13 +433,13 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return
[
BlockUsageLocator
(
url
=
locator
.
as_course_locator
(),
block_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
,
cours
e_id
,
detached_categories
,
branch
):
def
get_orphans
(
self
,
packag
e_id
,
detached_categories
,
branch
):
"""
"""
Return a dict of all of the orphans in the course.
Return a dict of all of the orphans in the course.
:param
cours
e_id:
:param
packag
e_id:
"""
"""
course
=
self
.
_lookup_course
(
CourseLocator
(
course_id
=
cours
e_id
,
branch
=
branch
))
course
=
self
.
_lookup_course
(
CourseLocator
(
package_id
=
packag
e_id
,
branch
=
branch
))
items
=
set
(
course
[
'structure'
][
'blocks'
]
.
keys
())
items
=
set
(
course
[
'structure'
][
'blocks'
]
.
keys
())
items
.
remove
(
course
[
'structure'
][
'root'
])
items
.
remove
(
course
[
'structure'
][
'root'
])
for
block_id
,
block_data
in
course
[
'structure'
][
'blocks'
]
.
iteritems
():
for
block_id
,
block_data
in
course
[
'structure'
][
'blocks'
]
.
iteritems
():
...
@@ -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
=
cours
e_id
,
branch
=
branch
,
block_id
=
block_id
)
BlockUsageLocator
(
package_id
=
packag
e_id
,
branch
=
branch
,
block_id
=
block_id
)
for
block_id
in
items
for
block_id
in
items
]
]
...
@@ -456,7 +456,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -456,7 +456,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
The index records the initial creation of the indexed course and tracks the current version
The index records the initial creation of the indexed course and tracks the current version
heads. This function is primarily for test verification but may serve some
heads. This function is primarily for test verification but may serve some
more general purpose.
more general purpose.
:param course_locator: must have a
cours
e_id set
:param course_locator: must have a
packag
e_id set
:return {'org': , 'prettyid': ,
:return {'org': , 'prettyid': ,
versions: {'draft': the head draft version id,
versions: {'draft': the head draft version id,
'published': the head published version id if any,
'published': the head published version id if any,
...
@@ -465,9 +465,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -465,9 +465,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
'edited_on': when the course was originally created
'edited_on': when the course was originally created
}
}
"""
"""
if
course_locator
.
cours
e_id
is
None
:
if
course_locator
.
packag
e_id
is
None
:
return
None
return
None
index
=
self
.
db_connection
.
get_course_index
(
course_locator
.
cours
e_id
)
index
=
self
.
db_connection
.
get_course_index
(
course_locator
.
packag
e_id
)
return
index
return
index
# TODO figure out a way to make this info accessible from the course descriptor
# TODO figure out a way to make this info accessible from the course descriptor
...
@@ -662,7 +662,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -662,7 +662,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
serial
+=
1
serial
+=
1
return
category
+
str
(
serial
)
return
category
+
str
(
serial
)
def
_generate_
cours
e_id
(
self
,
id_root
):
def
_generate_
packag
e_id
(
self
,
id_root
):
"""
"""
Generate a somewhat readable course id unique w/in this db using the id_root
Generate a somewhat readable course id unique w/in this db using the id_root
:param course_blocks: the current list of blocks.
:param course_blocks: the current list of blocks.
...
@@ -699,7 +699,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -699,7 +699,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
merely the containing course.
merely the containing course.
raises InsufficientSpecificationError if there is no course locator.
raises InsufficientSpecificationError if there is no course locator.
raises VersionConflictError if
cours
e_id and version_guid given and the current version head != version_guid
raises VersionConflictError if
packag
e_id and version_guid given and the current version head != version_guid
and force is not True.
and force is not True.
:param force: fork the structure and don't update the course draftVersion if the above
:param force: fork the structure and don't update the course draftVersion if the above
:param continue_revision: for multistep transactions, continue revising the given version rather than creating
:param continue_revision: for multistep transactions, continue revising the given version rather than creating
...
@@ -724,11 +724,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -724,11 +724,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
Rules for course locator:
Rules for course locator:
* If the course locator specifies a
cours
e_id and either it doesn't
* If the course locator specifies a
packag
e_id and either it doesn't
specify version_guid or the one it specifies == the current head of the branch,
specify version_guid or the one it specifies == the current head of the branch,
it progresses the course to point
it progresses the course to point
to the new head and sets the active version to point to the new head
to the new head and sets the active version to point to the new head
* If the locator has a
cours
e_id but its version_guid != current head, it raises VersionConflictError.
* If the locator has a
packag
e_id but its version_guid != current head, it raises VersionConflictError.
NOTE: using a version_guid will end up creating a new version of the course. Your new item won't be in
NOTE: using a version_guid will end up creating a new version of the course. Your new item won't be in
the course id'd by version_guid but instead in one w/ a new version_guid. Ensure in this case that you get
the course id'd by version_guid but instead in one w/ a new version_guid. Ensure in this case that you get
...
@@ -805,7 +805,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -805,7 +805,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
course_parent
=
None
course_parent
=
None
# reconstruct the new_item from the cache
# reconstruct the new_item from the cache
return
self
.
get_item
(
BlockUsageLocator
(
cours
e_id
=
course_parent
,
return
self
.
get_item
(
BlockUsageLocator
(
packag
e_id
=
course_parent
,
block_id
=
new_block_id
,
block_id
=
new_block_id
,
version_guid
=
new_id
))
version_guid
=
new_id
))
...
@@ -818,7 +818,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -818,7 +818,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
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
the course root of the resulting entry (the location has the course id)
the course root of the resulting entry (the location has the course id)
id_root: allows the caller to specify the
cours
e_id. It's a root in that, if it's already taken,
id_root: allows the caller to specify the
packag
e_id. It's a root in that, if it's already taken,
this method will append things to the root to make it unique. (defaults to org)
this method will append things to the root to make it unique. (defaults to org)
fields: if scope.settings fields provided, will set the fields of the root course object in the
fields: if scope.settings fields provided, will set the fields of the root course object in the
...
@@ -911,7 +911,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -911,7 +911,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# create the index entry
# create the index entry
if
id_root
is
None
:
if
id_root
is
None
:
id_root
=
org
id_root
=
org
new_id
=
self
.
_generate_
cours
e_id
(
id_root
)
new_id
=
self
.
_generate_
packag
e_id
(
id_root
)
index_entry
=
{
index_entry
=
{
'_id'
:
new_id
,
'_id'
:
new_id
,
...
@@ -921,7 +921,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -921,7 +921,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
'edited_on'
:
datetime
.
datetime
.
now
(
UTC
),
'edited_on'
:
datetime
.
datetime
.
now
(
UTC
),
'versions'
:
versions_dict
}
'versions'
:
versions_dict
}
self
.
db_connection
.
insert_course_index
(
index_entry
)
self
.
db_connection
.
insert_course_index
(
index_entry
)
return
self
.
get_course
(
CourseLocator
(
cours
e_id
=
new_id
,
branch
=
master_branch
))
return
self
.
get_course
(
CourseLocator
(
packag
e_id
=
new_id
,
branch
=
master_branch
))
def
update_item
(
self
,
descriptor
,
user_id
,
force
=
False
):
def
update_item
(
self
,
descriptor
,
user_id
,
force
=
False
):
"""
"""
...
@@ -930,7 +930,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -930,7 +930,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
raises ItemNotFoundError if the location does not exist.
raises ItemNotFoundError if the location does not exist.
Creates a new course version. If the descriptor's location has a
cours
e_id, it moves the course head
Creates a new course version. If the descriptor's location has a
packag
e_id, it moves the course head
pointer. If the version_guid of the descriptor points to a non-head version and there's been an intervening
pointer. If the version_guid of the descriptor points to a non-head version and there's been an intervening
change to this item, it raises a VersionConflictError unless force is True. In the force case, it forks
change to this item, it raises a VersionConflictError unless force is True. In the force case, it forks
the course but leaves the head pointer where it is (this change will not be in the course head).
the course but leaves the head pointer where it is (this change will not be in the course head).
...
@@ -1019,7 +1019,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1019,7 +1019,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# fetch and return the new item--fetching is unnecessary but a good qc step
# fetch and return the new item--fetching is unnecessary but a good qc step
return
self
.
get_item
(
return
self
.
get_item
(
BlockUsageLocator
(
BlockUsageLocator
(
course_id
=
xblock
.
location
.
cours
e_id
,
package_id
=
xblock
.
location
.
packag
e_id
,
block_id
=
xblock
.
location
.
block_id
,
block_id
=
xblock
.
location
.
block_id
,
branch
=
xblock
.
location
.
branch
,
branch
=
xblock
.
location
.
branch
,
version_guid
=
new_id
version_guid
=
new_id
...
@@ -1143,7 +1143,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1143,7 +1143,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
"""
"""
# get the destination's index, and source and destination structures.
# get the destination's index, and source and destination structures.
source_structure
=
self
.
_lookup_course
(
source_course
)[
'structure'
]
source_structure
=
self
.
_lookup_course
(
source_course
)[
'structure'
]
index_entry
=
self
.
db_connection
.
get_course_index
(
destination_course
.
cours
e_id
)
index_entry
=
self
.
db_connection
.
get_course_index
(
destination_course
.
packag
e_id
)
if
index_entry
is
None
:
if
index_entry
is
None
:
# brand new course
# brand new course
raise
ItemNotFoundError
(
destination_course
)
raise
ItemNotFoundError
(
destination_course
)
...
@@ -1207,7 +1207,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1207,7 +1207,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
raises ItemNotFoundError if the location does not exist.
raises ItemNotFoundError if the location does not exist.
raises ValueError if usage_locator points to the structure root
raises ValueError if usage_locator points to the structure root
Creates a new course version. If the descriptor's location has a
cours
e_id, it moves the course head
Creates a new course version. If the descriptor's location has a
packag
e_id, it moves the course head
pointer. If the version_guid of the descriptor points to a non-head version and there's been an intervening
pointer. If the version_guid of the descriptor points to a non-head version and there's been an intervening
change to this item, it raises a VersionConflictError unless force is True. In the force case, it forks
change to this item, it raises a VersionConflictError unless force is True. In the force case, it forks
the course but leaves the head pointer where it is (this change will not be in the course head).
the course but leaves the head pointer where it is (this change will not be in the course head).
...
@@ -1249,12 +1249,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1249,12 +1249,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
# update the index entry if appropriate
# update the index entry if appropriate
if
index_entry
is
not
None
:
if
index_entry
is
not
None
:
self
.
_update_head
(
index_entry
,
usage_locator
.
branch
,
new_id
)
self
.
_update_head
(
index_entry
,
usage_locator
.
branch
,
new_id
)
result
.
course_id
=
usage_locator
.
cours
e_id
result
.
package_id
=
usage_locator
.
packag
e_id
result
.
branch
=
usage_locator
.
branch
result
.
branch
=
usage_locator
.
branch
return
result
return
result
def
delete_course
(
self
,
cours
e_id
):
def
delete_course
(
self
,
packag
e_id
):
"""
"""
Remove the given course from the course index.
Remove the given course from the course index.
...
@@ -1262,11 +1262,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1262,11 +1262,11 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
with a versions hash to restore the course; however, the edited_on and
with a versions hash to restore the course; however, the edited_on and
edited_by won't reflect the originals, of course.
edited_by won't reflect the originals, of course.
:param
course_id: uses cours
e_id rather than locator to emphasize its global effect
:param
package_id: uses packag
e_id rather than locator to emphasize its global effect
"""
"""
index
=
self
.
db_connection
.
get_course_index
(
cours
e_id
)
index
=
self
.
db_connection
.
get_course_index
(
packag
e_id
)
if
index
is
None
:
if
index
is
None
:
raise
ItemNotFoundError
(
cours
e_id
)
raise
ItemNotFoundError
(
packag
e_id
)
# this is the only real delete in the system. should it do something else?
# this is the only real delete in the system. should it do something else?
self
.
db_connection
.
delete_course_index
(
index
[
'_id'
])
self
.
db_connection
.
delete_course_index
(
index
[
'_id'
])
...
@@ -1405,7 +1405,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1405,7 +1405,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
:param continue_version: if True, assumes this operation requires a head version and will not create a new
:param continue_version: if True, assumes this operation requires a head version and will not create a new
version but instead continue an existing transaction on this version. This flag cannot be True if force is True.
version but instead continue an existing transaction on this version. This flag cannot be True if force is True.
"""
"""
if
locator
.
cours
e_id
is
None
or
locator
.
branch
is
None
:
if
locator
.
packag
e_id
is
None
or
locator
.
branch
is
None
:
if
continue_version
:
if
continue_version
:
raise
InsufficientSpecificationError
(
raise
InsufficientSpecificationError
(
"To continue a version, the locator must point to one ({})."
.
format
(
locator
)
"To continue a version, the locator must point to one ({})."
.
format
(
locator
)
...
@@ -1413,7 +1413,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1413,7 +1413,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
else
:
else
:
return
None
return
None
else
:
else
:
index_entry
=
self
.
db_connection
.
get_course_index
(
locator
.
cours
e_id
)
index_entry
=
self
.
db_connection
.
get_course_index
(
locator
.
packag
e_id
)
is_head
=
(
is_head
=
(
locator
.
version_guid
is
None
or
locator
.
version_guid
is
None
or
index_entry
[
'versions'
][
locator
.
branch
]
==
locator
.
version_guid
index_entry
[
'versions'
][
locator
.
branch
]
==
locator
.
version_guid
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
View file @
f5f24fcc
...
@@ -75,9 +75,9 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -75,9 +75,9 @@ class TestLocationMapper(unittest.TestCase):
self
.
assertEqual
(
entry
[
'prod_branch'
],
'live'
)
self
.
assertEqual
(
entry
[
'prod_branch'
],
'live'
)
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_
cours
e_id
,
block_id
,
branch
,
add_entry
=
False
):
def
translate_n_check
(
self
,
location
,
old_style_course_id
,
new_style_
packag
e_id
,
block_id
,
branch
,
add_entry
=
False
):
"""
"""
Request translation, check
cours
e_id, block_id, and branch
Request translation, check
packag
e_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
,
...
@@ -85,7 +85,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -85,7 +85,7 @@ class TestLocationMapper(unittest.TestCase):
published
=
(
branch
==
'published'
),
published
=
(
branch
==
'published'
),
add_entry_if_missing
=
add_entry
add_entry_if_missing
=
add_entry
)
)
self
.
assertEqual
(
prob_locator
.
course_id
,
new_style_cours
e_id
)
self
.
assertEqual
(
prob_locator
.
package_id
,
new_style_packag
e_id
)
self
.
assertEqual
(
prob_locator
.
block_id
,
block_id
)
self
.
assertEqual
(
prob_locator
.
block_id
,
block_id
)
self
.
assertEqual
(
prob_locator
.
branch
,
branch
)
self
.
assertEqual
(
prob_locator
.
branch
,
branch
)
...
@@ -104,7 +104,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -104,7 +104,7 @@ class TestLocationMapper(unittest.TestCase):
add_entry_if_missing
=
False
add_entry_if_missing
=
False
)
)
new_style_
cours
e_id
=
'{}.geek_dept.{}.baz_run'
.
format
(
org
,
course
)
new_style_
packag
e_id
=
'{}.geek_dept.{}.baz_run'
.
format
(
org
,
course
)
block_map
=
{
block_map
=
{
'abc123'
:
{
'problem'
:
'problem2'
},
'abc123'
:
{
'problem'
:
'problem2'
},
'def456'
:
{
'problem'
:
'problem4'
},
'def456'
:
{
'problem'
:
'problem4'
},
...
@@ -112,15 +112,15 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -112,15 +112,15 @@ class TestLocationMapper(unittest.TestCase):
}
}
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
),
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
),
new_style_
cours
e_id
,
new_style_
packag
e_id
,
block_map
=
block_map
block_map
=
block_map
)
)
test_problem_locn
=
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'abc123'
)
test_problem_locn
=
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'abc123'
)
# only one course matches
# only one course matches
self
.
translate_n_check
(
test_problem_locn
,
old_style_course_id
,
new_style_
cours
e_id
,
'problem2'
,
'published'
)
self
.
translate_n_check
(
test_problem_locn
,
old_style_course_id
,
new_style_
packag
e_id
,
'problem2'
,
'published'
)
# look for w/ only the Location (works b/c there's only one possible course match). Will force
# look for w/ only the Location (works b/c there's only one possible course match). Will force
# cache as default translation for this problemid
# cache as default translation for this problemid
self
.
translate_n_check
(
test_problem_locn
,
None
,
new_style_
cours
e_id
,
'problem2'
,
'published'
)
self
.
translate_n_check
(
test_problem_locn
,
None
,
new_style_
packag
e_id
,
'problem2'
,
'published'
)
# look for non-existent problem
# look for non-existent problem
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
loc_mapper
()
.
translate_location
(
loc_mapper
()
.
translate_location
(
...
@@ -143,7 +143,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -143,7 +143,7 @@ class TestLocationMapper(unittest.TestCase):
block_map
=
distractor_block_map
block_map
=
distractor_block_map
)
)
# test that old translation still works
# test that old translation still works
self
.
translate_n_check
(
test_problem_locn
,
old_style_course_id
,
new_style_
cours
e_id
,
'problem2'
,
'published'
)
self
.
translate_n_check
(
test_problem_locn
,
old_style_course_id
,
new_style_
packag
e_id
,
'problem2'
,
'published'
)
# and new returns new id
# and new returns new id
self
.
translate_n_check
(
test_problem_locn
,
test_delta_old_id
,
test_delta_new_id
,
'problem3'
,
'published'
)
self
.
translate_n_check
(
test_problem_locn
,
test_delta_old_id
,
test_delta_new_id
,
'problem3'
,
'published'
)
# look for default translation of uncached Location (not unique; so, just verify it returns something)
# look for default translation of uncached Location (not unique; so, just verify it returns something)
...
@@ -177,24 +177,24 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -177,24 +177,24 @@ class TestLocationMapper(unittest.TestCase):
old_style_course_id
=
'{}/{}/{}'
.
format
(
org
,
course
,
'baz_run'
)
old_style_course_id
=
'{}/{}/{}'
.
format
(
org
,
course
,
'baz_run'
)
problem_name
=
'abc123abc123abc123abc123abc123f9'
problem_name
=
'abc123abc123abc123abc123abc123f9'
location
=
Location
(
'i4x'
,
org
,
course
,
'problem'
,
problem_name
)
location
=
Location
(
'i4x'
,
org
,
course
,
'problem'
,
problem_name
)
new_style_
cours
e_id
=
'{}.{}.{}'
.
format
(
org
,
course
,
'baz_run'
)
new_style_
packag
e_id
=
'{}.{}.{}'
.
format
(
org
,
course
,
'baz_run'
)
self
.
translate_n_check
(
location
,
old_style_course_id
,
new_style_
cours
e_id
,
'problemabc'
,
'published'
,
True
)
self
.
translate_n_check
(
location
,
old_style_course_id
,
new_style_
packag
e_id
,
'problemabc'
,
'published'
,
True
)
# look for w/ only the Location (works b/c there's only one possible course match): causes cache
# look for w/ only the Location (works b/c there's only one possible course match): causes cache
self
.
translate_n_check
(
location
,
None
,
new_style_
cours
e_id
,
'problemabc'
,
'published'
,
True
)
self
.
translate_n_check
(
location
,
None
,
new_style_
packag
e_id
,
'problemabc'
,
'published'
,
True
)
# create an entry w/o a guid name
# create an entry w/o a guid name
other_location
=
Location
(
'i4x'
,
org
,
course
,
'chapter'
,
'intro'
)
other_location
=
Location
(
'i4x'
,
org
,
course
,
'chapter'
,
'intro'
)
self
.
translate_n_check
(
other_location
,
old_style_course_id
,
new_style_
cours
e_id
,
'intro'
,
'published'
,
True
)
self
.
translate_n_check
(
other_location
,
old_style_course_id
,
new_style_
packag
e_id
,
'intro'
,
'published'
,
True
)
# add a distractor course
# add a distractor course
delta_new_
cours
e_id
=
'{}.geek_dept.{}.{}'
.
format
(
org
,
course
,
'delta_run'
)
delta_new_
packag
e_id
=
'{}.geek_dept.{}.{}'
.
format
(
org
,
course
,
'delta_run'
)
delta_course_locn
=
Location
(
'i4x'
,
org
,
course
,
'course'
,
'delta_run'
)
delta_course_locn
=
Location
(
'i4x'
,
org
,
course
,
'course'
,
'delta_run'
)
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
delta_course_locn
,
delta_course_locn
,
delta_new_
cours
e_id
,
delta_new_
packag
e_id
,
block_map
=
{
problem_name
:
{
'problem'
:
'problem3'
}}
block_map
=
{
problem_name
:
{
'problem'
:
'problem3'
}}
)
)
self
.
translate_n_check
(
location
,
old_style_course_id
,
new_style_
cours
e_id
,
'problemabc'
,
'published'
,
True
)
self
.
translate_n_check
(
location
,
old_style_course_id
,
new_style_
packag
e_id
,
'problemabc'
,
'published'
,
True
)
# add a new one to both courses (ensure name doesn't have same beginning)
# add a new one to both courses (ensure name doesn't have same beginning)
new_prob_name
=
uuid
.
uuid4
()
.
hex
new_prob_name
=
uuid
.
uuid4
()
.
hex
...
@@ -202,9 +202,9 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -202,9 +202,9 @@ class TestLocationMapper(unittest.TestCase):
new_prob_name
=
uuid
.
uuid4
()
.
hex
new_prob_name
=
uuid
.
uuid4
()
.
hex
new_prob_locn
=
location
.
replace
(
name
=
new_prob_name
)
new_prob_locn
=
location
.
replace
(
name
=
new_prob_name
)
new_usage_id
=
'problem{}'
.
format
(
new_prob_name
[:
3
])
new_usage_id
=
'problem{}'
.
format
(
new_prob_name
[:
3
])
self
.
translate_n_check
(
new_prob_locn
,
old_style_course_id
,
new_style_
cours
e_id
,
new_usage_id
,
'published'
,
True
)
self
.
translate_n_check
(
new_prob_locn
,
old_style_course_id
,
new_style_
packag
e_id
,
new_usage_id
,
'published'
,
True
)
self
.
translate_n_check
(
self
.
translate_n_check
(
new_prob_locn
,
delta_course_locn
.
course_id
,
delta_new_
cours
e_id
,
new_usage_id
,
'published'
,
True
new_prob_locn
,
delta_course_locn
.
course_id
,
delta_new_
packag
e_id
,
new_usage_id
,
'published'
,
True
)
)
# look for w/ only the Location: causes caching and not unique; so, can't check which course
# look for w/ only the Location: causes caching and not unique; so, can't check which course
prob_locator
=
loc_mapper
()
.
translate_location
(
prob_locator
=
loc_mapper
()
.
translate_location
(
...
@@ -217,7 +217,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -217,7 +217,7 @@ class TestLocationMapper(unittest.TestCase):
# add a default course pointing to the delta_run
# add a default course pointing to the delta_run
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'789abc123efg456'
),
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'789abc123efg456'
),
delta_new_
cours
e_id
,
delta_new_
packag
e_id
,
block_map
=
{
problem_name
:
{
'problem'
:
'problem3'
}}
block_map
=
{
problem_name
:
{
'problem'
:
'problem3'
}}
)
)
# now the ambiguous query should return delta
# now the ambiguous query should return delta
...
@@ -226,11 +226,11 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -226,11 +226,11 @@ class TestLocationMapper(unittest.TestCase):
again_prob_name
=
uuid
.
uuid4
()
.
hex
again_prob_name
=
uuid
.
uuid4
()
.
hex
again_prob_locn
=
location
.
replace
(
name
=
again_prob_name
)
again_prob_locn
=
location
.
replace
(
name
=
again_prob_name
)
again_usage_id
=
'problem{}'
.
format
(
again_prob_name
[:
3
])
again_usage_id
=
'problem{}'
.
format
(
again_prob_name
[:
3
])
self
.
translate_n_check
(
again_prob_locn
,
old_style_course_id
,
new_style_
cours
e_id
,
again_usage_id
,
'published'
,
True
)
self
.
translate_n_check
(
again_prob_locn
,
old_style_course_id
,
new_style_
packag
e_id
,
again_usage_id
,
'published'
,
True
)
self
.
translate_n_check
(
self
.
translate_n_check
(
again_prob_locn
,
delta_course_locn
.
course_id
,
delta_new_
cours
e_id
,
again_usage_id
,
'published'
,
True
again_prob_locn
,
delta_course_locn
.
course_id
,
delta_new_
packag
e_id
,
again_usage_id
,
'published'
,
True
)
)
self
.
translate_n_check
(
again_prob_locn
,
None
,
delta_new_
cours
e_id
,
again_usage_id
,
'published'
,
True
)
self
.
translate_n_check
(
again_prob_locn
,
None
,
delta_new_
packag
e_id
,
again_usage_id
,
'published'
,
True
)
def
test_translate_locator
(
self
):
def
test_translate_locator
(
self
):
"""
"""
...
@@ -239,9 +239,9 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -239,9 +239,9 @@ class TestLocationMapper(unittest.TestCase):
# lookup for non-existent course
# lookup for non-existent course
org
=
'foo_org'
org
=
'foo_org'
course
=
'bar_course'
course
=
'bar_course'
new_style_
cours
e_id
=
'{}.geek_dept.{}.baz_run'
.
format
(
org
,
course
)
new_style_
packag
e_id
=
'{}.geek_dept.{}.baz_run'
.
format
(
org
,
course
)
prob_locator
=
BlockUsageLocator
(
prob_locator
=
BlockUsageLocator
(
course_id
=
new_style_cours
e_id
,
package_id
=
new_style_packag
e_id
,
block_id
=
'problem2'
,
block_id
=
'problem2'
,
branch
=
'published'
branch
=
'published'
)
)
...
@@ -250,7 +250,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -250,7 +250,7 @@ class TestLocationMapper(unittest.TestCase):
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
),
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
),
new_style_
cours
e_id
,
new_style_
packag
e_id
,
block_map
=
{
block_map
=
{
'abc123'
:
{
'problem'
:
'problem2'
},
'abc123'
:
{
'problem'
:
'problem2'
},
'48f23a10395384929234'
:
{
'chapter'
:
'chapter48f'
},
'48f23a10395384929234'
:
{
'chapter'
:
'chapter48f'
},
...
@@ -266,20 +266,20 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -266,20 +266,20 @@ 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
.
cours
e_id
,
branch
=
'draft'
,
block_id
=
prob_locator
.
block_id
package_id
=
prob_locator
.
packag
e_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_cours
e_id
,
block_id
=
'problem2'
,
branch
=
'production'
package_id
=
new_style_packag
e_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_cours
e_id
,
package_id
=
new_style_packag
e_id
,
block_id
=
'chapter48f'
,
block_id
=
'chapter48f'
,
branch
=
'production'
branch
=
'production'
)
)
...
@@ -290,14 +290,14 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -290,14 +290,14 @@ 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_cours
e_id
,
block_id
=
'chapter48f'
,
branch
=
'production'
package_id
=
new_style_packag
e_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'
))
# look for non-existent problem
# look for non-existent problem
prob_locator2
=
BlockUsageLocator
(
prob_locator2
=
BlockUsageLocator
(
course_id
=
new_style_cours
e_id
,
package_id
=
new_style_packag
e_id
,
branch
=
'draft'
,
branch
=
'draft'
,
block_id
=
'problem3'
block_id
=
'problem3'
)
)
...
@@ -305,10 +305,10 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -305,10 +305,10 @@ class TestLocationMapper(unittest.TestCase):
self
.
assertIsNone
(
prob_location
,
'Found non-existent problem'
)
self
.
assertIsNone
(
prob_location
,
'Found non-existent problem'
)
# add a distractor course
# add a distractor course
new_style_
cours
e_id
=
'{}.geek_dept.{}.{}'
.
format
(
org
,
course
,
'delta_run'
)
new_style_
packag
e_id
=
'{}.geek_dept.{}.{}'
.
format
(
org
,
course
,
'delta_run'
)
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'course'
,
'delta_run'
),
Location
(
'i4x'
,
org
,
course
,
'course'
,
'delta_run'
),
new_style_
cours
e_id
,
new_style_
packag
e_id
,
block_map
=
{
'abc123'
:
{
'problem'
:
'problem3'
}}
block_map
=
{
'abc123'
:
{
'problem'
:
'problem3'
}}
)
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
...
@@ -317,12 +317,12 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -317,12 +317,12 @@ class TestLocationMapper(unittest.TestCase):
# add a default course pointing to the delta_run
# add a default course pointing to the delta_run
loc_mapper
()
.
create_map_entry
(
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'789abc123efg456'
),
Location
(
'i4x'
,
org
,
course
,
'problem'
,
'789abc123efg456'
),
new_style_
cours
e_id
,
new_style_
packag
e_id
,
block_map
=
{
'abc123'
:
{
'problem'
:
'problem3'
}}
block_map
=
{
'abc123'
:
{
'problem'
:
'problem3'
}}
)
)
# now query delta (2 entries point to it)
# now query delta (2 entries point to it)
prob_locator
=
BlockUsageLocator
(
prob_locator
=
BlockUsageLocator
(
course_id
=
new_style_cours
e_id
,
package_id
=
new_style_packag
e_id
,
branch
=
'production'
,
branch
=
'production'
,
block_id
=
'problem3'
block_id
=
'problem3'
)
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_locators.py
View file @
f5f24fcc
...
@@ -24,14 +24,14 @@ class LocatorTest(TestCase):
...
@@ -24,14 +24,14 @@ class LocatorTest(TestCase):
OverSpecificationError
,
OverSpecificationError
,
CourseLocator
,
CourseLocator
,
url
=
'edx://mit.eecs.6002x'
,
url
=
'edx://mit.eecs.6002x'
,
cours
e_id
=
'harvard.history'
,
packag
e_id
=
'harvard.history'
,
branch
=
'published'
,
branch
=
'published'
,
version_guid
=
ObjectId
())
version_guid
=
ObjectId
())
self
.
assertRaises
(
self
.
assertRaises
(
OverSpecificationError
,
OverSpecificationError
,
CourseLocator
,
CourseLocator
,
url
=
'edx://mit.eecs.6002x'
,
url
=
'edx://mit.eecs.6002x'
,
cours
e_id
=
'harvard.history'
,
packag
e_id
=
'harvard.history'
,
version_guid
=
ObjectId
())
version_guid
=
ObjectId
())
self
.
assertRaises
(
self
.
assertRaises
(
OverSpecificationError
,
OverSpecificationError
,
...
@@ -41,7 +41,7 @@ class LocatorTest(TestCase):
...
@@ -41,7 +41,7 @@ class LocatorTest(TestCase):
self
.
assertRaises
(
self
.
assertRaises
(
OverSpecificationError
,
OverSpecificationError
,
CourseLocator
,
CourseLocator
,
cours
e_id
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
,
packag
e_id
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
,
branch
=
'draft'
)
branch
=
'draft'
)
def
test_course_constructor_underspecified
(
self
):
def
test_course_constructor_underspecified
(
self
):
...
@@ -71,9 +71,9 @@ class LocatorTest(TestCase):
...
@@ -71,9 +71,9 @@ class LocatorTest(TestCase):
self
.
assertEqual
(
str
(
testobj_2
),
VERSION_PREFIX
+
test_id_2_loc
)
self
.
assertEqual
(
str
(
testobj_2
),
VERSION_PREFIX
+
test_id_2_loc
)
self
.
assertEqual
(
testobj_2
.
url
(),
'edx://'
+
VERSION_PREFIX
+
test_id_2_loc
)
self
.
assertEqual
(
testobj_2
.
url
(),
'edx://'
+
VERSION_PREFIX
+
test_id_2_loc
)
def
test_course_constructor_bad_
cours
e_id
(
self
):
def
test_course_constructor_bad_
packag
e_id
(
self
):
"""
"""
Test all sorts of badly-formed
course_ids (and urls with those cours
e_ids)
Test all sorts of badly-formed
package_ids (and urls with those packag
e_ids)
"""
"""
for
bad_id
in
(
' mit.eecs'
,
for
bad_id
in
(
' mit.eecs'
,
'mit.eecs '
,
'mit.eecs '
,
...
@@ -91,7 +91,7 @@ class LocatorTest(TestCase):
...
@@ -91,7 +91,7 @@ class LocatorTest(TestCase):
'mit.eecs/'
+
BRANCH_PREFIX
+
'this '
,
'mit.eecs/'
+
BRANCH_PREFIX
+
'this '
,
'mit.eecs/'
+
BRANCH_PREFIX
+
'th
%
is '
,
'mit.eecs/'
+
BRANCH_PREFIX
+
'th
%
is '
,
):
):
self
.
assertRaises
(
ValueError
,
CourseLocator
,
cours
e_id
=
bad_id
)
self
.
assertRaises
(
ValueError
,
CourseLocator
,
packag
e_id
=
bad_id
)
self
.
assertRaises
(
ValueError
,
CourseLocator
,
url
=
'edx://'
+
bad_id
)
self
.
assertRaises
(
ValueError
,
CourseLocator
,
url
=
'edx://'
+
bad_id
)
def
test_course_constructor_bad_url
(
self
):
def
test_course_constructor_bad_url
(
self
):
...
@@ -103,16 +103,16 @@ class LocatorTest(TestCase):
...
@@ -103,16 +103,16 @@ class LocatorTest(TestCase):
def
test_course_constructor_redundant_001
(
self
):
def
test_course_constructor_redundant_001
(
self
):
testurn
=
'mit.eecs.6002x'
testurn
=
'mit.eecs.6002x'
testobj
=
CourseLocator
(
cours
e_id
=
testurn
,
url
=
'edx://'
+
testurn
)
testobj
=
CourseLocator
(
packag
e_id
=
testurn
,
url
=
'edx://'
+
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
course_id'
,
cours
e_id
=
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
package_id'
,
packag
e_id
=
testurn
)
def
test_course_constructor_redundant_002
(
self
):
def
test_course_constructor_redundant_002
(
self
):
testurn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
testurn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
expected_urn
=
'mit.eecs.6002x'
expected_urn
=
'mit.eecs.6002x'
expected_rev
=
'published'
expected_rev
=
'published'
testobj
=
CourseLocator
(
cours
e_id
=
testurn
,
url
=
'edx://'
+
testurn
)
testobj
=
CourseLocator
(
packag
e_id
=
testurn
,
url
=
'edx://'
+
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
cours
e_id'
,
self
.
check_course_locn_fields
(
testobj
,
'
packag
e_id'
,
cours
e_id
=
expected_urn
,
packag
e_id
=
expected_urn
,
branch
=
expected_rev
)
branch
=
expected_rev
)
def
test_course_constructor_url
(
self
):
def
test_course_constructor_url
(
self
):
...
@@ -126,71 +126,71 @@ class LocatorTest(TestCase):
...
@@ -126,71 +126,71 @@ class LocatorTest(TestCase):
version_guid
=
ObjectId
(
test_id_loc
)
version_guid
=
ObjectId
(
test_id_loc
)
)
)
def
test_course_constructor_url_
cours
e_id_and_version_guid
(
self
):
def
test_course_constructor_url_
packag
e_id_and_version_guid
(
self
):
test_id_loc
=
'519665f6223ebd6980884f2b'
test_id_loc
=
'519665f6223ebd6980884f2b'
testobj
=
CourseLocator
(
url
=
'edx://mit.eecs-honors.6002x/'
+
VERSION_PREFIX
+
test_id_loc
)
testobj
=
CourseLocator
(
url
=
'edx://mit.eecs-honors.6002x/'
+
VERSION_PREFIX
+
test_id_loc
)
self
.
check_course_locn_fields
(
testobj
,
'error parsing url with both course ID and version GUID'
,
self
.
check_course_locn_fields
(
testobj
,
'error parsing url with both course ID and version GUID'
,
cours
e_id
=
'mit.eecs-honors.6002x'
,
packag
e_id
=
'mit.eecs-honors.6002x'
,
version_guid
=
ObjectId
(
test_id_loc
))
version_guid
=
ObjectId
(
test_id_loc
))
def
test_course_constructor_url_
cours
e_id_branch_and_version_guid
(
self
):
def
test_course_constructor_url_
packag
e_id_branch_and_version_guid
(
self
):
test_id_loc
=
'519665f6223ebd6980884f2b'
test_id_loc
=
'519665f6223ebd6980884f2b'
testobj
=
CourseLocator
(
url
=
'edx://mit.eecs.~6002x/'
+
BRANCH_PREFIX
+
'draft-1/'
+
VERSION_PREFIX
+
test_id_loc
)
testobj
=
CourseLocator
(
url
=
'edx://mit.eecs.~6002x/'
+
BRANCH_PREFIX
+
'draft-1/'
+
VERSION_PREFIX
+
test_id_loc
)
self
.
check_course_locn_fields
(
testobj
,
'error parsing url with both course ID branch, and version GUID'
,
self
.
check_course_locn_fields
(
testobj
,
'error parsing url with both course ID branch, and version GUID'
,
cours
e_id
=
'mit.eecs.~6002x'
,
packag
e_id
=
'mit.eecs.~6002x'
,
branch
=
'draft-1'
,
branch
=
'draft-1'
,
version_guid
=
ObjectId
(
test_id_loc
))
version_guid
=
ObjectId
(
test_id_loc
))
def
test_course_constructor_
cours
e_id_no_branch
(
self
):
def
test_course_constructor_
packag
e_id_no_branch
(
self
):
testurn
=
'mit.eecs.6002x'
testurn
=
'mit.eecs.6002x'
testobj
=
CourseLocator
(
cours
e_id
=
testurn
)
testobj
=
CourseLocator
(
packag
e_id
=
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
course_id'
,
cours
e_id
=
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
package_id'
,
packag
e_id
=
testurn
)
self
.
assertEqual
(
testobj
.
cours
e_id
,
testurn
)
self
.
assertEqual
(
testobj
.
packag
e_id
,
testurn
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
testurn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
testurn
)
def
test_course_constructor_
cours
e_id_with_branch
(
self
):
def
test_course_constructor_
packag
e_id_with_branch
(
self
):
testurn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
testurn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
expected_id
=
'mit.eecs.6002x'
expected_id
=
'mit.eecs.6002x'
expected_branch
=
'published'
expected_branch
=
'published'
testobj
=
CourseLocator
(
cours
e_id
=
testurn
)
testobj
=
CourseLocator
(
packag
e_id
=
testurn
)
self
.
check_course_locn_fields
(
testobj
,
'
cours
e_id with branch'
,
self
.
check_course_locn_fields
(
testobj
,
'
packag
e_id with branch'
,
cours
e_id
=
expected_id
,
packag
e_id
=
expected_id
,
branch
=
expected_branch
,
branch
=
expected_branch
,
)
)
self
.
assertEqual
(
testobj
.
cours
e_id
,
expected_id
)
self
.
assertEqual
(
testobj
.
packag
e_id
,
expected_id
)
self
.
assertEqual
(
testobj
.
branch
,
expected_branch
)
self
.
assertEqual
(
testobj
.
branch
,
expected_branch
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
testurn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
testurn
)
def
test_course_constructor_
cours
e_id_separate_branch
(
self
):
def
test_course_constructor_
packag
e_id_separate_branch
(
self
):
test_id
=
'mit.eecs.6002x'
test_id
=
'mit.eecs.6002x'
test_branch
=
'published'
test_branch
=
'published'
expected_urn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
expected_urn
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
testobj
=
CourseLocator
(
cours
e_id
=
test_id
,
branch
=
test_branch
)
testobj
=
CourseLocator
(
packag
e_id
=
test_id
,
branch
=
test_branch
)
self
.
check_course_locn_fields
(
testobj
,
'
cours
e_id with separate branch'
,
self
.
check_course_locn_fields
(
testobj
,
'
packag
e_id with separate branch'
,
cours
e_id
=
test_id
,
packag
e_id
=
test_id
,
branch
=
test_branch
,
branch
=
test_branch
,
)
)
self
.
assertEqual
(
testobj
.
cours
e_id
,
test_id
)
self
.
assertEqual
(
testobj
.
packag
e_id
,
test_id
)
self
.
assertEqual
(
testobj
.
branch
,
test_branch
)
self
.
assertEqual
(
testobj
.
branch
,
test_branch
)
self
.
assertEqual
(
str
(
testobj
),
expected_urn
)
self
.
assertEqual
(
str
(
testobj
),
expected_urn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
expected_urn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
expected_urn
)
def
test_course_constructor_
cours
e_id_repeated_branch
(
self
):
def
test_course_constructor_
packag
e_id_repeated_branch
(
self
):
"""
"""
The same branch appears in the
cours
e_id and the branch field.
The same branch appears in the
packag
e_id and the branch field.
"""
"""
test_id
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
test_id
=
'mit.eecs.6002x/'
+
BRANCH_PREFIX
+
'published'
test_branch
=
'published'
test_branch
=
'published'
expected_id
=
'mit.eecs.6002x'
expected_id
=
'mit.eecs.6002x'
expected_urn
=
test_id
expected_urn
=
test_id
testobj
=
CourseLocator
(
cours
e_id
=
test_id
,
branch
=
test_branch
)
testobj
=
CourseLocator
(
packag
e_id
=
test_id
,
branch
=
test_branch
)
self
.
check_course_locn_fields
(
testobj
,
'
cours
e_id with repeated branch'
,
self
.
check_course_locn_fields
(
testobj
,
'
packag
e_id with repeated branch'
,
cours
e_id
=
expected_id
,
packag
e_id
=
expected_id
,
branch
=
test_branch
,
branch
=
test_branch
,
)
)
self
.
assertEqual
(
testobj
.
cours
e_id
,
expected_id
)
self
.
assertEqual
(
testobj
.
packag
e_id
,
expected_id
)
self
.
assertEqual
(
testobj
.
branch
,
test_branch
)
self
.
assertEqual
(
testobj
.
branch
,
test_branch
)
self
.
assertEqual
(
str
(
testobj
),
expected_urn
)
self
.
assertEqual
(
str
(
testobj
),
expected_urn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
expected_urn
)
self
.
assertEqual
(
testobj
.
url
(),
'edx://'
+
expected_urn
)
...
@@ -200,9 +200,9 @@ class LocatorTest(TestCase):
...
@@ -200,9 +200,9 @@ class LocatorTest(TestCase):
expected_id
=
'mit.eecs.6002x'
expected_id
=
'mit.eecs.6002x'
expected_branch
=
'published'
expected_branch
=
'published'
expected_block_ref
=
'HW3'
expected_block_ref
=
'HW3'
testobj
=
BlockUsageLocator
(
cours
e_id
=
testurn
)
testobj
=
BlockUsageLocator
(
packag
e_id
=
testurn
)
self
.
check_block_locn_fields
(
testobj
,
'test_block constructor'
,
self
.
check_block_locn_fields
(
testobj
,
'test_block constructor'
,
cours
e_id
=
expected_id
,
packag
e_id
=
expected_id
,
branch
=
expected_branch
,
branch
=
expected_branch
,
block
=
expected_block_ref
)
block
=
expected_block_ref
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
self
.
assertEqual
(
str
(
testobj
),
testurn
)
...
@@ -210,7 +210,7 @@ class LocatorTest(TestCase):
...
@@ -210,7 +210,7 @@ class LocatorTest(TestCase):
agnostic
=
testobj
.
version_agnostic
()
agnostic
=
testobj
.
version_agnostic
()
self
.
assertIsNone
(
agnostic
.
version_guid
)
self
.
assertIsNone
(
agnostic
.
version_guid
)
self
.
check_block_locn_fields
(
agnostic
,
'test_block constructor'
,
self
.
check_block_locn_fields
(
agnostic
,
'test_block constructor'
,
cours
e_id
=
expected_id
,
packag
e_id
=
expected_id
,
branch
=
expected_branch
,
branch
=
expected_branch
,
block
=
expected_block_ref
)
block
=
expected_block_ref
)
...
@@ -221,7 +221,7 @@ class LocatorTest(TestCase):
...
@@ -221,7 +221,7 @@ class LocatorTest(TestCase):
)
)
self
.
check_block_locn_fields
(
self
.
check_block_locn_fields
(
testobj
,
'error parsing URL with version and block'
,
testobj
,
'error parsing URL with version and block'
,
cours
e_id
=
'mit.eecs.6002x'
,
packag
e_id
=
'mit.eecs.6002x'
,
block
=
'lab2'
,
block
=
'lab2'
,
version_guid
=
ObjectId
(
test_id_loc
)
version_guid
=
ObjectId
(
test_id_loc
)
)
)
...
@@ -229,10 +229,10 @@ class LocatorTest(TestCase):
...
@@ -229,10 +229,10 @@ class LocatorTest(TestCase):
self
.
check_block_locn_fields
(
self
.
check_block_locn_fields
(
agnostic
,
'error parsing URL with version and block'
,
agnostic
,
'error parsing URL with version and block'
,
block
=
'lab2'
,
block
=
'lab2'
,
cours
e_id
=
None
,
packag
e_id
=
None
,
version_guid
=
ObjectId
(
test_id_loc
)
version_guid
=
ObjectId
(
test_id_loc
)
)
)
self
.
assertIsNone
(
agnostic
.
cours
e_id
)
self
.
assertIsNone
(
agnostic
.
packag
e_id
)
def
test_block_constructor_url_kitchen_sink
(
self
):
def
test_block_constructor_url_kitchen_sink
(
self
):
test_id_loc
=
'519665f6223ebd6980884f2b'
test_id_loc
=
'519665f6223ebd6980884f2b'
...
@@ -243,7 +243,7 @@ class LocatorTest(TestCase):
...
@@ -243,7 +243,7 @@ class LocatorTest(TestCase):
)
)
self
.
check_block_locn_fields
(
self
.
check_block_locn_fields
(
testobj
,
'error parsing URL with branch, version, and block'
,
testobj
,
'error parsing URL with branch, version, and block'
,
cours
e_id
=
'mit.eecs.6002x'
,
packag
e_id
=
'mit.eecs.6002x'
,
branch
=
'draft'
,
branch
=
'draft'
,
block
=
'lab2'
,
block
=
'lab2'
,
version_guid
=
ObjectId
(
test_id_loc
)
version_guid
=
ObjectId
(
test_id_loc
)
...
@@ -253,15 +253,15 @@ class LocatorTest(TestCase):
...
@@ -253,15 +253,15 @@ class LocatorTest(TestCase):
"""
"""
It seems we used to use colons in names; so, ensure they're acceptable.
It seems we used to use colons in names; so, ensure they're acceptable.
"""
"""
cours
e_id
=
'mit.eecs-1'
packag
e_id
=
'mit.eecs-1'
branch
=
'foo'
branch
=
'foo'
block_id
=
'problem:with-colon~2'
block_id
=
'problem:with-colon~2'
testobj
=
BlockUsageLocator
(
course_id
=
cours
e_id
,
branch
=
branch
,
block_id
=
block_id
)
testobj
=
BlockUsageLocator
(
package_id
=
packag
e_id
,
branch
=
branch
,
block_id
=
block_id
)
self
.
check_block_locn_fields
(
testobj
,
'Cannot handle colon'
,
course_id
=
cours
e_id
,
branch
=
branch
,
block
=
block_id
)
self
.
check_block_locn_fields
(
testobj
,
'Cannot handle colon'
,
package_id
=
packag
e_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'
testobj
=
BlockUsageLocator
(
cours
e_id
=
testurn
)
testobj
=
BlockUsageLocator
(
packag
e_id
=
testurn
)
self
.
assertEqual
(
'BlockUsageLocator("mit.eecs.6002x/branch/published/block/HW3")'
,
repr
(
testobj
))
self
.
assertEqual
(
'BlockUsageLocator("mit.eecs.6002x/branch/published/block/HW3")'
,
repr
(
testobj
))
def
test_old_location_helpers
(
self
):
def
test_old_location_helpers
(
self
):
...
@@ -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
(
cours
e_id
=
'foo.bar'
,
branch
=
'alpha'
,
block_id
=
'deep'
)
locator
=
BlockUsageLocator
(
packag
e_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
()))
...
@@ -299,7 +299,7 @@ class LocatorTest(TestCase):
...
@@ -299,7 +299,7 @@ class LocatorTest(TestCase):
"""
"""
Test the url_reverse method
Test the url_reverse method
"""
"""
locator
=
CourseLocator
(
cours
e_id
=
"a.fancy_course-id"
,
branch
=
"branch_1.2-3"
)
locator
=
CourseLocator
(
packag
e_id
=
"a.fancy_course-id"
,
branch
=
"branch_1.2-3"
)
self
.
assertEqual
(
self
.
assertEqual
(
'/expression/{}/format'
.
format
(
unicode
(
locator
)),
'/expression/{}/format'
.
format
(
unicode
(
locator
)),
locator
.
url_reverse
(
'expression'
,
'format'
)
locator
.
url_reverse
(
'expression'
,
'format'
)
...
@@ -332,19 +332,19 @@ class LocatorTest(TestCase):
...
@@ -332,19 +332,19 @@ class LocatorTest(TestCase):
# Utilities
# Utilities
def
check_course_locn_fields
(
self
,
testobj
,
msg
,
version_guid
=
None
,
def
check_course_locn_fields
(
self
,
testobj
,
msg
,
version_guid
=
None
,
cours
e_id
=
None
,
branch
=
None
):
packag
e_id
=
None
,
branch
=
None
):
"""
"""
Checks the version,
cours
e_id, and branch in testobj
Checks the version,
packag
e_id, and branch in testobj
"""
"""
self
.
assertEqual
(
testobj
.
version_guid
,
version_guid
,
msg
)
self
.
assertEqual
(
testobj
.
version_guid
,
version_guid
,
msg
)
self
.
assertEqual
(
testobj
.
course_id
,
cours
e_id
,
msg
)
self
.
assertEqual
(
testobj
.
package_id
,
packag
e_id
,
msg
)
self
.
assertEqual
(
testobj
.
branch
,
branch
,
msg
)
self
.
assertEqual
(
testobj
.
branch
,
branch
,
msg
)
def
check_block_locn_fields
(
self
,
testobj
,
msg
,
version_guid
=
None
,
def
check_block_locn_fields
(
self
,
testobj
,
msg
,
version_guid
=
None
,
cours
e_id
=
None
,
branch
=
None
,
block
=
None
):
packag
e_id
=
None
,
branch
=
None
,
block
=
None
):
"""
"""
Does adds a block id check over and above the check_course_locn_fields tests
Does adds a block id check over and above the check_course_locn_fields tests
"""
"""
self
.
check_course_locn_fields
(
testobj
,
msg
,
version_guid
,
cours
e_id
,
self
.
check_course_locn_fields
(
testobj
,
msg
,
version_guid
,
packag
e_id
,
branch
)
branch
)
self
.
assertEqual
(
testobj
.
block_id
,
block
)
self
.
assertEqual
(
testobj
.
block_id
,
block
)
common/lib/xmodule/xmodule/modulestore/tests/test_orphan.py
View file @
f5f24fcc
...
@@ -30,7 +30,7 @@ class TestOrphan(unittest.TestCase):
...
@@ -30,7 +30,7 @@ class TestOrphan(unittest.TestCase):
'xblock_mixins'
:
(
InheritanceMixin
,)
'xblock_mixins'
:
(
InheritanceMixin
,)
}
}
split_
cours
e_id
=
'test_org.test_course.runid'
split_
packag
e_id
=
'test_org.test_course.runid'
def
setUp
(
self
):
def
setUp
(
self
):
self
.
db_config
[
'collection'
]
=
'modulestore{0}'
.
format
(
uuid
.
uuid4
()
.
hex
[:
5
])
self
.
db_config
[
'collection'
]
=
'modulestore{0}'
.
format
(
uuid
.
uuid4
()
.
hex
[:
5
])
...
@@ -85,13 +85,13 @@ class TestOrphan(unittest.TestCase):
...
@@ -85,13 +85,13 @@ class TestOrphan(unittest.TestCase):
self
.
old_mongo
.
update_children
(
parent_location
,
parent
.
children
)
self
.
old_mongo
.
update_children
(
parent_location
,
parent
.
children
)
# create pointer for split
# create pointer for split
course_or_parent_locator
=
BlockUsageLocator
(
course_or_parent_locator
=
BlockUsageLocator
(
course_id
=
self
.
split_cours
e_id
,
package_id
=
self
.
split_packag
e_id
,
branch
=
'draft'
,
branch
=
'draft'
,
block_id
=
parent_name
block_id
=
parent_name
)
)
else
:
else
:
course_or_parent_locator
=
CourseLocator
(
course_or_parent_locator
=
CourseLocator
(
cours
e_id
=
'test_org.test_course.runid'
,
packag
e_id
=
'test_org.test_course.runid'
,
branch
=
'draft'
,
branch
=
'draft'
,
)
)
self
.
split_mongo
.
create_item
(
course_or_parent_locator
,
category
,
self
.
userid
,
block_id
=
name
,
fields
=
fields
)
self
.
split_mongo
.
create_item
(
course_or_parent_locator
,
category
,
self
.
userid
,
block_id
=
name
,
fields
=
fields
)
...
@@ -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_
cours
e_id
,
fields
=
fields
,
root_block_id
=
'runid'
'test_org'
,
'my course'
,
self
.
userid
,
self
.
split_
packag
e_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
)
...
@@ -148,11 +148,11 @@ class TestOrphan(unittest.TestCase):
...
@@ -148,11 +148,11 @@ class TestOrphan(unittest.TestCase):
"""
"""
Test that old mongo finds the orphans
Test that old mongo finds the orphans
"""
"""
orphans
=
self
.
split_mongo
.
get_orphans
(
self
.
split_
cours
e_id
,
[
'static_tab'
,
'about'
,
'course_info'
],
'draft'
)
orphans
=
self
.
split_mongo
.
get_orphans
(
self
.
split_
packag
e_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_cours
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanChapter'
)
location
=
BlockUsageLocator
(
package_id
=
self
.
split_packag
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanChapter'
)
self
.
assertIn
(
location
,
orphans
)
self
.
assertIn
(
location
,
orphans
)
location
=
BlockUsageLocator
(
course_id
=
self
.
split_cours
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanVert'
)
location
=
BlockUsageLocator
(
package_id
=
self
.
split_packag
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanVert'
)
self
.
assertIn
(
location
,
orphans
)
self
.
assertIn
(
location
,
orphans
)
location
=
BlockUsageLocator
(
course_id
=
self
.
split_cours
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanHtml'
)
location
=
BlockUsageLocator
(
package_id
=
self
.
split_packag
e_id
,
branch
=
'draft'
,
block_id
=
'OrphanHtml'
)
self
.
assertIn
(
location
,
orphans
)
self
.
assertIn
(
location
,
orphans
)
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
View file @
f5f24fcc
...
@@ -120,7 +120,7 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -120,7 +120,7 @@ class SplitModuleCourseTests(SplitModuleTest):
self
.
assertEqual
(
len
(
courses
),
3
,
"Wrong number of courses"
)
self
.
assertEqual
(
len
(
courses
),
3
,
"Wrong number of courses"
)
# check metadata -- NOTE no promised order
# check metadata -- NOTE no promised order
course
=
self
.
findByIdInResult
(
courses
,
"head12345"
)
course
=
self
.
findByIdInResult
(
courses
,
"head12345"
)
self
.
assertEqual
(
course
.
location
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
course
.
location
.
packag
e_id
,
"GreekHero"
)
self
.
assertEqual
(
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D0
,
str
(
course
.
location
.
version_guid
),
self
.
GUID_D0
,
"course version mismatch"
"course version mismatch"
...
@@ -151,7 +151,7 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -151,7 +151,7 @@ class SplitModuleCourseTests(SplitModuleTest):
self
.
assertEqual
(
len
(
courses_published
),
1
,
len
(
courses_published
))
self
.
assertEqual
(
len
(
courses_published
),
1
,
len
(
courses_published
))
course
=
self
.
findByIdInResult
(
courses_published
,
"head23456"
)
course
=
self
.
findByIdInResult
(
courses_published
,
"head23456"
)
self
.
assertIsNotNone
(
course
,
"published courses"
)
self
.
assertIsNotNone
(
course
,
"published courses"
)
self
.
assertEqual
(
course
.
location
.
cours
e_id
,
"wonderful"
)
self
.
assertEqual
(
course
.
location
.
packag
e_id
,
"wonderful"
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_P
,
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_P
,
course
.
location
.
version_guid
)
course
.
location
.
version_guid
)
self
.
assertEqual
(
course
.
category
,
'course'
,
'wrong category'
)
self
.
assertEqual
(
course
.
category
,
'course'
,
'wrong category'
)
...
@@ -190,7 +190,7 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -190,7 +190,7 @@ class SplitModuleCourseTests(SplitModuleTest):
'''
'''
locator
=
CourseLocator
(
version_guid
=
self
.
GUID_D1
)
locator
=
CourseLocator
(
version_guid
=
self
.
GUID_D1
)
course
=
modulestore
()
.
get_course
(
locator
)
course
=
modulestore
()
.
get_course
(
locator
)
self
.
assertIsNone
(
course
.
location
.
cours
e_id
)
self
.
assertIsNone
(
course
.
location
.
packag
e_id
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D1
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D1
)
self
.
assertEqual
(
course
.
category
,
'course'
)
self
.
assertEqual
(
course
.
category
,
'course'
)
self
.
assertEqual
(
len
(
course
.
tabs
),
6
)
self
.
assertEqual
(
len
(
course
.
tabs
),
6
)
...
@@ -203,9 +203,9 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -203,9 +203,9 @@ class SplitModuleCourseTests(SplitModuleTest):
self
.
assertEqual
(
course
.
edited_by
,
"testassist@edx.org"
)
self
.
assertEqual
(
course
.
edited_by
,
"testassist@edx.org"
)
self
.
assertDictEqual
(
course
.
grade_cutoffs
,
{
"Pass"
:
0.55
})
self
.
assertDictEqual
(
course
.
grade_cutoffs
,
{
"Pass"
:
0.55
})
locator
=
CourseLocator
(
cours
e_id
=
'GreekHero'
,
branch
=
'draft'
)
locator
=
CourseLocator
(
packag
e_id
=
'GreekHero'
,
branch
=
'draft'
)
course
=
modulestore
()
.
get_course
(
locator
)
course
=
modulestore
()
.
get_course
(
locator
)
self
.
assertEqual
(
course
.
location
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
course
.
location
.
packag
e_id
,
"GreekHero"
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D0
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D0
)
self
.
assertEqual
(
course
.
category
,
'course'
)
self
.
assertEqual
(
course
.
category
,
'course'
)
self
.
assertEqual
(
len
(
course
.
tabs
),
6
)
self
.
assertEqual
(
len
(
course
.
tabs
),
6
)
...
@@ -216,24 +216,24 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -216,24 +216,24 @@ class SplitModuleCourseTests(SplitModuleTest):
self
.
assertEqual
(
course
.
edited_by
,
"testassist@edx.org"
)
self
.
assertEqual
(
course
.
edited_by
,
"testassist@edx.org"
)
self
.
assertDictEqual
(
course
.
grade_cutoffs
,
{
"Pass"
:
0.45
})
self
.
assertDictEqual
(
course
.
grade_cutoffs
,
{
"Pass"
:
0.45
})
locator
=
CourseLocator
(
cours
e_id
=
'wonderful'
,
branch
=
'published'
)
locator
=
CourseLocator
(
packag
e_id
=
'wonderful'
,
branch
=
'published'
)
course
=
modulestore
()
.
get_course
(
locator
)
course
=
modulestore
()
.
get_course
(
locator
)
self
.
assertEqual
(
course
.
location
.
cours
e_id
,
"wonderful"
)
self
.
assertEqual
(
course
.
location
.
packag
e_id
,
"wonderful"
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_P
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_P
)
locator
=
CourseLocator
(
cours
e_id
=
'wonderful'
,
branch
=
'draft'
)
locator
=
CourseLocator
(
packag
e_id
=
'wonderful'
,
branch
=
'draft'
)
course
=
modulestore
()
.
get_course
(
locator
)
course
=
modulestore
()
.
get_course
(
locator
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D2
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D2
)
def
test_get_course_negative
(
self
):
def
test_get_course_negative
(
self
):
# Now negative testing
# Now negative testing
self
.
assertRaises
(
InsufficientSpecificationError
,
self
.
assertRaises
(
InsufficientSpecificationError
,
modulestore
()
.
get_course
,
CourseLocator
(
cours
e_id
=
'edu.meh.blah'
))
modulestore
()
.
get_course
,
CourseLocator
(
packag
e_id
=
'edu.meh.blah'
))
self
.
assertRaises
(
ItemNotFoundError
,
self
.
assertRaises
(
ItemNotFoundError
,
modulestore
()
.
get_course
,
CourseLocator
(
cours
e_id
=
'nosuchthing'
,
branch
=
'draft'
))
modulestore
()
.
get_course
,
CourseLocator
(
packag
e_id
=
'nosuchthing'
,
branch
=
'draft'
))
self
.
assertRaises
(
ItemNotFoundError
,
self
.
assertRaises
(
ItemNotFoundError
,
modulestore
()
.
get_course
,
modulestore
()
.
get_course
,
CourseLocator
(
cours
e_id
=
'GreekHero'
,
branch
=
'published'
))
CourseLocator
(
packag
e_id
=
'GreekHero'
,
branch
=
'published'
))
def
test_cache
(
self
):
def
test_cache
(
self
):
"""
"""
...
@@ -252,7 +252,7 @@ class SplitModuleCourseTests(SplitModuleTest):
...
@@ -252,7 +252,7 @@ class SplitModuleCourseTests(SplitModuleTest):
locator
=
CourseLocator
(
version_guid
=
self
.
GUID_D3
)
locator
=
CourseLocator
(
version_guid
=
self
.
GUID_D3
)
result
=
modulestore
()
.
get_course_successors
(
locator
)
result
=
modulestore
()
.
get_course_successors
(
locator
)
self
.
assertIsInstance
(
result
,
VersionTree
)
self
.
assertIsInstance
(
result
,
VersionTree
)
self
.
assertIsNone
(
result
.
locator
.
cours
e_id
)
self
.
assertIsNone
(
result
.
locator
.
packag
e_id
)
self
.
assertEqual
(
str
(
result
.
locator
.
version_guid
),
self
.
GUID_D3
)
self
.
assertEqual
(
str
(
result
.
locator
.
version_guid
),
self
.
GUID_D3
)
self
.
assertEqual
(
len
(
result
.
children
),
1
)
self
.
assertEqual
(
len
(
result
.
children
),
1
)
self
.
assertEqual
(
str
(
result
.
children
[
0
]
.
locator
.
version_guid
),
self
.
GUID_D1
)
self
.
assertEqual
(
str
(
result
.
children
[
0
]
.
locator
.
version_guid
),
self
.
GUID_D1
)
...
@@ -275,71 +275,71 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -275,71 +275,71 @@ class SplitModuleItemTests(SplitModuleTest):
'''
'''
has_item(BlockUsageLocator)
has_item(BlockUsageLocator)
'''
'''
cours
e_id
=
'GreekHero'
packag
e_id
=
'GreekHero'
# positive tests of various forms
# positive tests of various forms
locator
=
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
,
block_id
=
'head12345'
)
locator
=
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
,
block_id
=
'head12345'
)
self
.
assertTrue
(
modulestore
()
.
has_item
(
cours
e_id
,
locator
),
self
.
assertTrue
(
modulestore
()
.
has_item
(
packag
e_id
,
locator
),
"couldn't find in
%
s"
%
self
.
GUID_D1
)
"couldn't find in
%
s"
%
self
.
GUID_D1
)
locator
=
BlockUsageLocator
(
cours
e_id
=
'GreekHero'
,
block_id
=
'head12345'
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
'GreekHero'
,
block_id
=
'head12345'
,
branch
=
'draft'
)
self
.
assertTrue
(
self
.
assertTrue
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
locator
),
modulestore
()
.
has_item
(
locator
.
packag
e_id
,
locator
),
"couldn't find in 12345"
"couldn't find in 12345"
)
)
self
.
assertTrue
(
self
.
assertTrue
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
BlockUsageLocator
(
modulestore
()
.
has_item
(
locator
.
packag
e_id
,
BlockUsageLocator
(
course_id
=
locator
.
cours
e_id
,
package_id
=
locator
.
packag
e_id
,
branch
=
'draft'
,
branch
=
'draft'
,
block_id
=
locator
.
block_id
block_id
=
locator
.
block_id
)),
)),
"couldn't find in draft 12345"
"couldn't find in draft 12345"
)
)
self
.
assertFalse
(
self
.
assertFalse
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
BlockUsageLocator
(
modulestore
()
.
has_item
(
locator
.
packag
e_id
,
BlockUsageLocator
(
course_id
=
locator
.
cours
e_id
,
package_id
=
locator
.
packag
e_id
,
branch
=
'published'
,
branch
=
'published'
,
block_id
=
locator
.
block_id
)),
block_id
=
locator
.
block_id
)),
"found in published 12345"
"found in published 12345"
)
)
locator
.
branch
=
'draft'
locator
.
branch
=
'draft'
self
.
assertTrue
(
self
.
assertTrue
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
locator
),
modulestore
()
.
has_item
(
locator
.
packag
e_id
,
locator
),
"not found in draft 12345"
"not found in draft 12345"
)
)
# not a course obj
# not a course obj
locator
=
BlockUsageLocator
(
cours
e_id
=
'GreekHero'
,
block_id
=
'chapter1'
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
'GreekHero'
,
block_id
=
'chapter1'
,
branch
=
'draft'
)
self
.
assertTrue
(
self
.
assertTrue
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
locator
),
modulestore
()
.
has_item
(
locator
.
packag
e_id
,
locator
),
"couldn't find chapter1"
"couldn't find chapter1"
)
)
# in published course
# in published course
locator
=
BlockUsageLocator
(
cours
e_id
=
"wonderful"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
"wonderful"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
self
.
assertTrue
(
self
.
assertTrue
(
modulestore
()
.
has_item
(
modulestore
()
.
has_item
(
locator
.
cours
e_id
,
locator
.
packag
e_id
,
BlockUsageLocator
(
course_id
=
locator
.
cours
e_id
,
block_id
=
locator
.
block_id
,
branch
=
'published'
)
BlockUsageLocator
(
package_id
=
locator
.
packag
e_id
,
block_id
=
locator
.
block_id
,
branch
=
'published'
)
),
"couldn't find in 23456"
),
"couldn't find in 23456"
)
)
locator
.
branch
=
'published'
locator
.
branch
=
'published'
self
.
assertTrue
(
modulestore
()
.
has_item
(
cours
e_id
,
locator
),
"couldn't find in 23456"
)
self
.
assertTrue
(
modulestore
()
.
has_item
(
packag
e_id
,
locator
),
"couldn't find in 23456"
)
def
test_negative_has_item
(
self
):
def
test_negative_has_item
(
self
):
# negative tests--not found
# negative tests--not found
# no such course or block
# no such course or block
cours
e_id
=
'GreekHero'
packag
e_id
=
'GreekHero'
locator
=
BlockUsageLocator
(
cours
e_id
=
"doesnotexist"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
"doesnotexist"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
self
.
assertFalse
(
modulestore
()
.
has_item
(
cours
e_id
,
locator
))
self
.
assertFalse
(
modulestore
()
.
has_item
(
packag
e_id
,
locator
))
locator
=
BlockUsageLocator
(
cours
e_id
=
"wonderful"
,
block_id
=
"doesnotexist"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
"wonderful"
,
block_id
=
"doesnotexist"
,
branch
=
'draft'
)
self
.
assertFalse
(
modulestore
()
.
has_item
(
cours
e_id
,
locator
))
self
.
assertFalse
(
modulestore
()
.
has_item
(
packag
e_id
,
locator
))
# negative tests--insufficient specification
# negative tests--insufficient specification
self
.
assertRaises
(
InsufficientSpecificationError
,
BlockUsageLocator
)
self
.
assertRaises
(
InsufficientSpecificationError
,
BlockUsageLocator
)
self
.
assertRaises
(
InsufficientSpecificationError
,
self
.
assertRaises
(
InsufficientSpecificationError
,
modulestore
()
.
has_item
,
None
,
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
))
modulestore
()
.
has_item
,
None
,
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
))
self
.
assertRaises
(
InsufficientSpecificationError
,
self
.
assertRaises
(
InsufficientSpecificationError
,
modulestore
()
.
has_item
,
None
,
BlockUsageLocator
(
cours
e_id
=
'GreekHero'
))
modulestore
()
.
has_item
,
None
,
BlockUsageLocator
(
packag
e_id
=
'GreekHero'
))
def
test_get_item
(
self
):
def
test_get_item
(
self
):
'''
'''
...
@@ -349,11 +349,11 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -349,11 +349,11 @@ class SplitModuleItemTests(SplitModuleTest):
locator
=
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
,
block_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
cours
e_id
# get_instance just redirects to get_item, ignores
packag
e_id
self
.
assertIsInstance
(
modulestore
()
.
get_instance
(
"
cours
e_id"
,
locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
modulestore
()
.
get_instance
(
"
packag
e_id"
,
locator
),
CourseDescriptor
)
def
verify_greek_hero
(
block
):
def
verify_greek_hero
(
block
):
self
.
assertEqual
(
block
.
location
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
block
.
location
.
packag
e_id
,
"GreekHero"
)
self
.
assertEqual
(
len
(
block
.
tabs
),
6
,
"wrong number of tabs"
)
self
.
assertEqual
(
len
(
block
.
tabs
),
6
,
"wrong number of tabs"
)
self
.
assertEqual
(
block
.
display_name
,
"The Ancient Greek Hero"
)
self
.
assertEqual
(
block
.
display_name
,
"The Ancient Greek Hero"
)
self
.
assertEqual
(
block
.
advertised_start
,
"Fall 2013"
)
self
.
assertEqual
(
block
.
advertised_start
,
"Fall 2013"
)
...
@@ -365,15 +365,15 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -365,15 +365,15 @@ class SplitModuleItemTests(SplitModuleTest):
block
.
grade_cutoffs
,
{
"Pass"
:
0.45
},
block
.
grade_cutoffs
,
{
"Pass"
:
0.45
},
)
)
locator
=
BlockUsageLocator
(
cours
e_id
=
'GreekHero'
,
block_id
=
'head12345'
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
cours
e_id
# get_instance just redirects to get_item, ignores
packag
e_id
verify_greek_hero
(
modulestore
()
.
get_instance
(
"
cours
e_id"
,
locator
))
verify_greek_hero
(
modulestore
()
.
get_instance
(
"
packag
e_id"
,
locator
))
# try to look up other branches
# try to look up other branches
self
.
assertRaises
(
ItemNotFoundError
,
self
.
assertRaises
(
ItemNotFoundError
,
modulestore
()
.
get_item
,
modulestore
()
.
get_item
,
BlockUsageLocator
(
cours
e_id
=
locator
.
as_course_locator
(),
BlockUsageLocator
(
packag
e_id
=
locator
.
as_course_locator
(),
block_id
=
locator
.
block_id
,
block_id
=
locator
.
block_id
,
branch
=
'published'
))
branch
=
'published'
))
locator
.
branch
=
'draft'
locator
.
branch
=
'draft'
...
@@ -384,16 +384,16 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -384,16 +384,16 @@ 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
(
cours
e_id
=
'GreekHero'
,
block_id
=
'chapter1'
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
'GreekHero'
,
block_id
=
'chapter1'
,
branch
=
'draft'
)
block
=
modulestore
()
.
get_item
(
locator
)
block
=
modulestore
()
.
get_item
(
locator
)
self
.
assertEqual
(
block
.
location
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
block
.
location
.
packag
e_id
,
"GreekHero"
)
self
.
assertEqual
(
block
.
category
,
'chapter'
)
self
.
assertEqual
(
block
.
category
,
'chapter'
)
self
.
assertEqual
(
str
(
block
.
definition_locator
.
definition_id
),
"cd00000000000000dddd0020"
)
self
.
assertEqual
(
str
(
block
.
definition_locator
.
definition_id
),
"cd00000000000000dddd0020"
)
self
.
assertEqual
(
block
.
display_name
,
"Hercules"
)
self
.
assertEqual
(
block
.
display_name
,
"Hercules"
)
self
.
assertEqual
(
block
.
edited_by
,
"testassist@edx.org"
)
self
.
assertEqual
(
block
.
edited_by
,
"testassist@edx.org"
)
# in published course
# in published course
locator
=
BlockUsageLocator
(
cours
e_id
=
"wonderful"
,
block_id
=
"head23456"
,
branch
=
'published'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
"wonderful"
,
block_id
=
"head23456"
,
branch
=
'published'
)
self
.
assertIsInstance
(
self
.
assertIsInstance
(
modulestore
()
.
get_item
(
locator
),
modulestore
()
.
get_item
(
locator
),
CourseDescriptor
CourseDescriptor
...
@@ -401,10 +401,10 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -401,10 +401,10 @@ class SplitModuleItemTests(SplitModuleTest):
# negative tests--not found
# negative tests--not found
# no such course or block
# no such course or block
locator
=
BlockUsageLocator
(
cours
e_id
=
"doesnotexist"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
(
cours
e_id
=
"wonderful"
,
block_id
=
"doesnotexist"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_id
=
"wonderful"
,
block_id
=
"doesnotexist"
,
branch
=
'draft'
)
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
modulestore
()
.
get_item
(
locator
)
modulestore
()
.
get_item
(
locator
)
...
@@ -412,7 +412,7 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -412,7 +412,7 @@ class SplitModuleItemTests(SplitModuleTest):
with
self
.
assertRaises
(
InsufficientSpecificationError
):
with
self
.
assertRaises
(
InsufficientSpecificationError
):
modulestore
()
.
get_item
(
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
))
modulestore
()
.
get_item
(
BlockUsageLocator
(
version_guid
=
self
.
GUID_D1
))
with
self
.
assertRaises
(
InsufficientSpecificationError
):
with
self
.
assertRaises
(
InsufficientSpecificationError
):
modulestore
()
.
get_item
(
BlockUsageLocator
(
cours
e_id
=
'GreekHero'
,
branch
=
'draft'
))
modulestore
()
.
get_item
(
BlockUsageLocator
(
packag
e_id
=
'GreekHero'
,
branch
=
'draft'
))
# pylint: disable=W0212
# pylint: disable=W0212
def
test_matching
(
self
):
def
test_matching
(
self
):
...
@@ -473,11 +473,11 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -473,11 +473,11 @@ class SplitModuleItemTests(SplitModuleTest):
'''
'''
get_parent_locations(locator, [block_id], [branch]): [BlockUsageLocator]
get_parent_locations(locator, [block_id], [branch]): [BlockUsageLocator]
'''
'''
locator
=
BlockUsageLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
,
block_id
=
'chapter1'
)
locator
=
BlockUsageLocator
(
packag
e_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
]
.
block_id
,
'head12345'
)
self
.
assertEqual
(
parents
[
0
]
.
block_id
,
'head12345'
)
self
.
assertEqual
(
parents
[
0
]
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
parents
[
0
]
.
packag
e_id
,
"GreekHero"
)
locator
.
block_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
)
...
@@ -490,7 +490,7 @@ class SplitModuleItemTests(SplitModuleTest):
...
@@ -490,7 +490,7 @@ class SplitModuleItemTests(SplitModuleTest):
"""
"""
Test the existing get_children method on xdescriptors
Test the existing get_children method on xdescriptors
"""
"""
locator
=
BlockUsageLocator
(
cours
e_id
=
"GreekHero"
,
block_id
=
"head12345"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
=
[
...
@@ -532,7 +532,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -532,7 +532,7 @@ class TestItemCrud(SplitModuleTest):
create_item(course_or_parent_locator, category, user, definition_locator=None, fields): new_desciptor
create_item(course_or_parent_locator, category, user, definition_locator=None, fields): new_desciptor
"""
"""
# grab link to course to ensure new versioning works
# grab link to course to ensure new versioning works
locator
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
)
locator
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
'draft'
)
premod_course
=
modulestore
()
.
get_course
(
locator
)
premod_course
=
modulestore
()
.
get_course
(
locator
)
premod_time
=
datetime
.
datetime
.
now
(
UTC
)
-
datetime
.
timedelta
(
seconds
=
1
)
premod_time
=
datetime
.
datetime
.
now
(
UTC
)
-
datetime
.
timedelta
(
seconds
=
1
)
# add minimal one w/o a parent
# add minimal one w/o a parent
...
@@ -542,7 +542,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -542,7 +542,7 @@ class TestItemCrud(SplitModuleTest):
fields
=
{
'display_name'
:
'new sequential'
}
fields
=
{
'display_name'
:
'new sequential'
}
)
)
# 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
.
assertEqual
(
new_module
.
location
.
cours
e_id
,
"GreekHero"
)
self
.
assertEqual
(
new_module
.
location
.
packag
e_id
,
"GreekHero"
)
self
.
assertNotEqual
(
new_module
.
location
.
version_guid
,
premod_course
.
location
.
version_guid
)
self
.
assertNotEqual
(
new_module
.
location
.
version_guid
,
premod_course
.
location
.
version_guid
)
self
.
assertIsNone
(
locator
.
version_guid
,
"Version inadvertently filled in"
)
self
.
assertIsNone
(
locator
.
version_guid
,
"Version inadvertently filled in"
)
current_course
=
modulestore
()
.
get_course
(
locator
)
current_course
=
modulestore
()
.
get_course
(
locator
)
...
@@ -569,7 +569,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -569,7 +569,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
(
cours
e_id
=
"wonderful"
,
block_id
=
"head23456"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
(
...
@@ -589,7 +589,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -589,7 +589,7 @@ class TestItemCrud(SplitModuleTest):
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
(
cours
e_id
=
"contender"
,
block_id
=
"head345679"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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>"
...
@@ -633,7 +633,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -633,7 +633,7 @@ class TestItemCrud(SplitModuleTest):
course_block_update_version
=
new_course
.
update_version
course_block_update_version
=
new_course
.
update_version
self
.
assertIsNotNone
(
new_course_locator
.
version_guid
,
"Want to test a definite version"
)
self
.
assertIsNotNone
(
new_course_locator
.
version_guid
,
"Want to test a definite version"
)
versionless_course_locator
=
CourseLocator
(
versionless_course_locator
=
CourseLocator
(
course_id
=
new_course_locator
.
cours
e_id
,
branch
=
new_course_locator
.
branch
package_id
=
new_course_locator
.
packag
e_id
,
branch
=
new_course_locator
.
branch
)
)
# positive simple case: no force, add chapter
# positive simple case: no force, add chapter
...
@@ -687,7 +687,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -687,7 +687,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
.
cours
e_id
,
package_id
=
new_course
.
location
.
packag
e_id
,
block_id
=
new_course
.
location
.
block_id
,
block_id
=
new_course
.
location
.
block_id
,
branch
=
new_course
.
location
.
branch
branch
=
new_course
.
location
.
branch
)
)
...
@@ -709,7 +709,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -709,7 +709,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
(
cours
e_id
=
"GreekHero"
,
block_id
=
"problem3_2"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
...
@@ -747,7 +747,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -747,7 +747,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
(
cours
e_id
=
"GreekHero"
,
block_id
=
"chapter3"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
...
@@ -773,7 +773,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -773,7 +773,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
(
cours
e_id
=
"GreekHero"
,
block_id
=
"head12345"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
...
@@ -791,7 +791,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -791,7 +791,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
(
cours
e_id
=
"contender"
,
block_id
=
"head345679"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
(
...
@@ -832,7 +832,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -832,7 +832,7 @@ class TestItemCrud(SplitModuleTest):
course
.
location
,
course
.
location
,
'deleting_user'
)
'deleting_user'
)
reusable_location
=
BlockUsageLocator
(
reusable_location
=
BlockUsageLocator
(
course_id
=
course
.
location
.
cours
e_id
,
package_id
=
course
.
location
.
packag
e_id
,
block_id
=
course
.
location
.
block_id
,
block_id
=
course
.
location
.
block_id
,
branch
=
'draft'
)
branch
=
'draft'
)
...
@@ -840,16 +840,16 @@ class TestItemCrud(SplitModuleTest):
...
@@ -840,16 +840,16 @@ class TestItemCrud(SplitModuleTest):
problems
=
modulestore
()
.
get_items
(
reusable_location
,
{
'category'
:
'problem'
})
problems
=
modulestore
()
.
get_items
(
reusable_location
,
{
'category'
:
'problem'
})
locn_to_del
=
problems
[
0
]
.
location
locn_to_del
=
problems
[
0
]
.
location
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
.
cours
e_id
,
deleted
=
BlockUsageLocator
(
package_id
=
reusable_location
.
packag
e_id
,
branch
=
reusable_location
.
branch
,
branch
=
reusable_location
.
branch
,
block_id
=
locn_to_del
.
block_id
)
block_id
=
locn_to_del
.
block_id
)
self
.
assertFalse
(
modulestore
()
.
has_item
(
reusable_location
.
cours
e_id
,
deleted
))
self
.
assertFalse
(
modulestore
()
.
has_item
(
reusable_location
.
packag
e_id
,
deleted
))
self
.
assertRaises
(
VersionConflictError
,
modulestore
()
.
has_item
,
reusable_location
.
cours
e_id
,
locn_to_del
)
self
.
assertRaises
(
VersionConflictError
,
modulestore
()
.
has_item
,
reusable_location
.
packag
e_id
,
locn_to_del
)
locator
=
BlockUsageLocator
(
locator
=
BlockUsageLocator
(
version_guid
=
locn_to_del
.
version_guid
,
version_guid
=
locn_to_del
.
version_guid
,
block_id
=
locn_to_del
.
block_id
block_id
=
locn_to_del
.
block_id
)
)
self
.
assertTrue
(
modulestore
()
.
has_item
(
reusable_location
.
cours
e_id
,
locator
))
self
.
assertTrue
(
modulestore
()
.
has_item
(
reusable_location
.
packag
e_id
,
locator
))
self
.
assertNotEqual
(
new_course_loc
.
version_guid
,
course
.
location
.
version_guid
)
self
.
assertNotEqual
(
new_course_loc
.
version_guid
,
course
.
location
.
version_guid
)
# delete a subtree
# delete a subtree
...
@@ -860,15 +860,15 @@ class TestItemCrud(SplitModuleTest):
...
@@ -860,15 +860,15 @@ class TestItemCrud(SplitModuleTest):
def
check_subtree
(
node
):
def
check_subtree
(
node
):
if
node
:
if
node
:
node_loc
=
node
.
location
node_loc
=
node
.
location
self
.
assertFalse
(
modulestore
()
.
has_item
(
reusable_location
.
cours
e_id
,
self
.
assertFalse
(
modulestore
()
.
has_item
(
reusable_location
.
packag
e_id
,
BlockUsageLocator
(
BlockUsageLocator
(
course_id
=
node_loc
.
cours
e_id
,
package_id
=
node_loc
.
packag
e_id
,
branch
=
node_loc
.
branch
,
branch
=
node_loc
.
branch
,
block_id
=
node
.
location
.
block_id
)))
block_id
=
node
.
location
.
block_id
)))
locator
=
BlockUsageLocator
(
locator
=
BlockUsageLocator
(
version_guid
=
node
.
location
.
version_guid
,
version_guid
=
node
.
location
.
version_guid
,
block_id
=
node
.
location
.
block_id
)
block_id
=
node
.
location
.
block_id
)
self
.
assertTrue
(
modulestore
()
.
has_item
(
reusable_location
.
cours
e_id
,
locator
))
self
.
assertTrue
(
modulestore
()
.
has_item
(
reusable_location
.
packag
e_id
,
locator
))
if
node
.
has_children
:
if
node
.
has_children
:
for
sub
in
node
.
get_children
():
for
sub
in
node
.
get_children
():
check_subtree
(
sub
)
check_subtree
(
sub
)
...
@@ -877,7 +877,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -877,7 +877,7 @@ class TestItemCrud(SplitModuleTest):
def
create_course_for_deletion
(
self
):
def
create_course_for_deletion
(
self
):
course
=
modulestore
()
.
create_course
(
'nihilx'
,
'deletion'
,
'deleting_user'
)
course
=
modulestore
()
.
create_course
(
'nihilx'
,
'deletion'
,
'deleting_user'
)
root
=
BlockUsageLocator
(
root
=
BlockUsageLocator
(
course_id
=
course
.
location
.
cours
e_id
,
package_id
=
course
.
location
.
packag
e_id
,
block_id
=
course
.
location
.
block_id
,
block_id
=
course
.
location
.
block_id
,
branch
=
'draft'
)
branch
=
'draft'
)
for
_
in
range
(
4
):
for
_
in
range
(
4
):
...
@@ -934,13 +934,13 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -934,13 +934,13 @@ class TestCourseCreation(SplitModuleTest):
Test making a course which points to an existing draft and published but not making any changes to either.
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
)
pre_time
=
datetime
.
datetime
.
now
(
UTC
)
original_locator
=
CourseLocator
(
cours
e_id
=
"wonderful"
,
branch
=
'draft'
)
original_locator
=
CourseLocator
(
packag
e_id
=
"wonderful"
,
branch
=
'draft'
)
original_index
=
modulestore
()
.
get_course_index_info
(
original_locator
)
original_index
=
modulestore
()
.
get_course_index_info
(
original_locator
)
new_draft
=
modulestore
()
.
create_course
(
new_draft
=
modulestore
()
.
create_course
(
'leech'
,
'best_course'
,
'leech_master'
,
id_root
=
'best'
,
'leech'
,
'best_course'
,
'leech_master'
,
id_root
=
'best'
,
versions_dict
=
original_index
[
'versions'
])
versions_dict
=
original_index
[
'versions'
])
new_draft_locator
=
new_draft
.
location
new_draft_locator
=
new_draft
.
location
self
.
assertRegexpMatches
(
new_draft_locator
.
cours
e_id
,
r'best.*'
)
self
.
assertRegexpMatches
(
new_draft_locator
.
packag
e_id
,
r'best.*'
)
# the edited_by and other meta fields on the new course will be the original author not this one
# the edited_by and other meta fields on the new course will be the original author not this one
self
.
assertEqual
(
new_draft
.
edited_by
,
'test@edx.org'
)
self
.
assertEqual
(
new_draft
.
edited_by
,
'test@edx.org'
)
self
.
assertLess
(
new_draft
.
edited_on
,
pre_time
)
self
.
assertLess
(
new_draft
.
edited_on
,
pre_time
)
...
@@ -951,7 +951,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -951,7 +951,7 @@ class TestCourseCreation(SplitModuleTest):
self
.
assertLessEqual
(
new_index
[
"edited_on"
],
datetime
.
datetime
.
now
(
UTC
))
self
.
assertLessEqual
(
new_index
[
"edited_on"
],
datetime
.
datetime
.
now
(
UTC
))
self
.
assertEqual
(
new_index
[
'edited_by'
],
'leech_master'
)
self
.
assertEqual
(
new_index
[
'edited_by'
],
'leech_master'
)
new_published_locator
=
CourseLocator
(
course_id
=
new_draft_locator
.
cours
e_id
,
branch
=
'published'
)
new_published_locator
=
CourseLocator
(
package_id
=
new_draft_locator
.
packag
e_id
,
branch
=
'published'
)
new_published
=
modulestore
()
.
get_course
(
new_published_locator
)
new_published
=
modulestore
()
.
get_course
(
new_published_locator
)
self
.
assertEqual
(
new_published
.
edited_by
,
'test@edx.org'
)
self
.
assertEqual
(
new_published
.
edited_by
,
'test@edx.org'
)
self
.
assertLess
(
new_published
.
edited_on
,
pre_time
)
self
.
assertLess
(
new_published
.
edited_on
,
pre_time
)
...
@@ -979,7 +979,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -979,7 +979,7 @@ class TestCourseCreation(SplitModuleTest):
original_course
=
modulestore
()
.
get_course
(
original_locator
)
original_course
=
modulestore
()
.
get_course
(
original_locator
)
self
.
assertEqual
(
original_course
.
location
.
version_guid
,
original_index
[
'versions'
][
'draft'
])
self
.
assertEqual
(
original_course
.
location
.
version_guid
,
original_index
[
'versions'
][
'draft'
])
self
.
assertFalse
(
self
.
assertFalse
(
modulestore
()
.
has_item
(
new_draft_locator
.
cours
e_id
,
BlockUsageLocator
(
modulestore
()
.
has_item
(
new_draft_locator
.
packag
e_id
,
BlockUsageLocator
(
original_locator
,
original_locator
,
block_id
=
new_item
.
location
.
block_id
block_id
=
new_item
.
location
.
block_id
))
))
...
@@ -990,7 +990,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -990,7 +990,7 @@ class TestCourseCreation(SplitModuleTest):
Create a new course which overrides metadata and course_data
Create a new course which overrides metadata and course_data
"""
"""
pre_time
=
datetime
.
datetime
.
now
(
UTC
)
pre_time
=
datetime
.
datetime
.
now
(
UTC
)
original_locator
=
CourseLocator
(
cours
e_id
=
"contender"
,
branch
=
'draft'
)
original_locator
=
CourseLocator
(
packag
e_id
=
"contender"
,
branch
=
'draft'
)
original
=
modulestore
()
.
get_course
(
original_locator
)
original
=
modulestore
()
.
get_course
(
original_locator
)
original_index
=
modulestore
()
.
get_course_index_info
(
original_locator
)
original_index
=
modulestore
()
.
get_course_index_info
(
original_locator
)
fields
=
{}
fields
=
{}
...
@@ -1007,7 +1007,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -1007,7 +1007,7 @@ class TestCourseCreation(SplitModuleTest):
fields
=
fields
fields
=
fields
)
)
new_draft_locator
=
new_draft
.
location
new_draft_locator
=
new_draft
.
location
self
.
assertRegexpMatches
(
new_draft_locator
.
cours
e_id
,
r'counter.*'
)
self
.
assertRegexpMatches
(
new_draft_locator
.
packag
e_id
,
r'counter.*'
)
# the edited_by and other meta fields on the new course will be the original author not this one
# the edited_by and other meta fields on the new course will be the original author not this one
self
.
assertEqual
(
new_draft
.
edited_by
,
'leech_master'
)
self
.
assertEqual
(
new_draft
.
edited_by
,
'leech_master'
)
self
.
assertGreaterEqual
(
new_draft
.
edited_on
,
pre_time
)
self
.
assertGreaterEqual
(
new_draft
.
edited_on
,
pre_time
)
...
@@ -1027,7 +1027,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -1027,7 +1027,7 @@ class TestCourseCreation(SplitModuleTest):
"""
"""
Test changing the org, pretty id, etc of a course. Test that it doesn't allow changing the id, etc.
Test changing the org, pretty id, etc of a course. Test that it doesn't allow changing the id, etc.
"""
"""
locator
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
)
locator
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
'draft'
)
course_info
=
modulestore
()
.
get_course_index_info
(
locator
)
course_info
=
modulestore
()
.
get_course_index_info
(
locator
)
course_info
[
'org'
]
=
'funkyU'
course_info
[
'org'
]
=
'funkyU'
modulestore
()
.
update_course_index
(
course_info
)
modulestore
()
.
update_course_index
(
course_info
)
...
@@ -1051,7 +1051,7 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -1051,7 +1051,7 @@ class TestCourseCreation(SplitModuleTest):
# an allowed but not recommended way to publish a course
# an allowed but not recommended way to publish a course
versions
[
'published'
]
=
self
.
GUID_D1
versions
[
'published'
]
=
self
.
GUID_D1
modulestore
()
.
update_course_index
(
course_info
)
modulestore
()
.
update_course_index
(
course_info
)
course
=
modulestore
()
.
get_course
(
CourseLocator
(
course_id
=
locator
.
cours
e_id
,
branch
=
"published"
))
course
=
modulestore
()
.
get_course
(
CourseLocator
(
package_id
=
locator
.
packag
e_id
,
branch
=
"published"
))
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D1
)
self
.
assertEqual
(
str
(
course
.
location
.
version_guid
),
self
.
GUID_D1
)
def
test_create_with_root
(
self
):
def
test_create_with_root
(
self
):
...
@@ -1086,11 +1086,11 @@ class TestInheritance(SplitModuleTest):
...
@@ -1086,11 +1086,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
(
cours
e_id
=
"GreekHero"
,
block_id
=
"problem3_2"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
(
cours
e_id
=
"GreekHero"
,
block_id
=
"problem1"
,
branch
=
'draft'
)
locator
=
BlockUsageLocator
(
packag
e_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
))
...
@@ -1111,8 +1111,8 @@ class TestPublish(SplitModuleTest):
...
@@ -1111,8 +1111,8 @@ class TestPublish(SplitModuleTest):
"""
"""
Test the standard patterns: publish to new branch, revise and publish
Test the standard patterns: publish to new branch, revise and publish
"""
"""
source_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
)
source_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
'draft'
)
dest_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
"published"
)
dest_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
"published"
)
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
dest_course
,
[
"head12345"
],
[
"chapter2"
,
"chapter3"
])
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
dest_course
,
[
"head12345"
],
[
"chapter2"
,
"chapter3"
])
expected
=
[
"head12345"
,
"chapter1"
]
expected
=
[
"head12345"
,
"chapter1"
]
self
.
_check_course
(
self
.
_check_course
(
...
@@ -1153,13 +1153,13 @@ class TestPublish(SplitModuleTest):
...
@@ -1153,13 +1153,13 @@ class TestPublish(SplitModuleTest):
"""
"""
Test the exceptions which preclude successful publication
Test the exceptions which preclude successful publication
"""
"""
source_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
)
source_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
'draft'
)
# destination does not exist
# destination does not exist
destination_course
=
CourseLocator
(
cours
e_id
=
"Unknown"
,
branch
=
"published"
)
destination_course
=
CourseLocator
(
packag
e_id
=
"Unknown"
,
branch
=
"published"
)
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
destination_course
,
[
"chapter3"
],
None
)
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
destination_course
,
[
"chapter3"
],
None
)
# publishing into a new branch w/o publishing the root
# publishing into a new branch w/o publishing the root
destination_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
"published"
)
destination_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
"published"
)
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
destination_course
,
[
"chapter3"
],
None
)
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
destination_course
,
[
"chapter3"
],
None
)
# publishing a subdag w/o the parent already in course
# publishing a subdag w/o the parent already in course
...
@@ -1171,8 +1171,8 @@ class TestPublish(SplitModuleTest):
...
@@ -1171,8 +1171,8 @@ class TestPublish(SplitModuleTest):
"""
"""
Test publishing moves and deletes.
Test publishing moves and deletes.
"""
"""
source_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
'draft'
)
source_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
'draft'
)
dest_course
=
CourseLocator
(
cours
e_id
=
"GreekHero"
,
branch
=
"published"
)
dest_course
=
CourseLocator
(
packag
e_id
=
"GreekHero"
,
branch
=
"published"
)
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
dest_course
,
[
"head12345"
],
[
"chapter2"
])
modulestore
()
.
xblock_publish
(
self
.
user
,
source_course
,
dest_course
,
[
"head12345"
],
[
"chapter2"
])
expected
=
[
"head12345"
,
"chapter1"
,
"chapter3"
,
"problem1"
,
"problem3_2"
]
expected
=
[
"head12345"
,
"chapter1"
,
"chapter3"
,
"problem1"
,
"problem3_2"
]
self
.
_check_course
(
source_course
,
dest_course
,
expected
,
[
"chapter2"
])
self
.
_check_course
(
source_course
,
dest_course
,
expected
,
[
"chapter2"
])
...
@@ -1210,7 +1210,7 @@ class TestPublish(SplitModuleTest):
...
@@ -1210,7 +1210,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
.
cours
e_id
,
branch
=
course_loc
.
branch
,
block_id
=
block_id
)
return
BlockUsageLocator
(
package_id
=
course_loc
.
packag
e_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
):
"""
"""
...
...
lms/djangoapps/courseware/roles.py
View file @
f5f24fcc
...
@@ -10,7 +10,7 @@ from django.contrib.auth.models import User, Group
...
@@ -10,7 +10,7 @@ from django.contrib.auth.models import User, Group
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
from
xmodule.modulestore.exceptions
import
InvalidLocationError
,
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
InvalidLocationError
,
ItemNotFoundError
from
xmodule.modulestore.django
import
loc_mapper
from
xmodule.modulestore.django
import
loc_mapper
from
xmodule.modulestore.locator
import
CourseLocator
from
xmodule.modulestore.locator
import
CourseLocator
,
Locator
class
CourseContextRequired
(
Exception
):
class
CourseContextRequired
(
Exception
):
...
@@ -144,29 +144,29 @@ class CourseRole(GroupBasedRole):
...
@@ -144,29 +144,29 @@ class CourseRole(GroupBasedRole):
"""
"""
# TODO: figure out how to make the group name generation lazy so it doesn't force the
# TODO: figure out how to make the group name generation lazy so it doesn't force the
# loc mapping?
# loc mapping?
if
not
hasattr
(
location
,
'course_id'
):
location
=
Locator
.
to_locator_or_location
(
location
)
location
=
Location
(
location
)
# direct copy from auth.authz.get_all_course_role_groupnames will refactor to one impl asap
# direct copy from auth.authz.get_all_course_role_groupnames will refactor to one impl asap
groupnames
=
[]
groupnames
=
[]
try
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course_id
))
except
InvalidLocationError
:
# will occur on old locations where location is not of category course
if
course_context
is
None
:
raise
CourseContextRequired
()
else
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
course_context
))
# pylint: disable=no-member
# pylint: disable=no-member
if
isinstance
(
location
,
Location
):
if
isinstance
(
location
,
Location
):
try
:
try
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course_id
))
except
InvalidLocationError
:
# will occur on old locations where location is not of category course
if
course_context
is
None
:
raise
CourseContextRequired
()
else
:
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
course_context
))
try
:
locator
=
loc_mapper
()
.
translate_location
(
location
.
course_id
,
location
,
False
,
False
)
locator
=
loc_mapper
()
.
translate_location
(
location
.
course_id
,
location
,
False
,
False
)
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
locator
.
cours
e_id
))
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
locator
.
packag
e_id
))
except
(
InvalidLocationError
,
ItemNotFoundError
):
except
(
InvalidLocationError
,
ItemNotFoundError
):
# if it's never been mapped, the auth won't be via the Locator syntax
# if it's never been mapped, the auth won't be via the Locator syntax
pass
pass
# least preferred legacy role_course format
# least preferred legacy role_course format
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course
))
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
course
))
elif
isinstance
(
location
,
CourseLocator
):
elif
isinstance
(
location
,
CourseLocator
):
groupnames
.
append
(
'{0}_{1}'
.
format
(
role
,
location
.
package_id
))
# handle old Location syntax
# handle old Location syntax
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
,
get_course
=
True
)
old_location
=
loc_mapper
()
.
translate_locator_to_location
(
location
,
get_course
=
True
)
if
old_location
:
if
old_location
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment