Commit 970a7f09 by Felix Sun

Fixed some docstring formatting things.

Expanded test coverage a little.
parent b6760ceb
...@@ -129,11 +129,11 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -129,11 +129,11 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Called by hinter javascript after a problem is graded as incorrect. Called by hinter javascript after a problem is graded as incorrect.
Args: Args:
get -- must be interpretable by capa_answer_to_str. `get` -- must be interpretable by capa_answer_to_str.
Output keys: Output keys:
- best_hint is the hint text with the most votes. - 'best_hint' is the hint text with the most votes.
- rand_hint_1 and rand_hint_2 are two random hints to the answer in get. - 'rand_hint_1' and 'rand_hint_2' are two random hints to the answer in `get`.
- answer is the parsed answer that was submitted. - 'answer' is the parsed answer that was submitted.
""" """
answer = self.capa_answer_to_str(get) answer = self.capa_answer_to_str(get)
# Look for a hint to give. # Look for a hint to give.
...@@ -176,10 +176,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -176,10 +176,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
The student got it correct. Ask him to vote on hints, or submit a hint. The student got it correct. Ask him to vote on hints, or submit a hint.
Args: Args:
get -- not actually used. (It is assumed that the answer is correct.) `get` -- not actually used. (It is assumed that the answer is correct.)
Output keys: Output keys:
- index_to_hints maps previous answer indices to hints that the user saw earlier. - 'index_to_hints' maps previous answer indices to hints that the user saw earlier.
- index_to_answer maps previous answer indices to the actual answer submitted. - 'index_to_answer' maps previous answer indices to the actual answer submitted.
""" """
# The student got it right. # The student got it right.
# Did he submit at least one wrong answer? # Did he submit at least one wrong answer?
...@@ -217,10 +217,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -217,10 +217,10 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Tally a user's vote on his favorite hint. Tally a user's vote on his favorite hint.
Args: Args:
get -- expected to have the following keys: `get` -- expected to have the following keys:
'answer': ans_no (index in previous_answers) 'answer': ans_no (index in previous_answers)
'hint': hint_pk 'hint': hint_pk
Returns key hint_and_votes, a list of (hint_text, #votes) pairs. Returns key 'hint_and_votes', a list of (hint_text, #votes) pairs.
""" """
if self.user_voted: if self.user_voted:
return json.dumps({'contents': 'Sorry, but you have already voted!'}) return json.dumps({'contents': 'Sorry, but you have already voted!'})
...@@ -250,7 +250,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -250,7 +250,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
Take a hint submission and add it to the database. Take a hint submission and add it to the database.
Args: Args:
get -- expected to have the following keys: `get` -- expected to have the following keys:
'answer': answer index in previous_answers 'answer': answer index in previous_answers
'hint': text of the new hint that the user is adding 'hint': text of the new hint that the user is adding
Returns a thank-you message. Returns a thank-you message.
......
...@@ -192,6 +192,21 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -192,6 +192,21 @@ class CrowdsourceHinterTest(unittest.TestCase):
self.assertTrue('This is supposed to be test html.' in out_html) self.assertTrue('This is supposed to be test html.' in out_html)
self.assertTrue('this/is/a/fake/ajax/url' in out_html) self.assertTrue('this/is/a/fake/ajax/url' in out_html)
def test_gethtml_nochild(self):
"""
get_html, except the module has no child :( Should return a polite
error message.
"""
m = CHModuleFactory.create()
def fake_get_display_items():
"""
Returns no children.
"""
return []
m.get_display_items = fake_get_display_items
out_html = m.get_html()
self.assertTrue('Error in loading crowdsourced hinter' in out_html)
def test_gethtml_multiple(self): def test_gethtml_multiple(self):
""" """
Makes sure that multiple crowdsourced hinters play nice, when get_html Makes sure that multiple crowdsourced hinters play nice, when get_html
......
...@@ -54,17 +54,17 @@ def get_hints(request, course_id, field): ...@@ -54,17 +54,17 @@ def get_hints(request, course_id, field):
Load all of the hints submitted to the course. Load all of the hints submitted to the course.
Args: Args:
request -- Django request object. `request` -- Django request object.
course_id -- The course id, like 'Me/19.002/test_course' `course_id` -- The course id, like 'Me/19.002/test_course'
field -- Either 'hints' or 'mod_queue'; specifies which set of hints to load. `field` -- Either 'hints' or 'mod_queue'; specifies which set of hints to load.
Keys in returned dict: Keys in returned dict:
- field: Same as input - 'field': Same as input
- other_field: 'mod_queue' if field == 'hints'; and vice-versa. - 'other_field': 'mod_queue' if `field` == 'hints'; and vice-versa.
- field_label, other_field_label: English name for the above. - 'field_label', 'other_field_label': English name for the above.
- all_hints: A list of [answer, pk dict] pairs, representing all hints. - 'all_hints': A list of [answer, pk dict] pairs, representing all hints.
Sorted by answer. Sorted by answer.
- id_to_name: A dictionary mapping problem id to problem name. - 'id_to_name': A dictionary mapping problem id to problem name.
""" """
if field == 'mod_queue': if field == 'mod_queue':
other_field = 'hints' other_field = 'hints'
...@@ -92,8 +92,8 @@ def get_hints(request, course_id, field): ...@@ -92,8 +92,8 @@ def get_hints(request, course_id, field):
def answer_sorter(thing): def answer_sorter(thing):
""" """
thing is a tuple, where thing[0] contains an answer, and thing[1] contains `thing` is a tuple, where `thing[0]` contains an answer, and `thing[1]` contains
a dict of hints. This function returns an index based on thing[0], which a dict of hints. This function returns an index based on `thing[0]`, which
is used as a key to sort the list of things. is used as a key to sort the list of things.
""" """
try: try:
...@@ -131,10 +131,10 @@ def delete_hints(request, course_id, field): ...@@ -131,10 +131,10 @@ def delete_hints(request, course_id, field):
""" """
Deletes the hints specified. Deletes the hints specified.
request.POST contains some fields keyed by integers. Each such field contains a `request.POST` contains some fields keyed by integers. Each such field contains a
[problem_defn_id, answer, pk] tuple. These tuples specify the hints to be deleted. [problem_defn_id, answer, pk] tuple. These tuples specify the hints to be deleted.
Example request.POST: Example `request.POST`:
{'op': 'delete_hints', {'op': 'delete_hints',
'field': 'mod_queue', 'field': 'mod_queue',
1: ['problem_whatever', '42.0', '3'], 1: ['problem_whatever', '42.0', '3'],
...@@ -158,8 +158,8 @@ def change_votes(request, course_id, field): ...@@ -158,8 +158,8 @@ def change_votes(request, course_id, field):
""" """
Updates the number of votes. Updates the number of votes.
The numbered fields of request.POST contain [problem_id, answer, pk, new_votes] tuples. The numbered fields of `request.POST` contain [problem_id, answer, pk, new_votes] tuples.
- Very similar to delete_hints. Is there a way to merge them? Nah, too complicated. - Very similar to `delete_hints`. Is there a way to merge them? Nah, too complicated.
""" """
for key in request.POST: for key in request.POST:
...@@ -176,7 +176,7 @@ def change_votes(request, course_id, field): ...@@ -176,7 +176,7 @@ def change_votes(request, course_id, field):
def add_hint(request, course_id, field): def add_hint(request, course_id, field):
""" """
Add a new hint. request.POST: Add a new hint. `request.POST`:
op op
field field
problem - The problem id problem - The problem id
......
...@@ -74,13 +74,17 @@ class HintManagerTest(ModuleStoreTestCase): ...@@ -74,13 +74,17 @@ class HintManagerTest(ModuleStoreTestCase):
rejected. rejected.
""" """
out = self.c.post(self.url, {'op': 'delete hints', 'field': 'all your private data'}) out = self.c.post(self.url, {'op': 'delete hints', 'field': 'all your private data'})
# Keep this around for reference - might be useful later.
# request = RequestFactory()
# post = request.post(self.url, {'op': 'delete hints', 'field': 'all your private data'})
# out = view.hint_manager(post, 'Me/19.002/test_course')
print out print out
self.assertTrue('an invalid field was accessed' in out.content) self.assertTrue('an invalid field was accessed' in out.content)
def test_switchfields(self):
"""
Checks that the op: 'switch fields' POST request works.
"""
out = self.c.post(self.url, {'op': 'switch fields', 'field': 'mod_queue'})
print out
self.assertTrue('Hint 2' in out.content)
def test_gethints(self): def test_gethints(self):
""" """
Checks that gethints returns the right data. Checks that gethints returns the right data.
...@@ -93,6 +97,21 @@ class HintManagerTest(ModuleStoreTestCase): ...@@ -93,6 +97,21 @@ class HintManagerTest(ModuleStoreTestCase):
expected = {self.problem_id: [(u'2.0', {u'2': [u'Hint 2', 1]})]} expected = {self.problem_id: [(u'2.0', {u'2': [u'Hint 2', 1]})]}
self.assertTrue(out['all_hints'] == expected) self.assertTrue(out['all_hints'] == expected)
def test_gethints_other(self):
"""
Same as above, with hints instead of mod_queue
"""
request = RequestFactory()
post = request.post(self.url, {'field': 'hints'})
out = view.get_hints(post, self.course_id, 'hints')
print out
self.assertTrue(out['other_field'] == 'mod_queue')
expected = {self.problem_id: [('1.0', {'1': ['Hint 1', 2],
'3': ['Hint 3', 12]}),
('2.0', {'4': ['Hint 4', 3]})
]}
self.assertTrue(out['all_hints'] == expected)
def test_deletehints(self): def test_deletehints(self):
""" """
Checks that delete_hints deletes the right stuff. Checks that delete_hints deletes the right stuff.
...@@ -119,7 +138,35 @@ class HintManagerTest(ModuleStoreTestCase): ...@@ -119,7 +138,35 @@ class HintManagerTest(ModuleStoreTestCase):
print json.loads(problem_hints)['1.0']['1'] print json.loads(problem_hints)['1.0']['1']
self.assertTrue(json.loads(problem_hints)['1.0']['1'][1] == 5) self.assertTrue(json.loads(problem_hints)['1.0']['1'][1] == 5)
def test_addhint(self):
"""
Check that instructors can add new hints.
"""
request = RequestFactory()
post = request.post(self.url, {'field': 'mod_queue',
'op': 'add hint',
'problem': self.problem_id,
'answer': '3.14',
'hint': 'This is a new hint.'})
view.add_hint(post, self.course_id, 'mod_queue')
problem_hints = XModuleContentField.objects.get(field_name='mod_queue', definition_id=self.problem_id).value
self.assertTrue('3.14' in json.loads(problem_hints))
def test_approve(self):
"""
Check that instructors can approve hints. (Move them
from the mod_queue to the hints.)
"""
request = RequestFactory()
post = request.post(self.url, {'field': 'mod_queue',
'op': 'approve',
1: [self.problem_id, '2.0', '2']})
view.approve(post, self.course_id, 'mod_queue')
problem_hints = XModuleContentField.objects.get(field_name='mod_queue', definition_id=self.problem_id).value
self.assertTrue('2.0' not in json.loads(problem_hints) or len(json.loads(problem_hints)['2.0']) == 0)
problem_hints = XModuleContentField.objects.get(field_name='hints', definition_id=self.problem_id).value
self.assertTrue(json.loads(problem_hints)['2.0']['2'] == ['Hint 2', 1])
self.assertTrue(len(json.loads(problem_hints)['2.0']) == 2)
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