diff options
| -rw-r--r-- | src/mailman/app/inject.py (renamed from src/mailman/inject.py) | 26 | ||||
| -rw-r--r-- | src/mailman/app/tests/test_inject.py | 219 | ||||
| -rw-r--r-- | src/mailman/commands/cli_inject.py | 2 | ||||
| -rw-r--r-- | src/mailman/runners/docs/command.txt | 2 | ||||
| -rw-r--r-- | src/mailman/runners/docs/incoming.txt | 2 |
5 files changed, 235 insertions, 16 deletions
diff --git a/src/mailman/inject.py b/src/mailman/app/inject.py index 9292b62dd..edf4e0807 100644 --- a/src/mailman/inject.py +++ b/src/mailman/app/inject.py @@ -26,8 +26,6 @@ __all__ = [ ] -# pylint doesn't understand absolute_import -# pylint: disable-msg=E0611,W0403 from email import message_from_string from email.utils import formatdate, make_msgid @@ -36,16 +34,16 @@ from mailman.email.message import Message -def inject_message(mlist, msg, recips=None, switchboard=None, **kws): +def inject_message(mlist, msg, recipients=None, switchboard=None, **kws): """Inject a message into a queue. :param mlist: The mailing list this message is destined for. :type mlist: IMailingList :param msg: The Message object to inject. :type msg: a Message object - :param recips: Optional set of recipients to put into the message's + :param recipients: Optional set of recipients to put into the message's metadata. - :type recips: sequence of strings + :type recipients: sequence of strings :param switchboard: Optional name of switchboard to inject this message into. If not given, the 'in' switchboard is used. :type switchboard: string @@ -66,27 +64,29 @@ def inject_message(mlist, msg, recips=None, switchboard=None, **kws): original_size=getattr(msg, 'original_size', len(msg.as_string())), ) msgdata.update(kws) - if recips is not None: - msgdata['recipients'] = recips + if recipients is not None: + msgdata['recipients'] = recipients config.switchboards[switchboard].enqueue(msg, **msgdata) -def inject_text(mlist, text, recips=None, switchboard=None): - """Inject a message into a queue. +def inject_text(mlist, text, recipients=None, switchboard=None, **kws): + """Turn text into a message and inject that into a queue. :param mlist: The mailing list this message is destined for. :type mlist: IMailingList :param text: The text of the message to inject. This will be parsed into a Message object. - :type text: string - :param recips: Optional set of recipients to put into the message's + :type text: byte string + :param recipients: Optional set of recipients to put into the message's metadata. - :type recips: sequence of strings + :type recipients: sequence of strings :param switchboard: Optional name of switchboard to inject this message into. If not given, the 'in' switchboard is used. :type switchboard: string + :param kws: Additional values for the message metadata. + :type kws: dictionary """ message = message_from_string(text, Message) message.original_size = len(text) - inject_message(mlist, message, recips, switchboard) + inject_message(mlist, message, recipients, switchboard, **kws) diff --git a/src/mailman/app/tests/test_inject.py b/src/mailman/app/tests/test_inject.py new file mode 100644 index 000000000..b395eb989 --- /dev/null +++ b/src/mailman/app/tests/test_inject.py @@ -0,0 +1,219 @@ +# Copyright (C) 2011 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Testing app.inject functions.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'test_suite', + ] + + +import unittest + +from mailman.app.inject import inject_message, inject_text +from mailman.app.lifecycle import create_list +from mailman.email.message import Message +from mailman.testing.helpers import ( + get_queue_messages, + specialized_message_from_string as message_from_string) +from mailman.testing.layers import ConfigLayer + + +NL = '\n' + + + +class TestInjectMessage(unittest.TestCase): + """Test message injection.""" + + layer = ConfigLayer + + def setUp(self): + # Python 2.7 has a better equality tester for message texts. + self.eq = getattr(self, 'assertMultiLineEqual', self.assertEqual) + self.mlist = create_list('test@example.com') + self.msg = message_from_string("""\ +From: anne@example.com +To: test@example.com +Subject: A test message +Message-ID: <first> +Date: Tue, 14 Jun 2011 21:12:00 -0400 + +Nothing. +""") + # For Python 2.7. + self.maxDiff = None + + def test_inject_message(self): + # Test basic inject_message() call. + inject_message(self.mlist, self.msg) + items = get_queue_messages('in') + self.assertEqual(len(items), 1) + self.eq(items[0].msg.as_string(), self.msg.as_string()) + self.assertEqual(items[0].msgdata['listname'], 'test@example.com') + self.assertEqual(items[0].msgdata['original_size'], + len(self.msg.as_string())) + + def test_inject_message_with_recipients(self): + # Explicit recipients end up in the metadata. + recipients = ['bart@example.com', 'cris@example.com'] + inject_message(self.mlist, self.msg, recipients) + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['recipients'], recipients) + + def test_inject_message_to_queue(self): + # Explicitly use a different queue. + inject_message(self.mlist, self.msg, switchboard='virgin') + items = get_queue_messages('in') + self.assertEqual(len(items), 0) + items = get_queue_messages('virgin') + self.assertEqual(len(items), 1) + self.eq(items[0].msg.as_string(), self.msg.as_string()) + self.assertEqual(items[0].msgdata['listname'], 'test@example.com') + self.assertEqual(items[0].msgdata['original_size'], + len(self.msg.as_string())) + + def test_inject_message_without_message_id(self): + # inject_message() adds a Message-ID header if it's missing. + del self.msg['message-id'] + self.assertFalse('message-id' in self.msg) + inject_message(self.mlist, self.msg) + self.assertTrue('message-id' in self.msg) + items = get_queue_messages('in') + self.assertTrue('message-id' in items[0].msg) + self.assertEqual(items[0].msg['message-id'], self.msg['message-id']) + + def test_inject_message_without_date(self): + # inject_message() adds a Date header if it's missing. + del self.msg['date'] + self.assertFalse('date' in self.msg) + inject_message(self.mlist, self.msg) + self.assertTrue('date' in self.msg) + items = get_queue_messages('in') + self.assertTrue('date' in items[0].msg) + self.assertEqual(items[0].msg['date'], self.msg['date']) + + def test_inject_message_trusts_original_size_attribute(self): + # If the message object has an `original_size` attribute, this is + # copied into the metadata. + self.msg.original_size = 3 + inject_message(self.mlist, self.msg) + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['original_size'], 3) + + def test_inject_message_with_keywords(self): + # Keyword arguments are copied into the metadata. + inject_message(self.mlist, self.msg, foo='yes', bar='no') + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['foo'], 'yes') + self.assertEqual(items[0].msgdata['bar'], 'no') + + + +class TestInjectText(unittest.TestCase): + """Test text injection.""" + + layer = ConfigLayer + + def setUp(self): + # Python 2.7 has a better equality tester for message texts. + self.eq = getattr(self, 'assertMultiLineEqual', self.assertEqual) + self.mlist = create_list('test@example.com') + self.text = b"""\ +From: bart@example.com +To: test@example.com +Subject: A test message +Message-ID: <second> +Date: Tue, 14 Jun 2011 21:12:00 -0400 + +Nothing. +""" + # For Python 2.7. + self.maxDiff = None + + def _remove_line(self, header): + return NL.join(line for line in self.text.splitlines() + if not line.lower().startswith(header)) + + def test_inject_text(self): + # Test basic inject_text() call. + inject_text(self.mlist, self.text) + items = get_queue_messages('in') + self.assertEqual(len(items), 1) + self.assertTrue(isinstance(items[0].msg, Message)) + self.eq(items[0].msg.as_string(), self.text) + self.assertEqual(items[0].msgdata['listname'], 'test@example.com') + self.assertEqual(items[0].msgdata['original_size'], len(self.text)) + + def test_inject_text_with_recipients(self): + # Explicit recipients end up in the metadata. + recipients = ['bart@example.com', 'cris@example.com'] + inject_text(self.mlist, self.text, recipients) + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['recipients'], recipients) + + def test_inject_text_to_queue(self): + # Explicitly use a different queue. + inject_text(self.mlist, self.text, switchboard='virgin') + items = get_queue_messages('in') + self.assertEqual(len(items), 0) + items = get_queue_messages('virgin') + self.assertEqual(len(items), 1) + self.eq(items[0].msg.as_string(), self.text) + self.assertEqual(items[0].msgdata['listname'], 'test@example.com') + self.assertEqual(items[0].msgdata['original_size'], len(self.text)) + + def test_inject_text_without_message_id(self): + # inject_text() adds a Message-ID header if it's missing. + filtered = self._remove_line('message-id') + self.assertFalse('Message-ID' in filtered) + inject_text(self.mlist, filtered) + items = get_queue_messages('in') + self.assertTrue('message-id' in items[0].msg) + + def test_inject_text_without_date(self): + # inject_text() adds a Date header if it's missing. + filtered = self._remove_line('date') + self.assertFalse('date' in filtered) + inject_text(self.mlist, self.text) + items = get_queue_messages('in') + self.assertTrue('date' in items[0].msg) + + def test_inject_text_adds_original_size(self): + # The metadata gets an original_size attribute that is the length of + # the injected text. + inject_text(self.mlist, self.text) + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['original_size'], len(self.text)) + + def test_inject_text_with_keywords(self): + # Keyword arguments are copied into the metadata. + inject_text(self.mlist, self.text, foo='yes', bar='no') + items = get_queue_messages('in') + self.assertEqual(items[0].msgdata['foo'], 'yes') + self.assertEqual(items[0].msgdata['bar'], 'no') + + + +def test_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestInjectMessage)) + suite.addTest(unittest.makeSuite(TestInjectText)) + return suite diff --git a/src/mailman/commands/cli_inject.py b/src/mailman/commands/cli_inject.py index 431280fdf..1d019d9e0 100644 --- a/src/mailman/commands/cli_inject.py +++ b/src/mailman/commands/cli_inject.py @@ -30,9 +30,9 @@ import sys from zope.component import getUtility from zope.interface import implements +from mailman.app.inject import inject_text from mailman.config import config from mailman.core.i18n import _ -from mailman.inject import inject_text from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager diff --git a/src/mailman/runners/docs/command.txt b/src/mailman/runners/docs/command.txt index 3914069ff..f2fa86fcf 100644 --- a/src/mailman/runners/docs/command.txt +++ b/src/mailman/runners/docs/command.txt @@ -25,7 +25,7 @@ the sender. The command can be in the ``Subject`` header. ... ... """) - >>> from mailman.inject import inject_message + >>> from mailman.app.inject import inject_message >>> inject_message(mlist, msg, switchboard='command') >>> from mailman.runners.command import CommandRunner >>> from mailman.testing.helpers import make_testable_runner diff --git a/src/mailman/runners/docs/incoming.txt b/src/mailman/runners/docs/incoming.txt index b16567c44..df45d4716 100644 --- a/src/mailman/runners/docs/incoming.txt +++ b/src/mailman/runners/docs/incoming.txt @@ -54,7 +54,7 @@ While configurable, the *sender addresses* by default are those named in the Inject the message into the incoming queue, similar to the way the upstream mail server normally would. - >>> from mailman.inject import inject_message + >>> from mailman.app.inject import inject_message >>> inject_message(mlist, msg) The incoming runner runs until it is empty. |
