Added saving of outgoing emails as Message instances, with accompanying test.
- Legacy-Id: 17348
This commit is contained in:
parent
3227e42543
commit
fb740ff6bf
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2013-2019, All Rights Reserved
|
||||
# Copyright The IETF Trust 2013-2020, All Rights Reserved
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
@ -8,13 +8,14 @@ import datetime
|
|||
|
||||
from django.urls import reverse as urlreverse
|
||||
|
||||
from ietf.utils.test_utils import TestCase
|
||||
from ietf.utils.mail import outbox
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.message.models import Message, SendQueue
|
||||
from ietf.person.models import Person
|
||||
from ietf.group.factories import GroupFactory
|
||||
from ietf.message.models import Message, SendQueue
|
||||
from ietf.message.utils import send_scheduled_message_from_send_queue
|
||||
from ietf.person.models import Person
|
||||
from ietf.utils.mail import outbox, send_mail_text, send_mail_message, get_payload
|
||||
from ietf.utils.test_utils import TestCase
|
||||
|
||||
class MessageTests(TestCase):
|
||||
def test_message_view(self):
|
||||
|
@ -25,7 +26,7 @@ class MessageTests(TestCase):
|
|||
to="test@example.com",
|
||||
frm="nomcomchair@example.com",
|
||||
body="Hello World!",
|
||||
content_type="",
|
||||
content_type="text/plain",
|
||||
)
|
||||
msg.related_groups.add(nomcom)
|
||||
|
||||
|
@ -36,6 +37,41 @@ class MessageTests(TestCase):
|
|||
self.assertContains(r, msg.frm)
|
||||
self.assertContains(r, "Hello World!")
|
||||
|
||||
def test_capture_send_mail_text(self):
|
||||
def cmp(e1, e2):
|
||||
e1keys = set(e1.keys())
|
||||
e2keys = set(e2.keys())
|
||||
self.assertEqual(e1keys, e2keys)
|
||||
self.longMessage = True
|
||||
for k in e1keys:
|
||||
if k in ['Date', ]:
|
||||
continue
|
||||
self.assertEqual(e1.get_all(k), e2.get_all(k), "Header field: %s" % k)
|
||||
self.longMessage = False
|
||||
self.assertEqual(get_payload(e1), get_payload(e2))
|
||||
|
||||
#
|
||||
self.assertEqual(Message.objects.count(), 0)
|
||||
to = "<iesg-secretary@ietf.org>"
|
||||
subj = "Dummy subject"
|
||||
cc="cc.a@example.com, cc.b@example.com"
|
||||
body = "Dummy message text"
|
||||
bcc="bcc@example.com"
|
||||
msg1 = send_mail_text(None, to, None, subj, body, cc=cc, bcc=bcc)
|
||||
self.assertEqual(Message.objects.count(), 1)
|
||||
message = Message.objects.last()
|
||||
self.assertEqual(message.by.name, '(System)')
|
||||
self.assertEqual(message.to, to)
|
||||
self.assertEqual(message.subject, subj)
|
||||
self.assertEqual(message.body, body)
|
||||
self.assertEqual(message.cc, cc)
|
||||
self.assertEqual(message.bcc, bcc)
|
||||
self.assertEqual(message.content_type, 'text/plain')
|
||||
# Check round-trip msg --> message --> msg
|
||||
msg2 = send_mail_message(None, message)
|
||||
cmp(msg1, msg2)
|
||||
cmp(msg1, outbox[-1])
|
||||
|
||||
|
||||
class SendScheduledAnnouncementsTests(TestCase):
|
||||
def test_send_plain_announcement(self):
|
||||
|
@ -47,7 +83,7 @@ class SendScheduledAnnouncementsTests(TestCase):
|
|||
cc="cc.a@example.com, cc.b@example.com",
|
||||
bcc="bcc@example.com",
|
||||
body="Hello World!",
|
||||
content_type="",
|
||||
content_type="text/plain",
|
||||
)
|
||||
|
||||
q = SendQueue.objects.create(
|
||||
|
|
|
@ -192,10 +192,10 @@ def encode_message(txt):
|
|||
assert isinstance(txt, six.text_type)
|
||||
return MIMEText(txt.encode('utf-8'), 'plain', 'UTF-8')
|
||||
|
||||
def send_mail_text(request, to, frm, subject, txt, cc=None, extra=None, toUser=False, bcc=None, copy=True):
|
||||
def send_mail_text(request, to, frm, subject, txt, cc=None, extra=None, toUser=False, bcc=None, copy=True, save=True):
|
||||
"""Send plain text message."""
|
||||
msg = encode_message(txt)
|
||||
return send_mail_mime(request, to, frm, subject, msg, cc, extra, toUser, bcc, copy=copy)
|
||||
return send_mail_mime(request, to, frm, subject, msg, cc, extra, toUser, bcc, copy=copy, save=save)
|
||||
|
||||
def on_behalf_of(frm):
|
||||
if isinstance(frm, tuple):
|
||||
|
@ -320,6 +320,9 @@ def condition_message(to, frm, subject, msg, cc, extra):
|
|||
msg[k] = ", ".join(v)
|
||||
except Exception:
|
||||
raise
|
||||
if not msg.get('Message-ID', None):
|
||||
msg['Message-ID'] = make_msgid()
|
||||
|
||||
|
||||
def show_that_mail_was_sent(request,leadline,msg,bcc):
|
||||
if request and request.user:
|
||||
|
@ -334,11 +337,29 @@ def show_that_mail_was_sent(request,leadline,msg,bcc):
|
|||
info += "Bcc: %s\n" % bcc
|
||||
messages.info(request,info,extra_tags='preformatted',fail_silently=True)
|
||||
|
||||
def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=False, bcc=None, copy=True):
|
||||
def save_as_message(request, msg, bcc):
|
||||
by = ((request and request.user and not request.user.is_anonymous and request.user.person)
|
||||
or ietf.person.models.Person.objects.get(name="(System)"))
|
||||
headers, body = force_text(str(msg)).split('\n\n', 1)
|
||||
kwargs = {'by': by, 'body': body, 'content_type': msg.get_content_type(), 'bcc': bcc or '' }
|
||||
for (arg, field) in [
|
||||
('cc', 'Cc'),
|
||||
('frm', 'From'),
|
||||
('msgid', 'Message-ID'),
|
||||
('reply_to', 'Reply-To'),
|
||||
('subject', 'Subject'),
|
||||
('to', 'To'),
|
||||
]:
|
||||
kwargs[arg] = msg.get(field, '')
|
||||
m = ietf.message.models.Message.objects.create(**kwargs)
|
||||
log("Saved outgoing email from '%s' to %s id %s subject '%s as Message[%s]'" % (m.frm, m.to, m.msgid, m.subject, m.pk))
|
||||
return m
|
||||
|
||||
def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=False, bcc=None, copy=True, save=True):
|
||||
"""Send MIME message with content already filled in."""
|
||||
|
||||
condition_message(to, frm, subject, msg, cc, extra)
|
||||
|
||||
|
||||
# start debug server with python -m smtpd -n -c DebuggingServer localhost:2025
|
||||
# then put USING_DEBUG_EMAIL_SERVER=True and EMAIL_HOST='localhost'
|
||||
# and EMAIL_PORT=2025 in settings_local.py
|
||||
|
@ -352,16 +373,24 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=F
|
|||
if settings.SERVER_MODE == 'development':
|
||||
show_that_mail_was_sent(request,'In production, email would have been sent',msg,bcc)
|
||||
|
||||
# Maybe save in the database as a Message object
|
||||
if save:
|
||||
message = save_as_message(request, msg, bcc)
|
||||
else:
|
||||
message = None
|
||||
|
||||
if test_mode or debugging or production:
|
||||
try:
|
||||
send_smtp(msg, bcc)
|
||||
if save:
|
||||
message.sent = datetime.datetime.now()
|
||||
message.save()
|
||||
show_that_mail_was_sent(request,'Email was sent',msg,bcc)
|
||||
except smtplib.SMTPException as e:
|
||||
log_smtp_exception(e)
|
||||
build_warning_message(request, e)
|
||||
send_error_email(e)
|
||||
|
||||
show_that_mail_was_sent(request,'Email was sent',msg,bcc)
|
||||
|
||||
elif settings.SERVER_MODE == 'test':
|
||||
if toUser:
|
||||
copy_email(msg, to, toUser=True, originalBcc=bcc)
|
||||
|
@ -448,6 +477,7 @@ def send_mail_preformatted(request, preformatted, extra={}, override={}):
|
|||
def send_mail_message(request, message, extra={}):
|
||||
"""Send a Message object."""
|
||||
# note that this doesn't handle MIME messages at the moment
|
||||
assertion('isinstance(message.to, six.string_types) and isinstance(message.cc, six.string_types) and isinstance(message.bcc, six.string_types)')
|
||||
|
||||
e = extra.copy()
|
||||
if message.reply_to:
|
||||
|
@ -455,8 +485,21 @@ def send_mail_message(request, message, extra={}):
|
|||
if message.msgid:
|
||||
e['Message-ID'] = [ message.msgid, ]
|
||||
|
||||
return send_mail_text(request, message.to, message.frm, message.subject,
|
||||
message.body, cc=message.cc, bcc=message.bcc, extra=e)
|
||||
content_type = message.content_type or 'text/plain'
|
||||
if 'multipart' in content_type:
|
||||
body = ("MIME-Version: 1.0\r\nContent-Type: %s\r\n\r\n" % content_type) + message.body
|
||||
msg = message_from_string(force_str(body))
|
||||
else:
|
||||
msg = encode_message(message.body)
|
||||
|
||||
msg = send_mail_mime(request, message.to, message.frm, message.subject,
|
||||
msg, cc=message.cc, bcc=message.bcc, extra=e, save=False)
|
||||
|
||||
# msg = send_mail_text(request, message.to, message.frm, message.subject,
|
||||
# message.body, cc=message.cc, bcc=message.bcc, extra=e, save=False)
|
||||
message.sent = datetime.datetime.now()
|
||||
message.save()
|
||||
return msg
|
||||
|
||||
def exception_components(e):
|
||||
# See if it's a non-smtplib exception that we faked
|
||||
|
|
Loading…
Reference in a new issue