Add send_message methods to sendmail

Closes #13048
This commit is contained in:
Cédric Krier committed 2024-02-21 21:38:53 +01:00
1 parent 2ae89396c3
commit 3cc0bb6c15
22 files changed
+150 -117

No files matched your search

+7 -8
View File
@@ -8,7 +8,7 @@ from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval
from trytond.report import get_email
from trytond.sendmail import SMTPDataManager, sendmail_transactional
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools.email_ import convert_ascii_email, set_from_header
from trytond.transaction import Transaction
from trytond.wizard import StateTransition
@@ -143,15 +143,14 @@ class Dunning(metaclass=PoolMeta):
languages.add(lang)
msg, title = self._email(from_, to, cc, bcc, languages)
to_addrs = [e for _, e in getaddresses(to + cc + bcc)]
addr_fields = filter(None, (msg['To'], msg['Cc'], msg['Bcc']))
to_addrs = [e for _, e in getaddresses(addr_fields)]
if to_addrs:
if not pool.test:
sendmail_transactional(
from_, to_addrs, msg, datamanager=datamanager)
send_message_transactional(msg, datamanager=datamanager)
return Email(
recipients=', '.join(to),
recipients_secondary=', '.join(cc),
recipients_hidden=', '.join(bcc),
recipients=msg['To'],
recipients_secondary=msg['Cc'],
recipients_hidden=msg['Bcc'],
addresses=[{'address': a} for a in to_addrs],
subject=title,
resource=self,
@@ -6,13 +6,22 @@ Imports::
>>> import datetime
>>> from decimal import Decimal
>>> from unittest.mock import patch
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.account_dunning_email import account
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Patch send_message_transactional::
>>> smtp_calls = patch.object(
... account, 'send_message_transactional').start()
>>> manager = patch.object(
... account, 'SMTPDataManager').start()
Activate modules::
>>> config = activate_modules('account_dunning_email')
+2 -2
View File
@@ -26,7 +26,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, TimeDelta
from trytond.report import Report, get_email
from trytond.rpc import RPC
from trytond.sendmail import sendmail_transactional
from trytond.sendmail import send_message_transactional
from trytond.tools import sql_pairing
from trytond.tools.email_ import set_from_header
from trytond.transaction import Transaction
@@ -391,7 +391,7 @@ class Payment(StripeCustomerMethodMixin, CheckoutMixin, metaclass=PoolMeta):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = ','.join(emails)
msg['Subject'] = title
sendmail_transactional(from_cfg, emails, msg)
send_message_transactional(msg)
def _emails_checkout(self):
emails = []
@@ -37,7 +37,7 @@ from trytond.model import (
from trytond.pool import Pool
from trytond.pyson import Eval, If, PYSONDecoder, TimeDelta
from trytond.report import Report
from trytond.sendmail import SMTPDataManager, sendmail_transactional
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.tools.email_ import convert_ascii_email, set_from_header
from trytond.transaction import Transaction
@@ -741,11 +741,12 @@ class Activity(
to_addrs = [convert_ascii_email(a) for _, a in getaddresses([str(to)])]
if to_addrs:
sendmail_transactional(
from_, to_addrs, msg, datamanager=smtpd_datamanager)
send_message_transactional(msg, datamanager=smtpd_datamanager)
email = Email(
recipients=to,
recipients=msg['To'],
recipients_secondary=msg['Cc'],
recipients_hidden=msg['Bcc'],
addresses=[{'address': a} for a in to_addrs],
subject=title,
resource=record.record,
@@ -14,10 +14,10 @@ Imports::
... activate_modules, assertEqual, assertIn, assertTrue)
>>> from trytond.tools import file_open
Patch sendmail_transactional::
Patch send_message_transactional::
>>> smtp_calls = patch.object(
... marketing_automation, 'sendmail_transactional').start()
... marketing_automation, 'send_message_transactional').start()
>>> manager = patch.object(
... marketing_automation, 'SMTPDataManager').start()
@@ -149,10 +149,9 @@ Check email sent::
>>> smtp_calls.call_count
1
>>> from_, to, msg = smtp_calls.call_args[0]
>>> msg, = smtp_calls.call_args[0]
>>> smtp_calls.reset_mock()
>>> msg = msg.get_body().get_content()
>>> assertEqual(to, [contact.value])
>>> assertEqual(re.search(r'Hello, (.*)!', msg).group(1), party.name)
>>> open_url.shortened_url in msg
True
@@ -12,10 +12,10 @@ Imports::
>>> from trytond.tests.tools import activate_modules, assertEqual
>>> from trytond.tools import file_open
Patch sendmail_transactional::
Patch send_message_transactional::
>>> smtp_calls = patch.object(
... marketing_automation, 'sendmail_transactional').start()
... marketing_automation, 'send_message_transactional').start()
>>> manager = patch.object(
... marketing_automation, 'SMTPDataManager').start()
+5 -11
View File
@@ -5,7 +5,6 @@ import time
from collections import defaultdict
from email.headerregistry import Address
from email.message import EmailMessage
from email.utils import getaddresses
from functools import lru_cache, partial
from urllib.parse import (
parse_qs, parse_qsl, urlencode, urljoin, urlsplit, urlunsplit)
@@ -28,11 +27,10 @@ from trytond.model import (
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.report import Report, get_email
from trytond.sendmail import SMTPDataManager, sendmail_transactional
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools.email_ import (
EmailNotValidError, convert_ascii_email, normalize_email, set_from_header,
validate_email)
EmailNotValidError, normalize_email, set_from_header, validate_email)
from trytond.transaction import Transaction, inactive_records
from trytond.url import http_host
from trytond.wizard import Button, StateTransition, StateView, Wizard
@@ -317,8 +315,7 @@ class EmailList(DeactivableMixin, ModelSQL, ModelView):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = record.email
msg['Subject'] = title
sendmail_transactional(
from_cfg, [convert_ascii_email(record.email)], msg)
send_message_transactional(msg)
def request_unsubscribe(self, email, from_=None):
pool = Pool()
@@ -343,8 +340,7 @@ class EmailList(DeactivableMixin, ModelSQL, ModelView):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = record.email
msg['Subject'] = title
sendmail_transactional(
from_cfg, [convert_ascii_email(record.email)], msg)
send_message_transactional(msg)
class Message(Workflow, ModelSQL, ModelView):
@@ -522,9 +518,7 @@ class Message(Workflow, ModelSQL, ModelView):
content_text = converter.handle(content)
msg.add_alternative(content_text, subtype='plain')
sendmail_transactional(
from_cfg, getaddresses([str(to)]), msg,
datamanager=smtpd_datamanager)
send_message_transactional(msg, datamanager=smtpd_datamanager)
if not emails:
cls.sent(messages)
+9 -8
View File
@@ -53,9 +53,10 @@ class MarketingEmailTestCase(ModuleTestCase):
email_list.save()
with patch.object(
marketing_module, 'sendmail_transactional') as sendmail:
marketing_module,
'send_message_transactional') as send_message:
email_list.request_subscribe('user@example.com')
sendmail.assert_called_once_with(FROM, ['user@example.com'], ANY)
send_message.assert_called_once()
with inactive_records():
email, = Email.search([
@@ -98,9 +99,10 @@ class MarketingEmailTestCase(ModuleTestCase):
self.assertTrue(email.active)
with patch.object(
marketing_module, 'sendmail_transactional') as sendmail:
marketing_module,
'send_message_transactional') as send_message:
email_list.request_unsubscribe('user@example.com')
sendmail.assert_called_once_with(FROM, ['user@example.com'], ANY)
send_message.assert_called_once()
self.assertEqual(
email.get_email_unsubscribe_url(),
@@ -142,13 +144,12 @@ class MarketingEmailTestCase(ModuleTestCase):
with patch.object(
marketing_module,
'sendmail_transactional') as sendmail:
'send_message_transactional') as send_message:
smtpd_datamanager = Mock()
Message.process(smtpd_datamanager=smtpd_datamanager)
sendmail.assert_called_once_with(
FROM, [('', 'user@example.com')], ANY,
datamanager=smtpd_datamanager)
send_message.assert_called_once_with(
ANY, datamanager=smtpd_datamanager)
urls = ShortenedURL.search([
('record', '=', str(message)),
])
+16 -14
View File
@@ -12,8 +12,8 @@ from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Eval, TimeDelta
from trytond.report import get_email
from trytond.sendmail import SMTPDataManager, sendmail_transactional
from trytond.tools.email_ import convert_ascii_email, set_from_header
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools.email_ import set_from_header
from trytond.transaction import Transaction
from .exceptions import TemplateError
@@ -171,9 +171,12 @@ class Email(ModelSQL, ModelView):
# TODO order languages to get default as last one for title
msg, title = get_email(self.content, record, languages)
language = list(languages)[-1]
if languages:
language = list(languages)[-1].code
else:
language = None
from_ = sender
with Transaction().set_context(language=language.code):
with Transaction().set_context(language=language):
notification = self.__class__(self.id)
if notification.from_:
from_ = notification.from_
@@ -184,7 +187,7 @@ class Email(ModelSQL, ModelView):
if self.attachments:
for report in self.attachments:
name, data = Attachment.get(report, record, language.code)
name, data = Attachment.get(report, record, language)
ctype, _ = mimetypes.guess_type(name)
if not ctype:
ctype = 'application/octet-stream'
@@ -198,6 +201,7 @@ class Email(ModelSQL, ModelView):
set_from_header(msg, sender, from_)
msg['To'] = [Address(n, addr_spec=a) for n, a in getaddresses(to)]
msg['Cc'] = [Address(n, addr_spec=a) for n, a in getaddresses(cc)]
msg['Bcc'] = [Address(n, addr_spec=a) for n, a in getaddresses(bcc)]
msg['Subject'] = title
msg['Auto-Submitted'] = 'auto-generated'
return msg, title
@@ -239,17 +243,15 @@ class Email(ModelSQL, ModelView):
cc, cc_languages = self._get_cc(record)
bcc, bcc_languages = self._get_bcc(record)
languages = to_languages | cc_languages | bcc_languages
to_addrs = [
convert_ascii_email(e) for _, e in getaddresses(to + cc + bcc)]
msg, title = self.get_email(record, from_, to, cc, bcc, languages)
to_addrs = [e for _, e in getaddresses(
filter(None, (msg['To'], msg['Cc'], msg['Bcc'])))]
if to_addrs:
msg, title = self.get_email(
record, from_, to, cc, bcc, languages)
sendmail_transactional(
from_, to_addrs, msg, datamanager=datamanager)
send_message_transactional(msg, datamanager=datamanager)
emails.append(Email(
recipients=', '.join(to),
recipients_secondary=', '.join(cc),
recipients_hidden=', '.join(bcc),
recipients=msg['To'],
recipients_secondary=msg['Cc'],
recipients_hidden=msg['Bcc'],
addresses=[{'address': a} for a in to_addrs],
subject=title,
resource=record,
+19 -21
View File
@@ -3,7 +3,7 @@
import datetime as dt
import sys
import unittest
from unittest.mock import ANY, patch
from unittest.mock import patch
from trytond.config import config
@@ -104,14 +104,13 @@ class NotificationEmailTestCase(CompanyTestMixin, ModuleTestCase):
}])
with patch.object(
notification_module, 'sendmail_transactional') as sendmail, \
notification_module,
'send_message_transactional') as send_message, \
patch.object(notification_module, 'SMTPDataManager'):
user, = User.create([{'name': "Michael Scott", 'login': "msc"}])
self.run_tasks()
sendmail.assert_called_once_with(
FROM, ['user@example.com'], ANY,
datamanager=ANY)
_, _, msg = sendmail.call_args[0]
send_message.assert_called_once()
msg, = send_message.call_args[0]
self.assertEqual(msg['From'], FROM)
self.assertEqual(msg['Subject'], 'Notification Email')
self.assertEqual(msg['To'], 'Administrator <user@example.com>')
@@ -156,16 +155,15 @@ class NotificationEmailTestCase(CompanyTestMixin, ModuleTestCase):
}])
with patch.object(
notification_module, 'sendmail_transactional') as sendmail, \
notification_module,
'send_message_transactional') as send_message, \
patch.object(notification_module, 'SMTPDataManager'):
user, = User.create([{
'name': "Michael Scott",
'login': "msc",
'email': 'msc@example.com'}])
self.run_tasks()
sendmail.assert_called_once_with(
FROM, ['msc@example.com'], ANY,
datamanager=ANY)
send_message.assert_called_once()
email, = Email.search([])
self.assertEqual(email.recipients, 'Michael Scott <msc@example.com>')
@@ -200,14 +198,14 @@ class NotificationEmailTestCase(CompanyTestMixin, ModuleTestCase):
}])
with patch.object(
notification_module, 'sendmail_transactional') as sendmail, \
notification_module,
'send_message_transactional') as send_message, \
patch.object(notification_module, 'SMTPDataManager'):
User.create([{'name': "Michael Scott", 'login': "msc"}])
self.run_tasks(1)
sendmail.assert_not_called()
send_message.assert_not_called()
self.run_tasks()
sendmail.assert_called_once_with(
FROM, ['user@example.com'], ANY, datamanager=ANY)
send_message.assert_called_once()
@with_transaction()
def test_notification_email_attachment(self):
@@ -355,14 +353,13 @@ class NotificationEmailTestCase(CompanyTestMixin, ModuleTestCase):
}])
with patch.object(
notification_module, 'sendmail_transactional') as sendmail, \
notification_module,
'send_message_transactional') as send_message, \
patch.object(notification_module, 'SMTPDataManager'):
User.create([{'name': "Michael Scott", 'login': "msc"}])
self.run_tasks()
sendmail.assert_called_once_with(
FROM, ['fallback@example.com'], ANY,
datamanager=ANY)
_, _, msg = sendmail.call_args[0]
send_message.assert_called_once()
msg, = send_message.call_args[0]
self.assertEqual(msg['To'], 'Fallback <fallback@example.com>')
@with_transaction()
@@ -393,11 +390,12 @@ class NotificationEmailTestCase(CompanyTestMixin, ModuleTestCase):
}])
with patch.object(
notification_module, 'get_email') as get_email, \
notification_module,
'send_message_transactional') as send_message_transactional, \
patch.object(notification_module, 'SMTPDataManager'):
User.create([{'name': "Michael Scott", 'login': "msc"}])
self.run_tasks()
get_email.assert_not_called()
send_message_transactional.assert_not_called()
del ModuleTestCase
+2 -2
View File
@@ -13,7 +13,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id
from trytond.report import Report, get_email
from trytond.sendmail import sendmail_transactional
from trytond.sendmail import send_message_transactional
from trytond.tools.email_ import (
EmailNotValidError, set_from_header, validate_email)
from trytond.transaction import Transaction
@@ -198,7 +198,7 @@ class GiftCard(ModelSQL, ModelView):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = email
msg['Subject'] = title
sendmail_transactional(from_cfg, [email], msg, strict=True)
send_message_transactional(msg, strict=True)
class GiftCardReport(Report):
@@ -13,10 +13,10 @@ Imports::
>>> from trytond.modules.sale_gift_card import sale
>>> from trytond.tests.tools import activate_modules, assertEqual
Patch sendmail_transactional::
Patch send_message_transactional::
>>> smtp_calls = patch.object(
... sale, 'sendmail_transactional').start()
... sale, 'send_message_transactional').start()
Activate modules::
@@ -136,9 +136,7 @@ Check gift cards::
False
>>> smtp_calls.call_count
2
>>> from_, to, msg = smtp_calls.call_args[0]
>>> to
['customer@example.com']
>>> msg, = smtp_calls.call_args[0]
>>> card.number in msg.get_body().get_content()
True
+7 -5
View File
@@ -1,7 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from unittest.mock import ANY, patch
from unittest.mock import patch
from trytond.config import config
from trytond.modules.party.tests import PartyCheckEraseMixin
@@ -101,9 +101,10 @@ class WebUserTestCase(PartyCheckEraseMixin, ModuleTestCase):
self.assertFalse(user.email_valid)
self.assertFalse(user.email_token)
with patch.object(user_module, 'sendmail_transactional') as sendmail:
with patch.object(
user_module, 'send_message_transactional') as send_message:
User.validate_email([user])
sendmail.assert_called_once_with(FROM, ['user@example.com'], ANY)
send_message.assert_called_once()
token = user.email_token
self.assertTrue(token)
@@ -133,9 +134,10 @@ class WebUserTestCase(PartyCheckEraseMixin, ModuleTestCase):
user.save()
self.assertFalse(user.password_hash)
with patch.object(user_module, 'sendmail_transactional') as sendmail:
with patch.object(
user_module, 'send_message_transactional') as send_message:
User.reset_password([user])
sendmail.assert_called_once_with(FROM, ['user@example.com'], ANY)
send_message.assert_called_once()
token = user.reset_password_token
self.assertTrue(token)
+2 -2
View File
@@ -33,7 +33,7 @@ from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.report import Report, get_email
from trytond.res.user import CRYPT_CONTEXT, LoginAttempt
from trytond.sendmail import sendmail_transactional
from trytond.sendmail import send_message_transactional
from trytond.tools.email_ import (
EmailNotValidError, normalize_email, set_from_header, validate_email)
from trytond.transaction import Transaction, without_check_access
@@ -50,7 +50,7 @@ def _send_email(from_, users, email_func):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = user.email
msg['Subject'] = title
sendmail_transactional(from_cfg, [user.email], msg)
send_message_transactional(msg)
def _add_params(url, **params):
+1
View File
@@ -1,3 +1,4 @@
* Add send_message methods
* Store model on ir.rule.group
* Store model on ir.model.button
* Store model and field name on ir.model.field.access
+12 -1
View File
@@ -10,7 +10,7 @@ Sendmail
The required arguments are an :rfc:`5322` from-address string, a list of
:rfc:`5322` to-address strings (a bare string is treated as a list with 1
address), and an email message.
address), and an :py:class:`email.message.Message`.
The caller may pass a :class:`~trytond.transaction.Transaction` instance to
join otherwise the current one is joined.
A specific data manager can be specified otherwise the default
@@ -21,6 +21,12 @@ Sendmail
An SMTP failure is only logged without raising any exception.
.. function:: send_message_transactional(msg[, from_addr[, to_addrs[, transaction[, datamanager[, strict]]]]])
It is a convenience method for calling :func:`sendmail_transactional`.
If ``from_addr`` is ``None`` or ``to_addrs`` is ``None``, if fills those
arguments with addresses extracted from the headers of ``msg``.
.. function:: sendmail(from_addr, to_addrs, msg[, server[, strict]])
Send email message like :meth:`sendmail_transactional` but directly without
@@ -32,6 +38,11 @@ Sendmail
If strict is ``True``, an exception is raised if it is not possible to
connect to the server.
.. function:: send_message(msg[, from_addr[, to_addrs[, server[, strict]]]])
Same convenience method as :func:`send_message_transactional` but for
calling :func:`sendmail`.
.. function:: get_smtp_server([uri[, strict]])
Return a SMTP instance from `smtplib`_ using the ``uri`` or the one defined
+8 -5
View File
@@ -20,7 +20,7 @@ from trytond.pool import Pool
from trytond.pyson import Bool, Eval, PYSONDecoder
from trytond.report import Report
from trytond.rpc import RPC
from trytond.sendmail import sendmail_transactional
from trytond.sendmail import send_message_transactional
from trytond.tools import escape_wildcard
from trytond.tools.email_ import convert_ascii_email, set_from_header
from trytond.tools.string_ import StringMatcher
@@ -161,17 +161,20 @@ class Email(ResourceAccessMixin, ModelSQL, ModelView):
msg['Cc'] = ', '.join(
formataddr((n, convert_ascii_email(a)))
for n, a in getaddresses([cc]))
msg['Bcc'] = ', '.join(
formataddr((n, convert_ascii_email(a)))
for n, a in getaddresses([bcc]))
msg['Subject'] = subject
to_addrs = list(filter(None, map(
str.strip,
_get_emails(to) + _get_emails(cc) + _get_emails(bcc))))
sendmail_transactional(from_, to_addrs, msg, strict=True)
send_message_transactional(msg, strict=True)
email = cls(
recipients=to,
recipients_secondary=cc,
recipients_hidden=bcc,
recipients=msg['To'],
recipients_secondary=msg['Cc'],
recipients_hidden=msg['Bcc'],
addresses=[{'address': a} for a in to_addrs],
subject=subject,
body=body,
+2 -2
View File
@@ -51,7 +51,7 @@ from trytond.pool import Pool
from trytond.pyson import Bool, Eval, PYSONEncoder
from trytond.report import Report, get_email
from trytond.rpc import RPC
from trytond.sendmail import sendmail_transactional
from trytond.sendmail import send_message_transactional
from trytond.tools import grouped_slice
from trytond.tools.email_ import (
EmailNotValidError, normalize_email, set_from_header, validate_email)
@@ -96,7 +96,7 @@ def _send_email(from_, users, email_func):
set_from_header(msg, from_cfg, from_ or from_cfg)
msg['To'] = user.email
msg['Subject'] = title
sendmail_transactional(from_cfg, [user.email], msg)
send_message_transactional(msg)
class PasswordError(UserError):
+20 -6
View File
@@ -11,7 +11,10 @@ from urllib.parse import parse_qs, unquote_plus
from trytond.config import config, parse_uri
from trytond.transaction import Transaction
__all__ = ['sendmail_transactional', 'sendmail', 'SMTPDataManager']
__all__ = [
'sendmail_transactional', 'sendmail',
'send_message_transactional', 'send_message',
'SMTPDataManager']
logger = logging.getLogger(__name__)
retry = config.getint('email', 'retry', default=5)
@@ -19,6 +22,13 @@ retry = config.getint('email', 'retry', default=5)
def sendmail_transactional(
from_addr, to_addrs, msg, transaction=None, datamanager=None,
strict=False):
send_message_transactional(
msg, from_addr, to_addrs, transaction, datamanager, strict)
def send_message_transactional(
msg, from_addr=None, to_addrs=None, transaction=None, datamanager=None,
strict=False):
if transaction is None:
transaction = Transaction()
assert isinstance(transaction, Transaction), transaction
@@ -29,6 +39,11 @@ def sendmail_transactional(
def sendmail(from_addr, to_addrs, msg, server=None, strict=False):
return send_message(msg, from_addr, to_addrs, server, strict)
def send_message(
msg, from_addr=None, to_addrs=None, server=None, strict=False):
if server is None:
server = get_smtp_server(strict=strict)
if not server:
@@ -43,7 +58,7 @@ def sendmail(from_addr, to_addrs, msg, server=None, strict=False):
if count != retry:
time.sleep(0.02 * (retry - count))
try:
senderrs = server.sendmail(from_addr, to_addrs, msg.as_string())
senderrs = server.send_message(msg, from_addr, to_addrs)
except smtplib.SMTPServerDisconnected:
if count:
server = get_smtp_server(strict=strict)
@@ -82,8 +97,7 @@ def send_test_email(to_addrs, server=None):
msg['From'] = from_
msg['To'] = to_addrs
msg['Subject'] = 'Tryton test email'
sendmail(
config.get('email', 'from'), to_addrs, msg, server=server, strict=True)
send_message(msg, server=server, strict=True)
def get_smtp_server(uri=None, strict=False):
@@ -153,8 +167,8 @@ class SMTPDataManager(object):
def tpc_finish(self, trans):
if self._server is not None:
for from_addr, to_addrs, msg in self.queue:
new_server = sendmail(
from_addr, to_addrs, msg, server=self._server)
new_server = send_message(
msg, from_addr, to_addrs, server=self._server)
if new_server:
self._server = new_server
self._server.quit()
+5 -5
View File
@@ -17,7 +17,6 @@ except ImportError:
from dateutil.relativedelta import relativedelta
from trytond.config import config
from trytond.ir.exceptions import SequenceAffixError
from trytond.ir.lang import _replace
from trytond.pool import Pool
@@ -339,7 +338,9 @@ class IrTestCase(ModuleTestCase):
)
report.save()
with patch('trytond.ir.email_.sendmail_transactional') as sendmail:
with patch(
'trytond.ir.email_.send_message_transactional'
) as send_message:
email = Email.send(
to='"John Doe" <john@example.com>, Jane <jane@example.com>',
cc='User <user@example.com>',
@@ -359,11 +360,10 @@ class IrTestCase(ModuleTestCase):
'jane@example.com',
'user@example.com',
'me@example.com']
sendmail.assert_called_once_with(
config.get('email', 'from'), addresses, ANY, strict=True)
send_message.assert_called_once_with(ANY, strict=True)
self.assertEqual(
email.recipients,
'"John Doe" <john@example.com>, Jane <jane@example.com>')
'John Doe <john@example.com>, Jane <jane@example.com>')
self.assertEqual(email.recipients_secondary, 'User <user@example.com>')
self.assertEqual(email.recipients_hidden, 'me@example.com')
self.assertEqual(
+6 -6
View File
@@ -37,8 +37,8 @@ class SendmailTestCase(unittest.TestCase):
server = Mock()
sendmail(
'tryton@example.com', 'foo@example.com', message, server=server)
server.sendmail.assert_called_with(
'tryton@example.com', 'foo@example.com', message.as_string())
server.send_message.assert_called_with(
message, 'tryton@example.com', 'foo@example.com')
server.quit.assert_not_called()
def test_get_smtp_server(self):
@@ -97,9 +97,9 @@ class SendmailTestCase(unittest.TestCase):
transaction.commit()
server.sendmail.assert_has_calls([
call('foo@example.com', 'bar@example.com', msg1.as_string()),
call('bar@example.com', 'foo@example.com', msg2.as_string()),
server.send_message.assert_has_calls([
call(msg1, 'foo@example.com', 'bar@example.com'),
call(msg2, 'bar@example.com', 'foo@example.com'),
])
server.quit.assert_called_once_with()
self.assertFalse(datamanager.queue)
@@ -110,5 +110,5 @@ class SendmailTestCase(unittest.TestCase):
'foo@example.com', 'bar@example.com', MagicMock(Message))
transaction.rollback()
server.sendmail.assert_not_called()
server.send_message.assert_not_called()
self.assertFalse(datamanager.queue)
+5 -4
View File
@@ -4,7 +4,7 @@ import datetime
import os
import unittest
from contextlib import contextmanager
from unittest.mock import ANY, Mock, patch
from unittest.mock import Mock, patch
from trytond.config import config
from trytond.pool import Pool
@@ -151,9 +151,10 @@ class UserTestCase(unittest.TestCase):
user = self.create_user('user', '12345', email='user@example.com')
with patch.object(user_module, 'sendmail_transactional') as sendmail:
with patch.object(
user_module, 'send_message_transactional') as send_message:
User.reset_password([user], length=8)
sendmail.assert_called_once_with(FROM, ['user@example.com'], ANY)
send_message.assert_called_once()
cursor.execute(*user_table.select(
user_table.password_hash,
@@ -174,7 +175,7 @@ class UserTestCase(unittest.TestCase):
user = User(login='user', email='user@example.com')
user.save()
with patch.object(user_module, 'sendmail_transactional'):
with patch.object(user_module, 'send_message_transactional'):
User.reset_password([user], length=8)
user.password_reset_expire = (