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, {