- Add test content library XML.
- Ensure that only a course import is saved to the draft branch and then published. A content library has only a single 'library' branch. - Add a fields parameter to the create_library call so the call has the correct number of parameters. - Add tests which import content libraries using different test methods and with different branch settings. - Add test which imports a content library and then exports it. - Use XBlock module version that supports XML-serialized String of None. - Add re-import of content library and equality comparison to test. - Allow get_items to be called on LibraryLocators.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
Unit tests for course import and export
|
||||
"""
|
||||
import copy
|
||||
import ddt
|
||||
import json
|
||||
import logging
|
||||
import lxml
|
||||
@@ -15,20 +16,24 @@ from uuid import uuid4
|
||||
from django.test.utils import override_settings
|
||||
from django.conf import settings
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.xml_exporter import export_library_to_xml
|
||||
from xmodule.modulestore.xml_importer import import_library_from_xml
|
||||
from xmodule.modulestore import LIBRARY_ROOT
|
||||
from xmodule.modulestore import LIBRARY_ROOT, ModuleStoreEnum
|
||||
from contentstore.utils import reverse_course_url
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
|
||||
from xmodule.modulestore.tests.factories import ItemFactory, LibraryFactory
|
||||
from xmodule.modulestore.tests.utils import (
|
||||
MongoContentstoreBuilder, SPLIT_MODULESTORE_SETUP, TEST_DATA_DIR
|
||||
)
|
||||
from opaque_keys.edx.locator import LibraryLocator
|
||||
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
from openedx.core.lib.extract_tar import safetar_extractall
|
||||
from student import auth
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole
|
||||
from models.settings.course_metadata import CourseMetadata
|
||||
from util import milestones_helpers
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
|
||||
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
|
||||
@@ -123,6 +128,7 @@ class ImportEntranceExamTestCase(CourseTestCase, MilestonesTestCaseMixin):
|
||||
self.assertEquals(course.entrance_exam_minimum_score_pct, 0.7)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
|
||||
class ImportTestCase(CourseTestCase):
|
||||
"""
|
||||
@@ -435,6 +441,73 @@ class ImportTestCase(CourseTestCase):
|
||||
self.assertIn(test_block3.url_name, children)
|
||||
self.assertIn(test_block4.url_name, children)
|
||||
|
||||
@ddt.data(
|
||||
ModuleStoreEnum.Branch.draft_preferred,
|
||||
ModuleStoreEnum.Branch.published_only,
|
||||
)
|
||||
def test_library_import_branch_settings(self, branch_setting):
|
||||
"""
|
||||
Try importing a known good library archive under either branch setting.
|
||||
The branch setting should have no effect on library import.
|
||||
"""
|
||||
with self.store.branch_setting(branch_setting):
|
||||
library = LibraryFactory.create(modulestore=self.store)
|
||||
lib_key = library.location.library_key
|
||||
extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
|
||||
# the extract_dir needs to be passed as a relative dir to
|
||||
# import_library_from_xml
|
||||
extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)
|
||||
|
||||
try:
|
||||
with tarfile.open(path(TEST_DATA_DIR) / 'imports' / 'library.HhJfPD.tar.gz') as tar:
|
||||
safetar_extractall(tar, extract_dir)
|
||||
import_library_from_xml(
|
||||
self.store,
|
||||
self.user.id,
|
||||
settings.GITHUB_REPO_ROOT,
|
||||
[extract_dir_relative / 'library'],
|
||||
load_error_modules=False,
|
||||
static_content_store=contentstore(),
|
||||
target_id=lib_key
|
||||
)
|
||||
finally:
|
||||
shutil.rmtree(extract_dir)
|
||||
|
||||
@ddt.data(
|
||||
ModuleStoreEnum.Branch.draft_preferred,
|
||||
ModuleStoreEnum.Branch.published_only,
|
||||
)
|
||||
def test_library_import_branch_settings_again(self, branch_setting):
|
||||
# Construct the contentstore for storing the import
|
||||
with MongoContentstoreBuilder().build() as source_content:
|
||||
# Construct the modulestore for storing the import (using the previously created contentstore)
|
||||
with SPLIT_MODULESTORE_SETUP.build(contentstore=source_content) as source_store:
|
||||
# Use the test branch setting.
|
||||
with source_store.branch_setting(branch_setting):
|
||||
source_library_key = LibraryLocator(org='TestOrg', library='TestProbs')
|
||||
|
||||
extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
|
||||
# the extract_dir needs to be passed as a relative dir to
|
||||
# import_library_from_xml
|
||||
extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)
|
||||
|
||||
try:
|
||||
with tarfile.open(path(TEST_DATA_DIR) / 'imports' / 'library.HhJfPD.tar.gz') as tar:
|
||||
safetar_extractall(tar, extract_dir)
|
||||
import_library_from_xml(
|
||||
source_store,
|
||||
self.user.id,
|
||||
settings.GITHUB_REPO_ROOT,
|
||||
[extract_dir_relative / 'library'],
|
||||
static_content_store=source_content,
|
||||
target_id=source_library_key,
|
||||
load_error_modules=False,
|
||||
raise_on_failure=True,
|
||||
create_if_not_present=True,
|
||||
)
|
||||
finally:
|
||||
shutil.rmtree(extract_dir)
|
||||
|
||||
|
||||
@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
|
||||
class ExportTestCase(CourseTestCase):
|
||||
@@ -556,3 +629,59 @@ class ExportTestCase(CourseTestCase):
|
||||
)
|
||||
|
||||
self.test_export_targz_urlparam()
|
||||
|
||||
|
||||
@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
|
||||
class TestLibraryImportExport(CourseTestCase):
|
||||
"""
|
||||
Tests for importing content libraries from XML and exporting them to XML.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestLibraryImportExport, self).setUp()
|
||||
self.export_dir = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, self.export_dir, ignore_errors=True)
|
||||
|
||||
def test_content_library_export_import(self):
|
||||
library1 = LibraryFactory.create(modulestore=self.store)
|
||||
source_library1_key = library1.location.library_key
|
||||
library2 = LibraryFactory.create(modulestore=self.store)
|
||||
source_library2_key = library2.location.library_key
|
||||
|
||||
import_library_from_xml(
|
||||
self.store,
|
||||
'test_user',
|
||||
TEST_DATA_DIR,
|
||||
['library_empty_problem'],
|
||||
static_content_store=contentstore(),
|
||||
target_id=source_library1_key,
|
||||
load_error_modules=False,
|
||||
raise_on_failure=True,
|
||||
create_if_not_present=True,
|
||||
)
|
||||
|
||||
export_library_to_xml(
|
||||
self.store,
|
||||
contentstore(),
|
||||
source_library1_key,
|
||||
self.export_dir,
|
||||
'exported_source_library',
|
||||
)
|
||||
|
||||
source_library = self.store.get_library(source_library1_key)
|
||||
self.assertEqual(source_library.url_name, 'library')
|
||||
|
||||
# Import the exported library into a different content library.
|
||||
import_library_from_xml(
|
||||
self.store,
|
||||
'test_user',
|
||||
self.export_dir,
|
||||
['exported_source_library'],
|
||||
static_content_store=contentstore(),
|
||||
target_id=source_library2_key,
|
||||
load_error_modules=False,
|
||||
raise_on_failure=True,
|
||||
create_if_not_present=True,
|
||||
)
|
||||
|
||||
# Compare the two content libraries for equality.
|
||||
self.assertCoursesEqual(source_library1_key, source_library2_key)
|
||||
|
||||
Reference in New Issue
Block a user