Commit 4ee8111c by Felix Sun

Fixed monkey-patching persistent state bug.

parent 6b40c5cf
...@@ -126,7 +126,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -126,7 +126,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
-Lon-capa dependent. -Lon-capa dependent.
-Assumes that the problem only has one part. -Assumes that the problem only has one part.
""" """
return str(float(answer.values()[0])) return str(answer.values()[0])
def formula_answer_to_str(self, answer): def formula_answer_to_str(self, answer):
""" """
...@@ -207,7 +207,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -207,7 +207,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
""" """
try: try:
answer = self.answer_to_str(data) answer = self.answer_to_str(data)
except ValueError: except (ValueError, AttributeError):
# Sometimes, we get an answer that's just not parsable. Do nothing. # Sometimes, we get an answer that's just not parsable. Do nothing.
log.exception('Answer not parsable: ' + str(data)) log.exception('Answer not parsable: ' + str(data))
return return
......
...@@ -277,7 +277,7 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -277,7 +277,7 @@ class CrowdsourceHinterTest(unittest.TestCase):
mock_module = CHModuleFactory.create() mock_module = CHModuleFactory.create()
get = {'response1': '4'} get = {'response1': '4'}
parsed = mock_module.numerical_answer_to_str(get) parsed = mock_module.numerical_answer_to_str(get)
self.assertTrue(parsed == '4.0') self.assertTrue(parsed == '4')
def test_formula_answer_to_str(self): def test_formula_answer_to_str(self):
""" """
...@@ -342,12 +342,24 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -342,12 +342,24 @@ class CrowdsourceHinterTest(unittest.TestCase):
def test_gethint_unparsable(self): def test_gethint_unparsable(self):
""" """
Someone submits a hint that cannot be parsed into a float. Someone submits an answer that is in the wrong format.
- The answer should not be added to previous_answers. - The answer should not be added to previous_answers.
""" """
mock_module = CHModuleFactory.create() mock_module = CHModuleFactory.create()
old_answers = copy.deepcopy(mock_module.previous_answers) old_answers = copy.deepcopy(mock_module.previous_answers)
json_in = {'problem_name': 'fish'} json_in = 'blah'
out = mock_module.get_hint(json_in)
self.assertTrue(out is None)
self.assertTrue(mock_module.previous_answers == old_answers)
def test_gethint_signature_error(self):
"""
Someone submits an answer that cannot be calculated as a float.
Nothing should change.
"""
mock_module = CHModuleFactory.create()
old_answers = copy.deepcopy(mock_module.previous_answers)
json_in = {'problem1': 'fish'}
out = mock_module.get_hint(json_in) out = mock_module.get_hint(json_in)
self.assertTrue(out is None) self.assertTrue(out is None)
self.assertTrue(mock_module.previous_answers == old_answers) self.assertTrue(mock_module.previous_answers == old_answers)
......
...@@ -2,7 +2,7 @@ import json ...@@ -2,7 +2,7 @@ import json
from django.test.client import Client, RequestFactory from django.test.client import Client, RequestFactory
from django.test.utils import override_settings from django.test.utils import override_settings
from mock import MagicMock from mock import MagicMock, patch
from courseware.models import XModuleContentField from courseware.models import XModuleContentField
from courseware.tests.factories import ContentFactory from courseware.tests.factories import ContentFactory
...@@ -12,6 +12,8 @@ from student.tests.factories import UserFactory ...@@ -12,6 +12,8 @@ from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
import unittest
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class HintManagerTest(ModuleStoreTestCase): class HintManagerTest(ModuleStoreTestCase):
...@@ -140,12 +142,8 @@ class HintManagerTest(ModuleStoreTestCase): ...@@ -140,12 +142,8 @@ class HintManagerTest(ModuleStoreTestCase):
""" """
# Because add_hint accesses the xmodule, this test requires a bunch # Because add_hint accesses the xmodule, this test requires a bunch
# of monkey patching. # of monkey patching.
import courseware.module_render as module_render
import courseware.model_data as model_data
hinter = MagicMock() hinter = MagicMock()
hinter.answer_signature = lambda string: string hinter.answer_signature = lambda string: string
module_render.get_module = MagicMock(return_value=hinter)
model_data.ModelDataCache = MagicMock(return_value=None)
request = RequestFactory() request = RequestFactory()
post = request.post(self.url, {'field': 'mod_queue', post = request.post(self.url, {'field': 'mod_queue',
...@@ -154,14 +152,12 @@ class HintManagerTest(ModuleStoreTestCase): ...@@ -154,14 +152,12 @@ class HintManagerTest(ModuleStoreTestCase):
'answer': '3.14', 'answer': '3.14',
'hint': 'This is a new hint.'}) 'hint': 'This is a new hint.'})
post.user = 'fake user' post.user = 'fake user'
view.add_hint(post, self.course_id, 'mod_queue') with patch('courseware.module_render.get_module', MagicMock(return_value=hinter)):
with patch('courseware.model_data.ModelDataCache', MagicMock(return_value=None)):
view.add_hint(post, self.course_id, 'mod_queue')
problem_hints = XModuleContentField.objects.get(field_name='mod_queue', definition_id=self.problem_id).value problem_hints = XModuleContentField.objects.get(field_name='mod_queue', definition_id=self.problem_id).value
self.assertTrue('3.14' in json.loads(problem_hints)) self.assertTrue('3.14' in json.loads(problem_hints))
# Reload the things we monkey-patched.
reload(module_render)
reload(model_data)
def test_approve(self): def test_approve(self):
""" """
Check that instructors can approve hints. (Move them Check that instructors can approve hints. (Move them
......
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