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
ef0111d0
Commit
ef0111d0
authored
Oct 28, 2014
by
Don Mitchell
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5759 from edx/dhm/plat-142
Add tests for clone_course
parents
18ae9586
6989999d
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
14 deletions
+99
-14
common/lib/xmodule/xmodule/modulestore/mixed.py
+4
-0
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+91
-13
common/lib/xmodule/xmodule/tests/__init__.py
+4
-1
No files found.
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
ef0111d0
...
@@ -590,6 +590,10 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
...
@@ -590,6 +590,10 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
)
)
# the super handles assets and any other necessities
# the super handles assets and any other necessities
super
(
MixedModuleStore
,
self
)
.
clone_course
(
source_course_id
,
dest_course_id
,
user_id
,
fields
,
**
kwargs
)
super
(
MixedModuleStore
,
self
)
.
clone_course
(
source_course_id
,
dest_course_id
,
user_id
,
fields
,
**
kwargs
)
else
:
raise
NotImplementedError
(
"No code for cloning from {} to {}"
.
format
(
source_modulestore
,
dest_modulestore
))
@strip_key
@strip_key
def
create_item
(
self
,
user_id
,
course_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
def
create_item
(
self
,
user_id
,
course_key
,
block_type
,
block_id
=
None
,
fields
=
None
,
**
kwargs
):
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
ef0111d0
...
@@ -6,7 +6,6 @@ import datetime
...
@@ -6,7 +6,6 @@ import datetime
import
ddt
import
ddt
import
itertools
import
itertools
import
pymongo
import
pymongo
import
unittest
from
collections
import
namedtuple
from
collections
import
namedtuple
from
importlib
import
import_module
from
importlib
import
import_module
...
@@ -19,6 +18,10 @@ from uuid import uuid4
...
@@ -19,6 +18,10 @@ from uuid import uuid4
from
django.conf
import
settings
from
django.conf
import
settings
from
xmodule.modulestore.edit_info
import
EditInfoMixin
from
xmodule.modulestore.edit_info
import
EditInfoMixin
from
xmodule.modulestore.inheritance
import
InheritanceMixin
from
xmodule.modulestore.inheritance
import
InheritanceMixin
from
xmodule.modulestore.tests.test_cross_modulestore_import_export
import
MongoContentstoreBuilder
from
xmodule.contentstore.content
import
StaticContent
import
mimetypes
from
opaque_keys.edx.keys
import
CourseKey
if
not
settings
.
configured
:
if
not
settings
.
configured
:
settings
.
configure
()
settings
.
configure
()
...
@@ -70,12 +73,12 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -70,12 +73,12 @@ class TestMixedModuleStore(CourseComparisonTest):
'collection'
:
COLLECTION
,
'collection'
:
COLLECTION
,
'asset_collection'
:
ASSET_COLLECTION
,
'asset_collection'
:
ASSET_COLLECTION
,
}
}
OPTIONS
=
{
MAPPINGS
=
{
'mappings'
:
{
XML_COURSEID1
:
'xml'
,
XML_COURSEID1
:
'xml'
,
XML_COURSEID2
:
'xml'
,
XML_COURSEID2
:
'xml'
,
BAD_COURSE_ID
:
'xml'
,
BAD_COURSE_ID
:
'xml'
,
},
}
OPTIONS
=
{
'stores'
:
[
'stores'
:
[
{
{
'NAME'
:
'draft'
,
'NAME'
:
'draft'
,
...
@@ -95,6 +98,7 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -95,6 +98,7 @@ class TestMixedModuleStore(CourseComparisonTest):
'OPTIONS'
:
{
'OPTIONS'
:
{
'data_dir'
:
DATA_DIR
,
'data_dir'
:
DATA_DIR
,
'default_class'
:
'xmodule.hidden_module.HiddenDescriptor'
,
'default_class'
:
'xmodule.hidden_module.HiddenDescriptor'
,
'xblock_mixins'
:
(
EditInfoMixin
,
InheritanceMixin
),
}
}
},
},
]
]
...
@@ -111,6 +115,16 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -111,6 +115,16 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
"""
Set up the database for testing
Set up the database for testing
"""
"""
super
(
TestMixedModuleStore
,
self
)
.
setUp
()
self
.
exclude_field
(
None
,
'wiki_slug'
)
self
.
exclude_field
(
None
,
'xml_attributes'
)
self
.
exclude_field
(
None
,
'parent'
)
self
.
ignore_asset_key
(
'_id'
)
self
.
ignore_asset_key
(
'uploadDate'
)
self
.
ignore_asset_key
(
'content_son'
)
self
.
ignore_asset_key
(
'thumbnail_location'
)
self
.
options
=
getattr
(
self
,
'options'
,
self
.
OPTIONS
)
self
.
options
=
getattr
(
self
,
'options'
,
self
.
OPTIONS
)
self
.
connection
=
pymongo
.
MongoClient
(
self
.
connection
=
pymongo
.
MongoClient
(
host
=
self
.
HOST
,
host
=
self
.
HOST
,
...
@@ -120,13 +134,12 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -120,13 +134,12 @@ class TestMixedModuleStore(CourseComparisonTest):
self
.
connection
.
drop_database
(
self
.
DB
)
self
.
connection
.
drop_database
(
self
.
DB
)
self
.
addCleanup
(
self
.
connection
.
drop_database
,
self
.
DB
)
self
.
addCleanup
(
self
.
connection
.
drop_database
,
self
.
DB
)
self
.
addCleanup
(
self
.
connection
.
close
)
self
.
addCleanup
(
self
.
connection
.
close
)
super
(
TestMixedModuleStore
,
self
)
.
setUp
()
self
.
addTypeEqualityFunc
(
BlockUsageLocator
,
'_compare_ignore_version'
)
self
.
addTypeEqualityFunc
(
BlockUsageLocator
,
'_compare_ignore_version'
)
self
.
addTypeEqualityFunc
(
CourseLocator
,
'_compare_ignore_version'
)
self
.
addTypeEqualityFunc
(
CourseLocator
,
'_compare_ignore_version'
)
# define attrs which get set in initdb to quell pylint
# define attrs which get set in initdb to quell pylint
self
.
writable_chapter_location
=
self
.
store
=
self
.
fake_location
=
self
.
xml_chapter_location
=
None
self
.
writable_chapter_location
=
self
.
store
=
self
.
fake_location
=
self
.
xml_chapter_location
=
None
self
.
course_locations
=
[]
self
.
course_locations
=
{}
self
.
user_id
=
ModuleStoreEnum
.
UserID
.
test
self
.
user_id
=
ModuleStoreEnum
.
UserID
.
test
...
@@ -217,11 +230,16 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -217,11 +230,16 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
"""
return
self
.
course_locations
[
string
]
.
course_key
return
self
.
course_locations
[
string
]
.
course_key
def
_initialize_mixed
(
self
):
# pylint: disable=dangerous-default-value
def
_initialize_mixed
(
self
,
mappings
=
MAPPINGS
,
contentstore
=
None
):
"""
"""
initializes the mixed modulestore
initializes the mixed modulestore
.
"""
"""
self
.
store
=
MixedModuleStore
(
None
,
create_modulestore_instance
=
create_modulestore_instance
,
**
self
.
options
)
self
.
store
=
MixedModuleStore
(
contentstore
,
create_modulestore_instance
=
create_modulestore_instance
,
mappings
=
mappings
,
**
self
.
options
)
self
.
addCleanup
(
self
.
store
.
close_all_connections
)
self
.
addCleanup
(
self
.
store
.
close_all_connections
)
def
initdb
(
self
,
default
):
def
initdb
(
self
,
default
):
...
@@ -300,7 +318,7 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -300,7 +318,7 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
"""
Make sure we get back the store type we expect for given mappings
Make sure we get back the store type we expect for given mappings
"""
"""
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
with
self
.
store
.
default_store
(
default_ms
):
with
self
.
store
.
default_store
(
default_ms
):
self
.
store
.
create_course
(
'org_x'
,
'course_y'
,
'run_z'
,
self
.
user_id
)
self
.
store
.
create_course
(
'org_x'
,
'course_y'
,
'run_z'
,
self
.
user_id
)
if
reset_mixed_mappings
:
if
reset_mixed_mappings
:
...
@@ -1759,7 +1777,7 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -1759,7 +1777,7 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager
Test the default store context manager
"""
"""
# initialize the mixed modulestore
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
with
self
.
store
.
default_store
(
default_ms
):
with
self
.
store
.
default_store
(
default_ms
):
self
.
verify_default_store
(
default_ms
)
self
.
verify_default_store
(
default_ms
)
...
@@ -1769,7 +1787,7 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -1769,7 +1787,7 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager, nested within one another
Test the default store context manager, nested within one another
"""
"""
# initialize the mixed modulestore
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
with
self
.
store
.
default_store
(
ModuleStoreEnum
.
Type
.
mongo
):
with
self
.
store
.
default_store
(
ModuleStoreEnum
.
Type
.
mongo
):
self
.
verify_default_store
(
ModuleStoreEnum
.
Type
.
mongo
)
self
.
verify_default_store
(
ModuleStoreEnum
.
Type
.
mongo
)
...
@@ -1785,13 +1803,73 @@ class TestMixedModuleStore(CourseComparisonTest):
...
@@ -1785,13 +1803,73 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager, asking for a fake store
Test the default store context manager, asking for a fake store
"""
"""
# initialize the mixed modulestore
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
fake_store
=
"fake"
fake_store
=
"fake"
with
self
.
assertRaisesRegexp
(
Exception
,
"Cannot find store of type {}"
.
format
(
fake_store
)):
with
self
.
assertRaisesRegexp
(
Exception
,
"Cannot find store of type {}"
.
format
(
fake_store
)):
with
self
.
store
.
default_store
(
fake_store
):
with
self
.
store
.
default_store
(
fake_store
):
pass
# pragma: no cover
pass
# pragma: no cover
def
save_asset
(
self
,
asset_key
):
"""
Load and save the given file. (taken from test_contentstore)
"""
with
open
(
"{}/static/{}"
.
format
(
DATA_DIR
,
asset_key
.
block_id
),
"rb"
)
as
f
:
content
=
StaticContent
(
asset_key
,
"Funky Pix"
,
mimetypes
.
guess_type
(
asset_key
.
block_id
)[
0
],
f
.
read
(),
)
self
.
store
.
contentstore
.
save
(
content
)
@ddt.data
(
[
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
mongo
],
[
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
],
[
ModuleStoreEnum
.
Type
.
split
,
ModuleStoreEnum
.
Type
.
split
]
)
@ddt.unpack
def
test_clone_course
(
self
,
source_modulestore
,
destination_modulestore
):
"""
Test clone course
"""
with
MongoContentstoreBuilder
()
.
build
()
as
contentstore
:
# initialize the mixed modulestore
self
.
_initialize_mixed
(
contentstore
=
contentstore
,
mappings
=
{})
with
self
.
store
.
default_store
(
source_modulestore
):
source_course_key
=
self
.
store
.
make_course_key
(
"org.source"
,
"course.source"
,
"run.source"
)
self
.
_create_course
(
source_course_key
)
self
.
save_asset
(
source_course_key
.
make_asset_key
(
'asset'
,
'picture1.jpg'
))
with
self
.
store
.
default_store
(
destination_modulestore
):
dest_course_id
=
self
.
store
.
make_course_key
(
"org.other"
,
"course.other"
,
"run.other"
)
self
.
store
.
clone_course
(
source_course_key
,
dest_course_id
,
self
.
user_id
)
# pylint: disable=protected-access
source_store
=
self
.
store
.
_get_modulestore_by_type
(
source_modulestore
)
dest_store
=
self
.
store
.
_get_modulestore_by_type
(
destination_modulestore
)
self
.
assertCoursesEqual
(
source_store
,
source_course_key
,
dest_store
,
dest_course_id
)
def
test_clone_xml_split
(
self
):
"""
Can clone xml courses to split; so, test it.
"""
with
MongoContentstoreBuilder
()
.
build
()
as
contentstore
:
# initialize the mixed modulestore
self
.
_initialize_mixed
(
contentstore
=
contentstore
,
mappings
=
{
self
.
XML_COURSEID2
:
'xml'
,
})
source_course_key
=
CourseKey
.
from_string
(
self
.
XML_COURSEID2
)
with
self
.
store
.
default_store
(
ModuleStoreEnum
.
Type
.
split
):
dest_course_id
=
CourseLocator
(
"org.other"
,
"course.other"
,
"run.other"
)
self
.
store
.
clone_course
(
source_course_key
,
dest_course_id
,
ModuleStoreEnum
.
UserID
.
test
)
# pylint: disable=protected-access
source_store
=
self
.
store
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
xml
)
dest_store
=
self
.
store
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
split
)
self
.
assertCoursesEqual
(
source_store
,
source_course_key
,
dest_store
,
dest_course_id
)
# ============================================================================================================
# ============================================================================================================
# General utils for not using django settings
# General utils for not using django settings
# ============================================================================================================
# ============================================================================================================
...
...
common/lib/xmodule/xmodule/tests/__init__.py
View file @
ef0111d0
...
@@ -28,7 +28,7 @@ from xmodule.mako_module import MakoDescriptorSystem
...
@@ -28,7 +28,7 @@ from xmodule.mako_module import MakoDescriptorSystem
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.draft_and_published
import
DIRECT_ONLY_CATEGORIES
from
xmodule.modulestore.draft_and_published
import
DIRECT_ONLY_CATEGORIES
,
ModuleStoreDraftAndPublished
MODULE_DIR
=
path
(
__file__
)
.
dirname
()
MODULE_DIR
=
path
(
__file__
)
.
dirname
()
...
@@ -249,6 +249,7 @@ class LazyFormat(object):
...
@@ -249,6 +249,7 @@ class LazyFormat(object):
def
__repr__
(
self
):
def
__repr__
(
self
):
return
unicode
(
self
)
return
unicode
(
self
)
class
CourseComparisonTest
(
BulkAssertionTest
):
class
CourseComparisonTest
(
BulkAssertionTest
):
"""
"""
Mixin that has methods for comparing courses for equality.
Mixin that has methods for comparing courses for equality.
...
@@ -354,6 +355,8 @@ class CourseComparisonTest(BulkAssertionTest):
...
@@ -354,6 +355,8 @@ class CourseComparisonTest(BulkAssertionTest):
self
.
assertGreater
(
len
(
expected_items
),
0
)
self
.
assertGreater
(
len
(
expected_items
),
0
)
self
.
_assertCoursesEqual
(
expected_items
,
actual_items
,
actual_course_key
)
self
.
_assertCoursesEqual
(
expected_items
,
actual_items
,
actual_course_key
)
# if the modulestore supports having a draft branch
if
isinstance
(
expected_store
,
ModuleStoreDraftAndPublished
):
with
expected_store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
,
expected_course_key
):
with
expected_store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
,
expected_course_key
):
with
actual_store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
,
actual_course_key
):
with
actual_store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
,
actual_course_key
):
# compare draft
# compare draft
...
...
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