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
aca82be3
Commit
aca82be3
authored
Jul 22, 2016
by
Qubad786
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move fix to importer module and fix branch_setting in MixedModuleStore.
parent
210f9328
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
150 additions
and
16 deletions
+150
-16
cms/djangoapps/contentstore/tests/test_libraries.py
+3
-3
cms/djangoapps/contentstore/views/tests/test_import_export.py
+113
-3
common/lib/xmodule/xmodule/modulestore/mixed.py
+7
-2
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+1
-7
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+8
-0
common/lib/xmodule/xmodule/modulestore/xml_importer.py
+18
-1
No files found.
cms/djangoapps/contentstore/tests/test_libraries.py
View file @
aca82be3
...
@@ -64,7 +64,7 @@ class LibraryTestCase(ModuleStoreTestCase):
...
@@ -64,7 +64,7 @@ class LibraryTestCase(ModuleStoreTestCase):
self
.
assertIsInstance
(
lib_key
,
LibraryLocator
)
self
.
assertIsInstance
(
lib_key
,
LibraryLocator
)
return
lib_key
return
lib_key
def
_add_library_content_block
(
self
,
course
,
library_key
,
other_settings
=
None
):
def
_add_library_content_block
(
self
,
course
,
library_key
,
publish_item
=
False
,
other_settings
=
None
):
"""
"""
Helper method to add a LibraryContent block to a course.
Helper method to add a LibraryContent block to a course.
The block will be configured to select content from the library
The block will be configured to select content from the library
...
@@ -75,7 +75,7 @@ class LibraryTestCase(ModuleStoreTestCase):
...
@@ -75,7 +75,7 @@ class LibraryTestCase(ModuleStoreTestCase):
category
=
'library_content'
,
category
=
'library_content'
,
parent_location
=
course
.
location
,
parent_location
=
course
.
location
,
user_id
=
self
.
user
.
id
,
user_id
=
self
.
user
.
id
,
publish_item
=
False
,
publish_item
=
publish_item
,
source_library_id
=
unicode
(
library_key
),
source_library_id
=
unicode
(
library_key
),
**
(
other_settings
or
{})
**
(
other_settings
or
{})
)
)
...
@@ -159,7 +159,7 @@ class TestLibraries(LibraryTestCase):
...
@@ -159,7 +159,7 @@ class TestLibraries(LibraryTestCase):
with
modulestore
()
.
default_store
(
ModuleStoreEnum
.
Type
.
split
):
with
modulestore
()
.
default_store
(
ModuleStoreEnum
.
Type
.
split
):
course
=
CourseFactory
.
create
()
course
=
CourseFactory
.
create
()
lc_block
=
self
.
_add_library_content_block
(
course
,
self
.
lib_key
,
{
'max_count'
:
num_to_select
})
lc_block
=
self
.
_add_library_content_block
(
course
,
self
.
lib_key
,
other_settings
=
{
'max_count'
:
num_to_select
})
self
.
assertEqual
(
len
(
lc_block
.
children
),
0
)
self
.
assertEqual
(
len
(
lc_block
.
children
),
0
)
lc_block
=
self
.
_refresh_children
(
lc_block
)
lc_block
=
self
.
_refresh_children
(
lc_block
)
...
...
cms/djangoapps/contentstore/views/tests/test_import_export.py
View file @
aca82be3
...
@@ -15,15 +15,17 @@ from uuid import uuid4
...
@@ -15,15 +15,17 @@ from uuid import uuid4
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
django.conf
import
settings
from
django.conf
import
settings
from
contentstore.tests.test_libraries
import
LibraryTestCase
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.xml_exporter
import
export_library_to_xml
from
xmodule.modulestore.xml_exporter
import
export_library_to_xml
,
export_course_to_xml
from
xmodule.modulestore.xml_importer
import
import_library_from_xml
from
xmodule.modulestore.xml_importer
import
import_library_from_xml
,
import_course_from_xml
from
xmodule.modulestore
import
LIBRARY_ROOT
,
ModuleStoreEnum
from
xmodule.modulestore
import
LIBRARY_ROOT
,
ModuleStoreEnum
from
contentstore.utils
import
reverse_course_url
from
contentstore.utils
import
reverse_course_url
from
contentstore.tests.utils
import
CourseTestCase
from
contentstore.tests.utils
import
CourseTestCase
from
xmodule.modulestore.tests.factories
import
ItemFactory
,
LibraryFactory
from
xmodule.modulestore.tests.factories
import
ItemFactory
,
LibraryFactory
,
CourseFactory
from
xmodule.modulestore.tests.utils
import
(
from
xmodule.modulestore.tests.utils
import
(
MongoContentstoreBuilder
,
SPLIT_MODULESTORE_SETUP
,
TEST_DATA_DIR
MongoContentstoreBuilder
,
SPLIT_MODULESTORE_SETUP
,
TEST_DATA_DIR
)
)
...
@@ -697,3 +699,111 @@ class TestLibraryImportExport(CourseTestCase):
...
@@ -697,3 +699,111 @@ class TestLibraryImportExport(CourseTestCase):
# Compare the two content libraries for equality.
# Compare the two content libraries for equality.
self
.
assertCoursesEqual
(
source_library1_key
,
source_library2_key
)
self
.
assertCoursesEqual
(
source_library1_key
,
source_library2_key
)
@ddt.ddt
@override_settings
(
CONTENTSTORE
=
TEST_DATA_CONTENTSTORE
)
class
TestCourseExportImport
(
LibraryTestCase
):
"""
Tests for importing after exporting the course containing content libraries from XML.
"""
def
setUp
(
self
):
super
(
TestCourseExportImport
,
self
)
.
setUp
()
self
.
export_dir
=
tempfile
.
mkdtemp
()
# Create a problem in library
ItemFactory
.
create
(
category
=
"problem"
,
parent_location
=
self
.
library
.
location
,
user_id
=
self
.
user
.
id
,
# pylint: disable=no-member
publish_item
=
False
,
display_name
=
'Test Problem'
,
data
=
"<problem><multiplechoiceresponse></multiplechoiceresponse></problem>"
,
)
# Create a source course.
self
.
source_course
=
CourseFactory
.
create
(
default_store
=
ModuleStoreEnum
.
Type
.
split
)
self
.
addCleanup
(
shutil
.
rmtree
,
self
.
export_dir
,
ignore_errors
=
True
)
def
_setup_source_course_with_library_content
(
self
,
publish
=
False
):
"""
Sets up course with library content.
"""
chapter
=
ItemFactory
.
create
(
parent_location
=
self
.
source_course
.
location
,
category
=
'chapter'
,
display_name
=
'Test Section'
)
sequential
=
ItemFactory
.
create
(
parent_location
=
chapter
.
location
,
category
=
'sequential'
,
display_name
=
'Test Sequential'
)
vertical
=
ItemFactory
.
create
(
category
=
'vertical'
,
parent_location
=
sequential
.
location
,
display_name
=
'Test Unit'
)
lc_block
=
self
.
_add_library_content_block
(
vertical
,
self
.
lib_key
,
publish_item
=
publish
)
self
.
_refresh_children
(
lc_block
)
def
get_lib_content_block_children
(
self
,
block_location
):
"""
Search for library content block to return its immediate children
"""
if
block_location
.
block_type
==
'library_content'
:
return
self
.
store
.
get_item
(
block_location
)
.
children
return
self
.
get_lib_content_block_children
(
self
.
store
.
get_item
(
block_location
)
.
children
[
0
])
def
assert_problem_display_names
(
self
,
source_course_location
,
dest_course_location
):
"""
Asserts that problems' display names in both source and destination courses are same.
"""
source_course_lib_children
=
self
.
get_lib_content_block_children
(
source_course_location
)
dest_course_lib_children
=
self
.
get_lib_content_block_children
(
dest_course_location
)
self
.
assertEquals
(
len
(
source_course_lib_children
),
len
(
dest_course_lib_children
))
for
source_child_location
,
dest_child_location
in
zip
(
source_course_lib_children
,
dest_course_lib_children
):
source_child
=
self
.
store
.
get_item
(
source_child_location
)
dest_child
=
self
.
store
.
get_item
(
dest_child_location
)
self
.
assertEquals
(
source_child
.
display_name
,
dest_child
.
display_name
)
@ddt.data
(
True
,
False
)
def
test_library_content_on_course_export_import
(
self
,
publish_item
):
"""
Verify that library contents in destination and source courses are same after importing
the source course into destination course.
"""
self
.
_setup_source_course_with_library_content
(
publish
=
publish_item
)
# Create a course to import source course.
dest_course
=
CourseFactory
.
create
(
default_store
=
ModuleStoreEnum
.
Type
.
split
)
# Export the source course.
export_course_to_xml
(
self
.
store
,
contentstore
(),
self
.
source_course
.
location
.
course_key
,
self
.
export_dir
,
'exported_source_course'
,
)
# Now, import it back to dest_course.
import_course_from_xml
(
self
.
store
,
self
.
user
.
id
,
# pylint: disable=no-member
self
.
export_dir
,
[
'exported_source_course'
],
static_content_store
=
contentstore
(),
target_id
=
dest_course
.
location
.
course_key
,
load_error_modules
=
False
,
raise_on_failure
=
True
,
create_if_not_present
=
True
,
)
self
.
assert_problem_display_names
(
self
.
source_course
.
location
,
dest_course
.
location
)
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
aca82be3
...
@@ -980,8 +980,13 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -980,8 +980,13 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
to the given branch_setting. If course_id is None, the default store is used.
to the given branch_setting. If course_id is None, the default store is used.
"""
"""
store
=
self
.
_verify_modulestore_support
(
course_id
,
'branch_setting'
)
store
=
self
.
_verify_modulestore_support
(
course_id
,
'branch_setting'
)
with
store
.
branch_setting
(
branch_setting
,
course_id
):
previous_thread_branch_setting
=
getattr
(
self
.
thread_cache
,
'branch_setting'
,
None
)
yield
try
:
self
.
thread_cache
.
branch_setting
=
branch_setting
with
store
.
branch_setting
(
branch_setting
,
course_id
):
yield
finally
:
self
.
thread_cache
.
branch_setting
=
previous_thread_branch_setting
@contextmanager
@contextmanager
def
bulk_operations
(
self
,
course_id
,
emit_signals
=
True
):
def
bulk_operations
(
self
,
course_id
,
emit_signals
=
True
):
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
aca82be3
...
@@ -68,7 +68,6 @@ from xblock.core import XBlock
...
@@ -68,7 +68,6 @@ from xblock.core import XBlock
from
xblock.fields
import
Scope
,
Reference
,
ReferenceList
,
ReferenceValueDict
from
xblock.fields
import
Scope
,
Reference
,
ReferenceList
,
ReferenceValueDict
from
xmodule.course_module
import
CourseSummary
from
xmodule.course_module
import
CourseSummary
from
xmodule.errortracker
import
null_error_tracker
from
xmodule.errortracker
import
null_error_tracker
from
xmodule.library_tools
import
LibraryToolsService
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.locator
import
(
from
opaque_keys.edx.locator
import
(
BlockUsageLocator
,
DefinitionLocator
,
CourseLocator
,
LibraryLocator
,
VersionTree
,
LocalId
,
BlockUsageLocator
,
DefinitionLocator
,
CourseLocator
,
LibraryLocator
,
VersionTree
,
LocalId
,
...
@@ -2106,12 +2105,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
...
@@ -2106,12 +2105,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, 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
new_locator
=
course_key
.
make_usage_key
(
block_key
.
type
,
block_key
.
id
)
new_locator
=
course_key
.
make_usage_key
(
block_key
.
type
,
block_key
.
id
)
new_item
=
self
.
get_item
(
new_locator
,
**
kwargs
)
return
self
.
get_item
(
new_locator
,
**
kwargs
)
if
block_key
.
type
==
'library_content'
:
# Update imported xblocks' 'source_library_version' to keep it up to date.
LibraryToolsService
(
self
)
.
update_children
(
new_item
,
user_id
)
return
new_item
else
:
else
:
return
None
return
None
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
aca82be3
...
@@ -1991,6 +1991,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
...
@@ -1991,6 +1991,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# there should be no published problems with the old name
# there should be no published problems with the old name
assertNumProblems
(
problem_original_name
,
0
)
assertNumProblems
(
problem_original_name
,
0
)
# verify branch setting is published-only in manager
with
self
.
store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
published_only
):
self
.
assertEquals
(
self
.
store
.
get_branch_setting
(),
ModuleStoreEnum
.
Branch
.
published_only
)
# verify branch setting is draft-preferred in manager
with
self
.
store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
):
self
.
assertEquals
(
self
.
store
.
get_branch_setting
(),
ModuleStoreEnum
.
Branch
.
draft_preferred
)
def
verify_default_store
(
self
,
store_type
):
def
verify_default_store
(
self
,
store_type
):
"""
"""
Verifies the default_store property
Verifies the default_store property
...
...
common/lib/xmodule/xmodule/modulestore/xml_importer.py
View file @
aca82be3
...
@@ -30,6 +30,7 @@ import json
...
@@ -30,6 +30,7 @@ import json
import
re
import
re
from
lxml
import
etree
from
lxml
import
etree
from
xmodule.library_tools
import
LibraryToolsService
from
xmodule.modulestore.xml
import
XMLModuleStore
,
LibraryXMLModuleStore
,
ImportSystem
from
xmodule.modulestore.xml
import
XMLModuleStore
,
LibraryXMLModuleStore
,
ImportSystem
from
xblock.runtime
import
KvsFieldData
,
DictKeyValueStore
from
xblock.runtime
import
KvsFieldData
,
DictKeyValueStore
from
xmodule.x_module
import
XModuleDescriptor
,
XModuleMixin
from
xmodule.x_module
import
XModuleDescriptor
,
XModuleMixin
...
@@ -739,11 +740,27 @@ def _update_and_import_module(
...
@@ -739,11 +740,27 @@ def _update_and_import_module(
fields
=
_update_module_references
(
module
,
source_course_id
,
dest_course_id
)
fields
=
_update_module_references
(
module
,
source_course_id
,
dest_course_id
)
asides
=
module
.
get_asides
()
if
isinstance
(
module
,
XModuleMixin
)
else
None
asides
=
module
.
get_asides
()
if
isinstance
(
module
,
XModuleMixin
)
else
None
return
store
.
import_xblock
(
block
=
store
.
import_xblock
(
user_id
,
dest_course_id
,
module
.
location
.
category
,
user_id
,
dest_course_id
,
module
.
location
.
category
,
module
.
location
.
block_id
,
fields
,
runtime
,
asides
=
asides
module
.
location
.
block_id
,
fields
,
runtime
,
asides
=
asides
)
)
# TODO: Move this code once the following condition is met.
# Get to the point where XML import is happening inside the
# modulestore that is eventually going to store the data.
# Ticket: https://openedx.atlassian.net/browse/PLAT-1046
if
block
.
location
.
category
==
'library_content'
:
# if library exists, update source_library_version and children
# according to this existing library and library content block.
if
store
.
get_library
(
block
.
source_library_key
):
LibraryToolsService
(
store
)
.
update_children
(
block
,
user_id
,
version
=
block
.
source_library_version
)
return
block
def
_import_course_draft
(
def
_import_course_draft
(
xml_module_store
,
xml_module_store
,
...
...
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