[MERGE][IMP] mail, event: add test for batch emailing from template
PURPOSE
Mail: add tests for MailTemplate send_mail
Several flows use MailTemplate.send_mail() in batch, notably event email
scheduler which sends emails to event attendee in batch. This commit adds
tests around 'send_mail' method of MailTemplate model
* add tests for batch: it is currently not supported hence using a loop but
batch is going to be added soon, allowing to test the batch version works
as intended;
* add query counters, notably for batch mode and when dynamic reports are
involved in templates;
Event: improve mail scheduler tests
Make them easier to improve and modify
* use a dedicated setup (allowing to add specific unit tests on test data);
* move initial asserts into its own unit test (to keep other tests shorter);
* use available mocks for freezetime and sql.now;
Then add tests for registration emails, to check what happens for communication
scheduled right at registration time.
LINKS
Part of Task-3764894: Event: Allow using cron triggers for communication
Part of Task-3764891: Mail: Batch-ize MailTemplate send_mail
Part of Task-3164278: Mail: Batch send: ensure limit, avoid force
Part of Task-3084943: Event: Improve communication scheduler scalability
closes odoo/odoo#155717
Related: odoo/enterprise#57731
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -8,63 +8,82 @@ from freezegun import freeze_time
|
||||
from odoo import Command
|
||||
from odoo.addons.event.tests.common import EventCase
|
||||
from odoo.addons.mail.tests.common import MockEmail
|
||||
from odoo.tests import tagged, users
|
||||
from odoo.tools import formataddr, mute_logger
|
||||
|
||||
|
||||
@tagged('event_mail', 'post_install', '-at_install')
|
||||
class TestMailSchedule(EventCase, MockEmail):
|
||||
|
||||
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
|
||||
def test_event_mail_schedule(self):
|
||||
""" Test mail scheduling for events """
|
||||
self.env.company.write({
|
||||
'name': 'YourCompany',
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.env.company.write({
|
||||
'email': 'info@yourcompany.example.com',
|
||||
'name': 'YourCompany',
|
||||
})
|
||||
event_cron_id = self.env.ref('event.event_mail_scheduler')
|
||||
cls.event_cron_id = cls.env.ref('event.event_mail_scheduler')
|
||||
|
||||
# deactivate other schedulers to avoid messing with crons
|
||||
self.env['event.mail'].search([]).unlink()
|
||||
cls.env['event.mail'].search([]).unlink()
|
||||
|
||||
# freeze some datetimes, and ensure more than 1D+1H before event starts
|
||||
# to ease time-based scheduler check
|
||||
# Since `now` is used to set the `create_date` of an event and create_date
|
||||
# has often microseconds, we set it to ensure that the scheduler we still be
|
||||
# launched if scheduled_date == create_date - microseconds
|
||||
now = datetime(2021, 3, 20, 14, 30, 15, 123456)
|
||||
event_date_begin = datetime(2021, 3, 22, 8, 0, 0)
|
||||
event_date_end = datetime(2021, 3, 24, 18, 0, 0)
|
||||
cls.reference_now = datetime(2021, 3, 20, 14, 30, 15, 123456)
|
||||
cls.event_date_begin = datetime(2021, 3, 22, 8, 0, 0)
|
||||
cls.event_date_end = datetime(2021, 3, 24, 18, 0, 0)
|
||||
|
||||
with freeze_time(now):
|
||||
cls.template_subscription_id = cls.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')
|
||||
cls.template_reminder_id = cls.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')
|
||||
|
||||
with cls.mock_datetime_and_now(cls, cls.reference_now):
|
||||
# create with admin to force create_date
|
||||
test_event = self.env['event.event'].create({
|
||||
cls.test_event = cls.env['event.event'].create({
|
||||
'name': 'TestEventMail',
|
||||
'create_date': now,
|
||||
'user_id': self.user_eventmanager.id,
|
||||
'date_begin': event_date_begin,
|
||||
'date_end': event_date_end,
|
||||
'user_id': cls.user_eventmanager.id,
|
||||
'date_begin': cls.event_date_begin,
|
||||
'date_end': cls.event_date_end,
|
||||
'event_mail_ids': [
|
||||
(0, 0, { # right at subscription
|
||||
'interval_unit': 'now',
|
||||
'interval_type': 'after_sub',
|
||||
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')}),
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_subscription_id}',
|
||||
}),
|
||||
(0, 0, { # one hour after subscription
|
||||
'interval_nbr': 1,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'after_sub',
|
||||
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')}),
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_subscription_id}',
|
||||
}),
|
||||
(0, 0, { # 1 days before event
|
||||
'interval_nbr': 1,
|
||||
'interval_unit': 'days',
|
||||
'interval_type': 'before_event',
|
||||
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_reminder_id}',
|
||||
}),
|
||||
(0, 0, { # immediately after event
|
||||
'interval_nbr': 1,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'after_event',
|
||||
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_reminder_id}',
|
||||
}),
|
||||
]
|
||||
})
|
||||
self.assertEqual(test_event.create_date, now)
|
||||
|
||||
def test_assert_initial_values(self):
|
||||
""" Ensure base values for tests """
|
||||
test_event = self.test_event
|
||||
|
||||
# event data
|
||||
self.assertEqual(test_event.create_date, self.reference_now)
|
||||
|
||||
# check subscription scheduler
|
||||
after_sub_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'after_sub'), ('interval_unit', '=', 'now')])
|
||||
@@ -82,28 +101,38 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
# check before event scheduler
|
||||
event_prev_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'before_event')])
|
||||
self.assertEqual(len(event_prev_scheduler), 1, 'event: wrong scheduler creation')
|
||||
self.assertEqual(event_prev_scheduler.scheduled_date, event_date_begin + relativedelta(days=-1))
|
||||
self.assertEqual(event_prev_scheduler.scheduled_date, self.event_date_begin + relativedelta(days=-1))
|
||||
self.assertFalse(event_prev_scheduler.mail_done)
|
||||
self.assertEqual(event_prev_scheduler.mail_state, 'scheduled')
|
||||
self.assertEqual(event_prev_scheduler.mail_count_done, 0)
|
||||
# check after event scheduler
|
||||
event_next_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'after_event')])
|
||||
self.assertEqual(len(event_next_scheduler), 1, 'event: wrong scheduler creation')
|
||||
self.assertEqual(event_next_scheduler.scheduled_date, event_date_end + relativedelta(hours=1))
|
||||
self.assertEqual(event_next_scheduler.scheduled_date, self.event_date_end + relativedelta(hours=1))
|
||||
self.assertFalse(event_next_scheduler.mail_done)
|
||||
self.assertEqual(event_next_scheduler.mail_state, 'scheduled')
|
||||
self.assertEqual(event_next_scheduler.mail_count_done, 0)
|
||||
|
||||
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
|
||||
@users('user_eventmanager')
|
||||
def test_event_mail_schedule(self):
|
||||
""" Test mail scheduling for events """
|
||||
# create some registrations
|
||||
with freeze_time(now), self.mock_mail_gateway():
|
||||
test_event = self.test_event.with_env(self.env)
|
||||
now = self.reference_now
|
||||
schedulers = self.env['event.mail'].search([('event_id', '=', test_event.id)])
|
||||
after_sub_scheduler = schedulers.filtered(lambda s: s.interval_type == 'after_sub' and s.interval_unit == 'now')
|
||||
after_sub_scheduler_2 = schedulers.filtered(lambda s: s.interval_type == 'after_sub' and s.interval_unit == 'hours')
|
||||
event_prev_scheduler = schedulers.filtered(lambda s: s.interval_type == 'before_event')
|
||||
event_next_scheduler = schedulers.filtered(lambda s: s.interval_type == 'after_event')
|
||||
|
||||
with self.mock_datetime_and_now(now), self.mock_mail_gateway():
|
||||
reg1 = self.env['event.registration'].create({
|
||||
'create_date': now,
|
||||
'event_id': test_event.id,
|
||||
'name': 'Reg1',
|
||||
'email': 'reg1@example.com',
|
||||
})
|
||||
reg2 = self.env['event.registration'].create({
|
||||
'create_date': now,
|
||||
'event_id': test_event.id,
|
||||
'name': 'Reg2',
|
||||
'email': 'reg2@example.com',
|
||||
@@ -180,9 +209,9 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
self.assertEqual(event_prev_scheduler.mail_state, 'scheduled')
|
||||
|
||||
# simulate cron running before scheduled date -> should not do anything
|
||||
now_start = event_date_begin + relativedelta(hours=-25, microsecond=654321)
|
||||
now_start = self.event_date_begin + relativedelta(hours=-25, microsecond=654321)
|
||||
with freeze_time(now_start), self.mock_mail_gateway():
|
||||
event_cron_id.method_direct_trigger()
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
self.assertFalse(event_prev_scheduler.mail_done)
|
||||
self.assertEqual(event_prev_scheduler.mail_state, 'scheduled')
|
||||
@@ -190,9 +219,9 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
self.assertEqual(len(self._new_mails), 0)
|
||||
|
||||
# execute cron to run schedulers after scheduled date
|
||||
now_start = event_date_begin + relativedelta(hours=-23, microsecond=654321)
|
||||
now_start = self.event_date_begin + relativedelta(hours=-23, microsecond=654321)
|
||||
with freeze_time(now_start), self.mock_mail_gateway():
|
||||
event_cron_id.method_direct_trigger()
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
# check that scheduler is finished
|
||||
self.assertTrue(event_prev_scheduler.mail_done, 'event: reminder scheduler should have run')
|
||||
@@ -211,9 +240,8 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
# NEW REGISTRATION EFFECT ON SCHEDULERS
|
||||
# --------------------------------------------------
|
||||
|
||||
with freeze_time(now_start), self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(now_start), self.mock_mail_gateway():
|
||||
reg3 = self.env['event.registration'].create({
|
||||
'create_date': now_start,
|
||||
'event_id': test_event.id,
|
||||
'name': 'Reg3',
|
||||
'email': 'reg3@example.com',
|
||||
@@ -232,7 +260,7 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
# confirm registration -> should trigger registration schedulers
|
||||
# NOTE: currently all schedulers are based on create_date
|
||||
# meaning several communications may be sent in the time time
|
||||
with freeze_time(now_start + relativedelta(hours=1)), self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(now_start + relativedelta(hours=1)), self.mock_mail_gateway():
|
||||
reg3.action_confirm()
|
||||
|
||||
# verify that subscription scheduler was auto-executed after new registration confirmed
|
||||
@@ -265,9 +293,9 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
self.assertFalse(event_next_scheduler.mail_done)
|
||||
|
||||
# execute event reminder scheduler explicitly after its schedule date
|
||||
new_end = event_date_end + relativedelta(hours=2)
|
||||
with freeze_time(new_end), self.mock_mail_gateway():
|
||||
event_cron_id.method_direct_trigger()
|
||||
new_end = self.event_date_end + relativedelta(hours=2)
|
||||
with self.mock_datetime_and_now(new_end), self.mock_mail_gateway():
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
# check that scheduler is finished
|
||||
self.assertTrue(event_next_scheduler.mail_done, 'event: reminder scheduler should should have run')
|
||||
@@ -284,6 +312,63 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
'email_from': self.user_eventmanager.company_id.email_formatted,
|
||||
})
|
||||
|
||||
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
|
||||
@users('user_eventmanager')
|
||||
def test_event_mail_schedule_on_subscription(self):
|
||||
""" Test emails sent on subscription, notably to avoid bottlenecks """
|
||||
test_event = self.test_event.with_env(self.env)
|
||||
reference_now = self.reference_now
|
||||
|
||||
# remove on subscription, to create hanging registrations
|
||||
schedulers = self.env['event.mail'].search([('event_id', '=', test_event.id)])
|
||||
_sub_scheduler = schedulers.filtered(lambda s: s.interval_type == 'after_sub' and s.interval_unit == 'now')
|
||||
_sub_scheduler.unlink()
|
||||
|
||||
# consider having hanging registrations, still not processed (e.g. adding
|
||||
# a new scheduler after)
|
||||
self.env.invalidate_all()
|
||||
# com 58, event 36
|
||||
with self.assertQueryCount(61), self.mock_datetime_and_now(reference_now), \
|
||||
self.mock_mail_gateway():
|
||||
_existing = self.env['event.registration'].create([
|
||||
{
|
||||
'email': f'existing.attendee.{idx}@test.example.com',
|
||||
'event_id': test_event.id,
|
||||
'name': f'Attendee {idx}',
|
||||
} for idx in range(5)
|
||||
])
|
||||
self.assertEqual(len(self._new_mails), 0)
|
||||
self.assertEqual(self.mail_mail_create_mocked.call_count, 0)
|
||||
|
||||
# add on subscription scheduler, then new registrations ! yay ! check what
|
||||
# happens with old ones
|
||||
test_event.write({'event_mail_ids': [
|
||||
(0, 0, { # right at subscription
|
||||
'interval_unit': 'now',
|
||||
'interval_type': 'after_sub',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{self.template_subscription_id}',
|
||||
}),
|
||||
]})
|
||||
self.env.invalidate_all()
|
||||
# com 148, event 134
|
||||
with self.assertQueryCount(153), \
|
||||
self.mock_datetime_and_now(reference_now + relativedelta(minutes=10)), \
|
||||
self.mock_mail_gateway():
|
||||
_new = self.env['event.registration'].create([
|
||||
{
|
||||
'email': f'new.attendee.{idx}@test.example.com',
|
||||
'event_id': test_event.id,
|
||||
'name': f'New Attendee {idx}',
|
||||
} for idx in range(2)
|
||||
])
|
||||
# self.assertEqual(len(self._new_mails), 2)
|
||||
# self.assertEqual(self.mail_mail_create_mocked.call_count, 2)
|
||||
self.assertEqual(len(self._new_mails), 7,
|
||||
'EventMail: TODO: should be limited to new registrations')
|
||||
self.assertEqual(self.mail_mail_create_mocked.call_count, 7,
|
||||
'EventMail: TODO: should create one mail / new registration')
|
||||
|
||||
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
|
||||
def test_unique_event_mail_ids(self):
|
||||
# create event with default event_mail_ids lines
|
||||
@@ -353,7 +438,7 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
event_date_begin = datetime(2023, 7, 26, 8, 0, 0)
|
||||
event_date_end = datetime(2023, 7, 28, 18, 0, 0)
|
||||
|
||||
with freeze_time(now):
|
||||
with self.mock_datetime_and_now(now):
|
||||
test_event = self.env['event.event'].with_user(self.user_eventmanager).create({
|
||||
'name': 'TestEventMail',
|
||||
'date_begin': event_date_begin,
|
||||
@@ -377,15 +462,13 @@ class TestMailSchedule(EventCase, MockEmail):
|
||||
|
||||
event_prev_scheduler = self.env['event.mail'].search([('event_id', '=', test_event.id), ('interval_type', '=', 'before_event')])
|
||||
|
||||
with freeze_time(now), self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(now), self.mock_mail_gateway():
|
||||
self.env['event.registration'].create({
|
||||
'create_date': now,
|
||||
'event_id': test_event.id,
|
||||
'name': 'Reg1',
|
||||
'email': 'reg1@example.com',
|
||||
})
|
||||
self.env['event.registration'].create({
|
||||
'create_date': now,
|
||||
'event_id': test_event.id,
|
||||
'name': 'Reg2',
|
||||
'email': 'reg2@example.com',
|
||||
|
||||
@@ -7,9 +7,10 @@ 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
|
||||
from odoo.tests import tagged, users
|
||||
|
||||
|
||||
@tagged('event_mail')
|
||||
class TestSMSSchedule(EventCase, SMSCase):
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -226,14 +226,15 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
||||
'is_published': True,
|
||||
}
|
||||
|
||||
cls.test_event = cls.env['event.event'].create({
|
||||
'name': 'Test Event',
|
||||
'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,
|
||||
})
|
||||
with cls.mock_datetime_and_now(cls, cls.reference_now):
|
||||
cls.test_event = cls.env['event.event'].create({
|
||||
'name': 'Test Event',
|
||||
'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')
|
||||
|
||||
@@ -77,9 +77,6 @@ class TestEventEvent(TestEventFullCommon):
|
||||
@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')
|
||||
@@ -93,14 +90,15 @@ class TestEventEvent(TestEventFullCommon):
|
||||
self.assertFalse(ticket_2.sale_available)
|
||||
|
||||
# make 9 registrations (let 1 on ticket)
|
||||
with self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
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,
|
||||
{
|
||||
'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)
|
||||
])
|
||||
@@ -113,27 +111,29 @@ class TestEventEvent(TestEventFullCommon):
|
||||
self.assertEqual(ticket_2.seats_available, 0)
|
||||
|
||||
# prevent registration due to ticket limit
|
||||
with self.assertRaises(exceptions.ValidationError):
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
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,
|
||||
{
|
||||
'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():
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
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,
|
||||
{
|
||||
'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)
|
||||
])
|
||||
@@ -144,14 +144,15 @@ class TestEventEvent(TestEventFullCommon):
|
||||
self.assertEqual(ticket_2.seats_available, 0)
|
||||
|
||||
# prevent registration due to event limit
|
||||
with self.assertRaises(exceptions.ValidationError):
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
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,
|
||||
{
|
||||
'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)
|
||||
])
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
|
||||
from odoo.addons.test_event_full.tests.common import TestWEventCommon
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged('event_mail')
|
||||
class TestTemplateRefModel(TestWEventCommon):
|
||||
|
||||
def test_template_ref_model_constraint(self):
|
||||
|
||||
test_cases = [
|
||||
('mail', 'mail.template', True),
|
||||
('mail', 'sms.template', False),
|
||||
|
||||
@@ -116,50 +116,202 @@ class TestMailTemplate(TestMailTemplateCommon):
|
||||
self.assertEqual(mail.body_html, body_result)
|
||||
self.assertEqual(mail.body, body_result)
|
||||
|
||||
@tagged('mail_template', 'multi_lang')
|
||||
|
||||
@tagged('mail_template', 'multi_lang', 'post_install', '-at_install')
|
||||
class TestMailTemplateLanguages(TestMailTemplateCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
""" Create lang-based records and templates, to test batch and performances
|
||||
with language involved. """
|
||||
super().setUpClass()
|
||||
|
||||
# use test notification layout
|
||||
cls.test_template.write({
|
||||
'email_layout_xmlid': 'mail.test_layout',
|
||||
})
|
||||
|
||||
# double record, one in each lang
|
||||
cls.test_records = cls.test_record + cls.env['mail.test.lang'].create({
|
||||
'email_from': 'ignasse.es@example.com',
|
||||
'lang': 'es_ES',
|
||||
'name': 'Test Record 2',
|
||||
})
|
||||
|
||||
# pure batch, 100 records
|
||||
cls.test_records_batch, test_partners = cls._create_records_for_batch(
|
||||
'mail.test.lang', 100,
|
||||
)
|
||||
test_partners[:50].lang = 'es_ES'
|
||||
|
||||
# have a template with dynamic templates to check impact
|
||||
cls.test_template_wreports = cls.test_template.copy({
|
||||
'email_layout_xmlid': 'mail.test_layout',
|
||||
})
|
||||
cls.test_reports = cls.env['ir.actions.report'].create([
|
||||
{
|
||||
'name': f'Test Report on {cls.test_record._name}',
|
||||
'model': cls.test_record._name,
|
||||
'print_report_name': "f'TestReport for {object.name}'",
|
||||
'report_type': 'qweb-pdf',
|
||||
'report_name': 'test_mail.mail_test_ticket_test_template',
|
||||
}, {
|
||||
'name': f'Test Report 2 on {cls.test_record._name}',
|
||||
'model': cls.test_record._name,
|
||||
'print_report_name': "f'TestReport2 for {object.name}'",
|
||||
'report_type': 'qweb-pdf',
|
||||
'report_name': 'test_mail.mail_test_ticket_test_template_2',
|
||||
}
|
||||
])
|
||||
cls.test_template_wreports.report_template_ids = cls.test_reports
|
||||
|
||||
cls.env.flush_all()
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_send_email(self):
|
||||
mail_id = self.test_template.send_mail(self.test_record.id)
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
""" Test 'send_email' on template on a given record, used notably as
|
||||
contextual action. """
|
||||
self.env.invalidate_all()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(28): # test_mail: 28
|
||||
mail_id = self.test_template.with_env(self.env).send_mail(self.test_record.id)
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
|
||||
self.assertEqual(sorted(mail.attachment_ids.mapped('name')), ['first.txt', 'second.txt'])
|
||||
self.assertEqual(mail.body_html,
|
||||
f'<body><p>EnglishBody for {self.test_record.name}</p> English Layout for Lang Chatter Model</body>')
|
||||
self.assertEqual(mail.email_cc, self.test_template.email_cc)
|
||||
self.assertEqual(mail.email_to, self.test_template.email_to)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id)
|
||||
self.assertEqual(mail.subject, 'EnglishSubject for %s' % self.test_record.name)
|
||||
self.assertEqual(mail.subject, f'EnglishSubject for {self.test_record.name}')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_send_email_nolayout(self):
|
||||
""" Test without layout, just to check impact """
|
||||
self.test_template.email_layout_xmlid = False
|
||||
self.env.invalidate_all()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(21): # test_mail: 21
|
||||
mail_id = self.test_template.with_env(self.env).send_mail(self.test_record.id)
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
|
||||
self.assertEqual(sorted(mail.attachment_ids.mapped('name')), ['first.txt', 'second.txt'])
|
||||
self.assertEqual(mail.body_html,
|
||||
f'<p>EnglishBody for {self.test_record.name}</p>')
|
||||
self.assertEqual(mail.email_cc, self.test_template.email_cc)
|
||||
self.assertEqual(mail.email_to, self.test_template.email_to)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id)
|
||||
self.assertEqual(mail.subject, f'EnglishSubject for {self.test_record.name}')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_send_email_batch(self):
|
||||
""" Test 'send_email' on template in batch """
|
||||
self.env.invalidate_all()
|
||||
mails = self.env['mail.mail'].sudo()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(934): # test_mail: 934
|
||||
template = self.test_template.with_env(self.env)
|
||||
for record in self.test_records_batch:
|
||||
mails += mails.browse(template.send_mail(record.id))
|
||||
|
||||
self.assertEqual(len(mails), 100)
|
||||
for idx, (mail, record) in enumerate(zip(mails, self.test_records_batch)):
|
||||
self.assertEqual(sorted(mail.attachment_ids.mapped('name')), ['first.txt', 'second.txt'])
|
||||
self.assertEqual(mail.email_cc, self.test_template.email_cc)
|
||||
self.assertEqual(mail.email_to, self.test_template.email_to)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id)
|
||||
if idx >= 50:
|
||||
self.assertEqual(mail.subject, f'EnglishSubject for {record.name}')
|
||||
else:
|
||||
self.assertEqual(mail.subject, f'SpanishSubject for {record.name}')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_send_email_wreport(self):
|
||||
""" Test 'send_email' on template on a given record, used notably as
|
||||
contextual action, with dynamic reports involved """
|
||||
self.env.invalidate_all()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(107): # test_mail: 106
|
||||
mail_id = self.test_template_wreports.with_env(self.env).send_mail(self.test_record.id)
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
|
||||
self.assertEqual(
|
||||
sorted(mail.attachment_ids.mapped('name')),
|
||||
[f'TestReport for {self.test_record.name}.html', f'TestReport2 for {self.test_record.name}.html', 'first.txt', 'second.txt']
|
||||
)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id)
|
||||
self.assertEqual(mail.subject, f'EnglishSubject for {self.test_record.name}')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_send_email_wreport_batch(self):
|
||||
""" Test 'send_email' on template in batch with dynamic reports """
|
||||
self.env.invalidate_all()
|
||||
mails = self.env['mail.mail'].sudo()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(1645): # test_mail: 1645
|
||||
template = self.test_template_wreports.with_env(self.env)
|
||||
for record in self.test_records_batch:
|
||||
mails += mails.browse(template.send_mail(record.id))
|
||||
|
||||
self.assertEqual(len(mails), 100)
|
||||
for idx, (mail, record) in enumerate(zip(mails, self.test_records_batch)):
|
||||
self.assertEqual(
|
||||
sorted(mail.attachment_ids.mapped('name')),
|
||||
[f'TestReport for {record.name}.html', f'TestReport2 for {record.name}.html', 'first.txt', 'second.txt']
|
||||
)
|
||||
self.assertEqual(mail.email_cc, self.test_template.email_cc)
|
||||
self.assertEqual(mail.email_to, self.test_template.email_to)
|
||||
self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id)
|
||||
if idx >= 50:
|
||||
self.assertEqual(mail.subject, f'EnglishSubject for {record.name}')
|
||||
self.assertEqual(mail.body_html,
|
||||
f'<body><p>EnglishBody for {record.name}</p> English Layout for Lang Chatter Model</body>')
|
||||
else:
|
||||
self.assertEqual(mail.subject, f'SpanishSubject for {record.name}')
|
||||
self.assertEqual(mail.body_html,
|
||||
f'<body><p>SpanishBody for {record.name}</p> Spanish Layout para Spanish Model Description</body>')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_translation_lang(self):
|
||||
""" Test template rendering using lang defined directly on the record """
|
||||
test_record = self.test_record.with_env(self.env)
|
||||
test_record.write({
|
||||
'lang': 'es_ES',
|
||||
})
|
||||
test_template = self.test_template.with_env(self.env)
|
||||
test_template.write({
|
||||
'email_layout_xmlid': 'mail.test_layout',
|
||||
})
|
||||
|
||||
mail_id = test_template.send_mail(test_record.id)
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
self.assertEqual(mail.body_html,
|
||||
'<body><p>SpanishBody for %s</p> Spanish Layout para Spanish Model Description</body>' % self.test_record.name)
|
||||
self.assertEqual(mail.subject, 'SpanishSubject for %s' % self.test_record.name)
|
||||
f'<body><p>SpanishBody for {self.test_record.name}</p> Spanish Layout para Spanish Model Description</body>')
|
||||
self.assertEqual(mail.subject, f'SpanishSubject for {self.test_record.name}')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||
def test_template_translation_partner_lang(self):
|
||||
test_record = self.env['mail.test.lang'].browse(self.test_record.ids)
|
||||
customer = self.env['res.partner'].create({
|
||||
'email': 'robert.carlos@test.example.com',
|
||||
'lang': 'es_ES',
|
||||
'name': 'Roberto Carlos',
|
||||
})
|
||||
test_record.write({
|
||||
'customer_id': customer.id,
|
||||
})
|
||||
test_template = self.env['mail.template'].browse(self.test_template.ids)
|
||||
""" Test template rendering using lang defined on a sub-record aka
|
||||
'partner_id.lang' """
|
||||
test_records = self.env['mail.test.lang'].browse(self.test_records.ids)
|
||||
customers = self.env['res.partner'].create([
|
||||
{
|
||||
'email': 'roberto.carlos@test.example.com',
|
||||
'lang': 'es_ES',
|
||||
'name': 'Roberto Carlos',
|
||||
}, {
|
||||
'email': 'rob.charly@test.example.com',
|
||||
'lang': 'en_US',
|
||||
'name': 'Rob Charly',
|
||||
}
|
||||
])
|
||||
test_records[0].write({'customer_id': customers[0].id})
|
||||
test_records[1].write({'customer_id': customers[1].id})
|
||||
|
||||
mail_id = test_template.send_mail(test_record.id, email_layout_xmlid='mail.test_layout')
|
||||
mail = self.env['mail.mail'].sudo().browse(mail_id)
|
||||
self.assertEqual(mail.body_html,
|
||||
'<body><p>SpanishBody for %s</p> Spanish Layout para Spanish Model Description</body>' % self.test_record.name)
|
||||
self.assertEqual(mail.subject, 'SpanishSubject for %s' % self.test_record.name)
|
||||
self.env.invalidate_all()
|
||||
mails = self.env['mail.mail'].sudo()
|
||||
with self.with_user(self.user_employee.login), self.assertQueryCount(52):
|
||||
template = self.test_template.with_env(self.env)
|
||||
for record in self.test_records:
|
||||
mails += mails.browse(
|
||||
template.send_mail(record.id, email_layout_xmlid='mail.test_layout')
|
||||
)
|
||||
|
||||
self.assertEqual(mails[0].body_html,
|
||||
f'<body><p>SpanishBody for {test_records[0].name}</p> Spanish Layout para Spanish Model Description</body>')
|
||||
self.assertEqual(mails[0].subject, f'SpanishSubject for {test_records[0].name}')
|
||||
self.assertEqual(mails[1].body_html,
|
||||
f'<body><p>EnglishBody for {test_records[1].name}</p> English Layout for Lang Chatter Model</body>')
|
||||
self.assertEqual(mails[1].subject, f'EnglishSubject for {test_records[1].name}')
|
||||
|
||||
@@ -286,11 +286,11 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
# voip module read activity_type during create leading to one less query in enterprise on action_feedback
|
||||
_category = activity.activity_type_id.category
|
||||
|
||||
with self.assertQueryCount(admin=13, employee=13):
|
||||
with self.assertQueryCount(admin=12, employee=12):
|
||||
activity.action_feedback(feedback='Zizisse Done !')
|
||||
|
||||
@warmup
|
||||
def test_adv_activity_mixin_batched(self):
|
||||
def test_activity_mixin_batched(self):
|
||||
records = self.env['mail.test.activity'].create([{'name': 'Test'}] * 10)
|
||||
MailActivity = self.env['mail.activity'].with_context({
|
||||
'default_res_model': 'mail.test.activity',
|
||||
@@ -304,7 +304,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
} for record in records])
|
||||
|
||||
self.env.invalidate_all()
|
||||
with self.assertQueryCount(3):
|
||||
with self.assertQueryCount(2):
|
||||
records.mapped('activity_date_deadline')
|
||||
|
||||
@users('admin', 'employee')
|
||||
@@ -321,7 +321,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
|
||||
record.write({'name': 'Dupe write'})
|
||||
|
||||
with self.assertQueryCount(admin=14, employee=14):
|
||||
with self.assertQueryCount(admin=13, employee=13):
|
||||
record.action_close('Dupe feedback')
|
||||
|
||||
self.assertEqual(record.activity_ids, self.env['mail.activity'])
|
||||
@@ -347,7 +347,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
|
||||
record.write({'name': 'Dupe write'})
|
||||
|
||||
with self.assertQueryCount(admin=17, employee=17): # com+tm 16/16
|
||||
with self.assertQueryCount(admin=15, employee=15): # com+tm 14/14
|
||||
record.action_close('Dupe feedback', attachment_ids=attachments.ids)
|
||||
|
||||
# notifications
|
||||
@@ -373,7 +373,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
'partner_ids': [(4, customer_id)],
|
||||
})
|
||||
|
||||
with self.assertQueryCount(admin=39, employee=39): # com 35/35
|
||||
with self.assertQueryCount(admin=39, employee=39):
|
||||
composer._action_send_mail()
|
||||
|
||||
@users('admin', 'employee')
|
||||
@@ -394,7 +394,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
'partner_ids': [(4, customer.id)],
|
||||
})
|
||||
|
||||
with self.assertQueryCount(admin=40, employee=40): # com 35/35
|
||||
with self.assertQueryCount(admin=40, employee=40):
|
||||
composer._action_send_mail()
|
||||
|
||||
@users('admin', 'employee')
|
||||
@@ -418,7 +418,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
composer_form.attachment_ids.add(attachment)
|
||||
composer = composer_form.save()
|
||||
|
||||
with self.assertQueryCount(admin=55, employee=55): # tm+com 53/53
|
||||
with self.assertQueryCount(admin=55, employee=55): # tm+com 54/54
|
||||
composer._action_send_mail()
|
||||
|
||||
# notifications
|
||||
@@ -472,7 +472,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
test_record, test_template = self._create_test_records()
|
||||
test_template.write({'attachment_ids': [(5, 0)]})
|
||||
|
||||
with self.assertQueryCount(admin=27, employee=27): # tm 15/15 / com 25/25
|
||||
with self.assertQueryCount(admin=27, employee=27): # tm 16/16 / com 26/26
|
||||
composer = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': test_record._name,
|
||||
@@ -496,7 +496,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
def test_mail_composer_w_template_attachments(self):
|
||||
test_record, test_template = self._create_test_records()
|
||||
|
||||
with self.assertQueryCount(admin=28, employee=28): # tm 16/16 / com 26/26
|
||||
with self.assertQueryCount(admin=28, employee=28): # tm 17/17 / com 27/27
|
||||
composer = self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
'default_model': test_record._name,
|
||||
@@ -525,7 +525,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
test_template.write({'attachment_ids': [(5, 0)]})
|
||||
|
||||
customer = self.env['res.partner'].browse(self.customer.ids)
|
||||
with self.assertQueryCount(admin=34, employee=34): # tm 22/22 / com 32/32
|
||||
with self.assertQueryCount(admin=34, employee=34): # tm 23/23 / com 33/33
|
||||
composer_form = Form(
|
||||
self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
@@ -555,7 +555,7 @@ class TestBaseAPIPerformance(BaseMailPerformance):
|
||||
test_record, test_template = self._create_test_records()
|
||||
|
||||
customer = self.env['res.partner'].browse(self.customer.ids)
|
||||
with self.assertQueryCount(admin=34, employee=34): # tm 22/22 / com 32/32
|
||||
with self.assertQueryCount(admin=34, employee=34): # tm 23/23 / com 32/32
|
||||
composer_form = Form(
|
||||
self.env['mail.compose.message'].with_context({
|
||||
'default_composition_mode': 'comment',
|
||||
@@ -878,7 +878,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
record = self.container.with_user(self.env.user)
|
||||
|
||||
# about 20 (19?) queries per additional customer group
|
||||
with self.assertQueryCount(admin=61, employee=60): # com 55/54
|
||||
with self.assertQueryCount(admin=60, employee=59):
|
||||
record.message_post(
|
||||
body=Markup('<p>Test Post Performances</p>'),
|
||||
message_type='comment',
|
||||
@@ -896,7 +896,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
template = self.env.ref('test_mail.mail_test_container_tpl')
|
||||
|
||||
# about 20 (19 ?) queries per additional customer group
|
||||
with self.assertQueryCount(admin=70, employee=69): # com 62/61
|
||||
with self.assertQueryCount(admin=69, employee=68):
|
||||
record.message_post_with_source(
|
||||
template,
|
||||
message_type='comment',
|
||||
@@ -920,7 +920,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
'default_template_id': test_template.id,
|
||||
}).create({})
|
||||
|
||||
with self.assertQueryCount(admin=151, employee=151): # com 141/141
|
||||
with self.assertQueryCount(admin=151, employee=151):
|
||||
messages_as_sudo = test_records.message_post_with_source(
|
||||
'test_mail.mail_template_simple_test',
|
||||
render_values={'partner': self.user_test.partner_id},
|
||||
@@ -1006,7 +1006,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
customer_id = self.customer.id
|
||||
user_id = self.user_portal.id
|
||||
|
||||
with self.assertQueryCount(admin=102, employee=102):
|
||||
with self.assertQueryCount(admin=101, employee=101):
|
||||
rec = self.env['mail.test.ticket'].create({
|
||||
'name': 'Test',
|
||||
'container_id': container_id,
|
||||
@@ -1035,7 +1035,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
rec1 = rec.with_context(active_test=False) # to see inactive records
|
||||
self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
|
||||
self.assertEqual(len(rec1.message_ids), 1)
|
||||
with self.assertQueryCount(admin=63, employee=63):
|
||||
with self.assertQueryCount(admin=62, employee=62):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'container_id': self.container.id,
|
||||
@@ -1072,7 +1072,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
|
||||
rec1 = rec.with_context(active_test=False) # to see inactive records
|
||||
self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
|
||||
|
||||
with self.assertQueryCount(admin=70, employee=70):
|
||||
with self.assertQueryCount(admin=69, employee=69):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'container_id': container_id,
|
||||
@@ -1264,7 +1264,7 @@ class TestMailFormattersPerformance(BaseMailPerformance):
|
||||
"""
|
||||
messages_all = self.messages_all.with_env(self.env)
|
||||
|
||||
with self.assertQueryCount(employee=26): # test_mail: 25
|
||||
with self.assertQueryCount(employee=26):
|
||||
res = messages_all.message_format()
|
||||
|
||||
self.assertEqual(len(res), 2*2)
|
||||
@@ -1277,7 +1277,7 @@ class TestMailFormattersPerformance(BaseMailPerformance):
|
||||
def test_message_format_single(self):
|
||||
message = self.messages_all[0].with_env(self.env)
|
||||
|
||||
with self.assertQueryCount(employee=23): # test_mail: 22
|
||||
with self.assertQueryCount(employee=23):
|
||||
res = message.message_format()
|
||||
|
||||
self.assertEqual(len(res), 1)
|
||||
@@ -1382,7 +1382,7 @@ class TestPerformance(BaseMailPerformance):
|
||||
attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals)
|
||||
# enable_logging = self.cr._enable_logging() if self.warm else nullcontext()
|
||||
# with self.assertQueryCount(employee=63), enable_logging:
|
||||
with self.assertQueryCount(employee=69): # com 63
|
||||
with self.assertQueryCount(employee=68):
|
||||
record_container.with_context({}).message_post(
|
||||
body=Markup('<p>Test body <img src="cid:cid1"> <img src="cid:cid2"></p>'),
|
||||
subject='Test Subject',
|
||||
|
||||
@@ -91,7 +91,7 @@ class TestMailPerformance(FullBaseMailPerformance):
|
||||
record_ticket = self.env['mail.test.ticket.mc'].browse(self.record_ticket.ids)
|
||||
attachments = self.env['ir.attachment'].create(self.test_attachments_vals)
|
||||
|
||||
with self.assertQueryCount(employee=101): # test_mail_full: 95
|
||||
with self.assertQueryCount(employee=99): # test_mail_full: 95
|
||||
new_message = record_ticket.message_post(
|
||||
attachment_ids=attachments.ids,
|
||||
body=Markup('<p>Test Content</p>'),
|
||||
|
||||
Reference in New Issue
Block a user