diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py index c3c32a9880a..4713aa09716 100644 --- a/addons/event/tests/common.py +++ b/addons/event/tests/common.py @@ -1,52 +1,79 @@ # -*- 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 -class TestEventCommon(common.TransactionCase): +class EventCase(common.TransactionCase): @classmethod def setUpClass(cls): - super(TestEventCommon, cls).setUpClass() + super(EventCase, cls).setUpClass() + + cls.admin_user = cls.env.ref('base.user_admin') + cls.admin_user.write({ + 'country_id': cls.env.ref('base.be').id, + 'login': 'admin', + 'notification_type': 'inbox', + }) + cls.company_admin = cls.admin_user.company_id + # set country in order to format Belgian numbers + cls.company_admin.write({ + 'country_id': cls.env.ref('base.be').id, + }) # Test users to use through the various tests 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.env, + company_id=cls.company_admin.id, + email='patrick.portal@test.example.com', + groups='base.group_portal', + login='portal_test', + name='Patrick Portal', + notification_type='email', + tz='Europe/Brussels', + ) 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, + cls.env, + company_id=cls.company_admin.id, + email='eglantine.employee@test.example.com', groups='base.group_user', + login='user_employee', + name='Eglantine Employee', + notification_type='inbox', + tz='Europe/Brussels', ) cls.user_eventregistrationdesk = mail_new_test_user( - cls.env, login='user_eventregistrationdesk', - name='Ursule EventRegistration', email='ursule.eventregistration@test.example.com', - tz='Europe/Brussels', notification_type='inbox', - company_id=cls.env.ref("base.main_company").id, + cls.env, + company_id=cls.company_admin.id, + email='ursule.eventregistration@test.example.com', + login='user_eventregistrationdesk', groups='base.group_user,event.group_event_registration_desk', + name='Ursule EventRegistration', + notification_type='inbox', + tz='Europe/Brussels', ) 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, + cls.env, + company_id=cls.company_admin.id, + email='ursule.eventuser@test.example.com', groups='base.group_user,event.group_event_user', + login='user_eventuser', + name='Ursule EventUser', + notification_type='inbox', + tz='Europe/Brussels', ) 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, + cls.env, + company_id=cls.company_admin.id, + email='martine.eventmanager@test.example.com', groups='base.group_user,event.group_event_manager', + login='user_eventmanager', + name='Martine EventManager', + notification_type='inbox', + tz='Europe/Brussels', ) cls.event_customer = cls.env['res.partner'].create({ @@ -64,41 +91,6 @@ class TestEventCommon(common.TransactionCase): 'mobile': '0456654321', }) - cls.event_type_complex = cls.env['event.type'].create({ - 'name': 'Update Type', - 'auto_confirm': True, - 'has_seats_limitation': True, - 'seats_max': 30, - 'default_timezone': 'Europe/Paris', - 'event_type_ticket_ids': [(0, 0, { - 'name': 'First Ticket', - }), (0, 0, { - 'name': 'Second Ticket', - }) - ], - 'event_type_mail_ids': [ - (0, 0, { # right at subscription - 'interval_unit': 'now', - 'interval_type': 'after_sub', - 'template_ref': 'mail.template,%i' % 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_ref': 'mail.template,%i' % 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 Belgian numbers - cls.event_0.company_id.write({'country_id': cls.env.ref('base.be').id}) - @classmethod def _create_registrations(cls, event, reg_count): # create some registrations diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index 93667aba78e..dd021b25e73 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -5,12 +5,12 @@ import datetime from dateutil.relativedelta import relativedelta -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase from odoo.exceptions import ValidationError from odoo.tools import mute_logger -class TestEventFlow(TestEventCommon): +class TestEventFlow(EventCase): @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') def test_event_auto_confirm(self): diff --git a/addons/event/tests/test_event_internals.py b/addons/event/tests/test_event_internals.py index 9fb11beff6d..e02a42aedf5 100644 --- a/addons/event/tests/test_event_internals.py +++ b/addons/event/tests/test_event_internals.py @@ -1,63 +1,95 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import date, datetime, timedelta -from unittest.mock import patch +from datetime import datetime, timedelta +from freezegun import freeze_time from odoo import Command -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase from odoo import exceptions -from odoo.fields import Datetime as FieldsDatetime, Date as FieldsDate +from odoo.fields import Datetime as FieldsDatetime from odoo.tests.common import users, Form from odoo.tools import mute_logger -class TestEventData(TestEventCommon): +class TestEventInternalsCommon(EventCase): @classmethod def setUpClass(cls): - super(TestEventData, cls).setUpClass() - cls.patcher = patch('odoo.addons.event.models.event_event.fields.Datetime', wraps=FieldsDatetime) - cls.mock_datetime = cls.patcher.start() - cls.mock_datetime.now.return_value = datetime(2020, 1, 31, 10, 0, 0) - cls.addClassCleanup(cls.patcher.stop) + super(TestEventInternalsCommon, cls).setUpClass() - cls.event_0.write({ - 'date_begin': datetime(2020, 2, 1, 8, 30, 0), - 'date_end': datetime(2020, 2, 4, 18, 45, 0), + cls.event_type_complex = cls.env['event.type'].create({ + 'name': 'Update Type', + 'auto_confirm': True, + 'has_seats_limitation': True, + 'seats_max': 30, + 'default_timezone': 'Europe/Paris', + 'event_type_ticket_ids': [ + (0, 0, {'name': 'First Ticket',}), + (0, 0, {'name': 'Second Ticket',}), + ], + 'event_type_mail_ids': [ + (0, 0, { # right at subscription + 'interval_unit': 'now', + 'interval_type': 'after_sub', + 'template_ref': 'mail.template,%i' % 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_ref': 'mail.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}), + ], }) + # Mock dates to have reproducible computed fields based on time + cls.reference_now = datetime(2020, 1, 31, 10, 0, 0) + cls.reference_beg = datetime(2020, 2, 1, 8, 30, 0) + cls.reference_end = datetime(2020, 2, 4, 18, 45, 0) + + cls.event_0 = cls.env['event.event'].create({ + 'auto_confirm': True, + 'date_begin': cls.reference_beg, + 'date_end': cls.reference_end, + 'date_tz': 'Europe/Brussels', + 'name': 'TestEvent', + }) + + +class TestEventData(TestEventInternalsCommon): + @users('user_eventmanager') def test_event_date_computation(self): event = self.event_0.with_user(self.env.user) - event.write({ - 'registration_ids': [(0, 0, {'partner_id': self.event_customer.id, 'name': 'test_reg'})], - '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') + with freeze_time(self.reference_now): + event.write({ + 'registration_ids': [(0, 0, {'partner_id': self.event_customer.id, 'name': 'test_reg'})], + '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, 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, 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, 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.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') - # Is actually 8:30 to 20:00 in Mexico - event.write({ - 'date_begin': datetime(2020, 1, 31, 14, 30, 0), - 'date_end': datetime(2020, 2, 1, 2, 0, 0), - 'date_tz': 'Mexico/General' - }) - self.assertTrue(event.is_one_day) + # Is actually 8:30 to 20:00 in Mexico + event.write({ + 'date_begin': datetime(2020, 1, 31, 14, 30, 0), + 'date_end': datetime(2020, 2, 1, 2, 0, 0), + 'date_tz': 'Mexico/General' + }) + self.assertTrue(event.is_one_day) + @freeze_time('2020-1-31 10:00:00') @users('user_eventmanager') def test_event_date_timezone(self): event = self.event_0.with_user(self.env.user) @@ -349,6 +381,7 @@ class TestEventData(TestEventCommon): templates = self.env['mail.template'].with_context(filter_template_on_event=True).name_search('test template') self.assertEqual(len(templates), 1, 'Should return only mail templates related to the event registration model') + @freeze_time('2020-1-31 10:00:00') @users('user_eventmanager') def test_event_registrable(self): """Test if `_compute_event_registrations_open` works properly.""" @@ -401,6 +434,7 @@ class TestEventData(TestEventCommon): self.assertTrue(ticket.is_expired) self.assertFalse(event.event_registrations_open) + @freeze_time('2020-1-31 10:00:00') @users('user_eventmanager') def test_event_ongoing(self): event_1 = self.env['event.event'].create({ @@ -475,7 +509,7 @@ class TestEventData(TestEventCommon): self.assertEqual(event.seats_expected, 7) -class TestEventRegistrationData(TestEventCommon): +class TestEventRegistrationData(TestEventInternalsCommon): @users('user_eventmanager') def test_registration_partner_sync(self): @@ -569,22 +603,9 @@ class TestEventRegistrationData(TestEventCommon): self.assertEqual(new_reg.phone, contact.phone) -class TestEventTicketData(TestEventCommon): - - def setUp(self): - super(TestEventTicketData, self).setUp() - self.ticket_date_patcher = patch('odoo.addons.event.models.event_ticket.fields.Date', wraps=FieldsDate) - self.ticket_date_patcher_mock = self.ticket_date_patcher.start() - self.ticket_date_patcher_mock.context_today.return_value = date(2020, 1, 31) - self.ticket_datetime_patcher = patch('odoo.addons.event.models.event_ticket.fields.Datetime', wraps=FieldsDatetime) - self.ticket_datetime_patcher_mock = self.ticket_datetime_patcher.start() - self.ticket_datetime_patcher_mock.now.return_value = datetime(2020, 1, 31, 10, 0, 0) - - def tearDown(self): - super(TestEventTicketData, self).tearDown() - self.ticket_date_patcher.stop() - self.ticket_datetime_patcher.stop() +class TestEventTicketData(TestEventInternalsCommon): + @freeze_time('2020-1-31 10:00:00') @users('user_eventmanager') def test_event_ticket_fields(self): """ Test event ticket fields synchronization """ @@ -657,7 +678,7 @@ class TestEventTicketData(TestEventCommon): self.assertTrue(second_ticket.is_expired) -class TestEventTypeData(TestEventCommon): +class TestEventTypeData(TestEventInternalsCommon): @users('user_eventmanager') def test_event_type_fields(self): diff --git a/addons/event/tests/test_event_mail_schedule.py b/addons/event/tests/test_event_mail_schedule.py index 85f639648d2..1089c8358a5 100644 --- a/addons/event/tests/test_event_mail_schedule.py +++ b/addons/event/tests/test_event_mail_schedule.py @@ -5,12 +5,12 @@ from datetime import datetime from dateutil.relativedelta import relativedelta from freezegun import freeze_time -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase from odoo.addons.mail.tests.common import MockEmail from odoo.tools import formataddr, mute_logger -class TestMailSchedule(TestEventCommon, MockEmail): +class TestMailSchedule(EventCase, MockEmail): @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') def test_event_mail_schedule(self): diff --git a/addons/event_booth/tests/common.py b/addons/event_booth/tests/common.py index b378449ad6a..7b8fb50f907 100644 --- a/addons/event_booth/tests/common.py +++ b/addons/event_booth/tests/common.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase -class TestEventBoothCommon(TestEventCommon): +class TestEventBoothCommon(EventCase): @classmethod def setUpClass(cls): @@ -18,13 +18,3 @@ class TestEventBoothCommon(TestEventCommon): 'name': 'Premium', 'description': '

Premium

', }) - - cls.event_type_complex.write({ - 'event_type_booth_ids': [ - (5, 0), - (0, 0, - {'name': 'Standard 1', 'booth_category_id': cls.event_booth_category_1.id}), - (0, 0, - {'name': 'Premium 1', 'booth_category_id': cls.event_booth_category_2.id}), - ], - }) diff --git a/addons/event_booth_sale/tests/common.py b/addons/event_booth_sale/tests/common.py index b2c98e5b4a0..f72e6bf399b 100644 --- a/addons/event_booth_sale/tests/common.py +++ b/addons/event_booth_sale/tests/common.py @@ -2,10 +2,9 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.event_booth.tests.common import TestEventBoothCommon -from odoo.addons.event_sale.tests.common import TestEventSaleCommon -class TestEventBoothSaleCommon(TestEventBoothCommon, TestEventSaleCommon): +class TestEventBoothSaleCommon(TestEventBoothCommon): @classmethod def setUpClass(cls): diff --git a/addons/event_crm/tests/common.py b/addons/event_crm/tests/common.py index c27b82d21c0..6d53c0fb41f 100644 --- a/addons/event_crm/tests/common.py +++ b/addons/event_crm/tests/common.py @@ -1,15 +1,18 @@ # -*- 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.crm.tests.common import TestCrmCommon -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase -class TestEventCrmCommon(TestCrmCommon, TestEventCommon): +class EventCrmCase(TestCrmCommon, EventCase): @classmethod def setUpClass(cls): - super(TestEventCrmCommon, cls).setUpClass() + super(EventCrmCase, cls).setUpClass() # avoid clash with existing rules cls.env['event.lead.rule'].search([]).write({'active': False}) @@ -20,7 +23,6 @@ class TestEventCrmCommon(TestCrmCommon, TestEventCommon): 'name': 'Rule Attendee', 'lead_creation_basis': 'attendee', 'lead_creation_trigger': 'create', - 'event_id': cls.event_0.id, 'event_registration_filter': [['email', 'ilike', '@test.example.com']], 'lead_type': 'lead', 'lead_user_id': cls.user_sales_salesman.id, @@ -31,7 +33,6 @@ class TestEventCrmCommon(TestCrmCommon, TestEventCommon): 'name': 'Rule Order', 'lead_creation_basis': 'order', 'lead_creation_trigger': 'create', - 'event_id': cls.event_0.id, 'event_registration_filter': [['email', 'ilike', '@test.example.com']], 'lead_type': 'opportunity', 'lead_user_id': cls.user_sales_leads.id, @@ -96,7 +97,6 @@ class TestEventCrmCommon(TestCrmCommon, TestEventCommon): self.assertEqual(lead.partner_id, partner) self.assertEqual(lead.name, '%s - %s' % (event.name, expected_reg_name)) self.assertNotIn('False', lead.name) # avoid a "Dear False" like construct ^^ (this assert is serious and intended) - self.assertEqual(lead.contact_name, expected_contact_name) self.assertEqual(lead.partner_name, expected_partner_name) self.assertEqual(lead.email_from, partner.email if partner else registrations._find_first_notnull('email')) @@ -120,3 +120,21 @@ class TestEventCrmCommon(TestCrmCommon, TestEventCommon): self.assertEqual(lead.user_id, rule.lead_user_id) self.assertEqual(lead.team_id, rule.lead_sales_team_id) self.assertEqual(lead.tag_ids, rule.lead_tag_ids) + + +class TestEventCrmCommon(EventCrmCase): + + @classmethod + def setUpClass(cls): + super(TestEventCrmCommon, cls).setUpClass() + + 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', + }) + + cls.test_rule_attendee.event_id = cls.event_0.id + cls.test_rule_order.event_id = cls.event_0.id diff --git a/addons/event_sale/tests/common.py b/addons/event_sale/tests/common.py index cf75273e000..d40bbc853da 100644 --- a/addons/event_sale/tests/common.py +++ b/addons/event_sale/tests/common.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.event.tests.common import TestEventCommon +from datetime import datetime, timedelta + +from odoo import fields +from odoo.addons.event.tests.common import EventCase from odoo.addons.sales_team.tests.common import TestSalesCommon -class TestEventSaleCommon(TestEventCommon, TestSalesCommon): +class TestEventSaleCommon(EventCase, TestSalesCommon): @classmethod def setUpClass(cls): @@ -18,3 +21,26 @@ class TestEventSaleCommon(TestEventCommon, TestSalesCommon): 'standard_price': 30.0, 'detailed_type': 'event', }) + + cls.event_type_tickets = cls.env['event.type'].create({ + 'name': 'Update Type', + 'auto_confirm': True, + 'has_seats_limitation': True, + 'seats_max': 30, + 'default_timezone': 'Europe/Paris', + 'event_type_ticket_ids': [ + (0, 0, {'name': 'First Ticket', + 'product_id': cls.event_product.id, + 'seats_max': 5, + }) + ], + 'event_type_mail_ids': [], + }) + + 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', + }) diff --git a/addons/event_sale/tests/test_event_internals.py b/addons/event_sale/tests/test_event_internals.py index 6eb4833426e..260a4ddf131 100644 --- a/addons/event_sale/tests/test_event_internals.py +++ b/addons/event_sale/tests/test_event_internals.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import date, datetime, timedelta -from unittest.mock import patch +from freezegun import freeze_time from odoo.addons.event_sale.tests.common import TestEventSaleCommon from odoo.fields import Datetime as FieldsDatetime, Date as FieldsDate @@ -15,7 +15,8 @@ class TestEventData(TestEventSaleCommon): def test_event_configuration_from_type(self): """ In addition to event test, also test tickets configuration coming from event_sale capabilities. """ - event_type = self.event_type_complex.with_user(self.env.user) + event_type = self.event_type_tickets.with_user(self.env.user) + self.assertEqual(event_type.event_type_ticket_ids.description, self.event_product.description_sale) event = self.env['event.event'].create({ 'name': 'Event Update Type', @@ -23,14 +24,6 @@ class TestEventData(TestEventSaleCommon): 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), }) - event_type.write({ - 'event_type_ticket_ids': [(5, 0), (0, 0, { - 'name': 'First Ticket', - 'product_id': self.event_product.id, - 'seats_max': 5, - })] - }) - self.assertEqual(event_type.event_type_ticket_ids.description, self.event_product.description_sale) # synchronize event event.write({'event_type_id': event_type.id}) @@ -73,20 +66,7 @@ class TestEventData(TestEventSaleCommon): class TestEventTicketData(TestEventSaleCommon): - def setUp(self): - super(TestEventTicketData, self).setUp() - self.ticket_date_patcher = patch('odoo.addons.event.models.event_ticket.fields.Date', wraps=FieldsDate) - self.ticket_date_patcher_mock = self.ticket_date_patcher.start() - self.ticket_date_patcher_mock.context_today.return_value = date(2020, 1, 31) - self.ticket_datetime_patcher = patch('odoo.addons.event.models.event_event.fields.Datetime', wraps=FieldsDatetime) - self.mock_datetime = self.ticket_datetime_patcher.start() - self.mock_datetime.now.return_value = datetime(2020, 1, 31, 10, 0, 0) - - def tearDown(self): - super(TestEventTicketData, self).tearDown() - self.ticket_date_patcher.stop() - self.ticket_datetime_patcher.stop() - + @freeze_time('2020-01-31 10:00:00') @users('user_eventmanager') def test_event_ticket_fields(self): """ Test event ticket fields synchronization """ diff --git a/addons/event_sms/tests/test_sms_schedule.py b/addons/event_sms/tests/test_sms_schedule.py index 25caf1b1855..8045c1ac65e 100644 --- a/addons/event_sms/tests/test_sms_schedule.py +++ b/addons/event_sms/tests/test_sms_schedule.py @@ -1,14 +1,16 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from dateutil.relativedelta import relativedelta +from datetime import datetime, timedelta -from odoo.addons.event.tests.common import TestEventCommon +from odoo import fields +from odoo.addons.event.tests.common import EventCase from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.sms.tests.common import SMSCase +from odoo.tests import users -class TestSMSSchedule(TestEventCommon, SMSCase): +class TestSMSSchedule(EventCase, SMSCase): @classmethod def setUpClass(cls): @@ -27,7 +29,11 @@ class TestSMSSchedule(TestEventCommon, SMSCase): 'lang': '{{ object.partner_id.lang }}' }) - cls.event_0.write({ + cls.test_event = cls.env['event.event'].create({ + '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', 'event_mail_ids': [ (5, 0), (0, 0, { # right at subscription @@ -41,51 +47,55 @@ class TestSMSSchedule(TestEventCommon, SMSCase): 'interval_type': 'before_event', 'notification_type': 'sms', 'template_ref': 'sms.template,%i' % cls.sms_template_rem.id}), - ] + ], + 'name': 'TestEvent', }) + @users('user_eventmanager') def test_sms_schedule(self): + test_event = self.env['event.event'].browse(self.test_event.ids) + with self.mockSMSGateway(): - self._create_registrations(self.event_0, 3) + self._create_registrations(test_event, 3) # check subscription scheduler - sub_scheduler = self.env['event.mail'].search([('event_id', '=', self.event_0.id), ('interval_type', '=', 'after_sub')]) + sub_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'after_sub')]) self.assertEqual(len(sub_scheduler), 1) - self.assertEqual(sub_scheduler.scheduled_date, self.event_0.create_date, 'event: incorrect scheduled date for checking controller') + self.assertEqual(sub_scheduler.scheduled_date, test_event.create_date, 'event: incorrect scheduled date for checking controller') # verify that subscription scheduler was auto-executed after each registration self.assertEqual(len(sub_scheduler.mail_registration_ids), 3) self.assertTrue(all(m.mail_sent is True for m in sub_scheduler.mail_registration_ids)) - self.assertEqual(sub_scheduler.mapped('mail_registration_ids.registration_id'), self.event_0.registration_ids) + self.assertEqual(sub_scheduler.mapped('mail_registration_ids.registration_id'), test_event.registration_ids) sanitized_numbers = [] - for registration in self.event_0.registration_ids: + for registration in test_event.registration_ids: reg_sanitized_number = phone_validation.phone_format(registration.phone, 'BE', '32', force_format='E164') sanitized_numbers.append(reg_sanitized_number) self.assertSMSOutgoing( self.env['res.partner'], reg_sanitized_number, - content='%s registration confirmation.' % self.event_0.organizer_id.name) + content='%s registration confirmation.' % test_event.organizer_id.name) self.assertTrue(sub_scheduler.mail_done) self.assertEqual(sub_scheduler.mail_count_done, 3) # clear notification queue to avoid conflicts when checking next notifications - self.env['mail.notification'].search([('sms_number', 'in', sanitized_numbers)]).unlink() - self.env['sms.sms'].search([('number', 'in', sanitized_numbers)]).unlink() + self.env['mail.notification'].sudo().search([('sms_number', 'in', sanitized_numbers)]).unlink() + self.env['sms.sms'].sudo().search([('number', 'in', sanitized_numbers)]).unlink() # check before event scheduler - before_scheduler = self.env['event.mail'].search([('event_id', '=', self.event_0.id), ('interval_type', '=', 'before_event')]) + before_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'before_event')]) self.assertEqual(len(before_scheduler), 1, 'event: wrong scheduler creation') - self.assertEqual(before_scheduler.scheduled_date, self.event_0.date_begin + relativedelta(days=-3)) + self.assertEqual(before_scheduler.scheduled_date, test_event.date_begin + timedelta(days=-3)) # execute event reminder scheduler explicitly with self.mockSMSGateway(): before_scheduler.execute() # verify that subscription scheduler was auto-executed after each registration - for registration in self.event_0.registration_ids: + for registration in test_event.registration_ids: reg_sanitized_number = phone_validation.phone_format(registration.phone, 'BE', '32', force_format='E164') self.assertSMSOutgoing( self.env['res.partner'], reg_sanitized_number, - content='%s reminder' % self.event_0.organizer_id.name) + content='%s reminder' % test_event.organizer_id.name) self.assertTrue(before_scheduler.mail_done) self.assertEqual(before_scheduler.mail_count_done, 3) diff --git a/addons/test_event_full/__manifest__.py b/addons/test_event_full/__manifest__.py index a474fbd6cdf..e79701f045c 100644 --- a/addons/test_event_full/__manifest__.py +++ b/addons/test_event_full/__manifest__.py @@ -14,7 +14,10 @@ automatic lead generation, full Online support, ... 'event', 'event_booth', 'event_crm', + 'event_crm_sale', 'event_sale', + 'event_sms', + 'payment_test', 'website_event_booth_sale_exhibitor', 'website_event_crm_questions', 'website_event_exhibitor', @@ -25,7 +28,11 @@ automatic lead generation, full Online support, ... 'website_event_track_live', 'website_event_track_quiz', ], - 'installable': True, + 'data': [ + # 'data/event_type_data.xml', # uncomment to reproduce test tour + 'data/ir_actions_report_data.xml', + 'views/event_registration_templates_reports.xml', + ], 'assets': { 'web.assets_tests': [ 'test_event_full/static/**/*', diff --git a/addons/test_event_full/data/event_type_data.xml b/addons/test_event_full/data/event_type_data.xml new file mode 100644 index 00000000000..4ebf4a299ad --- /dev/null +++ b/addons/test_event_full/data/event_type_data.xml @@ -0,0 +1,122 @@ + + + + +

Standard

+ Standard + +
+ +

Premium

+ Premium + + 90 +
+ + + + Europe/Paris + + + + + Test Type +

Template note

+ + 30 + +

Ticket Instructions

+ +
+ + + simple_choice + + + Question1 + + + Q1-Answer1 + 1 + + + + Q1-Answer2 + 2 + + + + simple_choice + + + Question2 + + + Q2-Answer1 + 1 + + + + Q2-Answer2 + 2 + + + + text_box + + + Question3 + + +
diff --git a/addons/test_event_full/data/ir_actions_report_data.xml b/addons/test_event_full/data/ir_actions_report_data.xml new file mode 100644 index 00000000000..2b1608935a7 --- /dev/null +++ b/addons/test_event_full/data/ir_actions_report_data.xml @@ -0,0 +1,13 @@ + + + + Test Report + event.registration + qweb-pdf + test_event_full.event_registration_template_report + test_event_full.event_registration_template_report + 'Badge - %s - %s' % ((object.event_id.name or 'Event').replace('/',''), object.name.replace('/','')) + + report + + diff --git a/addons/test_event_full/static/src/js/tours/wevent_performance_tour.js b/addons/test_event_full/static/src/js/tours/wevent_performance_tour.js new file mode 100644 index 00000000000..a0d3f811e2e --- /dev/null +++ b/addons/test_event_full/static/src/js/tours/wevent_performance_tour.js @@ -0,0 +1,85 @@ +odoo.define('test_event_full.tour.performance', function (require) { +"use strict"; + +var tour = require('web_tour.tour'); + +var registerSteps = [{ + content: "Select 2 units of 'Ticket1' ticket type", + trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket1"] select', + run: 'text 2', +}, { + content: "Select 1 unit of 'Ticket2' ticket type", + trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket2"] select', + run: 'text 1', +}, { + content: "Click on 'Register' button", + trigger: '#o_wevent_tickets .btn-primary:contains("Register"):not(:disabled)', + run: 'click', +}, { + content: "Fill attendees details", + trigger: 'form[id="attendee_registration"] .btn:contains("Continue")', + run: function () { + $("input[name='1-name']").val("Raoulette Poiluchette"); + $("input[name='1-phone']").val("0456112233"); + $("input[name='1-email']").val("raoulette@example.com"); + $("div[name*='Question1'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q1-Answer2')").val()); + $("div[name*='Question2'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q2-Answer1')").val()); + $("input[name='2-name']").val("Michel Tractopelle"); + $("input[name='2-phone']").val("0456332211"); + $("input[name='2-email']").val("michel@example.com"); + $("div[name*='Question1'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q1-Answer1')").val()); + $("div[name*='Question2'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q2-Answer2')").val()); + $("input[name='3-name']").val("Hubert Boitaclous"); + $("input[name='3-phone']").val("0456995511"); + $("input[name='3-email']").val("hubert@example.com"); + $("div[name*='Question1'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q1-Answer2')").val()); + $("div[name*='Question2'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q2-Answer2')").val()); + $("textarea[name*='question_answer']").text("Random answer from random guy"); + }, +}, { + content: "Validate attendees details", + extra_trigger: "input[name='1-name'], input[name='2-name'], input[name='3-name']", + trigger: 'button:contains("Continue")', + run: 'click', +}, { + content: "Address filling", + trigger: 'select[name="country_id"]', + run: function () { + $('input[name="name"]').val('Raoulette Poiluchette'); + $('input[name="phone"]').val('0456112233'); + $('input[name="email"]').val('raoulette@example.com'); + $('input[name="street"]').val('Cheesy Crust Street, 42'); + $('input[name="city"]').val('CheeseCity'); + $('input[name="zip"]').val('8888'); + $('#country_id option:eq(1)').attr('selected', true); + }, +}, { + content: "Next", + trigger: '.oe_cart .btn:contains("Next")', +}, { + content: 'Select Test payment acquirer', + trigger: '.o_payment_option_card:contains("Test")' +}, { + content: 'Add card number', + trigger: 'input[name="customer_input"]', + run: 'text 4242424242424242' +}, { + content: "Pay now", + extra_trigger: "#cart_products:contains(Ticket1):contains(Ticket2)", + trigger: 'button:contains(Pay Now)', + run: 'click', +}, { + content: 'Payment is successful', + trigger: '.oe_website_sale_tx_status:contains("Your payment has been successfully processed.")', + run: function () {} +}]; + + +tour.register('wevent_performance_register', { + test: true +}, [].concat( + registerSteps, + ) +); + +}); diff --git a/addons/test_event_full/tests/__init__.py b/addons/test_event_full/tests/__init__.py index f08227d67fe..f29bd66c342 100644 --- a/addons/test_event_full/tests/__init__.py +++ b/addons/test_event_full/tests/__init__.py @@ -3,5 +3,7 @@ from . import common from . import test_event_crm -from . import test_wevent_register +from . import test_event_event from . import test_event_security +from . import test_performance +from . import test_wevent_register diff --git a/addons/test_event_full/tests/common.py b/addons/test_event_full/tests/common.py index 0f5b152364b..d3c962cffc4 100644 --- a/addons/test_event_full/tests/common.py +++ b/addons/test_event_full/tests/common.py @@ -4,110 +4,287 @@ from datetime import datetime, timedelta, time from odoo.addons.base.tests.common import HttpCaseWithUserDemo, HttpCaseWithUserPortal -from odoo.addons.event_crm.tests.common import TestEventCrmCommon +from odoo.addons.event_crm.tests.common import EventCrmCase +from odoo.addons.mail.tests.common import mail_new_test_user from odoo.addons.sales_team.tests.common import TestSalesCommon from odoo.addons.website.tests.test_website_visitor import MockVisitor -from odoo.addons.website_event.tests.common import EventDtPatcher -class TestEventFullCommon(TestEventCrmCommon, TestSalesCommon, EventDtPatcher, MockVisitor): +class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor): @classmethod def setUpClass(cls): super(TestEventFullCommon, cls).setUpClass() + cls._init_mail_gateway() - # ------------------------------------------------------------ - # TICKET INFORMATIONS + # Context data: dates # ------------------------------------------------------------ - cls.event_product = cls.env['product.product'].create({ - 'name': 'Test Registration Product', - 'description_sale': 'Mighty Description', - 'list_price': 10, - 'standard_price': 30.0, - 'detailed_type': 'event', + # Mock dates to have reproducible computed fields based on time + cls.reference_now = datetime(2021, 12, 1, 10, 0, 0) + cls.reference_today = datetime(2021, 12, 1) + + # Users and contacts + # ------------------------------------------------------------ + + cls.admin_user = cls.env.ref('base.user_admin') + cls.admin_user.write({ + 'country_id': cls.env.ref('base.be').id, + 'login': 'admin', + 'notification_type': 'inbox', }) - - cls.website = cls.env['website'].search([ - ('company_id', '=', cls.env.user.company_id.id) - ], limit=1) - - cls.event_0.write({ - # event if 8-18 in Europe/Brussels (DST) (first day: begins at 9, last day: ends at 15) - 'date_begin': datetime.combine(cls.reference_now, time(7, 0)) - timedelta(days=1), - 'date_end': datetime.combine(cls.reference_now, time(13, 0)) + timedelta(days=1), - # ticket informations - 'event_ticket_ids': [ - (5, 0), - (0, 0, { - 'name': 'First Ticket', - 'product_id': cls.event_product.id, - 'seats_max': 30, - }), (0, 0, { - 'name': 'Second Ticket', - 'product_id': cls.event_product.id, - }) - ], + cls.company_admin = cls.admin_user.company_id + # set country in order to format Belgian numbers + cls.company_admin.write({ + 'country_id': cls.env.ref('base.be').id, }) + cls.event_user = mail_new_test_user( + cls.env, + company_id=cls.company_admin.id, + company_ids=[(4, cls.company_admin.id)], + country_id=cls.env.ref('base.be').id, + groups='base.group_user,base.group_partner_manager,event.group_event_user', + email='e.e@example.com', + login='event_user', + name='Ernest Employee', + notification_type='inbox', + signature='--\nErnest', + ) + cls.customer = cls.env['res.partner'].create({ + 'country_id': cls.env.ref('base.be').id, + 'email': 'customer.test@example.com', + 'name': 'Test Customer', + 'mobile': '0456123456', + 'phone': '0456123456', + }) # make a SO for a customer, selling some tickets cls.customer_so = cls.env['sale.order'].with_user(cls.user_sales_salesman).create({ 'partner_id': cls.event_customer.id, }) - # ------------------------------------------------------------ - # QUESTIONS + # Side records for event main records # ------------------------------------------------------------ - cls.event_question_1 = cls.env['event.question'].create({ - 'title': 'Question1', - 'question_type': 'simple_choice', - 'event_id': cls.event_0.id, - 'once_per_order': False, - 'answer_ids': [ - (0, 0, {'name': 'Q1-Answer1'}), - (0, 0, {'name': 'Q1-Answer2'}) + cls.ticket_product = cls.env['product.product'].create({ + 'description_sale': 'Ticket Product Description', + 'detailed_type': 'event', + 'list_price': 10, + 'name': 'Test Registration Product', + 'standard_price': 30.0, + }) + cls.booth_product = cls.env['product.product'].create({ + 'description_sale': 'Booth Product Description', + 'detailed_type': 'event_booth', + 'list_price': 20, + 'name': 'Test Booth Product', + 'standard_price': 60.0, + }) + + cls.tag_categories = cls.env['event.tag.category'].create([ + {'is_published': True, 'name': 'Published Category'}, + {'is_published': False, 'name': 'Unpublished Category'}, + ]) + cls.tags = cls.env['event.tag'].create([ + {'category_id': cls.tag_categories[0].id, 'name': 'PubTag1'}, + {'category_id': cls.tag_categories[0].id, 'color': 0, 'name': 'PubTag2'}, + {'category_id': cls.tag_categories[1].id, 'name': 'UnpubTag1'}, + ]) + + cls.event_booth_categories = cls.env['event.booth.category'].create([ + {'description': '

Standard

', + 'name': 'Standard', + 'product_id': cls.booth_product.id, + }, + {'description': '

Premium

', + 'name': 'Premium', + 'product_id': cls.booth_product.id, + 'price': 90, + } + ]) + + cls.sponsor_types = cls.env['event.sponsor.type'].create([ + {'name': 'GigaTop', + 'sequence': 1, + } + ]) + cls.sponsor_partners = cls.env['res.partner'].create([ + {'country_id': cls.env.ref('base.be').id, + 'email': 'event.sponsor@example.com', + 'name': 'EventSponsor', + 'phone': '04856112233', + } + ]) + + # Event type + # ------------------------------------------------------------ + test_registration_report = cls.env.ref('test_event_full.event_registration_report_test') + subscription_template = cls.env.ref('event.event_subscription') + subscription_template.write({'report_template': test_registration_report.id}) + cls.test_event_type = cls.env['event.type'].create({ + 'auto_confirm': True, + 'default_timezone': 'Europe/Paris', + 'event_type_booth_ids': [ + (0, 0, {'booth_category_id': cls.event_booth_categories[0].id, + 'name': 'Standard Booth', + } + ), + (0, 0, {'booth_category_id': cls.event_booth_categories[0].id, + 'name': 'Standard Booth 2', + } + ), + (0, 0, {'booth_category_id': cls.event_booth_categories[1].id, + 'name': 'Premium Booth', + } + ), + (0, 0, {'booth_category_id': cls.event_booth_categories[1].id, + 'name': 'Premium Booth 2', + } + ), ], - }) - cls.event_question_2 = cls.env['event.question'].create({ - 'title': 'Question2', - 'question_type': 'simple_choice', - 'event_id': cls.event_0.id, - 'once_per_order': True, - 'answer_ids': [ - (0, 0, {'name': 'Q2-Answer1'}), - (0, 0, {'name': 'Q2-Answer2'}) + 'event_type_mail_ids': [ + (0, 0, {'interval_unit': 'now', # right at subscription + 'interval_type': 'after_sub', + 'notification_type': 'mail', + 'template_ref': 'mail.template,%i' % subscription_template.id, + } + ), + (0, 0, {'interval_nbr': 1, # 1 days before event + 'interval_unit': 'days', + 'interval_type': 'before_event', + 'notification_type': 'mail', + 'template_ref': 'mail.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event.event_reminder'), + } + ), + (0, 0, {'interval_nbr': 1, # 1 days after event + 'interval_unit': 'days', + 'interval_type': 'after_event', + 'notification_type': 'sms', + 'template_ref': 'sms.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event_sms.sms_template_data_event_reminder'), + } + ), ], - }) - cls.event_question_3 = cls.env['event.question'].create({ - 'title': 'Question3', - 'question_type': 'text_box', - 'event_id': cls.event_0.id, - 'once_per_order': True, + 'event_type_ticket_ids': [ + (0, 0, {'description': 'Ticket1 Description', + 'name': 'Ticket1', + 'product_id': cls.ticket_product.id, + 'seats_max': 10, + } + ), + (0, 0, {'description': 'Ticket2 Description', + 'name': 'Ticket2', + 'product_id': cls.ticket_product.id, + 'price': 45, + } + ) + ], + 'has_seats_limitation': True, + 'name': 'Test Type', + 'note': '

Template note

', + 'question_ids': [ + (0, 0, {'answer_ids': + [(0, 0, {'name': 'Q1-Answer1'}), + (0, 0, {'name': 'Q1-Answer2'}), + ], + 'question_type': 'simple_choice', + 'once_per_order': False, + 'title': 'Question1', + } + ), + (0, 0, {'answer_ids': + [(0, 0, {'name': 'Q2-Answer1'}), + (0, 0, {'name': 'Q2-Answer2'}), + ], + 'question_type': 'simple_choice', + 'once_per_order': False, + 'title': 'Question2', + } + ), + (0, 0, {'question_type': 'text_box', + 'once_per_order': True, + 'title': 'Question3', + } + ), + ], + 'seats_max': 30, + 'tag_ids': [(4, tag.id) for tag in cls.tags], + 'ticket_instructions': '

Ticket Instructions

', + 'website_menu': True, }) - # ------------------------------------------------------------ - # DATA MARSHMALLING + # Stages + cls.stage_def = cls.env['event.stage'].create({ + 'name': 'First Stage', + 'sequence': 0, + }) + + # Event data # ------------------------------------------------------------ - cls.website_customer_data = [{ - 'name': 'My Customer %02d' % x, - 'partner_id': cls.env.ref('base.public_partner').id, - 'email': 'email.%02d@test.example.com' % x, - 'phone': '04560000%02d' % x, - 'registration_answer_ids': [ + cls.event_base_vals = { + 'name': 'Test Event', + 'date_begin': cls.reference_now + timedelta(days=1), + 'date_end': cls.reference_now + timedelta(days=5), + 'is_published': True, + } + + cls.test_event = cls.env['event.event'].create({ + 'name': 'Test Event', + 'auto_confirm': True, + 'date_begin': datetime.now() + timedelta(days=1), + 'date_end': datetime.now() + timedelta(days=5), + 'date_tz': 'Europe/Brussels', + 'event_type_id': cls.test_event_type.id, + 'is_published': True, + }) + # update post-synchronize data + ticket_1 = cls.test_event.event_ticket_ids.filtered(lambda t: t.name == 'Ticket1') + ticket_2 = cls.test_event.event_ticket_ids.filtered(lambda t: t.name == 'Ticket2') + ticket_1.start_sale_datetime = cls.reference_now + timedelta(hours=1) + ticket_2.start_sale_datetime = cls.reference_now + timedelta(hours=2) + + # Website data + # ------------------------------------------------------------ + + cls.website = cls.env['website'].search([ + ('company_id', '=', cls.company_admin.id) + ], limit=1) + + cls.customer_data = [ + {'email': 'customer.email.%02d@test.example.com' % x, + 'name': 'My Customer %02d' % x, + 'mobile': '04569999%02d' % x, + 'partner_id': False, + 'phone': '04560000%02d' % x, + } for x in range(0, 10) + ] + cls.website_customer_data = [ + {'email': 'website.email.%02d@test.example.com' % x, + 'name': 'My Customer %02d' % x, + 'mobile': '04569999%02d' % x, + 'partner_id': cls.env.ref('base.public_partner').id, + 'phone': '04560000%02d' % x, + 'registration_answer_ids': [ (0, 0, { - 'question_id': cls.event_question_1.id, - 'value_answer_id': cls.event_question_1.answer_ids[(x % 2)].id, + 'question_id': cls.test_event.question_ids[0].id, + 'value_answer_id': cls.test_event.question_ids[0].answer_ids[(x % 2)].id, }), (0, 0, { - 'question_id': cls.event_question_2.id, - 'value_answer_id': cls.event_question_2.answer_ids[(x % 2)].id, + 'question_id': cls.test_event.question_ids[1].id, + 'value_answer_id': cls.test_event.question_ids[1].answer_ids[(x % 2)].id, }), (0, 0, { - 'question_id': cls.event_question_3.id, + 'question_id': cls.test_event.question_ids[2].id, 'value_text_box': 'CustomerAnswer%s' % x, }) - ], - } for x in range(0, 4)] + ], + } for x in range(0, 10) + ] + cls.partners = cls.env['res.partner'].create([ + {'email': 'partner.email.%02d@test.example.com' % x, + 'name': 'PartnerCustomer', + 'mobile': '04569999%02d' % x, + 'phone': '04560000%02d' % x, + } for x in range(0, 10) + ]) def assertLeadConvertion(self, rule, registrations, partner=None, **expected): super(TestEventFullCommon, self).assertLeadConvertion(rule, registrations, partner=partner, **expected) @@ -127,11 +304,18 @@ class TestEventFullCommon(TestEventCrmCommon, TestSalesCommon, EventDtPatcher, M self.assertIn(answer.value_text_box, lead.description) # better: check multi line -class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, EventDtPatcher, MockVisitor): +class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor): def setUp(self): super(TestWEventCommon, self).setUp() + # Context data: dates + # ------------------------------------------------------------ + + # Mock dates to have reproducible computed fields based on time + self.reference_now = datetime(2021, 12, 1, 10, 0, 0) + self.reference_today = datetime(2021, 12, 1) + self.event_product = self.env['product.product'].create({ 'name': 'Test Event Registration', 'default_code': 'EVENT_REG', diff --git a/addons/test_event_full/tests/test_event_crm.py b/addons/test_event_full/tests/test_event_crm.py index 5da23531480..9c1d6f11375 100644 --- a/addons/test_event_full/tests/test_event_crm.py +++ b/addons/test_event_full/tests/test_event_crm.py @@ -12,8 +12,10 @@ class TestEventCrm(TestEventFullCommon): super(TestEventCrm, cls).setUpClass() cls.TICKET1_COUNT, cls.TICKET2_COUNT = 3, 1 - ticket1 = cls.event_0.event_ticket_ids[0] - ticket2 = cls.event_0.event_ticket_ids[1] + ticket1 = cls.test_event.event_ticket_ids[0] + ticket2 = cls.test_event.event_ticket_ids[1] + + (cls.test_rule_attendee + cls.test_rule_order).write({'event_id': cls.test_event.id}) # PREPARE SO DATA # ------------------------------------------------------------ @@ -22,12 +24,12 @@ class TestEventCrm(TestEventFullCommon): cls.customer_so.write({ 'order_line': [ (0, 0, { - 'event_id': cls.event_0.id, + 'event_id': cls.test_event.id, 'event_ticket_id': ticket1.id, 'product_id': ticket1.product_id.id, 'product_uom_qty': cls.TICKET1_COUNT, }), (0, 0, { - 'event_id': cls.event_0.id, + 'event_id': cls.test_event.id, 'event_ticket_id': ticket2.id, 'product_id': ticket2.product_id.id, 'product_uom_qty': cls.TICKET2_COUNT, @@ -52,7 +54,7 @@ class TestEventCrm(TestEventFullCommon): t1_registrations = self.env['event.registration'].create(t1_reg_vals) # check effect: registrations, leads - self.assertEqual(self.event_0.registration_ids, t1_registrations) + self.assertEqual(self.test_event.registration_ids, t1_registrations) self.assertEqual(len(self.test_rule_order.lead_ids), 1) self.assertEqual(self.test_rule_order_done.lead_ids, self.env['crm.lead']) # check lead converted based on registrations @@ -62,17 +64,17 @@ class TestEventCrm(TestEventFullCommon): # and added to the lead as part of the same group customer_so.action_confirm() self.assertEqual(customer_so.state, 'sale') - self.assertEqual(len(self.event_0.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT) + self.assertEqual(len(self.test_event.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT) self.assertEqual(len(self.test_rule_order.lead_ids), 1) # no new lead created self.assertEqual(self.test_rule_order_done.lead_ids, self.env['crm.lead']) # this one still not triggered # check existing lead has been updated with new registrations - self.assertLeadConvertion(self.test_rule_order, self.event_0.registration_ids, partner=customer_so.partner_id) + self.assertLeadConvertion(self.test_rule_order, self.test_event.registration_ids, partner=customer_so.partner_id) # Confirm registrations -> trigger the "DONE" rule, one new lead linked to all # event registrations created in this test as all belong to the same SO - self.event_0.registration_ids.write({'state': 'done'}) - self.assertLeadConvertion(self.test_rule_order_done, self.event_0.registration_ids, partner=customer_so.partner_id) + self.test_event.registration_ids.write({'state': 'done'}) + self.assertLeadConvertion(self.test_rule_order_done, self.test_event.registration_ids, partner=customer_so.partner_id) @users('user_sales_salesman') def test_event_crm_sale_mixed_group(self): @@ -83,9 +85,9 @@ class TestEventCrm(TestEventFullCommon): 'partner_id': public_partner.id, 'order_line': [ (0, 0, { - 'event_id': self.event_0.id, - 'event_ticket_id': self.event_0.event_ticket_ids[0].id, - 'product_id': self.event_0.event_ticket_ids[0].product_id.id, + 'event_id': self.test_event.id, + 'event_ticket_id': self.test_event.event_ticket_ids[0].id, + 'product_id': self.test_event.event_ticket_ids[0].product_id.id, 'product_uom_qty': 2, }) ] @@ -109,9 +111,9 @@ class TestEventCrm(TestEventFullCommon): ] self.env['event.registration'].create(mixed_reg_vals) - public_regs = self.event_0.registration_ids.filtered(lambda reg: reg.sale_order_id == public_so) + public_regs = self.test_event.registration_ids.filtered(lambda reg: reg.sale_order_id == public_so) self.assertEqual(len(public_regs), 2) - customer_regs = self.event_0.registration_ids.filtered(lambda reg: reg.sale_order_id == customer_so) + customer_regs = self.test_event.registration_ids.filtered(lambda reg: reg.sale_order_id == customer_so) self.assertEqual(len(customer_regs), 2) self.assertLeadConvertion(self.test_rule_order, public_regs, partner=None) self.assertLeadConvertion(self.test_rule_order, customer_regs, partner=customer_so.partner_id) @@ -122,7 +124,9 @@ class TestEventCrm(TestEventFullCommon): This somehow simulates a simplified website_event_sale flow. """ public_partner = self.env.ref('base.public_partner') customer_so = self.env['sale.order'].browse(self.customer_so.id) - customer_so.write({'partner_id': public_partner.id}) + customer_so.write({ + 'partner_id': public_partner.id, + }) # adding some tickets to SO t1_reg_vals = [ @@ -132,7 +136,7 @@ class TestEventCrm(TestEventFullCommon): for customer_data in self.website_customer_data[:self.TICKET1_COUNT] ] t1_registrations = self.env['event.registration'].create(t1_reg_vals) - self.assertEqual(self.event_0.registration_ids, t1_registrations) + self.assertEqual(self.test_event.registration_ids, t1_registrations) # check lead converted based on registrations self.assertLeadConvertion(self.test_rule_order, t1_registrations, partner=None) @@ -141,7 +145,7 @@ class TestEventCrm(TestEventFullCommon): # BUT as public user -> no email -> not taken into account by rule customer_so.action_confirm() self.assertEqual(customer_so.state, 'sale') - self.assertEqual(len(self.event_0.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT) + self.assertEqual(len(self.test_event.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT) self.assertLeadConvertion(self.test_rule_order, t1_registrations, partner=None) # SO has a customer set -> main contact of lead is updated accordingly diff --git a/addons/test_event_full/tests/test_event_event.py b/addons/test_event_full/tests/test_event_event.py new file mode 100644 index 00000000000..7a96c7eee93 --- /dev/null +++ b/addons/test_event_full/tests/test_event_event.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import datetime, timedelta +from freezegun import freeze_time + +from odoo import Command, exceptions +from odoo.addons.test_event_full.tests.common import TestEventFullCommon +from odoo.tests.common import users + + +class TestEventEvent(TestEventFullCommon): + + @users('event_user') + def test_event_create_wtype(self): + """ Test a single event creation with a type defining all sub records. """ + event_type = self.env['event.type'].browse(self.test_event_type.ids) + + event_values = dict( + self.event_base_vals, + event_type_id=event_type.id, + ) + event = self.env['event.event'].create([event_values]) + event.write({ + 'event_ticket_ids': [ + Command.update( + event.event_ticket_ids[0].id, + {'start_sale_datetime': self.reference_now + timedelta(hours=1)}, + ), + Command.update( + event.event_ticket_ids[1].id, + {'start_sale_datetime': self.reference_now + timedelta(hours=2)}, + ) + ], + }) + + # check result + self.assertEqual(event.address_id, self.env.user.company_id.partner_id) + self.assertTrue(event.auto_confirm) + self.assertEqual(event.country_id, self.env.user.company_id.country_id) + self.assertEqual(event.date_tz, 'Europe/Paris') + self.assertEqual(event.event_booth_count, 4) + self.assertEqual(len(event.event_mail_ids), 3) + self.assertEqual(len(event.event_ticket_ids), 2) + self.assertTrue(event.introduction_menu) + self.assertTrue(event.location_menu) + self.assertTrue(event.menu_register_cta) + self.assertEqual(event.message_partner_ids, self.env.user.partner_id + self.env.user.company_id.partner_id) + self.assertEqual(event.note, '

Template note

') + self.assertTrue(event.register_menu) + self.assertEqual(len(event.question_ids), 3) + self.assertTrue(event.seats_limited) + self.assertEqual(event.seats_max, 30) + self.assertEqual(event.stage_id, self.stage_def) + self.assertEqual(event.tag_ids, self.tags) + self.assertTrue(event.website_menu) + + # check time dependent computation: before event + with freeze_time(self.reference_now): + self.assertFalse(event.is_finished) + self.assertFalse(event.is_ongoing) + self.assertFalse(event.event_registrations_started) + + # check time dependent computation: registrations started + with freeze_time(self.reference_now + timedelta(hours=1)): + event.invalidate_cache(fnames=['is_finished', 'is_ongoing', 'event_registrations_started']) + self.assertFalse(event.is_finished) + self.assertFalse(event.is_ongoing) + self.assertTrue(event.event_registrations_started) + + # check time dependent computation: during event + with freeze_time(self.reference_now + timedelta(days=1, hours=1)): + event.invalidate_cache(fnames=['is_finished', 'is_ongoing', 'event_registrations_started']) + self.assertFalse(event.is_finished) + self.assertTrue(event.is_ongoing) + self.assertTrue(event.event_registrations_started) + + @freeze_time('2021-12-01 11:00:00') + @users('event_user') + def test_event_seats_and_schedulers(self): + now = datetime.now() # used to force create_date, as sql is not wrapped by freeze gun + self.env.cr._now = now + + test_event = self.env['event.event'].browse(self.test_event.ids) + ticket_1 = test_event.event_ticket_ids.filtered(lambda ticket: ticket.name == 'Ticket1') + ticket_2 = test_event.event_ticket_ids.filtered(lambda ticket: ticket.name == 'Ticket2') + + # check initial data + self.assertTrue(test_event.event_registrations_started) + self.assertEqual(test_event.seats_available, 30) + self.assertEqual(ticket_1.seats_available, 10) + self.assertTrue(ticket_1.sale_available) + self.assertEqual(ticket_2.seats_available, 0) + self.assertFalse(ticket_2.sale_available) + + # make 9 registrations (let 1 on ticket) + with self.mock_mail_gateway(): + self.env['event.registration'].create([ + {'create_date': now, + 'email': 'test.customer.%02d@test.example.com' % x, + 'phone': '04560011%02d' % x, + 'event_id': test_event.id, + 'event_ticket_id': ticket_1.id, + 'name': 'Customer %d' % x, + } + for x in range(0, 9) + ]) + # generated emails from scheduler + self.assertEqual(len(self._new_mails), 9) + # event and ticket seats update + self.assertEqual(len(test_event.registration_ids), 9) + self.assertEqual(test_event.seats_available, 21) + self.assertEqual(ticket_1.seats_available, 1) + self.assertEqual(ticket_2.seats_available, 0) + + # prevent registration due to ticket limit + with self.assertRaises(exceptions.ValidationError): + self.env['event.registration'].create([ + {'create_date': now, + 'email': 'additional.customer.%02d@test.example.com' % x, + 'phone': '04560011%02d' % x, + 'event_id': test_event.id, + 'event_ticket_id': ticket_1.id, + 'name': 'Additional Customer %d' % x, + } + for x in range(0, 2) + ]) + + # make 20 registrations (on free ticket) + with self.mock_mail_gateway(): + self.env['event.registration'].create([ + {'create_date': now, + 'email': 'other.customer.%02d@test.example.com' % x, + 'phone': '04560011%02d' % x, + 'event_id': test_event.id, + 'event_ticket_id': ticket_2.id, + 'name': 'Other Customer %d' % x, + } + for x in range(0, 20) + ]) + # event and ticket seats update + self.assertEqual(len(test_event.registration_ids), 29) + self.assertEqual(test_event.seats_available, 1) + self.assertEqual(ticket_1.seats_available, 1) + self.assertEqual(ticket_2.seats_available, 0) + + # prevent registration due to event limit + with self.assertRaises(exceptions.ValidationError): + self.env['event.registration'].create([ + {'create_date': now, + 'email': 'additional.customer.%02d@test.example.com' % x, + 'phone': '04560011%02d' % x, + 'event_id': test_event.id, + 'event_ticket_id': ticket_2.id, + 'name': 'Additional Customer %d' % x, + } + for x in range(0, 2) + ]) diff --git a/addons/test_event_full/tests/test_event_security.py b/addons/test_event_full/tests/test_event_security.py index a5ba250691d..e6adc5817a8 100644 --- a/addons/test_event_full/tests/test_event_security.py +++ b/addons/test_event_full/tests/test_event_security.py @@ -1,30 +1,31 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import datetime -from dateutil.relativedelta import relativedelta +from datetime import datetime, timedelta -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.test_event_full.tests.common import TestEventFullCommon from odoo.exceptions import AccessError +from odoo.tests import tagged from odoo.tests.common import users from odoo.tools import mute_logger -class TestEventSecurity(TestEventCommon): +@tagged('security') +class TestEventSecurity(TestEventFullCommon): @users('user_employee') @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') def test_event_access_employee(self): # Event: read ok - event = self.event_0.with_user(self.env.user) + event = self.test_event.with_user(self.env.user) event.read(['name']) # Event: read only 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), + 'date_begin': datetime.now() + timedelta(days=-1), + 'date_end': datetime.now() + timedelta(days=1), 'seats_limited': True, 'seats_max': 10, }) @@ -35,9 +36,9 @@ class TestEventSecurity(TestEventCommon): # Event Type with self.assertRaises(AccessError): - self.event_type_complex.with_user(self.env.user).read(['name']) + self.test_event_type.with_user(self.env.user).read(['name']) with self.assertRaises(AccessError): - self.event_type_complex.with_user(self.env.user).write({'name': 'Test Write'}) + self.test_event_type.with_user(self.env.user).write({'name': 'Test Write'}) # Event Stage with self.assertRaises(AccessError): @@ -53,7 +54,7 @@ class TestEventSecurity(TestEventCommon): @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') def test_event_access_event_registration(self): # Event: read ok - event = self.event_0.with_user(self.env.user) + event = self.test_event.with_user(self.env.user) event.read(['name', 'user_id', 'kanban_state_label']) # Event: read only @@ -64,9 +65,9 @@ class TestEventSecurity(TestEventCommon): # Event Registration registration = self.env['event.registration'].create({ - 'event_id': self.event_0.id, + 'event_id': event.id, }) - self.assertEqual(registration.event_id.name, self.event_0.name, 'Registration users should be able to read') + self.assertEqual(registration.event_id.name, event.name, 'Registration users should be able to read') registration.name = 'Test write' with self.assertRaises(AccessError): registration.unlink() @@ -75,13 +76,13 @@ class TestEventSecurity(TestEventCommon): @mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model') def test_event_access_event_user(self): # Event - event = self.event_0.with_user(self.env.user) + event = self.test_event.with_user(self.env.user) event.read(['name', 'user_id', 'kanban_state_label']) event.write({'name': 'New name'}) self.env['event.event'].create({ 'name': 'Event', - 'date_begin': datetime.now() + relativedelta(days=-1), - 'date_end': datetime.now() + relativedelta(days=1), + 'date_begin': datetime.now() + timedelta(days=-1), + 'date_end': datetime.now() + timedelta(days=1), }) # Event: cannot unlink @@ -112,8 +113,8 @@ class TestEventSecurity(TestEventCommon): # Event event = self.env['event.event'].create({ 'name': 'ManagerEvent', - 'date_begin': datetime.now() + relativedelta(days=-1), - 'date_end': datetime.now() + relativedelta(days=1), + 'date_begin': datetime.now() + timedelta(days=-1), + 'date_end': datetime.now() + timedelta(days=1), }) event.write({'name': 'New Event Name'}) @@ -180,13 +181,13 @@ class TestEventSecurity(TestEventCommon): event_company_1, event_company_2 = self.env['event.event'].create([ { 'name': 'Event Company 1', - 'date_begin': datetime.now() + relativedelta(days=-1), - 'date_end': datetime.now() + relativedelta(days=1), + 'date_begin': datetime.now() + timedelta(days=-1), + 'date_end': datetime.now() + timedelta(days=1), 'company_id': company_1.id, }, { 'name': 'Event Company 2', - 'date_begin': datetime.now() + relativedelta(days=-1), - 'date_end': datetime.now() + relativedelta(days=1), + 'date_begin': datetime.now() + timedelta(days=-1), + 'date_end': datetime.now() + timedelta(days=1), 'company_id': company_2.id, } ]) diff --git a/addons/test_event_full/tests/test_performance.py b/addons/test_event_full/tests/test_performance.py new file mode 100644 index 00000000000..91c59cdd5fb --- /dev/null +++ b/addons/test_event_full/tests/test_performance.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import timedelta +from freezegun import freeze_time + +from odoo.addons.test_event_full.tests.common import TestEventFullCommon +from odoo.addons.website.tests.test_performance import UtilPerf +from odoo.tests.common import users, warmup, Form +from odoo.tests import tagged + + +@tagged('event_performance') +class EventPerformanceCase(TestEventFullCommon): + + def setUp(self): + super(EventPerformanceCase, self).setUp() + # patch registry to simulate a ready environment + self.patch(self.env.registry, 'ready', True) + self._flush_tracking() + + def _flush_tracking(self): + """ Force the creation of tracking values notably, and ensure tests are + reproducible. """ + self.env['base'].flush() + self.cr.flush() + + +@tagged('event_performance') +class TestEventPerformance(EventPerformanceCase): + + @users('event_user') + @warmup + def test_event_create_batch_notype(self): + """ Test multiple event creation (import) """ + batch_size = 20 + + # simple without type involved + with freeze_time(self.reference_now), self.assertQueryCount(event_user=459): # tef only: 459 (453) - com runbot: 453 - ent runbot 453 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = [ + dict(self.event_base_vals, + website_menu=False) + for x in range(batch_size) + ] + self.env['event.event'].create(event_values) + + @users('event_user') + @warmup + def test_event_create_batch_notype_website(self): + """ Test multiple event creation (import) """ + batch_size = 20 + + # simple without type involved + website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=5604): # tef only: 5179 (5174) - com runbot: 5178 - ent runbot 5603 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = [ + dict(self.event_base_vals, + website_menu=True + ) + for x in range(batch_size) + ] + self.env['event.event'].create(event_values) + + @users('event_user') + @warmup + def test_event_create_batch_wtype(self): + """ Test multiple event creation (import) """ + batch_size = 20 + event_type = self.env['event.type'].browse(self.test_event_type.ids) + + # complex with type + with freeze_time(self.reference_now), self.assertQueryCount(event_user=804): # tef only: 804 (798) - com runbot: 798 - ent runbot 798 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = [ + dict(self.event_base_vals, + event_type_id=event_type.id, + website_menu=False, + ) + for x in range(batch_size) + ] + self.env['event.event'].create(event_values) + + @users('event_user') + @warmup + def test_event_create_batch_wtype_website(self): + """ Test multiple event creation (import) """ + batch_size = 20 + event_type = self.env['event.type'].browse(self.test_event_type.ids) + + # complex with type + website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=5956): # tef only: 5531 (5526) - com runbot: 5530 - ent runbot 5955 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = [ + dict(self.event_base_vals, + event_type_id=event_type.id, + ) + for x in range(batch_size) + ] + self.env['event.event'].create(event_values) + + + @users('event_user') + @warmup + def test_event_create_form_notype(self): + """ Test a single event creation using Form """ + has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise + + # no type, no website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=240): # tef only: 186 - com runbot: 185 + self.env.cr._now = self.reference_now # force create_date to check schedulers + with Form(self.env['event.event']) as event_form: + event_form.name = 'Test Event' + event_form.date_begin = self.reference_now + timedelta(days=1) + event_form.date_end = self.reference_now + timedelta(days=5) + event_form.website_menu = False + if has_social: + event_form.social_menu = False + _event = event_form.save() + + @users('event_user') + @warmup + def test_event_create_form_notype_website(self): + """ Test a single event creation using Form """ + has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise + + # no type, website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=748): # tef only: 632 - com runbot: 632 + self.env.cr._now = self.reference_now # force create_date to check schedulers + with Form(self.env['event.event']) as event_form: + event_form.name = 'Test Event' + event_form.date_begin = self.reference_now + timedelta(days=1) + event_form.date_end = self.reference_now + timedelta(days=5) + event_form.website_menu = True + if has_social: + event_form.social_menu = False + _event = event_form.save() + + @users('event_user') + @warmup + def test_event_create_form_type_website(self): + """ Test a single event creation using Form """ + event_type = self.env['event.type'].browse(self.test_event_type.ids) + has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise + + # type and website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=795): # tef only: 681 - com runbot: 683 + self.env.cr._now = self.reference_now # force create_date to check schedulers + with Form(self.env['event.event']) as event_form: + event_form.name = 'Test Event' + event_form.date_begin = self.reference_now + timedelta(days=1) + event_form.date_end = self.reference_now + timedelta(days=5) + event_form.event_type_id = event_type + if has_social: + event_form.social_menu = False + + @users('event_user') + @warmup + def test_event_create_single_notype(self): + """ Test a single event creation """ + # simple without type involved + with freeze_time(self.reference_now), self.assertQueryCount(event_user=41): # tef only: 41 (35) - com runbot: 35 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = dict( + self.event_base_vals, + website_menu=False + ) + self.env['event.event'].create([event_values]) + + @users('event_user') + @warmup + def test_event_create_single_notype_website(self): + """ Test a single event creation """ + # simple without type involved + website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=379): # tef only: 353 (348) - com runbot: 352 - ent runbot 378 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = dict( + self.event_base_vals, + website_menu=True + ) + self.env['event.event'].create([event_values]) + + @users('event_user') + @warmup + def test_event_create_single_wtype(self): + """ Test a single event creation """ + event_type = self.env['event.type'].browse(self.test_event_type.ids) + + # complex with type + with freeze_time(self.reference_now), self.assertQueryCount(event_user=81): # tef only: 81 (75) - com runbot: 75 - ent runbot 75 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = dict( + self.event_base_vals, + event_type_id=event_type.id, + website_menu=False + ) + self.env['event.event'].create([event_values]) + + @users('event_user') + @warmup + def test_event_create_single_wtype_website(self): + """ Test a single event creation """ + event_type = self.env['event.type'].browse(self.test_event_type.ids) + + # complex with type + website + with freeze_time(self.reference_now), self.assertQueryCount(event_user=426): # tef only: 400 (395) - com runbot: 399 - ent runbot 425 + self.env.cr._now = self.reference_now # force create_date to check schedulers + event_values = dict( + self.event_base_vals, + event_type_id=event_type.id, + ) + self.env['event.event'].create([event_values]) + + +@tagged('event_performance', 'registration_performance') +class TestRegistrationPerformance(EventPerformanceCase): + + @users('event_user') + @warmup + def test_registration_create_batch(self): + """ Test multiple registrations creation (batch of 10 without partner + and batch of 10 with partner) + + # TODO: with self.profile(collectors=['sql']) as _profile: + """ + event = self.env['event.event'].browse(self.test_event.ids) + + with freeze_time(self.reference_now), self.assertQueryCount(event_user=873): # tef only: 828 - com runbot 871 + self.env.cr._now = self.reference_now # force create_date to check schedulers + registration_values = [ + dict(reg_data, + event_id=event.id) + for reg_data in self.customer_data + ] + registration_values += [ + {'event_id': event.id, + 'partner_id': partner.id, + } for partner in self.partners + ] + self.env['event.registration'].create(registration_values) + + @users('event_user') + @warmup + def test_registration_create_batch_website(self): + """ Test multiple registrations creation (batch of 10 without partner + and batch of 10 with partner) with some additional informations (register + form like) """ + event = self.env['event.event'].browse(self.test_event.ids) + + with freeze_time(self.reference_now), self.assertQueryCount(event_user=944): # tef only: 898 - com runbot 941 + self.env.cr._now = self.reference_now # force create_date to check schedulers + registration_values = [ + dict(reg_data, + event_id=event.id) + for reg_data in self.website_customer_data + ] + registration_values += [ + {'event_id': event.id, + 'partner_id': partner.id, + 'registration_answer_ids': self.website_customer_data[0]['registration_answer_ids'], + } for partner in self.partners + ] + self.env['event.registration'].create(registration_values) + + @users('event_user') + @warmup + def test_registration_create_form_customer(self): + """ Test a single registration creation using Form """ + event = self.env['event.event'].browse(self.test_event.ids) + + with freeze_time(self.reference_now), self.assertQueryCount(event_user=238): # tef only: 218 - com runbot 223 + self.env.cr._now = self.reference_now # force create_date to check schedulers + with Form(self.env['event.registration']) as reg_form: + reg_form.event_id = event + reg_form.email = 'email.00@test.example.com' + reg_form.mobile = '0456999999' + reg_form.name = 'My Customer' + reg_form.phone = '0456000000' + _registration = reg_form.save() + + @users('event_user') + @warmup + def test_registration_create_form_partner(self): + """ Test a single registration creation using Form """ + event = self.env['event.event'].browse(self.test_event.ids) + + with freeze_time(self.reference_now), self.assertQueryCount(event_user=241): # tef only: 221 - com runbot 225 + self.env.cr._now = self.reference_now # force create_date to check schedulers + with Form(self.env['event.registration']) as reg_form: + reg_form.event_id = event + reg_form.partner_id = self.partners[0] + _registration = reg_form.save() + + @users('event_user') + @warmup + def test_registration_create_single_customer(self): + """ Test a single registration creation """ + event = self.env['event.event'].browse(self.test_event.ids) + + # simple customer data + with freeze_time(self.reference_now), self.assertQueryCount(event_user=144): # tef only: 137 - com runbot 142 + self.env.cr._now = self.reference_now # force create_date to check schedulers + registration_values = dict( + self.customer_data[0], + event_id=event.id) + self.env['event.registration'].create([registration_values]) + + @users('event_user') + @warmup + def test_registration_create_single_partner(self): + """ Test a single registration creation """ + event = self.env['event.event'].browse(self.test_event.ids) + + # partner-based customer + with freeze_time(self.reference_now), self.assertQueryCount(event_user=151): # tef only: 145 - com runbot 150 + self.env.cr._now = self.reference_now # force create_date to check schedulers + registration_values = { + 'event_id': event.id, + 'partner_id': self.partners[0].id, + } + self.env['event.registration'].create([registration_values]) + + @users('event_user') + @warmup + def test_registration_create_single_website(self): + """ Test a single registration creation """ + event = self.env['event.event'].browse(self.test_event.ids) + + # website customer data + with freeze_time(self.reference_now), self.assertQueryCount(event_user=155): # tef only: 146 - com runbot 151 + self.env.cr._now = self.reference_now # force create_date to check schedulers + registration_values = dict( + self.website_customer_data[0], + event_id=event.id) + self.env['event.registration'].create([registration_values]) + + +@tagged('event_performance', 'event_online', 'post_install', '-at_install') +class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf): + + @classmethod + def setUpClass(cls): + super(TestOnlineEventPerformance, cls).setUpClass() + # if website_livechat is installed, disable it + if 'channel_id' in cls.env['website']: + cls.env['website'].search([]).channel_id = False + + cash_journal = cls.env['account.journal'].create({ + 'name': 'Cash - Test', + 'type': 'cash', + 'code': 'CASH - Test' + }) + cls.env['payment.acquirer'].search([('provider', '=', 'test')]).write({ + 'journal_id': cash_journal.id, + 'state': 'test' + }) + + # clean even page to make it reproducible + cls.env['event.event'].search([('name', '!=', 'Test Event')]).write({'active': False}) + # create noise for events + cls.noise_events = cls.env['event.event'].create([ + {'name': 'Event %02d' % idx, + 'date_begin': cls.reference_now + timedelta(days=(-2 + int(idx/10))), + 'date_end': cls.reference_now + timedelta(days=5), + 'is_published': True, + } + for idx in range(0, 50) + ]) + + def _test_url_open(self, url): + url += ('?' not in url and '?' or '') + '&nocache' + return self.url_open(url) + + @warmup + def test_event_page_event_manager(self): + # website customer data + with freeze_time(self.reference_now): + self.authenticate('user_eventmanager', 'user_eventmanager') + with self.assertQueryCount(default=65): # tef only: 64 (+1 ent) + self._test_url_open('/event/%i' % self.test_event.id) + + @warmup + def test_event_page_public(self): + # website customer data + with freeze_time(self.reference_now): + self.authenticate(None, None) + with self.assertQueryCount(default=43): # tef only: 43 + self._test_url_open('/event/%i' % self.test_event.id) + + @warmup + def test_events_browse_event_manager(self): + # website customer data + with freeze_time(self.reference_now): + self.authenticate('user_eventmanager', 'user_eventmanager') + with self.assertQueryCount(default=51): # tef only: 50 (+1 ent) + self._test_url_open('/event') + + @warmup + def test_events_browse_public(self): + # website customer data + with freeze_time(self.reference_now): + self.authenticate(None, None) + with self.assertQueryCount(default=32): # tef only: 32 + self._test_url_open('/event') + + # @warmup + # def test_register_public(self): + # with freeze_time(self.reference_now + timedelta(hours=3)): # be sure sales has started + # self.assertTrue(self.test_event.event_registrations_started) + # self.authenticate(None, None) + # with self.assertQueryCount(default=99999): # tef only: 1110 + # self.browser_js( + # '/event/%i/register' % self.test_event.id, + # 'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_performance_register")', + # 'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_performance_register.ready', + # login=None, + # timeout=200, + # ) + + # # minimal checkup, to be improved in future tests independently from performance + # self.assertEqual(len(self.test_event.registration_ids), 3) + # self.assertEqual(len(self.test_event.registration_ids.visitor_id), 1) diff --git a/addons/test_event_full/tests/test_wevent_register.py b/addons/test_event_full/tests/test_wevent_register.py index b1f34d102cd..32ec951e657 100644 --- a/addons/test_event_full/tests/test_wevent_register.py +++ b/addons/test_event_full/tests/test_wevent_register.py @@ -1,21 +1,23 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from freezegun import freeze_time + from odoo import tests from odoo.addons.test_event_full.tests.common import TestWEventCommon -from odoo.tests.common import HOST -@tests.common.tagged('post_install', '-at_install') +@tests.common.tagged('event_online', 'post_install', '-at_install') class TestWEventRegister(TestWEventCommon): def test_register(self): - self.browser_js( - '/event', - 'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_register")', - 'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_register.ready', - login=None - ) + with freeze_time(self.reference_now): + self.browser_js( + '/event', + 'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_register")', + 'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_register.ready', + login=None + ) new_registrations = self.event.registration_ids visitor = new_registrations.visitor_id diff --git a/addons/test_event_full/views/event_registration_templates_reports.xml b/addons/test_event_full/views/event_registration_templates_reports.xml new file mode 100644 index 00000000000..0fede0937b8 --- /dev/null +++ b/addons/test_event_full/views/event_registration_templates_reports.xml @@ -0,0 +1,14 @@ + + + + diff --git a/addons/website_event/models/event_event.py b/addons/website_event/models/event_event.py index 22ab9a88b91..41570117f58 100644 --- a/addons/website_event/models/event_event.py +++ b/addons/website_event/models/event_event.py @@ -44,7 +44,7 @@ class Event(models.Model): website_published = fields.Boolean(tracking=True) website_menu = fields.Boolean( string='Website Menu', - compute='_compute_website_menu', readonly=False, store=True, + compute='_compute_website_menu', precompute=True, readonly=False, store=True, help="Allows to display and manage event-specific menus on website.") menu_id = fields.Many2one('website.menu', 'Event Menu', copy=False) menu_register_cta = fields.Boolean( diff --git a/addons/website_event/tests/common.py b/addons/website_event/tests/common.py index 7fe660d403f..cc081c84ed4 100644 --- a/addons/website_event/tests/common.py +++ b/addons/website_event/tests/common.py @@ -4,74 +4,36 @@ from datetime import datetime, timedelta, time from unittest.mock import patch -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase from odoo.addons.mail.tests.common import mail_new_test_user from odoo.fields import Datetime as FieldsDatetime, Date as FieldsDate from odoo.tests.common import TransactionCase -class EventDtPatcher(TransactionCase): +class OnlineEventCase(EventCase): @classmethod def setUpClass(cls): - super(EventDtPatcher, cls).setUpClass() - - # Mock dates to have reproducible computed fields based on time - cls.reference_now = datetime(2020, 7, 6, 10, 0, 0) - cls.reference_today = datetime(2020, 7, 6) - - cls.event_dt = patch( - 'odoo.addons.event.models.event_event.fields.Datetime', - wraps=FieldsDatetime - ) - cls.wevent_dt = patch( - 'odoo.addons.website_event.models.event_event.fields.Datetime', - wraps=FieldsDatetime - ) - cls.wevent_main_dt = patch( - 'odoo.addons.website_event.controllers.main.fields.Datetime', - wraps=FieldsDatetime - ) - cls.event_date = patch( - 'odoo.addons.event.models.event_event.fields.Date', - wraps=FieldsDate - ) - cls.wevent_main_date = patch( - 'odoo.addons.website_event.controllers.main.fields.Date', - wraps=FieldsDate - ) - cls.mock_event_dt = cls.event_dt.start() - cls.mock_wevent_dt = cls.wevent_dt.start() - cls.mock_wevent_main_dt = cls.wevent_main_dt.start() - cls.mock_event_date = cls.event_date.start() - cls.mock_wevent_main_date = cls.wevent_main_date.start() - cls.mock_event_dt.now.return_value = cls.reference_now - cls.mock_wevent_dt.now.return_value = cls.reference_now - cls.mock_wevent_main_dt.now.return_value = cls.reference_now - cls.mock_event_date.today.return_value = cls.reference_today - cls.mock_wevent_main_date.today.return_value = cls.reference_today - cls.addClassCleanup(cls.event_dt.stop) - cls.addClassCleanup(cls.wevent_dt.stop) - cls.addClassCleanup(cls.wevent_main_dt.stop) - cls.addClassCleanup(cls.event_date.stop) - cls.addClassCleanup(cls.wevent_main_date.stop) - - -class TestWebsiteEventCommon(TestEventCommon): - - @classmethod - def setUpClass(cls): - super(TestWebsiteEventCommon, cls).setUpClass() + super(OnlineEventCase, cls).setUpClass() cls.company_main = cls.env.user.company_id cls.user_event_web_manager = mail_new_test_user( - cls.env, login='user_event_web_manager', - name='Martin Sales Manager', email='crm_manager@test.example.com', - company_id=cls.company_main.id, - notification_type='inbox', + cls.env, + company_id=cls.company_admin.id, + email='crm_manager@test.example.com', groups='event.group_event_manager,website.group_website_designer', + login='user_event_web_manager', + name='Martin Sales Manager', + notification_type='inbox', ) + cls.event_customer.write({ + 'website_description': '

I am your best customer, %s

' % cls.event_customer.name, + }) + cls.event_customer2.write({ + 'website_description': '

I am your best customer, %s

' % cls.event_customer2.name, + }) + def _get_menus(self): return set(['Introduction', 'Location', 'Register', 'Community']) @@ -97,21 +59,21 @@ class TestWebsiteEventCommon(TestEventCommon): self.assertFalse(bool(view)) -class TestEventOnlineCommon(TestEventCommon, EventDtPatcher): +class TestEventOnlineCommon(OnlineEventCase): @classmethod def setUpClass(cls): super(TestEventOnlineCommon, cls).setUpClass() + # Mock dates to have reproducible computed fields based on time + cls.reference_now = datetime(2020, 7, 6, 10, 0, 0) + cls.reference_today = datetime(2020, 7, 6) + # event if 8-18 in Europe/Brussels (DST) (first day: begins at 9, last day: ends at 15) - cls.event_0.write({ + cls.event_0 = cls.env['event.event'].create({ + 'name': 'TestEvent', + 'auto_confirm': True, 'date_begin': datetime.combine(cls.reference_now, time(7, 0)) - timedelta(days=1), 'date_end': datetime.combine(cls.reference_now, time(13, 0)) + timedelta(days=1), - }) - - cls.event_customer.write({ - 'website_description': '

I am your best customer, %s

' % cls.event_customer.name, - }) - cls.event_customer2.write({ - 'website_description': '

I am your best customer, %s

' % cls.event_customer2.name, + 'date_tz': 'Europe/Brussels', }) diff --git a/addons/website_event/tests/test_event_menus.py b/addons/website_event/tests/test_event_menus.py index aa65e159119..5ecdcb16236 100644 --- a/addons/website_event/tests/test_event_menus.py +++ b/addons/website_event/tests/test_event_menus.py @@ -4,11 +4,11 @@ from datetime import datetime, timedelta from odoo import fields -from odoo.addons.website_event.tests.common import TestWebsiteEventCommon +from odoo.addons.website_event.tests.common import OnlineEventCase from odoo.tests.common import users -class TestEventMenus(TestWebsiteEventCommon): +class TestEventMenus(OnlineEventCase): @users('user_eventmanager') def test_menu_management(self): diff --git a/addons/website_event/tests/test_event_visitor.py b/addons/website_event/tests/test_event_visitor.py index b9ef29c6547..7ba97eee480 100644 --- a/addons/website_event/tests/test_event_visitor.py +++ b/addons/website_event/tests/test_event_visitor.py @@ -4,10 +4,10 @@ from datetime import datetime, timedelta from odoo import fields -from odoo.addons.website_event.tests.common import TestWebsiteEventCommon +from odoo.addons.website_event.tests.common import TestEventOnlineCommon -class TestEventVisitor(TestWebsiteEventCommon): +class TestEventVisitor(TestEventOnlineCommon): def test_visitor_events(self): event_1 = self.env['event.event'].create({ diff --git a/addons/website_event/tests/test_website_event.py b/addons/website_event/tests/test_website_event.py index 36ce39b74c8..3bdd6ed447f 100644 --- a/addons/website_event/tests/test_website_event.py +++ b/addons/website_event/tests/test_website_event.py @@ -6,7 +6,7 @@ from datetime import datetime, timedelta from odoo.addons.base.tests.common import HttpCaseWithUserDemo from odoo.addons.mail.tests.common import mail_new_test_user from odoo.addons.website.tests.test_base_url import TestUrlCommon -from odoo.addons.website_event.tests.common import TestWebsiteEventCommon +from odoo.addons.website_event.tests.common import OnlineEventCase from odoo.tests import tagged from odoo.tools import mute_logger @@ -27,7 +27,7 @@ class TestURLs(TestUrlCommon): @tagged('post_install', '-at_install') -class TestWebsiteAccess(HttpCaseWithUserDemo, TestWebsiteEventCommon): +class TestWebsiteAccess(HttpCaseWithUserDemo, OnlineEventCase): def setUp(self): super(TestWebsiteAccess, self).setUp() diff --git a/addons/website_event/views/event_templates_page_registration.xml b/addons/website_event/views/event_templates_page_registration.xml index bb82f43fa57..41908d7c1d1 100644 --- a/addons/website_event/views/event_templates_page_registration.xml +++ b/addons/website_event/views/event_templates_page_registration.xml @@ -167,7 +167,9 @@
-
+
diff --git a/addons/website_event_exhibitor/tests/common.py b/addons/website_event_exhibitor/tests/common.py index 9e957fc2d32..57768661eed 100644 --- a/addons/website_event_exhibitor/tests/common.py +++ b/addons/website_event_exhibitor/tests/common.py @@ -26,4 +26,6 @@ class TestEventExhibitorCommon(TestEventOnlineCommon): 'partner_id': cls.sponsor_0_partner.id, 'event_id': cls.event_0.id, 'sponsor_type_id': cls.sponsor_type_0.id, + 'hour_from': 8.0, + 'hour_to': 18.0, }) diff --git a/addons/website_event_exhibitor/tests/test_sponsor_internals.py b/addons/website_event_exhibitor/tests/test_sponsor_internals.py index 8a84840042f..64ac1595b58 100644 --- a/addons/website_event_exhibitor/tests/test_sponsor_internals.py +++ b/addons/website_event_exhibitor/tests/test_sponsor_internals.py @@ -2,86 +2,63 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from datetime import datetime -from unittest.mock import patch +from freezegun import freeze_time from odoo.addons.website_event_exhibitor.tests.common import TestEventExhibitorCommon -from odoo.fields import Datetime as FieldsDatetime from odoo.tests.common import users class TestSponsorData(TestEventExhibitorCommon): - @classmethod - def setUpClass(cls): - super(TestSponsorData, cls).setUpClass() - - cls.sponsor_0.write({ - 'hour_from': 8.0, - 'hour_to': 18.0, - }) - - cls.wevent_exhib_dt = patch( - 'odoo.addons.website_event_exhibitor.models.event_sponsor.fields.Datetime', - wraps=FieldsDatetime - ) - cls.mock_wevent_exhib_dt = cls.wevent_exhib_dt.start() - cls.mock_wevent_exhib_dt.now.return_value = cls.reference_now - cls.addClassCleanup(cls.wevent_exhib_dt.stop) - @users('user_eventmanager') def test_event_date_computation(self): """ Test date computation. Pay attention that mocks returns UTC values, meaning we have to take into account Europe/Brussels offset """ - event = self.env['event.event'].browse(self.event_0.id) - sponsor = self.env['event.sponsor'].browse(self.sponsor_0.id) - event.invalidate_cache(fnames=['is_ongoing']) - self.assertTrue(sponsor.is_in_opening_hours) - self.assertTrue(event.is_ongoing) + with freeze_time(self.reference_now): + event = self.env['event.event'].browse(self.event_0.id) + sponsor = self.env['event.sponsor'].browse(self.sponsor_0.id) + event.invalidate_cache(fnames=['is_ongoing']) + self.assertTrue(sponsor.is_in_opening_hours) + self.assertTrue(event.is_ongoing) # After hour_from (9 > 8) - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 6, 7, 0, 0) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 6, 7, 0, 0) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertTrue(sponsor.is_in_opening_hours) - self.assertTrue(event.is_ongoing) + with freeze_time(datetime(2020, 7, 6, 7, 0, 0)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertTrue(sponsor.is_in_opening_hours) + self.assertTrue(event.is_ongoing) # At hour_from (8 = 8) - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 6, 6, 0, 0) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 6, 6, 0, 0) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertTrue(sponsor.is_in_opening_hours) - self.assertTrue(event.is_ongoing) + with freeze_time(datetime(2020, 7, 6, 6, 0, 0)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertTrue(sponsor.is_in_opening_hours) + self.assertTrue(event.is_ongoing) # Started but not opened (7h59 < 8) - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 6, 5, 59, 59) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 6, 5, 59, 59) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertFalse(sponsor.is_in_opening_hours) - self.assertTrue(event.is_ongoing) + with freeze_time(datetime(2020, 7, 6, 5, 59, 59)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertFalse(sponsor.is_in_opening_hours) + self.assertTrue(event.is_ongoing) # Evening event is not in opening hours (20 > 18) - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 6, 18, 0, 0) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 6, 18, 0, 0) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertFalse(sponsor.is_in_opening_hours) - self.assertTrue(event.is_ongoing) + with freeze_time(datetime(2020, 7, 6, 18, 0, 0)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertFalse(sponsor.is_in_opening_hours) + self.assertTrue(event.is_ongoing) # First day begins later - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 5, 6, 30, 0) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 5, 6, 30, 0) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertFalse(sponsor.is_in_opening_hours) - self.assertFalse(event.is_ongoing) + with freeze_time(datetime(2020, 7, 5, 6, 30, 0)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertFalse(sponsor.is_in_opening_hours) + self.assertFalse(event.is_ongoing) # End day finished sooner - self.mock_wevent_dt.now.return_value = datetime(2020, 7, 7, 13, 0, 1) - self.mock_wevent_exhib_dt.now.return_value = datetime(2020, 7, 7, 13, 0, 1) - event.invalidate_cache(fnames=['is_ongoing']) - sponsor.invalidate_cache(fnames=['is_in_opening_hours']) - self.assertFalse(sponsor.is_in_opening_hours) - self.assertFalse(event.is_ongoing) + with freeze_time(datetime(2020, 7, 7, 13, 0, 1)): + event.invalidate_cache(fnames=['is_ongoing']) + sponsor.invalidate_cache(fnames=['is_in_opening_hours']) + self.assertFalse(sponsor.is_in_opening_hours) + self.assertFalse(event.is_ongoing) diff --git a/addons/website_event_meet/tests/test_website_event_meet.py b/addons/website_event_meet/tests/test_website_event_meet.py index 8d1b8a95b0f..3e91f364481 100644 --- a/addons/website_event_meet/tests/test_website_event_meet.py +++ b/addons/website_event_meet/tests/test_website_event_meet.py @@ -1,11 +1,26 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.event.tests.common import TestEventCommon +from datetime import datetime, timedelta + +from odoo import fields +from odoo.addons.event.tests.common import EventCase from odoo.tests import Form -class TestWebsiteEventMeet(TestEventCommon): +class TestWebsiteEventMeet(EventCase): + + @classmethod + def setUpClass(cls): + super(TestWebsiteEventMeet, cls).setUpClass() + 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', + }) + def test_meeting_room_create(self): """Test that the field of the mixin are automatically filled.""" new_meeting_room_form = Form(self.env["event.meeting.room"]) diff --git a/addons/website_event_questions/tests/common.py b/addons/website_event_questions/tests/common.py index 1a621875dc2..62c30acbd70 100644 --- a/addons/website_event_questions/tests/common.py +++ b/addons/website_event_questions/tests/common.py @@ -1,19 +1,29 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.event.tests.common import TestEventCommon +from odoo.addons.event.tests.common import EventCase -class TestEventQuestionCommon(TestEventCommon): +class TestEventQuestionCommon(EventCase): @classmethod def setUpClass(cls): super(TestEventQuestionCommon, cls).setUpClass() + cls.event_type_questions = cls.env['event.type'].create({ + 'name': 'Update Type', + 'auto_confirm': True, + 'has_seats_limitation': True, + 'seats_max': 30, + 'default_timezone': 'Europe/Paris', + 'event_type_ticket_ids': [], + 'event_type_mail_ids': [], + }) + cls.event_question_1 = cls.env['event.question'].create({ 'title': 'Question1', 'question_type': 'simple_choice', - 'event_type_id': cls.event_type_complex.id, + 'event_type_id': cls.event_type_questions.id, 'once_per_order': False, 'answer_ids': [ (0, 0, {'name': 'Q1-Answer1'}), @@ -23,7 +33,7 @@ class TestEventQuestionCommon(TestEventCommon): cls.event_question_2 = cls.env['event.question'].create({ 'title': 'Question2', 'question_type': 'simple_choice', - 'event_type_id': cls.event_type_complex.id, + 'event_type_id': cls.event_type_questions.id, 'once_per_order': True, 'answer_ids': [ (0, 0, {'name': 'Q2-Answer1'}), @@ -33,6 +43,6 @@ class TestEventQuestionCommon(TestEventCommon): cls.event_question_3 = cls.env['event.question'].create({ 'title': 'Question3', 'question_type': 'text_box', - 'event_type_id': cls.event_type_complex.id, + 'event_type_id': cls.event_type_questions.id, 'once_per_order': True, }) diff --git a/addons/website_event_questions/tests/test_event_internals.py b/addons/website_event_questions/tests/test_event_internals.py index 28c9099734a..f1b8ce7d322 100644 --- a/addons/website_event_questions/tests/test_event_internals.py +++ b/addons/website_event_questions/tests/test_event_internals.py @@ -14,7 +14,7 @@ class TestEventData(TestEventQuestionCommon): @users('user_eventmanager') def test_event_type_configuration_from_type(self): - event_type = self.event_type_complex.with_user(self.env.user) + event_type = self.event_type_questions.with_user(self.env.user) event = self.env['event.event'].create({ 'name': 'Event Update Type', @@ -40,7 +40,7 @@ class TestEventData(TestEventQuestionCommon): def test_process_attendees_form(self): event = self.env['event.event'].create({ 'name': 'Event Update Type', - 'event_type_id': self.event_type_complex.with_user(self.env.user).id, + 'event_type_id': self.event_type_questions.with_user(self.env.user).id, 'date_begin': FieldsDatetime.to_string(datetime.today() + timedelta(days=1)), 'date_end': FieldsDatetime.to_string(datetime.today() + timedelta(days=15)), }) diff --git a/addons/website_event_questions/views/event_templates.xml b/addons/website_event_questions/views/event_templates.xml index 02c21b99b34..21b3428b8b8 100644 --- a/addons/website_event_questions/views/event_templates.xml +++ b/addons/website_event_questions/views/event_templates.xml @@ -5,7 +5,7 @@ -
+
@@ -18,7 +18,7 @@