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>
162 lines
5.6 KiB
Python
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)
|