Commit b4a18403 by Calen Pennington

Move xmodule_runtime.xmodule_instance registration earlier

This allows XModules (specifically CombinedOpenEnded) to use ajax_url
during their init functions (which would, before, have thrown an
exception).

[LMS-1493]
parent 6c9ad30e
...@@ -45,7 +45,7 @@ class ABTestModule(ABTestFields, XModule): ...@@ -45,7 +45,7 @@ class ABTestModule(ABTestFields, XModule):
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs) super(ABTestModule, self).__init__(*args, **kwargs)
if self.group is None: if self.group is None:
self.group = group_from_value( self.group = group_from_value(
......
...@@ -50,7 +50,7 @@ class AnnotatableModule(AnnotatableFields, XModule): ...@@ -50,7 +50,7 @@ class AnnotatableModule(AnnotatableFields, XModule):
icon_class = 'annotatable' icon_class = 'annotatable'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs) super(AnnotatableModule, self).__init__(*args, **kwargs)
xmltree = etree.fromstring(self.data) xmltree = etree.fromstring(self.data)
......
...@@ -190,7 +190,7 @@ class CapaModule(CapaFields, XModule): ...@@ -190,7 +190,7 @@ class CapaModule(CapaFields, XModule):
""" """
Accepts the same arguments as xmodule.x_module:XModule.__init__ Accepts the same arguments as xmodule.x_module:XModule.__init__
""" """
XModule.__init__(self, *args, **kwargs) super(CapaModule, self).__init__(*args, **kwargs)
due_date = self.due due_date = self.due
......
...@@ -412,7 +412,7 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule): ...@@ -412,7 +412,7 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule):
See DEFAULT_DATA for a sample. See DEFAULT_DATA for a sample.
""" """
XModule.__init__(self, *args, **kwargs) super(CombinedOpenEndedModule, self).__init__(*args, **kwargs)
self.system.set('location', self.location) self.system.set('location', self.location)
......
...@@ -75,7 +75,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -75,7 +75,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
js_module_name = "Hinter" js_module_name = "Hinter"
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs) super(CrowdsourceHinterModule, self).__init__(*args, **kwargs)
# We need to know whether we are working with a FormulaResponse problem. # We need to know whether we are working with a FormulaResponse problem.
try: try:
responder = self.get_display_items()[0].lcp.responders.values()[0] responder = self.get_display_items()[0].lcp.responders.values()[0]
......
...@@ -39,7 +39,7 @@ class FolditModule(FolditFields, XModule): ...@@ -39,7 +39,7 @@ class FolditModule(FolditFields, XModule):
required_sublevel_half_credit="3" required_sublevel_half_credit="3"
show_leaderboard="false"/> show_leaderboard="false"/>
""" """
XModule.__init__(self, *args, **kwargs) super(FolditModule, self).__init__(*args, **kwargs)
self.due_time = self.due self.due_time = self.due
def is_complete(self): def is_complete(self):
......
...@@ -39,7 +39,7 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -39,7 +39,7 @@ class RandomizeModule(RandomizeFields, XModule):
modules. modules.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs) super(RandomizeModule, self).__init__(*args, **kwargs)
# NOTE: calling self.get_children() creates a circular reference-- # NOTE: calling self.get_children() creates a circular reference--
# it calls get_child_descriptors() internally, but that doesn't work until # it calls get_child_descriptors() internally, but that doesn't work until
......
...@@ -38,7 +38,7 @@ class SequenceModule(SequenceFields, XModule): ...@@ -38,7 +38,7 @@ class SequenceModule(SequenceFields, XModule):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs) super(SequenceModule, self).__init__(*args, **kwargs)
# if position is specified in system, then use that instead # if position is specified in system, then use that instead
if getattr(self.system, 'position', None) is not None: if getattr(self.system, 'position', None) is not None:
......
...@@ -133,7 +133,6 @@ class CapaFactory(object): ...@@ -133,7 +133,6 @@ class CapaFactory(object):
DictFieldData(field_data), DictFieldData(field_data),
ScopeIds(None, None, location, location), ScopeIds(None, None, location, location),
) )
system.xmodule_instance = module
if correct: if correct:
# TODO: probably better to actually set the internal state properly, but... # TODO: probably better to actually set the internal state properly, but...
......
...@@ -664,7 +664,6 @@ class CombinedOpenEndedModuleTest(unittest.TestCase): ...@@ -664,7 +664,6 @@ class CombinedOpenEndedModuleTest(unittest.TestCase):
static_data=self.static_data, static_data=self.static_data,
metadata=self.metadata, metadata=self.metadata,
instance_state=instance_state) instance_state=instance_state)
self.test_system.xmodule_instance = module
return combinedoe return combinedoe
def ai_state_reset(self, task_state, task_number=None): def ai_state_reset(self, task_state, task_number=None):
...@@ -717,6 +716,7 @@ class CombinedOpenEndedModuleTest(unittest.TestCase): ...@@ -717,6 +716,7 @@ class CombinedOpenEndedModuleTest(unittest.TestCase):
def test_state_pe_single(self): def test_state_pe_single(self):
self.ai_state_success(TEST_STATE_PE_SINGLE, iscore=0, tasks=[self.task_xml2]) self.ai_state_success(TEST_STATE_PE_SINGLE, iscore=0, tasks=[self.task_xml2])
class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
""" """
Test the student flow in the combined open ended xmodule Test the student flow in the combined open ended xmodule
...@@ -764,7 +764,6 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -764,7 +764,6 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
task_one_json = json.loads(self._module().task_states[0]) task_one_json = json.loads(self._module().task_states[0])
self.assertEqual(task_one_json['child_history'][0]['answer'], self.answer) self.assertEqual(task_one_json['child_history'][0]['answer'], self.answer)
@unittest.expectedFailure
def test_open_ended_flow_reset(self): def test_open_ended_flow_reset(self):
""" """
Test the flow of the module if we complete the self assessment step and then reset Test the flow of the module if we complete the self assessment step and then reset
...@@ -803,7 +802,6 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -803,7 +802,6 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
self._handle_ajax("reset", {}) self._handle_ajax("reset", {})
self.assertEqual(self._module().current_task_number, 0) self.assertEqual(self._module().current_task_number, 0)
@unittest.expectedFailure
def test_open_ended_flow_correct(self): def test_open_ended_flow_correct(self):
""" """
Test a two step problem where the student first goes through the self assessment step, and then the Test a two step problem where the student first goes through the self assessment step, and then the
...@@ -915,7 +913,6 @@ class OpenEndedModuleXmlAttemptTest(unittest.TestCase, DummyModulestore): ...@@ -915,7 +913,6 @@ class OpenEndedModuleXmlAttemptTest(unittest.TestCase, DummyModulestore):
def _module(self): def _module(self):
return self.get_module_from_location(self.problem_location, COURSE) return self.get_module_from_location(self.problem_location, COURSE)
@unittest.expectedFailure
def test_reset_fail(self): def test_reset_fail(self):
""" """
Test the flow of the module if we complete the self assessment step and then reset Test the flow of the module if we complete the self assessment step and then reset
......
...@@ -143,7 +143,6 @@ class CHModuleFactory(object): ...@@ -143,7 +143,6 @@ class CHModuleFactory(object):
return capa_module return capa_module
system.get_module = fake_get_module system.get_module = fake_get_module
module = CrowdsourceHinterModule(descriptor, system, DictFieldData(field_data), Mock()) module = CrowdsourceHinterModule(descriptor, system, DictFieldData(field_data), Mock())
system.xmodule_instance = module
return module return module
......
...@@ -288,7 +288,6 @@ class PeerGradingModuleLinkedTest(unittest.TestCase, DummyModulestore): ...@@ -288,7 +288,6 @@ class PeerGradingModuleLinkedTest(unittest.TestCase, DummyModulestore):
self.field_data, self.field_data,
self.scope_ids, self.scope_ids,
) )
test_system.xmodule_instance = peer_grading
return peer_grading return peer_grading
......
...@@ -31,9 +31,6 @@ class TimeLimitModule(TimeLimitFields, XModule): ...@@ -31,9 +31,6 @@ class TimeLimitModule(TimeLimitFields, XModule):
Wrapper module which imposes a time constraint for the completion of its child. Wrapper module which imposes a time constraint for the completion of its child.
''' '''
def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs)
# For a timed activity, we are only interested here # For a timed activity, we are only interested here
# in time-related accommodations, and these should be disjoint. # in time-related accommodations, and these should be disjoint.
# (For proctored exams, it is possible to have multiple accommodations # (For proctored exams, it is possible to have multiple accommodations
......
...@@ -16,9 +16,6 @@ class VerticalFields(object): ...@@ -16,9 +16,6 @@ class VerticalFields(object):
class VerticalModule(VerticalFields, XModule): class VerticalModule(VerticalFields, XModule):
''' Layout module for laying out submodules vertically.''' ''' Layout module for laying out submodules vertically.'''
def __init__(self, *args, **kwargs):
XModule.__init__(self, *args, **kwargs)
def student_view(self, context): def student_view(self, context):
fragment = Fragment() fragment = Fragment()
contents = [] contents = []
......
...@@ -392,6 +392,7 @@ class XModule(XModuleMixin, HTMLSnippet, XBlock): # pylint: disable=abstract-me ...@@ -392,6 +392,7 @@ class XModule(XModuleMixin, HTMLSnippet, XBlock): # pylint: disable=abstract-me
super(XModule, self).__init__(*args, **kwargs) super(XModule, self).__init__(*args, **kwargs)
self._loaded_children = None self._loaded_children = None
self.system = self.runtime self.system = self.runtime
self.runtime.xmodule_instance = self
def __unicode__(self): def __unicode__(self):
return u'<x_module(id={0})>'.format(self.id) return u'<x_module(id={0})>'.format(self.id)
...@@ -737,7 +738,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock): ...@@ -737,7 +738,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
assert self.xmodule_runtime.error_descriptor_class is not None assert self.xmodule_runtime.error_descriptor_class is not None
if self.xmodule_runtime.xmodule_instance is None: if self.xmodule_runtime.xmodule_instance is None:
try: try:
self.xmodule_runtime.xmodule_instance = self.xmodule_runtime.construct_xblock_from_class( self.xmodule_runtime.construct_xblock_from_class(
self.module_class, self.module_class,
descriptor=self, descriptor=self,
scope_ids=self.scope_ids, scope_ids=self.scope_ids,
...@@ -1041,6 +1042,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs ...@@ -1041,6 +1042,7 @@ class ModuleSystem(ConfigurableFragmentWrapper, Runtime): # pylint: disable=abs
""" """
The url prefix to be used by XModules to call into handle_ajax The url prefix to be used by XModules to call into handle_ajax
""" """
assert self.xmodule_instance is not None
return self.handler_url(self.xmodule_instance, 'xmodule_handler', '', '').rstrip('/?') return self.handler_url(self.xmodule_instance, 'xmodule_handler', '', '').rstrip('/?')
......
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