Commit f4d84e67 by Ned Batchelder

Build the XModuleSystem anew for each test so we can fiddle with it safely.

parent 0ba4b680
...@@ -22,21 +22,27 @@ def calledback_url(dispatch = 'score_update'): ...@@ -22,21 +22,27 @@ def calledback_url(dispatch = 'score_update'):
xqueue_interface = MagicMock() xqueue_interface = MagicMock()
xqueue_interface.send_to_queue.return_value = (0, 'Success!') xqueue_interface.send_to_queue.return_value = (0, 'Success!')
test_system = Mock( def test_system():
ajax_url='courses/course_id/modx/a_location', """
track_function=Mock(), Construct a mock ModuleSystem instance.
get_module=Mock(),
render_template=tst_render_template, """
replace_urls=Mock(), the_system = Mock(
user=Mock(), ajax_url='courses/course_id/modx/a_location',
filestore=fs.osfs.OSFS(os.path.join(TEST_DIR, "test_files")), track_function=Mock(),
debug=True, get_module=Mock(),
xqueue={'interface': xqueue_interface, 'construct_callback': calledback_url, 'default_queuename': 'testqueue', 'waittime': 10}, render_template=tst_render_template,
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"), replace_urls=Mock(),
anonymous_student_id='student', user=Mock(),
cache=None, filestore=fs.osfs.OSFS(os.path.join(TEST_DIR, "test_files")),
) debug=True,
xqueue={'interface': xqueue_interface, 'construct_callback': calledback_url, 'default_queuename': 'testqueue', 'waittime': 10},
def new_loncapa_problem(xml): node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
anonymous_student_id='student',
cache=None,
)
return the_system
def new_loncapa_problem(xml, system=None):
"""Construct a `LoncapaProblem` suitable for unit tests.""" """Construct a `LoncapaProblem` suitable for unit tests."""
return LoncapaProblem(xml, id='1', seed=723, system=test_system) return LoncapaProblem(xml, id='1', seed=723, system=system or test_system())
...@@ -26,7 +26,7 @@ class HelperTest(unittest.TestCase): ...@@ -26,7 +26,7 @@ class HelperTest(unittest.TestCase):
Make sure that our helper function works! Make sure that our helper function works!
''' '''
def check(self, d): def check(self, d):
xml = etree.XML(test_system.render_template('blah', d)) xml = etree.XML(test_system().render_template('blah', d))
self.assertEqual(d, extract_context(xml)) self.assertEqual(d, extract_context(xml))
def test_extract_context(self): def test_extract_context(self):
...@@ -46,11 +46,11 @@ class SolutionRenderTest(unittest.TestCase): ...@@ -46,11 +46,11 @@ class SolutionRenderTest(unittest.TestCase):
xml_str = """<solution id="solution_12">{s}</solution>""".format(s=solution) xml_str = """<solution id="solution_12">{s}</solution>""".format(s=solution)
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
renderer = lookup_tag('solution')(test_system, element) renderer = lookup_tag('solution')(test_system(), element)
self.assertEqual(renderer.id, 'solution_12') self.assertEqual(renderer.id, 'solution_12')
# our test_system "renders" templates to a div with the repr of the context # Our test_system "renders" templates to a div with the repr of the context.
xml = renderer.get_html() xml = renderer.get_html()
context = extract_context(xml) context = extract_context(xml)
self.assertEqual(context, {'id': 'solution_12'}) self.assertEqual(context, {'id': 'solution_12'})
...@@ -65,7 +65,7 @@ class MathRenderTest(unittest.TestCase): ...@@ -65,7 +65,7 @@ class MathRenderTest(unittest.TestCase):
xml_str = """<math>{tex}</math>""".format(tex=latex_in) xml_str = """<math>{tex}</math>""".format(tex=latex_in)
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
renderer = lookup_tag('math')(test_system, element) renderer = lookup_tag('math')(test_system(), element)
self.assertEqual(renderer.mathstr, mathjax_out) self.assertEqual(renderer.mathstr, mathjax_out)
......
...@@ -11,6 +11,10 @@ from . import test_system, new_loncapa_problem ...@@ -11,6 +11,10 @@ from . import test_system, new_loncapa_problem
class CapaHtmlRenderTest(unittest.TestCase): class CapaHtmlRenderTest(unittest.TestCase):
def setUp(self):
super(CapaHtmlRenderTest, self).setUp()
self.system = test_system()
def test_blank_problem(self): def test_blank_problem(self):
""" """
It's important that blank problems don't break, since that's It's important that blank problems don't break, since that's
...@@ -38,7 +42,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -38,7 +42,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
""") """)
# Create the problem # Create the problem
problem = new_loncapa_problem(xml_str) problem = new_loncapa_problem(xml_str, system=self.system)
# Render the HTML # Render the HTML
rendered_html = etree.XML(problem.get_html()) rendered_html = etree.XML(problem.get_html())
...@@ -48,9 +52,6 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -48,9 +52,6 @@ class CapaHtmlRenderTest(unittest.TestCase):
self.assertEqual(test_element.tag, "test") self.assertEqual(test_element.tag, "test")
self.assertEqual(test_element.text, "Test include") self.assertEqual(test_element.text, "Test include")
def test_process_outtext(self): def test_process_outtext(self):
# Generate some XML with <startouttext /> and <endouttext /> # Generate some XML with <startouttext /> and <endouttext />
xml_str = textwrap.dedent(""" xml_str = textwrap.dedent("""
...@@ -116,11 +117,12 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -116,11 +117,12 @@ class CapaHtmlRenderTest(unittest.TestCase):
xml_str = StringResponseXMLFactory().build_xml(**kwargs) xml_str = StringResponseXMLFactory().build_xml(**kwargs)
# Mock out the template renderer # Mock out the template renderer
test_system.render_template = mock.Mock() the_system = test_system()
test_system.render_template.return_value = "<div>Input Template Render</div>" the_system.render_template = mock.Mock()
the_system.render_template.return_value = "<div>Input Template Render</div>"
# Create the problem and render the HTML # Create the problem and render the HTML
problem = new_loncapa_problem(xml_str) problem = new_loncapa_problem(xml_str, system=the_system)
rendered_html = etree.XML(problem.get_html()) rendered_html = etree.XML(problem.get_html())
# Expect problem has been turned into a <div> # Expect problem has been turned into a <div>
...@@ -165,7 +167,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -165,7 +167,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
mock.call('textline.html', expected_textline_context), mock.call('textline.html', expected_textline_context),
mock.call('solutionspan.html', expected_solution_context)] mock.call('solutionspan.html', expected_solution_context)]
self.assertEqual(test_system.render_template.call_args_list, self.assertEqual(the_system.render_template.call_args_list,
expected_calls) expected_calls)
...@@ -226,7 +228,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -226,7 +228,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
self.assertEqual(span_element.get('attr'), "TEST") self.assertEqual(span_element.get('attr'), "TEST")
def _create_test_file(self, path, content_str): def _create_test_file(self, path, content_str):
test_fp = test_system.filestore.open(path, "w") test_fp = self.system.filestore.open(path, "w")
test_fp.write(content_str) test_fp.write(content_str)
test_fp.close() test_fp.close()
......
...@@ -45,7 +45,7 @@ class OptionInputTest(unittest.TestCase): ...@@ -45,7 +45,7 @@ class OptionInputTest(unittest.TestCase):
state = {'value': 'Down', state = {'value': 'Down',
'id': 'sky_input', 'id': 'sky_input',
'status': 'answered'} 'status': 'answered'}
option_input = lookup_tag('optioninput')(test_system, element, state) option_input = lookup_tag('optioninput')(test_system(), element, state)
context = option_input._get_render_context() context = option_input._get_render_context()
...@@ -92,7 +92,7 @@ class ChoiceGroupTest(unittest.TestCase): ...@@ -92,7 +92,7 @@ class ChoiceGroupTest(unittest.TestCase):
'id': 'sky_input', 'id': 'sky_input',
'status': 'answered'} 'status': 'answered'}
the_input = lookup_tag(tag)(test_system, element, state) the_input = lookup_tag(tag)(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -142,7 +142,7 @@ class JavascriptInputTest(unittest.TestCase): ...@@ -142,7 +142,7 @@ class JavascriptInputTest(unittest.TestCase):
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
state = {'value': '3', } state = {'value': '3', }
the_input = lookup_tag('javascriptinput')(test_system, element, state) the_input = lookup_tag('javascriptinput')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -170,7 +170,7 @@ class TextLineTest(unittest.TestCase): ...@@ -170,7 +170,7 @@ class TextLineTest(unittest.TestCase):
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
state = {'value': 'BumbleBee', } state = {'value': 'BumbleBee', }
the_input = lookup_tag('textline')(test_system, element, state) the_input = lookup_tag('textline')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -198,7 +198,7 @@ class TextLineTest(unittest.TestCase): ...@@ -198,7 +198,7 @@ class TextLineTest(unittest.TestCase):
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
state = {'value': 'BumbleBee', } state = {'value': 'BumbleBee', }
the_input = lookup_tag('textline')(test_system, element, state) the_input = lookup_tag('textline')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -236,7 +236,7 @@ class TextLineTest(unittest.TestCase): ...@@ -236,7 +236,7 @@ class TextLineTest(unittest.TestCase):
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
state = {'value': 'BumbleBee', } state = {'value': 'BumbleBee', }
the_input = lookup_tag('textline')(test_system, element, state) the_input = lookup_tag('textline')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -274,7 +274,7 @@ class FileSubmissionTest(unittest.TestCase): ...@@ -274,7 +274,7 @@ class FileSubmissionTest(unittest.TestCase):
'status': 'incomplete', 'status': 'incomplete',
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
input_class = lookup_tag('filesubmission') input_class = lookup_tag('filesubmission')
the_input = input_class(test_system, element, state) the_input = input_class(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -319,7 +319,7 @@ class CodeInputTest(unittest.TestCase): ...@@ -319,7 +319,7 @@ class CodeInputTest(unittest.TestCase):
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
input_class = lookup_tag('codeinput') input_class = lookup_tag('codeinput')
the_input = input_class(test_system, element, state) the_input = input_class(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -368,7 +368,7 @@ class MatlabTest(unittest.TestCase): ...@@ -368,7 +368,7 @@ class MatlabTest(unittest.TestCase):
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
self.input_class = lookup_tag('matlabinput') self.input_class = lookup_tag('matlabinput')
self.the_input = self.input_class(test_system, elt, state) self.the_input = self.input_class(test_system(), elt, state)
def test_rendering(self): def test_rendering(self):
context = self.the_input._get_render_context() context = self.the_input._get_render_context()
...@@ -396,7 +396,7 @@ class MatlabTest(unittest.TestCase): ...@@ -396,7 +396,7 @@ class MatlabTest(unittest.TestCase):
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
the_input = self.input_class(test_system, elt, state) the_input = self.input_class(test_system(), elt, state)
context = the_input._get_render_context() context = the_input._get_render_context()
expected = {'id': 'prob_1_2', expected = {'id': 'prob_1_2',
...@@ -423,7 +423,7 @@ class MatlabTest(unittest.TestCase): ...@@ -423,7 +423,7 @@ class MatlabTest(unittest.TestCase):
} }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
the_input = self.input_class(test_system, elt, state) the_input = self.input_class(test_system(), elt, state)
context = the_input._get_render_context() context = the_input._get_render_context()
expected = {'id': 'prob_1_2', expected = {'id': 'prob_1_2',
'value': 'print "good evening"', 'value': 'print "good evening"',
...@@ -448,7 +448,7 @@ class MatlabTest(unittest.TestCase): ...@@ -448,7 +448,7 @@ class MatlabTest(unittest.TestCase):
} }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
the_input = self.input_class(test_system, elt, state) the_input = self.input_class(test_system(), elt, state)
context = the_input._get_render_context() context = the_input._get_render_context()
expected = {'id': 'prob_1_2', expected = {'id': 'prob_1_2',
'value': 'print "good evening"', 'value': 'print "good evening"',
...@@ -470,7 +470,7 @@ class MatlabTest(unittest.TestCase): ...@@ -470,7 +470,7 @@ class MatlabTest(unittest.TestCase):
get = {'submission': 'x = 1234;'} get = {'submission': 'x = 1234;'}
response = self.the_input.handle_ajax("plot", get) response = self.the_input.handle_ajax("plot", get)
test_system.xqueue['interface'].send_to_queue.assert_called_with(header=ANY, body=ANY) test_system().xqueue['interface'].send_to_queue.assert_called_with(header=ANY, body=ANY)
self.assertTrue(response['success']) self.assertTrue(response['success'])
self.assertTrue(self.the_input.input_state['queuekey'] is not None) self.assertTrue(self.the_input.input_state['queuekey'] is not None)
...@@ -479,13 +479,12 @@ class MatlabTest(unittest.TestCase): ...@@ -479,13 +479,12 @@ class MatlabTest(unittest.TestCase):
def test_plot_data_failure(self): def test_plot_data_failure(self):
get = {'submission': 'x = 1234;'} get = {'submission': 'x = 1234;'}
error_message = 'Error message!' error_message = 'Error message!'
test_system.xqueue['interface'].send_to_queue.return_value = (1, error_message) test_system().xqueue['interface'].send_to_queue.return_value = (1, error_message)
response = self.the_input.handle_ajax("plot", get) response = self.the_input.handle_ajax("plot", get)
self.assertFalse(response['success']) self.assertFalse(response['success'])
self.assertEqual(response['message'], error_message) self.assertEqual(response['message'], error_message)
self.assertTrue('queuekey' not in self.the_input.input_state) self.assertTrue('queuekey' not in self.the_input.input_state)
self.assertTrue('queuestate' not in self.the_input.input_state) self.assertTrue('queuestate' not in self.the_input.input_state)
test_system.xqueue['interface'].send_to_queue.return_value = (0, 'Success!')
def test_ungraded_response_success(self): def test_ungraded_response_success(self):
queuekey = 'abcd' queuekey = 'abcd'
...@@ -496,7 +495,7 @@ class MatlabTest(unittest.TestCase): ...@@ -496,7 +495,7 @@ class MatlabTest(unittest.TestCase):
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
the_input = self.input_class(test_system, elt, state) the_input = self.input_class(test_system(), elt, state)
inner_msg = 'hello!' inner_msg = 'hello!'
queue_msg = json.dumps({'msg': inner_msg}) queue_msg = json.dumps({'msg': inner_msg})
...@@ -514,7 +513,7 @@ class MatlabTest(unittest.TestCase): ...@@ -514,7 +513,7 @@ class MatlabTest(unittest.TestCase):
'feedback': {'message': '3'}, } 'feedback': {'message': '3'}, }
elt = etree.fromstring(self.xml) elt = etree.fromstring(self.xml)
the_input = self.input_class(test_system, elt, state) the_input = self.input_class(test_system(), elt, state)
inner_msg = 'hello!' inner_msg = 'hello!'
queue_msg = json.dumps({'msg': inner_msg}) queue_msg = json.dumps({'msg': inner_msg})
...@@ -553,7 +552,7 @@ class SchematicTest(unittest.TestCase): ...@@ -553,7 +552,7 @@ class SchematicTest(unittest.TestCase):
state = {'value': value, state = {'value': value,
'status': 'unsubmitted'} 'status': 'unsubmitted'}
the_input = lookup_tag('schematic')(test_system, element, state) the_input = lookup_tag('schematic')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -592,7 +591,7 @@ class ImageInputTest(unittest.TestCase): ...@@ -592,7 +591,7 @@ class ImageInputTest(unittest.TestCase):
state = {'value': value, state = {'value': value,
'status': 'unsubmitted'} 'status': 'unsubmitted'}
the_input = lookup_tag('imageinput')(test_system, element, state) the_input = lookup_tag('imageinput')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -643,7 +642,7 @@ class CrystallographyTest(unittest.TestCase): ...@@ -643,7 +642,7 @@ class CrystallographyTest(unittest.TestCase):
state = {'value': value, state = {'value': value,
'status': 'unsubmitted'} 'status': 'unsubmitted'}
the_input = lookup_tag('crystallography')(test_system, element, state) the_input = lookup_tag('crystallography')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -681,7 +680,7 @@ class VseprTest(unittest.TestCase): ...@@ -681,7 +680,7 @@ class VseprTest(unittest.TestCase):
state = {'value': value, state = {'value': value,
'status': 'unsubmitted'} 'status': 'unsubmitted'}
the_input = lookup_tag('vsepr_input')(test_system, element, state) the_input = lookup_tag('vsepr_input')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
...@@ -708,7 +707,7 @@ class ChemicalEquationTest(unittest.TestCase): ...@@ -708,7 +707,7 @@ class ChemicalEquationTest(unittest.TestCase):
element = etree.fromstring(xml_str) element = etree.fromstring(xml_str)
state = {'value': 'H2OYeah', } state = {'value': 'H2OYeah', }
self.the_input = lookup_tag('chemicalequationinput')(test_system, element, state) self.the_input = lookup_tag('chemicalequationinput')(test_system(), element, state)
def test_rendering(self): def test_rendering(self):
''' Verify that the render context matches the expected render context''' ''' Verify that the render context matches the expected render context'''
...@@ -783,7 +782,7 @@ class DragAndDropTest(unittest.TestCase): ...@@ -783,7 +782,7 @@ class DragAndDropTest(unittest.TestCase):
] ]
} }
the_input = lookup_tag('drag_and_drop_input')(test_system, element, state) the_input = lookup_tag('drag_and_drop_input')(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
expected = {'id': 'prob_1_2', expected = {'id': 'prob_1_2',
...@@ -832,7 +831,7 @@ class AnnotationInputTest(unittest.TestCase): ...@@ -832,7 +831,7 @@ class AnnotationInputTest(unittest.TestCase):
tag = 'annotationinput' tag = 'annotationinput'
the_input = lookup_tag(tag)(test_system, element, state) the_input = lookup_tag(tag)(test_system(), element, state)
context = the_input._get_render_context() context = the_input._get_render_context()
......
...@@ -33,15 +33,14 @@ def test_system(): ...@@ -33,15 +33,14 @@ def test_system():
""" """
Construct a test ModuleSystem instance. Construct a test ModuleSystem instance.
By default, the render_template() method simply returns By default, the render_template() method simply returns the context it is
the context it is passed as a string. passed as a string. You can override this behavior by monkey patching::
You can override this behavior by monkey patching:
system = test_system() system = test_system()
system.render_template = my_render_func system.render_template = my_render_func
where `my_render_func` is a function of the form my_render_func(template, context).
where my_render_func is a function of the form
my_render_func(template, context)
""" """
return ModuleSystem( return ModuleSystem(
ajax_url='courses/course_id/modx/a_location', ajax_url='courses/course_id/modx/a_location',
......
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