diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/survey/tests/common.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/survey/tests/common.py')
| -rw-r--r-- | addons/survey/tests/common.py | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py new file mode 100644 index 00000000..421b7fe1 --- /dev/null +++ b/addons/survey/tests/common.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import re + +from collections import Counter +from contextlib import contextmanager + +from odoo.addons.mail.tests.common import mail_new_test_user +from odoo.tests import common + + +class SurveyCase(common.SavepointCase): + def setUp(self): + super(SurveyCase, self).setUp() + + """ 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 = { + 'text_box': ('text_box', 'value_text_box'), + 'char_box': ('char_box', 'value_char_box'), + 'numerical_box': ('numerical_box', 'value_numerical_box'), + 'date': ('date', 'value_date'), + 'simple_choice': ('suggestion', 'suggested_answer_id'), # TDE: still unclear + 'multiple_choice': ('suggestion', 'suggested_answer_id'), # TDE: still unclear + 'matrix': ('suggestion', ('suggested_answer_id', 'matrix_row_id')), # TDE: still unclear + } + + # ------------------------------------------------------------ + # ASSERTS + # ------------------------------------------------------------ + + def assertAnswer(self, answer, state, page): + self.assertEqual(answer.state, state) + self.assertEqual(answer.last_displayed_page_id, page) + + def assertAnswerLines(self, page, answer, answer_data): + """ Check answer lines. + + :param dict answer_data: + key = question ID + value = {'value': [user input]} + """ + lines = answer.user_input_line_ids.filtered(lambda l: l.page_id == page) + answer_count = sum(len(user_input['value']) for user_input in answer_data.values()) + self.assertEqual(len(lines), answer_count) + for qid, user_input in answer_data.items(): + answer_lines = lines.filtered(lambda l: l.question_id.id == qid) + question = answer_lines[0].question_id # TDE note: might have several answers for a given question + if question.question_type == 'multiple_choice': + values = user_input['value'] + answer_fname = self._type_match[question.question_type][1] + self.assertEqual( + Counter(getattr(line, answer_fname).id for line in answer_lines), + Counter(values)) + elif question.question_type == 'simple_choice': + [value] = user_input['value'] + answer_fname = self._type_match[question.question_type][1] + self.assertEqual(getattr(answer_lines, answer_fname).id, value) + elif question.question_type == 'matrix': + [value_col, value_row] = user_input['value'] + answer_fname_col = self._type_match[question.question_type][1][0] + answer_fname_row = self._type_match[question.question_type][1][1] + self.assertEqual(getattr(answer_lines, answer_fname_col).id, value_col) + self.assertEqual(getattr(answer_lines, answer_fname_row).id, value_row) + else: + [value] = user_input['value'] + answer_fname = self._type_match[question.question_type][1] + if question.question_type == 'numerical_box': + self.assertEqual(getattr(answer_lines, answer_fname), float(value)) + else: + self.assertEqual(getattr(answer_lines, answer_fname), value) + + def assertResponse(self, response, status_code, text_bits=None): + self.assertEqual(response.status_code, status_code) + for text in text_bits or []: + self.assertIn(text, response.text) + + # ------------------------------------------------------------ + # DATA CREATION + # ------------------------------------------------------------ + + def _add_question(self, page, name, qtype, **kwargs): + constr_mandatory = kwargs.pop('constr_mandatory', True) + constr_error_msg = kwargs.pop('constr_error_msg', 'TestError') + + sequence = kwargs.pop('sequence', False) + if not sequence: + sequence = page.question_ids[-1].sequence + 1 if page.question_ids else page.sequence + 1 + + base_qvalues = { + 'sequence': sequence, + 'title': name, + 'question_type': qtype, + 'constr_mandatory': constr_mandatory, + 'constr_error_msg': constr_error_msg, + } + if qtype in ('simple_choice', 'multiple_choice'): + base_qvalues['suggested_answer_ids'] = [ + (0, 0, { + 'value': label['value'], + 'answer_score': label.get('answer_score', 0), + 'is_correct': label.get('is_correct', False) + }) for label in kwargs.pop('labels') + ] + elif qtype == 'matrix': + base_qvalues['matrix_subtype'] = kwargs.pop('matrix_subtype', 'simple') + base_qvalues['suggested_answer_ids'] = [ + (0, 0, {'value': label['value'], 'answer_score': label.get('answer_score', 0)}) + for label in kwargs.pop('labels') + ] + base_qvalues['matrix_row_ids'] = [ + (0, 0, {'value': label['value'], 'answer_score': label.get('answer_score', 0)}) + for label in kwargs.pop('labels_2') + ] + else: + pass + base_qvalues.update(kwargs) + question = self.env['survey.question'].create(base_qvalues) + return question + + def _add_answer(self, survey, partner, **kwargs): + base_avals = { + 'survey_id': survey.id, + 'partner_id': partner.id if partner else False, + 'email': kwargs.pop('email', False), + } + base_avals.update(kwargs) + return self.env['survey.user_input'].create(base_avals) + + def _add_answer_line(self, question, answer, answer_value, **kwargs): + qtype = self._type_match.get(question.question_type, (False, False)) + answer_type = kwargs.pop('answer_type', qtype[0]) + answer_fname = kwargs.pop('answer_fname', qtype[1]) + + base_alvals = { + 'user_input_id': answer.id, + 'question_id': question.id, + 'skipped': False, + 'answer_type': answer_type, + } + base_alvals[answer_fname] = answer_value + base_alvals.update(kwargs) + return self.env['survey.user_input.line'].create(base_alvals) + + # ------------------------------------------------------------ + # UTILS + # ------------------------------------------------------------ + + 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_begin(self, survey, token): + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + url = base_url + '/survey/begin/%s/%s' % (survey.access_token, token) + return self.opener.post(url=url, json={}) + + def _access_submit(self, survey, token, post_data): + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + url = base_url + '/survey/submit/%s/%s' % (survey.access_token, token) + return self.opener.post(url=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) + return csrf_token_re.search(text).groups()[1] + + def _prepare_post_data(self, question, answers, post_data): + values = answers if isinstance(answers, list) else [answers] + if question.question_type == 'multiple_choice': + for value in values: + value = str(value) + if question.id in post_data: + if isinstance(post_data[question.id], list): + post_data[question.id].append(value) + else: + post_data[question.id] = [post_data[question.id], value] + else: + post_data[question.id] = value + else: + [values] = values + post_data[question.id] = str(values) + return post_data + + def _answer_question(self, question, answer, answer_token, csrf_token, button_submit='next'): + # 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) + self.assertResponse(response, 200) + + # Employee is redirected on next question + 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 + post_data.update(self._prepare_post_data(question, answer, post_data)) + if question.page_id: + post_data['page_id'] = question.page_id.id + post_data.update(**additional_post_data) + return post_data + + +class TestSurveyCommon(SurveyCase): + def setUp(self): + super(TestSurveyCommon, self).setUp() + + """ 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' + ) + + self.survey_user = mail_new_test_user( + self.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', + 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', + groups='base.group_portal' + ) + + self.user_public = mail_new_test_user( + self.env, name='Pauline Public', login='user_public', email='public@example.com', + groups='base.group_public' + ) + + self.customer = self.env['res.partner'].create({ + 'name': 'Caroline Customer', + 'email': 'customer@example.com', + }) + + self.survey = self.env['survey.survey'].with_user(self.survey_manager).create({ + 'title': 'Test Survey', + 'access_mode': 'public', + 'users_login_required': True, + 'users_can_go_back': False, + 'state': 'open', + }) + self.page_0 = self.env['survey.question'].with_user(self.survey_manager).create({ + 'title': 'First page', + 'survey_id': self.survey.id, + 'sequence': 1, + 'is_page': True, + }) + self.question_ft = self.env['survey.question'].with_user(self.survey_manager).create({ + 'title': 'Test Free Text', + 'survey_id': self.survey.id, + 'sequence': 2, + 'question_type': 'text_box', + }) + self.question_num = self.env['survey.question'].with_user(self.survey_manager).create({ + 'title': 'Test NUmerical Box', + 'survey_id': self.survey.id, + 'sequence': 3, + 'question_type': 'numerical_box', + }) |
