Commit 4d6f8ea7 by Adam

Merge pull request #12393 from edx/add-discussion-id-to-export

add discussion_id to course structure dump command (AN-6696)
parents 05f00a82 bfb319db
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
<html url_name='test_html'> <html url_name='test_html'>
Foobar Foobar
</html> </html>
<discussion url_name="custom_id" discussion_id="custom"></discussion>
</vertical> </vertical>
</sequential> </sequential>
</chapter> </chapter>
......
...@@ -22,6 +22,7 @@ from textwrap import dedent ...@@ -22,6 +22,7 @@ from textwrap import dedent
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from xmodule.discussion_module import DiscussionDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.inheritance import own_metadata, compute_inherited_metadata from xmodule.modulestore.inheritance import own_metadata, compute_inherited_metadata
from xblock.fields import Scope from xblock.fields import Scope
...@@ -95,6 +96,10 @@ def dump_module(module, destination=None, inherited=False, defaults=False): ...@@ -95,6 +96,10 @@ def dump_module(module, destination=None, inherited=False, defaults=False):
items = own_metadata(module) items = own_metadata(module)
# HACK: add discussion ids to list of items to export (AN-6696)
if isinstance(module, DiscussionDescriptor) and 'discussion_id' not in items:
items['discussion_id'] = module.discussion_id
filtered_metadata = {k: v for k, v in items.iteritems() if k not in FILTER_LIST} filtered_metadata = {k: v for k, v in items.iteritems() if k not in FILTER_LIST}
destination[unicode(module.location)] = { destination[unicode(module.location)] = {
......
...@@ -16,19 +16,19 @@ from django.core.management import call_command ...@@ -16,19 +16,19 @@ from django.core.management import call_command
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import ( from xmodule.modulestore.tests.django_utils import (
TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE
) )
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.xml_importer import import_course_from_xml from xmodule.modulestore.xml_importer import import_course_from_xml
DATA_DIR = settings.COMMON_TEST_DATA_ROOT DATA_DIR = settings.COMMON_TEST_DATA_ROOT
XML_COURSE_DIRS = ['toy', 'simple'] XML_COURSE_DIRS = ['simple']
@attr('shard_1') @attr('shard_1')
class CommandsTestBase(ModuleStoreTestCase): class CommandsTestBase(SharedModuleStoreTestCase):
""" """
Base class for testing different django commands. Base class for testing different django commands.
...@@ -39,28 +39,34 @@ class CommandsTestBase(ModuleStoreTestCase): ...@@ -39,28 +39,34 @@ class CommandsTestBase(ModuleStoreTestCase):
__test__ = False __test__ = False
url_name = '2012_Fall' url_name = '2012_Fall'
def setUp(self): @classmethod
super(CommandsTestBase, self).setUp() def setUpClass(cls):
self.test_course_key = modulestore().make_course_key("edX", "simple", "2012_Fall") super(CommandsTestBase, cls).setUpClass()
self.loaded_courses = self.load_courses() cls.test_course_key = modulestore().make_course_key("edX", "simple", "2012_Fall")
cls.loaded_courses = cls.load_courses()
def load_courses(self): @classmethod
def load_courses(cls):
"""Load test courses and return list of ids""" """Load test courses and return list of ids"""
store = modulestore() store = modulestore()
# Add a course with a unicode name. unique_org = factory.Sequence(lambda n: 'edX.%d' % n)
unique_org = factory.Sequence(lambda n: u'ëḋẌ.%d' % n) cls.course = CourseFactory.create(
CourseFactory.create(
emit_signals=True, emit_signals=True,
org=unique_org, org=unique_org,
course=u'śíḿṕĺé', course='simple',
run="run",
display_name=u'2012_Fáĺĺ', display_name=u'2012_Fáĺĺ',
modulestore=store modulestore=store
) )
cls.discussion = ItemFactory.create(
category='discussion', parent_location=cls.course.location
)
courses = store.get_courses() courses = store.get_courses()
# NOTE: if xml store owns these, it won't import them into mongo # NOTE: if xml store owns these, it won't import them into mongo
if self.test_course_key not in [c.id for c in courses]: if cls.test_course_key not in [c.id for c in courses]:
import_course_from_xml( import_course_from_xml(
store, ModuleStoreEnum.UserID.mgmt_command, DATA_DIR, XML_COURSE_DIRS, create_if_not_present=True store, ModuleStoreEnum.UserID.mgmt_command, DATA_DIR, XML_COURSE_DIRS, create_if_not_present=True
) )
...@@ -82,7 +88,7 @@ class CommandsTestBase(ModuleStoreTestCase): ...@@ -82,7 +88,7 @@ class CommandsTestBase(ModuleStoreTestCase):
self.assertEqual(course_ids, dumped_ids) self.assertEqual(course_ids, dumped_ids)
def test_correct_course_structure_metadata(self): def test_correct_course_structure_metadata(self):
course_id = unicode(modulestore().make_course_key('edX', 'simple', '2012_Fall')) course_id = unicode(self.test_course_key)
args = [course_id] args = [course_id]
kwargs = {'modulestore': 'default'} kwargs = {'modulestore': 'default'}
...@@ -129,7 +135,7 @@ class CommandsTestBase(ModuleStoreTestCase): ...@@ -129,7 +135,7 @@ class CommandsTestBase(ModuleStoreTestCase):
# Check if there are the right number of elements # Check if there are the right number of elements
self.assertEqual(len(dump), 16) self.assertEqual(len(dump), 17)
def test_dump_inherited_course_structure(self): def test_dump_inherited_course_structure(self):
args = [unicode(self.test_course_key)] args = [unicode(self.test_course_key)]
...@@ -161,6 +167,19 @@ class CommandsTestBase(ModuleStoreTestCase): ...@@ -161,6 +167,19 @@ class CommandsTestBase(ModuleStoreTestCase):
# ... and contains inherited metadata containing a default value: # ... and contains inherited metadata containing a default value:
self.assertIsNone(element['inherited_metadata']['due']) self.assertIsNone(element['inherited_metadata']['due'])
def test_export_discussion_ids(self):
output = self.call_command('dump_course_structure', unicode(self.course.id))
dump = json.loads(output)
dumped_id = dump[unicode(self.discussion.location)]['metadata']['discussion_id']
self.assertEqual(dumped_id, self.discussion.discussion_id)
def test_export_discussion_id_custom_id(self):
output = self.call_command('dump_course_structure', unicode(self.test_course_key))
dump = json.loads(output)
discussion_key = unicode(self.test_course_key.make_usage_key('discussion', 'custom_id'))
dumped_id = dump[unicode(discussion_key)]['metadata']['discussion_id']
self.assertEqual(dumped_id, "custom")
def test_export_course(self): def test_export_course(self):
tmp_dir = path(mkdtemp()) tmp_dir = path(mkdtemp())
self.addCleanup(shutil.rmtree, tmp_dir) self.addCleanup(shutil.rmtree, tmp_dir)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment