Commit 85f5c49b by Don Mitchell Committed by Ben McMorran

Unit tests for rerun

along w/ fixes to make them work
LMS-11011
parent 4bc672b9
......@@ -4,6 +4,11 @@ Unit tests for cloning a course between the same and different module stores.
from opaque_keys.edx.locator import CourseLocator
from xmodule.modulestore import ModuleStoreEnum
from contentstore.tests.utils import CourseTestCase
from contentstore.tasks import rerun_course
from contentstore.views.access import has_course_access
from course_action_state.models import CourseRerunState
from course_action_state.managers import CourseRerunUIStateManager
from mock import patch, Mock
class CloneCourseTest(CourseTestCase):
......@@ -39,3 +44,44 @@ class CloneCourseTest(CourseTestCase):
)
self.store.clone_course(split_course3_id, split_course4_id, self.user.id)
self.assertCoursesEqual(split_course3_id, split_course4_id)
def test_rerun_course(self):
"""
Unit tests for :meth: `contentstore.tasks.rerun_course`
"""
mongo_course1_id = self.import_and_populate_course()
# rerun from mongo into split
split_course3_id = CourseLocator(
org="edx3", course="split3", run="rerun_test"
)
# Mark the action as initiated
fields = {'display_name': 'rerun'}
CourseRerunState.objects.initiated(mongo_course1_id, split_course3_id, self.user, fields['display_name'])
result = rerun_course.delay(unicode(mongo_course1_id), unicode(split_course3_id), self.user.id, fields)
self.assertEqual(result.get(), "succeeded")
self.assertTrue(has_course_access(self.user, split_course3_id), "Didn't grant access")
rerun_state = CourseRerunState.objects.find_first(course_key=split_course3_id)
self.assertEqual(rerun_state.state, CourseRerunUIStateManager.State.SUCCEEDED)
# try creating rerunning again to same name and ensure it generates error
result = rerun_course.delay(unicode(mongo_course1_id), unicode(split_course3_id), self.user.id)
self.assertEqual(result.get(), "duplicate course")
# the below will raise an exception if the record doesn't exist
CourseRerunState.objects.find_first(
course_key=split_course3_id,
state=CourseRerunUIStateManager.State.FAILED
)
# try to hit the generic exception catch
with patch('xmodule.modulestore.split_mongo.mongo_connection.MongoConnection.insert_course_index', Mock(side_effect=Exception)):
split_course4_id = CourseLocator(org="edx3", course="split3", run="rerun_fail")
fields = {'display_name': 'total failure'}
CourseRerunState.objects.initiated(split_course3_id, split_course4_id, self.user, fields['display_name'])
result = rerun_course.delay(unicode(split_course3_id), unicode(split_course4_id), self.user.id, fields)
self.assertIn("exception: ", result.get())
self.assertIsNone(self.store.get_course(split_course4_id), "Didn't delete course after error")
CourseRerunState.objects.find_first(
course_key=split_course4_id,
state=CourseRerunUIStateManager.State.FAILED
)
......@@ -599,7 +599,7 @@ def _rerun_course(request, org, number, run, fields):
with store.default_store('split'):
destination_course_key = store.make_course_key(org, number, run)
# verify org course and run don't already exist
# verify org course and run don't already exist
if store.has_course(destination_course_key, ignore_case=True):
raise DuplicateCourseError(source_course_key, destination_course_key)
......
......@@ -393,15 +393,13 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
if source_modulestore == dest_modulestore:
return source_modulestore.clone_course(source_course_id, dest_course_id, user_id, fields, **kwargs)
# ensure super's only called once. The delegation above probably calls it; so, don't move
# the invocation above the delegation call
super(MixedModuleStore, self).clone_course(source_course_id, dest_course_id, user_id, fields, **kwargs)
if dest_modulestore.get_modulestore_type() == ModuleStoreEnum.Type.split:
split_migrator = SplitMigrator(dest_modulestore, source_modulestore)
split_migrator.migrate_mongo_course(
source_course_id, user_id, dest_course_id.org, dest_course_id.course, dest_course_id.run, fields, **kwargs
)
# the super handles assets and any other necessities
super(MixedModuleStore, self).clone_course(source_course_id, dest_course_id, user_id, fields, **kwargs)
@strip_key
def create_item(self, user_id, course_key, block_type, block_id=None, fields=None, **kwargs):
......
......@@ -952,11 +952,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
In split, other than copying the assets, this is cheap as it merely creates a new version of the
existing course.
"""
super(SplitMongoModuleStore, self).clone_course(source_course_id, dest_course_id, user_id, fields, **kwargs)
source_index = self.get_course_index_info(source_course_id)
if source_index is None:
raise ItemNotFoundError("Cannot find a course at {0}. Aborting".format(source_course_id))
return self.create_course(
new_course = self.create_course(
dest_course_id.org, dest_course_id.course, dest_course_id.run,
user_id,
fields=fields,
......@@ -965,6 +964,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
skip_auto_publish=True,
**kwargs
)
# don't copy assets until we create the course in case something's awry
super(SplitMongoModuleStore, self).clone_course(source_course_id, dest_course_id, user_id, fields, **kwargs)
return new_course
DEFAULT_ROOT_BLOCK_ID = 'course'
def create_course(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment