summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2015-10-31 20:54:26 -0400
committerBarry Warsaw2015-10-31 21:01:54 -0400
commit49fff6df2add54fa2c195ca734b00bfe9f275c5c (patch)
tree803a37e051a766d4acef865f10a9a3ec57fc73a6 /src
parent8a07200b064205a7ec330e1e2bed703acb48743b (diff)
downloadmailman-49fff6df2add54fa2c195ca734b00bfe9f275c5c.tar.gz
mailman-49fff6df2add54fa2c195ca734b00bfe9f275c5c.tar.zst
mailman-49fff6df2add54fa2c195ca734b00bfe9f275c5c.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/commands/eml_confirm.py9
-rw-r--r--src/mailman/commands/tests/test_confirm.py86
-rw-r--r--src/mailman/docs/NEWS.rst2
3 files changed, 93 insertions, 4 deletions
diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py
index ddf0db0e2..27cc8c22d 100644
--- a/src/mailman/commands/eml_confirm.py
+++ b/src/mailman/commands/eml_confirm.py
@@ -54,11 +54,16 @@ class Confirm:
tokens.add(token)
results.confirms = tokens
try:
- token, token_owner, member = IRegistrar(mlist).confirm(token)
- if token is None:
+ new_token, token_owner, member = IRegistrar(mlist).confirm(token)
+ if new_token is None:
assert token_owner is TokenOwner.no_one, token_owner
assert member is not None, member
succeeded = True
+ elif token_owner is TokenOwner.moderator:
+ # This must have been a confirm-then-moderator subscription.
+ assert new_token != token
+ assert member is None, member
+ succeeded = True
else:
assert token_owner is not TokenOwner.no_one, token_owner
assert member is None, member
diff --git a/src/mailman/commands/tests/test_confirm.py b/src/mailman/commands/tests/test_confirm.py
index e980141b0..0d12fa211 100644
--- a/src/mailman/commands/tests/test_confirm.py
+++ b/src/mailman/commands/tests/test_confirm.py
@@ -19,6 +19,7 @@
__all__ = [
'TestConfirm',
+ 'TestEmailResponses',
]
@@ -26,12 +27,14 @@ import unittest
from mailman.app.lifecycle import create_list
from mailman.commands.eml_confirm import Confirm
+from mailman.config import config
from mailman.email.message import Message
from mailman.interfaces.command import ContinueProcessing
+from mailman.interfaces.mailinglist import SubscriptionPolicy
from mailman.interfaces.registrar import IRegistrar
from mailman.interfaces.usermanager import IUserManager
-from mailman.runners.command import Results
-from mailman.testing.helpers import get_queue_messages
+from mailman.runners.command import CommandRunner, Results
+from mailman.testing.helpers import get_queue_messages, make_testable_runner
from mailman.testing.layers import ConfigLayer
from zope.component import getUtility
@@ -76,3 +79,82 @@ class TestConfirm(unittest.TestCase):
# There will be no messages in the queue.
messages = get_queue_messages('virgin')
self.assertEqual(len(messages), 0)
+
+
+class TestEmailResponses(unittest.TestCase):
+ """Test the `confirm` command through the command runner."""
+
+ layer = ConfigLayer
+
+ def setUp(self):
+ self._mlist = create_list('test@example.com')
+
+ def test_confirm_then_moderate_workflow(self):
+ # Issue #114 describes a problem when confirming the moderation email.
+ self._mlist.subscription_policy = \
+ SubscriptionPolicy.confirm_then_moderate
+ bart = getUtility(IUserManager).create_address(
+ 'bart@example.com', 'Bart Person')
+ # Clear any previously queued confirmation messages.
+ get_queue_messages('virgin')
+ self._token, token_owner, member = IRegistrar(self._mlist).register(
+ bart)
+ # There should now be one email message in the virgin queue, i.e. the
+ # confirmation message sent to Bart.
+ items = get_queue_messages('virgin')
+ self.assertEqual(len(items), 1)
+ msg = items[0].msg
+ # Confirmations come first, so this one goes to the subscriber.
+ self.assertEqual(msg['to'], 'bart@example.com')
+ confirm, token = str(msg['subject']).split()
+ self.assertEqual(confirm, 'confirm')
+ self.assertEqual(token, self._token)
+ # Craft a confirmation response with the expected tokens.
+ user_response = Message()
+ user_response['From'] = 'bart@example.com'
+ user_response['To'] = 'test-confirm+{}@example.com'.format(token)
+ user_response['Subject'] = 'Re: confirm {}'.format(token)
+ user_response.set_payload('')
+ # Process the message through the command runner.
+ config.switchboards['command'].enqueue(
+ user_response, listid='test.example.com')
+ make_testable_runner(CommandRunner, 'command').run()
+ # There are now two messages in the virgin queue. One is going to the
+ # subscriber containing the results of their confirmation message, and
+ # the other is to the moderators informing them that they need to
+ # handle the moderation queue.
+ items = get_queue_messages('virgin')
+ self.assertEqual(len(items), 2)
+ if items[0].msg['to'] == 'bart@example.com':
+ results = items[0].msg
+ moderator_msg = items[1].msg
+ else:
+ results = items[1].msg
+ moderator_msg = items[0].msg
+ # Check the moderator message first.
+ self.assertEqual(moderator_msg['to'], 'test-owner@example.com')
+ self.assertEqual(
+ moderator_msg['subject'],
+ 'New subscription request to Test from bart@example.com')
+ lines = moderator_msg.get_payload().splitlines()
+ self.assertEqual(
+ lines[-2].strip(),
+ 'For: Bart Person <bart@example.com>')
+ self.assertEqual(lines[-1].strip(), 'List: test@example.com')
+ # Now check the results message.
+ self.assertEqual(
+ str(results['subject']), 'The results of your email commands')
+ self.assertMultiLineEqual(results.get_payload(), """\
+The results of your email command are provided below.
+
+- Original message details:
+From: bart@example.com
+Subject: Re: confirm {}
+Date: n/a
+Message-ID: n/a
+
+- Results:
+Confirmed
+
+- Done.
+""".format(token))
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst
index adcc40b37..926466a20 100644
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -43,6 +43,8 @@ Bugs
* Collapse multiple ``Re:`` in Subject headers. Given by Mark Sapiro.
(Closes: #147)
* Added Trove classifiers to setup.py. (Closes: #152)
+ * Fix the processing of subscription confirmation messages when the mailing
+ list is set to confirm-then-moderate. (Closes #114)
Configuration
-------------