diff --git a/cms/djangoapps/contentstore/tests/test_clone_course.py b/cms/djangoapps/contentstore/tests/test_clone_course.py index b95b01c800..a0c9428dd0 100644 --- a/cms/djangoapps/contentstore/tests/test_clone_course.py +++ b/cms/djangoapps/contentstore/tests/test_clone_course.py @@ -2,6 +2,8 @@ Unit tests for cloning a course between the same and different module stores. """ import json +from django.conf import settings + from opaque_keys.edx.locator import CourseLocator from xmodule.modulestore import ModuleStoreEnum, EdxJSONEncoder from contentstore.tests.utils import CourseTestCase @@ -10,6 +12,12 @@ from student.auth import has_course_author_access from course_action_state.models import CourseRerunState from course_action_state.managers import CourseRerunUIStateManager from mock import patch, Mock +from xmodule.contentstore.content import StaticContent +from xmodule.contentstore.django import contentstore +from xmodule.modulestore.tests.factories import CourseFactory + + +TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT class CloneCourseTest(CourseTestCase): @@ -46,6 +54,54 @@ 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_space_in_asset_name_for_rerun_course(self): + """ + Tests check the scenario where one course which has an asset with percentage(%) in its + name, it should re-run successfully. + """ + org = 'edX' + course_number = 'CS101' + course_run = '2015_Q1' + display_name = 'rerun' + fields = {'display_name': display_name} + course_assets = set([u'subs_Introduction%20To%20New.srt.sjson'], ) + + # Create a course using split modulestore + course = CourseFactory.create( + org=org, + number=course_number, + run=course_run, + display_name=display_name, + default_store=ModuleStoreEnum.Type.split + ) + + # add an asset + asset_key = course.id.make_asset_key('asset', 'subs_Introduction%20To%20New.srt.sjson') + content = StaticContent( + asset_key, 'Dummy assert', 'application/json', 'dummy data', + ) + contentstore().save(content) + + # Get & verify all assets of the course + assets, count = contentstore().get_all_content_for_course(course.id) + self.assertEqual(count, 1) + self.assertEqual(set([asset['asset_key'].block_id for asset in assets]), course_assets) + + # rerun from split into split + split_rerun_id = CourseLocator(org=org, course=course_number, run="2012_Q2") + CourseRerunState.objects.initiated(course.id, split_rerun_id, self.user, fields['display_name']) + result = rerun_course.delay( + unicode(course.id), + unicode(split_rerun_id), + self.user.id, + json.dumps(fields, cls=EdxJSONEncoder) + ) + + # Check if re-run was successful + self.assertEqual(result.get(), "succeeded") + rerun_state = CourseRerunState.objects.find_first(course_key=split_rerun_id) + self.assertEqual(rerun_state.state, CourseRerunUIStateManager.State.SUCCEEDED) + def test_rerun_course(self): """ Unit tests for :meth: `contentstore.tasks.rerun_course` diff --git a/cms/djangoapps/contentstore/tests/test_import.py b/cms/djangoapps/contentstore/tests/test_import.py index f69f450493..c35405e189 100644 --- a/cms/djangoapps/contentstore/tests/test_import.py +++ b/cms/djangoapps/contentstore/tests/test_import.py @@ -283,3 +283,23 @@ class ContentStoreImportTest(SignalDisconnectTestMixin, ModuleStoreTestCase): } self.assertEqual(remapped_verticals, split_test_module.group_id_to_child) + + @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) + def test_video_components_present_while_import(self, store): + """ + Test that video components with same edx_video_id are present while re-importing + """ + with modulestore().default_store(store): + module_store = modulestore() + course_id = module_store.make_course_key('edX', 'test_import_course', '2012_Fall') + + # Import first time + __, __, course = self.load_test_import_course(target_id=course_id, module_store=module_store) + + # Re-import + __, __, re_course = self.load_test_import_course(target_id=course.id, module_store=module_store) + + vertical = module_store.get_item(re_course.id.make_usage_key('vertical', 'vertical_test')) + + video = module_store.get_item(vertical.children[1]) + self.assertEqual(video.display_name, 'default') diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 1066a35ff8..cd92cbda2d 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -1259,7 +1259,7 @@ class MetricsMixin(object): ) -class DescriptorSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abstract-method +class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime): # pylint: disable=abstract-method """ Base class for :class:`Runtime`s to be used with :class:`XModuleDescriptor`s """ @@ -1505,7 +1505,7 @@ class XMLParsingSystem(DescriptorSystem): setattr(xblock, field.name, field_value) -class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abstract-method +class ModuleSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime): # pylint: disable=abstract-method """ This is an abstraction such that x_modules can function independent of the courseware (e.g. import into other types of courseware, LMS, diff --git a/common/test/data/test_import_course/video/separate_file_video.xml b/common/test/data/test_import_course/video/separate_file_video.xml index b90ea9d8c4..16f2506d23 100644 --- a/common/test/data/test_import_course/video/separate_file_video.xml +++ b/common/test/data/test_import_course/video/separate_file_video.xml @@ -1 +1,5 @@ -