Commit 891cf8bb by Andy Armstrong

Merge pull request #2924 from edx/andya/studio-split-test-support-2

Fix split_test xblock so that it can render in Studio
parents 2218764e 58483c06
...@@ -231,9 +231,10 @@ def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, v ...@@ -231,9 +231,10 @@ def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, v
# with the new container view. # with the new container view.
is_read_only_view = is_container_view is_read_only_view = is_container_view
context = { context = {
'runtime_type': 'studio',
'container_view': is_container_view, 'container_view': is_container_view,
'read_only': is_read_only_view, 'read_only': is_read_only_view,
'root_xblock': component 'root_xblock': component,
} }
fragment = get_preview_fragment(request, component, context) fragment = get_preview_fragment(request, component, context)
......
...@@ -157,6 +157,22 @@ class GetItem(ItemTest): ...@@ -157,6 +157,22 @@ class GetItem(ItemTest):
'<span class="action-button-text">View</span>') '<span class="action-button-text">View</span>')
) )
def test_split_test(self):
"""
Test that a split_test module renders all of its children in Studio.
"""
root_locator = self._create_vertical()
resp = self.create_xblock(category='split_test', parent_locator=root_locator)
self.assertEqual(resp.status_code, 200)
split_test_locator = self.response_locator(resp)
resp = self.create_xblock(parent_locator=split_test_locator, category='html', boilerplate='announcement.yaml')
self.assertEqual(resp.status_code, 200)
resp = self.create_xblock(parent_locator=split_test_locator, category='html', boilerplate='zooming_image.yaml')
self.assertEqual(resp.status_code, 200)
html, __ = self._get_container_preview(split_test_locator)
self.assertIn('Announcement', html)
self.assertIn('Zooming', html)
class DeleteItem(ItemTest): class DeleteItem(ItemTest):
"""Tests for '/xblock' DELETE url.""" """Tests for '/xblock' DELETE url."""
......
...@@ -41,7 +41,7 @@ class SplitTestFields(object): ...@@ -41,7 +41,7 @@ class SplitTestFields(object):
@XBlock.needs('user_tags') # pylint: disable=abstract-method @XBlock.needs('user_tags') # pylint: disable=abstract-method
@XBlock.needs('partitions') @XBlock.wants('partitions')
class SplitTestModule(SplitTestFields, XModule): class SplitTestModule(SplitTestFields, XModule):
""" """
Show the user the appropriate child. Uses the ExperimentState Show the user the appropriate child. Uses the ExperimentState
...@@ -61,7 +61,10 @@ class SplitTestModule(SplitTestFields, XModule): ...@@ -61,7 +61,10 @@ class SplitTestModule(SplitTestFields, XModule):
super(SplitTestModule, self).__init__(*args, **kwargs) super(SplitTestModule, self).__init__(*args, **kwargs)
self.child_descriptor = self.get_child_descriptors()[0] self.child_descriptor = None
child_descriptors = self.get_child_descriptors()
if len(child_descriptors) >= 1:
self.child_descriptor = child_descriptors[0]
if self.child_descriptor is not None: if self.child_descriptor is not None:
self.child = self.system.get_module(self.child_descriptor) self.child = self.system.get_module(self.child_descriptor)
else: else:
...@@ -106,7 +109,9 @@ class SplitTestModule(SplitTestFields, XModule): ...@@ -106,7 +109,9 @@ class SplitTestModule(SplitTestFields, XModule):
""" """
For grading--return just the chosen child. For grading--return just the chosen child.
""" """
group_id = self.runtime.service(self, 'partitions').get_user_group_for_partition(self.user_partition_id) group_id = self.get_group_id()
if group_id is None:
return []
# group_id_to_child comes from json, so it has to have string keys # group_id_to_child comes from json, so it has to have string keys
str_group_id = str(group_id) str_group_id = str(group_id)
...@@ -126,6 +131,15 @@ class SplitTestModule(SplitTestFields, XModule): ...@@ -126,6 +131,15 @@ class SplitTestModule(SplitTestFields, XModule):
return [child_descriptor] return [child_descriptor]
def get_group_id(self):
"""
Returns the group ID, or None if none is available.
"""
partitions_service = self.runtime.service(self, 'partitions')
if not partitions_service:
return None
return partitions_service.get_user_group_for_partition(self.user_partition_id)
def _staff_view(self, context): def _staff_view(self, context):
""" """
Render the staff view for a split test module. Render the staff view for a split test module.
...@@ -155,11 +169,37 @@ class SplitTestModule(SplitTestFields, XModule): ...@@ -155,11 +169,37 @@ class SplitTestModule(SplitTestFields, XModule):
fragment.initialize_js('ABTestSelector') fragment.initialize_js('ABTestSelector')
return fragment return fragment
def studio_preview_view(self, context):
"""
Renders the Studio preview by rendering each child so that they can all be seen and edited.
"""
fragment = Fragment()
contents = []
for child in self.descriptor.get_children():
rendered_child = self.runtime.get_module(child).render('student_view', context)
fragment.add_frag_resources(rendered_child)
contents.append({
'id': child.id,
'content': rendered_child.content
})
fragment.add_content(self.system.render_template('vert_module.html', {
'items': contents
}))
return fragment
def student_view(self, context): def student_view(self, context):
""" """
Render the contents of the chosen condition for students, and all the Render the contents of the chosen condition for students, and all the
conditions for staff. conditions for staff.
""" """
# When rendering a Studio preview, render all of the block's children
if context and context['runtime_type'] == 'studio':
return self.studio_preview_view(context)
if self.child is None: if self.child is None:
# raise error instead? In fact, could complain on descriptor load... # raise error instead? In fact, could complain on descriptor load...
return Fragment(content=u"<div>Nothing here. Move along.</div>") return Fragment(content=u"<div>Nothing here. Move along.</div>")
...@@ -197,7 +237,7 @@ class SplitTestModule(SplitTestFields, XModule): ...@@ -197,7 +237,7 @@ class SplitTestModule(SplitTestFields, XModule):
@XBlock.needs('user_tags') # pylint: disable=abstract-method @XBlock.needs('user_tags') # pylint: disable=abstract-method
@XBlock.needs('partitions') @XBlock.wants('partitions')
class SplitTestDescriptor(SplitTestFields, SequenceDescriptor): class SplitTestDescriptor(SplitTestFields, SequenceDescriptor):
# the editing interface can be the same as for sequences -- just a container # the editing interface can be the same as for sequences -- just a container
module_class = SplitTestModule module_class = SplitTestModule
......
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