Odoo18-Base/addons/test_mail_full/tests/test_mail_performance.py

320 lines
14 KiB
Python
Raw Permalink Normal View History

2025-01-06 10:57:38 +07:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, timedelta
from markupsafe import Markup
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.test_mail.tests.test_performance import BaseMailPerformance
from odoo.tests.common import users, warmup
from odoo.tests import tagged
from odoo.tools import mute_logger
@tagged('mail_performance', 'post_install', '-at_install')
class FullBaseMailPerformance(BaseMailPerformance):
@classmethod
def setUpClass(cls):
super().setUpClass()
# users / followers
cls.user_emp_email = mail_new_test_user(
cls.env,
company_id=cls.user_admin.company_id.id,
company_ids=[(4, cls.user_admin.company_id.id)],
email='user.emp.email@test.example.com',
login='user_emp_email',
groups='base.group_user,base.group_partner_manager',
name='Emmanuel Email',
notification_type='email',
signature='--\nEmmanuel',
)
cls.user_portal = mail_new_test_user(
cls.env,
company_id=cls.user_admin.company_id.id,
company_ids=[(4, cls.user_admin.company_id.id)],
email='user.portal@test.example.com',
login='user_portal',
groups='base.group_portal',
name='Paul Portal',
)
cls.customers = cls.env['res.partner'].create([
{
'country_id': cls.env.ref('base.be').id,
'email': f'customer.full.test.{idx}@example.com',
'name': f'Test Full Customer {idx}',
'mobile': f'045600000{idx}',
'phone': f'045611111{idx}',
} for idx in range(5)
])
cls.test_users = cls.user_employee + cls.user_test + cls.user_test_email + cls.user_emp_email + cls.user_portal
# records
cls.record_containers = cls.env['mail.test.container.mc'].create([
{
'alias_name': 'test-alias-0',
'customer_id': cls.customers[0].id,
'name': 'Test Container 1',
},
{
'alias_name': 'test-alias-1',
'customer_id': cls.customers[1].id,
'name': 'Test Container 2',
},
])
cls.record_ticket = cls.env['mail.test.ticket.mc'].create({
'email_from': 'email.from@test.example.com',
'container_id': cls.record_containers[0].id,
'customer_id': False,
'name': 'Test Ticket',
'user_id': cls.user_emp_email.id,
})
cls.record_ticket.message_subscribe(cls.customers.ids + cls.user_admin.partner_id.ids + cls.user_portal.partner_id.ids)
@tagged('mail_performance', 'post_install', '-at_install')
class TestMailPerformance(FullBaseMailPerformance):
def test_assert_initial_values(self):
""" Simply ensure some values through all tests """
record_ticket = self.env['mail.test.ticket.mc'].browse(self.record_ticket.ids)
self.assertEqual(record_ticket.message_partner_ids,
self.user_emp_email.partner_id + self.user_admin.partner_id + self.customers + self.user_portal.partner_id)
self.assertEqual(len(record_ticket.message_ids), 1)
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('employee')
@warmup
def test_message_post_w_followers(self):
""" Aims to cover as much features of message_post as possible """
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=99): # test_mail_full: 98
new_message = record_ticket.message_post(
attachment_ids=attachments.ids,
body=Markup('<p>Test Content</p>'),
message_type='comment',
subject='Test Subject',
subtype_xmlid='mail.mt_comment',
)
self.assertEqual(
new_message.notified_partner_ids,
self.user_emp_email.partner_id + self.user_admin.partner_id + self.customers + self.user_portal.partner_id
)
@tagged('mail_performance', 'post_install', '-at_install')
class TestPortalFormatPerformance(FullBaseMailPerformance):
"""Test performance of `portal_message_format` with multiple messages
with multiple attachments, with ratings.
Those messages might not make sense functionally but they are crafted to
cover as much of the code as possible in regard to number of queries.
Setup :
* 5 records (self.containers -> 5 mail.test.rating records, with
a different customer_id each)
* 2 messages / record
* 2 attachments / message
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
# rating-enabled test records
cls.record_ratings = cls.env['mail.test.rating'].create([
{
'customer_id': cls.customers[idx].id,
'name': f'TestRating_{idx}',
'user_id': cls.test_users[idx].id,
}
for idx in range(5)
])
# messages and ratings
user_id_field = cls.env['ir.model.fields']._get(cls.record_ratings._name, 'user_id')
comment_subtype_id = cls.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
cls.messages_all = cls.env['mail.message'].sudo().create([
{
'attachment_ids': [
(0, 0, {
'datas': 'data',
'name': f'Test file {att_idx}',
'res_id': record.id,
'res_model': record._name,
})
for att_idx in range(2)
],
'author_id': record.customer_id.id,
'body': f'<p>Test {msg_idx}</p>',
'date': datetime(2023, 5, 15, 10, 30, 5),
'email_from': record.customer_id.email_formatted,
'link_preview_ids': [
(0, 0, {
'source_url': 'https://www.odoo.com',
}), (0, 0, {
'source_url': 'https://www.example.com',
}),
],
'notification_ids': [
(0, 0, {
'is_read': False,
'notification_type': 'inbox',
'res_partner_id': cls.customers[(msg_idx * 2)].id,
}),
(0, 0, {
'is_read': True,
'notification_type': 'email',
'notification_status': 'sent',
'res_partner_id': cls.customers[(msg_idx * 2) + 1].id,
}),
],
'message_type': 'comment',
'model': record._name,
'partner_ids': [
(4, cls.customers[(msg_idx * 2)].id),
(4, cls.customers[record_idx].id),
],
'reaction_ids': [
(0, 0, {
'content': 'https://www.odoo.com',
'partner_id': cls.customers[(msg_idx * 2) + 1].id
}), (0, 0, {
'content': 'https://www.example.com',
'partner_id': cls.customers[record_idx].id
}),
],
'res_id': record.id,
'subject': f'Test Rating {msg_idx}',
'subtype_id': comment_subtype_id,
'starred_partner_ids': [
(4, cls.customers[(msg_idx * 2)].id),
(4, cls.customers[(msg_idx * 2) + 1].id),
],
'tracking_value_ids': [
(0, 0, {
'field_id': user_id_field.id,
'new_value_char': 'new 1',
'new_value_integer': record.user_id.id,
'old_value_char': 'old 1',
'old_value_integer': cls.user_admin.id,
}),
]
}
for msg_idx in range(2)
for record_idx, record in enumerate(cls.record_ratings)
])
cls.messages_records = [cls.env[message.model].browse(message.res_id) for message in cls.messages_all]
# ratings values related to rating-enabled records
cls.ratings_all = cls.env['rating.rating'].sudo().create([
{
'consumed': True,
'message_id': message.id,
'partner_id': record.customer_id.id,
'publisher_comment': 'Comment',
'publisher_id': cls.user_admin.partner_id.id,
'publisher_datetime': datetime(2023, 5, 15, 10, 30, 5) - timedelta(days=2),
'rated_partner_id': record.user_id.partner_id.id,
'rating': 4,
'res_id': message.res_id,
'res_model_id': cls.env['ir.model']._get_id(message.model),
}
for rating_idx in range(2)
for message, record in zip(cls.messages_all, cls.messages_records)
])
def test_assert_initial_values(self):
self.assertEqual(len(self.messages_all), 5 * 2)
self.assertEqual(len(self.ratings_all), len(self.messages_all) * 2)
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('employee')
@warmup
def test_portal_message_format_norating(self):
messages_all = self.messages_all.with_user(self.env.user)
with self.assertQueryCount(employee=13):
# res = messages_all.portal_message_format(options=None)
res = messages_all.portal_message_format(options={'rating_include': False})
comment_subtype = self.env.ref('mail.mt_comment')
self.assertEqual(len(res), len(messages_all))
for format_res, message, record in zip(res, messages_all, self.messages_records):
self.assertEqual(len(format_res['attachment_ids']), 2)
self.assertEqual(
format_res['attachment_ids'],
[
{
'access_token': message.attachment_ids[0].access_token,
'checksum': message.attachment_ids[0].checksum,
'filename': 'Test file 1',
'id': message.attachment_ids[0].id,
'mimetype': 'application/octet-stream',
'name': 'Test file 1',
'res_id': record.id,
'res_model': record._name,
}, {
'access_token': message.attachment_ids[1].access_token,
'checksum': message.attachment_ids[1].checksum,
'filename': 'Test file 0',
'id': message.attachment_ids[1].id,
'mimetype': 'application/octet-stream',
'name': 'Test file 0',
'res_id': record.id,
'res_model': record._name,
}
]
)
self.assertEqual(format_res["author"]["id"], record.customer_id.id)
self.assertEqual(format_res["author"]["name"], record.customer_id.display_name)
self.assertEqual(format_res['author_avatar_url'], f'/web/image/mail.message/{message.id}/author_avatar/50x50')
self.assertEqual(format_res['date'], datetime(2023, 5, 15, 10, 30, 5))
self.assertEqual(' '.join(format_res['published_date_str'].split()), 'May 15, 2023, 10:30:05 AM')
self.assertEqual(format_res['id'], message.id)
self.assertFalse(format_res['is_internal'])
self.assertFalse(format_res['is_message_subtype_note'])
self.assertEqual(format_res['subtype_id'], (comment_subtype.id, comment_subtype.name))
# should not be in, not asked
self.assertNotIn('rating', format_res)
self.assertNotIn('rating_stats', format_res)
self.assertNotIn('rating_value', format_res)
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('employee')
@warmup
def test_portal_message_format_rating(self):
messages_all = self.messages_all.with_user(self.env.user)
with self.assertQueryCount(employee=27):
res = messages_all.portal_message_format(options={'rating_include': True})
self.assertEqual(len(res), len(messages_all))
for format_res, _message, _record in zip(res, messages_all, self.messages_records):
self.assertEqual(format_res['rating']['publisher_avatar'], f'/web/image/res.partner/{self.partner_admin.id}/avatar_128/50x50')
self.assertEqual(format_res['rating']['publisher_comment'], 'Comment')
self.assertEqual(format_res['rating']['publisher_id'], self.partner_admin.id)
self.assertEqual(" ".join(format_res['rating']['publisher_datetime'].split()), 'May 13, 2023, 10:30:05 AM')
self.assertEqual(format_res['rating']['publisher_name'], self.partner_admin.display_name)
self.assertDictEqual(
format_res['rating_stats'],
{'avg': 4.0, 'total': 4, 'percent': {1: 0.0, 2: 0.0, 3: 0.0, 4: 100.0, 5: 0.0}}
)
self.assertEqual(format_res['rating_value'], 4)
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('employee')
@warmup
def test_portal_message_format_monorecord(self):
message = self.messages_all[0].with_user(self.env.user)
with self.assertQueryCount(employee=19):
res = message.portal_message_format(options={'rating_include': True})
self.assertEqual(len(res), 1)