diff --git a/addons/event/tests/__init__.py b/addons/event/tests/__init__.py index 360b9308e19..881edfc8974 100644 --- a/addons/event/tests/__init__.py +++ b/addons/event/tests/__init__.py @@ -1,3 +1,6 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import test_event_flow, test_mail_schedule +from . import test_event_flow +from . import test_event_internals +from . import test_event_mail_schedule diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py index 06de8639651..56c14a78451 100644 --- a/addons/event/tests/common.py +++ b/addons/event/tests/common.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import datetime, timedelta from odoo import fields +from odoo.addons.mail.tests.common import mail_new_test_user from odoo.tests import common @@ -12,36 +14,70 @@ class TestEventCommon(common.SavepointCase): def setUpClass(cls): super(TestEventCommon, cls).setUpClass() - # User groups - cls.group_employee_id = cls.env.ref('base.group_user').id - cls.group_event_user_id = cls.env.ref('event.group_event_user').id - cls.group_event_manager_id = cls.env.ref('event.group_event_manager').id - cls.group_system_id = cls.env.ref('base.group_system').id - # Test users to use through the various tests - cls.user_eventuser = cls.env['res.users'].with_context({'no_reset_password': True}).create({ - 'name': 'Armande EventUser', - 'login': 'Armande', - 'email': 'armande.eventuser@example.com', - 'tz': 'Europe/Brussels', - 'groups_id': [(6, 0, [cls.group_employee_id, cls.group_event_user_id])] - }) - cls.user_eventmanager = cls.env['res.users'].with_context({'no_reset_password': True}).create({ - 'name': 'Bastien EventManager', - 'login': 'bastien', - 'email': 'bastien.eventmanager@example.com', - 'tz': 'Europe/Brussels', - 'groups_id': [(6, 0, [ - cls.group_employee_id, - cls.group_event_manager_id, - cls.group_system_id])] - }) + cls.user_portal = mail_new_test_user( + cls.env, login='portal_test', + name='Patrick Portal', email='patrick.portal@test.example.com', + notification_type='email', company_id=cls.env.ref("base.main_company").id, + groups='base.group_portal') + cls.user_employee = mail_new_test_user( + cls.env, login='user_employee', + name='Eglantine Employee', email='eglantine.employee@test.example.com', + tz='Europe/Brussels', notification_type='inbox', + company_id=cls.env.ref("base.main_company").id, + groups='base.group_user', + ) + cls.user_eventuser = mail_new_test_user( + cls.env, login='user_eventuser', + name='Ursule EventUser', email='ursule.eventuser@test.example.com', + tz='Europe/Brussels', notification_type='inbox', + company_id=cls.env.ref("base.main_company").id, + groups='base.group_user,event.group_event_user', + ) + cls.user_eventmanager = mail_new_test_user( + cls.env, login='user_eventmanager', + name='Martine EventManager', email='martine.eventmanager@test.example.com', + tz='Europe/Brussels', notification_type='inbox', + company_id=cls.env.ref("base.main_company").id, + groups='base.group_user,event.group_event_manager', + ) + cls.customer = cls.env['res.partner'].create({ + 'name': 'Constantin Customer', + 'email': 'constantin@example.com', + 'country_id': cls.env.ref('base.be').id, + 'phone': '0485112233', + }) + cls.event_type_complex = cls.env['event.type'].create({ + 'name': 'Update Type', + 'auto_confirm': True, + 'is_online': False, + 'has_seats_limitation': True, + 'default_registration_min': 10, + 'default_registration_max': 30, + 'use_timezone': True, + 'default_timezone': 'Europe/Paris', + 'use_hashtag': True, + 'default_hashtag': 'amazing', + 'use_mail_schedule': True, + 'event_type_mail_ids': [ + (0, 0, { # right at subscription + 'interval_unit': 'now', + 'interval_type': 'after_sub', + 'template_id': cls.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')}), + (0, 0, { # 1 days before event + 'interval_nbr': 1, + 'interval_unit': 'days', + 'interval_type': 'before_event', + 'template_id': cls.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')}), + ], + }) cls.event_0 = cls.env['event.event'].create({ 'name': 'TestEvent', 'auto_confirm': True, 'date_begin': fields.Datetime.to_string(datetime.today() + timedelta(days=1)), 'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=15)), + 'date_tz': 'Europe/Brussels', }) # set country in order to format belgium numbers diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index d57dd62189d..6c317b74a02 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -1,22 +1,19 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. import datetime + from dateutil.relativedelta import relativedelta from odoo.addons.event.tests.common import TestEventCommon -from odoo.exceptions import ValidationError, UserError, AccessError +from odoo.exceptions import ValidationError from odoo.tools import mute_logger -from odoo.fields import Datetime -try: - from unittest.mock import patch -except ImportError: - from mock import patch class TestEventFlow(TestEventCommon): @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_00_basic_event_auto_confirm(self): + def test_event_auto_confirm(self): """ Basic event management with auto confirmation """ # EventUser creates a new event: ok test_event = self.env['event.event'].with_user(self.user_eventmanager).create({ @@ -58,7 +55,7 @@ class TestEventFlow(TestEventCommon): self.assertEqual(test_event.seats_used, 2, 'Event: incorrect number of attendees after closing registration') @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_10_advanced_event_flow(self): + def test_event_flow(self): """ Avanced event flow: no auto confirmation, manage minimum / maximum seats, ... """ # EventUser creates a new event: ok @@ -77,59 +74,3 @@ class TestEventFlow(TestEventCommon): self.assertEqual( test_reg1.state, 'draft', 'Event: new registration should not be confirmed with auto_confirmation parameter being False') - - def test_event_access_rights(self): - # EventManager required to create or update events - with self.assertRaises(AccessError): - self.env['event.event'].with_user(self.user_eventuser).create({ - 'name': 'TestEvent', - 'date_begin': datetime.datetime.now() + relativedelta(days=-1), - 'date_end': datetime.datetime.now() + relativedelta(days=1), - 'seats_max': 10, - }) - with self.assertRaises(AccessError): - self.event_0.with_user(self.user_eventuser).write({ - 'name': 'TestEvent Modified', - }) - - # Settings access rights required to enable some features - self.user_eventmanager.write({'groups_id': [ - (3, self.env.ref('base.group_system').id), - (4, self.env.ref('base.group_erp_manager').id) - ]}) - with self.assertRaises(AccessError): - event_config = self.env['res.config.settings'].with_user(self.user_eventmanager).create({ - }) - event_config.execute() - - def test_event_data(self): - self.event_0.write({'registration_ids': [(0, 0, {'partner_id': self.user_eventuser.partner_id.id})]}) - self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'tomorrow') - self.event_0.write({ - 'date_begin': '2019-11-09 14:30:00', - 'date_end': '2019-11-10 00:00:00', - 'date_tz': 'Mexico/General' - }) - self.assertTrue(self.event_0.is_one_day) - - def test_event_date_range(self): - self.event_0.write({'registration_ids': [(0, 0, {'partner_id': self.user_eventuser.partner_id.id})]}) - self.patcher = patch('odoo.addons.event.models.event.fields.Datetime', wraps=Datetime) - self.mock_datetime = self.patcher.start() - - self.mock_datetime.now.return_value = datetime.datetime(2015, 12, 31, 12, 0) - - self.event_0.date_begin = datetime.datetime(2015, 12, 31, 18, 0) - self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'today') - - self.event_0.date_begin = datetime.datetime(2016, 1, 1, 6, 0) - self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'tomorrow') - - self.event_0.date_begin = datetime.datetime(2016, 1, 2, 6, 0) - self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'in 2 days') - - self.mock_datetime.now.return_value = datetime.datetime(2015, 12, 10, 12, 0) - self.event_0.date_begin = datetime.datetime(2016, 1, 25, 6, 0) - self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'next month') - - self.patcher.stop() diff --git a/addons/event/tests/test_event_internals.py b/addons/event/tests/test_event_internals.py new file mode 100644 index 00000000000..905222dcc5f --- /dev/null +++ b/addons/event/tests/test_event_internals.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta +from unittest.mock import patch + +from odoo.addons.event.tests.common import TestEventCommon +from odoo.exceptions import AccessError +from odoo.fields import Datetime as FieldsDatetime +from odoo.tests.common import users +from odoo.tools import mute_logger + + +class TestEventData(TestEventCommon): + + @users('user_eventmanager') + def test_event_date_computation(self): + self.patcher = patch('odoo.addons.event.models.event.fields.Datetime', wraps=FieldsDatetime) + self.mock_datetime = self.patcher.start() + self.mock_datetime.now.return_value = datetime(2020, 1, 31, 8, 0, 0) + + event = self.event_0.with_user(self.env.user) + event.write({ + 'registration_ids': [(0, 0, {'partner_id': self.customer.id})], + 'date_begin': datetime(2020, 1, 31, 15, 0, 0), + 'date_end': datetime(2020, 4, 5, 18, 0, 0), + }) + registration = event.registration_ids[0] + self.assertEqual(registration.get_date_range_str(), u'today') + + event.date_begin = datetime(2020, 2, 1, 15, 0, 0) + self.assertEqual(registration.get_date_range_str(), u'tomorrow') + + event.date_begin = datetime(2020, 2, 2, 6, 0, 0) + self.assertEqual(registration.get_date_range_str(), u'in 2 days') + + event.date_begin = datetime(2020, 2, 20, 17, 0, 0) + self.assertEqual(registration.get_date_range_str(), u'next month') + + event.date_begin = datetime(2020, 3, 1, 10, 0, 0) + self.assertEqual(registration.get_date_range_str(), u'on Mar 1, 2020, 11:00:00 AM') + + event.write({ + 'date_begin': '2019-11-09 14:30:00', + 'date_end': '2019-11-10 02:00:00', + 'date_tz': 'Mexico/General' + }) + self.assertTrue(event.is_one_day) + + self.patcher.stop() + + @users('user_eventmanager') + def test_event_fields(self): + event_type = self.event_type_complex.with_user(self.env.user) + event = self.env['event.event'].create({ + 'name': 'Event Update Type', + 'event_type_id': event_type.id, + 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), + 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), + }) + event._onchange_type() + self.assertFalse(event.is_online) + self.assertEqual(event.address_id, self.env.user.company_id.partner_id) + # seats: coming from event type configuration + self.assertEqual(event.seats_availability, 'limited') + self.assertEqual(event.seats_available, event.event_type_id.default_registration_max) + self.assertEqual(event.seats_unconfirmed, 0) + self.assertEqual(event.seats_reserved, 0) + self.assertEqual(event.seats_used, 0) + self.assertEqual(event.seats_expected, 0) + + # set is_online: should reset the address_id field + event.update({'is_online': True}) + event._onchange_is_online() + self.assertTrue(event.is_online) + self.assertFalse(event.address_id) + + # create registration in order to check the seats computation + self.assertTrue(event.auto_confirm) + for x in range(5): + reg = self.env['event.registration'].create({ + 'event_id': event.id + }) + self.assertEqual(reg.state, 'open') + reg_draft = self.env['event.registration'].create({ + 'event_id': event.id + }) + reg_draft.write({'state': 'draft'}) + reg_done = self.env['event.registration'].create({ + 'event_id': event.id + }) + reg_done.write({'state': 'done'}) + self.assertEqual(event.seats_available, event.event_type_id.default_registration_max - 6) + self.assertEqual(event.seats_unconfirmed, 1) + self.assertEqual(event.seats_reserved, 5) + self.assertEqual(event.seats_used, 1) + self.assertEqual(event.seats_expected, 7) + + @users('user_eventmanager') + @mute_logger('odoo.models.unlink') + def test_event_type_configuration(self): + self.assertEqual(self.env.user.tz, 'Europe/Brussels') + + event_type = self.event_type_complex.with_user(self.env.user) + event_type.write({ + 'use_mail_schedule': False, + }) + # self.assertEqual(event_type.event_type_mail_ids, self.env['event.type.mail']) # TDE FIXME: currently crashing + + event = self.env['event.event'].create({ + 'name': 'Event Update Type', + 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), + 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), + 'auto_confirm': False, + 'twitter_hashtag': 'somuchwow', + 'is_online': True, + }) + self.assertEqual(event.date_tz, self.env.user.tz) + self.assertEqual(event.seats_availability, 'unlimited') + self.assertFalse(event.auto_confirm) + self.assertEqual(event.twitter_hashtag, 'somuchwow') + self.assertTrue(event.is_online) + self.assertEqual(event.event_mail_ids, self.env['event.mail']) + + event.update({'event_type_id': event_type.id}) + event._onchange_type() + self.assertEqual(event.date_tz, 'Europe/Paris') + self.assertEqual(event.seats_availability, 'limited') + self.assertEqual(event.seats_min, event_type.default_registration_min) + self.assertEqual(event.seats_max, event_type.default_registration_max) + self.assertTrue(event.auto_confirm) + self.assertEqual(event.twitter_hashtag, event_type.default_hashtag) + self.assertFalse(event.is_online) + # self.assertEqual(event.event_mail_ids, self.env['event.mail']) # TDE FIXME: currently crashing + + event_type.write({ + 'use_mail_schedule': True, + 'event_type_mail_ids': [(5, 0), (0, 0, { + 'interval_nbr': 1, 'interval_unit': 'days', 'interval_type': 'before_event', + 'template_id': self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')})] + }) + event._onchange_type() + self.assertEqual(event.event_mail_ids.interval_nbr, 1) + self.assertEqual(event.event_mail_ids.interval_unit, 'days') + self.assertEqual(event.event_mail_ids.interval_type, 'before_event') + self.assertEqual(event.event_mail_ids.template_id, self.env.ref('event.event_reminder')) + + +class TestEventSecurity(TestEventCommon): + + @users('user_employee') + @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') + def test_event_access_employee(self): + # employee can read events (sure ?) + event = self.event_0.with_user(self.env.user) + event.read(['name']) + # event.stage_id.read(['name', 'description']) + # event.event_type_id.read(['name', 'has_seats_limitation']) + + with self.assertRaises(AccessError): + self.env['event.event'].create({ + 'name': 'TestEvent', + 'date_begin': datetime.now() + relativedelta(days=-1), + 'date_end': datetime.now() + relativedelta(days=1), + 'seats_max': 10, + }) + + with self.assertRaises(AccessError): + event.write({ + 'name': 'TestEvent Modified', + }) + + with self.assertRaises(AccessError): + self.env['event.stage'].create({ + 'name': 'TestStage', + }) + + @users('user_eventuser') + @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') + def test_event_access_event_user(self): + event = self.event_0.with_user(self.env.user) + event.read(['name', 'user_id', 'kanban_state_label']) + + with self.assertRaises(AccessError): + self.env['event.event'].create({ + 'name': 'TestEvent', + 'date_begin': datetime.now() + relativedelta(days=-1), + 'date_end': datetime.now() + relativedelta(days=1), + 'seats_max': 10, + }) + + with self.assertRaises(AccessError): + event.write({ + 'name': 'TestEvent Modified', + }) + + # with self.assertRaises(AccessError): + # self.env['event.stage'].create({ + # 'name': 'TestStage', + # }) + + @users('user_eventmanager') + @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') + def test_event_access_event_manager(self): + # EventManager can do about everything + event_type = self.env['event.type'].create({ + 'name': 'ManagerEventType', + 'use_mail_schedule': True, + 'event_type_mail_ids': [(5, 0), (0, 0, { + 'interval_nbr': 1, 'interval_unit': 'days', 'interval_type': 'before_event', + 'template_id': self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')})] + }) + event = self.env['event.event'].create({ + 'name': 'ManagerEvent', + 'date_begin': datetime.now() + relativedelta(days=-1), + 'date_end': datetime.now() + relativedelta(days=1), + }) + event.update({'event_type_id': event_type.id}) + event._onchange_type() + event.flush() + + registration = self.env['event.registration'].create({'event_id': event.id}) + registration.write({'name': 'Myself'}) + + stage = self.env.ref('event.event_stage_done') + stage.write({'name': 'ManagerEnded'}) + event.write({'stage_id': stage.id}) + + registration.unlink() + event.unlink() + stage.unlink() + event_type.unlink() + + # Settings access rights required to enable some features + self.user_eventmanager.write({'groups_id': [ + (3, self.env.ref('base.group_system').id), + (4, self.env.ref('base.group_erp_manager').id) + ]}) + with self.assertRaises(AccessError): + event_config = self.env['res.config.settings'].with_user(self.user_eventmanager).create({ + }) + event_config.execute() diff --git a/addons/event/tests/test_mail_schedule.py b/addons/event/tests/test_event_mail_schedule.py similarity index 96% rename from addons/event/tests/test_mail_schedule.py rename to addons/event/tests/test_event_mail_schedule.py index 678342c74fa..ba1223ccc0f 100644 --- a/addons/event/tests/test_mail_schedule.py +++ b/addons/event/tests/test_event_mail_schedule.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. -import datetime from dateutil.relativedelta import relativedelta -from odoo import fields, tools +from odoo import fields from odoo.addons.event.tests.common import TestEventCommon from odoo.tools import mute_logger @@ -11,7 +11,7 @@ from odoo.tools import mute_logger class TestMailSchedule(TestEventCommon): @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_00_event_mail_schedule(self): + def test_event_mail_schedule(self): """ Test mail scheduling for events """ now = fields.Datetime.now() event_date_begin = now + relativedelta(days=1) diff --git a/addons/event_sale/tests/test_event_sale.py b/addons/event_sale/tests/test_event_sale.py index b42ae306319..720b3ad7fbf 100644 --- a/addons/event_sale/tests/test_event_sale.py +++ b/addons/event_sale/tests/test_event_sale.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. import datetime from odoo.tests import common -from odoo.fields import Datetime -from unittest.mock import patch class EventSaleTest(common.TransactionCase): diff --git a/addons/event_sms/tests/test_sms_schedule.py b/addons/event_sms/tests/test_sms_schedule.py index e1aa63e6800..fae816dc215 100644 --- a/addons/event_sms/tests/test_sms_schedule.py +++ b/addons/event_sms/tests/test_sms_schedule.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from dateutil.relativedelta import relativedelta from odoo.addons.event.tests.common import TestEventCommon from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.sms.tests.common import MockSMS -from odoo.tools import mute_logger class TestSMSSchedule(TestEventCommon, MockSMS): diff --git a/addons/website_event_questions/__init__.py b/addons/website_event_questions/__init__.py index 5905766d867..8114cc7a69b 100644 --- a/addons/website_event_questions/__init__.py +++ b/addons/website_event_questions/__init__.py @@ -4,3 +4,4 @@ from . import controllers from . import models from . import report +from . import tests diff --git a/addons/website_event_questions/tests/__init__.py b/addons/website_event_questions/tests/__init__.py new file mode 100644 index 00000000000..d03842855ce --- /dev/null +++ b/addons/website_event_questions/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import common +from . import test_event_internals diff --git a/addons/website_event_questions/tests/common.py b/addons/website_event_questions/tests/common.py new file mode 100644 index 00000000000..e31f0356e09 --- /dev/null +++ b/addons/website_event_questions/tests/common.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.event.tests.common import TestEventCommon + + +class TestEventQuestionCommon(TestEventCommon): + + @classmethod + def setUpClass(cls): + super(TestEventQuestionCommon, cls).setUpClass() + + cls.event_question_1 = cls.env['event.question'].create({ + 'title': 'Question1', + 'event_type_id': cls.event_type_complex.id, + 'is_individual': True, + 'answer_ids': [ + (0, 0, {'name': 'Q1-Answer1'}), + (0, 0, {'name': 'Q1-Answer2'}) + ], + }) + cls.event_question_2 = cls.env['event.question'].create({ + 'title': 'Question2', + 'event_type_id': cls.event_type_complex.id, + 'is_individual': False, + 'answer_ids': [ + (0, 0, {'name': 'Q2-Answer1'}), + (0, 0, {'name': 'Q2-Answer2'}) + ], + }) + cls.event_type_complex.write({'use_questions': True}) diff --git a/addons/website_event_questions/tests/test_event_internals.py b/addons/website_event_questions/tests/test_event_internals.py new file mode 100644 index 00000000000..dd13343b62c --- /dev/null +++ b/addons/website_event_questions/tests/test_event_internals.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import datetime, timedelta + +from odoo.addons.website_event_questions.tests.common import TestEventQuestionCommon +from odoo.fields import Datetime as FieldsDatetime +from odoo.tests.common import users + + +class TestEventData(TestEventQuestionCommon): + + @users('user_eventmanager') + def test_event_type_configuration(self): + event_type = self.event_type_complex.with_user(self.env.user) + + event = self.env['event.event'].create({ + 'name': 'Event Update Type', + 'event_type_id': event_type.id, + 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), + 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), + }) + event._onchange_type() + self.assertEqual(event.specific_question_ids.title, 'Question1') + self.assertEqual( + set(event.specific_question_ids.mapped('answer_ids.name')), + set(['Q1-Answer1', 'Q1-Answer2'])) + self.assertEqual(event.general_question_ids.title, 'Question2') + self.assertEqual( + set(event.general_question_ids.mapped('answer_ids.name')), + set(['Q2-Answer1', 'Q2-Answer2']))