From 0e4d2ff8238fa4e75eaf80708f8ad3190f4e3615 Mon Sep 17 00:00:00 2001 From: Hamza Farooq <42243411+HamzaIbnFarooq@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:18:52 +0500 Subject: [PATCH] fix: adds default texts for missing answer texts in capa problems to fix response report generation If an author has created a capa problem like an mcqs or something similar without providing answer text to an option and some learner selected that option then the response report generation will fail due to that missing answer text. The current commit will add default text to be substituted and prevents report generation crash. --- common/lib/capa/capa/capa_problem.py | 18 ++++++--- .../lib/capa/capa/tests/test_capa_problem.py | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 84af4db4b6..ee2c9967c6 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -669,11 +669,17 @@ class LoncapaProblem(object): answer_id=answer_id, choice_number=current_answer )) - assert len(elems) == 1 - choicegroup = elems[0].getparent() - input_cls = inputtypes.registry.get_class_for_tag(choicegroup.tag) - choices_map = dict(input_cls.extract_choices(choicegroup, self.capa_system.i18n, text_only=True)) - answer_text = choices_map[current_answer] + if len(elems) == 0: + log.warning("Answer Text Missing for answer id: %s and choice number: %s", answer_id, current_answer) + answer_text = "Answer Text Missing" + elif len(elems) == 1: + choicegroup = elems[0].getparent() + input_cls = inputtypes.registry.get_class_for_tag(choicegroup.tag) + choices_map = dict(input_cls.extract_choices(choicegroup, self.capa_system.i18n, text_only=True)) + answer_text = choices_map.get(current_answer, "Answer Text Missing") + else: + log.warning("Multiple answers found for answer id: %s and choice number: %s", answer_id, current_answer) + answer_text = "Multiple answers found" elif isinstance(current_answer, six.string_types): # Already a string with the answer @@ -682,7 +688,7 @@ class LoncapaProblem(object): else: raise NotImplementedError() - return answer_text + return answer_text or "Answer Text Missing" def do_targeted_feedback(self, tree): """ diff --git a/common/lib/capa/capa/tests/test_capa_problem.py b/common/lib/capa/capa/tests/test_capa_problem.py index f4cbf8eb2a..9ff748618d 100644 --- a/common/lib/capa/capa/tests/test_capa_problem.py +++ b/common/lib/capa/capa/tests/test_capa_problem.py @@ -627,6 +627,43 @@ class CAPAProblemReportHelpersTest(unittest.TestCase): ) assert problem.find_answer_text(answer_id, choice_id) == answer_text + @ddt.data( + # Test for ChoiceResponse + ('1_2_1', 'choice_0', 'Answer Text Missing'), + ('1_2_1', 'choice_1', 'funny'), + # Test for MultipleChoiceResponse + ('1_3_1', 'choice_0', 'The iPad'), + ('1_3_1', 'choice_2', 'Answer Text Missing'), + ('1_3_1', ['choice_0', 'choice_1'], 'The iPad, Answer Text Missing'), + # Test for OptionResponse + ('1_4_1', '', 'Answer Text Missing'), + ) + @ddt.unpack + def test_find_answer_text_choices_with_missing_text(self, answer_id, choice_id, answer_text): + problem = new_loncapa_problem( + """ + + + + + funny + + + + + The iPad + + + + + + + + + """ + ) + assert problem.find_answer_text(answer_id, choice_id) == answer_text + @ddt.data( # Test for ChoiceResponse ('1_2_1', 'over-suspicious'),