diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py
index b0571fba9fb4..822ca902ceee 100644
--- a/common/lib/xmodule/xmodule/html_module.py
+++ b/common/lib/xmodule/xmodule/html_module.py
@@ -76,6 +76,17 @@ def student_view(self, _context):
"""
return Fragment(self.get_html())
+ def student_view_data(self):
+ """
+ Returns a JSON representation of the student_view of this XBlock,
+ retrievable from the Course Block API.
+ Since this data is not user-specific, fields like `html` may contain
+ placeholders like %%USER_ID%%.
+ """
+ return {
+ 'html': self.data
+ }
+
def get_html(self):
""" Returns html required for rendering XModule. """
diff --git a/common/lib/xmodule/xmodule/tests/test_html_module.py b/common/lib/xmodule/xmodule/tests/test_html_module.py
index 2b272487ff13..b0f00432e51e 100644
--- a/common/lib/xmodule/xmodule/tests/test_html_module.py
+++ b/common/lib/xmodule/xmodule/tests/test_html_module.py
@@ -1,5 +1,5 @@
import unittest
-
+import ddt
from mock import Mock
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xblock.field_data import DictFieldData
@@ -24,6 +24,30 @@ def instantiate_descriptor(**field_data):
)
+@ddt.ddt
+class HtmlModuleCourseApiTestCase(unittest.TestCase):
+ """
+ Ensure that student_view_data can handle likely input,
+ and doesn't modify the HTML in any way.
+ This means that it does NOT protect against XSS, escape HTML tags, etc.
+ """
+ @ddt.data(
+ '
Some content
', # Valid HTML
+ '',
+ None,
+ 'Some contentalert()', # Does not escape tags
+ '
', # Images allowed
+ 'short string ' * 100, # May contain long strings
+ )
+ def test_common_values(self, html):
+ descriptor = Mock()
+ field_data = DictFieldData({'data': html})
+ module_system = get_test_system()
+ module = HtmlModule(descriptor, module_system, field_data, Mock())
+ self.assertEqual(module.student_view_data(), {'html': html})
+
+
class HtmlModuleSubstitutionTestCase(unittest.TestCase):
descriptor = Mock()
diff --git a/lms/djangoapps/course_api/blocks/tests/test_views.py b/lms/djangoapps/course_api/blocks/tests/test_views.py
index 5c518fa7e27a..70a6e4918201 100644
--- a/lms/djangoapps/course_api/blocks/tests/test_views.py
+++ b/lms/djangoapps/course_api/blocks/tests/test_views.py
@@ -22,7 +22,7 @@ class TestBlocksView(SharedModuleStoreTestCase):
Test class for BlocksView
"""
requested_fields = ['graded', 'format', 'student_view_multi_device', 'children', 'not_a_field', 'due']
- BLOCK_TYPES_WITH_STUDENT_VIEW_DATA = ['video', 'discussion']
+ BLOCK_TYPES_WITH_STUDENT_VIEW_DATA = ['video', 'discussion', 'html']
@classmethod
def setUpClass(cls):
diff --git a/lms/djangoapps/course_api/blocks/transformers/tests/test_student_view.py b/lms/djangoapps/course_api/blocks/transformers/tests/test_student_view.py
index b37ec88e80f4..f20e76c40a3d 100644
--- a/lms/djangoapps/course_api/blocks/transformers/tests/test_student_view.py
+++ b/lms/djangoapps/course_api/blocks/transformers/tests/test_student_view.py
@@ -44,7 +44,7 @@ def test_transform(self):
# verify html data
html_block_key = self.course_key.make_usage_key('html', 'toyhtml')
- self.assertIsNone(
+ self.assertIsNotNone(
self.block_structure.get_transformer_block_field(
html_block_key, StudentViewTransformer, StudentViewTransformer.STUDENT_VIEW_DATA,
)