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
0425fc0e
Commit
0425fc0e
authored
Oct 28, 2014
by
Don Mitchell
Committed by
Zia Fazal
Apr 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests for clone_course
PLAT-142
parent
6f3bddc3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
115 additions
and
30 deletions
+115
-30
common/lib/xmodule/xmodule/modulestore/mixed.py
+4
-0
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+93
-15
common/lib/xmodule/xmodule/tests/__init__.py
+18
-15
No files found.
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
0425fc0e
...
...
@@ -590,6 +590,10 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
)
# the super handles assets and any other necessities
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
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 @
0425fc0e
...
...
@@ -6,7 +6,6 @@ import datetime
import
ddt
import
itertools
import
pymongo
import
unittest
from
collections
import
namedtuple
from
importlib
import
import_module
...
...
@@ -19,6 +18,10 @@ from uuid import uuid4
from
django.conf
import
settings
from
xmodule.modulestore.edit_info
import
EditInfoMixin
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
:
settings
.
configure
()
...
...
@@ -70,12 +73,12 @@ class TestMixedModuleStore(CourseComparisonTest):
'collection'
:
COLLECTION
,
'asset_collection'
:
ASSET_COLLECTION
,
}
MAPPINGS
=
{
XML_COURSEID1
:
'xml'
,
XML_COURSEID2
:
'xml'
,
BAD_COURSE_ID
:
'xml'
,
}
OPTIONS
=
{
'mappings'
:
{
XML_COURSEID1
:
'xml'
,
XML_COURSEID2
:
'xml'
,
BAD_COURSE_ID
:
'xml'
,
},
'stores'
:
[
{
'NAME'
:
'draft'
,
...
...
@@ -95,6 +98,7 @@ class TestMixedModuleStore(CourseComparisonTest):
'OPTIONS'
:
{
'data_dir'
:
DATA_DIR
,
'default_class'
:
'xmodule.hidden_module.HiddenDescriptor'
,
'xblock_mixins'
:
(
EditInfoMixin
,
InheritanceMixin
),
}
},
]
...
...
@@ -111,6 +115,16 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
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
.
connection
=
pymongo
.
MongoClient
(
host
=
self
.
HOST
,
...
...
@@ -120,13 +134,12 @@ class TestMixedModuleStore(CourseComparisonTest):
self
.
connection
.
drop_database
(
self
.
DB
)
self
.
addCleanup
(
self
.
connection
.
drop_database
,
self
.
DB
)
self
.
addCleanup
(
self
.
connection
.
close
)
super
(
TestMixedModuleStore
,
self
)
.
setUp
()
self
.
addTypeEqualityFunc
(
BlockUsageLocator
,
'_compare_ignore_version'
)
self
.
addTypeEqualityFunc
(
CourseLocator
,
'_compare_ignore_version'
)
# 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
.
course_locations
=
[]
self
.
course_locations
=
{}
self
.
user_id
=
ModuleStoreEnum
.
UserID
.
test
...
...
@@ -217,11 +230,16 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
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
)
def
initdb
(
self
,
default
):
...
...
@@ -300,7 +318,7 @@ class TestMixedModuleStore(CourseComparisonTest):
"""
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
):
self
.
store
.
create_course
(
'org_x'
,
'course_y'
,
'run_z'
,
self
.
user_id
)
if
reset_mixed_mappings
:
...
...
@@ -1757,7 +1775,7 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager
"""
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
with
self
.
store
.
default_store
(
default_ms
):
self
.
verify_default_store
(
default_ms
)
...
...
@@ -1767,7 +1785,7 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager, nested within one another
"""
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
with
self
.
store
.
default_store
(
ModuleStoreEnum
.
Type
.
mongo
):
self
.
verify_default_store
(
ModuleStoreEnum
.
Type
.
mongo
)
...
...
@@ -1783,13 +1801,73 @@ class TestMixedModuleStore(CourseComparisonTest):
Test the default store context manager, asking for a fake store
"""
# initialize the mixed modulestore
self
.
_initialize_mixed
()
self
.
_initialize_mixed
(
mappings
=
{}
)
fake_store
=
"fake"
with
self
.
assertRaisesRegexp
(
Exception
,
"Cannot find store of type {}"
.
format
(
fake_store
)):
with
self
.
store
.
default_store
(
fake_store
):
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
# ============================================================================================================
...
...
common/lib/xmodule/xmodule/tests/__init__.py
View file @
0425fc0e
...
...
@@ -28,7 +28,7 @@ from xmodule.mako_module import MakoDescriptorSystem
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.modulestore
import
ModuleStoreEnum
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
()
...
...
@@ -249,6 +249,7 @@ class LazyFormat(object):
def
__repr__
(
self
):
return
unicode
(
self
)
class
CourseComparisonTest
(
BulkAssertionTest
):
"""
Mixin that has methods for comparing courses for equality.
...
...
@@ -354,20 +355,22 @@ class CourseComparisonTest(BulkAssertionTest):
self
.
assertGreater
(
len
(
expected_items
),
0
)
self
.
_assertCoursesEqual
(
expected_items
,
actual_items
,
actual_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
):
# compare draft
if
expected_store
.
get_modulestore_type
(
None
)
==
ModuleStoreEnum
.
Type
.
split
:
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
else
:
revision
=
None
expected_items
=
expected_store
.
get_items
(
expected_course_key
,
revision
=
revision
)
if
actual_store
.
get_modulestore_type
(
None
)
==
ModuleStoreEnum
.
Type
.
split
:
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
else
:
revision
=
None
actual_items
=
actual_store
.
get_items
(
actual_course_key
,
revision
=
revision
)
self
.
_assertCoursesEqual
(
expected_items
,
actual_items
,
actual_course_key
,
expect_drafts
=
True
)
# 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
actual_store
.
branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
,
actual_course_key
):
# compare draft
if
expected_store
.
get_modulestore_type
(
None
)
==
ModuleStoreEnum
.
Type
.
split
:
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
else
:
revision
=
None
expected_items
=
expected_store
.
get_items
(
expected_course_key
,
revision
=
revision
)
if
actual_store
.
get_modulestore_type
(
None
)
==
ModuleStoreEnum
.
Type
.
split
:
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
else
:
revision
=
None
actual_items
=
actual_store
.
get_items
(
actual_course_key
,
revision
=
revision
)
self
.
_assertCoursesEqual
(
expected_items
,
actual_items
,
actual_course_key
,
expect_drafts
=
True
)
def
_assertCoursesEqual
(
self
,
expected_items
,
actual_items
,
actual_course_key
,
expect_drafts
=
False
):
with
self
.
bulk_assertions
():
...
...
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