19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:30:27 +01:00
parent d1963a3c3a
commit 2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions

View file

@ -1,28 +1,32 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
import re
from collections import Counter
from contextlib import contextmanager
from contextlib import nullcontext
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.tests import common
class SurveyCase(common.TransactionCase):
def setUp(self):
super(SurveyCase, self).setUp()
@classmethod
def setUpClass(cls):
super(SurveyCase, cls).setUpClass()
""" Some custom stuff to make the matching between questions and answers
:param dict _type_match: dict
key: question type
value: (answer type, answer field_name)
"""
self._type_match = {
cls._type_match = {
'text_box': ('text_box', 'value_text_box'),
'char_box': ('char_box', 'value_char_box'),
'numerical_box': ('numerical_box', 'value_numerical_box'),
'scale': ('scale', 'value_scale'), # similar to numerical_box
'date': ('date', 'value_date'),
'datetime': ('datetime', 'value_datetime'),
'simple_choice': ('suggestion', 'suggested_answer_id'), # TDE: still unclear
@ -160,16 +164,18 @@ class SurveyCase(common.TransactionCase):
def _access_start(self, survey):
return self.url_open('/survey/start/%s' % survey.access_token)
def _access_page(self, survey, token):
return self.url_open('/survey/%s/%s' % (survey.access_token, token))
def _access_page(self, survey, token, query_count=None):
with self.assertQueryCount(query_count) if query_count else nullcontext():
return self.url_open('/survey/%s/%s' % (survey.access_token, token))
def _access_begin(self, survey, token):
url = survey.get_base_url() + '/survey/begin/%s/%s' % (survey.access_token, token)
return self.opener.post(url=url, json={})
url = survey.get_base_url() + f'/survey/begin/{survey.access_token}/{token}'
return self.url_open(url, json={'params': {'lang_code': 'en_US'}})
def _access_submit(self, survey, token, post_data):
def _access_submit(self, survey, token, post_data, query_count=None):
url = survey.get_base_url() + '/survey/submit/%s/%s' % (survey.access_token, token)
return self.opener.post(url=url, json={'params': post_data})
with self.assertQueryCount(query_count) if query_count else nullcontext():
return self.url_open(url, json={'params': post_data})
def _find_csrf_token(self, text):
csrf_token_re = re.compile("(input.+csrf_token.+value=\")([a-f0-9]{40}o[0-9]*)", re.MULTILINE)
@ -192,14 +198,15 @@ class SurveyCase(common.TransactionCase):
post_data[question.id] = str(values)
return post_data
def _answer_question(self, question, answer, answer_token, csrf_token, button_submit='next'):
def _answer_question(self, question, answer, answer_token, csrf_token, button_submit='next',
submit_query_count=None, access_page_query_count=None):
# Employee submits the question answer
post_data = self._format_submission_data(question, answer, {'csrf_token': csrf_token, 'token': answer_token, 'button_submit': button_submit})
response = self._access_submit(question.survey_id, answer_token, post_data)
response = self._access_submit(question.survey_id, answer_token, post_data, query_count=submit_query_count)
self.assertResponse(response, 200)
# Employee is redirected on next question
response = self._access_page(question.survey_id, answer_token)
response = self._access_page(question.survey_id, answer_token, query_count=access_page_query_count)
self.assertResponse(response, 200)
def _answer_page(self, page, answers, answer_token, csrf_token):
@ -236,11 +243,11 @@ class SurveyCase(common.TransactionCase):
False
)
self.assertTrue(bool(question_data))
self.assertEqual(len(question_data.get('answer_input_skipped_ids')), 1)
self.assertEqual(len(question_data.get('answer_input_ids') - question_data.get('answer_input_done_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:
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'}]
@ -253,64 +260,184 @@ class SurveyCase(common.TransactionCase):
return all_questions
def _create_one_question_per_type_with_scoring(self):
all_questions = self.env['survey.question']
for (question_type, _dummy) in self.env['survey.question']._fields['question_type'].selection:
kwargs = {}
kwargs['question_type'] = question_type
if question_type == 'numerical_box':
kwargs['answer_score'] = 1
kwargs['answer_numerical_box'] = 5
elif question_type == 'date':
kwargs['answer_score'] = 2
kwargs['answer_date'] = datetime.date(2023, 10, 16)
elif question_type == 'datetime':
kwargs['answer_score'] = 3
kwargs['answer_datetime'] = datetime.datetime(2023, 11, 17, 8, 0, 0)
elif question_type == 'multiple_choice':
kwargs['answer_score'] = 4
kwargs['labels'] = [
{'value': 'MChoice0', 'is_correct': True},
{'value': 'MChoice1', 'is_correct': True},
{'value': 'MChoice2'}
]
elif question_type == 'simple_choice':
kwargs['answer_score'] = 5
kwargs['labels'] = [
{'value': 'SChoice0', 'is_correct': True},
{'value': 'SChoice1'}
]
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):
super(TestSurveyCommon, self).setUp()
@classmethod
def setUpClass(cls):
super().setUpClass()
""" Create test data: a survey with some pre-defined questions and various test users for ACL """
self.survey_manager = mail_new_test_user(
self.env, name='Gustave Doré', login='survey_manager', email='survey.manager@example.com',
groups='survey.group_survey_manager,base.group_user'
cls.survey_manager = mail_new_test_user(
cls.env, name='Gustave Doré', login='survey_manager', email='survey.manager@example.com',
groups='survey.group_survey_manager,base.group_user', tz='Europe/Brussels',
)
self.survey_user = mail_new_test_user(
self.env, name='Lukas Peeters', login='survey_user', email='survey.user@example.com',
cls.survey_user = mail_new_test_user(
cls.env, name='Lukas Peeters', login='survey_user', email='survey.user@example.com',
groups='survey.group_survey_user,base.group_user'
)
self.user_emp = mail_new_test_user(
self.env, name='Eglantine Employee', login='user_emp', email='employee@example.com',
cls.user_emp = mail_new_test_user(
cls.env, name='Eglantine Employee', login='user_emp', email='employee@example.com',
groups='base.group_user', password='user_emp'
)
self.user_portal = mail_new_test_user(
self.env, name='Patrick Portal', login='user_portal', email='portal@example.com',
cls.user_portal = mail_new_test_user(
cls.env, name='Patrick Portal', login='user_portal', email='portal@example.com',
groups='base.group_portal'
)
self.user_public = mail_new_test_user(
self.env, name='Pauline Public', login='user_public', email='public@example.com',
cls.user_public = mail_new_test_user(
cls.env, name='Pauline Public', login='user_public', email='public@example.com',
groups='base.group_public'
)
self.customer = self.env['res.partner'].create({
cls.customer = cls.env['res.partner'].create({
'name': 'Caroline Customer',
'email': 'customer@example.com',
})
self.survey = self.env['survey.survey'].with_user(self.survey_manager).create({
cls.survey = cls.env['survey.survey'].with_user(cls.survey_manager).create({
'title': 'Test Survey',
'access_mode': 'public',
'users_login_required': True,
'users_can_go_back': False,
})
self.page_0 = self.env['survey.question'].with_user(self.survey_manager).create({
cls.page_0 = cls.env['survey.question'].with_user(cls.survey_manager).create({
'title': 'First page',
'survey_id': self.survey.id,
'survey_id': cls.survey.id,
'sequence': 1,
'is_page': True,
'question_type': False,
})
self.question_ft = self.env['survey.question'].with_user(self.survey_manager).create({
cls.question_ft = cls.env['survey.question'].with_user(cls.survey_manager).create({
'title': 'Test Free Text',
'survey_id': self.survey.id,
'survey_id': cls.survey.id,
'sequence': 2,
'question_type': 'text_box',
})
self.question_num = self.env['survey.question'].with_user(self.survey_manager).create({
cls.question_num = cls.env['survey.question'].with_user(cls.survey_manager).create({
'title': 'Test NUmerical Box',
'survey_id': self.survey.id,
'survey_id': cls.survey.id,
'sequence': 3,
'question_type': 'numerical_box',
})
cls.question_scale = cls.env['survey.question'].with_user(cls.survey_manager).create({
'title': 'Test Scale',
'survey_id': cls.survey.id,
'sequence': 40,
'question_type': 'scale',
})
class TestSurveyResultsCommon(SurveyCase):
@classmethod
def setUpClass(cls):
super(TestSurveyResultsCommon, cls).setUpClass()
cls.survey_manager = mail_new_test_user(
cls.env, name='Gustave Doré', login='survey_manager', email='survey.manager@example.com',
groups='survey.group_survey_manager,base.group_user'
)
# Create survey with questions
cls.survey = cls.env['survey.survey'].create({
'title': 'Test Survey Results',
'questions_layout': 'one_page'
})
cls.question_char_box = cls._add_question(
cls, None, 'What is your name', 'char_box', survey_id=cls.survey.id, sequence='1')
cls.question_numerical_box = cls._add_question(
cls, None, 'What is your age', 'numerical_box', survey_id=cls.survey.id, sequence='2')
cls.question_sc = cls._add_question(
cls, None, 'Are you a cat or a dog person', 'simple_choice', survey_id=cls.survey.id,
sequence='3', labels=[{'value': 'Cat'},
{'value': 'Dog'}])
cls.question_mc = cls._add_question(
cls, None, 'What do you like most in our tarte al djotte', 'multiple_choice', survey_id=cls.survey.id,
sequence='4', labels=[{'value': 'The gras'},
{'value': 'The bette'},
{'value': 'The tout'},
{'value': 'The regime is fucked up'}])
cls.question_mx1 = cls._add_question(
cls, None, 'When do you harvest those fruits', 'matrix', survey_id=cls.survey.id, sequence='5',
labels=[{'value': 'Spring'}, {'value': 'Summer'}],
labels_2=[{'value': 'Apples'},
{'value': 'Strawberries'}])
cls.question_mx2 = cls._add_question(
cls, None, 'How often should you water those plants', 'matrix', survey_id=cls.survey.id, sequence='6',
labels=[{'value': 'Once a month'}, {'value': 'Once a week'}],
labels_2=[{'value': 'Cactus'},
{'value': 'Ficus'}])
cls.question_scale = cls._add_question(
cls, None, 'How would you rate your experience on our website ?', 'scale', survey_id=cls.survey.id, sequence='7',
)
# Question answers ids
[cls.cat_id, cls.dog_id] = cls.question_sc.suggested_answer_ids.ids
[cls.gras_id, cls.bette_id, _, _] = cls.question_mc.suggested_answer_ids.ids
[cls.apples_row_id, cls.strawberries_row_id] = cls.question_mx1.matrix_row_ids.ids
[cls.spring_id, cls.summer_id] = cls.question_mx1.suggested_answer_ids.ids
[cls.cactus_row_id, cls.ficus_row_id] = cls.question_mx2.matrix_row_ids.ids
[cls.once_a_month_id, cls.once_a_week_id] = cls.question_mx2.suggested_answer_ids.ids
# Populate survey with answers
cls.user_input_1 = cls._add_answer(cls, cls.survey, cls.survey_manager.partner_id)
cls.answer_lukas = cls._add_answer_line(cls, cls.question_char_box, cls.user_input_1, 'Lukas')
cls.answer_24 = cls._add_answer_line(cls, cls.question_numerical_box, cls.user_input_1, 24)
cls.answer_cat = cls._add_answer_line(cls, cls.question_sc, cls.user_input_1, cls.cat_id)
cls._add_answer_line(cls, cls.question_mc, cls.user_input_1, cls.gras_id)
cls._add_answer_line(cls, cls.question_mx1, cls.user_input_1, cls.summer_id, **{'answer_value_row': cls.apples_row_id})
cls._add_answer_line(cls, cls.question_mx1, cls.user_input_1, cls.spring_id, **{'answer_value_row': cls.strawberries_row_id})
cls._add_answer_line(cls, cls.question_mx2, cls.user_input_1, cls.once_a_month_id, **{'answer_value_row': cls.cactus_row_id})
cls._add_answer_line(cls, cls.question_mx2, cls.user_input_1, cls.once_a_week_id, **{'answer_value_row': cls.ficus_row_id})
cls._add_answer_line(cls, cls.question_scale, cls.user_input_1, '5')
cls.user_input_1.state = 'done'
cls.user_input_2 = cls._add_answer(cls, cls.survey, cls.survey_manager.partner_id)
cls.answer_pauline = cls._add_answer_line(cls, cls.question_char_box, cls.user_input_2, 'Pauline')
cls._add_answer_line(cls, cls.question_numerical_box, cls.user_input_2, 24)
cls.answer_dog = cls._add_answer_line(cls, cls.question_sc, cls.user_input_2, cls.dog_id)
cls._add_answer_line(cls, cls.question_mc, cls.user_input_2, cls.gras_id)
cls._add_answer_line(cls, cls.question_mc, cls.user_input_2, cls.bette_id)
cls._add_answer_line(cls, cls.question_mx1, cls.user_input_2, cls.spring_id, **{'answer_value_row': cls.apples_row_id})
cls._add_answer_line(cls, cls.question_mx1, cls.user_input_2, cls.spring_id, **{'answer_value_row': cls.strawberries_row_id})
cls._add_answer_line(cls, cls.question_mx2, cls.user_input_2, cls.once_a_month_id, **{'answer_value_row': cls.cactus_row_id})
cls._add_answer_line(cls, cls.question_mx2, cls.user_input_2, cls.once_a_month_id, **{'answer_value_row': cls.ficus_row_id})
cls.scale_answer_line_2 = cls._add_answer_line(cls, cls.question_scale, cls.user_input_1, '7')
cls.user_input_2.state = 'done'