diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_import.py b/cms/djangoapps/contentstore/management/commands/tests/test_import.py index f613c27875..7a56893607 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_import.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_import.py @@ -11,6 +11,7 @@ from django.core.management import call_command from django_comment_common.utils import are_permissions_roles_seeded from xmodule.modulestore.django import modulestore +from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -27,7 +28,7 @@ class TestImport(ModuleStoreTestCase): 'course="{0.course}"/>'.format(course_id)) with open(os.path.join(directory, "course", "{0.run}.xml".format(course_id)), "w+") as f: - f.write('') + f.write('') return directory @@ -72,3 +73,23 @@ class TestImport(ModuleStoreTestCase): # Now load up the course with a similar course_id and verify it loads call_command('import', self.content_dir, self.course_dir) self.assertIsNotNone(store.get_course(self.truncated_key)) + + def test_existing_course_with_different_modulestore(self): + """ + Checks that a course that originally existed in old mongo can be re-imported when + split is the default modulestore. + """ + with modulestore().default_store(ModuleStoreEnum.Type.mongo): + call_command('import', self.content_dir, self.good_dir) + + # Clear out the modulestore mappings, else when the next import command goes to create a destination + # course_key, it will find the existing course and return the mongo course_key. To reproduce TNL-1362, + # the destination course_key needs to be the one for split modulestore. + modulestore().mappings = {} + + with modulestore().default_store(ModuleStoreEnum.Type.split): + call_command('import', self.content_dir, self.good_dir) + course = modulestore().get_course(self.base_course_key) + # With the bug, this fails because the chapter's course_key is the split mongo form, + # while the course's course_key is the old mongo form. + self.assertEqual(unicode(course.location.course_key), unicode(course.children[0].course_key)) diff --git a/common/lib/xmodule/xmodule/modulestore/xml_importer.py b/common/lib/xmodule/xmodule/modulestore/xml_importer.py index e697c61011..1054520a7e 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/xml_importer.py @@ -195,11 +195,18 @@ def import_from_xml( if target_course_id is not None: dest_course_id = target_course_id else: + # Note that dest_course_id will be in the format for the default modulestore. dest_course_id = store.make_course_key(course_key.org, course_key.course, course_key.run) + existing_course_id = store.has_course(dest_course_id, ignore_case=True) + # store.has_course will return the course_key in the format for the modulestore in which it was found. + # This may be different from dest_course_id, so correct to the format found. + if existing_course_id: + dest_course_id = existing_course_id + runtime = None # Creates a new course if it doesn't already exist - if create_course_if_not_present and not store.has_course(dest_course_id, ignore_case=True): + if create_course_if_not_present and not existing_course_id: try: new_course = store.create_course(dest_course_id.org, dest_course_id.course, dest_course_id.run, user_id) runtime = new_course.runtime