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
483e2a6a
Commit
483e2a6a
authored
Jul 15, 2014
by
Calen Pennington
Committed by
Nimisha Asthagiri
Jul 18, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
split create_item and create_child out as separate methods
parent
06ef306f
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
447 additions
and
256 deletions
+447
-256
cms/djangoapps/contentstore/course_info_model.py
+2
-2
cms/djangoapps/contentstore/tests/test_contentstore.py
+2
-5
cms/djangoapps/contentstore/tests/test_crud.py
+3
-3
cms/djangoapps/contentstore/tests/test_orphan.py
+7
-1
cms/djangoapps/contentstore/tests/utils.py
+2
-2
cms/djangoapps/contentstore/views/item.py
+9
-10
cms/djangoapps/contentstore/views/tests/test_course_updates.py
+13
-4
common/lib/xmodule/xmodule/modulestore/__init__.py
+40
-63
common/lib/xmodule/xmodule/modulestore/draft_and_published.py
+2
-2
common/lib/xmodule/xmodule/modulestore/mixed.py
+60
-33
common/lib/xmodule/xmodule/modulestore/mongo/base.py
+59
-2
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
+5
-31
common/lib/xmodule/xmodule/modulestore/split_migrator.py
+4
-3
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+0
-0
common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py
+67
-18
common/lib/xmodule/xmodule/modulestore/tests/factories.py
+9
-1
common/lib/xmodule/xmodule/modulestore/tests/persistent_factories.py
+8
-1
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+0
-0
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
+93
-32
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
+1
-1
common/lib/xmodule/xmodule/modulestore/tests/test_split_draft_modulestore.py
+1
-2
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
+34
-34
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
+23
-5
common/lib/xmodule/xmodule/split_test_module.py
+3
-1
No files found.
cms/djangoapps/contentstore/course_info_model.py
View file @
483e2a6a
...
@@ -36,7 +36,7 @@ def get_course_updates(location, provided_id, user_id):
...
@@ -36,7 +36,7 @@ def get_course_updates(location, provided_id, user_id):
try
:
try
:
course_updates
=
modulestore
()
.
get_item
(
location
)
course_updates
=
modulestore
()
.
get_item
(
location
)
except
ItemNotFoundError
:
except
ItemNotFoundError
:
course_updates
=
modulestore
()
.
create_item
(
user_id
,
location
)
course_updates
=
modulestore
()
.
create_item
(
user_id
,
location
.
course_key
,
location
.
block_type
,
location
.
block_id
)
course_update_items
=
get_course_update_items
(
course_updates
,
provided_id
)
course_update_items
=
get_course_update_items
(
course_updates
,
provided_id
)
return
_get_visible_update
(
course_update_items
)
return
_get_visible_update
(
course_update_items
)
...
@@ -51,7 +51,7 @@ def update_course_updates(location, update, passed_id=None, user=None):
...
@@ -51,7 +51,7 @@ def update_course_updates(location, update, passed_id=None, user=None):
try
:
try
:
course_updates
=
modulestore
()
.
get_item
(
location
)
course_updates
=
modulestore
()
.
get_item
(
location
)
except
ItemNotFoundError
:
except
ItemNotFoundError
:
course_updates
=
modulestore
()
.
create_item
(
user
.
id
,
location
)
course_updates
=
modulestore
()
.
create_item
(
user
.
id
,
location
.
course_key
,
location
.
block_type
,
location
.
block_id
)
course_update_items
=
list
(
reversed
(
get_course_update_items
(
course_updates
)))
course_update_items
=
list
(
reversed
(
get_course_update_items
(
course_updates
)))
...
...
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
483e2a6a
...
@@ -575,7 +575,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
...
@@ -575,7 +575,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
location
=
course
.
id
.
make_usage_key
(
'chapter'
,
'neuvo'
)
location
=
course
.
id
.
make_usage_key
(
'chapter'
,
'neuvo'
)
# Ensure draft mongo store does not create drafts for things that shouldn't be draft
# Ensure draft mongo store does not create drafts for things that shouldn't be draft
newobject
=
draft_store
.
create_item
(
self
.
user
.
id
,
location
)
newobject
=
draft_store
.
create_item
(
self
.
user
.
id
,
location
.
course_key
,
location
.
block_type
,
location
.
block_id
)
self
.
assertFalse
(
getattr
(
newobject
,
'is_draft'
,
False
))
self
.
assertFalse
(
getattr
(
newobject
,
'is_draft'
,
False
))
with
self
.
assertRaises
(
InvalidVersionError
):
with
self
.
assertRaises
(
InvalidVersionError
):
draft_store
.
convert_to_draft
(
location
,
self
.
user
.
id
)
draft_store
.
convert_to_draft
(
location
,
self
.
user
.
id
)
...
@@ -1392,12 +1392,9 @@ class ContentStoreTest(ContentStoreTestCase):
...
@@ -1392,12 +1392,9 @@ class ContentStoreTest(ContentStoreTestCase):
def
test_forum_id_generation
(
self
):
def
test_forum_id_generation
(
self
):
course
=
CourseFactory
.
create
(
org
=
'edX'
,
course
=
'999'
,
display_name
=
'Robot Super Course'
)
course
=
CourseFactory
.
create
(
org
=
'edX'
,
course
=
'999'
,
display_name
=
'Robot Super Course'
)
new_component_location
=
course
.
id
.
make_usage_key
(
'discussion'
,
'new_component'
)
# crate a new module and add it as a child to a vertical
# crate a new module and add it as a child to a vertical
self
.
store
.
create_item
(
self
.
user
.
id
,
new_component_location
)
new_discussion_item
=
self
.
store
.
create_item
(
self
.
user
.
id
,
course
.
id
,
'discussion'
,
'new_component'
)
new_discussion_item
=
self
.
store
.
get_item
(
new_component_location
)
self
.
assertNotEquals
(
new_discussion_item
.
discussion_id
,
'$$GUID$$'
)
self
.
assertNotEquals
(
new_discussion_item
.
discussion_id
,
'$$GUID$$'
)
...
...
cms/djangoapps/contentstore/tests/test_crud.py
View file @
483e2a6a
...
@@ -162,7 +162,7 @@ class TemplateTests(unittest.TestCase):
...
@@ -162,7 +162,7 @@ class TemplateTests(unittest.TestCase):
self
.
assertIsInstance
(
self
.
split_store
.
get_course
(
id_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
self
.
split_store
.
get_course
(
id_locator
),
CourseDescriptor
)
# and by guid
# and by guid
self
.
assertIsInstance
(
self
.
split_store
.
get_item
(
guid_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
self
.
split_store
.
get_item
(
guid_locator
),
CourseDescriptor
)
self
.
split_store
.
delete_course
(
id_locator
,
ModuleStoreEnum
.
UserID
.
test
)
self
.
split_store
.
delete_course
(
id_locator
,
'testbot'
)
# test can no longer retrieve by id
# test can no longer retrieve by id
self
.
assertRaises
(
ItemNotFoundError
,
self
.
split_store
.
get_course
,
id_locator
)
self
.
assertRaises
(
ItemNotFoundError
,
self
.
split_store
.
get_course
,
id_locator
)
# but can by guid
# but can by guid
...
@@ -187,11 +187,11 @@ class TemplateTests(unittest.TestCase):
...
@@ -187,11 +187,11 @@ class TemplateTests(unittest.TestCase):
)
)
first_problem
.
max_attempts
=
3
first_problem
.
max_attempts
=
3
first_problem
.
save
()
# decache the above into the kvs
first_problem
.
save
()
# decache the above into the kvs
updated_problem
=
self
.
split_store
.
update_item
(
first_problem
,
ModuleStoreEnum
.
UserID
.
test
)
updated_problem
=
self
.
split_store
.
update_item
(
first_problem
,
'testbot'
)
self
.
assertIsNotNone
(
updated_problem
.
previous_version
)
self
.
assertIsNotNone
(
updated_problem
.
previous_version
)
self
.
assertEqual
(
updated_problem
.
previous_version
,
first_problem
.
update_version
)
self
.
assertEqual
(
updated_problem
.
previous_version
,
first_problem
.
update_version
)
self
.
assertNotEqual
(
updated_problem
.
update_version
,
first_problem
.
update_version
)
self
.
assertNotEqual
(
updated_problem
.
update_version
,
first_problem
.
update_version
)
self
.
split_store
.
delete_item
(
updated_problem
.
location
,
ModuleStoreEnum
.
UserID
.
test
,
'testbot'
)
self
.
split_store
.
delete_item
(
updated_problem
.
location
,
'testbot'
)
second_problem
=
persistent_factories
.
ItemFactory
.
create
(
second_problem
=
persistent_factories
.
ItemFactory
.
create
(
display_name
=
'problem 2'
,
display_name
=
'problem 2'
,
...
...
cms/djangoapps/contentstore/tests/test_orphan.py
View file @
483e2a6a
...
@@ -34,7 +34,13 @@ class TestOrphan(CourseTestCase):
...
@@ -34,7 +34,13 @@ class TestOrphan(CourseTestCase):
location
=
self
.
course
.
location
.
replace
(
category
=
category
,
name
=
name
)
location
=
self
.
course
.
location
.
replace
(
category
=
category
,
name
=
name
)
store
=
modulestore
()
store
=
modulestore
()
store
.
create_item
(
store
.
create_item
(
self
.
user
.
id
,
location
,
definition_data
=
data
,
metadata
=
metadata
,
runtime
=
runtime
self
.
user
.
id
,
location
.
course_key
,
location
.
block_type
,
location
.
block_id
,
definition_data
=
data
,
metadata
=
metadata
,
runtime
=
runtime
)
)
if
parent_name
:
if
parent_name
:
# add child to parent in mongo
# add child to parent in mongo
...
...
cms/djangoapps/contentstore/tests/utils.py
View file @
483e2a6a
...
@@ -151,11 +151,11 @@ class CourseTestCase(ModuleStoreTestCase):
...
@@ -151,11 +151,11 @@ class CourseTestCase(ModuleStoreTestCase):
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
draft_vertical
),
PublishState
.
draft
)
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
draft_vertical
),
PublishState
.
draft
)
# create a Private (draft only) vertical
# create a Private (draft only) vertical
private_vertical
=
self
.
store
.
create_item
(
self
.
user
.
id
,
course_id
.
make_usage_key
(
'vertical'
,
self
.
PRIVATE_VERTICAL
)
)
private_vertical
=
self
.
store
.
create_item
(
self
.
user
.
id
,
course_id
,
'vertical'
,
self
.
PRIVATE_VERTICAL
)
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
private_vertical
),
PublishState
.
private
)
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
private_vertical
),
PublishState
.
private
)
# create a Published (no draft) vertical
# create a Published (no draft) vertical
public_vertical
=
self
.
store
.
create_item
(
self
.
user
.
id
,
course_id
.
make_usage_key
(
'vertical'
,
self
.
PUBLISHED_VERTICAL
)
)
public_vertical
=
self
.
store
.
create_item
(
self
.
user
.
id
,
course_id
,
'vertical'
,
self
.
PUBLISHED_VERTICAL
)
public_vertical
=
self
.
store
.
publish
(
public_vertical
.
location
,
self
.
user
.
id
)
public_vertical
=
self
.
store
.
publish
(
public_vertical
.
location
,
self
.
user
.
id
)
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
public_vertical
),
PublishState
.
public
)
self
.
assertEqual
(
self
.
store
.
compute_publish_state
(
public_vertical
),
PublishState
.
public
)
...
...
cms/djangoapps/contentstore/views/item.py
View file @
483e2a6a
...
@@ -287,7 +287,7 @@ def _save_item(user, usage_key, data=None, children=None, metadata=None, nullout
...
@@ -287,7 +287,7 @@ def _save_item(user, usage_key, data=None, children=None, metadata=None, nullout
if
usage_key
.
category
in
CREATE_IF_NOT_FOUND
:
if
usage_key
.
category
in
CREATE_IF_NOT_FOUND
:
# New module at this location, for pages that are not pre-created.
# New module at this location, for pages that are not pre-created.
# Used for course info handouts.
# Used for course info handouts.
existing_item
=
store
.
create_item
(
user
.
id
,
usage_key
)
existing_item
=
store
.
create_item
(
user
.
id
,
usage_key
.
course_key
,
usage_key
.
block_type
,
usage_key
.
block_id
)
else
:
else
:
raise
raise
except
InvalidLocationError
:
except
InvalidLocationError
:
...
@@ -416,9 +416,11 @@ def _create_item(request):
...
@@ -416,9 +416,11 @@ def _create_item(request):
if
display_name
is
not
None
:
if
display_name
is
not
None
:
metadata
[
'display_name'
]
=
display_name
metadata
[
'display_name'
]
=
display_name
created_block
=
store
.
create_
item
(
created_block
=
store
.
create_
child
(
request
.
user
.
id
,
request
.
user
.
id
,
dest_usage_key
,
usage_key
,
dest_usage_key
.
block_type
,
block_id
=
dest_usage_key
.
block_id
,
definition_data
=
data
,
definition_data
=
data
,
metadata
=
metadata
,
metadata
=
metadata
,
runtime
=
parent
.
runtime
,
runtime
=
parent
.
runtime
,
...
@@ -437,11 +439,6 @@ def _create_item(request):
...
@@ -437,11 +439,6 @@ def _create_item(request):
)
)
store
.
update_item
(
course
,
request
.
user
.
id
)
store
.
update_item
(
course
,
request
.
user
.
id
)
# TODO replace w/ nicer accessor
if
not
'detached'
in
parent
.
runtime
.
load_block_type
(
category
)
.
_class_tags
:
parent
.
children
.
append
(
created_block
.
location
)
store
.
update_item
(
parent
,
request
.
user
.
id
)
return
JsonResponse
({
"locator"
:
unicode
(
created_block
.
location
),
"courseKey"
:
unicode
(
created_block
.
location
.
course_key
)})
return
JsonResponse
({
"locator"
:
unicode
(
created_block
.
location
),
"courseKey"
:
unicode
(
created_block
.
location
.
course_key
)})
...
@@ -467,7 +464,9 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_
...
@@ -467,7 +464,9 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_
dest_module
=
store
.
create_item
(
dest_module
=
store
.
create_item
(
user
.
id
,
user
.
id
,
dest_usage_key
,
dest_usage_key
.
course_key
,
dest_usage_key
.
block_type
,
block_id
=
dest_usage_key
.
block_id
,
definition_data
=
source_item
.
get_explicitly_set_fields_by_scope
(
Scope
.
content
),
definition_data
=
source_item
.
get_explicitly_set_fields_by_scope
(
Scope
.
content
),
metadata
=
duplicate_metadata
,
metadata
=
duplicate_metadata
,
runtime
=
source_item
.
runtime
,
runtime
=
source_item
.
runtime
,
...
@@ -555,7 +554,7 @@ def _get_module_info(usage_key, user, rewrite_static_links=True):
...
@@ -555,7 +554,7 @@ def _get_module_info(usage_key, user, rewrite_static_links=True):
except
ItemNotFoundError
:
except
ItemNotFoundError
:
if
usage_key
.
category
in
CREATE_IF_NOT_FOUND
:
if
usage_key
.
category
in
CREATE_IF_NOT_FOUND
:
# Create a new one for certain categories only. Used for course info handouts.
# Create a new one for certain categories only. Used for course info handouts.
module
=
store
.
create_item
(
user
.
id
,
usage_key
)
module
=
store
.
create_item
(
user
.
id
,
usage_key
.
course_key
,
usage_key
.
block_type
,
block_id
=
usage_key
.
block_id
)
else
:
else
:
raise
raise
...
...
cms/djangoapps/contentstore/views/tests/test_course_updates.py
View file @
483e2a6a
...
@@ -130,7 +130,12 @@ class CourseUpdateTest(CourseTestCase):
...
@@ -130,7 +130,12 @@ class CourseUpdateTest(CourseTestCase):
'''
'''
# get the updates and populate 'data' field with some data.
# get the updates and populate 'data' field with some data.
location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'updates'
)
location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'updates'
)
course_updates
=
modulestore
()
.
create_item
(
self
.
user
.
id
,
location
)
course_updates
=
modulestore
()
.
create_item
(
self
.
user
.
id
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
update_date
=
u"January 23, 2014"
update_date
=
u"January 23, 2014"
update_content
=
u"Hello world!"
update_content
=
u"Hello world!"
update_data
=
u"<ol><li><h2>"
+
update_date
+
"</h2>"
+
update_content
+
"</li></ol>"
update_data
=
u"<ol><li><h2>"
+
update_date
+
"</h2>"
+
update_content
+
"</li></ol>"
...
@@ -204,7 +209,12 @@ class CourseUpdateTest(CourseTestCase):
...
@@ -204,7 +209,12 @@ class CourseUpdateTest(CourseTestCase):
'''Test trying to add to a saved course_update which is not an ol.'''
'''Test trying to add to a saved course_update which is not an ol.'''
# get the updates and set to something wrong
# get the updates and set to something wrong
location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'updates'
)
location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'updates'
)
modulestore
()
.
create_item
(
self
.
user
.
id
,
location
)
modulestore
()
.
create_item
(
self
.
user
.
id
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
course_updates
=
modulestore
()
.
get_item
(
location
)
course_updates
=
modulestore
()
.
get_item
(
location
)
course_updates
.
data
=
'bad news'
course_updates
.
data
=
'bad news'
modulestore
()
.
update_item
(
course_updates
,
self
.
user
.
id
)
modulestore
()
.
update_item
(
course_updates
,
self
.
user
.
id
)
...
@@ -229,8 +239,7 @@ class CourseUpdateTest(CourseTestCase):
...
@@ -229,8 +239,7 @@ class CourseUpdateTest(CourseTestCase):
"""
"""
Test that a user can successfully post on course updates and handouts of a course
Test that a user can successfully post on course updates and handouts of a course
"""
"""
course_key
=
SlashSeparatedCourseKey
(
'Org1'
,
'Course_1'
,
'Run_1'
)
course_update_url
=
self
.
create_update_url
(
course_key
=
self
.
course
.
id
)
course_update_url
=
self
.
create_update_url
(
course_key
=
course_key
)
# create a course via the view handler
# create a course via the view handler
self
.
client
.
ajax_post
(
course_update_url
)
self
.
client
.
ajax_post
(
course_update_url
)
...
...
common/lib/xmodule/xmodule/modulestore/__init__.py
View file @
483e2a6a
...
@@ -368,6 +368,25 @@ class ModuleStoreWrite(ModuleStoreRead):
...
@@ -368,6 +368,25 @@ class ModuleStoreWrite(ModuleStoreRead):
pass
pass
@abstractmethod
@abstractmethod
def
create_item
(
self
,
user_id
,
course_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
"""
Creates and saves a new item in a course.
Returns the newly created item.
Args:
user_id: ID of the user creating and saving the xmodule
course_key: A :class:`~opaque_keys.edx.CourseKey` identifying which course to create
this item in
block_type: The type of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
fields (dict): A dictionary specifying initial values for some or all fields
in the newly created block
"""
pass
@abstractmethod
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
"""
"""
Sets up source_course_id to point a course with the same content as the desct_course_id. This
Sets up source_course_id to point a course with the same content as the desct_course_id. This
...
@@ -561,54 +580,6 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
...
@@ -561,54 +580,6 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
result
[
field
.
scope
][
field_name
]
=
value
result
[
field
.
scope
][
field_name
]
=
value
return
result
return
result
def
create_item
(
self
,
user_id
,
location
,
parent_location
=
None
,
category
=
None
,
**
kwargs
):
"""
Creates and saves a new item.
Either location or (category, parent_location) or both must be provided.
If parent_location is provided, a new item of the given category is added as a child.
If location is not provided, a new item with the given category and given block_id
is added to the parent_location. If the block_id is not provided, a unique name
is automatically generated.
Returns the newly created item.
:param user_id: ID of the user creating and saving the xmodule
:param location: a Location--must have a category
:param parent_location: optional parameter, specifying the Location of the parent item
:param category: optional parameter for the category of the new item
:param block_id: a unique identifier for the new item
"""
raise
NotImplementedError
def
update_item
(
self
,
xblock
,
user_id
,
allow_not_found
=
False
,
force
=
False
):
"""
Update the given xblock's persisted repr. Pass the user's unique id which the persistent store
should save with the update if it has that ability.
:param allow_not_found: whether this method should raise an exception if the given xblock
has not been persisted before.
:param force: fork the structure and don't update the course draftVersion if there's a version
conflict (only applicable to version tracking and conflict detecting persistence stores)
:raises VersionConflictError: if org, course, run, and version_guid given and the current
version head != version_guid and force is not True. (only applicable to version tracking stores)
"""
raise
NotImplementedError
def
delete_item
(
self
,
location
,
user_id
,
force
=
False
):
"""
Delete an item from persistence. Pass the user's unique id which the persistent store
should save with the update if it has that ability.
:param user_id: ID of the user deleting the item
:param force: fork the structure and don't update the course draftVersion if there's a version
conflict (only applicable to version tracking and conflict detecting persistence stores)
:raises VersionConflictError: if org, course, run, and version_guid given and the current
version head != version_guid and force is not True. (only applicable to version tracking stores)
"""
raise
NotImplementedError
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
"""
"""
This base method just copies the assets. The lower level impls must do the actual cloning of
This base method just copies the assets. The lower level impls must do the actual cloning of
...
@@ -639,6 +610,27 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
...
@@ -639,6 +610,27 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
self
.
contentstore
.
_drop_database
()
# pylint: disable=protected-access
self
.
contentstore
.
_drop_database
()
# pylint: disable=protected-access
super
(
ModuleStoreWriteBase
,
self
)
.
_drop_database
()
# pylint: disable=protected-access
super
(
ModuleStoreWriteBase
,
self
)
.
_drop_database
()
# pylint: disable=protected-access
def
create_child
(
self
,
user_id
,
parent_usage_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
"""
Creates and saves a new xblock that as a child of the specified block
Returns the newly created item.
Args:
user_id: ID of the user creating and saving the xmodule
parent_usage_key: a :class:`~opaque_key.edx.UsageKey` identifing the
block that this item should be parented under
block_type: The type of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
fields (dict): A dictionary specifying initial values for some or all fields
in the newly created block
"""
item
=
self
.
create_item
(
user_id
,
parent_usage_key
.
course_key
,
block_type
,
block_id
=
block_id
,
fields
=
fields
,
**
kwargs
)
parent
=
self
.
get_item
(
parent_usage_key
)
parent
.
children
.
append
(
item
.
location
)
self
.
update_item
(
parent
,
user_id
)
@contextmanager
@contextmanager
def
bulk_write_operations
(
self
,
course_id
):
def
bulk_write_operations
(
self
,
course_id
):
"""
"""
...
@@ -699,18 +691,3 @@ class EdxJSONEncoder(json.JSONEncoder):
...
@@ -699,18 +691,3 @@ class EdxJSONEncoder(json.JSONEncoder):
return
obj
.
isoformat
()
return
obj
.
isoformat
()
else
:
else
:
return
super
(
EdxJSONEncoder
,
self
)
.
default
(
obj
)
return
super
(
EdxJSONEncoder
,
self
)
.
default
(
obj
)
def
compute_location_from_args
(
location
=
None
,
parent_location
=
None
,
**
kwargs
):
"""
Returns a Location object that is generated from the given arguments, as follows:
If location is provided, returns it.
If location is not provided, returns a location with the given category and given block_id.
If the block_id is not provided, a unique name is automatically generated.
"""
if
location
is
None
:
block_id
=
kwargs
.
get
(
'block_id'
,
kwargs
.
get
(
'name'
,
kwargs
.
get
(
'display_name'
,
uuid4
()
.
hex
)))
category
=
kwargs
.
pop
(
'category'
)
course_key
=
getattr
(
parent_location
,
'course_key'
,
parent_location
)
location
=
course_key
.
make_usage_key
(
category
,
Location
.
clean
(
block_id
))
return
location
common/lib/xmodule/xmodule/modulestore/draft_and_published.py
View file @
483e2a6a
...
@@ -12,8 +12,8 @@ class ModuleStoreDraftAndPublished(object):
...
@@ -12,8 +12,8 @@ class ModuleStoreDraftAndPublished(object):
"""
"""
__metaclass__
=
ABCMeta
__metaclass__
=
ABCMeta
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
*
*
kwargs
):
super
(
ModuleStoreDraftAndPublished
,
self
)
.
__init__
(
**
kwargs
)
super
(
ModuleStoreDraftAndPublished
,
self
)
.
__init__
(
*
args
,
*
*
kwargs
)
self
.
branch_setting_func
=
kwargs
.
pop
(
'branch_setting_func'
,
lambda
:
ModuleStoreEnum
.
Branch
.
published_only
)
self
.
branch_setting_func
=
kwargs
.
pop
(
'branch_setting_func'
,
lambda
:
ModuleStoreEnum
.
Branch
.
published_only
)
@abstractmethod
@abstractmethod
...
...
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
483e2a6a
...
@@ -7,21 +7,23 @@ In this way, courses can be served up both - say - XMLModuleStore or MongoModule
...
@@ -7,21 +7,23 @@ In this way, courses can be served up both - say - XMLModuleStore or MongoModule
import
logging
import
logging
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
opaque_keys
import
InvalidKeyError
import
itertools
from
.
import
ModuleStoreWriteBase
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
import
itertools
from
xmodule.modulestore.split_migrator
import
SplitMigrator
from
.
import
ModuleStoreWriteBase
from
.
import
ModuleStoreEnum
from
.exceptions
import
ItemNotFoundError
from
.draft_and_published
import
ModuleStoreDraftAndPublished
from
.split_migrator
import
SplitMigrator
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
class
MixedModuleStore
(
ModuleStoreWriteBase
):
class
MixedModuleStore
(
ModuleStore
DraftAndPublished
,
ModuleStore
WriteBase
):
"""
"""
ModuleStore knows how to route requests to the right persistence ms
ModuleStore knows how to route requests to the right persistence ms
"""
"""
...
@@ -282,7 +284,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -282,7 +284,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
Returns: a CourseDescriptor
Returns: a CourseDescriptor
"""
"""
store
=
self
.
_
get_modulestore_for_courseid
(
None
)
store
=
self
.
_
verify_modulestore_support
(
None
,
'create_course'
)
return
store
.
create_course
(
org
,
course
,
run
,
user_id
,
**
kwargs
)
return
store
.
create_course
(
org
,
course
,
run
,
user_id
,
**
kwargs
)
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
...
@@ -312,40 +314,57 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -312,40 +314,57 @@ class MixedModuleStore(ModuleStoreWriteBase):
source_course_id
,
user_id
,
dest_course_id
.
org
,
dest_course_id
.
course
,
dest_course_id
.
run
source_course_id
,
user_id
,
dest_course_id
.
org
,
dest_course_id
.
course
,
dest_course_id
.
run
)
)
def
create_item
(
self
,
user_id
,
location
=
None
,
parent_location
=
None
,
**
kwargs
):
def
create_item
(
self
,
user_id
,
course_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
"""
"""
Creates and saves a new item.
Creates and saves a new item in a course.
Either location or (category, parent_location) or both must be provided.
If parent_location is provided, a new item of the given category is added as a child.
If location is not provided, a new item with the given category and given block_id
is added to the parent_location. If the block_id is not provided, a unique name
is automatically generated.
Returns the newly created item.
Returns the newly created item.
:param user_id: ID of the user creating and saving the xmodule
Args:
:param location: a Location--must have a category
user_id: ID of the user creating and saving the xmodule
:param parent_location: optional parameter, specifying the Location of the parent item
course_key: A :class:`~opaque_keys.edx.CourseKey` identifying which course to create
:param category: optional parameter for the category of the new item
this item in
:param block_id: a unique identifier for the new item
block_type: The typo of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
fields (dict): A dictionary specifying initial values for some or all fields
in the newly created block
"""
modulestore
=
self
.
_verify_modulestore_support
(
course_key
,
'create_item'
)
return
modulestore
.
create_item
(
user_id
,
course_key
,
block_type
,
block_id
=
block_id
,
fields
=
fields
,
**
kwargs
)
def
create_child
(
self
,
user_id
,
parent_usage_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
"""
"""
location
=
compute_location_from_args
(
location
,
parent_location
,
**
kwargs
)
Creates and saves a new xblock that is a child of the specified block
modulestore
=
self
.
_verify_modulestore_support
(
location
,
'create_item'
)
return
modulestore
.
create_item
(
user_id
,
location
,
parent_location
,
**
kwargs
)
Returns the newly created item.
Args:
user_id: ID of the user creating and saving the xmodule
parent_usage_key: a :class:`~opaque_key.edx.UsageKey` identifying the
block that this item should be parented under
block_type: The typo of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
fields (dict): A dictionary specifying initial values for some or all fields
in the newly created block
"""
modulestore
=
self
.
_verify_modulestore_support
(
parent_usage_key
.
course_key
,
'create_child'
)
return
modulestore
.
create_child
(
user_id
,
parent_usage_key
,
block_type
,
block_id
=
block_id
,
fields
=
fields
,
**
kwargs
)
def
update_item
(
self
,
xblock
,
user_id
,
allow_not_found
=
False
):
def
update_item
(
self
,
xblock
,
user_id
,
allow_not_found
=
False
):
"""
"""
Update the xblock persisted to be the same as the given for all types of fields
Update the xblock persisted to be the same as the given for all types of fields
(content, children, and metadata) attribute the change to the given user.
(content, children, and metadata) attribute the change to the given user.
"""
"""
store
=
self
.
_verify_modulestore_support
(
xblock
.
location
,
'update_item'
)
store
=
self
.
_verify_modulestore_support
(
xblock
.
location
.
course_key
,
'update_item'
)
return
store
.
update_item
(
xblock
,
user_id
,
allow_not_found
)
return
store
.
update_item
(
xblock
,
user_id
,
allow_not_found
)
def
delete_item
(
self
,
location
,
user_id
,
**
kwargs
):
def
delete_item
(
self
,
location
,
user_id
,
**
kwargs
):
"""
"""
Delete the given item from persistence. kwargs allow modulestore specific parameters.
Delete the given item from persistence. kwargs allow modulestore specific parameters.
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'delete_item'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'delete_item'
)
store
.
delete_item
(
location
,
user_id
=
user_id
,
**
kwargs
)
store
.
delete_item
(
location
,
user_id
=
user_id
,
**
kwargs
)
def
revert_to_published
(
self
,
location
,
user_id
):
def
revert_to_published
(
self
,
location
,
user_id
):
...
@@ -358,7 +377,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -358,7 +377,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
:raises InvalidVersionError: if no published version exists for the location specified
:raises InvalidVersionError: if no published version exists for the location specified
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'revert_to_published'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'revert_to_published'
)
return
store
.
revert_to_published
(
location
,
user_id
)
return
store
.
revert_to_published
(
location
,
user_id
)
def
close_all_connections
(
self
):
def
close_all_connections
(
self
):
...
@@ -388,7 +407,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -388,7 +407,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
:param runtime: if you already have an xblock from the course, the xblock.runtime value
:param runtime: if you already have an xblock from the course, the xblock.runtime value
:param fields: a dictionary of field names and values for the new xmodule
:param fields: a dictionary of field names and values for the new xmodule
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'create_xmodule'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'create_xmodule'
)
return
store
.
create_xmodule
(
location
,
definition_data
,
metadata
,
runtime
,
fields
,
**
kwargs
)
return
store
.
create_xmodule
(
location
,
definition_data
,
metadata
,
runtime
,
fields
,
**
kwargs
)
def
get_courses_for_wiki
(
self
,
wiki_slug
):
def
get_courses_for_wiki
(
self
,
wiki_slug
):
...
@@ -433,7 +452,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -433,7 +452,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
Save a current draft to the underlying modulestore
Save a current draft to the underlying modulestore
Returns the newly published item.
Returns the newly published item.
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'publish'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'publish'
)
return
store
.
publish
(
location
,
user_id
)
return
store
.
publish
(
location
,
user_id
)
def
unpublish
(
self
,
location
,
user_id
):
def
unpublish
(
self
,
location
,
user_id
):
...
@@ -441,7 +460,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -441,7 +460,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
Save a current draft to the underlying modulestore
Save a current draft to the underlying modulestore
Returns the newly unpublished item.
Returns the newly unpublished item.
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'unpublish'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'unpublish'
)
return
store
.
unpublish
(
location
,
user_id
)
return
store
.
unpublish
(
location
,
user_id
)
def
convert_to_draft
(
self
,
location
,
user_id
):
def
convert_to_draft
(
self
,
location
,
user_id
):
...
@@ -451,18 +470,26 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -451,18 +470,26 @@ class MixedModuleStore(ModuleStoreWriteBase):
:param source: the location of the source (its revision must be None)
:param source: the location of the source (its revision must be None)
"""
"""
store
=
self
.
_verify_modulestore_support
(
location
,
'convert_to_draft'
)
store
=
self
.
_verify_modulestore_support
(
location
.
course_key
,
'convert_to_draft'
)
return
store
.
convert_to_draft
(
location
,
user_id
)
return
store
.
convert_to_draft
(
location
,
user_id
)
def
_verify_modulestore_support
(
self
,
location
,
method
):
def
has_changes
(
self
,
usage_key
):
"""
Checks if the given block has unpublished changes
:param usage_key: the block to check
:return: True if the draft and published versions differ
"""
store
=
self
.
_verify_modulestore_support
(
usage_key
.
course_key
,
'has_changes'
)
return
store
.
has_changes
(
usage_key
)
def
_verify_modulestore_support
(
self
,
course_key
,
method
):
"""
"""
Finds and returns the store that contains the course for the given location, and verifying
Finds and returns the store that contains the course for the given location, and verifying
that the store supports the given method.
that the store supports the given method.
Raises NotImplementedError if the found store does not support the given method.
Raises NotImplementedError if the found store does not support the given method.
"""
"""
course_id
=
location
.
course_key
store
=
self
.
_get_modulestore_for_courseid
(
course_key
)
store
=
self
.
_get_modulestore_for_courseid
(
course_id
)
if
hasattr
(
store
,
method
):
if
hasattr
(
store
,
method
):
return
store
return
store
else
:
else
:
...
...
common/lib/xmodule/xmodule/modulestore/mongo/base.py
View file @
483e2a6a
...
@@ -17,6 +17,7 @@ import sys
...
@@ -17,6 +17,7 @@ import sys
import
logging
import
logging
import
copy
import
copy
import
re
import
re
from
uuid
import
uuid4
from
bson.son
import
SON
from
bson.son
import
SON
from
fs.osfs
import
OSFS
from
fs.osfs
import
OSFS
...
@@ -904,7 +905,12 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -904,7 +905,12 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
]))
]))
location
=
course_id
.
make_usage_key
(
'course'
,
course_id
.
run
)
location
=
course_id
.
make_usage_key
(
'course'
,
course_id
.
run
)
course
=
self
.
create_item
(
user_id
,
location
,
fields
=
fields
,
**
kwargs
)
course
=
self
.
create_xmodule
(
location
,
fields
=
fields
,
**
kwargs
)
self
.
update_item
(
course
,
user_id
,
allow_not_found
=
True
)
# clone a default 'about' overview module as well
# clone a default 'about' overview module as well
about_location
=
location
.
replace
(
about_location
=
location
.
replace
(
...
@@ -914,7 +920,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -914,7 +920,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
overview_template
=
AboutDescriptor
.
get_template
(
'overview.yaml'
)
overview_template
=
AboutDescriptor
.
get_template
(
'overview.yaml'
)
self
.
create_item
(
self
.
create_item
(
user_id
,
user_id
,
about_location
,
about_location
.
course_key
,
about_location
.
block_type
,
block_id
=
about_location
.
block_id
,
definition_data
=
overview_template
.
get
(
'data'
),
definition_data
=
overview_template
.
get
(
'data'
),
runtime
=
course
.
system
runtime
=
course
.
system
)
)
...
@@ -975,6 +983,52 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -975,6 +983,52 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
xmodule
.
save
()
xmodule
.
save
()
return
xmodule
return
xmodule
def
create_item
(
self
,
user_id
,
course_key
,
block_type
,
block_id
=
None
,
**
kwargs
):
"""
Creates and saves a new item in a course.
Returns the newly created item.
Args:
user_id: ID of the user creating and saving the xmodule
course_key: A :class:`~opaque_keys.edx.CourseKey` identifying which course to create
this item in
block_type: The typo of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
"""
if
block_id
is
None
:
block_id
=
uuid4
()
.
hex
location
=
course_key
.
make_usage_key
(
block_type
,
block_id
)
xblock
=
self
.
create_xmodule
(
location
,
**
kwargs
)
self
.
update_item
(
xblock
,
user_id
,
allow_not_found
=
True
)
return
xblock
def
create_child
(
self
,
user_id
,
parent_usage_key
,
block_type
,
block_id
=
None
,
**
kwargs
):
"""
Creates and saves a new xblock that as a child of the specified block
Returns the newly created item.
Args:
user_id: ID of the user creating and saving the xmodule
parent_usage_key: a :class:`~opaque_key.edx.UsageKey` identifing the
block that this item should be parented under
block_type: The typo of block to create
block_id: a unique identifier for the new item. If not supplied,
a new identifier will be generated
"""
xblock
=
self
.
create_item
(
user_id
,
parent_usage_key
.
course_key
,
block_type
,
block_id
=
block_id
,
**
kwargs
)
# attach to parent if given
if
'detached'
not
in
xblock
.
_class_tags
:
parent
=
self
.
get_item
(
parent_usage_key
)
parent
.
children
.
append
(
xblock
.
location
)
self
.
update_item
(
parent
,
user_id
)
return
xblock
def
_get_course_for_item
(
self
,
location
,
depth
=
0
):
def
_get_course_for_item
(
self
,
location
,
depth
=
0
):
'''
'''
for a given Xmodule, return the course that it belongs to
for a given Xmodule, return the course that it belongs to
...
@@ -1065,6 +1119,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -1065,6 +1119,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
except
ItemNotFoundError
:
except
ItemNotFoundError
:
if
not
allow_not_found
:
if
not
allow_not_found
:
raise
raise
elif
not
self
.
has_course
(
xblock
.
location
.
course_key
):
raise
ItemNotFoundError
(
xblock
.
location
.
course_key
)
return
xblock
return
xblock
...
...
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
View file @
483e2a6a
...
@@ -11,7 +11,7 @@ import logging
...
@@ -11,7 +11,7 @@ import logging
from
opaque_keys.edx.locations
import
Location
from
opaque_keys.edx.locations
import
Location
from
xmodule.exceptions
import
InvalidVersionError
from
xmodule.exceptions
import
InvalidVersionError
from
xmodule.modulestore
import
PublishState
,
ModuleStoreEnum
,
compute_location_from_args
from
xmodule.modulestore
import
PublishState
,
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
(
from
xmodule.modulestore.exceptions
import
(
ItemNotFoundError
,
DuplicateItemError
,
InvalidBranchSetting
,
DuplicateCourseError
ItemNotFoundError
,
DuplicateItemError
,
InvalidBranchSetting
,
DuplicateCourseError
)
)
...
@@ -305,35 +305,6 @@ class DraftModuleStore(MongoModuleStore):
...
@@ -305,35 +305,6 @@ class DraftModuleStore(MongoModuleStore):
super
(
DraftModuleStore
,
self
)
.
create_xmodule
(
location
,
definition_data
,
metadata
,
runtime
,
fields
)
super
(
DraftModuleStore
,
self
)
.
create_xmodule
(
location
,
definition_data
,
metadata
,
runtime
,
fields
)
)
)
def
create_item
(
self
,
user_id
,
location
=
None
,
parent_location
=
None
,
**
kwargs
):
"""
Creates and saves a new item.
Either location or (category, parent_location) or both must be provided.
If parent_location is provided, a new item of the given category is added as a child.
If location is not provided, a new item with the given category and given block_id
is added to the parent_location. If the block_id is not provided, a unique name
is automatically generated.
Returns the newly created item.
:param user_id: ID of the user creating and saving the xmodule
:param location: a Location--must have a category
:param parent_location: optional parameter, specifying the Location of the parent item
:param category: optional parameter for the category of the new item
:param block_id: a unique identifier for the new item
"""
location
=
compute_location_from_args
(
location
,
parent_location
,
**
kwargs
)
xblock
=
self
.
create_xmodule
(
location
,
**
kwargs
)
self
.
update_item
(
xblock
,
user_id
,
allow_not_found
=
True
)
# attach to parent if given
if
parent_location
is
not
None
and
not
'detached'
in
xblock
.
_class_tags
:
parent
=
self
.
get_item
(
parent_location
)
parent
.
children
.
append
(
location
)
self
.
update_item
(
parent
,
user_id
)
return
xblock
def
get_items
(
self
,
course_key
,
settings
=
None
,
content
=
None
,
revision
=
None
,
**
kwargs
):
def
get_items
(
self
,
course_key
,
settings
=
None
,
content
=
None
,
revision
=
None
,
**
kwargs
):
"""
"""
Performance Note: This is generally a costly operation, but useful for wildcard searches.
Performance Note: This is generally a costly operation, but useful for wildcard searches.
...
@@ -511,6 +482,7 @@ class DraftModuleStore(MongoModuleStore):
...
@@ -511,6 +482,7 @@ class DraftModuleStore(MongoModuleStore):
ModuleStoreEnum.RevisionOption.published_only - removes only Published versions
ModuleStoreEnum.RevisionOption.published_only - removes only Published versions
ModuleStoreEnum.RevisionOption.all - removes both Draft and Published parents
ModuleStoreEnum.RevisionOption.all - removes both Draft and Published parents
currently only provided by contentstore.views.item.orphan_handler
currently only provided by contentstore.views.item.orphan_handler
Otherwise, raises a ValueError.
"""
"""
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
_verify_revision_is_published
(
location
)
_verify_revision_is_published
(
location
)
...
@@ -555,8 +527,10 @@ class DraftModuleStore(MongoModuleStore):
...
@@ -555,8 +527,10 @@ class DraftModuleStore(MongoModuleStore):
as_functions
=
[
as_draft
,
as_published
]
as_functions
=
[
as_draft
,
as_published
]
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
as_functions
=
[
as_published
]
as_functions
=
[
as_published
]
el
s
e
:
el
if
revision
is
Non
e
:
as_functions
=
[
as_draft
]
as_functions
=
[
as_draft
]
else
:
raise
ValueError
(
'revision not one of None, ModuleStoreEnum.RevisionOption.published_only, or ModuleStoreEnum.RevisionOption.all'
)
self
.
_delete_subtree
(
location
,
as_functions
)
self
.
_delete_subtree
(
location
,
as_functions
)
def
_delete_subtree
(
self
,
location
,
as_functions
):
def
_delete_subtree
(
self
,
location
,
as_functions
):
...
...
common/lib/xmodule/xmodule/modulestore/split_migrator.py
View file @
483e2a6a
...
@@ -85,8 +85,8 @@ class SplitMigrator(object):
...
@@ -85,8 +85,8 @@ class SplitMigrator(object):
# the 'children' field as it goes.
# the 'children' field as it goes.
_new_module
=
self
.
split_modulestore
.
create_item
(
_new_module
=
self
.
split_modulestore
.
create_item
(
user_id
,
user_id
,
course_version_locator
.
make_usage_key
(
module
.
location
.
category
,
module
.
location
.
block_id
)
,
course_version_locator
,
parent_location
=
course_version_locator
,
module
.
location
.
block_type
,
block_id
=
module
.
location
.
block_id
,
block_id
=
module
.
location
.
block_id
,
fields
=
self
.
_get_json_fields_translate_references
(
fields
=
self
.
_get_json_fields_translate_references
(
module
,
course_version_locator
,
new_course
.
location
.
block_id
module
,
course_version_locator
,
new_course
.
location
.
block_id
...
@@ -131,7 +131,8 @@ class SplitMigrator(object):
...
@@ -131,7 +131,8 @@ class SplitMigrator(object):
else
:
else
:
# only a draft version (aka, 'private').
# only a draft version (aka, 'private').
_new_module
=
self
.
split_modulestore
.
create_item
(
_new_module
=
self
.
split_modulestore
.
create_item
(
user_id
,
new_locator
,
parent_location
=
new_draft_course_loc
,
user_id
,
new_draft_course_loc
,
new_locator
.
block_type
,
block_id
=
new_locator
.
block_id
,
block_id
=
new_locator
.
block_id
,
fields
=
self
.
_get_json_fields_translate_references
(
fields
=
self
.
_get_json_fields_translate_references
(
module
,
new_draft_course_loc
,
published_course_usage_key
.
block_id
module
,
new_draft_course_loc
,
published_course_usage_key
.
block_id
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
483e2a6a
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/modulestore/split_mongo/split_draft.py
View file @
483e2a6a
...
@@ -6,6 +6,7 @@ from ..exceptions import ItemNotFoundError
...
@@ -6,6 +6,7 @@ from ..exceptions import ItemNotFoundError
from
split
import
SplitMongoModuleStore
from
split
import
SplitMongoModuleStore
from
xmodule.modulestore
import
ModuleStoreEnum
,
PublishState
from
xmodule.modulestore
import
ModuleStoreEnum
,
PublishState
from
xmodule.modulestore.draft_and_published
import
ModuleStoreDraftAndPublished
from
xmodule.modulestore.draft_and_published
import
ModuleStoreDraftAndPublished
from
xmodule.modulestore.draft
import
DIRECT_ONLY_CATEGORIES
class
DraftVersioningModuleStore
(
ModuleStoreDraftAndPublished
,
SplitMongoModuleStore
):
class
DraftVersioningModuleStore
(
ModuleStoreDraftAndPublished
,
SplitMongoModuleStore
):
...
@@ -13,13 +14,10 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
...
@@ -13,13 +14,10 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
A subclass of Split that supports a dual-branch fall-back versioning framework
A subclass of Split that supports a dual-branch fall-back versioning framework
with a Draft branch that falls back to a Published branch.
with a Draft branch that falls back to a Published branch.
"""
"""
def
__init__
(
self
,
**
kwargs
):
super
(
DraftVersioningModuleStore
,
self
)
.
__init__
(
**
kwargs
)
def
create_course
(
self
,
org
,
course
,
run
,
user_id
,
**
kwargs
):
def
create_course
(
self
,
org
,
course
,
run
,
user_id
,
**
kwargs
):
master_branch
=
kwargs
.
pop
(
'master_branch'
,
ModuleStoreEnum
.
BranchName
.
draft
)
master_branch
=
kwargs
.
pop
(
'master_branch'
,
ModuleStoreEnum
.
BranchName
.
draft
)
return
super
(
DraftVersioningModuleStore
,
self
)
.
create_course
(
return
super
(
DraftVersioningModuleStore
,
self
)
.
create_course
(
org
,
course
,
run
,
user_id
,
master_branch
,
**
kwargs
org
,
course
,
run
,
user_id
,
master_branch
=
master_branch
,
**
kwargs
)
)
def
get_courses
(
self
):
def
get_courses
(
self
):
...
@@ -31,32 +29,81 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
...
@@ -31,32 +29,81 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
def
delete_item
(
self
,
location
,
user_id
,
revision
=
None
,
**
kwargs
):
def
delete_item
(
self
,
location
,
user_id
,
revision
=
None
,
**
kwargs
):
"""
"""
Delete the given item from persistence. kwargs allow modulestore specific parameters.
Delete the given item from persistence. kwargs allow modulestore specific parameters.
Args:
location: UsageKey of the item to be deleted
user_id: id of the user deleting the item
revision:
None - deletes the item and its subtree, and updates the parents per description above
ModuleStoreEnum.RevisionOption.published_only - removes only Published versions
ModuleStoreEnum.RevisionOption.all - removes both Draft and Published parents
currently only provided by contentstore.views.item.orphan_handler
Otherwise, raises a ValueError.
"""
"""
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
published
]
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
published
]
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
all
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
all
:
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
published
,
ModuleStoreEnum
.
BranchName
.
draft
]
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
published
,
ModuleStoreEnum
.
BranchName
.
draft
]
el
s
e
:
el
if
revision
is
Non
e
:
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
draft
]
branches_to_delete
=
[
ModuleStoreEnum
.
BranchName
.
draft
]
else
:
raise
ValueError
(
'revision not one of None, ModuleStoreEnum.RevisionOption.published_only, or ModuleStoreEnum.RevisionOption.all'
)
for
branch
in
branches_to_delete
:
for
branch
in
branches_to_delete
:
SplitMongoModuleStore
.
delete_item
(
self
,
location
.
for_branch
(
branch
),
user_id
,
**
kwargs
)
SplitMongoModuleStore
.
delete_item
(
self
,
location
.
for_branch
(
branch
),
user_id
,
**
kwargs
)
def
get_item
(
self
,
usage_key
,
depth
=
0
,
revision
=
None
):
def
_map_revision_to_branch
(
self
,
key
,
revision
=
None
):
"""
"""
Returns the item identified by usage_key and revision.
Maps RevisionOptions to BranchNames, inserting them into the key
"""
"""
def
for_branch
(
branch_state
):
if
usage_key
.
branch
is
not
None
and
usage_key
.
branch
is
not
branch_state
:
raise
ValueError
(
'{} already has a branch.'
.
format
(
usage_key
))
return
usage_key
.
for_branch
(
branch_state
)
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
usage_key
=
for_branch
(
ModuleStoreEnum
.
BranchName
.
published
)
return
key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
published
)
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_only
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_only
:
usage_key
=
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
return
key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
else
:
return
key
def
has_item
(
self
,
usage_key
,
revision
=
None
):
"""
Returns True if location exists in this ModuleStore.
"""
usage_key
=
self
.
_map_revision_to_branch
(
usage_key
,
revision
=
revision
)
return
super
(
DraftVersioningModuleStore
,
self
)
.
has_item
(
usage_key
)
def
get_item
(
self
,
usage_key
,
depth
=
0
,
revision
=
None
):
"""
Returns the item identified by usage_key and revision.
"""
usage_key
=
self
.
_map_revision_to_branch
(
usage_key
,
revision
=
revision
)
return
super
(
DraftVersioningModuleStore
,
self
)
.
get_item
(
usage_key
,
depth
=
depth
)
return
super
(
DraftVersioningModuleStore
,
self
)
.
get_item
(
usage_key
,
depth
=
depth
)
def
get_items
(
self
,
course_locator
,
settings
=
None
,
content
=
None
,
revision
=
None
,
**
kwargs
):
"""
Returns a list of XModuleDescriptor instances for the matching items within the course with
the given course_locator.
"""
course_locator
=
self
.
_map_revision_to_branch
(
course_locator
,
revision
=
revision
)
return
super
(
DraftVersioningModuleStore
,
self
)
.
get_items
(
course_locator
,
settings
=
settings
,
content
=
content
,
**
kwargs
)
def
get_parent_location
(
self
,
location
,
revision
=
None
,
**
kwargs
):
def
get_parent_location
(
self
,
location
,
revision
=
None
,
**
kwargs
):
# NAATODO - support draft_preferred
'''
Returns the given location's parent location in this course.
Args:
revision:
None - uses the branch setting for the revision
ModuleStoreEnum.RevisionOption.published_only
- return only the PUBLISHED parent if it exists, else returns None
ModuleStoreEnum.RevisionOption.draft_preferred
- return either the DRAFT or PUBLISHED parent, preferring DRAFT, if parent(s) exists,
else returns None
'''
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
:
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
location
=
self
.
_map_revision_to_branch
(
location
,
revision
=
revision
)
return
SplitMongoModuleStore
.
get_parent_location
(
self
,
location
,
**
kwargs
)
return
SplitMongoModuleStore
.
get_parent_location
(
self
,
location
,
**
kwargs
)
def
has_changes
(
self
,
usage_key
):
def
has_changes
(
self
,
usage_key
):
...
@@ -65,6 +112,7 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
...
@@ -65,6 +112,7 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
:param usage_key: the block to check
:param usage_key: the block to check
:return: True if the draft and published versions differ
:return: True if the draft and published versions differ
"""
"""
# TODO for better performance: lookup the courses and get the block entry, don't create the instances
draft
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
))
draft
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
))
try
:
try
:
published
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
published
))
published
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
published
))
...
@@ -120,20 +168,21 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
...
@@ -120,20 +168,21 @@ class DraftVersioningModuleStore(ModuleStoreDraftAndPublished, SplitMongoModuleS
course_structure
=
self
.
_lookup_course
(
xblock
.
location
.
course_key
.
for_branch
(
branch
))[
'structure'
]
course_structure
=
self
.
_lookup_course
(
xblock
.
location
.
course_key
.
for_branch
(
branch
))[
'structure'
]
return
self
.
_get_block_from_structure
(
course_structure
,
xblock
.
location
.
block_id
)
return
self
.
_get_block_from_structure
(
course_structure
,
xblock
.
location
.
block_id
)
if
xblock
.
location
.
branch
is
None
:
raise
ValueError
(
u'{} is not in a branch; so, this is nonsensical'
.
format
(
xblock
.
location
))
if
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
draft
:
if
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
draft
:
try
:
other
=
get_head
(
ModuleStoreEnum
.
BranchName
.
published
)
other
=
get_head
(
ModuleStoreEnum
.
BranchName
.
published
)
except
ItemNotFoundError
:
return
PublishState
.
private
elif
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
published
:
elif
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
published
:
other
=
get_head
(
ModuleStoreEnum
.
BranchName
.
draft
)
other
=
get_head
(
ModuleStoreEnum
.
BranchName
.
draft
)
else
:
else
:
raise
ValueError
(
u'{} is
not in a branch other than draft or published; so, this is nonsensical
'
.
format
(
xblock
.
location
))
raise
ValueError
(
u'{} is
in a branch other than draft or published.
'
.
format
(
xblock
.
location
))
if
not
other
:
if
not
other
:
if
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
draft
:
if
xblock
.
location
.
branch
==
ModuleStoreEnum
.
BranchName
.
draft
:
return
PublishState
.
private
return
PublishState
.
private
else
:
else
:
return
PublishState
.
public
# a bit nonsensical
return
PublishState
.
public
elif
xblock
.
update_version
!=
other
[
'edit_info'
][
'update_version'
]:
elif
xblock
.
update_version
!=
other
[
'edit_info'
][
'update_version'
]:
return
PublishState
.
draft
return
PublishState
.
draft
else
:
else
:
...
...
common/lib/xmodule/xmodule/modulestore/tests/factories.py
View file @
483e2a6a
...
@@ -174,7 +174,15 @@ class ItemFactory(XModuleFactory):
...
@@ -174,7 +174,15 @@ class ItemFactory(XModuleFactory):
if
display_name
is
not
None
:
if
display_name
is
not
None
:
metadata
[
'display_name'
]
=
display_name
metadata
[
'display_name'
]
=
display_name
runtime
=
parent
.
runtime
if
parent
else
None
runtime
=
parent
.
runtime
if
parent
else
None
store
.
create_item
(
user_id
,
location
,
metadata
=
metadata
,
definition_data
=
data
,
runtime
=
runtime
)
store
.
create_item
(
user_id
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
,
metadata
=
metadata
,
definition_data
=
data
,
runtime
=
runtime
)
module
=
store
.
get_item
(
location
)
module
=
store
.
get_item
(
location
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/persistent_factories.py
View file @
483e2a6a
...
@@ -4,6 +4,7 @@ from xmodule.course_module import CourseDescriptor
...
@@ -4,6 +4,7 @@ from xmodule.course_module import CourseDescriptor
from
xmodule.x_module
import
XModuleDescriptor
from
xmodule.x_module
import
XModuleDescriptor
import
factory
import
factory
from
factory.helpers
import
lazy_attribute
from
factory.helpers
import
lazy_attribute
from
opaque_keys.edx.keys
import
UsageKey
# Factories don't have __init__ methods, and are self documenting
# Factories don't have __init__ methods, and are self documenting
# pylint: disable=W0232, C0111
# pylint: disable=W0232, C0111
...
@@ -73,8 +74,14 @@ class ItemFactory(SplitFactory):
...
@@ -73,8 +74,14 @@ class ItemFactory(SplitFactory):
:param definition_locator (optional): the DescriptorLocator for the definition this uses or branches
:param definition_locator (optional): the DescriptorLocator for the definition this uses or branches
"""
"""
modulestore
=
kwargs
.
pop
(
'modulestore'
)
modulestore
=
kwargs
.
pop
(
'modulestore'
)
if
isinstance
(
parent_location
,
UsageKey
):
return
modulestore
.
create_child
(
user_id
,
parent_location
,
category
,
defintion_locator
=
definition_locator
,
force
=
force
,
continue_version
=
continue_version
,
**
kwargs
)
else
:
return
modulestore
.
create_item
(
return
modulestore
.
create_item
(
user_id
,
category
=
category
,
parent_location
=
parent_location
,
defintion_locator
=
definition_locator
,
user_id
,
parent_location
,
category
,
defintion_locator
=
definition_locator
,
force
=
force
,
continue_version
=
continue_version
,
**
kwargs
force
=
force
,
continue_version
=
continue_version
,
**
kwargs
)
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
483e2a6a
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
View file @
483e2a6a
...
@@ -391,12 +391,27 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -391,12 +391,27 @@ class TestMongoModuleStore(unittest.TestCase):
course
=
self
.
draft_store
.
get_course
(
course_key
)
course
=
self
.
draft_store
.
get_course
(
course_key
)
# can't use item factory as it depends on django settings
# can't use item factory as it depends on django settings
p1ele
=
self
.
draft_store
.
create_item
(
p1ele
=
self
.
draft_store
.
create_item
(
99
,
course
.
id
.
make_usage_key
(
'problem'
,
'p1'
),
runtime
=
course
.
runtime
)
99
,
course_key
,
'problem'
,
block_id
=
'p1'
,
runtime
=
course
.
runtime
)
p2ele
=
self
.
draft_store
.
create_item
(
p2ele
=
self
.
draft_store
.
create_item
(
99
,
course
.
id
.
make_usage_key
(
'problem'
,
'p2'
),
runtime
=
course
.
runtime
)
99
,
course_key
,
'problem'
,
block_id
=
'p2'
,
runtime
=
course
.
runtime
)
self
.
refloc
=
course
.
id
.
make_usage_key
(
'ref_test'
,
'ref_test'
)
self
.
refloc
=
course
.
id
.
make_usage_key
(
'ref_test'
,
'ref_test'
)
self
.
draft_store
.
create_item
(
self
.
draft_store
.
create_item
(
99
,
self
.
refloc
,
runtime
=
course
.
runtime
,
fields
=
{
99
,
self
.
refloc
.
course_key
,
self
.
refloc
.
block_type
,
block_id
=
self
.
refloc
.
block_id
,
runtime
=
course
.
runtime
,
fields
=
{
'reference_link'
:
p1ele
.
location
,
'reference_link'
:
p1ele
.
location
,
'reference_list'
:
[
p1ele
.
location
,
p2ele
.
location
],
'reference_list'
:
[
p1ele
.
location
,
p2ele
.
location
],
'reference_dict'
:
{
'p1'
:
p1ele
.
location
,
'p2'
:
p2ele
.
location
},
'reference_dict'
:
{
'p1'
:
p1ele
.
location
,
'p2'
:
p2ele
.
location
},
...
@@ -497,12 +512,16 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -497,12 +512,16 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that has_changes() returns false when a new xblock in a direct only category is checked
Tests that has_changes() returns false when a new xblock in a direct only category is checked
"""
"""
course_location
=
Location
(
'ed
x'
,
'direct'
,
'2012_Fall'
,
'course'
,
'test_course
'
)
course_location
=
Location
(
'ed
X'
,
'toy'
,
'2012_Fall'
,
'course'
,
'2012_Fall
'
)
chapter_location
=
Location
(
'ed
x'
,
'direct'
,
'2012_Fall'
,
'chapter'
,
'test_chapt
er'
)
chapter_location
=
Location
(
'ed
X'
,
'toy'
,
'2012_Fall'
,
'chapter'
,
'vertical_contain
er'
)
# Create dummy direct only xblocks
# Create dummy direct only xblocks
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
course_location
)
self
.
draft_store
.
create_item
(
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
chapter_location
)
self
.
dummy_user
,
chapter_location
.
course_key
,
chapter_location
.
block_type
,
block_id
=
chapter_location
.
block_id
)
# Check that neither xblock has changes
# Check that neither xblock has changes
self
.
assertFalse
(
self
.
draft_store
.
has_changes
(
course_location
))
self
.
assertFalse
(
self
.
draft_store
.
has_changes
(
course_location
))
...
@@ -512,10 +531,15 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -512,10 +531,15 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that has_changes() only returns true when changes are present
Tests that has_changes() only returns true when changes are present
"""
"""
location
=
Location
(
'edX'
,
'
changes
'
,
'2012_Fall'
,
'vertical'
,
'test_vertical'
)
location
=
Location
(
'edX'
,
'
toy
'
,
'2012_Fall'
,
'vertical'
,
'test_vertical'
)
# Create a dummy component to test against
# Create a dummy component to test against
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
location
)
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
# Not yet published, so changes are present
# Not yet published, so changes are present
self
.
assertTrue
(
self
.
draft_store
.
has_changes
(
location
))
self
.
assertTrue
(
self
.
draft_store
.
has_changes
(
location
))
...
@@ -538,11 +562,16 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -538,11 +562,16 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that has_changes() returns False when a published parent points to a child that doesn't exist.
Tests that has_changes() returns False when a published parent points to a child that doesn't exist.
"""
"""
location
=
Location
(
'edX'
,
'
missing
'
,
'2012_Fall'
,
'sequential'
,
'parent'
)
location
=
Location
(
'edX'
,
'
toy
'
,
'2012_Fall'
,
'sequential'
,
'parent'
)
# Create the parent and point it to a fake child
# Create the parent and point it to a fake child
parent
=
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
location
)
parent
=
self
.
draft_store
.
create_item
(
parent
.
children
+=
[
Location
(
'edX'
,
'missing'
,
'2012_Fall'
,
'vertical'
,
'does_not_exist'
)]
self
.
dummy_user
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
parent
.
children
+=
[
Location
(
'edX'
,
'toy'
,
'2012_Fall'
,
'vertical'
,
'does_not_exist'
)]
self
.
draft_store
.
update_item
(
parent
,
self
.
dummy_user
)
self
.
draft_store
.
update_item
(
parent
,
self
.
dummy_user
)
# Check the parent for changes should return False and not throw an exception
# Check the parent for changes should return False and not throw an exception
...
@@ -561,16 +590,28 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -561,16 +590,28 @@ class TestMongoModuleStore(unittest.TestCase):
if
user_id
is
None
:
if
user_id
is
None
:
user_id
=
self
.
dummy_user
user_id
=
self
.
dummy_user
org
=
'edX'
course
=
'tree{}'
.
format
(
name
)
run
=
name
if
not
self
.
draft_store
.
has_course
(
SlashSeparatedCourseKey
(
org
,
course
,
run
)):
self
.
draft_store
.
create_course
(
org
,
course
,
run
,
user_id
)
locations
=
{
locations
=
{
'grandparent'
:
Location
(
'edX'
,
'tree'
,
name
,
'chapter'
,
'grandparent'
),
'grandparent'
:
Location
(
org
,
course
,
run
,
'chapter'
,
'grandparent'
),
'parent_sibling'
:
Location
(
'edX'
,
'tree'
,
name
,
'sequential'
,
'parent_sibling'
),
'parent_sibling'
:
Location
(
org
,
course
,
run
,
'sequential'
,
'parent_sibling'
),
'parent'
:
Location
(
'edX'
,
'tree'
,
name
,
'sequential'
,
'parent'
),
'parent'
:
Location
(
org
,
course
,
run
,
'sequential'
,
'parent'
),
'child_sibling'
:
Location
(
'edX'
,
'tree'
,
name
,
'vertical'
,
'child_sibling'
),
'child_sibling'
:
Location
(
org
,
course
,
run
,
'vertical'
,
'child_sibling'
),
'child'
:
Location
(
'edX'
,
'tree'
,
name
,
'vertical'
,
'child'
),
'child'
:
Location
(
org
,
course
,
run
,
'vertical'
,
'child'
),
}
}
for
key
in
locations
:
for
key
in
locations
:
self
.
draft_store
.
create_item
(
user_id
,
locations
[
key
])
self
.
draft_store
.
create_item
(
user_id
,
locations
[
key
]
.
course_key
,
locations
[
key
]
.
block_type
,
block_id
=
locations
[
key
]
.
block_id
)
grandparent
=
self
.
draft_store
.
get_item
(
locations
[
'grandparent'
])
grandparent
=
self
.
draft_store
.
get_item
(
locations
[
'grandparent'
])
grandparent
.
children
+=
[
locations
[
'parent_sibling'
],
locations
[
'parent'
]]
grandparent
.
children
+=
[
locations
[
'parent_sibling'
],
locations
[
'parent'
]]
...
@@ -663,10 +704,12 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -663,10 +704,12 @@ class TestMongoModuleStore(unittest.TestCase):
# Create a new child and attach it to parent
# Create a new child and attach it to parent
new_child_location
=
Location
(
'edX'
,
'tree'
,
'has_changes_add_remove_child'
,
'vertical'
,
'new_child'
)
new_child_location
=
Location
(
'edX'
,
'tree'
,
'has_changes_add_remove_child'
,
'vertical'
,
'new_child'
)
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
new_child_location
)
self
.
draft_store
.
create_child
(
parent
=
self
.
draft_store
.
get_item
(
locations
[
'parent'
])
self
.
dummy_user
,
parent
.
children
+=
[
new_child_location
]
locations
[
'parent'
],
self
.
draft_store
.
update_item
(
parent
,
user_id
=
self
.
dummy_user
)
new_child_location
.
block_type
,
block_id
=
new_child_location
.
block_id
)
# Verify that the ancestors now have changes
# Verify that the ancestors now have changes
self
.
assertTrue
(
self
.
draft_store
.
has_changes
(
locations
[
'grandparent'
]))
self
.
assertTrue
(
self
.
draft_store
.
has_changes
(
locations
[
'grandparent'
]))
...
@@ -685,13 +728,21 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -685,13 +728,21 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that has_changes() returns true after editing the child of a vertical (both not direct only categories).
Tests that has_changes() returns true after editing the child of a vertical (both not direct only categories).
"""
"""
parent_location
=
Location
(
'edX'
,
't
est'
,
'non_direct_only_children
'
,
'vertical'
,
'parent'
)
parent_location
=
Location
(
'edX'
,
't
oy'
,
'2012_Fall
'
,
'vertical'
,
'parent'
)
child_location
=
Location
(
'edX'
,
't
est'
,
'non_direct_only_children
'
,
'html'
,
'child'
)
child_location
=
Location
(
'edX'
,
't
oy'
,
'2012_Fall
'
,
'html'
,
'child'
)
parent
=
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
parent_location
)
parent
=
self
.
draft_store
.
create_item
(
child
=
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
child_location
)
self
.
dummy_user
,
parent
.
children
+=
[
child_location
]
parent_location
.
course_key
,
self
.
draft_store
.
update_item
(
parent
,
user_id
=
self
.
dummy_user
)
parent_location
.
block_type
,
block_id
=
parent_location
.
block_id
)
child
=
self
.
draft_store
.
create_child
(
self
.
dummy_user
,
parent_location
,
child_location
.
block_type
,
block_id
=
child_location
.
block_id
)
self
.
draft_store
.
publish
(
parent_location
,
self
.
dummy_user
)
self
.
draft_store
.
publish
(
parent_location
,
self
.
dummy_user
)
# Verify that there are no changes
# Verify that there are no changes
...
@@ -757,10 +808,15 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -757,10 +808,15 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that edited_on and edited_by are set correctly during an update
Tests that edited_on and edited_by are set correctly during an update
"""
"""
location
=
Location
(
'edX'
,
'
editInfoTest
'
,
'2012_Fall'
,
'html'
,
'test_html'
)
location
=
Location
(
'edX'
,
'
toy
'
,
'2012_Fall'
,
'html'
,
'test_html'
)
# Create a dummy component to test against
# Create a dummy component to test against
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
location
)
self
.
draft_store
.
create_item
(
self
.
dummy_user
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
# Store the current edit time and verify that dummy_user created the component
# Store the current edit time and verify that dummy_user created the component
component
=
self
.
draft_store
.
get_item
(
location
)
component
=
self
.
draft_store
.
get_item
(
location
)
...
@@ -780,12 +836,17 @@ class TestMongoModuleStore(unittest.TestCase):
...
@@ -780,12 +836,17 @@ class TestMongoModuleStore(unittest.TestCase):
"""
"""
Tests that published_date and published_by are set correctly
Tests that published_date and published_by are set correctly
"""
"""
location
=
Location
(
'edX'
,
'
publishInfo
'
,
'2012_Fall'
,
'html'
,
'test_html'
)
location
=
Location
(
'edX'
,
'
toy
'
,
'2012_Fall'
,
'html'
,
'test_html'
)
create_user
=
123
create_user
=
123
publish_user
=
456
publish_user
=
456
# Create a dummy component to test against
# Create a dummy component to test against
self
.
draft_store
.
create_item
(
create_user
,
location
)
self
.
draft_store
.
create_item
(
create_user
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
)
# Store the current time, then publish
# Store the current time, then publish
old_time
=
datetime
.
now
(
UTC
)
old_time
=
datetime
.
now
(
UTC
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
View file @
483e2a6a
...
@@ -19,7 +19,7 @@ class TestPublish(SplitWMongoCourseBoostrapper):
...
@@ -19,7 +19,7 @@ class TestPublish(SplitWMongoCourseBoostrapper):
# There are 12 created items and 7 parent updates
# There are 12 created items and 7 parent updates
# create course: finds: 1 to verify uniqueness, 1 to find parents
# create course: finds: 1 to verify uniqueness, 1 to find parents
# sends: 1 to create course, 1 to create overview
# sends: 1 to create course, 1 to create overview
with
check_mongo_calls
(
self
.
draft_mongo
,
5
,
2
):
with
check_mongo_calls
(
self
.
draft_mongo
,
6
,
2
):
super
(
TestPublish
,
self
)
.
_create_course
(
split
=
False
)
# 2 inserts (course and overview)
super
(
TestPublish
,
self
)
.
_create_course
(
split
=
False
)
# 2 inserts (course and overview)
# with bulk will delay all inheritance computations which won't be added into the mongo_calls
# with bulk will delay all inheritance computations which won't be added into the mongo_calls
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_draft_modulestore.py
View file @
483e2a6a
...
@@ -30,8 +30,7 @@ class TestDraftVersioningModuleStore(unittest.TestCase):
...
@@ -30,8 +30,7 @@ class TestDraftVersioningModuleStore(unittest.TestCase):
render_template
=
render_to_template_mock
,
render_template
=
render_to_template_mock
,
xblock_mixins
=
(
InheritanceMixin
,
XModuleMixin
),
xblock_mixins
=
(
InheritanceMixin
,
XModuleMixin
),
)
)
# NAATODO - uncomment once merged with drop_database PR
self
.
addCleanup
(
self
.
module_store
.
_drop_database
)
# self.addCleanup(module_store._drop_database)
SplitModuleTest
.
bootstrapDB
(
self
.
module_store
)
SplitModuleTest
.
bootstrapDB
(
self
.
module_store
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
View file @
483e2a6a
...
@@ -985,7 +985,7 @@ class TestItemCrud(SplitModuleTest):
...
@@ -985,7 +985,7 @@ class TestItemCrud(SplitModuleTest):
# add minimal one w/o a parent
# add minimal one w/o a parent
category
=
'sequential'
category
=
'sequential'
new_module
=
modulestore
()
.
create_item
(
new_module
=
modulestore
()
.
create_item
(
'user123'
,
parent_location
=
locator
,
category
=
category
,
'user123'
,
locator
,
category
,
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
...
@@ -1025,8 +1025,8 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1025,8 +1025,8 @@ class TestItemCrud(SplitModuleTest):
)
)
premod_course
=
modulestore
()
.
get_course
(
locator
.
course_key
)
premod_course
=
modulestore
()
.
get_course
(
locator
.
course_key
)
category
=
'chapter'
category
=
'chapter'
new_module
=
modulestore
()
.
create_
item
(
new_module
=
modulestore
()
.
create_
child
(
'user123'
,
parent_location
=
locator
,
category
=
category
,
'user123'
,
locator
,
category
,
fields
=
{
'display_name'
:
'new chapter'
},
fields
=
{
'display_name'
:
'new chapter'
},
definition_locator
=
original
.
definition_locator
definition_locator
=
original
.
definition_locator
)
)
...
@@ -1054,13 +1054,13 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1054,13 +1054,13 @@ class TestItemCrud(SplitModuleTest):
)
)
category
=
'problem'
category
=
'problem'
new_payload
=
"<problem>empty</problem>"
new_payload
=
"<problem>empty</problem>"
new_module
=
modulestore
()
.
create_
item
(
new_module
=
modulestore
()
.
create_
child
(
'anotheruser'
,
parent_location
=
locator
,
category
=
category
,
'anotheruser'
,
locator
,
category
,
fields
=
{
'display_name'
:
'problem 1'
,
'data'
:
new_payload
},
fields
=
{
'display_name'
:
'problem 1'
,
'data'
:
new_payload
},
)
)
another_payload
=
"<problem>not empty</problem>"
another_payload
=
"<problem>not empty</problem>"
another_module
=
modulestore
()
.
create_
item
(
another_module
=
modulestore
()
.
create_
child
(
'anotheruser'
,
parent_location
=
locator
,
category
=
category
,
'anotheruser'
,
locator
,
category
,
fields
=
{
'display_name'
:
'problem 2'
,
'data'
:
another_payload
},
fields
=
{
'display_name'
:
'problem 2'
,
'data'
:
another_payload
},
definition_locator
=
original
.
definition_locator
,
definition_locator
=
original
.
definition_locator
,
)
)
...
@@ -1086,8 +1086,8 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1086,8 +1086,8 @@ class TestItemCrud(SplitModuleTest):
course_key
=
CourseLocator
(
org
=
'guestx'
,
course
=
'contender'
,
run
=
"run"
,
branch
=
BRANCH_NAME_DRAFT
)
course_key
=
CourseLocator
(
org
=
'guestx'
,
course
=
'contender'
,
run
=
"run"
,
branch
=
BRANCH_NAME_DRAFT
)
parent_locator
=
BlockUsageLocator
(
course_key
,
'course'
,
block_id
=
"head345679"
)
parent_locator
=
BlockUsageLocator
(
course_key
,
'course'
,
block_id
=
"head345679"
)
chapter_locator
=
BlockUsageLocator
(
course_key
,
'chapter'
,
block_id
=
"foo.bar_-~:0"
)
chapter_locator
=
BlockUsageLocator
(
course_key
,
'chapter'
,
block_id
=
"foo.bar_-~:0"
)
modulestore
()
.
create_
item
(
modulestore
()
.
create_
child
(
'anotheruser'
,
parent_locat
ion
=
parent_locator
,
category
=
'chapter'
,
'anotheruser'
,
parent_locat
or
,
'chapter'
,
block_id
=
chapter_locator
.
block_id
,
block_id
=
chapter_locator
.
block_id
,
fields
=
{
'display_name'
:
'chapter 99'
},
fields
=
{
'display_name'
:
'chapter 99'
},
)
)
...
@@ -1097,8 +1097,8 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1097,8 +1097,8 @@ class TestItemCrud(SplitModuleTest):
# now try making that a parent of something
# now try making that a parent of something
new_payload
=
"<problem>empty</problem>"
new_payload
=
"<problem>empty</problem>"
problem_locator
=
BlockUsageLocator
(
course_key
,
'problem'
,
block_id
=
"prob.bar_-~:99a"
)
problem_locator
=
BlockUsageLocator
(
course_key
,
'problem'
,
block_id
=
"prob.bar_-~:99a"
)
modulestore
()
.
create_
item
(
modulestore
()
.
create_
child
(
'anotheruser'
,
parent_location
=
chapter_locator
,
category
=
'problem'
,
'anotheruser'
,
chapter_locator
,
'problem'
,
block_id
=
problem_locator
.
block_id
,
block_id
=
problem_locator
.
block_id
,
fields
=
{
'display_name'
:
'chapter 99'
,
'data'
:
new_payload
},
fields
=
{
'display_name'
:
'chapter 99'
,
'data'
:
new_payload
},
)
)
...
@@ -1123,8 +1123,8 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1123,8 +1123,8 @@ class TestItemCrud(SplitModuleTest):
versionless_course_locator
=
new_course_locator
.
version_agnostic
()
versionless_course_locator
=
new_course_locator
.
version_agnostic
()
# positive simple case: no force, add chapter
# positive simple case: no force, add chapter
new_ele
=
modulestore
()
.
create_
item
(
new_ele
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
new_course
.
location
,
category
=
'chapter'
,
user
,
new_course
.
location
,
'chapter'
,
fields
=
{
'display_name'
:
'chapter 1'
},
fields
=
{
'display_name'
:
'chapter 1'
},
continue_version
=
True
continue_version
=
True
)
)
...
@@ -1141,40 +1141,40 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1141,40 +1141,40 @@ class TestItemCrud(SplitModuleTest):
# try to create existing item
# try to create existing item
with
self
.
assertRaises
(
DuplicateItemError
):
with
self
.
assertRaises
(
DuplicateItemError
):
_fail
=
modulestore
()
.
create_
item
(
_fail
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
new_course
.
location
,
category
=
'chapter'
,
user
,
new_course
.
location
,
'chapter'
,
block_id
=
new_ele
.
location
.
block_id
,
block_id
=
new_ele
.
location
.
block_id
,
fields
=
{
'display_name'
:
'chapter 2'
},
fields
=
{
'display_name'
:
'chapter 2'
},
continue_version
=
True
continue_version
=
True
)
)
# start a new transaction
# start a new transaction
new_ele
=
modulestore
()
.
create_
item
(
new_ele
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
new_course
.
location
,
category
=
'chapter'
,
user
,
new_course
.
location
,
'chapter'
,
fields
=
{
'display_name'
:
'chapter 2'
},
fields
=
{
'display_name'
:
'chapter 2'
},
continue_version
=
False
continue_version
=
False
)
)
transaction_guid
=
new_ele
.
location
.
version_guid
transaction_guid
=
new_ele
.
location
.
version_guid
# ensure force w/ continue gives exception
# ensure force w/ continue gives exception
with
self
.
assertRaises
(
VersionConflictError
):
with
self
.
assertRaises
(
VersionConflictError
):
_fail
=
modulestore
()
.
create_
item
(
_fail
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
new_course
.
location
,
category
=
'chapter'
,
user
,
new_course
.
location
,
'chapter'
,
fields
=
{
'display_name'
:
'chapter 2'
},
fields
=
{
'display_name'
:
'chapter 2'
},
force
=
True
,
continue_version
=
True
force
=
True
,
continue_version
=
True
)
)
# ensure trying to continue the old one gives exception
# ensure trying to continue the old one gives exception
with
self
.
assertRaises
(
VersionConflictError
):
with
self
.
assertRaises
(
VersionConflictError
):
_fail
=
modulestore
()
.
create_
item
(
_fail
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
new_course
.
location
,
category
=
'chapter'
,
user
,
new_course
.
location
,
'chapter'
,
fields
=
{
'display_name'
:
'chapter 3'
},
fields
=
{
'display_name'
:
'chapter 3'
},
continue_version
=
True
continue_version
=
True
)
)
# 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
=
new_course
.
location
.
version_agnostic
()
course_module_locator
=
new_course
.
location
.
version_agnostic
()
new_ele
=
modulestore
()
.
create_
item
(
new_ele
=
modulestore
()
.
create_
child
(
user
,
parent_location
=
course_module_locator
,
category
=
'chapter'
,
user
,
course_module_locator
,
'chapter'
,
fields
=
{
'display_name'
:
'chapter 4'
},
fields
=
{
'display_name'
:
'chapter 4'
},
continue_version
=
True
continue_version
=
True
)
)
...
@@ -1283,13 +1283,13 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1283,13 +1283,13 @@ class TestItemCrud(SplitModuleTest):
)
)
category
=
'problem'
category
=
'problem'
new_payload
=
"<problem>empty</problem>"
new_payload
=
"<problem>empty</problem>"
modulestore
()
.
create_
item
(
modulestore
()
.
create_
child
(
'test_update_manifold'
,
parent_location
=
locator
,
category
=
category
,
'test_update_manifold'
,
locator
,
category
,
fields
=
{
'display_name'
:
'problem 1'
,
'data'
:
new_payload
},
fields
=
{
'display_name'
:
'problem 1'
,
'data'
:
new_payload
},
)
)
another_payload
=
"<problem>not empty</problem>"
another_payload
=
"<problem>not empty</problem>"
modulestore
()
.
create_
item
(
modulestore
()
.
create_
child
(
'test_update_manifold'
,
parent_location
=
locator
,
category
=
category
,
'test_update_manifold'
,
locator
,
category
,
fields
=
{
'display_name'
:
'problem 2'
,
'data'
:
another_payload
},
fields
=
{
'display_name'
:
'problem 2'
,
'data'
:
another_payload
},
definition_locator
=
original
.
definition_locator
,
definition_locator
=
original
.
definition_locator
,
)
)
...
@@ -1368,8 +1368,8 @@ class TestItemCrud(SplitModuleTest):
...
@@ -1368,8 +1368,8 @@ class TestItemCrud(SplitModuleTest):
"""
"""
if
not
category_queue
:
if
not
category_queue
:
return
return
node
=
modulestore
()
.
create_
item
(
node
=
modulestore
()
.
create_
child
(
'deleting_user'
,
parent
_location
=
parent
.
version_agnostic
(),
category
=
category_queue
[
0
]
'deleting_user'
,
parent
.
version_agnostic
(),
category_queue
[
0
]
)
)
node_loc
=
node
.
location
.
map_into_course
(
parent
.
course_key
)
node_loc
=
node
.
location
.
map_into_course
(
parent
.
course_key
)
for
_
in
range
(
4
):
for
_
in
range
(
4
):
...
@@ -1433,8 +1433,8 @@ class TestCourseCreation(SplitModuleTest):
...
@@ -1433,8 +1433,8 @@ class TestCourseCreation(SplitModuleTest):
# changing this course will not change the original course
# changing this course will not change the original course
# using new_draft.location will insert the chapter under the course root
# using new_draft.location will insert the chapter under the course root
new_item
=
modulestore
()
.
create_
item
(
new_item
=
modulestore
()
.
create_
child
(
'leech_master'
,
parent_location
=
new_draft
.
location
,
category
=
'chapter'
,
'leech_master'
,
new_draft
.
location
,
'chapter'
,
fields
=
{
'display_name'
:
'new chapter'
}
fields
=
{
'display_name'
:
'new chapter'
}
)
)
new_draft_locator
=
new_draft_locator
.
course_key
.
version_agnostic
()
new_draft_locator
=
new_draft_locator
.
course_key
.
version_agnostic
()
...
@@ -1595,8 +1595,8 @@ class TestPublish(SplitModuleTest):
...
@@ -1595,8 +1595,8 @@ class TestPublish(SplitModuleTest):
source_course
,
dest_course
,
expected
,
[
chapter2
.
block_id
,
chapter3
.
block_id
,
"problem1"
,
"problem3_2"
]
source_course
,
dest_course
,
expected
,
[
chapter2
.
block_id
,
chapter3
.
block_id
,
"problem1"
,
"problem3_2"
]
)
)
# add a child under chapter1
# add a child under chapter1
new_module
=
modulestore
()
.
create_
item
(
new_module
=
modulestore
()
.
create_
child
(
self
.
user_id
,
parent_location
=
chapter1
,
category
=
"sequential"
,
self
.
user_id
,
chapter1
,
"sequential"
,
fields
=
{
'display_name'
:
'new sequential'
},
fields
=
{
'display_name'
:
'new sequential'
},
)
)
# remove chapter1 from expected b/c its pub'd version != the source anymore since source changed
# remove chapter1 from expected b/c its pub'd version != the source anymore since source changed
...
@@ -1614,7 +1614,7 @@ class TestPublish(SplitModuleTest):
...
@@ -1614,7 +1614,7 @@ class TestPublish(SplitModuleTest):
)
)
# ensure intentionally orphaned blocks work (e.g., course_info)
# ensure intentionally orphaned blocks work (e.g., course_info)
new_module
=
modulestore
()
.
create_item
(
new_module
=
modulestore
()
.
create_item
(
self
.
user_id
,
parent_location
=
source_course
,
category
=
"course_info"
,
block_id
=
"handouts"
self
.
user_id
,
source_course
,
"course_info"
,
block_id
=
"handouts"
)
)
# publish it
# publish it
modulestore
()
.
copy
(
self
.
user_id
,
source_course
,
dest_course
,
[
new_module
.
location
],
None
)
modulestore
()
.
copy
(
self
.
user_id
,
source_course
,
dest_course
,
[
new_module
.
location
],
None
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
View file @
483e2a6a
...
@@ -87,7 +87,13 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
...
@@ -87,7 +87,13 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
"""
"""
location
=
self
.
old_course_key
.
make_usage_key
(
category
,
name
)
location
=
self
.
old_course_key
.
make_usage_key
(
category
,
name
)
self
.
draft_mongo
.
create_item
(
self
.
draft_mongo
.
create_item
(
self
.
user_id
,
location
,
definition_data
=
data
,
metadata
=
metadata
,
runtime
=
self
.
runtime
self
.
user_id
,
location
.
course_key
,
location
.
block_type
,
block_id
=
location
.
block_id
,
definition_data
=
data
,
metadata
=
metadata
,
runtime
=
self
.
runtime
)
)
if
not
draft
:
if
not
draft
:
self
.
draft_mongo
.
publish
(
location
,
self
.
user_id
)
self
.
draft_mongo
.
publish
(
location
,
self
.
user_id
)
...
@@ -104,16 +110,28 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
...
@@ -104,16 +110,28 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
self
.
draft_mongo
.
update_item
(
parent
,
self
.
user_id
)
self
.
draft_mongo
.
update_item
(
parent
,
self
.
user_id
)
if
not
draft
:
if
not
draft
:
self
.
draft_mongo
.
publish
(
parent_location
,
self
.
user_id
)
self
.
draft_mongo
.
publish
(
parent_location
,
self
.
user_id
)
# create pointer for split
# create child for split
course_or_parent_locator
=
BlockUsageLocator
(
if
split
:
self
.
split_mongo
.
create_child
(
self
.
user_id
,
BlockUsageLocator
(
course_key
=
self
.
split_course_key
,
course_key
=
self
.
split_course_key
,
block_type
=
parent_category
,
block_type
=
parent_category
,
block_id
=
parent_name
block_id
=
parent_name
),
category
,
block_id
=
name
,
fields
=
fields
)
)
else
:
else
:
course_or_parent_locator
=
self
.
split_course_key
if
split
:
if
split
:
self
.
split_mongo
.
create_item
(
course_or_parent_locator
,
category
,
self
.
user_id
,
block_id
=
name
,
fields
=
fields
)
self
.
split_mongo
.
create_item
(
self
.
user_id
,
self
.
split_course_key
,
category
,
block_id
=
name
,
fields
=
fields
)
def
_create_course
(
self
,
split
=
True
):
def
_create_course
(
self
,
split
=
True
):
"""
"""
...
...
common/lib/xmodule/xmodule/split_test_module.py
View file @
483e2a6a
...
@@ -578,7 +578,9 @@ class SplitTestDescriptor(SplitTestFields, SequenceDescriptor, StudioEditableDes
...
@@ -578,7 +578,9 @@ class SplitTestDescriptor(SplitTestFields, SequenceDescriptor, StudioEditableDes
metadata
=
{
'display_name'
:
group
.
name
}
metadata
=
{
'display_name'
:
group
.
name
}
modulestore
.
create_item
(
modulestore
.
create_item
(
user_id
,
user_id
,
dest_usage_key
,
self
.
location
.
course_key
,
dest_usage_key
.
block_type
,
block_id
=
dest_usage_key
.
block_id
,
definition_data
=
None
,
definition_data
=
None
,
metadata
=
metadata
,
metadata
=
metadata
,
runtime
=
self
.
system
,
runtime
=
self
.
system
,
...
...
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