[MERGE] test_mail: update test models and reorder addon

PURPOSE

Have a cleaner test_mail addons

SPECIFICATIONS

Keep only mail-related tests, move odoobot in test mail full, send "update
notification" tests in mail (specific to mail). Merge some test files to
lessen number of files, perform light file renaming.

Split test mail models file to prepare some cleaning in those models and tests.

Keep only mail-related tests, move odoobot in test mail full, send "update
notification" tests in mail (specific to mail). Merge some test files to
lessen number of files, perform light file renaming.

Split test mail models file to prepare some cleaning in those models and tests.

LINKS

Prepares Task ID 2238597 (clean notification models)
Prepares Task ID 2083854 (improve mass mailing technical flows)
PR #49891

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2020-04-22 11:24:38 +02:00
committed by GitHub
23 changed files with 427 additions and 414 deletions
+40 -38
View File
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
@@ -6,53 +7,66 @@ from odoo import api, fields, models
from odoo.tools.translate import _
class Notification(models.Model):
class MailNotification(models.Model):
_name = 'mail.notification'
_table = 'mail_message_res_partner_needaction_rel'
_rec_name = 'res_partner_id'
_log_access = False
_description = 'Message Notifications'
mail_message_id = fields.Many2one(
'mail.message', 'Message', index=True, ondelete='cascade', required=True)
res_partner_id = fields.Many2one(
'res.partner', 'Needaction Recipient', index=True, ondelete='cascade', required=False)
is_read = fields.Boolean('Is Read', index=True)
# origin
mail_message_id = fields.Many2one('mail.message', 'Message', index=True, ondelete='cascade', required=True)
mail_id = fields.Many2one('mail.mail', 'Mail', index=True, help='Optional mail_mail ID. Used mainly to optimize searches.')
# recipient
res_partner_id = fields.Many2one('res.partner', 'Recipient', index=True, ondelete='cascade')
# status
notification_type = fields.Selection([
('inbox', 'Inbox'), ('email', 'Email')], string='Notification Type',
default='inbox', index=True, required=True)
('inbox', 'Inbox'), ('email', 'Email')
], string='Notification Type', default='inbox', index=True, required=True)
notification_status = fields.Selection([
('ready', 'Ready to Send'),
('sent', 'Sent'),
('bounce', 'Bounced'),
('exception', 'Exception'),
('canceled', 'Canceled')], 'Email Status',
default='ready', index=True)
mail_id = fields.Many2one('mail.mail', 'Mail', index=True)
# it would be technically possible to find notification from mail without adding a mail_id field on notification,
# comparing partner_ids and message_ids, but this will involve to search notifications one by one since we want to match
# bot value. Working with set inclusion, we could have a notif matching message from mail 1 and partner from mail 2, we dont want that.
# The solution would be to iterate over mail or to filter mail after search,... or add a mail_id field on notification to KISS
failure_type = fields.Selection(selection=[
("SMTP", "Connection failed (outgoing mail server problem)"),
("RECIPIENT", "Invalid email address"),
("BOUNCE", "Email address rejected by destination"),
("UNKNOWN", "Unknown error"),
], string='Failure type')
failure_reason = fields.Text('Failure reason', copy=False)
('canceled', 'Canceled')
], string='Status', default='ready', index=True)
is_read = fields.Boolean('Is Read', index=True)
read_date = fields.Datetime('Read Date', copy=False)
failure_type = fields.Selection(selection=[
("SMTP", "Connection failed (outgoing mail server problem)"),
("RECIPIENT", "Invalid email address"),
("BOUNCE", "Email address rejected by destination"),
("UNKNOWN", "Unknown error"),
], string='Failure type')
failure_reason = fields.Text('Failure reason', copy=False)
_sql_constraints = [
# email notification;: partner is required
('notification_partner_required',
"CHECK(notification_type NOT IN ('email', 'inbox') OR res_partner_id IS NOT NULL)",
'Customer is required for inbox / email notification'),
"CHECK(notification_type NOT IN ('email', 'inbox') OR res_partner_id IS NOT NULL)",
'Customer is required for inbox / email notification'),
]
def init(self):
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_res_partner_id_is_read_notification_status_mail_message_id',))
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s',
('mail_notification_res_partner_id_is_read_notification_status_mail_message_id',))
if not self._cr.fetchone():
self._cr.execute('CREATE INDEX mail_notification_res_partner_id_is_read_notification_status_mail_message_id ON mail_message_res_partner_needaction_rel (res_partner_id, is_read, notification_status, mail_message_id)')
self._cr.execute("""
CREATE INDEX mail_notification_res_partner_id_is_read_notification_status_mail_message_id
ON mail_message_res_partner_needaction_rel (res_partner_id, is_read, notification_status, mail_message_id)
""")
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('is_read'):
vals['read_date'] = fields.Datetime.now()
return super(MailNotification, self).create(vals_list)
def write(self, vals):
if vals.get('is_read'):
vals['read_date'] = fields.Datetime.now()
return super(MailNotification, self).write(vals)
def format_failure_reason(self):
self.ensure_one()
@@ -61,18 +75,6 @@ class Notification(models.Model):
else:
return _("Unknown error") + ": %s" % (self.failure_reason or '')
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get('is_read'):
vals['read_date'] = fields.Datetime.now()
return super(Notification, self).create(vals_list)
def write(self, vals):
if vals.get('is_read'):
vals['read_date'] = fields.Datetime.now()
return super(Notification, self).write(vals)
@api.model
def _gc_notifications(self, max_age_days=180):
domain = [
+1
View File
@@ -2,3 +2,4 @@
from . import common
from . import test_res_partner
from . import test_update_notification
+3 -3
View File
@@ -17,7 +17,7 @@ from odoo.addons.base.models.ir_mail_server import IrMailServer, MailDeliveryExc
from odoo.addons.bus.models.bus import ImBus, json_dump
from odoo.addons.mail.models.mail_mail import MailMail
from odoo.addons.mail.models.mail_message import Message
from odoo.addons.mail.models.mail_notification import Notification
from odoo.addons.mail.models.mail_notification import MailNotification
from odoo.tests import common, new_test_user
from odoo.tools import formataddr, pycompat
@@ -284,7 +284,7 @@ class MailCase(MockEmail):
@contextmanager
def mock_mail_app(self):
message_create_origin = Message.create
notification_create_origin = Notification.create
notification_create_origin = MailNotification.create
self._init_mock_mail()
def _mail_message_create(model, *args, **kwargs):
@@ -298,7 +298,7 @@ class MailCase(MockEmail):
return res
with patch.object(Message, 'create', autospec=True, wraps=Message, side_effect=_mail_message_create) as _mail_message_create_mock, \
patch.object(Notification, 'create', autospec=True, wraps=Notification, side_effect=_mail_notification_create) as _mail_notification_create_mock:
patch.object(MailNotification, 'create', autospec=True, wraps=MailNotification, side_effect=_mail_notification_create) as _mail_notification_create_mock:
yield
def _init_mock_mail(self):
+3 -3
View File
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.tools.translate import _
from odoo import fields, models
class Notification(models.Model):
class MailNotification(models.Model):
_inherit = 'mail.notification'
notification_type = fields.Selection(selection_add=[
+13 -13
View File
@@ -9,26 +9,26 @@
<field name="internal" eval="False"/>
</record>
<record id="st_mail_test_full_umbrella_upd" model="mail.message.subtype">
<field name="name">Umbrella Changed Subtype</field>
<field name="description">Umbrella Changed</field>
<field name="res_model">mail.test.full</field>
<record id="st_mail_test_ticket_container_upd" model="mail.message.subtype">
<field name="name">Container Changed Subtype</field>
<field name="description">Container Changed</field>
<field name="res_model">mail.test.ticket</field>
<field name="default" eval="True"/>
<field name="internal" eval="False"/>
</record>
<record id="st_mail_test_default" model="mail.message.subtype">
<field name="name">Umbrella Default Subtype</field>
<field name="res_model">mail.test</field>
<record id="st_mail_test_container_default" model="mail.message.subtype">
<field name="name">Container Default Subtype</field>
<field name="res_model">mail.test.container</field>
<field name="default" eval="True"/>
<field name="internal" eval="False"/>
</record>
<!-- when subscribing to mail.test umbrella, delegate to mail.test.full child -->
<record id="st_mail_test_child_full" model="mail.message.subtype">
<field name="name">Umbrella Child Full Subtype</field>
<field name="res_model">mail.test</field>
<field name="parent_id" ref="test_mail.st_mail_test_full_umbrella_upd"/>
<field name="relation_field">umbrella_id</field>
<!-- when subscribing to mail.test.container, delegate to mail.test.ticket child -->
<record id="st_mail_test_container_child_full" model="mail.message.subtype">
<field name="name">Container Child Full Subtype</field>
<field name="res_model">mail.test.container</field>
<field name="parent_id" ref="test_mail.st_mail_test_ticket_container_upd"/>
<field name="relation_field">container_id</field>
<field name="default" eval="False"/>
<field name="internal" eval="False"/>
</record>
+5 -5
View File
@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mail_test_full_tracking_tpl" model="mail.template">
<record id="mail_test_ticket_tracking_tpl" model="mail.template">
<field name="name">Mail Test Full: Tracking Template</field>
<field name="subject">Test Template</field>
<field name="partner_to">${object.customer_id.id | safe}</field>
<field name="body_html" type="xml"><p>Hello ${object.name}</p></field>
<field name="model_id" ref="test_mail.model_mail_test_full"/>
<field name="model_id" ref="test_mail.model_mail_test_ticket"/>
<field name="auto_delete" eval="True"/>
</record>
<record id="mail_test_tpl" model="mail.template">
<record id="mail_test_container_tpl" model="mail.template">
<field name="name">Mail Test: Template</field>
<field name="subject">Post on ${object.name}</field>
<field name="partner_to">${object.customer_id.id}</field>
<field name="body_html" type="xml"><p>Adding stuff on ${object.name}</p></field>
<field name="model_id" ref="test_mail.model_mail_test"/>
<field name="model_id" ref="test_mail.model_mail_test_container"/>
<field name="auto_delete" eval="True"/>
</record>
<template id="mail_test_full_tracking_view">
<template id="mail_test_ticket_tracking_view">
<p><span t-esc="object.name"/> datetime has been updated to <span t-esc="object.datetime"/></p>
</template>
</odoo>
+3 -1
View File
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
from . import test_mail_models
from . import test_mail_models
from . import test_mail_corner_case_models
from . import test_mail_thread_models
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class MailPerformanceThread(models.Model):
_name = 'mail.performance.thread'
_description = 'Performance: mail.thread'
_inherit = ['mail.thread']
name = fields.Char()
value = fields.Integer()
value_pc = fields.Float(compute="_value_pc", store=True)
track = fields.Char(default='test', tracking=True)
partner_id = fields.Many2one('res.partner', string='Customer')
@api.depends('value')
def _value_pc(self):
for record in self:
record.value_pc = float(record.value) / 100
class MailPerformanceTracking(models.Model):
_name = 'mail.performance.tracking'
_description = 'Performance: multi tracking'
_inherit = ['mail.thread']
name = fields.Char(required=True, tracking=True)
field_0 = fields.Char(tracking=True)
field_1 = fields.Char(tracking=True)
field_2 = fields.Char(tracking=True)
class MailTestTrackCompute(models.Model):
_name = 'mail.test.track.compute'
_description = "Test tracking with computed fields"
_inherit = ['mail.thread']
partner_id = fields.Many2one('res.partner', tracking=True)
partner_name = fields.Char(related='partner_id.name', store=True, tracking=True)
partner_email = fields.Char(related='partner_id.email', store=True, tracking=True)
partner_phone = fields.Char(related='partner_id.phone', tracking=True)
class MailTestMultiCompany(models.Model):
""" This model can be used in multi company tests"""
_name = 'mail.test.multi.company'
_description = "Test Multi Company Mail"
_inherit = 'mail.thread'
name = fields.Char()
company_id = fields.Many2one('res.company')
+19 -76
View File
@@ -38,7 +38,7 @@ class MailTestStandard(models.Model):
name = fields.Char()
email_from = fields.Char()
user_id = fields.Many2one('res.users', 'Responsible', tracking=True)
umbrella_id = fields.Many2one('mail.test', tracking=True)
container_id = fields.Many2one('mail.test.container', tracking=True)
company_id = fields.Many2one('res.company')
@@ -63,11 +63,11 @@ class MailTestActivity(models.Model):
self.activity_feedback(['test_mail.mail_act_test_todo'], feedback=action_feedback)
class MailTestFull(models.Model):
class MailTestTicket(models.Model):
""" This model can be used in tests when complex chatter features are
required like modeling tasks or tickets. """
_description = 'Full Chatter Model'
_name = 'mail.test.full'
_description = 'Ticket-like model'
_name = 'mail.test.ticket'
_inherit = ['mail.thread']
name = fields.Char()
@@ -77,34 +77,34 @@ class MailTestFull(models.Model):
mail_template = fields.Many2one('mail.template', 'Template')
customer_id = fields.Many2one('res.partner', 'Customer', tracking=2)
user_id = fields.Many2one('res.users', 'Responsible', tracking=1)
umbrella_id = fields.Many2one('mail.test', tracking=True)
container_id = fields.Many2one('mail.test.container', tracking=True)
def _track_template(self, changes):
res = super(MailTestFull, self)._track_template(changes)
res = super(MailTestTicket, self)._track_template(changes)
record = self[0]
if 'customer_id' in changes and record.mail_template:
res['customer_id'] = (record.mail_template, {'composition_mode': 'mass_mail'})
elif 'datetime' in changes:
res['datetime'] = ('test_mail.mail_test_full_tracking_view', {'composition_mode': 'mass_mail'})
res['datetime'] = ('test_mail.mail_test_ticket_tracking_view', {'composition_mode': 'mass_mail'})
return res
def _creation_subtype(self):
if self.umbrella_id:
return self.env.ref('test_mail.st_mail_test_full_umbrella_upd')
return super(MailTestFull, self)._creation_subtype()
if self.container_id:
return self.env.ref('test_mail.st_mail_test_ticket_container_upd')
return super(MailTestTicket, self)._creation_subtype()
def _track_subtype(self, init_values):
self.ensure_one()
if 'umbrella_id' in init_values and self.umbrella_id:
return self.env.ref('test_mail.st_mail_test_full_umbrella_upd')
return super(MailTestFull, self)._track_subtype(init_values)
if 'container_id' in init_values and self.container_id:
return self.env.ref('test_mail.st_mail_test_ticket_container_upd')
return super(MailTestTicket, self)._track_subtype(init_values)
class MailTestAlias(models.Model):
""" This model can be used in tests when umbrella records like projects
class MailTestContainer(models.Model):
""" This model can be used in tests when container records like projects
or teams are required. """
_description = 'Alias Chatter Model'
_name = 'mail.test'
_description = 'Project-like model with alias'
_name = 'mail.test.container'
_mail_post_access = 'read'
_inherit = ['mail.thread', 'mail.alias.mixin']
@@ -116,66 +116,9 @@ class MailTestAlias(models.Model):
delegate=True)
def _alias_get_creation_values(self):
values = super(MailTestAlias, self)._alias_get_creation_values()
values['alias_model_id'] = self.env['ir.model']._get('mail.test').id
values = super(MailTestContainer, self)._alias_get_creation_values()
values['alias_model_id'] = self.env['ir.model']._get('mail.test.container').id
if self.id:
values['alias_force_thread_id'] = self.id
values['alias_parent_thread_id'] = self.id
return values
class MailModel(models.Model):
_name = 'test_performance.mail'
_description = 'Test Performance Mail'
_inherit = 'mail.thread'
name = fields.Char()
value = fields.Integer()
value_pc = fields.Float(compute="_value_pc", store=True)
track = fields.Char(default='test', tracking=True)
partner_id = fields.Many2one('res.partner', string='Customer')
@api.depends('value')
def _value_pc(self):
for record in self:
record.value_pc = float(record.value) / 100
class MailCC(models.Model):
_name = 'mail.test.cc'
_description = "Test Email CC Thread"
_inherit = ['mail.thread.cc']
name = fields.Char()
class MailMultiCompany(models.Model):
""" This model can be used in multi company tests"""
_name = 'mail.test.multi.company'
_description = "Test Multi Company Mail"
_inherit = 'mail.thread'
name = fields.Char()
company_id = fields.Many2one('res.company')
class MailTrackingModel(models.Model):
_description = 'Test Tracking Model'
_name = 'mail.test.tracking'
_inherit = ['mail.thread']
name = fields.Char(required=True, tracking=True)
field_0 = fields.Char(tracking=True)
field_1 = fields.Char(tracking=True)
field_2 = fields.Char(tracking=True)
class MailCompute(models.Model):
_name = 'mail.test.compute'
_description = "Test model with several tracked computed fields"
_inherit = ['mail.thread']
partner_id = fields.Many2one('res.partner', tracking=True)
partner_name = fields.Char(related='partner_id.name', store=True, tracking=True)
partner_email = fields.Char(related='partner_id.email', store=True, tracking=True)
partner_phone = fields.Char(related='partner_id.phone', tracking=True)
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class MailTestCC(models.Model):
_name = 'mail.test.cc'
_description = "Test Email CC Thread"
_inherit = ['mail.thread.cc']
name = fields.Char()
@@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_test_performance_mail,access_test_performance_mail,model_test_performance_mail,,1,1,1,1
access_mail_performance_thread,access_mail_performance_thread,model_mail_performance_thread,,1,1,1,1
access_mail_performance_tracking_user,mail.performance.tracking,model_mail_performance_tracking,base.group_user,1,1,1,1
access_mail_test_simple_portal,mail.test.simple.portal,model_mail_test_simple,base.group_portal,1,0,0,0
access_mail_test_simple_user,mail.test.simple.user,model_mail_test_simple,base.group_user,1,1,1,1
access_mail_test_gateway_portal,mail.test.gateway.portal,model_mail_test_gateway,base.group_portal,1,0,0,0
@@ -8,13 +9,12 @@ access_mail_test_track_portal,mail.test.track.portal,model_mail_test_track,base.
access_mail_test_track_user,mail.test.track.user.employee,model_mail_test_track,base.group_user,1,1,1,1
access_mail_test_activity_portal,mail.test.activity.portal,model_mail_test_activity,base.group_portal,1,0,0,0
access_mail_test_activity_user,mail.test.activity.user,model_mail_test_activity,base.group_user,1,1,1,1
access_mail_test_full_portal,mail.test.full.portal,model_mail_test_full,base.group_portal,0,0,0,0
access_mail_test_full_user,mail.test.full.user,model_mail_test_full,base.group_user,1,1,1,1
access_mail_test_portal,mail.test.portal,model_mail_test,base.group_portal,1,1,0,0
access_mail_test_user,mail.test.user,model_mail_test,base.group_user,1,1,1,1
access_mail_test_ticket_portal,mail.test.ticket.portal,model_mail_test_ticket,base.group_portal,0,0,0,0
access_mail_test_ticket_user,mail.test.ticket.user,model_mail_test_ticket,base.group_user,1,1,1,1
access_mail_test_container_portal,mail.test.container_portal,model_mail_test_container,base.group_portal,1,1,0,0
access_mail_test_container_user,mail.test.container.user,model_mail_test_container,base.group_user,1,1,1,1
access_mail_test_cc_portal,mail.test.cc.portal,model_mail_test_cc,base.group_portal,1,0,0,0
access_mail_test_cc_user,mail.test.cc.user,model_mail_test_cc,base.group_user,1,1,1,1
access_mail_test_multi_company_user,mail.test.multi.company.user,model_mail_test_multi_company,base.group_user,1,1,1,1
access_mail_test_multi_company_portal,mail.test.multi.company.portal,model_mail_test_multi_company,base.group_portal,1,0,0,0
access_mail_test_tracking_user,mail.test.tracking,model_mail_test_tracking,base.group_user,1,1,1,1
access_mail_test_compute,mail.test.compute,model_mail_test_compute,base.group_user,1,1,1,1
access_mail_test_track_compute,mail.test.track.compute,model_mail_test_track_compute,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_test_performance_mail access_mail_performance_thread access_test_performance_mail access_mail_performance_thread model_test_performance_mail model_mail_performance_thread 1 1 1 1
3 access_mail_performance_tracking_user mail.performance.tracking model_mail_performance_tracking base.group_user 1 1 1 1
4 access_mail_test_simple_portal mail.test.simple.portal model_mail_test_simple base.group_portal 1 0 0 0
5 access_mail_test_simple_user mail.test.simple.user model_mail_test_simple base.group_user 1 1 1 1
6 access_mail_test_gateway_portal mail.test.gateway.portal model_mail_test_gateway base.group_portal 1 0 0 0
9 access_mail_test_track_user mail.test.track.user.employee model_mail_test_track base.group_user 1 1 1 1
10 access_mail_test_activity_portal mail.test.activity.portal model_mail_test_activity base.group_portal 1 0 0 0
11 access_mail_test_activity_user mail.test.activity.user model_mail_test_activity base.group_user 1 1 1 1
12 access_mail_test_full_portal access_mail_test_ticket_portal mail.test.full.portal mail.test.ticket.portal model_mail_test_full model_mail_test_ticket base.group_portal 0 0 0 0
13 access_mail_test_full_user access_mail_test_ticket_user mail.test.full.user mail.test.ticket.user model_mail_test_full model_mail_test_ticket base.group_user 1 1 1 1
14 access_mail_test_portal access_mail_test_container_portal mail.test.portal mail.test.container_portal model_mail_test model_mail_test_container base.group_portal 1 1 0 0
15 access_mail_test_user access_mail_test_container_user mail.test.user mail.test.container.user model_mail_test model_mail_test_container base.group_user 1 1 1 1
16 access_mail_test_cc_portal mail.test.cc.portal model_mail_test_cc base.group_portal 1 0 0 0
17 access_mail_test_cc_user mail.test.cc.user model_mail_test_cc base.group_user 1 1 1 1
18 access_mail_test_multi_company_user mail.test.multi.company.user model_mail_test_multi_company base.group_user 1 1 1 1
19 access_mail_test_multi_company_portal mail.test.multi.company.portal model_mail_test_multi_company base.group_portal 1 0 0 0
20 access_mail_test_tracking_user access_mail_test_track_compute mail.test.tracking mail.test.track.compute model_mail_test_tracking model_mail_test_track_compute base.group_user 1 1 1 1
access_mail_test_compute mail.test.compute model_mail_test_compute base.group_user 1 1 1 1
+1 -4
View File
@@ -2,19 +2,16 @@
from . import test_invite
from . import test_ir_actions
from . import test_discuss
from . import test_mail_activity
from . import test_mail_followers
from . import test_mail_message
from . import test_mail_mail
from . import test_mail_channel
from . import test_mail_gateway
from . import test_mail_redirect
from . import test_mail_template
from . import test_mail_thread_internals
from . import test_message_composer
from . import test_message_management
from . import test_message_post
from . import test_message_track
from . import test_odoobot
from . import test_performance
from . import test_update_notification
+17 -17
View File
@@ -19,7 +19,7 @@ class BaseFollowersTest(TestMailCommon):
Subtype = cls.env['mail.message.subtype']
cls.mt_mg_def = Subtype.create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test.simple'})
cls.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'mail.test'})
cls.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'mail.test.container'})
cls.mt_al_def = Subtype.create({'name': 'mt_al_def', 'default': True, 'res_model': False})
cls.mt_mg_nodef = Subtype.create({'name': 'mt_mg_nodef', 'default': False, 'res_model': 'mail.test.simple'})
cls.mt_al_nodef = Subtype.create({'name': 'mt_al_nodef', 'default': False, 'res_model': False})
@@ -141,19 +141,19 @@ class AdvancedFollowersTest(TestMailCommon):
Subtype = cls.env['mail.message.subtype']
# clean demo data to avoid interferences
Subtype.search([('res_model', 'in', ['mail.test', 'mail.test.track'])]).unlink()
Subtype.search([('res_model', 'in', ['mail.test.container', 'mail.test.track'])]).unlink()
cls.sub_nodef = Subtype.create({'name': 'Sub NoDefault', 'default': False, 'res_model': 'mail.test'})
cls.sub_umb1 = Subtype.create({'name': 'Sub Umbrella1', 'default': False, 'res_model': 'mail.test.track'})
cls.sub_umb2 = Subtype.create({'name': 'Sub Umbrella2', 'default': False, 'res_model': 'mail.test.track'})
cls.umb_def = Subtype.create({'name': 'Umbrella Default', 'default': True, 'res_model': 'mail.test'})
# create subtypes for auto subscription from umbrella to sub records
cls.sub_nodef = Subtype.create({'name': 'Sub NoDefault', 'default': False, 'res_model': 'mail.test.container'})
cls.sub_umb1 = Subtype.create({'name': 'Sub Container1', 'default': False, 'res_model': 'mail.test.track'})
cls.sub_umb2 = Subtype.create({'name': 'Sub Container2', 'default': False, 'res_model': 'mail.test.track'})
cls.umb_def = Subtype.create({'name': 'Container Default', 'default': True, 'res_model': 'mail.test.container'})
# create subtypes for auto subscription from container to sub records
cls.umb_sub_def = Subtype.create({
'name': 'Umbrella Sub1', 'default': True, 'res_model': 'mail.test',
'parent_id': cls.sub_umb1.id, 'relation_field': 'umbrella_id'})
'name': 'Container Sub1', 'default': True, 'res_model': 'mail.test.container',
'parent_id': cls.sub_umb1.id, 'relation_field': 'container_id'})
cls.umb_sub_nodef = Subtype.create({
'name': 'Umbrella Sub2', 'default': False, 'res_model': 'mail.test',
'parent_id': cls.sub_umb2.id, 'relation_field': 'umbrella_id'})
'name': 'Container Sub2', 'default': False, 'res_model': 'mail.test.container',
'parent_id': cls.sub_umb2.id, 'relation_field': 'container_id'})
def test_auto_subscribe_create(self):
""" Creator of records are automatically added as followers """
@@ -183,27 +183,27 @@ class AdvancedFollowersTest(TestMailCommon):
self.assertEqual(sub.message_partner_ids, (self.user_employee.partner_id | self.user_admin.partner_id))
def test_auto_subscribe_defaults(self):
""" Test auto subscription based on an umbrella record. This mimics
""" Test auto subscription based on an container record. This mimics
the behavior of addons like project and task where subscribing to
some project's subtypes automatically subscribe the follower to its tasks.
Functional rules applied here
* subscribing to an umbrella subtype with parent_id / relation_field set
* subscribing to an container subtype with parent_id / relation_field set
automatically create subscription with matching subtypes
* subscribing to a sub-record as creator applies default subtype values
* portal user should not have access to internal subtypes
"""
umbrella = self.env['mail.test'].with_context(self._test_context).create({
container = self.env['mail.test.container'].with_context(self._test_context).create({
'name': 'Project-Like',
})
umbrella.message_subscribe(partner_ids=[self.partner_portal.id])
self.assertEqual(umbrella.message_partner_ids, self.partner_portal)
container.message_subscribe(partner_ids=[self.partner_portal.id])
self.assertEqual(container.message_partner_ids, self.partner_portal)
sub1 = self.env['mail.test.track'].with_user(self.user_employee).create({
'name': 'Task-Like Test',
'umbrella_id': umbrella.id,
'container_id': container.id,
})
all_defaults = self.env['mail.message.subtype'].search([('default', '=', True), '|', ('res_model', '=', 'mail.test.track'), ('res_model', '=', False)])
+14 -14
View File
@@ -76,14 +76,14 @@ class TestMailAlias(TestMailCommon):
@users('employee')
def test_alias_creation(self):
record = self.env['mail.test'].create({
record = self.env['mail.test.container'].create({
'name': 'Test Record',
'alias_name': 'alias.test',
'alias_contact': 'followers',
})
self.assertEqual(record.alias_id.alias_model_id, self.env['ir.model']._get('mail.test'))
self.assertEqual(record.alias_id.alias_model_id, self.env['ir.model']._get('mail.test.container'))
self.assertEqual(record.alias_id.alias_force_thread_id, record.id)
self.assertEqual(record.alias_id.alias_parent_model_id, self.env['ir.model']._get('mail.test'))
self.assertEqual(record.alias_id.alias_parent_model_id, self.env['ir.model']._get('mail.test.container'))
self.assertEqual(record.alias_id.alias_parent_thread_id, record.id)
self.assertEqual(record.alias_id.alias_name, 'alias.test')
self.assertEqual(record.alias_id.alias_contact, 'followers')
@@ -108,7 +108,7 @@ class TestMailAlias(TestMailCommon):
def test_alias_setup(self):
alias = self.env['mail.alias'].create({
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_name': 'b4r+_#_R3wl$$',
})
self.assertEqual(alias.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens')
@@ -234,7 +234,7 @@ class TestMailgateway(TestMailCommon):
# Test: author (and not recipient) added as follower
# self.assertEqual(self.test_public.message_partner_ids, self.partner_1 | self.partner_2,
# 'message_process: after reply, group should have 2 followers')
# self.assertEqual(self.test_public.message_channel_ids, self.env['mail.test'],
# self.assertEqual(self.test_public.message_channel_ids, self.env['mail.test.container'],
# 'message_process: after reply, group should have 2 followers (0 channels)')
# --------------------------------------------------
@@ -516,7 +516,7 @@ class TestMailgateway(TestMailCommon):
new_alias_2 = self.env['mail.alias'].create({
'alias_name': 'test',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
new_rec = self.format_and_process(
@@ -543,7 +543,7 @@ class TestMailgateway(TestMailCommon):
new_alias_2 = self.env['mail.alias'].create({
'alias_name': 'test',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
new_rec = self.format_and_process(
@@ -573,7 +573,7 @@ class TestMailgateway(TestMailCommon):
new_alias_2 = self.env['mail.alias'].create({
'alias_name': 'test',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
new_rec = self.format_and_process(
@@ -599,7 +599,7 @@ class TestMailgateway(TestMailCommon):
new_alias_2 = self.env['mail.alias'].create({
'alias_name': 'test',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
new_rec = self.format_and_process(
@@ -852,14 +852,14 @@ class TestMailgateway(TestMailCommon):
self.env['mail.alias'].create({
'alias_name': 'test.alias',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
init_msg_count = len(self.test_record.message_ids)
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'test.alias@test.com',
subject='My Dear Forward', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
target_model='mail.test')
target_model='mail.test.container')
self.assertEqual(len(self.test_record.message_ids), init_msg_count)
self.assertEqual(len(self.fake_email.child_ids), 0)
@@ -879,7 +879,7 @@ class TestMailgateway(TestMailCommon):
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'test.alias@test.com',
subject='My Dear Forward', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
target_model='mail.test')
target_model='mail.test.container')
self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1)
self.assertEqual(len(self.fake_email.child_ids), 1)
@@ -891,14 +891,14 @@ class TestMailgateway(TestMailCommon):
self.env['mail.alias'].create({
'alias_name': 'test.alias',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test').id,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
init_msg_count = len(self.test_record.message_ids)
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'catchall.test@test.com', cc='test.alias@test.com',
subject='My Dear Forward', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
target_model='mail.test')
target_model='mail.test.container')
self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1)
self.assertEqual(len(self.fake_email.child_ids), 1)
+6 -6
View File
@@ -19,7 +19,7 @@ class TestMessageValues(TestMailCommon):
super(TestMessageValues, cls).setUpClass()
cls._init_mail_gateway()
cls.alias_record = cls.env['mail.test'].with_context(cls._test_context).create({
cls.alias_record = cls.env['mail.test.container'].with_context(cls._test_context).create({
'name': 'Pigs',
'alias_name': 'pigs',
'alias_contact': 'followers',
@@ -65,7 +65,7 @@ class TestMessageValues(TestMailCommon):
@mute_logger('odoo.models.unlink')
def test_mail_message_values_document_alias(self):
msg = self.Message.create({
'model': 'mail.test',
'model': 'mail.test.container',
'res_id': self.alias_record.id
})
self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id.split('@')[0])
@@ -78,7 +78,7 @@ class TestMessageValues(TestMailCommon):
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink()
msg = self.Message.create({
'model': 'mail.test',
'model': 'mail.test.container',
'res_id': self.alias_record.id
})
self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id.split('@')[0])
@@ -90,7 +90,7 @@ class TestMessageValues(TestMailCommon):
self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.alias')]).unlink()
msg = self.Message.create({
'model': 'mail.test',
'model': 'mail.test.container',
'res_id': self.alias_record.id
})
self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id.split('@')[0])
@@ -137,12 +137,12 @@ class TestMessageValues(TestMailCommon):
def test_mail_message_values_no_auto_thread(self):
msg = self.Message.create({
'model': 'mail.test',
'model': 'mail.test.container',
'res_id': self.alias_record.id,
'no_auto_thread': True,
})
self.assertIn('reply_to', msg.message_id.split('@')[0])
self.assertNotIn('mail.test', msg.message_id.split('@')[0])
self.assertNotIn('mail.test.container', msg.message_id.split('@')[0])
self.assertNotIn('-%d-' % self.alias_record.id, msg.message_id.split('@')[0])
def test_mail_message_base64_image(self):
@@ -1,67 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from werkzeug.urls import url_decode, url_parse
from odoo.tests.common import HttpCase, tagged
@tagged('-at_install', 'post_install')
class TestMultiCompany(HttpCase):
def test_redirect_to_records(self):
self.company_A = self.env['res.company'].create({
'name': 'Company A',
'user_ids': [(4, self.ref('base.user_admin'))],
})
self.company_B = self.env['res.company'].create({
'name': 'Company B',
})
self.multi_company_record = self.env['mail.test.multi.company'].create({
'name': 'Multi Company Record',
'company_id': self.company_A.id,
})
# Test Case 0
# Not logged, redirect to web/login
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
path = url_parse(response.url).path
self.assertEqual(path, '/web/login')
self.authenticate('admin', 'admin')
# Test Case 1
# Logged into company 1, try accessing record in company A
# _redirect_to_record should add company A in allowed_company_ids
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
self.assertEqual(response.status_code, 200)
fragment = url_parse(response.url).fragment
cids = url_decode(fragment)['cids']
self.assertEqual(cids, '1,%s' % (self.company_A.id))
# Test Case 2
# Logged into company 1, try accessing record in company B
# _redirect_to_record should redirect to messaging as the user
# doesn't have any access for this company
self.multi_company_record.company_id = self.company_B
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
self.assertEqual(response.status_code, 200)
fragment = url_parse(response.url).fragment
action = url_decode(fragment)['action']
self.assertEqual(action, 'mail.action_discuss')
@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from werkzeug.urls import url_parse, url_decode
from odoo.addons.test_mail.tests.common import TestMailCommon, TestRecipients
from odoo.tests.common import tagged, HttpCase
from odoo.tools import mute_logger
@@ -141,3 +144,65 @@ class TestDiscuss(TestMailCommon, TestRecipients):
(False, 'cc1@example.com', 'CC Email'),
(False, 'cc2@example.com', 'CC Email'),
], 'cc should be in suggestions')
@tagged('-at_install', 'post_install')
class TestMultiCompany(HttpCase):
def test_redirect_to_records(self):
self.company_A = self.env['res.company'].create({
'name': 'Company A',
'user_ids': [(4, self.ref('base.user_admin'))],
})
self.company_B = self.env['res.company'].create({
'name': 'Company B',
})
self.multi_company_record = self.env['mail.test.multi.company'].create({
'name': 'Multi Company Record',
'company_id': self.company_A.id,
})
# Test Case 0
# Not logged, redirect to web/login
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
path = url_parse(response.url).path
self.assertEqual(path, '/web/login')
self.authenticate('admin', 'admin')
# Test Case 1
# Logged into company 1, try accessing record in company A
# _redirect_to_record should add company A in allowed_company_ids
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
self.assertEqual(response.status_code, 200)
fragment = url_parse(response.url).fragment
cids = url_decode(fragment)['cids']
self.assertEqual(cids, '1,%s' % (self.company_A.id))
# Test Case 2
# Logged into company 1, try accessing record in company B
# _redirect_to_record should redirect to messaging as the user
# doesn't have any access for this company
self.multi_company_record.company_id = self.company_B
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.multi_company_record._name,
self.multi_company_record.id), timeout=15)
self.assertEqual(response.status_code, 200)
fragment = url_parse(response.url).fragment
action = url_decode(fragment)['action']
self.assertEqual(action, 'mail.action_discuss')
+79 -74
View File
@@ -4,14 +4,16 @@
from unittest.mock import patch
from odoo.addons.test_mail.tests.common import TestMailCommon
from odoo.tests.common import tagged
@tagged('mail_track')
class TestTracking(TestMailCommon):
def setUp(self):
super(TestTracking, self).setUp()
record = self.env['mail.test.full'].with_user(self.user_employee).with_context(self._test_context).create({
record = self.env['mail.test.ticket'].with_user(self.user_employee).with_context(self._test_context).create({
'name': 'Test',
})
self.flush_tracking()
@@ -55,33 +57,33 @@ class TestTracking(TestMailCommon):
""" Update some tracked fields linked to some subtype -> message with onchange """
self.record.message_subscribe(
partner_ids=[self.user_admin.partner_id.id],
subtype_ids=[self.env.ref('test_mail.st_mail_test_full_umbrella_upd').id]
subtype_ids=[self.env.ref('test_mail.st_mail_test_ticket_container_upd').id]
)
umbrella = self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({'name': 'Umbrella'})
container = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({'name': 'Container'})
self.record.write({
'name': 'Test2',
'email_from': 'noone@example.com',
'umbrella_id': umbrella.id,
'container_id': container.id,
})
self.flush_tracking()
# one new message containing tracking; subtype linked to tracking
self.assertEqual(len(self.record.message_ids), 1)
self.assertEqual(self.record.message_ids.subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(self.record.message_ids.subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
# no specific recipients except those following umbrella
# no specific recipients except those following container
self.assertEqual(self.record.message_ids.partner_ids, self.env['res.partner'])
self.assertEqual(self.record.message_ids.notified_partner_ids, self.user_admin.partner_id)
# verify tracked value
self.assertTracking(
self.record.message_ids,
[('umbrella_id', 'many2one', False, umbrella) # onchange tracked field
[('container_id', 'many2one', False, container) # onchange tracked field
])
def test_message_track_template(self):
""" Update some tracked fields linked to some template -> message with onchange """
self.record.write({'mail_template': self.env.ref('test_mail.mail_test_full_tracking_tpl').id})
self.record.write({'mail_template': self.env.ref('test_mail.mail_test_ticket_tracking_tpl').id})
self.assertEqual(self.record.message_ids, self.env['mail.message'])
with self.mock_mail_gateway():
@@ -110,13 +112,13 @@ class TestTracking(TestMailCommon):
def test_message_track_template_at_create(self):
""" Create a record with tracking template on create, template should be sent."""
Model = self.env['mail.test.full'].with_user(self.user_employee).with_context(self._test_context)
Model = self.env['mail.test.ticket'].with_user(self.user_employee).with_context(self._test_context)
Model = Model.with_context(mail_notrack=False)
with self.mock_mail_gateway():
record = Model.create({
'name': 'Test',
'customer_id': self.user_admin.partner_id.id,
'mail_template': self.env.ref('test_mail.mail_test_full_tracking_tpl').id,
'mail_template': self.env.ref('test_mail.mail_test_ticket_tracking_tpl').id,
})
self.flush_tracking()
@@ -127,61 +129,6 @@ class TestTracking(TestMailCommon):
# one email send due to template
self.assertSentEmail(self.record.env.user.partner_id, [self.partner_admin], body='<p>Hello Test</p>')
def test_message_tracking_sequence(self):
""" Update some tracked fields and check that the mail.tracking.value are ordered according to their tracking_sequence"""
self.record.write({
'name': 'Zboub',
'customer_id': self.user_admin.partner_id.id,
'user_id': self.user_admin.id,
'umbrella_id': self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({'name': 'Umbrella'}).id
})
self.flush_tracking()
self.assertEqual(len(self.record.message_ids), 1, 'should have 1 tracking message')
tracking_values = self.env['mail.tracking.value'].search([('mail_message_id', '=', self.record.message_ids.id)])
self.assertEqual(tracking_values[0].tracking_sequence, 1)
self.assertEqual(tracking_values[1].tracking_sequence, 2)
self.assertEqual(tracking_values[2].tracking_sequence, 100)
def test_track_groups(self):
# patch the group attribute
field = self.record._fields['email_from']
self.addCleanup(setattr, field, 'groups', field.groups)
field.groups = 'base.group_erp_manager'
self.record.sudo().write({'email_from': 'X'})
self.flush_tracking()
msg_emp = self.record.message_ids.message_format()
msg_sudo = self.record.sudo().message_ids.message_format()
self.assertFalse(msg_emp[0].get('tracking_value_ids'), "should not have protected tracking values")
self.assertTrue(msg_sudo[0].get('tracking_value_ids'), "should have protected tracking values")
def test_notify_track_groups(self):
# patch the group attribute
field = self.record._fields['email_from']
self.addCleanup(setattr, field, 'groups', field.groups)
field.groups = 'base.group_erp_manager'
self.record.sudo().write({'email_from': 'X'})
self.flush_tracking()
msg_emp = self.record._notify_prepare_template_context(self.record.message_ids, {})
msg_sudo = self.record.sudo()._notify_prepare_template_context(self.record.message_ids, {})
self.assertFalse(msg_emp.get('tracking_values'), "should not have protected tracking values")
self.assertTrue(msg_sudo.get('tracking_values'), "should have protected tracking values")
def test_unlinked_field(self):
record_sudo = self.record.sudo()
record_sudo.write({'email_from': 'X'}) # create a tracking value
self.flush_tracking()
self.assertEqual(len(record_sudo.message_ids.tracking_value_ids), 1)
ir_model_field = self.env['ir.model.fields'].search([
('model', '=', 'mail.test.full'),
('name', '=', 'email_from')])
ir_model_field.with_context(_force_unlink=True).unlink()
self.assertEqual(len(record_sudo.message_ids.tracking_value_ids), 0)
def test_create_partner_from_tracking_multicompany(self):
company1 = self.env['res.company'].create({'name': 'company1'})
self.env.user.write({'company_ids': [(4, company1.id, False)]})
@@ -234,7 +181,7 @@ class TestTracking(TestMailCommon):
mail_template = self.env['mail.template'].create({
'name': 'SPECIAL CONTENT UNLOCKED',
'subject': 'SPECIAL CONTENT UNLOCKED',
'model_id': self.env.ref('test_mail.model_mail_test').id,
'model_id': self.env.ref('test_mail.model_mail_test_container').id,
'auto_delete': True,
'body_html': '''<div>WOOP WOOP</div>''',
})
@@ -243,16 +190,16 @@ class TestTracking(TestMailCommon):
if 'name' in init_values and init_values['name'] == magic_code:
return 'mail.mt_name_changed'
return False
self.registry('mail.test')._patch_method('_track_subtype', _track_subtype)
self.registry('mail.test.container')._patch_method('_track_subtype', _track_subtype)
def _track_template(self, changes):
res = {}
if 'name' in changes:
res['name'] = (mail_template, {'composition_mode': 'mass_mail'})
return res
self.registry('mail.test')._patch_method('_track_template', _track_template)
self.registry('mail.test.container')._patch_method('_track_template', _track_template)
cls = type(self.env['mail.test'])
cls = type(self.env['mail.test.container'])
self.assertFalse(hasattr(getattr(cls, 'name'), 'track_visibility'))
getattr(cls, 'name').track_visibility = 'always'
@@ -260,7 +207,7 @@ class TestTracking(TestMailCommon):
def cleanup():
del getattr(cls, 'name').track_visibility
test_mail_record = self.env['mail.test'].create({
test_mail_record = self.env['mail.test.container'].create({
'name': 'Zizizatestmailname',
'description': 'Zizizatestmaildescription',
})
@@ -268,11 +215,11 @@ class TestTracking(TestMailCommon):
def test_message_track_multiple(self):
""" check that multiple updates generate a single tracking message """
umbrella = self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({'name': 'Umbrella'})
container = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({'name': 'Container'})
self.record.name = 'Zboub'
self.record.customer_id = self.user_admin.partner_id
self.record.user_id = self.user_admin
self.record.umbrella_id = umbrella
self.record.container_id = container
self.flush_tracking()
# should have a single message with all tracked fields
@@ -280,12 +227,12 @@ class TestTracking(TestMailCommon):
self.assertTracking(self.record.message_ids[0], [
('customer_id', 'many2one', False, self.user_admin.partner_id),
('user_id', 'many2one', False, self.user_admin),
('umbrella_id', 'many2one', False, umbrella),
('container_id', 'many2one', False, container),
])
def test_tracked_compute(self):
# no tracking at creation
record = self.env['mail.test.compute'].create({})
record = self.env['mail.test.track.compute'].create({})
self.flush_tracking()
self.assertEqual(len(record.message_ids), 1)
self.assertEqual(len(record.message_ids[0].tracking_value_ids), 0)
@@ -334,3 +281,61 @@ class TestTracking(TestMailCommon):
('partner_name', 'char', 'Fool', 'Bar'),
('partner_email', 'char', 'foo@example.com', 'bar@example.com'),
])
@tagged('mail_track')
class TestTrackingInternals(TestMailCommon):
def setUp(self):
super(TestTrackingInternals, self).setUp()
record = self.env['mail.test.ticket'].with_user(self.user_employee).with_context(self._test_context).create({
'name': 'Test',
})
self.flush_tracking()
self.record = record.with_context(mail_notrack=False)
def test_track_groups(self):
field = self.record._fields['email_from']
self.addCleanup(setattr, field, 'groups', field.groups)
field.groups = 'base.group_erp_manager'
self.record.sudo().write({'email_from': 'X'})
self.flush_tracking()
msg_emp = self.record.message_ids.message_format()
msg_sudo = self.record.sudo().message_ids.message_format()
self.assertFalse(msg_emp[0].get('tracking_value_ids'), "should not have protected tracking values")
self.assertTrue(msg_sudo[0].get('tracking_value_ids'), "should have protected tracking values")
msg_emp = self.record._notify_prepare_template_context(self.record.message_ids, {})
msg_sudo = self.record.sudo()._notify_prepare_template_context(self.record.message_ids, {})
self.assertFalse(msg_emp.get('tracking_values'), "should not have protected tracking values")
self.assertTrue(msg_sudo.get('tracking_values'), "should have protected tracking values")
def test_track_sequence(self):
""" Update some tracked fields and check that the mail.tracking.value are ordered according to their tracking_sequence"""
self.record.write({
'name': 'Zboub',
'customer_id': self.user_admin.partner_id.id,
'user_id': self.user_admin.id,
'container_id': self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({'name': 'Container'}).id
})
self.flush_tracking()
self.assertEqual(len(self.record.message_ids), 1, 'should have 1 tracking message')
tracking_values = self.env['mail.tracking.value'].search([('mail_message_id', '=', self.record.message_ids.id)])
self.assertEqual(tracking_values[0].tracking_sequence, 1)
self.assertEqual(tracking_values[1].tracking_sequence, 2)
self.assertEqual(tracking_values[2].tracking_sequence, 100)
def test_unlinked_field(self):
record_sudo = self.record.sudo()
record_sudo.write({'email_from': 'new_value'}) # create a tracking value
self.flush_tracking()
self.assertEqual(len(record_sudo.message_ids.tracking_value_ids), 1)
ir_model_field = self.env['ir.model.fields'].search([
('model', '=', 'mail.test.ticket'),
('name', '=', 'email_from')])
ir_model_field.with_context(_force_unlink=True).unlink()
self.assertEqual(len(record_sudo.message_ids.tracking_value_ids), 0)
+83 -84
View File
@@ -54,7 +54,7 @@ class TestMailPerformance(BaseMailPerformance):
'name': 'Azure Interior',
'email': 'azure.Interior24@example.com',
})
self.env['test_performance.mail'].create([
self.env['mail.performance.thread'].create([
{
'name': 'Object 0',
'value': 0,
@@ -82,7 +82,7 @@ class TestMailPerformance(BaseMailPerformance):
@warmup
def test_read_mail(self):
""" Read records inheriting from 'mail.thread'. """
records = self.env['test_performance.mail'].search([])
records = self.env['mail.performance.thread'].search([])
self.assertEqual(len(records), 5)
with self.assertQueryCount(__system__=2, demo=2):
@@ -104,7 +104,7 @@ class TestMailPerformance(BaseMailPerformance):
@warmup
def test_write_mail(self):
""" Write records inheriting from 'mail.thread' (no recomputation). """
records = self.env['test_performance.mail'].search([])
records = self.env['mail.performance.thread'].search([])
self.assertEqual(len(records), 5)
with self.assertQueryCount(__system__=2, demo=2):
@@ -114,7 +114,7 @@ class TestMailPerformance(BaseMailPerformance):
@warmup
def test_write_mail_with_recomputation(self):
""" Write records inheriting from 'mail.thread' (with recomputation). """
records = self.env['test_performance.mail'].search([])
records = self.env['mail.performance.thread'].search([])
self.assertEqual(len(records), 5)
with self.assertQueryCount(__system__=2, demo=2):
@@ -124,7 +124,7 @@ class TestMailPerformance(BaseMailPerformance):
@warmup
def test_write_mail_with_tracking(self):
""" Write records inheriting from 'mail.thread' (with field tracking). """
record = self.env['test_performance.mail'].create({
record = self.env['mail.performance.thread'].create({
'name': 'Test',
'track': 'Y',
'value': 40,
@@ -138,7 +138,7 @@ class TestMailPerformance(BaseMailPerformance):
@warmup
def test_create_mail(self):
""" Create records inheriting from 'mail.thread' (without field tracking). """
model = self.env['test_performance.mail']
model = self.env['mail.performance.thread']
with self.assertQueryCount(__system__=2, demo=2):
model.with_context(tracking_disable=True).create({'name': 'X'})
@@ -148,7 +148,7 @@ class TestMailPerformance(BaseMailPerformance):
def test_create_mail_with_tracking(self):
""" Create records inheriting from 'mail.thread' (with field tracking). """
with self.assertQueryCount(__system__=7, demo=7):
self.env['test_performance.mail'].create({'name': 'X'})
self.env['mail.performance.thread'].create({'name': 'X'})
@users('__system__', 'emp')
@warmup
@@ -183,7 +183,12 @@ class TestMailAPIPerformance(BaseMailPerformance):
'notification_type': 'inbox',
'groups_id': [(6, 0, [self.env.ref('base.group_user').id])],
})
self.test_record_full = self.env['mail.test.full'].with_context(self._quick_create_ctx).create({
# automatically follow activities, for backward compatibility concerning query count
self.env.ref('mail.mt_activities').write({'default': True})
def _create_test_records(self):
self.test_record_full = self.env['mail.test.ticket'].with_context(self._quick_create_ctx).create({
'name': 'TestRecord',
'customer_id': self.customer.id,
'user_id': self.user_test.id,
@@ -191,7 +196,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
})
self.test_template_full = self.env['mail.template'].create({
'name': 'TestTemplate',
'model_id': self.env['ir.model']._get('mail.test.full').id,
'model_id': self.env['ir.model']._get('mail.test.ticket').id,
'subject': 'About ${object.name}',
'body_html': '<p>Hello ${object.name}</p>',
'email_from': '${object.user_id.email_formatted | safe}',
@@ -199,9 +204,6 @@ class TestMailAPIPerformance(BaseMailPerformance):
'email_to': '${("%s Customer <%s>" % (object.name, object.email_from)) | safe}',
})
# automatically follow activities, for backward compatibility concerning query count
self.env.ref('mail.mt_activities').write({'default': True})
@users('__system__', 'emp')
@warmup
def test_adv_activity(self):
@@ -255,7 +257,8 @@ class TestMailAPIPerformance(BaseMailPerformance):
@warmup
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail')
def test_mail_composer(self):
test_record = self.env['mail.test.full'].browse(self.test_record_full.id)
self._create_test_records()
test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id)
customer_id = self.customer.id
with self.assertQueryCount(__system__=4, emp=4):
composer = self.env['mail.compose.message'].with_context({
@@ -274,7 +277,8 @@ class TestMailAPIPerformance(BaseMailPerformance):
@warmup
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_mail_composer_w_template(self):
test_record = self.env['mail.test.full'].browse(self.test_record_full.id)
self._create_test_records()
test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id)
test_template = self.env['mail.template'].browse(self.test_template_full.id)
# TODO FIXME non deterministic, last check 25 Mar 2020. Runbot at most +7 compared to local.
with self.assertQueryCount(__system__=28, emp=29):
@@ -395,6 +399,25 @@ class TestMailAPIPerformance(BaseMailPerformance):
with self.assertQueryCount(__system__=2, emp=2):
record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
@mute_logger('odoo.models.unlink')
@users('__system__', 'emp')
@warmup
def test_message_track(self):
record = self.env['mail.performance.tracking'].create({'name': 'Zizizatestname'})
with self.assertQueryCount(__system__=3, emp=3):
record.write({'name': 'Zizizanewtestname'})
record.flush()
with self.assertQueryCount(__system__=5, emp=5):
record.write({'field_%s' % (i): 'Tracked Char Fields %s' % (i) for i in range(3)})
record.flush()
with self.assertQueryCount(__system__=6, emp=6):
record.write({'field_%s' % (i): 'Field Without Cache %s' % (i) for i in range(3)})
record.flush()
record.write({'field_%s' % (i): 'Field With Cache %s' % (i) for i in range(3)})
record.flush()
@tagged('mail_performance')
class TestMailComplexPerformance(BaseMailPerformance):
@@ -424,8 +447,8 @@ class TestMailComplexPerformance(BaseMailPerformance):
'name': 'Test Customer',
'email': 'test@example.com'
})
self.umbrella = self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({
'name': 'Test Umbrella',
self.container = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
'name': 'Test Container',
'customer_id': self.customer.id,
'alias_name': 'test-alias',
})
@@ -433,12 +456,12 @@ class TestMailComplexPerformance(BaseMailPerformance):
self.partners = self.env['res.partner']
for x in range(0, 10):
self.partners |= Partners.create({'name': 'Test %s' % x, 'email': 'test%s@example.com' % x})
self.umbrella.message_subscribe(self.partners.ids, subtype_ids=[
self.container.message_subscribe(self.partners.ids, subtype_ids=[
self.env.ref('mail.mt_comment').id,
self.env.ref('test_mail.st_mail_test_child_full').id]
self.env.ref('test_mail.st_mail_test_container_child_full').id]
)
# `test_complex_mail_mail_send`
self.umbrella.flush()
self.container.flush()
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('__system__', 'emp')
@@ -449,8 +472,8 @@ class TestMailComplexPerformance(BaseMailPerformance):
'body': '<p>Test</p>',
'author_id': self.env.user.partner_id.id,
'email_from': self.env.user.partner_id.email,
'model': 'mail.test',
'res_id': self.umbrella.id,
'model': 'mail.test.container',
'res_id': self.container.id,
})
mail = self.env['mail.mail'].sudo().create({
'body_html': '<p>Test</p>',
@@ -462,14 +485,14 @@ class TestMailComplexPerformance(BaseMailPerformance):
self.env['mail.mail'].sudo().browse(mail_ids).send()
self.assertEqual(mail.body_html, '<p>Test</p>')
self.assertEqual(mail.reply_to, formataddr(('%s %s' % (self.env.company.name, self.umbrella.name), 'test-alias@example.com')))
self.assertEqual(mail.reply_to, formataddr(('%s %s' % (self.env.company.name, self.container.name), 'test-alias@example.com')))
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('__system__', 'emp')
@warmup
def test_complex_message_post(self):
self.umbrella.message_subscribe(self.user_portal.partner_id.ids)
record = self.umbrella.with_user(self.env.user)
self.container.message_subscribe(self.user_portal.partner_id.ids)
record = self.container.with_user(self.env.user)
with self.assertQueryCount(__system__=68, emp=69):
record.message_post(
@@ -484,9 +507,9 @@ class TestMailComplexPerformance(BaseMailPerformance):
@users('__system__', 'emp')
@warmup
def test_complex_message_post_template(self):
self.umbrella.message_subscribe(self.user_portal.partner_id.ids)
record = self.umbrella.with_user(self.env.user)
template_id = self.env.ref('test_mail.mail_test_tpl').id
self.container.message_subscribe(self.user_portal.partner_id.ids)
record = self.container.with_user(self.env.user)
template_id = self.env.ref('test_mail.mail_test_container_tpl').id
with self.assertQueryCount(__system__=78, emp=80):
record.message_post_with_template(template_id, message_type='comment', composition_mode='comment')
@@ -500,11 +523,11 @@ class TestMailComplexPerformance(BaseMailPerformance):
def test_complex_message_subscribe(self):
pids = self.partners.ids
cids = self.channel.ids
subtypes = self.env.ref('mail.mt_comment') | self.env.ref('test_mail.st_mail_test_full_umbrella_upd')
subtypes = self.env.ref('mail.mt_comment') | self.env.ref('test_mail.st_mail_test_ticket_container_upd')
subtype_ids = subtypes.ids
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': False,
'container_id': False,
'customer_id': False,
'user_id': self.user_portal.id,
})
@@ -551,9 +574,9 @@ class TestMailComplexPerformance(BaseMailPerformance):
@warmup
def test_complex_tracking_assignation(self):
""" Assignation performance test on already-created record """
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': self.umbrella.id,
'container_id': self.container.id,
'customer_id': self.customer.id,
'user_id': self.env.uid,
})
@@ -566,7 +589,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('mail.mt_note'))
self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.env['res.partner'])
# creation message
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.partners)
self.assertEqual(len(rec1.message_ids), 2)
@@ -575,14 +598,14 @@ class TestMailComplexPerformance(BaseMailPerformance):
@warmup
def test_complex_tracking_subscription_create(self):
""" Creation performance test involving auto subscription, assignation, tracking with subtype and template send. """
umbrella_id = self.umbrella.id
container_id = self.container.id
customer_id = self.customer.id
user_id = self.user_portal.id
with self.assertQueryCount(__system__=116, emp=117):
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': umbrella_id,
'container_id': container_id,
'customer_id': customer_id,
'user_id': user_id,
})
@@ -590,7 +613,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
rec1 = rec.with_context(active_test=False) # to see inactive records
self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
# creation message
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
self.assertEqual(len(rec1.message_ids), 1)
@@ -599,9 +622,9 @@ class TestMailComplexPerformance(BaseMailPerformance):
@warmup
def test_complex_tracking_subscription_subtype(self):
""" Write performance test involving auto subscription, tracking with subtype """
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': False,
'container_id': False,
'customer_id': False,
'user_id': self.user_portal.id,
})
@@ -611,12 +634,12 @@ class TestMailComplexPerformance(BaseMailPerformance):
with self.assertQueryCount(__system__=83, emp=83):
rec.write({
'name': 'Test2',
'umbrella_id': self.umbrella.id,
'container_id': self.container.id,
})
self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
# write tracking message
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
# creation message
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('mail.mt_note'))
@@ -628,17 +651,17 @@ class TestMailComplexPerformance(BaseMailPerformance):
@warmup
def test_complex_tracking_subscription_write(self):
""" Write performance test involving auto subscription, tracking with subtype and template send """
umbrella_id = self.umbrella.id
container_id = self.container.id
customer_id = self.customer.id
umbrella2 = self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({
'name': 'Test Umbrella 2',
container2 = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
'name': 'Test Container 2',
'customer_id': False,
'alias_name': False,
})
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': umbrella2.id,
'container_id': container2.id,
'customer_id': False,
'user_id': self.user_portal.id,
})
@@ -648,16 +671,16 @@ class TestMailComplexPerformance(BaseMailPerformance):
with self.assertQueryCount(__system__=91, emp=91):
rec.write({
'name': 'Test2',
'umbrella_id': umbrella_id,
'container_id': container_id,
'customer_id': customer_id,
})
self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
# write tracking message
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[0].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id)
# creation message
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.user_portal.partner_id)
self.assertEqual(len(rec1.message_ids), 2)
@@ -668,12 +691,12 @@ class TestMailComplexPerformance(BaseMailPerformance):
""" Write performance test involving assignation, tracking with template """
customer_id = self.customer.id
self.assertTrue(self.env.registry.ready, "We need to simulate that registery is ready")
rec = self.env['mail.test.full'].create({
rec = self.env['mail.test.ticket'].create({
'name': 'Test',
'umbrella_id': self.umbrella.id,
'container_id': self.container.id,
'customer_id': False,
'user_id': self.user_portal.id,
'mail_template': self.env.ref('test_mail.mail_test_full_tracking_tpl').id,
'mail_template': self.env.ref('test_mail.mail_test_ticket_tracking_tpl').id,
})
rec1 = rec.with_context(active_test=False) # to see inactive records
self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
@@ -692,7 +715,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
self.assertEqual(rec1.message_ids[1].subtype_id, self.env.ref('mail.mt_note'))
self.assertEqual(rec1.message_ids[1].notified_partner_ids, self.env['res.partner'])
# creation message
self.assertEqual(rec1.message_ids[2].subtype_id, self.env.ref('test_mail.st_mail_test_full_umbrella_upd'))
self.assertEqual(rec1.message_ids[2].subtype_id, self.env.ref('test_mail.st_mail_test_ticket_container_upd'))
self.assertEqual(rec1.message_ids[2].notified_partner_ids, self.partners | self.user_portal.partner_id)
self.assertEqual(len(rec1.message_ids), 3)
@@ -706,16 +729,16 @@ class TestMailComplexPerformance(BaseMailPerformance):
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.
"""
name_field = self.env['ir.model.fields']._get(self.umbrella._name, 'name')
customer_id_field = self.env['ir.model.fields']._get(self.umbrella._name, 'customer_id')
name_field = self.env['ir.model.fields']._get(self.container._name, 'name')
customer_id_field = self.env['ir.model.fields']._get(self.container._name, 'customer_id')
messages = self.env['mail.message'].sudo().create([{
'subject': 'Test 0',
'body': '<p>Test 0</p>',
'author_id': self.partners[0].id,
'email_from': self.partners[0].email,
'model': 'mail.test',
'res_id': self.umbrella.id,
'model': 'mail.test.container',
'res_id': self.container.id,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'),
'attachment_ids': [
(0, 0, {
@@ -758,8 +781,8 @@ class TestMailComplexPerformance(BaseMailPerformance):
'body': '<p>Test 1</p>',
'author_id': self.partners[1].id,
'email_from': self.partners[1].email,
'model': 'mail.test',
'res_id': self.umbrella.id,
'model': 'mail.test.container',
'res_id': self.container.id,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'attachment_ids': [
(0, 0, {
@@ -821,7 +844,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance):
'name': 'customer',
'email': 'customer@example.com',
})
self.record = self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({
self.record = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({
'name': 'Test record',
'customer_id': self.customer.id,
'alias_name': 'test-alias',
@@ -949,27 +972,3 @@ class TestMailHeavyPerformancePost(BaseMailPerformance):
self.assertEqual(self.attachements.mapped('res_model'), [record._name for i in range(3)])
self.assertEqual(self.attachements.mapped('res_id'), [record.id for i in range(3)])
# self.assertEqual(record.message_ids[0].notified_partner_ids, [])
@tagged('mail_performance')
class TestTrackingPerformance(BaseMailPerformance):
@users('__system__', 'demo')
@warmup
def test_tracking_multiple_fields(self):
""" Check that tracking multiple fields is scalable """
record = self.env['mail.test.tracking'].create({'name': 'Zizizatestname'})
with self.assertQueryCount(__system__=3, demo=3):
record.write({'name': 'Zizizanewtestname'})
record.flush()
with self.assertQueryCount(__system__=5, demo=5):
record.write({'field_%s' % (i): 'Tracked Char Fields %s' % (i) for i in range(3)})
record.flush()
with self.assertQueryCount(__system__=6, demo=6):
record.write({'field_%s' % (i): 'Field Without Cache %s' % (i) for i in range(3)})
record.flush()
record.write({'field_%s' % (i): 'Field With Cache %s' % (i) for i in range(3)})
record.flush()
+1
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from . import common
from . import test_odoobot
from . import test_phone_blacklist
from . import test_mass_sms
from . import test_sms_composer
@@ -29,6 +29,6 @@ class MassMailTestBlacklist(models.Model):
user_id = fields.Many2one(
'res.users', 'Responsible',
tracking=True)
umbrella_id = fields.Many2one(
'mail.test', 'Meta Umbrella Record',
container_id = fields.Many2one(
'mail.test.container', 'Meta Container Record',
tracking=True)