diff options
| author | Aurélien Warnon <awa@odoo.com> | 2019-02-01 07:12:43 +0000 |
|---|---|---|
| committer | Aurélien Warnon <awa@odoo.com> | 2019-02-06 10:34:43 +0000 |
| commit | 445541989f9dc094bf81201a715abe0a68ed1c63 (patch) | |
| tree | 6bb45ba7d9dcaa52038dba4f1365e0885ec8c82e /addons/survey/tests | |
| parent | afb1abbb60e5cdc4f76ab7b5a1b54b5e8a9283d5 (diff) | |
[IMP] survey: add randomization and survey layout selection
Task #1902306
Purpose
=======
The "page" concept is now only present in the user interface.
Surveys are split in "sections" that have two purposes:
- Organizing a (long) survey/certification
- Allow to pick a random questions count for that section (more information here after)
On the user interface, based on the questions_layout field, surveys are displayed:
- On a single page, where sections still appear but are only used as visual separations
- On multiple pages, having one page per section (this matches the previous behavior)
- On multiple pages, having one page per *question*
On top of that page concept, this commit added randomization for the survey questions.
The randomization mechanism will take X questions per section of the survey.
The survey.user_input is initialized with the selected questions to be sure to keep that
set of questions and avoid showing a new set of questions every time the user refreshes the page.
This also allows to easilly go back and know which question we have to show.
Diffstat (limited to 'addons/survey/tests')
| -rw-r--r-- | addons/survey/tests/__init__.py | 2 | ||||
| -rw-r--r-- | addons/survey/tests/common.py | 26 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey.py | 12 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey_flow.py | 21 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey_randomize.py | 59 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey_ui.py | 12 |
6 files changed, 105 insertions, 27 deletions
diff --git a/addons/survey/tests/__init__.py b/addons/survey/tests/__init__.py index bc51dec7bcf..7259a6d6673 100644 --- a/addons/survey/tests/__init__.py +++ b/addons/survey/tests/__init__.py @@ -4,7 +4,9 @@ from . import common from . import test_survey from . import test_survey_flow +from . import test_certification_flow from . import test_survey_invite from . import test_survey_security +from . import test_survey_randomize from . import test_survey_ui from . import test_survey_compute_pages_questions diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py index 13b988f9ec0..d0a7942ade7 100644 --- a/addons/survey/tests/common.py +++ b/addons/survey/tests/common.py @@ -13,7 +13,6 @@ survey_new_test_user = partial(new_test_user, context={'mail_create_nolog': True class SurveyCase(common.SavepointCase): - def setUp(self): super(SurveyCase, self).setUp() @@ -45,7 +44,7 @@ class SurveyCase(common.SavepointCase): self.user_emp = survey_new_test_user( self.env, name='Eglantine Employee', login='user_emp', email='employee@example.com', - groups='base.group_user' + groups='base.group_user', password='user_emp' ) self.user_portal = survey_new_test_user( @@ -149,8 +148,13 @@ class SurveyCase(common.SavepointCase): 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': page.question_ids[-1].sequence + 1 if page.question_ids else page.sequence + 1, + 'sequence': sequence, 'title': name, 'question_type': qtype, 'constr_mandatory': constr_mandatory, @@ -158,8 +162,11 @@ class SurveyCase(common.SavepointCase): } if qtype in ('simple_choice', 'multiple_choice'): base_qvalues['labels_ids'] = [ - (0, 0, {'value': label['value'], 'answer_score': label.get('answer_score', 0)}) - for label in kwargs.pop('labels') + (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') @@ -202,6 +209,15 @@ class SurveyCase(common.SavepointCase): base_alvals.update(kwargs) return self.env['survey.user_input_line'].create(base_alvals) + 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/fill/%s/%s' % (survey.access_token, token)) + + def _access_submit(self, survey, token, post_data): + return self.url_open('/survey/submit/%s/%s' % (survey.access_token, token), data=post_data) + def _find_csrf_token(self, text): csrf_token_re = re.compile("(input.+csrf_token.+value=\")([_a-zA-Z0-9]{51})", re.MULTILINE) return csrf_token_re.search(text).groups()[1] diff --git a/addons/survey/tests/test_survey.py b/addons/survey/tests/test_survey.py index b962a4fa1dd..1f94723d045 100644 --- a/addons/survey/tests/test_survey.py +++ b/addons/survey/tests/test_survey.py @@ -29,7 +29,7 @@ class TestSurveyInternals(common.SurveyCase): kwargs['labels_2'] = [{'value': 'Row0'}, {'value': 'Row1'}] question = self._add_question(self.page_0, 'Q0', question_type, **kwargs) - answer_tag = '%s_%s_%s' % (self.survey.id, self.page_0.id, question.id) + answer_tag = '%s_%s' % (self.survey.id, question.id) self.assertDictEqual( question.validate_question({answer_tag: ''}, answer_tag), {answer_tag: 'TestError'} @@ -40,7 +40,7 @@ class TestSurveyInternals(common.SurveyCase): 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') - answer_tag = '%s_%s_%s' % (self.survey.id, self.page_0.id, question.id) + answer_tag = '%s_%s' % (self.survey.id, question.id) self.assertEqual( question.validate_question({answer_tag: 'Is Alfred an answer ?'}, answer_tag), @@ -67,7 +67,7 @@ class TestSurveyInternals(common.SurveyCase): 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') - answer_tag = '%s_%s_%s' % (self.survey.id, self.page_0.id, question.id) + answer_tag = '%s_%s' % (self.survey.id, question.id) self.assertEqual( question.validate_question({answer_tag: 'Is Alfred an answer ?'}, answer_tag), @@ -92,7 +92,7 @@ class TestSurveyInternals(common.SurveyCase): @users('survey_manager') def test_answer_validation_textbox_email(self): question = self._add_question(self.page_0, 'Q0', 'textbox', validation_email=True) - answer_tag = '%s_%s_%s' % (self.survey.id, self.page_0.id, question.id) + answer_tag = '%s_%s' % (self.survey.id, question.id) self.assertEqual( question.validate_question({answer_tag: 'not an email'}, answer_tag), @@ -109,7 +109,7 @@ class TestSurveyInternals(common.SurveyCase): question = self._add_question( self.page_0, 'Q0', 'textbox', validation_required=True, validation_length_min=2, validation_length_max=8, validation_error_msg='ValidationError') - answer_tag = '%s_%s_%s' % (self.survey.id, self.page_0.id, question.id) + answer_tag = '%s_%s' % (self.survey.id, question.id) self.assertEqual( question.validate_question({answer_tag: 'l'}, answer_tag), @@ -138,7 +138,7 @@ class TestSurveyInternals(common.SurveyCase): question, answer, random.choice(question.labels_ids.ids), answer_type='suggestion', answer_fname='value_suggested') lines = [line.value_suggested.id for line in question.user_input_line_ids] - answers = [{'text': label.value, 'count': lines.count(label.id), 'answer_id': label.id} for label in question.labels_ids] + answers = [{'text': label.value, 'count': lines.count(label.id), 'answer_id': label.id, 'answer_score': label.answer_score} for label in question.labels_ids] prp_result = self.env['survey.survey'].prepare_result(question)['answers'] self.assertItemsEqual(prp_result, answers) diff --git a/addons/survey/tests/test_survey_flow.py b/addons/survey/tests/test_survey_flow.py index bda59666e3d..b2d8c6f09c6 100644 --- a/addons/survey/tests/test_survey_flow.py +++ b/addons/survey/tests/test_survey_flow.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -import re - from odoo.addons.survey.tests import common from odoo.tests import tagged from odoo.tests.common import HttpCase @@ -10,16 +8,6 @@ from odoo.tests.common import HttpCase @tagged('functional') class TestSurveyFlow(common.SurveyCase, HttpCase): - - 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/fill/%s/%s' % (survey.access_token, token)) - - def _access_submit(self, survey, token, post_data): - return self.url_open('/survey/submit/%s/%s' % (survey.access_token, token), data=post_data) - def _format_submission_data(self, page, answer_data, additional_post_data): post_data = {} post_data['page_id'] = page.id @@ -28,11 +16,11 @@ class TestSurveyFlow(common.SurveyCase, HttpCase): if question.question_type == 'multiple_choice': values = answer_vals['value'] for value in values: - key = "%s_%s_%s_%s" % (page.survey_id.id, page.id, question.id, value) + key = "%s_%s_%s" % (page.survey_id.id, question.id, value) post_data[key] = value else: [value] = answer_vals['value'] - key = "%s_%s_%s" % (page.survey_id.id, page.id, question.id) + key = "%s_%s" % (page.survey_id.id, question.id) post_data[key] = value post_data.update(**additional_post_data) return post_data @@ -45,6 +33,8 @@ class TestSurveyFlow(common.SurveyCase, HttpCase): 'title': 'Public Survey for Tarte Al Djotte', 'access_mode': 'public', 'users_login_required': False, + 'questions_layout': 'page_per_section', + 'stage_id': self.env['survey.stage'].search([('closed', '=', False)]).id }) # First page is about customer data @@ -120,8 +110,7 @@ class TestSurveyFlow(common.SurveyCase, HttpCase): # Customer is redirected on second page and begins filling it r = self._access_page(survey, answer_token) self.assertResponse(r, 200) - csrf_token_re = re.compile("(input.+csrf_token.+value=\")([_a-zA-Z0-9]{51})", re.MULTILINE) - csrf_token = csrf_token_re.search(r.text).groups()[1] + csrf_token = self._find_csrf_token(r.text) # Customer submit second page answers answer_data = { diff --git a/addons/survey/tests/test_survey_randomize.py b/addons/survey/tests/test_survey_randomize.py new file mode 100644 index 00000000000..1ab5ddefd6b --- /dev/null +++ b/addons/survey/tests/test_survey_randomize.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import TransactionCase + + +class TestSurveyRandomize(TransactionCase): + def test_01_generate_randomized_questions(self): + """ Use random generate for a survey and verify that questions within the page are selected accordingly """ + Question = self.env['survey.question'].sudo() + question_and_pages = self.env['survey.question'] + page_1 = Question.create({ + 'title': 'Page 1', + 'is_page': True, + 'sequence': 1, + 'random_questions_count': 3 + }) + question_and_pages |= page_1 + question_and_pages = self._add_questions(question_and_pages, page_1, 5) + + page_2 = Question.create({ + 'title': 'Page 2', + 'is_page': True, + 'sequence': 100, + 'random_questions_count': 5 + }) + question_and_pages |= page_2 + question_and_pages = self._add_questions(question_and_pages, page_2, 10) + + page_3 = Question.create({ + 'title': 'Page 2', + 'is_page': True, + 'sequence': 1000, + 'random_questions_count': 4 + }) + question_and_pages |= page_3 + question_and_pages = self._add_questions(question_and_pages, page_3, 2) + + self.survey1 = self.env['survey.survey'].sudo().create({ + 'title': "S0", + 'question_and_page_ids': [(6, 0, question_and_pages.ids)], + 'questions_selection': 'random' + }) + + generated_questions = self.survey1._prepare_answer_questions() + + self.assertEqual(len(generated_questions.ids), 10, msg="Expected 10 unique questions") + self.assertEqual(len(generated_questions.filtered(lambda question: question.page_id == page_1)), 3, msg="Expected 3 questions in page 1") + self.assertEqual(len(generated_questions.filtered(lambda question: question.page_id == page_2)), 5, msg="Expected 5 questions in page 2") + self.assertEqual(len(generated_questions.filtered(lambda question: question.page_id == page_3)), 2, msg="Expected 2 questions in page 3") + + def _add_questions(self, question_and_pages, page, count): + for i in range(count): + question_and_pages |= self.env['survey.question'].sudo().create({ + 'title': page.title + ' Q' + str(i + 1), + 'sequence': page.sequence + (i + 1) + }) + + return question_and_pages diff --git a/addons/survey/tests/test_survey_ui.py b/addons/survey/tests/test_survey_ui.py index adcf821c396..1e14241a932 100644 --- a/addons/survey/tests/test_survey_ui.py +++ b/addons/survey/tests/test_survey_ui.py @@ -16,3 +16,15 @@ class TestUi(odoo.tests.HttpCase): def test_03_public_survey_tour(self): access_token = self.env.ref('survey.survey_feedback').access_token self.phantom_js("/survey/start/%s" % access_token, "odoo.__DEBUG__.services['web_tour.tour'].run('test_survey')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_survey.ready") + + def test_04_certification_success_tour(self): + access_token = self.env.ref('survey.vendor_certification').access_token + self.phantom_js("/survey/start/%s" % access_token, "odoo.__DEBUG__.services['web_tour.tour'].run('test_certification_success')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_certification_success.ready", login="demo") + + def test_05_certification_failure_tour(self): + access_token = self.env.ref('survey.vendor_certification').access_token + self.phantom_js("/survey/start/%s" % access_token, "odoo.__DEBUG__.services['web_tour.tour'].run('test_certification_failure')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_certification_failure.ready", login="demo") + + def test_06_survey_prefill(self): + access_token = self.env.ref('survey.survey_feedback').access_token + self.phantom_js("/survey/start/%s" % access_token, "odoo.__DEBUG__.services['web_tour.tour'].run('test_survey_prefill')", "odoo.__DEBUG__.services['web_tour.tour'].tours.test_survey_prefill.ready") |
