@@ -148,16 +190,29 @@ class ConditionalModule(ConditionalFields, XModule, StudioEditableModule):
'voted': 'voted' # poll_question attr
}
- @lazy
- def required_modules(self):
- return [self.system.get_module(descriptor) for
- descriptor in self.descriptor.get_required_module_descriptors()]
+ def __init__(self, *args, **kwargs):
+ """
+ Create an instance of the Conditional XBlock.
+ """
+ super(ConditionalBlock, self).__init__(*args, **kwargs)
+ # Convert sources xml_attribute to a ReferenceList field type so Location/Locator
+ # substitution can be done.
+ if not self.sources_list:
+ if 'sources' in self.xml_attributes and isinstance(self.xml_attributes['sources'], six.string_types):
+ self.sources_list = [
+ # TODO: it is not clear why we are replacing the run here (which actually is a no-op
+ # for old-style course locators. However, this is the implementation of
+ # CourseLocator.make_usage_key_from_deprecated_string, which was previously
+ # being called in this location.
+ BlockUsageLocator.from_string(item).replace(run=self.location.course_key.run)
+ for item in ConditionalBlock.parse_sources(self.xml_attributes)
+ ]
def is_condition_satisfied(self):
attr_name = self.conditions_map[self.conditional_attr]
- if self.conditional_value and self.required_modules:
- for module in self.required_modules:
+ if self.conditional_value and self.get_required_blocks:
+ for module in self.get_required_blocks:
if not hasattr(module, attr_name):
# We don't throw an exception here because it is possible for
# the descriptor of a required module to have a property but
@@ -180,15 +235,22 @@ class ConditionalModule(ConditionalFields, XModule, StudioEditableModule):
return True
return False
- def get_html(self):
- # Calculate html ids of dependencies
- self.required_html_ids = [descriptor.location.html_id() for
- descriptor in self.descriptor.get_required_module_descriptors()]
+ def student_view(self, _context):
+ """
+ Renders the student view.
+ """
+ fragment = Fragment()
+ fragment.add_content(self.get_html())
+ add_webpack_to_fragment(fragment, 'ConditionalBlockPreview')
+ shim_xmodule_js(fragment, 'Conditional')
+ return fragment
+ def get_html(self):
+ required_html_ids = [descriptor.location.html_id() for descriptor in self.get_required_blocks]
return self.system.render_template('conditional_ajax.html', {
'element_id': self.location.html_id(),
- 'ajax_url': self.system.ajax_url,
- 'depends': ';'.join(self.required_html_ids)
+ 'ajax_url': self.ajax_url,
+ 'depends': ';'.join(required_html_ids)
})
def author_view(self, context):
@@ -206,6 +268,17 @@ class ConditionalModule(ConditionalFields, XModule, StudioEditableModule):
return fragment
+ def studio_view(self, _context):
+ """
+ Return the studio view.
+ """
+ fragment = Fragment(
+ self.system.render_template(self.mako_template, self.get_context())
+ )
+ add_webpack_to_fragment(fragment, 'ConditionalBlockStudio')
+ shim_xmodule_js(fragment, self.studio_js_module_name)
+ return fragment
+
def handle_ajax(self, _dispatch, _data):
"""This is called by courseware.moduleodule_render, to handle
an AJAX call.
@@ -227,55 +300,14 @@ class ConditionalModule(ConditionalFields, XModule, StudioEditableModule):
# OBSOLETE: This obsoletes 'type'
class_priority = ['video', 'problem']
- child_classes = [self.system.get_module(child_descriptor).get_icon_class()
- for child_descriptor in self.descriptor.get_children()]
+ child_classes = [
+ child_descriptor.get_icon_class() for child_descriptor in self.get_children()
+ ]
for c in class_priority:
if c in child_classes:
new_class = c
return new_class
- def validate(self):
- """
- Message for either error or warning validation message/s.
-
- Returns message and type. Priority given to error type message.
- """
- return self.descriptor.validate()
-
-
-class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditableDescriptor):
- """Descriptor for conditional xmodule."""
- _tag_name = 'conditional'
-
- module_class = ConditionalModule
-
- resources_dir = None
-
- filename_extension = "xml"
-
- has_score = False
-
- show_in_read_only_mode = True
-
- def __init__(self, *args, **kwargs):
- """
- Create an instance of the conditional module.
- """
- super(ConditionalDescriptor, self).__init__(*args, **kwargs)
-
- # Convert sources xml_attribute to a ReferenceList field type so Location/Locator
- # substitution can be done.
- if not self.sources_list:
- if 'sources' in self.xml_attributes and isinstance(self.xml_attributes['sources'], six.string_types):
- self.sources_list = [
- # TODO: it is not clear why we are replacing the run here (which actually is a no-op
- # for old-style course locators. However, this is the implementation of
- # CourseLocator.make_usage_key_from_deprecated_string, which was previously
- # being called in this location.
- BlockUsageLocator.from_string(item).replace(run=self.location.course_key.run)
- for item in ConditionalDescriptor.parse_sources(self.xml_attributes)
- ]
-
@staticmethod
def parse_sources(xml_element):
""" Parse xml_element 'sources' attr and return a list of location strings. """
@@ -283,9 +315,16 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl
if sources:
return [location.strip() for location in sources.split(';')]
+ @lazy
+ def get_required_blocks(self):
+ """
+ Returns a list of bound XBlocks instances upon which XBlock depends.
+ """
+ return [self.system.get_module(descriptor) for descriptor in self.get_required_module_descriptors()]
+
def get_required_module_descriptors(self):
- """Returns a list of XModuleDescriptor instances upon
- which this module depends.
+ """
+ Returns a list of unbound XBlocks instances upon which this XBlock depends.
"""
descriptors = []
for location in self.sources_list:
@@ -304,7 +343,7 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl
children = []
show_tag_list = []
definition = {}
- for conditional_attr in six.iterkeys(ConditionalModule.conditions_map):
+ for conditional_attr in six.iterkeys(cls.conditions_map):
conditional_value = xml_object.get(conditional_attr)
if conditional_value is not None:
definition.update({
@@ -313,7 +352,7 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl
})
for child in xml_object:
if child.tag == 'show':
- locations = ConditionalDescriptor.parse_sources(child)
+ locations = cls.parse_sources(child)
for location in locations:
children.append(location)
show_tag_list.append(location)
@@ -351,7 +390,7 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl
return xml_object
def validate(self):
- validation = super(ConditionalDescriptor, self).validate()
+ validation = super(ConditionalBlock, self).validate()
if not self.sources_list:
conditional_validation = StudioValidation(self.location)
conditional_validation.add(
@@ -368,14 +407,9 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor, StudioEditabl
@property
def non_editable_metadata_fields(self):
- non_editable_fields = super(ConditionalDescriptor, self).non_editable_metadata_fields
+ non_editable_fields = super(ConditionalBlock, self).non_editable_metadata_fields
non_editable_fields.extend([
- ConditionalDescriptor.due,
- ConditionalDescriptor.is_practice_exam,
- ConditionalDescriptor.is_proctored_enabled,
- ConditionalDescriptor.is_time_limited,
- ConditionalDescriptor.default_time_limit_minutes,
- ConditionalDescriptor.show_tag_list,
- ConditionalDescriptor.exam_review_rules,
+ ConditionalBlock.due,
+ ConditionalBlock.show_tag_list,
])
return non_editable_fields
diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py
index 1210294b97..7d56dc576c 100644
--- a/common/lib/xmodule/xmodule/seq_module.py
+++ b/common/lib/xmodule/xmodule/seq_module.py
@@ -12,7 +12,6 @@ from datetime import datetime
from functools import reduce
import six
-from django.contrib.auth.models import User
from lxml import etree
from opaque_keys.edx.keys import UsageKey
from pkg_resources import resource_string
@@ -281,6 +280,13 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
datetime.now(UTC) < date
)
+ def _get_user(self):
+ """
+ Return the current runtime Django user.
+ """
+ from django.contrib.auth.models import User
+ return User.objects.get(id=self.runtime.user_id)
+
def gate_sequence_if_it_is_a_timed_exam_and_contains_content_type_gated_problems(self):
"""
Problem:
@@ -316,7 +322,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
return
try:
- user = User.objects.get(id=self.runtime.user_id)
+ user = self._get_user()
course_id = self.runtime.course_id
content_type_gating_service = self.runtime.service(self, 'content_type_gating')
if not (content_type_gating_service and
@@ -806,7 +812,46 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
return new_class
-class SequenceDescriptor(SequenceFields, ProctoringFields, MakoModuleDescriptor, XmlDescriptor):
+class SequenceMixin(SequenceFields):
+ """
+ A mixin of shared code between the SequenceDescriptor and XBlocks
+ converted from XModules which inherited from SequenceDescriptor.
+ """
+ @classmethod
+ def definition_from_xml(cls, xml_object, system):
+ children = []
+ for child in xml_object:
+ try:
+ child_block = system.process_xml(etree.tostring(child, encoding='unicode'))
+ children.append(child_block.scope_ids.usage_id)
+ except Exception as e:
+ log.exception("Unable to load child when parsing Sequence. Continuing...")
+ if system.error_tracker is not None:
+ system.error_tracker(u"ERROR: {0}".format(e))
+ continue
+ return {}, children
+
+ def index_dictionary(self):
+ """
+ Return dictionary prepared with module content and type for indexing.
+ """
+ # return key/value fields in a Python dict object
+ # values may be numeric / string or dict
+ # default implementation is an empty dict
+ xblock_body = super(SequenceMixin, self).index_dictionary()
+ html_body = {
+ "display_name": self.display_name,
+ }
+ if "content" in xblock_body:
+ xblock_body["content"].update(html_body)
+ else:
+ xblock_body["content"] = html_body
+ xblock_body["content_type"] = "Sequence"
+
+ return xblock_body
+
+
+class SequenceDescriptor(SequenceMixin, ProctoringFields, MakoModuleDescriptor, XmlDescriptor):
"""
A Sequence's Descriptor object
"""
@@ -822,20 +867,6 @@ class SequenceDescriptor(SequenceFields, ProctoringFields, MakoModuleDescriptor,
}
js_module_name = "SequenceDescriptor"
- @classmethod
- def definition_from_xml(cls, xml_object, system):
- children = []
- for child in xml_object:
- try:
- child_block = system.process_xml(etree.tostring(child, encoding='unicode'))
- children.append(child_block.scope_ids.usage_id)
- except Exception as e:
- log.exception("Unable to load child when parsing Sequence. Continuing...")
- if system.error_tracker is not None:
- system.error_tracker(u"ERROR: {0}".format(e))
- continue
- return {}, children
-
def definition_to_xml(self, resource_fs):
xml_object = etree.Element('sequential')
for child in self.get_children():
@@ -848,28 +879,9 @@ class SequenceDescriptor(SequenceFields, ProctoringFields, MakoModuleDescriptor,
`is_entrance_exam` should not be editable in the Studio settings editor.
"""
non_editable_fields = super(SequenceDescriptor, self).non_editable_metadata_fields
- non_editable_fields.append(self.fields['is_entrance_exam'])
+ non_editable_fields.append(self.fields['is_entrance_exam']) # pylint:disable=unsubscriptable-object
return non_editable_fields
- def index_dictionary(self):
- """
- Return dictionary prepared with module content and type for indexing.
- """
- # return key/value fields in a Python dict object
- # values may be numeric / string or dict
- # default implementation is an empty dict
- xblock_body = super(SequenceDescriptor, self).index_dictionary()
- html_body = {
- "display_name": self.display_name,
- }
- if "content" in xblock_body:
- xblock_body["content"].update(html_body)
- else:
- xblock_body["content"] = html_body
- xblock_body["content_type"] = "Sequence"
-
- return xblock_body
-
class HighlightsFields(object):
"""Only Sections have summaries now, but we may expand that later."""
diff --git a/common/lib/xmodule/xmodule/static_content.py b/common/lib/xmodule/xmodule/static_content.py
index 44d8fa4033..607c3e90d8 100755
--- a/common/lib/xmodule/xmodule/static_content.py
+++ b/common/lib/xmodule/xmodule/static_content.py
@@ -21,6 +21,7 @@ from docopt import docopt
from path import Path as path
from xmodule.capa_module import ProblemBlock
+from xmodule.conditional_module import ConditionalBlock
from xmodule.html_module import AboutBlock, CourseInfoBlock, HtmlBlock, StaticTabBlock
from xmodule.library_content_module import LibraryContentBlock
from xmodule.word_cloud_module import WordCloudBlock
@@ -66,6 +67,7 @@ class VideoBlock(HTMLSnippet):
# Should only be used for XModules being converted to XBlocks.
XBLOCK_CLASSES = [
AboutBlock,
+ ConditionalBlock,
CourseInfoBlock,
HtmlBlock,
LibraryContentBlock,
diff --git a/common/lib/xmodule/xmodule/tests/test_conditional.py b/common/lib/xmodule/xmodule/tests/test_conditional.py
index 9b248f6e81..5155a0f787 100644
--- a/common/lib/xmodule/xmodule/tests/test_conditional.py
+++ b/common/lib/xmodule/xmodule/tests/test_conditional.py
@@ -13,7 +13,7 @@ from web_fragments.fragment import Fragment
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
-from xmodule.conditional_module import ConditionalDescriptor
+from xmodule.conditional_module import ConditionalBlock
from xmodule.error_module import NonStaffErrorDescriptor
from xmodule.modulestore.xml import CourseLocationManager, ImportSystem, XMLModuleStore
from xmodule.tests import DATA_DIR, get_test_descriptor_system, get_test_system
@@ -45,9 +45,9 @@ class DummySystem(ImportSystem):
raise Exception("Shouldn't be called")
-class ConditionalModuleFactory(xml.XmlImportFactory):
+class ConditionalBlockFactory(xml.XmlImportFactory):
"""
- Factory for generating ConditionalModule for testing purposes
+ Factory for generating ConditionalBlock for testing purposes
"""
tag = 'conditional'
@@ -125,17 +125,15 @@ class ConditionalFactory(object):
'children': [child_descriptor.location],
})
- cond_descriptor = ConditionalDescriptor(
+ cond_descriptor = ConditionalBlock(
descriptor_system,
field_data,
ScopeIds(None, None, cond_location, cond_location)
)
cond_descriptor.xmodule_runtime = system
system.get_module = lambda desc: desc if visible_to_nonstaff_users(desc) else None
- cond_descriptor.get_required_module_descriptors = Mock(return_value=[source_descriptor])
- cond_descriptor.required_modules = [
- system.get_module(descriptor)
- for descriptor in cond_descriptor.get_required_module_descriptors()
+ cond_descriptor.get_required_blocks = [
+ system.get_module(source_descriptor),
]
# return dict:
@@ -144,14 +142,14 @@ class ConditionalFactory(object):
'child_module': child_descriptor}
-class ConditionalModuleBasicTest(unittest.TestCase):
+class ConditionalBlockBasicTest(unittest.TestCase):
"""
Make sure that conditional module works, using mocks for
other modules.
"""
def setUp(self):
- super(ConditionalModuleBasicTest, self).setUp()
+ super(ConditionalBlockBasicTest, self).setUp()
self.test_system = get_test_system()
def test_icon_class(self):
@@ -169,7 +167,7 @@ class ConditionalModuleBasicTest(unittest.TestCase):
# we reverse it here
html = modules['cond_module'].render(STUDENT_VIEW).content
expected = modules['cond_module'].xmodule_runtime.render_template('conditional_ajax.html', {
- 'ajax_url': modules['cond_module'].xmodule_runtime.ajax_url,
+ 'ajax_url': modules['cond_module'].ajax_url,
'element_id': u'i4x-edX-conditional_test-conditional-SampleConditional',
'depends': u'i4x-edX-conditional_test-problem-SampleProblem',
})
@@ -214,12 +212,12 @@ class ConditionalModuleBasicTest(unittest.TestCase):
cond_module.is_attempted = "false"
cond_module.handle_ajax('', '')
self.assertFalse(mock_log.warn.called)
- self.assertIn(None, cond_module.required_modules)
+ self.assertIn(None, cond_module.get_required_blocks)
-class ConditionalModuleXmlTest(unittest.TestCase):
+class ConditionalBlockXmlTest(unittest.TestCase):
"""
- Make sure ConditionalModule works, by loading data in from an XML-defined course.
+ Make sure ConditionalBlock works, by loading data in from an XML-defined course.
"""
@staticmethod
@@ -228,7 +226,7 @@ class ConditionalModuleXmlTest(unittest.TestCase):
return DummySystem(load_error_modules)
def setUp(self):
- super(ConditionalModuleXmlTest, self).setUp()
+ super(ConditionalBlockXmlTest, self).setUp()
self.test_system = get_test_system()
def get_course(self, name):
@@ -241,7 +239,8 @@ class ConditionalModuleXmlTest(unittest.TestCase):
self.assertEqual(len(courses), 1)
return courses[0]
- def test_conditional_module(self):
+ @patch('xmodule.x_module.descriptor_global_local_resource_url')
+ def test_conditional_module(self, _):
"""Make sure that conditional module works"""
print("Starting import")
@@ -309,9 +308,11 @@ class ConditionalModuleXmlTest(unittest.TestCase):
fragments = ajax['fragments']
self.assertTrue(any(['This is a secret' in item['content'] for item in fragments]))
+ maxDiff = None
+
def test_conditional_module_with_empty_sources_list(self):
"""
- If a ConditionalDescriptor is initialized with an empty sources_list, we assert that the sources_list is set
+ If a ConditionalBlock is initialized with an empty sources_list, we assert that the sources_list is set
via generating UsageKeys from the values in xml_attributes['sources']
"""
dummy_system = Mock()
@@ -323,16 +324,18 @@ class ConditionalModuleXmlTest(unittest.TestCase):
'xml_attributes': {'sources': 'i4x://HarvardX/ER22x/poll_question/T15_poll'},
'children': None,
})
- conditional = ConditionalDescriptor(
+ conditional = ConditionalBlock(
dummy_system,
dummy_field_data,
dummy_scope_ids,
)
+
new_run = conditional.location.course_key.run
self.assertEqual(
conditional.sources_list[0],
- # Matching what is in ConditionalDescriptor.__init__.
- BlockUsageLocator.from_string(conditional.xml_attributes['sources']).replace(run=new_run)
+ BlockUsageLocator.from_string(
+ conditional.xml_attributes['sources']
+ ).replace(run=dummy_location.course_key.run)
)
def test_conditional_module_parse_sources(self):
@@ -345,7 +348,7 @@ class ConditionalModuleXmlTest(unittest.TestCase):
'xml_attributes': {'sources': 'i4x://HarvardX/ER22x/poll_question/T15_poll;i4x://HarvardX/ER22x/poll_question/T16_poll'},
'children': None,
})
- conditional = ConditionalDescriptor(
+ conditional = ConditionalBlock(
dummy_system,
dummy_field_data,
dummy_scope_ids,
@@ -358,7 +361,7 @@ class ConditionalModuleXmlTest(unittest.TestCase):
def test_conditional_module_parse_attr_values(self):
root = ''
xml_object = etree.XML(root)
- definition = ConditionalDescriptor.definition_from_xml(xml_object, Mock())[0]
+ definition = ConditionalBlock.definition_from_xml(xml_object, Mock())[0]
expected_definition = {
'show_tag_list': [],
'conditional_attr': 'attempted',
@@ -380,16 +383,16 @@ class ConditionalModuleXmlTest(unittest.TestCase):
self.assertDictEqual(modules['cond_module'].xml_attributes, expected_xml_attributes)
-class ConditionalModuleStudioTest(XModuleXmlImportTest):
+class ConditionalBlockStudioTest(XModuleXmlImportTest):
"""
Unit tests for how conditional test interacts with Studio.
"""
def setUp(self):
- super(ConditionalModuleStudioTest, self).setUp()
+ super().setUp()
course = xml.CourseFactory.build()
sequence = xml.SequenceFactory.build(parent=course)
- conditional = ConditionalModuleFactory(
+ conditional = ConditionalBlockFactory(
parent=sequence,
attribs={
'group_id_to_child': '{"0": "i4x://edX/xml_test_course/html/conditional_0"}'
@@ -438,11 +441,7 @@ class ConditionalModuleStudioTest(XModuleXmlImportTest):
Test the settings that are marked as "non-editable".
"""
non_editable_metadata_fields = self.conditional.non_editable_metadata_fields
- self.assertIn(ConditionalDescriptor.due, non_editable_metadata_fields)
- self.assertIn(ConditionalDescriptor.is_practice_exam, non_editable_metadata_fields)
- self.assertIn(ConditionalDescriptor.is_time_limited, non_editable_metadata_fields)
- self.assertIn(ConditionalDescriptor.default_time_limit_minutes, non_editable_metadata_fields)
- self.assertIn(ConditionalDescriptor.show_tag_list, non_editable_metadata_fields)
+ self.assertIn(ConditionalBlock.due, non_editable_metadata_fields)
def test_validation_messages(self):
"""
diff --git a/common/lib/xmodule/xmodule/tests/test_conditional_logic.py b/common/lib/xmodule/xmodule/tests/test_conditional_logic.py
deleted file mode 100644
index 0f0eb20daa..0000000000
--- a/common/lib/xmodule/xmodule/tests/test_conditional_logic.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-"""Test for Conditional Xmodule functional logic."""
-
-
-from xmodule.conditional_module import ConditionalDescriptor
-
-from . import LogicTest
-
-
-class ConditionalModuleTest(LogicTest):
- """Logic tests for Conditional Xmodule."""
- descriptor_class = ConditionalDescriptor
-
- def test_ajax_request(self):
- "Make sure that ajax request works correctly"
- # Mock is_condition_satisfied
- self.xmodule.is_condition_satisfied = lambda: True
- self.xmodule.descriptor.get_children = lambda: []
-
- response = self.ajax_request('No', {})
- fragments = response['fragments']
-
- self.assertEqual(fragments, [])
diff --git a/common/lib/xmodule/xmodule/tests/test_sequence.py b/common/lib/xmodule/xmodule/tests/test_sequence.py
index f866ed8556..1e07e83ff5 100644
--- a/common/lib/xmodule/xmodule/tests/test_sequence.py
+++ b/common/lib/xmodule/xmodule/tests/test_sequence.py
@@ -160,7 +160,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self.assertIn("'prev_url': 'PrevSequential'", html)
self.assertNotIn("fa fa-check-circle check-circle is-hidden", html)
- @patch('xmodule.seq_module.User.objects.get', return_value=UserFactory.build())
+ @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build())
def test_timed_exam_gating_waffle_flag(self, mocked_user):
"""
Verify the code inside the waffle flag is not executed with the flag off
@@ -185,7 +185,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
mocked_user.assert_called_once()
@override_waffle_flag(TIMED_EXAM_GATING_WAFFLE_FLAG, active=True)
- @patch('xmodule.seq_module.User.objects.get', return_value=UserFactory.build())
+ @patch('xmodule.seq_module.SequenceModule._get_user', return_value=UserFactory.build())
def test_that_timed_sequence_gating_respects_access_configurations(self, mocked_user): # pylint: disable=unused-argument
"""
Verify that if a time limited sequence contains content type gated problems, we gate the sequence
diff --git a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
index 12cdaecb75..dfb30941f5 100644
--- a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
+++ b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
@@ -31,7 +31,7 @@ from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
from xmodule.annotatable_module import AnnotatableDescriptor
-from xmodule.conditional_module import ConditionalDescriptor
+from xmodule.conditional_module import ConditionalBlock
from xmodule.course_module import CourseDescriptor
from xmodule.html_module import HtmlBlock
from xmodule.poll_module import PollDescriptor
@@ -66,7 +66,7 @@ LEAF_XMODULES = {
# to a list of sample field values to test with.
# TODO: Add more types of sample data
CONTAINER_XMODULES = {
- ConditionalDescriptor: [{}],
+ ConditionalBlock: [{}],
CourseDescriptor: [{}],
RandomizeDescriptor: [{'display_name': 'Test String Display'}],
SequenceDescriptor: [{'display_name': u'Test Unicode हिंदी Display'}],
diff --git a/lms/templates/conditional_module.html b/lms/templates/conditional_module.html
index 90c5ccdfde..06a055e2a0 100644
--- a/lms/templates/conditional_module.html
+++ b/lms/templates/conditional_module.html
@@ -14,7 +14,7 @@ def _message(reqm, message):
url_name = reqm.display_name_with_default))
%>
% if message:
- % for reqm in module.required_modules:
+ % for reqm in module.get_required_blocks:
% if reqm:
${_message(reqm, message)}
% else: