This is an automated email from the ASF dual-hosted git repository. brondsem pushed a commit to branch db/8375 in repository https://gitbox.apache.org/repos/asf/allura.git
commit d32ccf8ba17a357783262a7cbbd0926f01dcc6b2 Author: Dave Brondsema <d...@brondsema.net> AuthorDate: Mon Aug 24 17:38:51 2020 -0400 [#8375] various mail formatting/encoding fixes for py3 --- Allura/allura/app.py | 2 +- Allura/allura/lib/mail_util.py | 2 +- Allura/allura/model/auth.py | 4 +++- Allura/allura/tests/functional/test_user_profile.py | 2 +- Allura/allura/tests/test_mail_util.py | 2 +- Allura/allura/tests/test_tasks.py | 21 ++++++++++----------- .../forgediscussion/tests/functional/test_forum.py | 3 +++ 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Allura/allura/app.py b/Allura/allura/app.py index ef751ef..fb59e52 100644 --- a/Allura/allura/app.py +++ b/Allura/allura/app.py @@ -736,7 +736,7 @@ class Application(object): thread_id=thd._id, post_id=message_id) else: - text = message['payload'] or '--no text body--' + text = six.ensure_text(message['payload']) or '--no text body--' post = thd.post( message_id=message_id, parent_id=parent_id, diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py index 9d61333..3c417b4 100644 --- a/Allura/allura/lib/mail_util.py +++ b/Allura/allura/lib/mail_util.py @@ -201,7 +201,7 @@ def encode_email_part(content, content_type): # switch to Quoted-Printable encoding to avoid too-long lines # we could always Quoted-Printabl, but it makes the output a little messier and less human-readable # the particular order of all these operations seems to be very important for everything to end up right - msg = MIMEText(None, content_type) + msg = MIMEText('', content_type) msg.replace_header('content-transfer-encoding', 'quoted-printable') cs = email.charset.Charset('utf-8') cs.header_encoding = email.charset.QP diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py index 10c6550..65e47dc 100644 --- a/Allura/allura/model/auth.py +++ b/Allura/allura/model/auth.py @@ -20,6 +20,7 @@ from __future__ import absolute_import import logging import calendar +import six from markupsafe import Markup from six.moves.urllib.parse import urlparse from email import header @@ -791,7 +792,8 @@ class User(MappedClass, ActivityNode, ActivityObject, SearchIndexable): def email_address_header(self): h = header.Header() - h.append('"%s" ' % self.get_pref('display_name')) + h.append('"%s"%s' % (self.get_pref('display_name'), + ' ' if six.PY2 else '')) # py2 needs explicit space for unicode/text_type cast of Header h.append('<%s>' % self.get_pref('email_address')) return h diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py index 96162ca..4583da3 100644 --- a/Allura/allura/tests/functional/test_user_profile.py +++ b/Allura/allura/tests/functional/test_user_profile.py @@ -115,7 +115,7 @@ class TestUserProfile(TestController): response = self.app.get( '/u/test-user/profile/send_message', status=200) assert 'you currently have user messages disabled' not in response - assert '<b>From:</b> "Test Admin" <test-admin@users.localhost>' in response + response.mustcontain('<b>From:</b> "Test Admin" <test-admin@users.localhost>') self.app.post('/u/test-user/profile/send_user_message', params={'subject': 'test subject', diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py index 3c107be..7391aec 100644 --- a/Allura/allura/tests/test_mail_util.py +++ b/Allura/allura/tests/test_mail_util.py @@ -210,7 +210,7 @@ Content-Type: text/html; charset="utf-8" for part in msg2['parts']: if part['payload'] is None: continue - assert isinstance(part['payload'], six.text_type) + assert isinstance(part['payload'], six.text_type), type(part['payload']) class TestHeader(object): diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py index 6c82b52..bacf6c1 100644 --- a/Allura/allura/tests/test_tasks.py +++ b/Allura/allura/tests/test_tasks.py @@ -23,6 +23,8 @@ import operator import shutil import sys import unittest + +import six from base64 import b64encode import logging import pkg_resources @@ -143,9 +145,6 @@ class TestEventTasks(unittest.TestCase): assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event4']) def test_compound_error(self): - '''test_compound_exception -- make sure our multi-exception return works - OK - ''' t = raise_exc.post() with LogCapture(level=logging.ERROR) as l, \ mock.patch.dict(tg.config, {'monq.raise_errors': False}): # match normal non-test behavior @@ -153,8 +152,8 @@ class TestEventTasks(unittest.TestCase): # l.check() would be nice, but string is too detailed to check assert_equal(l.records[0].name, 'allura.model.monq_model') msg = l.records[0].getMessage() - assert_in("AssertionError('assert 0',)", msg) - assert_in("AssertionError('assert 5',)", msg) + assert_in("AssertionError('assert 0'", msg) + assert_in("AssertionError('assert 5'", msg) assert_in(' on job <MonQTask ', msg) assert_in(' (error) P:10 allura.tests.test_tasks.raise_exc ', msg) for x in range(10): @@ -297,16 +296,16 @@ class TestMailTasks(unittest.TestCase): assert_in('Reply-To: %s' % g.noreply, body) # The address portion must not be encoded, only the name portion can be. - # Also it is apparently not necessary to have the double-quote separators present - # when the name portion is encoded. That is, the encoding below is - # just По and not "По" - assert_in('From: =?utf-8?b?0J/Qvg==?= <f...@bar.com>', body) + # Also py2 and py3 vary in handling of double-quote separators when the name portion is encoded + unquoted_cyrillic_No = '=?utf-8?b?0J/Qvg==?=' # По + quoted_cyrillic_No = '=?utf-8?b?ItCf0L4i?=' # "По" + assert ('From: {} <f...@bar.com>'.format(quoted_cyrillic_No) in body or + 'From: {} <f...@bar.com>'.format(unquoted_cyrillic_No) in body), body assert_in( 'Subject: =?utf-8?b?0J/QviDQvtC20LjQstC70ZHQvdC90YvQvCDQsdC10YDQtdCz0LDQvA==?=', body) assert_in('Content-Type: text/plain; charset="utf-8"', body) assert_in('Content-Transfer-Encoding: base64', body) - assert_in( - b64encode('Громады стройные теснятся'.encode('utf-8')), body) + assert_in(six.ensure_text(b64encode('Громады стройные теснятся'.encode('utf-8'))), body) def test_send_email_with_disabled_user(self): c.user = M.User.by_username('test-admin') diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py index 657262a..a1d2614 100644 --- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py +++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py @@ -212,12 +212,15 @@ class TestForumMessageHandling(TestController): assert_equal(FM.ForumPost.query.find().count(), 3) def test_attach(self): + # runs handle_artifact_message() with filename field self._post('testforum', 'Attachment Thread', 'This is text attachment', message_id='test.attach....@domain.net', filename='test.txt', content_type='text/plain') + # runs handle_artifact_message() where there's no post with given message_id yet self._post('testforum', 'Test Thread', b'Nothing here', message_id='test.attach....@domain.net') + # runs handle_artifact_message() where there IS a post with given message_id self._post('testforum', 'Attachment Thread', 'This is binary ¶¬¡™£¢¢•º™™¶'.encode('utf-8'), message_id='test.attach....@domain.net', content_type='text/plain')