[FIX] survey: conditional score with sections
Steps:
- Go to Surveys
- Create an new survey:
- Questions:
1. First section
2. First question:
- Multiple choice: only one answer
- Answers:
1. First answer
- Choice: Yes
- Is a correct answer: Checked
- Score for this choice: 1
2. Second answer
- Choice: No
3. Second question:
- Multiple choice: only one answer
- Answers:
1. First answer
- Choice: Yes
- Is a correct answer: Checked
- Score for this choice: 1
2. Second answer
- Choice: No
- Options tab:
- Conditional display: Checked
- Triggering question: (First question)
- Triggering answer: (First question, First answer)
- Options tab:
- Layout: One page per section
- Scoring: Scoring with answers at the end
- Click Test
- Select the two correct answers
- Submit
Bug:
The score is 50% instead of 100%.
Explanation:
Since multiple questions are submitted at the same time, we cannot know
before saving the question whether the following is still going to be
active.
This commit re-evaluates, for each question, which are the ones that are
still active.
opw:2537713
closes odoo/odoo#72126
X-original-commit: ec836acdc7bf10212f14a8bc98eac4cfa2f12e26
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
Signed-off-by: backspac <backspac@users.noreply.github.com>
This commit is contained in:
@@ -467,8 +467,8 @@ class Survey(http.Controller):
|
||||
|
||||
errors = {}
|
||||
# Prepare answers / comment by question, validate and save answers
|
||||
inactive_questions = request.env['survey.question'] if answer_sudo.is_session_answer else answer_sudo._get_inactive_conditional_questions()
|
||||
for question in questions:
|
||||
inactive_questions = request.env['survey.question'] if answer_sudo.is_session_answer else answer_sudo._get_inactive_conditional_questions()
|
||||
if question in inactive_questions: # if question is inactive, skip validation and save
|
||||
continue
|
||||
answer, comment = self._extract_comment_from_answers(question, post.get(str(question.id)))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
from . import common
|
||||
from . import test_survey
|
||||
from . import test_survey_flow
|
||||
from . import test_survey_flow_with_conditions
|
||||
from . import test_certification_flow
|
||||
from . import test_survey_invite
|
||||
from . import test_survey_security
|
||||
|
||||
@@ -195,6 +195,18 @@ class SurveyCase(common.TransactionCase):
|
||||
response = self._access_page(question.survey_id, answer_token)
|
||||
self.assertResponse(response, 200)
|
||||
|
||||
def _answer_page(self, page, answers, answer_token, csrf_token):
|
||||
post_data = {}
|
||||
for question, answer in answers.items():
|
||||
post_data[question.id] = answer.id
|
||||
post_data['page_id'] = page.id
|
||||
post_data['csrf_token'] = csrf_token
|
||||
post_data['token'] = answer_token
|
||||
response = self._access_submit(page.survey_id, answer_token, post_data)
|
||||
self.assertResponse(response, 200)
|
||||
response = self._access_page(page.survey_id, answer_token)
|
||||
self.assertResponse(response, 200)
|
||||
|
||||
def _format_submission_data(self, question, answer, additional_post_data):
|
||||
post_data = {}
|
||||
post_data['question_id'] = question.id
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.survey.tests import common
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install', 'functional')
|
||||
class TestSurveyFlowWithConditions(common.TestSurveyCommon, HttpCase):
|
||||
def test_conditional_flow_with_scoring(self):
|
||||
with self.with_user('survey_user'):
|
||||
survey = self.env['survey.survey'].create({
|
||||
'title': 'Survey',
|
||||
'access_mode': 'public',
|
||||
'questions_layout': 'page_per_section',
|
||||
'scoring_type': 'scoring_with_answers',
|
||||
'scoring_success_min': 85.0,
|
||||
})
|
||||
|
||||
page_0 = self.env['survey.question'].with_user(self.survey_manager).create({
|
||||
'title': 'First page',
|
||||
'survey_id': survey.id,
|
||||
'sequence': 1,
|
||||
'is_page': True,
|
||||
})
|
||||
|
||||
q01 = self._add_question(
|
||||
page_0, 'Question 1', 'simple_choice',
|
||||
sequence=1,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2'},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4', 'is_correct': True, 'answer_score': 1.0}
|
||||
])
|
||||
|
||||
q02 = self._add_question(
|
||||
page_0, 'Question 2', 'simple_choice',
|
||||
sequence=2,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
is_conditional=True, triggering_question_id=q01.id, triggering_answer_id=q01.suggested_answer_ids.filtered(lambda q: q.is_correct).id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2', 'is_correct': True, 'answer_score': 1.0},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4'}
|
||||
])
|
||||
|
||||
q03 = self._add_question(
|
||||
page_0, 'Question 3', 'simple_choice',
|
||||
sequence=1,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2'},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4', 'is_correct': True, 'answer_score': 1.0}
|
||||
])
|
||||
|
||||
self._add_question( # q04
|
||||
page_0, 'Question 4', 'simple_choice',
|
||||
sequence=2,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
is_conditional=True, triggering_question_id=q03.id, triggering_answer_id=q03.suggested_answer_ids.filtered(lambda q: q.is_correct).id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2', 'is_correct': True, 'answer_score': 1.0},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4'}
|
||||
])
|
||||
|
||||
q05 = self._add_question(
|
||||
page_0, 'Question 5', 'simple_choice',
|
||||
sequence=1,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2'},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4', 'is_correct': True, 'answer_score': 1.0}
|
||||
])
|
||||
|
||||
q06 = self._add_question(
|
||||
page_0, 'Question 6', 'simple_choice',
|
||||
sequence=2,
|
||||
constr_mandatory=True, constr_error_msg='Please select an answer', survey_id=survey.id,
|
||||
is_conditional=True, triggering_question_id=q05.id, triggering_answer_id=q05.suggested_answer_ids.filtered(lambda q: q.is_correct).id,
|
||||
labels=[
|
||||
{'value': 'Answer 1'},
|
||||
{'value': 'Answer 2', 'is_correct': True, 'answer_score': 1.0},
|
||||
{'value': 'Answer 3'},
|
||||
{'value': 'Answer 4'}
|
||||
])
|
||||
|
||||
# User opens start page
|
||||
self._access_start(survey)
|
||||
|
||||
# -> this should have generated a new user_input with a token
|
||||
user_inputs = self.env['survey.user_input'].search([('survey_id', '=', survey.id)])
|
||||
self.assertEqual(len(user_inputs), 1)
|
||||
answer_token = user_inputs.access_token
|
||||
|
||||
# User begins survey with first page
|
||||
response = self._access_page(survey, answer_token)
|
||||
self.assertResponse(response, 200)
|
||||
csrf_token = self._find_csrf_token(response.text)
|
||||
|
||||
r = self._access_begin(survey, answer_token)
|
||||
self.assertResponse(r, 200)
|
||||
|
||||
answers = {
|
||||
q01: q01.suggested_answer_ids[3], # Right
|
||||
q02: q02.suggested_answer_ids[1], # Right
|
||||
q03: q03.suggested_answer_ids[0], # Wrong
|
||||
q05: q05.suggested_answer_ids[3], # Right
|
||||
q06: q06.suggested_answer_ids[2], # Wrong
|
||||
}
|
||||
|
||||
self._answer_page(page_0, answers, answer_token, csrf_token)
|
||||
|
||||
user_inputs.invalidate_cache()
|
||||
self.assertEqual(round(user_inputs.scoring_percentage), 60, "Three right answers out of five (the fourth one is still hidden)")
|
||||
self.assertFalse(user_inputs.scoring_success)
|
||||
Reference in New Issue
Block a user