fix: handle invalid source library version on course import

Importing a course with an invalid source library version (e.g. created on
another instance) should not make the import fail.
This commit is contained in:
Agrendalath
2021-07-16 17:37:16 +02:00
committed by Braden MacDonald
parent 8be9fb6b51
commit 4b8421dfd8
2 changed files with 28 additions and 15 deletions

View File

@@ -2,6 +2,7 @@
Unit tests for course import and export Unit tests for course import and export
""" """
import copy import copy
import itertools
import json import json
import logging import logging
import os import os
@@ -15,6 +16,7 @@ from uuid import uuid4
import ddt import ddt
import lxml import lxml
from bson import ObjectId
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
@@ -1076,7 +1078,7 @@ class TestCourseExportImport(LibraryTestCase):
self.source_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split) self.source_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
self.addCleanup(shutil.rmtree, self.export_dir, ignore_errors=True) self.addCleanup(shutil.rmtree, self.export_dir, ignore_errors=True)
def _setup_source_course_with_library_content(self, publish=False): def _setup_source_course_with_library_content(self, publish=False, version=None):
""" """
Sets up course with library content. Sets up course with library content.
""" """
@@ -1095,7 +1097,9 @@ class TestCourseExportImport(LibraryTestCase):
parent_location=sequential.location, parent_location=sequential.location,
display_name='Test Unit' display_name='Test Unit'
) )
lc_block = self._add_library_content_block(vertical, self.lib_key, publish_item=publish) lc_block = self._add_library_content_block(
vertical, self.lib_key, publish_item=publish, other_settings=dict(source_library_version=version)
)
self._refresh_children(lc_block) self._refresh_children(lc_block)
def get_lib_content_block_children(self, block_location): def get_lib_content_block_children(self, block_location):
@@ -1134,13 +1138,18 @@ class TestCourseExportImport(LibraryTestCase):
dest_child = self.store.get_item(dest_child_location) dest_child = self.store.get_item(dest_child_location)
self.assertEqual(source_child.display_name, dest_child.display_name) self.assertEqual(source_child.display_name, dest_child.display_name)
@ddt.data(True, False) @ddt.data(*itertools.product([False, True], repeat=2))
def test_library_content_on_course_export_import(self, publish_item): @ddt.unpack
def test_library_content_on_course_export_import(self, publish_item, generate_version):
""" """
Verify that library contents in destination and source courses are same after importing Verify that library contents in destination and source courses are same after importing
the source course into destination course. the source course into destination course.
If a library with the specified version does not exist in the modulestore, the import should not fail.
""" """
self._setup_source_course_with_library_content(publish=publish_item) self._setup_source_course_with_library_content(
publish=publish_item, version=str(ObjectId()) if generate_version else None
)
# Create a course to import source course. # Create a course to import source course.
dest_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split) dest_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)

View File

@@ -897,16 +897,20 @@ def _update_and_import_module(
if lib_content_block_already_published: if lib_content_block_already_published:
return block return block
# Update library content block's children on draft branch try:
with store.branch_setting(branch_setting=ModuleStoreEnum.Branch.draft_preferred): # Update library content block's children on draft branch
LibraryToolsService(store, user_id).update_children( with store.branch_setting(branch_setting=ModuleStoreEnum.Branch.draft_preferred):
block, LibraryToolsService(store, user_id).update_children(
version=block.source_library_version, block,
) version=block.source_library_version,
)
# Publish it if importing the course for branch setting published_only. except ValueError as err:
if store.get_branch_setting() == ModuleStoreEnum.Branch.published_only: # The specified library version does not exist.
store.publish(block.location, user_id) log.error(err)
else:
# Publish it if importing the course for branch setting published_only.
if store.get_branch_setting() == ModuleStoreEnum.Branch.published_only:
store.publish(block.location, user_id)
return block return block