Studio render XBlockAside views
PLAT-280
This commit is contained in:
@@ -45,7 +45,7 @@ from contentstore.views.helpers import is_unit, xblock_studio_url, xblock_primar
|
||||
from contentstore.views.preview import get_preview_fragment
|
||||
from edxmako.shortcuts import render_to_string
|
||||
from models.settings.course_grading import CourseGradingModel
|
||||
from cms.lib.xblock.runtime import handler_url, local_resource_url, applicable_aside_types
|
||||
from cms.lib.xblock.runtime import handler_url, local_resource_url
|
||||
from opaque_keys.edx.keys import UsageKey, CourseKey
|
||||
|
||||
__all__ = ['orphan_handler', 'xblock_handler', 'xblock_view_handler', 'xblock_outline_handler']
|
||||
@@ -64,7 +64,6 @@ ALWAYS = lambda x: True
|
||||
# TODO: Remove this code when Runtimes are no longer created by modulestores
|
||||
xmodule.x_module.descriptor_global_handler_url = handler_url
|
||||
xmodule.x_module.descriptor_global_local_resource_url = local_resource_url
|
||||
xmodule.x_module.descriptor_global_applicable_aside_types = applicable_aside_types
|
||||
|
||||
|
||||
def hash_resource(resource):
|
||||
|
||||
@@ -87,7 +87,7 @@ class PreviewModuleSystem(ModuleSystem): # pylint: disable=abstract-method
|
||||
|
||||
def handler_url(self, block, handler_name, suffix='', query='', thirdparty=False):
|
||||
return reverse('preview_handler', kwargs={
|
||||
'usage_key_string': unicode(block.location),
|
||||
'usage_key_string': unicode(block.scope_ids.usage_id),
|
||||
'handler': handler_name,
|
||||
'suffix': suffix,
|
||||
}) + '?' + query
|
||||
@@ -96,8 +96,14 @@ class PreviewModuleSystem(ModuleSystem): # pylint: disable=abstract-method
|
||||
return local_resource_url(block, uri)
|
||||
|
||||
def applicable_aside_types(self, block):
|
||||
# TODO: Implement this to enable XBlockAsides on previews in Studio
|
||||
return []
|
||||
"""
|
||||
Remove acid_aside
|
||||
"""
|
||||
return [
|
||||
aside_type
|
||||
for aside_type in super(PreviewModuleSystem, self).applicable_aside_types(block)
|
||||
if aside_type != 'acid_aside'
|
||||
]
|
||||
|
||||
|
||||
class StudioUserService(object):
|
||||
|
||||
@@ -9,6 +9,10 @@ from student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
|
||||
from contentstore.views.preview import get_preview_fragment
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xblock.core import XBlockAside
|
||||
from xmodule.modulestore.tests.test_asides import AsideTestType
|
||||
import re
|
||||
|
||||
|
||||
class GetPreviewHtmlTestCase(TestCase):
|
||||
@@ -19,6 +23,7 @@ class GetPreviewHtmlTestCase(TestCase):
|
||||
get_preview_fragment via the xblock RESTful API.
|
||||
"""
|
||||
|
||||
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
|
||||
def test_preview_fragment(self):
|
||||
"""
|
||||
Test for calling get_preview_html.
|
||||
@@ -26,7 +31,7 @@ class GetPreviewHtmlTestCase(TestCase):
|
||||
This test used to be specifically about Locators (ensuring that they did not
|
||||
get translated to Locations). The test now has questionable value.
|
||||
"""
|
||||
course = CourseFactory.create()
|
||||
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
|
||||
html = ItemFactory.create(
|
||||
parent_location=course.location,
|
||||
category="html",
|
||||
@@ -45,9 +50,13 @@ class GetPreviewHtmlTestCase(TestCase):
|
||||
html = get_preview_fragment(request, html, context).content
|
||||
|
||||
# Verify student view html is returned, and the usage ID is as expected.
|
||||
html_pattern = unicode(course.id.make_usage_key('html', 'html_')).replace('html_', r'html_[0-9]*')
|
||||
html_pattern = re.escape(unicode(course.id.make_usage_key('html', 'replaceme'))).replace('replaceme', r'html_[0-9]*')
|
||||
self.assertRegexpMatches(
|
||||
html,
|
||||
'data-usage-id="{}"'.format(html_pattern)
|
||||
)
|
||||
self.assertRegexpMatches(html, '<html>foobar</html>')
|
||||
self.assertRegexpMatches(html, r"data-block-type=[\"\']test_aside[\"\']")
|
||||
self.assertRegexpMatches(html, "Aside rendered")
|
||||
# Now ensure the acid_aside is not in the result
|
||||
self.assertNotRegexpMatches(html, r"data-block-type=[\"\']acid_aside[\"\']")
|
||||
|
||||
@@ -33,11 +33,3 @@ def local_resource_url(block, uri):
|
||||
'block_type': block.scope_ids.block_type,
|
||||
'uri': uri,
|
||||
})
|
||||
|
||||
|
||||
def applicable_aside_types(block): # pylint: disable=unused-argument
|
||||
"""
|
||||
Get the application-relative list of aside types for this type of block.
|
||||
"""
|
||||
# TODO: Implement this method to make XBlockAsides for editing views in Studio
|
||||
return []
|
||||
|
||||
@@ -356,6 +356,10 @@ class CachingDescriptorSystem(MakoDescriptorSystem, EditInfoRuntimeMixin):
|
||||
"""
|
||||
return xblock._edit_info.get('published_date')
|
||||
|
||||
def applicable_aside_types(self, block):
|
||||
# "old" mongo does support asides yet
|
||||
return []
|
||||
|
||||
|
||||
# The only thing using this w/ wildcards is contentstore.mongo for asset retrieval
|
||||
def location_to_query(location, wildcard=True, tag='i4x'):
|
||||
|
||||
@@ -28,7 +28,7 @@ class TestAsidesXmlStore(TestCase):
|
||||
"""
|
||||
Test Asides sourced from xml store
|
||||
"""
|
||||
@patch('xmodule.x_module.descriptor_global_applicable_aside_types', lambda block: ['test_aside'])
|
||||
@patch('xmodule.modulestore.xml.ImportSystem.applicable_aside_types', lambda self, block: ['test_aside'])
|
||||
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
|
||||
def test_xml_aside(self):
|
||||
"""
|
||||
|
||||
@@ -203,6 +203,6 @@ class TestLibraries(MixedSplitTestCase):
|
||||
message = u"Hello world"
|
||||
hello_render = lambda _, context: Fragment(message)
|
||||
with patch('xmodule.html_module.HtmlDescriptor.author_view', hello_render, create=True):
|
||||
with patch('xmodule.x_module.descriptor_global_applicable_aside_types', lambda block: []):
|
||||
with patch('xmodule.x_module.DescriptorSystem.applicable_aside_types', lambda self, block: []):
|
||||
result = library.render(AUTHOR_VIEW, context)
|
||||
self.assertIn(message, result.content)
|
||||
|
||||
@@ -1133,15 +1133,6 @@ def descriptor_global_local_resource_url(block, uri): # pylint: disable=invalid
|
||||
raise NotImplementedError("Applications must monkey-patch this function before using local_resource_url for studio_view")
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def descriptor_global_applicable_aside_types(block): # pylint: disable=unused-argument
|
||||
"""
|
||||
See :meth:`xblock.runtime.Runtime.applicable_aside_types`.
|
||||
"""
|
||||
raise NotImplementedError("Applications must monkey-patch this function before using applicable_aside_types"
|
||||
" from a DescriptorSystem.")
|
||||
|
||||
|
||||
class MetricsMixin(object):
|
||||
"""
|
||||
Mixin for adding metric logging for render and handle methods in the DescriptorSystem and ModuleSystem.
|
||||
@@ -1320,14 +1311,11 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime): # p
|
||||
"""
|
||||
See :meth:`xblock.runtime.Runtime:applicable_aside_types` for documentation.
|
||||
"""
|
||||
potential_set = set(super(DescriptorSystem, self).applicable_aside_types(block))
|
||||
if getattr(block, 'xmodule_runtime', None) is not None:
|
||||
return block.xmodule_runtime.applicable_aside_types(block)
|
||||
else:
|
||||
# Currently, Modulestore is responsible for instantiating DescriptorSystems
|
||||
# This means that LMS/CMS don't have a way to define a subclass of DescriptorSystem
|
||||
# that implements the correct get_asides. So, for now, instead, we will reference a
|
||||
# global function that the application can override.
|
||||
return descriptor_global_applicable_aside_types(block)
|
||||
application_set = set(block.xmodule_runtime.applicable_aside_types(block))
|
||||
return list(potential_set.intersection(application_set))
|
||||
return list(potential_set)
|
||||
|
||||
def resource_url(self, resource):
|
||||
"""
|
||||
|
||||
@@ -326,7 +326,7 @@ def _section_data_download(course, access):
|
||||
|
||||
def null_applicable_aside_types(block): # pylint: disable=unused-argument
|
||||
"""
|
||||
get_aside method for monkey-patching into descriptor_global_applicable_aside_types
|
||||
get_aside method for monkey-patching into applicable_aside_types
|
||||
while rendering an HtmlDescriptor for email text editing. This returns
|
||||
an empty list.
|
||||
"""
|
||||
@@ -337,8 +337,8 @@ def _section_send_email(course, access):
|
||||
""" Provide data for the corresponding bulk email section """
|
||||
course_key = course.id
|
||||
|
||||
# Monkey-patch descriptor_global_applicable_aside_types to return no asides for the duration of this render
|
||||
with patch('xmodule.x_module.descriptor_global_applicable_aside_types', null_applicable_aside_types):
|
||||
# Monkey-patch applicable_aside_types to return no asides for the duration of this render
|
||||
with patch.object(course.runtime, 'applicable_aside_types', null_applicable_aside_types):
|
||||
# This HtmlDescriptor is only being used to generate a nice text editor.
|
||||
html_module = HtmlDescriptor(
|
||||
course.system,
|
||||
|
||||
@@ -9,7 +9,6 @@ from django.core.urlresolvers import reverse
|
||||
from django.conf import settings
|
||||
from lms.djangoapps.lms_xblock.models import XBlockAsidesConfig
|
||||
from openedx.core.djangoapps.user_api.api import course_tag as user_course_tag_api
|
||||
from xblock.core import XBlockAside
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.x_module import ModuleSystem
|
||||
from xmodule.partitions.partitions_service import PartitionService
|
||||
|
||||
Reference in New Issue
Block a user