diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/app/bounces.py | 10 | ||||
| -rw-r--r-- | src/mailman/app/tests/test_bounces.py | 72 | ||||
| -rw-r--r-- | src/mailman/utilities/i18n.py | 29 |
3 files changed, 100 insertions, 11 deletions
diff --git a/src/mailman/app/bounces.py b/src/mailman/app/bounces.py index a95ee954b..62f24d39b 100644 --- a/src/mailman/app/bounces.py +++ b/src/mailman/app/bounces.py @@ -206,11 +206,11 @@ def send_probe(member, msg): """ mlist = getUtility(IListManager).get(member.mailing_list) text = make('probe.txt', mlist, member.preferred_language.code, - listname=mlist.fqdn_listname, - address= member.address.email, - optionsurl=member.options_url, - owneraddr=mlist.owner_address, - ) + listname=mlist.fqdn_listname, + address= member.address.email, + optionsurl=member.options_url, + owneraddr=mlist.owner_address, + ) pendable = _ProbePendable( member_id=member.member_id, message_id=msg['message-id'], diff --git a/src/mailman/app/tests/test_bounces.py b/src/mailman/app/tests/test_bounces.py index 7ef78500f..47fadeb67 100644 --- a/src/mailman/app/tests/test_bounces.py +++ b/src/mailman/app/tests/test_bounces.py @@ -25,6 +25,9 @@ __all__ = [ ] +import os +import shutil +import tempfile import unittest from zope.component import getUtility @@ -32,6 +35,8 @@ from zope.component import getUtility from mailman.app.bounces import StandardVERP, send_probe from mailman.app.lifecycle import create_list from mailman.app.membership import add_member +from mailman.config import config +from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.member import DeliveryMode from mailman.interfaces.pending import IPendings from mailman.testing.helpers import ( @@ -260,6 +265,70 @@ Message-ID: <first> +class TestSendProbeNonEnglish(unittest.TestCase): + """Test sending of the probe message to a non-English speaker.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + self._member = add_member(self._mlist, 'anne@example.com', + 'Anne Person', 'xxx', + DeliveryMode.regular, 'en') + self._msg = message_from_string("""\ +From: bouncer@example.com +To: anne@example.com +Subject: You bounced +Message-ID: <first> + +""") + # Set up the translation context. + self._template_dir = tempfile.mkdtemp() + xx_template_path = os.path.join( + self._template_dir, 't', 'xx', 'probe.txt') + os.makedirs(os.path.dirname(xx_template_path)) + config.push('xx template dir', """\ + [paths.testing] + template_dir: {0}/t + var_dir: {0}/v + """.format(self._template_dir)) + language_manager = getUtility(ILanguageManager) + language_manager.add('xx', 'utf-8', 'Freedonia') + self._member.preferences.preferred_language = 'xx' + with open(xx_template_path, 'w') as fp: + print >> fp, """\ +blah blah blah +$listname +$address +$optionsurl +$owneraddr +""" + + def tearDown(self): + config.pop('xx template dir') + shutil.rmtree(self._template_dir) + + def test_subject_with_member_nonenglish(self): + # Test that members with non-English preferred language get a Subject + # header in the expected language. + send_probe(self._member, self._msg) + message = get_queue_messages('virgin')[0].msg + self.assertEqual( + message['Subject'], + '=?utf-8?q?ailing-may_ist-lay_Test_obe-pray_essage-may?=') + + def test_probe_notice_with_member_nonenglish(self): + # Test that a member with non-English preferred language gets the + # probe message in their language. + send_probe(self._member, self._msg) + message = get_queue_messages('virgin')[0].msg + notice = message.get_payload(0).get_payload() + self.assertEqual(notice, """\ +blah blah blah test@example.com anne@example.com +http://example.com/anne@example.com test-owner@example.com""") + + + class TestProbe(unittest.TestCase): """Test VERP probing.""" @@ -268,7 +337,7 @@ class TestProbe(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') - + @@ -276,5 +345,6 @@ def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestProbe)) suite.addTest(unittest.makeSuite(TestSendProbe)) + suite.addTest(unittest.makeSuite(TestSendProbeNonEnglish)) suite.addTest(unittest.makeSuite(TestVERP)) return suite diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py index 000e74ac6..cdc25530d 100644 --- a/src/mailman/utilities/i18n.py +++ b/src/mailman/utilities/i18n.py @@ -28,23 +28,28 @@ __all__ = [ import os +import sys import errno from itertools import product from mailman.config import config from mailman.core.constants import system_preferences +from mailman.core.errors import MailmanException from mailman.core.i18n import _ from mailman.utilities.string import expand, wrap as wrap_text -class TemplateNotFoundError(Exception): +class TemplateNotFoundError(MailmanException): """The named template was not found.""" def __init__(self, template_file): self.template_file = template_file + def __str__(self): + return self.template_file + def _search(template_file, mailing_list=None, language=None): @@ -70,7 +75,7 @@ def _search(template_file, mailing_list=None, language=None): -def find(template_file, mailing_list=None, language=None): +def find(template_file, mailing_list=None, language=None, _trace=False): """Locate an i18n template file. When something in Mailman needs a template file, it always asks for the @@ -140,6 +145,9 @@ def find(template_file, mailing_list=None, language=None): :type mailing_list: `IMailingList` :param language: Optional language code, which influences the search. :type language: string + :param _trace: Enable printing of debugging information during + template search. + :type _trace: bool :return: A tuple of the file system path to the first matching template, and an open file object allowing reading of the file. :rtype: (string, file) @@ -148,16 +156,24 @@ def find(template_file, mailing_list=None, language=None): raw_search_order = _search(template_file, mailing_list, language) for path in raw_search_order: try: + if _trace: + print >> sys.stderr, '@@@', path, fp = open(path) except IOError as error: - if error.errno != errno.ENOENT: + if error.errno == errno.ENOENT: + if _trace: + print >> sys.stderr, 'MISSING' + else: raise else: + if _trace: + print >> sys.stderr, 'FOUND:', path return path, fp raise TemplateNotFoundError(template_file) -def make(template_file, mailing_list=None, language=None, wrap=True, **kw): +def make(template_file, mailing_list=None, language=None, wrap=True, + _trace=False, **kw): """Locate and 'make' a template file. The template file is located as with `find()`, and the resulting text is @@ -173,12 +189,15 @@ def make(template_file, mailing_list=None, language=None, wrap=True, **kw): :type language: string :param wrap: When True, wrap the text. :type wrap: bool + :param _trace: Passed through to ``find()``, this enables printing of + debugging information during template search. + :type _trace: bool :param **kw: Keyword arguments for template interpolation. :return: The interpolated text. :rtype: string :raises TemplateNotFoundError: when the template could not be found. """ - path, fp = find(template_file, mailing_list, language) + path, fp = find(template_file, mailing_list, language, _trace) try: # XXX Removing the trailing newline is a hack carried over from # Mailman 2. The (stripped) template text is then passed through the |
