[FIX] mail, test_mail: ensure thread name is up to date on message

When formatting a message, a message could be with an empty or obsolete
record_name field. It's better to rely on the relation between the message and
the thread and fetch the current thread name.

task-2411715

closes odoo/odoo#63000

closes odoo/odoo#67549

X-original-commit: 51e962803d2048efeb0f7e96a9fe561ac49ee05a
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Didier (did)
2021-03-09 16:46:41 +00:00
committed by Sébastien Theys
parent 7b7483f3ed
commit c1504fb429
5 changed files with 63 additions and 4 deletions
+8
View File
@@ -6849,6 +6849,7 @@ msgstr ""
#. module: mail
#: code:addons/mail/models/mail_thread.py:0
#: code:addons/mail/static/src/components/message/message.xml:0
#, python-format
msgid "document"
msgstr ""
@@ -7076,3 +7077,10 @@ msgstr ""
#: model:ir.model.fields.selection,name:mail.selection__mail_activity_type__delay_unit__weeks
msgid "weeks"
msgstr ""
#. module: mail
#. openerp-web
#: code:addons/mail/static/src/components/message/message.xml:0
#, python-format
msgid "channel"
msgstr ""
+17
View File
@@ -3,6 +3,7 @@
import logging
import re
from collections import defaultdict
from binascii import Error as binascii_error
from operator import itemgetter
@@ -991,6 +992,12 @@ class Message(models.Model):
self.check_access_rule('read')
vals_list = self._read_format(fnames)
safari = request and request.httprequest.user_agent.browser == 'safari'
thread_ids_by_model_name = defaultdict(set)
for message in self:
if message.model and message.res_id:
thread_ids_by_model_name[message.model].add(message.res_id)
for vals in vals_list:
message_sudo = self.browse(vals['id']).sudo().with_prefetch(self.ids)
@@ -1031,11 +1038,21 @@ class Message(models.Model):
'currency_id': tracking.currency_id.id,
})
if message_sudo.model and message_sudo.res_id:
record_name = self.env[message_sudo.model] \
.browse(message_sudo.res_id) \
.sudo() \
.with_prefetch(thread_ids_by_model_name[message_sudo.model]) \
.display_name
else:
record_name = False
vals.update({
'author_id': author,
'notifications': message_sudo.notification_ids._filtered_for_web_client()._notification_format(),
'attachment_ids': attachment_ids,
'tracking_value_ids': tracking_value_ids,
'record_name': record_name,
})
return vals_list
@@ -83,10 +83,10 @@
<t t-if="threadView and message.originThread and message.originThread !== threadView.thread">
<div class="o_Message_originThread" t-att-class="{ 'o-message-selected': isSelected }">
<t t-if="message.originThread.model === 'mail.channel'">
(from <a class="o_Message_originThreadLink" t-att-href="message.originThread.url" t-on-click="_onClickOriginThread">#<t t-esc="message.originThread.name"/></a>)
(from <a class="o_Message_originThreadLink" t-att-href="message.originThread.url" t-on-click="_onClickOriginThread"><t t-if="message.originThread.name">#<t t-esc="message.originThread.name"/></t><t t-else="">channel</t></a>)
</t>
<t t-else="">
on <a class="o_Message_originThreadLink" t-att-href="message.originThread.url" t-on-click="_onClickOriginThread"><t t-esc="message.originThread.name"/></a>
on <a class="o_Message_originThreadLink" t-att-href="message.originThread.url" t-on-click="_onClickOriginThread"><t t-if="message.originThread.name"><t t-esc="message.originThread.name"/></t><t t-else="">document</t></a>
</t>
</div>
</t>
@@ -26,6 +26,40 @@ class TestMessageValues(TestMailCommon):
})
cls.Message = cls.env['mail.message'].with_user(cls.user_employee)
@mute_logger('odoo.models.unlink')
def test_mail_message_format(self):
record1 = self.env['mail.test.simple'].create({'name': 'Test1'})
message = self.env['mail.message'].create([{
'model': 'mail.test.simple',
'res_id': record1.id,
}])
res = message.message_format()
self.assertEqual(res[0].get('record_name'), 'Test1')
record1.write({"name": "Test2"})
res = message.message_format()
self.assertEqual(res[0].get('record_name'), 'Test2')
@mute_logger('odoo.models.unlink')
def test_mail_message_format_access(self):
"""
User that doesn't have access to a record should still be able to fetch
the record_name inside message_format.
"""
company_2 = self.env['res.company'].create({'name': 'Second Test Company'})
record1 = self.env['mail.test.multi.company'].create({
'name': 'Test1',
'company_id': company_2.id,
})
message = record1.message_post(body='', partner_ids=[self.user_employee.partner_id.id])
# We need to flush and invalidate the ORM cache since the record_name
# is already cached from the creation. Otherwise it will leak inside
# message_format.
message.flush()
message.invalidate_cache()
res = message.with_user(self.user_employee).message_format()
self.assertEqual(res[0].get('record_name'), 'Test1')
@mute_logger('odoo.models.unlink')
def test_mail_message_values_no_document_values(self):
msg = self.Message.create({
+2 -2
View File
@@ -838,7 +838,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
def test_message_format_group_thread_name_by_model(self):
"""Ensures the fetch of multiple thread names is grouped by model."""
records = []
for i in range(5):
for _i in range(5):
records.append(self.env['mail.test.simple'].create({'name': 'Test'}))
records.append(self.env['mail.test.track'].create({'name': 'Test'}))
@@ -854,7 +854,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
messages.flush()
messages.invalidate_cache()
with self.assertQueryCount(emp=13):
with self.assertQueryCount(emp=15):
res = messages.message_format()
self.assertEqual(len(res), 6)