def test_existing_destination_course_id(self): """Test when the destination course id already exists""" api.copy_course_videos('test-course', 'test-course2') original_videos = Video.objects.filter(courses__course_id='test-course') copied_videos = Video.objects.filter(courses__course_id='test-course2') self.assertEqual(len(original_videos), 2) self.assertLessEqual(set(original_videos), set(copied_videos)) self.assertEqual(len(copied_videos), 3)
def test_existing_destination_course_id(self): """Test when the destination course id already exists""" api.copy_course_videos("test-course", "test-course2") original_videos = Video.objects.filter(courses__course_id="test-course") copied_videos = Video.objects.filter(courses__course_id="test-course2") self.assertEqual(len(original_videos), 2) self.assertLessEqual(set(original_videos), set(copied_videos)) self.assertEqual(len(copied_videos), 3)
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None): """ Reruns a course in a new celery task. """ # import here, at top level this import prevents the celery workers from starting up correctly from edxval.api import copy_course_videos try: # deserialize the payload source_course_key = CourseKey.from_string(source_course_key_string) destination_course_key = CourseKey.from_string( destination_course_key_string) fields = deserialize_fields(fields) if fields else None # use the split modulestore as the store for the rerun course, # as the Mongo modulestore doesn't support multiple runs of the same course. store = modulestore() with store.default_store('split'): store.clone_course(source_course_key, destination_course_key, user_id, fields=fields) # set initial permissions for the user to access the course. initialize_permissions(destination_course_key, User.objects.get(id=user_id)) # update state: Succeeded CourseRerunState.objects.succeeded(course_key=destination_course_key) # call edxval to attach videos to the rerun copy_course_videos(source_course_key, destination_course_key) return "succeeded" except DuplicateCourseError as exc: # do NOT delete the original course, only update the status CourseRerunState.objects.failed(course_key=destination_course_key) logging.exception(u'Course Rerun Error') return "duplicate course" # catch all exceptions so we can update the state and properly cleanup the course. except Exception as exc: # pylint: disable=broad-except # update state: Failed CourseRerunState.objects.failed(course_key=destination_course_key) logging.exception(u'Course Rerun Error') try: # cleanup any remnants of the course modulestore().delete_course(destination_course_key, user_id) except ItemNotFoundError: # it's possible there was an error even before the course module was created pass return "exception: " + unicode(exc)
def test_same_course_ids(self): """ Tests when the destination course id name is the same as the source """ original_videos = Video.objects.filter(courses__course_id="test-course") api.copy_course_videos("test-course", "test-course") copied_videos = Video.objects.filter(courses__course_id="test-course") self.assertEqual(len(original_videos), 2) self.assertTrue(set(original_videos) == set(copied_videos))
def test_same_course_ids(self): """ Tests when the destination course id name is the same as the source """ original_videos = Video.objects.filter(courses__course_id='test-course') api.copy_course_videos('test-course', 'test-course') copied_videos = Video.objects.filter(courses__course_id='test-course') self.assertEqual(len(original_videos), 2) self.assertTrue(set(original_videos) == set(copied_videos))
def test_successful_copy(self): """Tests a successful copy course""" api.copy_course_videos("test-course", "course-copy1") original_videos = Video.objects.filter(courses__course_id="test-course") copied_videos = Video.objects.filter(courses__course_id="course-copy1") self.assertEqual(len(original_videos), 2) self.assertEqual( {original_video.edx_video_id for original_video in original_videos}, {constants.VIDEO_DICT_FISH["edx_video_id"], constants.VIDEO_DICT_STAR["edx_video_id"]}, ) self.assertTrue(set(original_videos) == set(copied_videos))
def test_successful_copy(self): """Tests a successful copy course""" api.copy_course_videos('test-course', 'course-copy1') original_videos = Video.objects.filter(courses__course_id='test-course') copied_videos = Video.objects.filter(courses__course_id='course-copy1') self.assertEqual(len(original_videos), 2) self.assertEqual( {original_video.edx_video_id for original_video in original_videos}, {constants.VIDEO_DICT_FISH["edx_video_id"], constants.VIDEO_DICT_STAR["edx_video_id"]} ) self.assertTrue(set(original_videos) == set(copied_videos))
def test_existing_video_in_destination_course_id(self): """ Test when the destination course id already has videos from source id """ course_id3 = "test-course3" # 1st video CourseVideo.objects.create(video=self.video1, course_id=course_id3) api.copy_course_videos("test-course", "test-course3") original_videos = Video.objects.filter(courses__course_id="test-course") copied_videos = Video.objects.filter(courses__course_id="test-course3") self.assertEqual(len(original_videos), 2) self.assertTrue(set(copied_videos) == set(original_videos))
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None): """ Reruns a course in a new celery task. """ # import here, at top level this import prevents the celery workers from starting up correctly from edxval.api import copy_course_videos try: # deserialize the payload source_course_key = CourseKey.from_string(source_course_key_string) destination_course_key = CourseKey.from_string(destination_course_key_string) fields = deserialize_fields(fields) if fields else None # use the split modulestore as the store for the rerun course, # as the Mongo modulestore doesn't support multiple runs of the same course. store = modulestore() with store.default_store('split'): store.clone_course(source_course_key, destination_course_key, user_id, fields=fields) # set initial permissions for the user to access the course. initialize_permissions(destination_course_key, User.objects.get(id=user_id)) # update state: Succeeded CourseRerunState.objects.succeeded(course_key=destination_course_key) # call edxval to attach videos to the rerun copy_course_videos(source_course_key, destination_course_key) return "succeeded" except DuplicateCourseError as exc: # do NOT delete the original course, only update the status CourseRerunState.objects.failed(course_key=destination_course_key) logging.exception(u'Course Rerun Error') return "duplicate course" # catch all exceptions so we can update the state and properly cleanup the course. except Exception as exc: # pylint: disable=broad-except # update state: Failed CourseRerunState.objects.failed(course_key=destination_course_key) logging.exception(u'Course Rerun Error') try: # cleanup any remnants of the course modulestore().delete_course(destination_course_key, user_id) except ItemNotFoundError: # it's possible there was an error even before the course module was created pass return "exception: " + unicode(exc)
def test_existing_video_in_destination_course_id(self): """ Test when the destination course id already has videos from source id """ course_id3 = 'test-course3' # 1st video CourseVideo.objects.create(video=self.video1, course_id=course_id3) api.copy_course_videos('test-course', 'test-course3') original_videos = Video.objects.filter(courses__course_id='test-course') copied_videos = Video.objects.filter(courses__course_id='test-course3') self.assertEqual(len(original_videos), 2) self.assertTrue(set(copied_videos) == set(original_videos))
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None): """ Reruns a course in a new celery task. """ # import here, at top level this import prevents the celery workers from starting up correctly from edxval.api import copy_course_videos source_course_key = CourseKey.from_string(source_course_key_string) destination_course_key = CourseKey.from_string( destination_course_key_string) try: # deserialize the payload fields = deserialize_fields(fields) if fields else None # use the split modulestore as the store for the rerun course, # as the Mongo modulestore doesn't support multiple runs of the same course. store = modulestore() with store.default_store('split'): store.clone_course(source_course_key, destination_course_key, user_id, fields=fields) # set initial permissions for the user to access the course. initialize_permissions(destination_course_key, User.objects.get(id=user_id)) # update state: Succeeded CourseRerunState.objects.succeeded(course_key=destination_course_key) # call edxval to attach videos to the rerun copy_course_videos(source_course_key, destination_course_key) # Copy OrganizationCourse organization_course = OrganizationCourse.objects.filter( course_id=source_course_key_string).first() if organization_course: clone_instance(organization_course, {'course_id': destination_course_key_string}) # Copy RestrictedCourse restricted_course = RestrictedCourse.objects.filter( course_key=source_course_key).first() if restricted_course: country_access_rules = CountryAccessRule.objects.filter( restricted_course=restricted_course) new_restricted_course = clone_instance( restricted_course, {'course_key': destination_course_key}) for country_access_rule in country_access_rules: clone_instance(country_access_rule, {'restricted_course': new_restricted_course}) org_data = get_organization_by_short_name(source_course_key.org) add_organization_course(org_data, destination_course_key) return "succeeded" except DuplicateCourseError: # do NOT delete the original course, only update the status CourseRerunState.objects.failed(course_key=destination_course_key) LOGGER.exception(u'Course Rerun Error') return "duplicate course" # catch all exceptions so we can update the state and properly cleanup the course. except Exception as exc: # pylint: disable=broad-except # update state: Failed CourseRerunState.objects.failed(course_key=destination_course_key) LOGGER.exception(u'Course Rerun Error') try: # cleanup any remnants of the course modulestore().delete_course(destination_course_key, user_id) except ItemNotFoundError: # it's possible there was an error even before the course module was created pass return u"exception: " + text_type(exc)
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None): """ Reruns a course in a new celery task. """ # import here, at top level this import prevents the celery workers from starting up correctly from edxval.api import copy_course_videos source_course_key = CourseKey.from_string(source_course_key_string) destination_course_key = CourseKey.from_string(destination_course_key_string) try: # deserialize the payload fields = deserialize_fields(fields) if fields else None # use the split modulestore as the store for the rerun course, # as the Mongo modulestore doesn't support multiple runs of the same course. store = modulestore() with store.default_store('split'): store.clone_course(source_course_key, destination_course_key, user_id, fields=fields) # set initial permissions for the user to access the course. initialize_permissions(destination_course_key, User.objects.get(id=user_id)) # update state: Succeeded CourseRerunState.objects.succeeded(course_key=destination_course_key) # call edxval to attach videos to the rerun copy_course_videos(source_course_key, destination_course_key) # Copy OrganizationCourse organization_course = OrganizationCourse.objects.filter(course_id=source_course_key_string).first() if organization_course: clone_instance(organization_course, {'course_id': destination_course_key_string}) # Copy RestrictedCourse restricted_course = RestrictedCourse.objects.filter(course_key=source_course_key).first() if restricted_course: country_access_rules = CountryAccessRule.objects.filter(restricted_course=restricted_course) new_restricted_course = clone_instance(restricted_course, {'course_key': destination_course_key}) for country_access_rule in country_access_rules: clone_instance(country_access_rule, {'restricted_course': new_restricted_course}) return "succeeded" except DuplicateCourseError: # do NOT delete the original course, only update the status CourseRerunState.objects.failed(course_key=destination_course_key) LOGGER.exception(u'Course Rerun Error') return "duplicate course" # catch all exceptions so we can update the state and properly cleanup the course. except Exception as exc: # pylint: disable=broad-except # update state: Failed CourseRerunState.objects.failed(course_key=destination_course_key) LOGGER.exception(u'Course Rerun Error') try: # cleanup any remnants of the course modulestore().delete_course(destination_course_key, user_id) except ItemNotFoundError: # it's possible there was an error even before the course module was created pass return u"exception: " + text_type(exc)
def clone_course(source_course_key_string, destination_course_key_string, user_id, fields=None): """ Reruns a course in a new celery task. """ # import here, at top level this import prevents the celery workers from starting up correctly from edxval.api import copy_course_videos from contentstore.utils import initialize_permissions from contentstore.courseware_index import SearchIndexingError from contentstore.views.course import reindex_course_and_check_access # deserialize the payload source_course_key = CourseKey.from_string(source_course_key_string) destination_course_key = CourseKey.from_string( destination_course_key_string) try: # use the split modulestore as the store for the rerun course, # as the Mongo modulestore doesn't support multiple runs of the same course. store = modulestore() with store.default_store('split'): store.clone_course(source_course_key, destination_course_key, user_id, fields=fields) # set initial permissions for the user to access the course. user = User.objects.get(id=user_id) initialize_permissions(destination_course_key, user) # add course intructor and staff roles to the new user CourseInstructorRole(destination_course_key).add_users(user) CourseStaffRole(destination_course_key).add_users(user) # call edxval to attach videos to the rerun copy_course_videos(source_course_key, destination_course_key) return "succeeded" except DuplicateCourseError as exc: # do NOT delete the original course, only update the status logging.exception(u'Course Clone Error') return "duplicate course" except SearchIndexingError as search_err: logging.exception(u'Course Clone index Error') return "index error" # catch all exceptions so we can update the state and properly cleanup the course. except Exception as exc: # pylint: disable=broad-except # update state: Failed logging.exception(u'Course Clone Error') try: # cleanup any remnants of the course modulestore().delete_course(destination_course_key, user_id) except ItemNotFoundError: # it's possible there was an error even before the course module was created pass return "exception: " + unicode(exc)