Commit 25955a79 by Peter Fogg

Merge pull request #492 from edx/peter-fogg/fix-stud-146

Fix word cloud modules not exporting correctly.
parents 8d11c246 512269f8
...@@ -855,6 +855,68 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): ...@@ -855,6 +855,68 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
shutil.rmtree(root_dir) shutil.rmtree(root_dir)
def test_export_course_with_metadata_only_word_cloud(self):
"""
Similar to `test_export_course_with_metadata_only_video`.
"""
module_store = modulestore('direct')
draft_store = modulestore('draft')
content_store = contentstore()
import_from_xml(module_store, 'common/test/data/', ['word_cloud'])
location = CourseDescriptor.id_to_location('HarvardX/ER22x/2013_Spring')
verticals = module_store.get_items(['i4x', 'HarvardX', 'ER22x', 'vertical', None, None])
self.assertGreater(len(verticals), 0)
parent = verticals[0]
ItemFactory.create(parent_location=parent.location, category="word_cloud", display_name="untitled")
root_dir = path(mkdtemp_clean())
print 'Exporting to tempdir = {0}'.format(root_dir)
# export out to a tempdir
export_to_xml(module_store, content_store, location, root_dir, 'test_export', draft_modulestore=draft_store)
shutil.rmtree(root_dir)
def test_empty_data_roundtrip(self):
"""
Test that an empty `data` field is preserved through
export/import.
"""
module_store = modulestore('direct')
draft_store = modulestore('draft')
content_store = contentstore()
import_from_xml(module_store, 'common/test/data/', ['toy'])
location = CourseDescriptor.id_to_location('edX/toy/2012_Fall')
verticals = module_store.get_items(['i4x', 'edX', 'toy', 'vertical', None, None])
self.assertGreater(len(verticals), 0)
parent = verticals[0]
# Create a module, and ensure that its `data` field is empty
word_cloud = ItemFactory.create(parent_location=parent.location, category="word_cloud", display_name="untitled")
del word_cloud.data
self.assertEquals(word_cloud.data, '')
# Export the course
root_dir = path(mkdtemp_clean())
export_to_xml(module_store, content_store, location, root_dir, 'test_roundtrip', draft_modulestore=draft_store)
# Reimport and get the video back
import_from_xml(module_store, root_dir)
imported_word_cloud = module_store.get_item(Location(['i4x', 'edX', 'toy', 'word_cloud', 'untitled', None]))
# It should now contain empty data
self.assertEquals(imported_word_cloud.data, '')
def test_course_handouts_rewrites(self): def test_course_handouts_rewrites(self):
module_store = modulestore('direct') module_store = modulestore('direct')
......
...@@ -32,3 +32,22 @@ class RawDescriptor(XmlDescriptor, XMLEditingDescriptor): ...@@ -32,3 +32,22 @@ class RawDescriptor(XmlDescriptor, XMLEditingDescriptor):
context=lines[line - 1][offset - 40:offset + 40], context=lines[line - 1][offset - 40:offset + 40],
loc=self.location)) loc=self.location))
raise Exception, msg, sys.exc_info()[2] raise Exception, msg, sys.exc_info()[2]
class EmptyDataRawDescriptor(XmlDescriptor, XMLEditingDescriptor):
"""
Version of RawDescriptor for modules which may have no XML data,
but use XMLEditingDescriptor for import/export handling.
"""
data = String(default='', scope=Scope.content)
@classmethod
def definition_from_xml(cls, xml_object, system):
if len(xml_object) == 0 and len(xml_object.items()) == 0:
return {'data': ''}, []
return {'data': etree.tostring(xml_object, pretty_print=True, encoding='unicode')}, []
def definition_to_xml(self, resource_fs):
if self.data:
return etree.fromstring(self.data)
return etree.Element(self.category)
...@@ -12,7 +12,7 @@ import time ...@@ -12,7 +12,7 @@ import time
from django.http import Http404 from django.http import Http404
from xmodule.x_module import XModule from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import EmptyDataRawDescriptor
from xmodule.editing_module import MetadataOnlyEditingDescriptor from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xblock.core import Integer, Scope, String, Float, Boolean from xblock.core import Integer, Scope, String, Float, Boolean
...@@ -97,7 +97,7 @@ class VideoModule(VideoFields, XModule): ...@@ -97,7 +97,7 @@ class VideoModule(VideoFields, XModule):
class VideoDescriptor(VideoFields, class VideoDescriptor(VideoFields,
MetadataOnlyEditingDescriptor, MetadataOnlyEditingDescriptor,
RawDescriptor): EmptyDataRawDescriptor):
module_class = VideoModule module_class = VideoModule
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -130,19 +130,15 @@ class VideoDescriptor(VideoFields, ...@@ -130,19 +130,15 @@ class VideoDescriptor(VideoFields,
_parse_video_xml(video, video.data) _parse_video_xml(video, video.data)
return video return video
def definition_to_xml(self, resource_fs):
"""
Override the base implementation. We don't actually have anything in the 'data' field
(it's an empty string), so we just return a simple XML element
"""
return etree.Element('video')
def _parse_video_xml(video, xml_data): def _parse_video_xml(video, xml_data):
""" """
Parse video fields out of xml_data. The fields are set if they are Parse video fields out of xml_data. The fields are set if they are
present in the XML. present in the XML.
""" """
if not xml_data:
return
xml = etree.fromstring(xml_data) xml = etree.fromstring(xml_data)
display_name = xml.get('display_name') display_name = xml.get('display_name')
......
...@@ -10,7 +10,7 @@ import json ...@@ -10,7 +10,7 @@ import json
import logging import logging
from pkg_resources import resource_string from pkg_resources import resource_string
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import EmptyDataRawDescriptor
from xmodule.editing_module import MetadataOnlyEditingDescriptor from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xmodule.x_module import XModule from xmodule.x_module import XModule
...@@ -240,7 +240,7 @@ class WordCloudModule(WordCloudFields, XModule): ...@@ -240,7 +240,7 @@ class WordCloudModule(WordCloudFields, XModule):
return self.content return self.content
class WordCloudDescriptor(WordCloudFields, MetadataOnlyEditingDescriptor, RawDescriptor): class WordCloudDescriptor(WordCloudFields, MetadataOnlyEditingDescriptor, EmptyDataRawDescriptor):
"""Descriptor for WordCloud Xmodule.""" """Descriptor for WordCloud Xmodule."""
module_class = WordCloudModule module_class = WordCloudModule
template_dir_name = 'word_cloud' template_dir_name = 'word_cloud'
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