Files
odoo_source/addons/survey/tests/test_survey.py
T
Noe Antoine 01ffaea48b [FIX] survey: allow partial scores to answers almost correct.
BEFORE THIS COMMIT / How to reproduce :

Consider a multiple choice question with single answer.

A. 2 points
B. 1 point
C. -1 point

Here, the user can only select one answer. He picks A. He only obtains 2/3 points.
This is because the maximum score was computed as the sum of all positive scores
for the question. It does not make sense, as the student can only pick one answer.
Therefore, the formula does not allow giving partial scores (here, answer B, close
to the correct answer) while maintaining correct score percentages.

AFTER THIS COMMIT:

The sum of positive scores is still used as maximum score for multiple choice
with multiple answers, as we want the student to pick all good answers for max score.

However, for multiple choice with single answer, we use the maximum positive score
(or 0, if none) among answers, as it the maximum score one can get while selecting
a single answer.

-> example above : I pick A, I obtain 2 points out of max(2, 1, (0)) = 2
-> I obtain max score for the question. 2/2.

ps: As the sum only uses striclty positive values, the negative points are still
operational and the flow is not changed.

TESTS:

A test test_partial_scores_simple_choice is added to make sure the simple_choice
is repaired and always gives 100% of points if the best answer is picked.

Task-2533836

closes odoo/odoo#77426

X-original-commit: 2cdfb7805564943ccf857e49b41d3b597fd727bb
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2021-09-30 10:38:15 +00:00

162 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _
from odoo.addons.survey.tests import common
from odoo.tests.common import users
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 in self._create_one_question_per_type():
self.assertDictEqual(
question.validate_question(''),
{question.id: 'TestError'}
)
@users('survey_manager')
def test_answer_validation_date(self):
question = self._add_question(
self.page_0, 'Q0', 'date', validation_required=True,
validation_min_date='2015-03-20', validation_max_date='2015-03-25', validation_error_msg='ValidationError')
self.assertEqual(
question.validate_question('Is Alfred an answer ?'),
{question.id: _('This is not a date')}
)
self.assertEqual(
question.validate_question('2015-03-19'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('2015-03-26'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('2015-03-25'),
{}
)
@users('survey_manager')
def test_answer_validation_numerical(self):
question = self._add_question(
self.page_0, 'Q0', 'numerical_box', validation_required=True,
validation_min_float_value=2.2, validation_max_float_value=3.3, validation_error_msg='ValidationError')
self.assertEqual(
question.validate_question('Is Alfred an answer ?'),
{question.id: _('This is not a number')}
)
self.assertEqual(
question.validate_question('2.0'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('4.0'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('2.9'),
{}
)
@users('survey_manager')
def test_answer_validation_char_box_email(self):
question = self._add_question(self.page_0, 'Q0', 'char_box', validation_email=True)
self.assertEqual(
question.validate_question('not an email'),
{question.id: _('This answer must be an email address')}
)
self.assertEqual(
question.validate_question('email@example.com'),
{}
)
@users('survey_manager')
def test_answer_validation_char_box_length(self):
question = self._add_question(
self.page_0, 'Q0', 'char_box', validation_required=True,
validation_length_min=2, validation_length_max=8, validation_error_msg='ValidationError')
self.assertEqual(
question.validate_question('l'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('waytoomuchlonganswer'),
{question.id: 'ValidationError'}
)
self.assertEqual(
question.validate_question('valid'),
{}
)
def test_partial_scores_simple_choice(self):
"""" Check that if partial scores are given for partially correct answers, in the case of a multiple
choice question with single choice, choosing the answer with max score gives 100% of points. """
partial_scores_survey = self.env['survey.survey'].create({
'title': 'How much do you know about words?',
'scoring_type': 'scoring_with_answers',
'scoring_success_min': 90.0,
})
[a_01, a_02, a_03] = self.env['survey.question.answer'].create([{
'value': 'A thing full of letters.',
'answer_score': 1.0
}, {
'value': 'A unit of language, [...], carrying a meaning.',
'answer_score': 4.0,
'is_correct': True
}, {
'value': '42',
'answer_score': -4.0
}])
q_01 = self.env['survey.question'].create({
'survey_id': partial_scores_survey.id,
'title': 'What is a word?',
'sequence': 1,
'question_type': 'simple_choice',
'suggested_answer_ids': [(6, 0, (a_01 | a_02 | a_03).ids)]
})
user_input = self.env['survey.user_input'].create({'survey_id': partial_scores_survey.id})
self.env['survey.user_input.line'].create({
'user_input_id': user_input.id,
'question_id': q_01.id,
'answer_type': 'suggestion',
'suggested_answer_id': a_02.id
})
# Check that scoring is correct and survey is passed
self.assertEqual(user_input.scoring_percentage, 100)
self.assertTrue(user_input.scoring_success)
@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)