147 lines
4.9 KiB
Python
147 lines
4.9 KiB
Python
"""Tests for Django management commands"""
|
|
|
|
import json
|
|
import shutil
|
|
from StringIO import StringIO
|
|
import tarfile
|
|
from tempfile import mkdtemp
|
|
|
|
from path import path
|
|
|
|
from django.core.management import call_command
|
|
from django.test.utils import override_settings
|
|
|
|
from courseware.tests.modulestore_config import TEST_DATA_XML_MODULESTORE
|
|
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
|
|
from courseware.tests.modulestore_config import TEST_DATA_MONGO_MODULESTORE
|
|
|
|
from xmodule.modulestore.django import modulestore
|
|
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
|
from xmodule.modulestore.xml_importer import import_from_xml
|
|
|
|
DATA_DIR = 'common/test/data/'
|
|
|
|
TEST_COURSE_ID = 'edX/simple/2012_Fall'
|
|
|
|
|
|
class CommandsTestBase(object):
|
|
"""
|
|
Base class for testing different django commands.
|
|
|
|
Must be subclassed using override_settings set to the modulestore
|
|
to be tested.
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.loaded_courses = self.load_courses()
|
|
|
|
def load_courses(self):
|
|
"""Load test courses and return list of ids"""
|
|
store = modulestore()
|
|
|
|
courses = store.get_courses()
|
|
if TEST_COURSE_ID not in [c.id for c in courses]:
|
|
import_from_xml(store, DATA_DIR, ['toy', 'simple'])
|
|
|
|
return [course.id for course in store.get_courses()]
|
|
|
|
def call_command(self, name, *args, **kwargs):
|
|
"""Call management command and return output"""
|
|
out = StringIO() # To Capture the output of the command
|
|
call_command(name, *args, stdout=out, **kwargs)
|
|
out.seek(0)
|
|
return out.read()
|
|
|
|
def test_dump_course_ids(self):
|
|
kwargs = {'modulestore': 'default'}
|
|
output = self.call_command('dump_course_ids', **kwargs)
|
|
dumped_courses = output.strip().split('\n')
|
|
self.assertEqual(self.loaded_courses, dumped_courses)
|
|
|
|
def test_dump_course_structure(self):
|
|
args = [TEST_COURSE_ID]
|
|
kwargs = {'modulestore': 'default'}
|
|
output = self.call_command('dump_course_structure', *args, **kwargs)
|
|
|
|
dump = json.loads(output)
|
|
|
|
# Check a few elements in the course dump
|
|
|
|
parent_id = 'i4x://edX/simple/chapter/Overview'
|
|
self.assertEqual(dump[parent_id]['category'], 'chapter')
|
|
self.assertEqual(len(dump[parent_id]['children']), 3)
|
|
|
|
child_id = dump[parent_id]['children'][1]
|
|
self.assertEqual(dump[child_id]['category'], 'videosequence')
|
|
self.assertEqual(len(dump[child_id]['children']), 2)
|
|
|
|
video_id = 'i4x://edX/simple/video/Welcome'
|
|
self.assertEqual(dump[video_id]['category'], 'video')
|
|
self.assertEqual(len(dump[video_id]['metadata']), 4)
|
|
self.assertIn('youtube_id_1_0', dump[video_id]['metadata'])
|
|
|
|
# Check if there is the right number of elements
|
|
|
|
self.assertEqual(len(dump), 16)
|
|
|
|
def test_export_course(self):
|
|
tmp_dir = path(mkdtemp())
|
|
filename = tmp_dir / 'test.tar.gz'
|
|
try:
|
|
self.run_export_course(filename)
|
|
with tarfile.open(filename) as tar_file:
|
|
self.check_export_file(tar_file)
|
|
|
|
finally:
|
|
shutil.rmtree(tmp_dir)
|
|
|
|
def test_export_course_stdout(self):
|
|
output = self.run_export_course('-')
|
|
with tarfile.open(fileobj=StringIO(output)) as tar_file:
|
|
self.check_export_file(tar_file)
|
|
|
|
def run_export_course(self, filename): # pylint: disable=missing-docstring
|
|
args = ['edX/simple/2012_Fall', filename]
|
|
kwargs = {'modulestore': 'default'}
|
|
return self.call_command('export_course', *args, **kwargs)
|
|
|
|
def check_export_file(self, tar_file): # pylint: disable=missing-docstring
|
|
names = tar_file.getnames()
|
|
|
|
# Check if some of the files are present.
|
|
|
|
# The rest is of the code should be covered by the tests for
|
|
# xmodule.modulestore.xml_exporter, used by the dump_course command
|
|
|
|
assert_in = self.assertIn
|
|
assert_in('edX-simple-2012_Fall', names)
|
|
assert_in('edX-simple-2012_Fall/policies/2012_Fall/policy.json', names)
|
|
assert_in('edX-simple-2012_Fall/html/toylab.html', names)
|
|
assert_in('edX-simple-2012_Fall/videosequence/A_simple_sequence.xml', names)
|
|
assert_in('edX-simple-2012_Fall/sequential/Lecture_2.xml', names)
|
|
|
|
|
|
@override_settings(MODULESTORE=TEST_DATA_XML_MODULESTORE)
|
|
class CommandsXMLTestCase(CommandsTestBase, ModuleStoreTestCase):
|
|
"""
|
|
Test case for management commands using the xml modulestore.
|
|
|
|
"""
|
|
|
|
|
|
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
|
class CommandsMongoTestCase(CommandsTestBase, ModuleStoreTestCase):
|
|
"""
|
|
Test case for management commands using the mongo modulestore.
|
|
|
|
"""
|
|
|
|
|
|
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
|
class CommandsMixedTestCase(CommandsTestBase, ModuleStoreTestCase):
|
|
"""
|
|
Test case for management commands. Using the mixed modulestore.
|
|
|
|
"""
|