From bfb319db9a7f56ed4c256c8ea24e89d61d2773ab Mon Sep 17 00:00:00 2001 From: Adam Palay Date: Fri, 6 May 2016 15:53:55 -0400 Subject: [PATCH] add discussion_id to course structure dump command (AN-6696) add test case for discussion_id already set in XML --- common/test/data/simple/course.xml | 1 + .../commands/dump_course_structure.py | 5 ++ .../commands/tests/test_dump_course.py | 51 +++++++++++++------ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/common/test/data/simple/course.xml b/common/test/data/simple/course.xml index 5cd6d54d29..c1490c7092 100644 --- a/common/test/data/simple/course.xml +++ b/common/test/data/simple/course.xml @@ -24,6 +24,7 @@ Foobar + diff --git a/lms/djangoapps/courseware/management/commands/dump_course_structure.py b/lms/djangoapps/courseware/management/commands/dump_course_structure.py index fdca7f4e65..ea308bf4b9 100644 --- a/lms/djangoapps/courseware/management/commands/dump_course_structure.py +++ b/lms/djangoapps/courseware/management/commands/dump_course_structure.py @@ -22,6 +22,7 @@ from textwrap import dedent from django.core.management.base import BaseCommand, CommandError +from xmodule.discussion_module import DiscussionDescriptor from xmodule.modulestore.django import modulestore from xmodule.modulestore.inheritance import own_metadata, compute_inherited_metadata from xblock.fields import Scope @@ -95,6 +96,10 @@ def dump_module(module, destination=None, inherited=False, defaults=False): 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} destination[unicode(module.location)] = { diff --git a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py index bbff7ff15e..bf4dc2bc6b 100644 --- a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py +++ b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py @@ -16,19 +16,19 @@ from django.core.management import call_command from xmodule.modulestore import ModuleStoreEnum 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 ( 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 DATA_DIR = settings.COMMON_TEST_DATA_ROOT -XML_COURSE_DIRS = ['toy', 'simple'] +XML_COURSE_DIRS = ['simple'] @attr('shard_1') -class CommandsTestBase(ModuleStoreTestCase): +class CommandsTestBase(SharedModuleStoreTestCase): """ Base class for testing different django commands. @@ -39,28 +39,34 @@ class CommandsTestBase(ModuleStoreTestCase): __test__ = False url_name = '2012_Fall' - def setUp(self): - super(CommandsTestBase, self).setUp() - self.test_course_key = modulestore().make_course_key("edX", "simple", "2012_Fall") - self.loaded_courses = self.load_courses() + @classmethod + def setUpClass(cls): + super(CommandsTestBase, cls).setUpClass() + 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""" store = modulestore() - # Add a course with a unicode name. - unique_org = factory.Sequence(lambda n: u'ëḋẌ.%d' % n) - CourseFactory.create( + unique_org = factory.Sequence(lambda n: 'edX.%d' % n) + cls.course = CourseFactory.create( emit_signals=True, org=unique_org, - course=u'śíḿṕĺé', + course='simple', + run="run", display_name=u'2012_Fáĺĺ', modulestore=store ) + cls.discussion = ItemFactory.create( + category='discussion', parent_location=cls.course.location + ) + courses = store.get_courses() # 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( store, ModuleStoreEnum.UserID.mgmt_command, DATA_DIR, XML_COURSE_DIRS, create_if_not_present=True ) @@ -82,7 +88,7 @@ class CommandsTestBase(ModuleStoreTestCase): self.assertEqual(course_ids, dumped_ids) 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] kwargs = {'modulestore': 'default'} @@ -129,7 +135,7 @@ class CommandsTestBase(ModuleStoreTestCase): # 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): args = [unicode(self.test_course_key)] @@ -161,6 +167,19 @@ class CommandsTestBase(ModuleStoreTestCase): # ... and contains inherited metadata containing a default value: 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): tmp_dir = path(mkdtemp()) self.addCleanup(shutil.rmtree, tmp_dir)