diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index ff3204f7d45..9159871264d 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -393,6 +393,7 @@ class SurveyQuestion(models.Model): if question.question_type in ['simple_choice', 'multiple_choice', 'matrix']: answer_lines = all_lines.filtered( lambda line: line.answer_type == 'suggestion' or ( + line.skipped and not line.answer_type) or ( line.answer_type == 'char_box' and question.comment_count_as_answer) ) comment_line_ids = all_lines.filtered(lambda line: line.answer_type == 'char_box') diff --git a/addons/survey/models/survey_user_input.py b/addons/survey/models/survey_user_input.py index 8f006543fec..e6aab8ba70a 100644 --- a/addons/survey/models/survey_user_input.py +++ b/addons/survey/models/survey_user_input.py @@ -274,6 +274,12 @@ class SurveyUserInput(models.Model): def _save_line_choice(self, question, old_answers, answers, comment): if not (isinstance(answers, list)): answers = [answers] + + if not answers: + # add a False answer to force saving a skipped line + # this will make this question correctly considered as skipped in statistics + answers = [False] + vals_list = [] if question.question_type == 'simple_choice': @@ -291,6 +297,11 @@ class SurveyUserInput(models.Model): def _save_line_matrix(self, question, old_answers, answers, comment): vals_list = [] + if not answers and question.matrix_row_ids: + # add a False answer to force saving a skipped line + # this will make this question correctly considered as skipped in statistics + answers = {question.matrix_row_ids[0].id: [False]} + if answers: for row_key, row_answer in answers.items(): for answer in row_answer: diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py index b917606ad8a..1103b699422 100644 --- a/addons/survey/tests/common.py +++ b/addons/survey/tests/common.py @@ -147,7 +147,7 @@ class SurveyCase(common.TransactionCase): return self.env['survey.user_input.line'].create(base_alvals) # ------------------------------------------------------------ - # UTILS + # UTILS / CONTROLLER ENDPOINTS FLOWS # ------------------------------------------------------------ def _access_start(self, survey): @@ -216,6 +216,36 @@ class SurveyCase(common.TransactionCase): post_data.update(**additional_post_data) return post_data + # ------------------------------------------------------------ + # UTILS / TOOLS + # ------------------------------------------------------------ + + def _assert_skipped_question(self, question, survey_user): + statistics = question._prepare_statistics(survey_user.user_input_line_ids) + question_data = next( + (question_data + for question_data in statistics + if question_data.get('question') == question), + False + ) + self.assertTrue(bool(question_data)) + self.assertEqual(len(question_data.get('answer_input_skipped_ids')), 1) + + def _create_one_question_per_type(self): + all_questions = self.env['survey.question'] + for (question_type, dummy) in self.env['survey.question']._fields['question_type'].selection: + kwargs = {} + if question_type == 'multiple_choice': + kwargs['labels'] = [{'value': 'MChoice0'}, {'value': 'MChoice1'}] + elif question_type == 'simple_choice': + kwargs['labels'] = [] + elif question_type == 'matrix': + kwargs['labels'] = [{'value': 'Column0'}, {'value': 'Column1'}] + kwargs['labels_2'] = [{'value': 'Row0'}, {'value': 'Row1'}] + all_questions |= self._add_question(self.page_0, 'Q0', question_type, **kwargs) + + return all_questions + class TestSurveyCommon(SurveyCase): def setUp(self): diff --git a/addons/survey/tests/test_survey.py b/addons/survey/tests/test_survey.py index f1c2dfc602c..dc6469b1f56 100644 --- a/addons/survey/tests/test_survey.py +++ b/addons/survey/tests/test_survey.py @@ -11,17 +11,7 @@ class TestSurveyInternals(common.TestSurveyCommon): @users('survey_manager') def test_answer_validation_mandatory(self): """ For each type of question check that mandatory questions correctly check for complete answers """ - for (question_type, text) in self.env['survey.question']._fields['question_type'].selection: - kwargs = {} - if question_type == 'multiple_choice': - kwargs['labels'] = [{'value': 'MChoice0'}, {'value': 'MChoice1'}] - elif question_type == 'simple_choice': - kwargs['labels'] = [] - elif question_type == 'matrix': - kwargs['labels'] = [{'value': 'Column0'}, {'value': 'Column1'}] - kwargs['labels_2'] = [{'value': 'Row0'}, {'value': 'Row1'}] - question = self._add_question(self.page_0, 'Q0', question_type, **kwargs) - + for question in self._create_one_question_per_type(): self.assertDictEqual( question.validate_question(''), {question.id: 'TestError'} @@ -113,3 +103,19 @@ class TestSurveyInternals(common.TestSurveyCommon): question.validate_question('valid'), {} ) + + @users('survey_manager') + def test_skipped_values(self): + """ Create one question per type of questions. + Make sure they are correctly registered as 'skipped' after saving an empty answer for each + of them. """ + + questions = self._create_one_question_per_type() + survey_user = self.survey._create_answer(user=self.survey_user) + + for question in questions: + answer = '' if question.question_type in ['char_box', 'text_box'] else None + survey_user.save_lines(question, answer) + + for question in questions: + self._assert_skipped_question(question, survey_user)