From 66a49c7ae8f7e7c2350d1cf13a5bdf58d3bbd64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Warnon?= Date: Wed, 15 Mar 2023 14:02:32 +0000 Subject: [PATCH] [IMP] survey: scored questions need at least one correct answer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit slightly modifies the condition to be considered as a "scored question" for questions of type simple/multi choice. Now, to be scored, you need to have at least one correct answer. This notably allows not showing "incorrect answer: 1" when displaying survey statistics as there is no way to get it correctly. Task-3224732 closes odoo/odoo#115322 Signed-off-by: Stéphane Debauche (std) --- addons/survey/models/survey_question.py | 6 +-- .../survey/tests/test_certification_flow.py | 41 ++++++++++++++++--- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index 01f621907fa..a976772cabf 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -345,14 +345,14 @@ class SurveyQuestion(models.Model): or question.triggering_answer_id is None: question.triggering_answer_id = False - @api.depends('question_type', 'scoring_type', 'answer_date', 'answer_datetime', 'answer_numerical_box') + @api.depends('question_type', 'scoring_type', 'answer_date', 'answer_datetime', 'answer_numerical_box', 'suggested_answer_ids.is_correct') def _compute_is_scored_question(self): """ Computes whether a question "is scored" or not. Handles following cases: - inconsistent Boolean=None edge case that breaks tests => False - survey is not scored => False - 'date'/'datetime'/'numerical_box' question types w/correct answer => True (implied without user having to activate, except for numerical whose correct value is 0.0) - - 'simple_choice / multiple_choice': set to True even if logic is a bit different (coming from answers) + - 'simple_choice / multiple_choice': set to True if any of suggested answers are marked as correct - question_type isn't scoreable (note: choice questions scoring logic handled separately) => False """ for question in self: @@ -365,7 +365,7 @@ class SurveyQuestion(models.Model): elif question.question_type == 'numerical_box' and question.answer_numerical_box: question.is_scored_question = True elif question.question_type in ['simple_choice', 'multiple_choice']: - question.is_scored_question = True + question.is_scored_question = any(question.suggested_answer_ids.mapped('is_correct')) else: question.is_scored_question = False diff --git a/addons/survey/tests/test_certification_flow.py b/addons/survey/tests/test_certification_flow.py index 65205a5a531..2c97fc36dbd 100644 --- a/addons/survey/tests/test_certification_flow.py +++ b/addons/survey/tests/test_certification_flow.py @@ -115,6 +115,25 @@ class TestCertificationFlow(common.TestSurveyCommon, HttpCase): self.assertEqual(user_inputs.scoring_percentage, 87.5) self.assertTrue(user_inputs.scoring_success) + # assert statistics + statistics = user_inputs._prepare_statistics()[user_inputs] + total_statistics = statistics['totals'] + self.assertEqual( + sorted( + total_statistics, + key=lambda item: item['text'] + ), + sorted( + [ + {'text': 'Correct', 'count': 2}, + {'text': 'Partially', 'count': 1}, + {'text': 'Incorrect', 'count': 0}, + {'text': 'Unanswered', 'count': 0}, + ], + key=lambda item: item['text'] + ) + ) + # Check that the certification is still successful even if scoring_success_min of certification is modified certification.write({'scoring_success_min': 90}) self.assertTrue(user_inputs.scoring_success) @@ -197,12 +216,22 @@ class TestCertificationFlow(common.TestSurveyCommon, HttpCase): statistics = user_inputs._prepare_statistics()[user_inputs] total_statistics = statistics['totals'] - self.assertEqual(total_statistics, [ - {'text': 'Correct', 'count': 1}, - {'text': 'Partially', 'count': 0}, - {'text': 'Incorrect', 'count': 0}, - {'text': 'Unanswered', 'count': 0}, - ], "With the configured randomization, there should be exactly 1 correctly answered question and none skipped.") + self.assertEqual( + sorted( + total_statistics, + key=lambda item: item['text'] + ), + sorted( + [ + {'text': 'Correct', 'count': 1}, + {'text': 'Partially', 'count': 0}, + {'text': 'Incorrect', 'count': 0}, + {'text': 'Unanswered', 'count': 0}, + ], + key=lambda item: item['text'] + ), + "With the configured randomization, there should be exactly 1 correctly answered question and none skipped." + ) section_statistics = statistics['by_section'] self.assertEqual(section_statistics, {