Currently, in demo data (or data) of some surveys, there are records of 'survey.question' having 'is_page' field value as true and 'question_type' is not defined. When question type is not defined, default value 'simple_choice' is assigned to the 'question_type' field. Now when we create a live session of that survey and go to the page, it tries to read the data for bar chart but data is not available (undefined) and the traceback is thrown. This happens because question types 'simple_choice' and 'multiple_choice') are expected to load a bar chart. It used to work before commit[1] where default 'question_type' value was being set to 'text_box' (so attempt to load bar chart was not made). This commit improves the behavior by adapting data/demo data/test cases and by adding a python constraint that prevents question creation of page type if there is a question type set, and compute `question_type` based on `is_page` field. Now that we have python constraint and a compute method, we no longer need the `default_get` method, so it is also removed. commit[1] - https://github.com/odoo/odoo/commit/1fb99d79b1567d4c150dc07f309ce54a3beea8e3 taskID-2841582 closes odoo/odoo#93414 Related: odoo/enterprise#28305 Related: odoo/upgrade#3600 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
362 lines
17 KiB
Python
362 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import datetime
|
|
|
|
from odoo.addons.survey.tests import common
|
|
from odoo.exceptions import AccessError, UserError
|
|
from odoo.tests import tagged
|
|
from odoo.tests.common import users, HttpCase
|
|
from odoo.tools import mute_logger
|
|
|
|
|
|
@tagged('security')
|
|
class TestAccess(common.TestSurveyCommon):
|
|
|
|
def setUp(self):
|
|
super(TestAccess, self).setUp()
|
|
|
|
self.answer_0 = self._add_answer(self.survey, self.customer)
|
|
self.answer_0_0 = self._add_answer_line(self.question_ft, self.answer_0, 'Test Answer')
|
|
self.answer_0_1 = self._add_answer_line(self.question_num, self.answer_0, 5)
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_emp')
|
|
def test_access_survey_employee(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].create({'title': 'Test Survey 2'})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].search([('title', 'ilike', 'Test')])
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).read(['title'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_portal')
|
|
def test_access_survey_portal(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].create({'title': 'Test Survey 2'})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].search([('title', 'ilike', 'Test')])
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).read(['title'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_public')
|
|
def test_access_survey_public(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].create({'title': 'Test Survey 2'})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.survey'].search([('title', 'ilike', 'Test')])
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).read(['title'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.page_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.question_ft.with_user(self.env.user).unlink()
|
|
|
|
@users('survey_manager')
|
|
def test_access_survey_survey_manager(self):
|
|
# Create: all
|
|
survey = self.env['survey.survey'].create({'title': 'Test Survey 2'})
|
|
self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': survey.id})
|
|
self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'survey_id': survey.id})
|
|
|
|
# Read: all
|
|
surveys = self.env['survey.survey'].search([('title', 'ilike', 'Test')])
|
|
self.assertEqual(surveys, self.survey | survey)
|
|
surveys.read(['title'])
|
|
|
|
# Write: all
|
|
(self.survey | survey).write({'title': 'New Title'})
|
|
|
|
# Unlink: all
|
|
(self.survey | survey).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('survey_user')
|
|
def test_access_survey_survey_user(self):
|
|
# Create: own only
|
|
survey = self.env['survey.survey'].create({'title': 'Test Survey 2'})
|
|
self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': survey.id})
|
|
self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'survey_id': survey.id})
|
|
|
|
# Read: all
|
|
surveys = self.env['survey.survey'].search([('title', 'ilike', 'Test')])
|
|
self.assertEqual(surveys, self.survey | survey)
|
|
surveys.read(['title'])
|
|
|
|
# Write: own only
|
|
survey.write({'title': 'New Title'})
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).write({'title': 'New Title'})
|
|
|
|
# Unlink: own only
|
|
survey.unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.survey.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_emp')
|
|
def test_access_answers_employee(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].create({'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).write({'state': 'done'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0_0.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_portal')
|
|
def test_access_answers_portal(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].create({'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).write({'state': 'done'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0_0.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('user_public')
|
|
def test_access_answers_public(self):
|
|
# Create: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].create({'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
|
|
|
|
# Read: nope
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
|
|
|
|
# Write: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).write({'state': 'done'})
|
|
|
|
# Unlink: nope
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0_0.with_user(self.env.user).unlink()
|
|
|
|
@mute_logger('odoo.addons.base.models.ir_model')
|
|
@users('survey_user')
|
|
def test_access_answers_survey_user(self):
|
|
survey_own = self.env['survey.survey'].create({'title': 'Other'})
|
|
self.env['survey.question'].create({'title': 'Other', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': survey_own.id})
|
|
question_own = self.env['survey.question'].create({'title': 'Other Question', 'sequence': 1, 'survey_id': survey_own.id})
|
|
|
|
# Create: own survey only
|
|
answer_own = self.env['survey.user_input'].create({'survey_id': survey_own.id})
|
|
with self.assertRaises(AccessError):
|
|
self.env['survey.user_input.line'].create({'question_id': question_own.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_own.id})
|
|
|
|
# Read: always
|
|
answers = self.env['survey.user_input'].search([('survey_id', 'in', [survey_own.id, self.survey.id])])
|
|
self.assertEqual(answers, answer_own | self.answer_0)
|
|
|
|
answer_lines = self.env['survey.user_input.line'].search([('survey_id', 'in', [survey_own.id, self.survey.id])])
|
|
self.assertEqual(answer_lines, self.answer_0_0 | self.answer_0_1)
|
|
|
|
self.env['survey.user_input'].browse(answer_own.ids).read(['state'])
|
|
self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
|
|
|
|
self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
|
|
|
|
# Create: own survey only (moved after read because DB not correctly rollbacked with assertRaises)
|
|
with self.assertRaises(AccessError):
|
|
answer_other = self.env['survey.user_input'].create({'survey_id': self.survey.id})
|
|
with self.assertRaises(AccessError):
|
|
answer_line_other = self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
|
|
|
|
# Write: own survey only
|
|
answer_own.write({'state': 'done'})
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).write({'state': 'done'})
|
|
|
|
# Unlink: own survey only
|
|
answer_own.unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0.with_user(self.env.user).unlink()
|
|
with self.assertRaises(AccessError):
|
|
self.answer_0_0.with_user(self.env.user).unlink()
|
|
|
|
@users('survey_manager')
|
|
def test_access_answers_survey_manager(self):
|
|
admin = self.env.ref('base.user_admin')
|
|
with self.with_user(admin.login):
|
|
survey_other = self.env['survey.survey'].create({'title': 'Other'})
|
|
self.env['survey.question'].create({'title': 'Other', 'sequence': 0, 'is_page': True, 'question_type': False, 'survey_id': survey_other.id})
|
|
question_other = self.env['survey.question'].create({'title': 'Other Question', 'sequence': 1, 'survey_id': survey_other.id})
|
|
self.assertEqual(survey_other.create_uid, admin)
|
|
self.assertEqual(question_other.create_uid, admin)
|
|
|
|
# Create: always
|
|
answer_own = self.env['survey.user_input'].create({'survey_id': self.survey.id})
|
|
answer_other = self.env['survey.user_input'].create({'survey_id': survey_other.id})
|
|
answer_line_own = self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_own.id})
|
|
answer_line_other = self.env['survey.user_input.line'].create({'question_id': question_other.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_other.id})
|
|
|
|
# Read: always
|
|
answers = self.env['survey.user_input'].search([('survey_id', 'in', [survey_other.id, self.survey.id])])
|
|
self.assertEqual(answers, answer_own | answer_other | self.answer_0)
|
|
|
|
answer_lines = self.env['survey.user_input.line'].search([('survey_id', 'in', [survey_other.id, self.survey.id])])
|
|
self.assertEqual(answer_lines, answer_line_own | answer_line_other | self.answer_0_0 | self.answer_0_1)
|
|
|
|
self.env['survey.user_input'].browse(answer_own.ids).read(['state'])
|
|
self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
|
|
|
|
self.env['survey.user_input.line'].browse(answer_line_own.ids).read(['value_numerical_box'])
|
|
self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
|
|
|
|
# Write: always
|
|
answer_own.write({'state': 'done'})
|
|
answer_other.write({'partner_id': self.env.user.partner_id.id})
|
|
|
|
# Unlink: always
|
|
(answer_own | answer_other | self.answer_0).unlink()
|
|
|
|
|
|
@tagged('post_install')
|
|
class TestSurveySecurityControllers(common.TestSurveyCommon, HttpCase):
|
|
def test_survey_start_short(self):
|
|
# avoid name clash with existing data
|
|
surveys = self.env['survey.survey'].search([
|
|
('session_state', 'in', ['ready', 'in_progress'])
|
|
])
|
|
self.survey.write({
|
|
'session_state': 'ready',
|
|
'session_code': '123456',
|
|
'session_start_time': datetime.datetime.now(),
|
|
'access_mode': 'public',
|
|
'users_login_required': False,
|
|
})
|
|
|
|
# right short access token
|
|
response = self.url_open('/s/123456')
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn('The session will begin automatically when the host starts', response.text)
|
|
|
|
# `like` operator injection
|
|
response = self.url_open('/s/______')
|
|
self.assertFalse(self.survey.title in response.text)
|
|
|
|
# right short token, but closed survey
|
|
self.survey.action_archive()
|
|
response = self.url_open('/s/123456')
|
|
self.assertFalse(self.survey.title in response.text)
|
|
|
|
# right short token, but wrong `session_state`
|
|
self.survey.write({'session_state': False, 'active': True})
|
|
response = self.url_open('/s/123456')
|
|
self.assertFalse(self.survey.title in response.text)
|