Files
odoo_source/addons/test_mail/tests/test_mail_mail.py
T
ryv-odooandThibault Delavallée ba9e79f29c [REF] mail: rename mail.notification table
RATIONALE

A bit of history. Link between a message and its recipients has been added
at first mail refactoring towards a Chatter / Discuss feature. It was done
in v7 at d64f3c9783 with the base addition of mail notification model (lots
of commits follow that one but that's the first one about notification).

Due to some people thinking that it was unnecessary to keep a model for
notification it has been removed in v9 at 88b8cd0587. Notification table was
renamed from mail_notification to mail_message_res_partner_needaction_rel.

It was proven to be a mistake even if those "some people" were warned and
model made its way back to Odoo in v10 at 72dfcae2a4 . Table name mail_message
_res_partner_needaction_rel was kept to ease migration and backward
compatibility.

It is now time to complete the circle and rename it to mail_notification.

SPECIFICATIONS

Rename ``mail_message_res_partner_needaction_rel`` to ``mail_notification`` .

RIP JEM.

Never forget.

LINKS

Task ID-2477444
Prepares Task ID-2377974 (trace management cleaning task)
Prepares Task ID-2070632 (channel members main task)
Prepares Task ID-2419762 (channel members followup task)
COM PR odoo/odoo#67382
UPG PR odoo/upgrade#2245

Co-Authored-By: Rémy Voet <ryv@odoo.com>
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
2021-03-05 15:20:53 +00:00

97 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import psycopg2
from odoo import api
from odoo.addons.base.models.ir_mail_server import MailDeliveryException
from odoo.addons.test_mail.tests.common import TestMailCommon
from odoo.tests import common
from odoo.tools import mute_logger
class TestMailMail(TestMailCommon):
@mute_logger('odoo.addons.mail.models.mail_mail')
def test_mail_message_notify_from_mail_mail(self):
# Due ot post-commit hooks, store send emails in every step
mail = self.env['mail.mail'].sudo().create({
'body_html': '<p>Test</p>',
'email_to': 'test@example.com',
'partner_ids': [(4, self.user_employee.partner_id.id)]
})
with self.mock_mail_gateway():
mail.send()
self.assertSentEmail(mail.env.user.partner_id, ['test@example.com'])
self.assertEqual(len(self._mails), 1)
class TestMailMailRace(common.TransactionCase):
@mute_logger('odoo.addons.mail.models.mail_mail')
def test_mail_bounce_during_send(self):
self.partner = self.env['res.partner'].create({
'name': 'Ernest Partner',
})
# we need to simulate a mail sent by the cron task, first create mail, message and notification by hand
mail = self.env['mail.mail'].sudo().create({
'body_html': '<p>Test</p>',
'notification': True,
'state': 'outgoing',
'recipient_ids': [(4, self.partner.id)]
})
message = self.env['mail.message'].create({
'subject': 'S',
'body': 'B',
'subtype_id': self.ref('mail.mt_comment'),
'notification_ids': [(0, 0, {
'res_partner_id': self.partner.id,
'mail_id': mail.id,
'notification_type': 'email',
'is_read': True,
'notification_status': 'ready',
})],
})
notif = self.env['mail.notification'].search([('res_partner_id', '=', self.partner.id)])
# we need to commit transaction or cr will keep the lock on notif
self.cr.commit()
# patch send_email in order to create a concurent update and check the notif is already locked by _send()
this = self # coding in javascript ruinned my life
bounce_deferred = []
@api.model
def send_email(self, message, *args, **kwargs):
with this.registry.cursor() as cr, mute_logger('odoo.sql_db'):
try:
# try ro aquire lock (no wait) on notification (should fail)
cr.execute("SELECT notification_status FROM mail_notification WHERE id = %s FOR UPDATE NOWAIT", [notif.id])
except psycopg2.OperationalError:
# record already locked by send, all good
bounce_deferred.append(True)
else:
# this should trigger psycopg2.extensions.TransactionRollbackError in send().
# Only here to simulate the initial use case
# If the record is lock, this line would create a deadlock since we are in the same thread
# In practice, the update will wait the end of the send() transaction and set the notif as bounce, as expeced
cr.execute("UPDATE mail_notification SET notification_status='bounce' WHERE id = %s", [notif.id])
return message['Message-Id']
self.env['ir.mail_server']._patch_method('send_email', send_email)
mail.send()
self.assertTrue(bounce_deferred, "The bounce should have been deferred")
self.assertEqual(notif.notification_status, 'sent')
# some cleaning since we commited the cr
self.env['ir.mail_server']._revert_method('send_email')
notif.unlink()
message.unlink()
mail.unlink()
self.partner.unlink()
self.env.cr.commit()
# because we committed the cursor, the savepoint of the test method is
# gone, and this would break TransactionCase cleanups
self.cr.execute('SAVEPOINT test_%d' % self._savepoint_id)