summaryrefslogtreecommitdiff
path: root/src/mailman/model/tests/test_bounce.py
diff options
context:
space:
mode:
authorBarry Warsaw2011-05-27 19:37:13 -0400
committerBarry Warsaw2011-05-27 19:37:13 -0400
commitc2167d784734f16adfd3abdc9573fd8f8d88d12f (patch)
treeb60e0c8dc70c195c9f0f97ea900d69065741d579 /src/mailman/model/tests/test_bounce.py
parent091917126e7c58657310524882743e8391166fc3 (diff)
parent5f93d80364aea9535c14f9f22c2fd7d02b8dd78d (diff)
downloadmailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.tar.gz
mailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.tar.zst
mailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.zip
Merge bounce cleanup branch. This is a major cleansing and refactoring of the
bounce processor. Note that one thing this does not do is implement any of the policy around bounce scores. It "merely" cleans up all the crud in the BounceRunner, and all the logic around registering bounce events. This means the bounce runner can actually be enabled again. More code needs to be written to process bounces events occasionally. Details: * maybe_forward() moved to app/bounces.py, and it can now discard the message, forward it to the list administrators (moderators + owners), or site owners. See UnrecognizedBounceDisposition. * scan_message() always returns a set of addresses. * The DSN bounce detector is cleaned up. * An IBounceProcessor utility is added. * IBounceEvents are added, with database support. * bounce_unrecognized_goes_to_list_owner -> forward_unrecognized_bounces_to * bounce_processing -> process_bounces * ReopenableFileHandler.filename is exposed as a public attribute. This aids in testing. * Fix the signature of UserNotification.__init__() to be more PEP 8 compliant. * Change the OwnerNotification.__init__() signature to take a roster object instead of `tomoderators`. When the roster is None, the site owner is used instead. * Fix the default style setting; s/personalization/personalize/ * BounceMixin is gone, baby gone. * Add tests for the OutgoingRunner. * make_testable_runner() can now take a predicate object, which can change how often the runner goes through its main loop. Use this e.g. to go through only once when a message does not get dequeued. * A new LogFileMark helper for testing messages to a log file.
Diffstat (limited to 'src/mailman/model/tests/test_bounce.py')
-rw-r--r--src/mailman/model/tests/test_bounce.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/mailman/model/tests/test_bounce.py b/src/mailman/model/tests/test_bounce.py
new file mode 100644
index 000000000..a232b37fd
--- /dev/null
+++ b/src/mailman/model/tests/test_bounce.py
@@ -0,0 +1,105 @@
+# 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/>.
+
+"""Test bounce model objects."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'test_suite',
+ ]
+
+
+import unittest
+
+from datetime import datetime
+from zope.component import getUtility
+
+from mailman.app.lifecycle import create_list
+from mailman.config import config
+from mailman.interfaces.bounce import BounceContext, IBounceProcessor
+from mailman.testing.helpers import (
+ specialized_message_from_string as message_from_string)
+from mailman.testing.layers import ConfigLayer
+
+
+
+class TestBounceEvents(unittest.TestCase):
+ layer = ConfigLayer
+
+ def setUp(self):
+ self._processor = getUtility(IBounceProcessor)
+ self._mlist = create_list('test@example.com')
+ self._msg = message_from_string("""\
+From: mail-daemon@example.com
+To: test-bounces@example.com
+Message-Id: <first>
+
+""")
+
+ def test_events_iterator(self):
+ self._processor.register(self._mlist, 'anne@example.com', self._msg)
+ config.db.commit()
+ events = list(self._processor.events)
+ self.assertEqual(len(events), 1)
+ event = events[0]
+ self.assertEqual(event.list_name, 'test@example.com')
+ self.assertEqual(event.email, 'anne@example.com')
+ self.assertEqual(event.timestamp, datetime(2005, 8, 1, 7, 49, 23))
+ self.assertEqual(event.message_id, '<first>')
+ self.assertEqual(event.context, BounceContext.normal)
+ self.assertEqual(event.processed, False)
+ # The unprocessed list will be exactly the same right now.
+ unprocessed = list(self._processor.unprocessed)
+ self.assertEqual(len(unprocessed), 1)
+ event = unprocessed[0]
+ self.assertEqual(event.list_name, 'test@example.com')
+ self.assertEqual(event.email, 'anne@example.com')
+ self.assertEqual(event.timestamp, datetime(2005, 8, 1, 7, 49, 23))
+ self.assertEqual(event.message_id, '<first>')
+ self.assertEqual(event.context, BounceContext.normal)
+ self.assertEqual(event.processed, False)
+
+ def test_unprocessed_events_iterator(self):
+ self._processor.register(self._mlist, 'anne@example.com', self._msg)
+ self._processor.register(self._mlist, 'bart@example.com', self._msg)
+ config.db.commit()
+ events = list(self._processor.events)
+ self.assertEqual(len(events), 2)
+ unprocessed = list(self._processor.unprocessed)
+ # The unprocessed list will be exactly the same right now.
+ self.assertEqual(len(unprocessed), 2)
+ # Process one of the events.
+ events[0].processed = True
+ config.db.commit()
+ # Now there will be only one unprocessed event.
+ unprocessed = list(self._processor.unprocessed)
+ self.assertEqual(len(unprocessed), 1)
+ # Process the other event.
+ events[1].processed = True
+ config.db.commit()
+ # Now there will be no unprocessed events.
+ unprocessed = list(self._processor.unprocessed)
+ self.assertEqual(len(unprocessed), 0)
+
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestBounceEvents))
+ return suite