diff --git a/addons/survey/__init__.py b/addons/survey/__init__.py index 365022d3a33..c895bdaf188 100644 --- a/addons/survey/__init__.py +++ b/addons/survey/__init__.py @@ -4,3 +4,4 @@ import survey import controllers import wizard +import tests diff --git a/addons/survey/static/src/js/tour_test_survey.js b/addons/survey/static/src/js/tour_test_survey.js new file mode 100644 index 00000000000..a3ee49244fc --- /dev/null +++ b/addons/survey/static/src/js/tour_test_survey.js @@ -0,0 +1,198 @@ +odoo.define('survey.tour_test_survey', function (require) { +'use strict'; +var Core = require('web.core'); +var Tour = require('web.Tour'); +var _t = Core._t; + + +Tour.register({ + id: 'test_survey', + name: _t("try to create and fill survey"), + path: '/survey/start/user-feedback-form-1/phantom', + mode: 'test', + steps: [ + // Page-1 + { + title: "Clicking on Start Survey", + element: 'a.btn.btn-primary.btn-lg:contains("Start Survey")', + }, + // Question: Where do you develop your new features? + { + title: "Selecting answer 'Yes, I use a version < 7.0'", + element: 'select[name="1_1_1"]', + sampleText:'1', + }, + // Question: Which modules are you using/testing? + { + title: "Ticking answer 'Sales Management'", + element: 'input[name="1_1_2_5"][value="5"]', + sampleText:'5', + }, + { + title: "Clicking on Next Page", + element: 'button[value="next"]', + }, + // Page-2 + // Question: What do you think about the documentation available on doc.odoo.com? + { + title: "For 'It is up-to-date' checking 'Totally disagree'", + element: 'input[name="1_2_3_15"][value="11"]', + sampleText:'11', + }, + { + title: "For 'It helps in the beginning' ckecking 'Disagree'", + element: 'input[name="1_2_3_16"][value="12"]', + sampleText:'12', + }, + { + title: "For 'I use the contextual help in Odoo' checking 'Agree'", + element: 'input[name="1_2_3_17"][value="13"]', + sampleText:'13', + }, + { + title: "For 'It is complete' checking 'Totally disagree'", + element: 'input[name="1_2_3_18"][value="11"]', + sampleText:'11', + }, + { + title: "For 'It is clear' checking 'Disagree'", + element: 'input[name="1_2_3_19"][value="12"]', + sampleText:'12', + }, + // Question: What do you think about the process views of Odoo, available in the web client ? + { + title: "For 'They help new users to understand Odoo' checking 'Totally disagree'", + element: 'input[name="1_2_4_24"][value="20"]', + sampleText:'20', + }, + { + title: "For 'They are clean and correct' checking 'Totally disagree'", + element: 'input[name="1_2_4_25"][value="20"]', + sampleText:'20', + }, + { + title: "For 'They are useful on a daily usage' checking 'Totally disagree'", + element: 'input[name="1_2_4_26"][value="20"]', + sampleText:'20', + }, + { + title: "For 'A process is defined for all enterprise flows' checking 'Disagree'", + element: 'input[name="1_2_4_27"][value="21"]', + sampleText:'21', + }, + { + title: "For 'It's easy to find the process you need' checking 'Agree'", + element: 'input[name="1_2_4_28"][value="22"]', + sampleText:'22', + }, + // Question: Do you have suggestions on how to improve the process view? + { + title: "Writing answer", + element: 'textarea[name="1_2_5"]', + sampleText:'I do not want to provide any suggestions.', + }, + // Question: What do you think about the structure of the menus? + { + title: "Checking 'It can be improved'", + element: 'input[name="1_2_6_30"][value="30"]', + sampleText:'30', + }, + // Question: What do you think about the groups of users? + { + title: "For 'The security rules defined on groups are useful' checking 'Agree'", + element: 'input[name="1_2_7_36"][value="32"]', + sampleText:'32', + }, + { + title: "For 'Those security rules are standard and can be used out-of-the-box in most cases' checking 'Totally agree'", + element: 'input[name="1_2_7_37"][value="35"]', + sampleText:'35', + }, + { + title: "For 'The 'Usability/Extended View' group helps in daily work' checking 'Totally agree'", + element: 'input[name="1_2_7_38"][value="35"]', + sampleText:'35', + }, + { + title: "For 'The 'Usability/Extended View' group hides only optional fields' checking 'Totally agree'", + element: 'input[name="1_2_7_39"][value="33"]', + sampleText:'33', + }, + { + title: "For 'The groups set on menu items are relevant' checking 'Totally disagree'", + element: 'input[name="1_2_7_40"][value="32"]', + sampleText:'32', + }, + // Question: What do you think about the structure of the menus? + { + title: "Checking 'There are too few groups defined, security isn't accurate enough'", + element: 'input[name="1_2_8"][value="42"]', + sampleText:'42', + }, + // Question: What do you think about configuration wizards? + { + title: "For 'Descriptions and help tooltips are clear enough' checking 'Agree'", + element: 'input[name="1_2_9_48"][value="46"]', + sampleText:'46', + }, + { + title: "For 'Configuration wizard exists for each important setting' checking 'Agree'", + element: 'input[name="1_2_9_49"][value="46"]', + sampleText:'46', + }, + { + title: "For 'Extra modules proposed are relevant' checking 'Totally agree'", + element: 'input[name="1_2_9_50"][value="47"]', + sampleText:'47', + }, + { + title: "For 'Running the configuration wizards is a good way to spare time' checking 'Totally disagree'", + element: 'input[name="1_2_9_51"][value="44"]', + sampleText:'44', + }, + { + title: "Clicking on Next Page", + element: 'button[value="next"]', + }, + // Page-3 + // Question: How do you contribute or plan to contribute to Odoo? + { + title: "Checking 'I would like to contribute but I don not know how?'", + element: 'input[name="1_3_10_53"][value="53"]', + sampleText:'53', + }, + // Question: Do you have a proposition to help people to contribute? + { + title: "Writing answer", + element: 'textarea[name="1_3_11"]', + sampleText:'No. I do not have any proposition to help people to contribute.', + }, + // Question: Do you have a proposition to attract new contributors? + { + title: "Writing answer", + element: 'textarea[name="1_3_12"]', + sampleText:'No. I do not have any proposition to Attract new contributors.', + }, + { + title: "Clicking on Next Page", + element: 'button[value="next"]', + }, + // Page-4 + // Question: Where do you develop your new features? + { + title: "Checking 'I host them on my own website'", + element: 'input[name="1_4_13_59"][value="59"]', + sampleText:'59', + }, + { + title: "Finish Survey", + element: 'button[value="finish"]', + }, + { + title: "Thank you", + element: 'h1:contains("Thank you!")', + } + ] +}); + +}); diff --git a/addons/survey/survey.py b/addons/survey/survey.py index a5c377d383c..40733f97309 100644 --- a/addons/survey/survey.py +++ b/addons/survey/survey.py @@ -380,7 +380,7 @@ class survey_survey(osv.Model): 'max': round(max(all_inputs), 2), 'min': round(min(all_inputs), 2), 'sum': sum(all_inputs), - 'most_comman': Counter(all_inputs).most_common(5)}) + 'most_common': Counter(all_inputs).most_common(5)}) return result_summary def get_input_summary(self, cr, uid, question, current_filters=None, context=None): @@ -751,7 +751,7 @@ class survey_question(osv.Model): if question.comments_allowed: comment_tag = "%s_%s" % (answer_tag, 'comment') # Empty answer to mandatory question - if question.constr_mandatory and not answer_tag in post: + if question.constr_mandatory and answer_tag not in post: errors.update({answer_tag: question.constr_error_msg}) if question.constr_mandatory and answer_tag in post and post[answer_tag].strip() == '': errors.update({answer_tag: question.constr_error_msg}) @@ -767,6 +767,9 @@ class survey_question(osv.Model): comment_flag = answer_candidates.pop(("%s_%s" % (answer_tag, -1)), None) if question.comments_allowed: comment_answer = answer_candidates.pop(("%s_%s" % (answer_tag, 'comment')), '').strip() + # Preventing answers with blank value + if all([True if answer.strip() == '' else False for answer in answer_candidates.values()]): + errors.update({answer_tag: question.constr_error_msg}) # There is no answer neither comments (if comments count as answer) if not answer_candidates and question.comment_count_as_answer and (not comment_flag or not comment_answer): errors.update({answer_tag: question.constr_error_msg}) diff --git a/addons/survey/test/test_survey.py b/addons/survey/test/test_survey.py deleted file mode 100644 index 24b7ff4abc6..00000000000 --- a/addons/survey/test/test_survey.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from openerp.tests import common - - -class test_survey(common.TransactionCase): - - def setUp(self): - super(test_survey, self).setUp() - cr, uid, context = self.cr, self.uid, {} - pass - - def test_00_create_survey_and_questions(self): - cr, uid, context = self.cr, self.uid, {} - pass - - def test_01_fill_survey(self): - pass - - def test_02_answer_survey(self): - pass diff --git a/addons/survey/test/__init__.py b/addons/survey/tests/__init__.py similarity index 70% rename from addons/survey/test/__init__.py rename to addons/survey/tests/__init__.py index 07bb9e9a6a0..852d49d2a74 100644 --- a/addons/survey/test/__init__.py +++ b/addons/survey/tests/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import test_survey +import test_survey +import test_survey_ui diff --git a/addons/survey/tests/test_survey.py b/addons/survey/tests/test_survey.py new file mode 100644 index 00000000000..72d36427846 --- /dev/null +++ b/addons/survey/tests/test_survey.py @@ -0,0 +1,278 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import random +import re +from collections import Counter +from itertools import product +from urlparse import urljoin + +from openerp import _ +from openerp.exceptions import UserError +from openerp.tests.common import TransactionCase +from openerp.addons.website.models.website import slug + + +class TestSurvey(TransactionCase): + + def setUp(self): + super(TestSurvey, self).setUp() + User = self.env['res.users'].with_context({'no_reset_password': True}) + (group_survey_user, group_employee) = (self.ref('base.group_survey_user'), self.ref('base.group_user')) + self.survey_manager = User.create({ + 'name': 'Gustave Doré', 'login': 'Gustav', 'alias_name': 'gustav', 'email': 'gustav.dore@example.com', + 'groups_id': [(6, 0, [self.ref('base.group_survey_manager'), group_survey_user, group_employee])]}) + + self.survey_user = User.create({ + 'name': 'Lukas Peeters', 'login': 'Lukas', 'alias_name': 'lukas', 'email': 'lukas.petters@example.com', + 'groups_id': [(6, 0, [group_survey_user, group_employee])]}) + + self.user_public = User.create({ + 'name': 'Wout Janssens', 'login': 'Wout', 'alias_name': 'wout', 'email': 'wout.janssens@example.com', + 'groups_id': [(6, 0, [self.ref('base.group_public')])]}) + + self.Partner = self.env['res.partner'] + self.Survey = self.env['survey.survey'] + self.Question = self.env['survey.question'] + self.Stage = self.env['survey.stage'] + self.SurveyMailMessage = self.env['survey.mail.compose.message'] + self.UserInput = self.env['survey.user_input'] + self.UserInputLine = self.env['survey.user_input_line'] + + self.survey1 = self.Survey.sudo(self.survey_manager).create({'title': "S0", 'page_ids': [(0, 0, {'title': "P0"})]}) + self.page1 = self.survey1.page_ids[0] + + def test_00_create_minimal_survey(self): + question = self.Question.sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0'}) + self.assertEqual(self.survey1.title, "S0", msg="Title of the survey is somehow modified.") + self.assertEqual(len(self.survey1.page_ids), 1, msg="Additional Pages are linked with the survey after creation.") + self.assertEqual(self.page1.title, "P0", msg="Title of the page is somehow modified.") + self.assertEqual(len(self.page1.question_ids), 1, msg="Additional questions are linked with the page after creation.") + self.assertEqual(question.question, "Q0", msg="Title of the Question is somehow modified.") + + def test_01_question_type_validation_save_line_function(self): + for (question_type, text) in self.Question._columns['type'].selection: + # Each question ype must have validation function. + self.assertTrue(hasattr(self.Question, 'validate_' + question_type), msg="Question must have a validation method in\ + the form of 'validate_' followed by the name of the type.") + + # Survey Input Lines must have validation function for each line. + self.assertTrue(hasattr(self.UserInputLine, 'save_line_' + question_type), msg="Inputline must have Save method in \ + the form of 'save_line_' followed by the name of the type.") + + def test_02_question_answer_required(self): + for (question_type, text) in self.Question._columns['type'].selection: + # Blank value of field is not accepted for mandatory questions. + if question_type == 'multiple_choice': + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'multiple_choice', + 'constr_mandatory': True, 'constr_error_msg': 'Error', + 'labels_ids': [(0, 0, {'value': "MChoice0", "quizz_mark": 0}), (0, 0, {'value': "MChoice1", "quizz_mark": 0})]}) + + elif question_type == 'matrix': + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'matrix', 'matrix_subtype': 'simple', + 'constr_mandatory': True, 'constr_error_msg': 'Error', + 'labels_ids': [(0, 0, {'value': "Column0", "quizz_mark": 0}), (0, 0, {'value': "Column1", "quizz_mark": 0})], + 'labels_ids_2': [(0, 0, {'value': "Row0", "quizz_mark": 0}), (0, 0, {'value': "Row1", "quizz_mark": 0})]}) + + else: + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': question_type, 'constr_mandatory': True, 'constr_error_msg': 'Error'}) + answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id) + self.assertDictEqual({answer_tag: "Error"}, self.Question.validate_question(question, {answer_tag: ''}, answer_tag), + msg=("Validation function for type %s is unable to generate error if it is mandatory and answer is blank." % question_type)) + + def test_03_question_textbox(self): + questions = [ + self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'textbox', 'validation_email': True}), + self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q1', 'type': 'textbox', 'validation_required': True, + 'validation_length_min': 2, 'validation_length_max': 8, 'validation_error_msg': "Error"})] + + results = [('test @ testcom', _('This answer must be an email address')), ('t', 'Error')] + for i in range(len(questions)): + answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, questions[i].id) + self.assertEqual(self.Question.validate_question(questions[i], {answer_tag: results[i][0]}, answer_tag), {answer_tag: results[i][1]}, msg="\ + Validation function for textbox is unable to notify if answer is violating the validation rules") + + def test_04_question_numerical_box(self): + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box', 'validation_required': True, + 'validation_min_float_value': 2.1, 'validation_max_float_value': 3.0, 'validation_error_msg': "Error"}) + answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id) + results = [('aaa', _('This is not a number')), ('4.5', 'Error'), ('0.1', 'Error')] + for i in range(len(results)): + self.assertEqual(self.Question.validate_question(question, {answer_tag: results[i][0]}, answer_tag), {answer_tag: results[i][1]}, msg="\ + Validation function for type numerical_box is unable to notify if answer is violating the validation rules") + + def test_05_question_datetime(self): + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'datetime', 'validation_required': True, + 'validation_min_date': '2015-03-20 00:00:00', 'validation_max_date': '2015-03-25 00:00:00', 'validation_error_msg': "Error"}) + answer_tag = '%s_%s_%s' % (self.survey1.id, self.page1.id, question.id) + results = [('2015-55-10', _('This is not a date/time')), ('2015-03-19 00:00:00', 'Error'), ('2015-03-26 00:00:00', 'Error')] + for i in range(len(results)): + self.assertEqual(self.Question.validate_question(question, {answer_tag: results[i][0]}, answer_tag), {answer_tag: results[i][1]}, msg="\ + Validation function for type datetime is unable to notify if answer is violating the validation rules") + + def test_06_survey_sharing(self): + # Case-1: Executing action with correct data. + correct_survey = self.Survey.sudo(self.survey_manager).create({ + 'title': "S0", 'stage_id': self.Stage.search([('sequence', '=', 1)]).id, + 'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'type': 'free_text'})]})]}) + action = correct_survey.action_send_survey() + templates = self.env['ir.model.data'].get_object_reference('survey', 'email_template_survey') + template_id = templates[1] if len(templates) > 0 else False + ctx = dict(self.env.context) + ctx.update({ + 'default_model': 'survey.survey', + 'default_res_id': correct_survey.id, + 'default_survey_id': correct_survey.id, + 'default_use_template': bool(template_id), + 'default_template_id': template_id, + 'default_composition_mode': 'comment'}) + + self.assertDictEqual(action, { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'survey.mail.compose.message', + 'target': 'new', + 'context': ctx, + }) + + # Case-2: Executing action with incorrect data. + surveys = [ + self.Survey.sudo(self.survey_manager).create({ # Survey without any page or question. + 'title': "Test survey"}), + self.Survey.sudo(self.survey_manager).create({ # Closed Survey. + 'title': "S0", 'stage_id': self.Stage.search([('closed', '=', True)]).id, # Getting Closed stage id. + 'page_ids': [(0, 0, {'title': "P0", 'question_ids': [(0, 0, {'question': "Q0", 'type': 'free_text'})]})]})] + for survey in surveys: + self.assertRaises(UserError, survey.action_send_survey) + + def test_07_survey_email_message(self): + # Case-1: Executing send_mail with correct data. + partner = self.Partner.create({'name': 'Marie De Cock', 'email': 'marie.de.cock@gmail.com'}) + survey_mail_message = self.SurveyMailMessage.sudo(self.survey_manager).create({ + 'survey_id': self.survey1.id, 'public': 'email_public_link', 'body': '__URL__', 'partner_ids': [(4, partner.id)]}) + survey_mail_message.send_mail() + + # Case-2: Executing send_mail with incorrect data. + mail_messages = [ + self.SurveyMailMessage.sudo(self.survey_manager).create({ # Mail Message without __URL__ in body. + 'survey_id': self.survey1.id, 'public': 'email_public_link'}), + self.SurveyMailMessage.sudo(self.survey_manager).create({ # Mail Message without recipents. + 'survey_id': self.survey1.id, 'public': 'email_public_link', 'body': "__URL__"})] + for message in mail_messages: + self.assertRaises(UserError, message.send_mail) + + def test_08_survey_urls(self): + def validate_url(url): + """ Reference: https://github.com/django/django/blob/master/django/core/validators.py """ + url_regex = re.compile( + r'^https?://' # http:// or https:// + r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain... + r'localhost|' # localhost... + r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4 + r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6 + r'(?::\d+)?' # optional port + r'(?:/?|[/?]\S+)$', re.IGNORECASE) + return True if url_regex.match(url) else False + + base_url = self.env['ir.config_parameter'].get_param('web.base.url') + urltypes = {'public': 'start', 'print': 'print', 'result': 'results'} + for urltype, urltxt in urltypes.iteritems(): + survey_url = getattr(self.survey1, urltype + '_url') + survey_url_relative = getattr(self.survey1.with_context({'relative_url': True}), urltype + '_url') + self.assertTrue(validate_url(survey_url)) + url = "survey/%s/%s" % (urltxt, slug(self.survey1)) + full_url = urljoin(base_url, url) + self.assertEqual(full_url, survey_url) + self.assertEqual('/' + url, survey_url_relative) + if urltype == 'public': + url_html = 'Click here to start survey' + self.assertEqual(url_html % full_url, getattr(self.survey1, urltype + '_url_html'), msg="Public URL is incorrect") + self.assertEqual(url_html % ('/' + url), getattr(self.survey1.with_context({'relative_url': True}), urltype + '_url_html'), msg="Public URL is incorrect.") + + def test_09_answer_survey(self): + question = self.Question.sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0'}) + input_portal = self.UserInput.sudo(self.survey_user).create({ + 'survey_id': self.survey1.id, + 'partner_id': self.survey_user.partner_id.id, + 'user_input_line_ids': [(0, 0, { + 'skipped': False, 'answer_type': 'free_text', 'value_free_text': "Test Answer", + 'survey_id': self.survey1.id, 'page_id': self.page1, 'question_id': question.id})]}) + + input_public = self.UserInput.sudo(self.user_public).create({ + 'survey_id': self.survey1.id, + 'partner_id': self.survey_user.partner_id.id, + 'user_input_line_ids': [(0, 0, { + 'skipped': False, 'answer_type': 'free_text', 'value_free_text': "Test Answer", + 'survey_id': self.survey1.id, 'page_id': self.page1, 'question_id': question.id})]}) + + answers = [input_portal.user_input_line_ids[0], input_public.user_input_line_ids[0]] + expected_values = {'answer_type': 'free_text', 'value_free_text': "Test Answer"} + for answer in answers: + for field, value in expected_values.iteritems(): + self.assertEqual(getattr(answer, field), value, msg="Unable to answer the survey. Expected behaviour of %s is not proper." % (field)) + + def test_10_survey_result_simple_multiple_choice(self): + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'simple_choice', + 'labels_ids': [(0, 0, {'value': "Choice0", 'quizz_mark': 0}), (0, 0, {'value': "Choice1", 'quizz_mark': 0})]}) + for i in range(3): + self.UserInput.sudo(self.user_public).create({'survey_id': self.survey1.id, 'user_input_line_ids': [(0, 0, { + 'question_id': question.id, + 'answer_type': 'suggestion', + 'value_suggested': random.choice(question.labels_ids.ids)})]}) + 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] + prp_result = self.Survey.prepare_result(question)['answers'] + answers.sort() + prp_result.sort() + self.assertEqual(prp_result, answers, msg="Statistics of simple, multiple choice questions are different from expectation") + + def test_11_survey_result_matrix(self): + question = self.Question.sudo(self.survey_manager).create({ + 'page_id': self.page1.id, 'question': 'Q0', 'type': 'matrix', 'matrix_subtype': 'simple', + 'labels_ids': [(0, 0, {'value': "Column0", "quizz_mark": 0}), (0, 0, {'value': "Column1", "quizz_mark": 0})], + 'labels_ids_2': [(0, 0, {'value': "Row0", "quizz_mark": 0}), (0, 0, {'value': "Row1", "quizz_mark": 0})]}) + for i in range(3): + self.UserInput.sudo(self.user_public).create({'survey_id': self.survey1.id, 'user_input_line_ids': [(0, 0, { + 'question_id': question.id, 'answer_type': 'suggestion', 'value_suggested': random.choice(question.labels_ids.ids), + 'value_suggested_row': random.choice(question.labels_ids_2.ids)})]}) + lines = [(line.value_suggested_row.id, line.value_suggested.id) for line in question.user_input_line_ids] + res = {} + for i in product(question.labels_ids_2.ids, question.labels_ids.ids): + res[i] = lines.count((i)) + self.assertEqual(self.Survey.prepare_result(question)['result'], res, msg="Statistics of matrix type questions are different from expectations") + + def test_12_survey_result_numeric_box(self): + question = self.Question.sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box'}) + num = map(float, random.sample(range(1, 100), 3)) + nsum = sum(num) + for i in range(3): + self.UserInput.sudo(self.user_public).create({'survey_id': self.survey1.id, 'user_input_line_ids': [(0, 0, { + 'question_id': question.id, 'answer_type': 'number', 'value_number': num[i]})]}) + exresult = { + 'average': round((nsum / len(num)), 2), 'max': round(max(num), 2), + 'min': round(min(num), 2), 'sum': nsum, 'most_common': Counter(num).most_common(5)} + result = self.Survey.prepare_result(question) + for key in exresult.keys(): + self.assertEqual(result[key], exresult[key], msg="Statistics of numeric box type questions are different from expectations") + + def test_13_survey_actions(self): + self.Question.sudo(self.survey_manager).create({'page_id': self.page1.id, 'question': 'Q0', 'type': 'numerical_box'}) + + actions = { + 'start': {'method': 'public', 'token': '/test', 'text': 'Start'}, + 'print': {'method': 'print', 'token': '/test', 'text': 'Print'}, + 'result': {'method': 'result', 'token': '', 'text': 'Results of the'}, + 'test': {'method': 'public', 'token': '/phantom', 'text': 'Results of the'}} + for action, val in actions.iteritems(): + result = getattr(self.survey1.with_context({'survey_token': val['token'][1:]}), 'action_' + action + '_survey')() + url = getattr(self.survey1.with_context({'relative_url': True}), val['method'] + '_url') + val['token'] + self.assertEqual(result['url'], url) diff --git a/addons/survey/tests/test_survey_ui.py b/addons/survey/tests/test_survey_ui.py new file mode 100644 index 00000000000..79a85c3ef31 --- /dev/null +++ b/addons/survey/tests/test_survey_ui.py @@ -0,0 +1,16 @@ +import openerp.tests +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +@openerp.tests.common.at_install(False) +@openerp.tests.common.post_install(True) +class TestUi(openerp.tests.HttpCase): + + def test_01_admin_survey_tour(self): + self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey", login="admin") + + def test_02_demo_survey_tour(self): + self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey", login="demo") + + def test_03_public_survey_tour(self): + self.phantom_js("/", "odoo.__DEBUG__.services['web.Tour'].run('test_survey', 'test')", "odoo.__DEBUG__.services['web.Tour'].tours.test_survey") diff --git a/addons/survey/views/survey_result.xml b/addons/survey/views/survey_result.xml index 11ce73eca33..f1b3b498646 100644 --- a/addons/survey/views/survey_result.xml +++ b/addons/survey/views/survey_result.xml @@ -274,7 +274,7 @@
  • - Most Common + Most Common
  • @@ -294,7 +294,7 @@ - + diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 840390eda36..37078640285 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -92,6 +92,7 @@