summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2012-03-04 02:53:44 -0500
committerBarry Warsaw2012-03-04 02:53:44 -0500
commit6c8cbfc327e05b11f22e675941f320731f3c79ce (patch)
treea594634a0f824b84e2e6645db913dcb0f6fee0ac
parentfe855654a1c67fad869c3035548b6f1b51350258 (diff)
downloadmailman-6c8cbfc327e05b11f22e675941f320731f3c79ce.tar.gz
mailman-6c8cbfc327e05b11f22e675941f320731f3c79ce.tar.zst
mailman-6c8cbfc327e05b11f22e675941f320731f3c79ce.zip
-rw-r--r--src/mailman/app/notifications.py6
-rw-r--r--src/mailman/app/registrar.py8
-rw-r--r--src/mailman/commands/docs/membership.rst1
-rw-r--r--src/mailman/commands/tests/test_confirm.py83
-rw-r--r--src/mailman/docs/NEWS.rst2
-rw-r--r--src/mailman/model/docs/registration.rst1
-rw-r--r--src/mailman/model/docs/requests.rst162
-rw-r--r--src/mailman/rest/docs/configuration.rst2
-rw-r--r--src/mailman/runners/docs/command.rst61
-rw-r--r--src/mailman/runners/tests/test_confirm.py30
-rw-r--r--src/mailman/styles/default.py2
11 files changed, 248 insertions, 110 deletions
diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py
index 3c31fbd23..84561a306 100644
--- a/src/mailman/app/notifications.py
+++ b/src/mailman/app/notifications.py
@@ -77,6 +77,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''):
# Find the IMember object which is subscribed to the mailing list, because
# from there, we can get the member's options url.
member = mlist.members.get_member(address)
+ user_name = member.user.real_name
options_url = member.options_url
# Get the text from the template.
text = expand(welcome, dict(
@@ -84,7 +85,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''):
list_name=mlist.real_name,
listinfo_uri=mlist.script_url('listinfo'),
list_requests=mlist.request_address,
- user_name=member.user.real_name,
+ user_name=user_name,
user_address=address,
user_options_uri=options_url,
))
@@ -93,7 +94,8 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''):
else:
digmode = ''
msg = UserNotification(
- address, mlist.request_address,
+ formataddr((user_name, address)),
+ mlist.request_address,
_('Welcome to the "$mlist.real_name" mailing list${digmode}'),
text, language)
msg['X-No-Archive'] = 'yes'
diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py
index 448b4f375..2e6d09a41 100644
--- a/src/mailman/app/registrar.py
+++ b/src/mailman/app/registrar.py
@@ -31,6 +31,7 @@ from pkg_resources import resource_string
from zope.component import getUtility
from zope.interface import implements
+from mailman.app.notifications import send_welcome_message
from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.address import IEmailValidator
@@ -148,13 +149,18 @@ class Registrar:
pass
address.verified_on = now()
# If this registration is tied to a mailing list, subscribe the person
- # to the list right now.
+ # to the list right now, and possibly send a welcome message.
list_name = pendable.get('list_name')
if list_name is not None:
mlist = getUtility(IListManager).get(list_name)
if mlist:
member = mlist.subscribe(address, MemberRole.member)
member.preferences.delivery_mode = delivery_mode
+ if mlist.send_welcome_message:
+ send_welcome_message(mlist,
+ address.email,
+ mlist.preferred_language,
+ delivery_mode)
return True
def discard(self, token):
diff --git a/src/mailman/commands/docs/membership.rst b/src/mailman/commands/docs/membership.rst
index 7f4de8570..f9d3aacd0 100644
--- a/src/mailman/commands/docs/membership.rst
+++ b/src/mailman/commands/docs/membership.rst
@@ -33,6 +33,7 @@ No address to join
------------------
>>> mlist = create_list('alpha@example.com')
+ >>> mlist.send_welcome_message = False
When no address argument is given, the message's From address will be used.
If that's missing though, then an error is returned.
diff --git a/src/mailman/commands/tests/test_confirm.py b/src/mailman/commands/tests/test_confirm.py
new file mode 100644
index 000000000..932372d10
--- /dev/null
+++ b/src/mailman/commands/tests/test_confirm.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2012 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 the `confirm` command."""
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'TestConfirm',
+ ]
+
+
+import unittest
+
+from zope.component import getUtility
+
+from mailman.app.lifecycle import create_list
+from mailman.commands.eml_confirm import Confirm
+from mailman.email.message import Message
+from mailman.interfaces.command import ContinueProcessing
+from mailman.interfaces.registrar import IRegistrar
+from mailman.runners.command import Results
+from mailman.testing.helpers import get_queue_messages, reset_the_world
+from mailman.testing.layers import ConfigLayer
+
+
+
+class TestConfirm(unittest.TestCase):
+ """Test the `confirm` command."""
+
+ layer = ConfigLayer
+
+ def setUp(self):
+ self._mlist = create_list('test@example.com')
+ self._token = getUtility(IRegistrar).register(
+ self._mlist, 'anne@example.com', 'Anne Person')
+ self._command = Confirm()
+ # Clear the virgin queue.
+ get_queue_messages('virgin')
+
+ def tearDown(self):
+ reset_the_world()
+
+ def test_welcome_message(self):
+ # A confirmation causes a welcome message to be sent to the member, if
+ # enabled by the mailing list.
+ #
+ status = self._command.process(
+ self._mlist, Message(), {}, (self._token,), Results())
+ self.assertEqual(status, ContinueProcessing.yes)
+ # There should be one messages in the queue; the welcome message.
+ messages = get_queue_messages('virgin')
+ self.assertEqual(len(messages), 1)
+ # Grab the welcome message.
+ welcome = messages[0].msg
+ self.assertEqual(welcome['subject'],
+ 'Welcome to the "Test" mailing list')
+ self.assertEqual(welcome['to'], 'Anne Person <anne@example.com>')
+
+ def test_no_welcome_message(self):
+ # When configured not to send a welcome message, none is sent.
+ self._mlist.send_welcome_message = False
+ status = self._command.process(
+ self._mlist, Message(), {}, (self._token,), Results())
+ self.assertEqual(status, ContinueProcessing.yes)
+ # There will be no messages in the queue.
+ messages = get_queue_messages('virgin')
+ self.assertEqual(len(messages), 0)
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst
index 243d99163..331ce64a8 100644
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -70,6 +70,8 @@ Commands
`digest=` argument now accepts the following values: `no` (for regular
delivery), `mime`, or `plain`.
* Added a `help` email command.
+ * A welcome message is sent when the user confirms their subscription via
+ email.
Bug fixes
---------
diff --git a/src/mailman/model/docs/registration.rst b/src/mailman/model/docs/registration.rst
index e9228d359..5ed2503b3 100644
--- a/src/mailman/model/docs/registration.rst
+++ b/src/mailman/model/docs/registration.rst
@@ -41,6 +41,7 @@ confirmation emails can come from some place. You also need the email
address of the user who is registering.
>>> mlist = create_list('alpha@example.com')
+ >>> mlist.send_welcome_message = False
Some amount of sanity checks are performed on the email address, although
honestly, not as much as probably should be done. Still, some patently bad
diff --git a/src/mailman/model/docs/requests.rst b/src/mailman/model/docs/requests.rst
index eca161de4..31597cf3a 100644
--- a/src/mailman/model/docs/requests.rst
+++ b/src/mailman/model/docs/requests.rst
@@ -6,7 +6,7 @@ Various actions will be held for moderator approval, such as subscriptions to
closed lists, or postings by non-members. The requests database is the low
level interface to these actions requiring approval.
-Here is a helper function for printing out held requests.
+.. Here is a helper function for printing out held requests.
>>> def show_holds(requests):
... for request in requests.held_requests:
@@ -16,19 +16,6 @@ Here is a helper function for printing out held requests.
... for key in sorted(data):
... print ' {0}: {1}'.format(key, data[key])
-And another helper for displaying messages in the virgin queue.
-
- >>> virginq = config.switchboards['virgin']
- >>> def dequeue(whichq=None, expected_count=1):
- ... if whichq is None:
- ... whichq = virginq
- ... assert len(whichq.files) == expected_count, (
- ... 'Unexpected file count: %d' % len(whichq.files))
- ... filebase = whichq.files[0]
- ... qmsg, qdata = whichq.dequeue(filebase)
- ... whichq.finish(filebase)
- ... return qmsg, qdata
-
Mailing list-centric
====================
@@ -263,7 +250,8 @@ Bye bye message!
>>> moderator.handle_message(mlist, id_1, Action.discard)
>>> print requests.get_request(id_1)
None
- >>> virginq.files
+ >>> from mailman.testing.helpers import get_queue_messages
+ >>> get_queue_messages('virgin')
[]
The message can be rejected, meaning it is bounced back to the sender.
@@ -271,8 +259,10 @@ The message can be rejected, meaning it is bounced back to the sender.
>>> moderator.handle_message(mlist, id_2, Action.reject, 'Off topic')
>>> print requests.get_request(id_2)
None
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -297,7 +287,7 @@ The message can be rejected, meaning it is bounced back to the sender.
<BLANKLINE>
alist-owner@example.com
<BLANKLINE>
- >>> dump_msgdata(qdata)
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -311,9 +301,10 @@ indicates that the message has been approved.
>>> id_3 = moderator.hold_message(mlist, msg, msgdata, 'Needs approval')
>>> moderator.handle_message(mlist, id_3, Action.accept)
- >>> inq = config.switchboards['pipeline']
- >>> qmsg, qdata = dequeue(inq)
- >>> print qmsg.as_string()
+ >>> messages = get_queue_messages('pipeline')
+ >>> len(messages)
+ 1
+ >>> print messages[0].msg.as_string()
From: aperson@example.org
To: alist@example.com
Subject: Something important
@@ -323,7 +314,7 @@ indicates that the message has been approved.
<BLANKLINE>
Here's something important about our mailing list.
<BLANKLINE>
- >>> dump_msgdata(qdata)
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
approved : True
moderator_approved: True
@@ -385,8 +376,11 @@ moderators.
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard,
... forward=['zperson@example.com'])
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+ >>> print messages[0].msg.as_string()
Subject: Forward of moderated message
From: alist-bounces@example.com
To: zperson@example.com
@@ -404,7 +398,8 @@ moderators.
<BLANKLINE>
Here's something important about our mailing list.
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -434,12 +429,13 @@ In the above case the mailing list was not configured to send the list
moderators a notice about the hold, so no email message is in the virgin
queue.
- >>> virginq.files
+ >>> get_queue_messages('virgin')
[]
But if we set the list up to notify the list moderators immediately when a
message is held for approval, there will be a message placed in the virgin
queue when the message is held.
+::
>>> mlist.admin_immed_notify = True
>>> # XXX This will almost certainly change once we've worked out the web
@@ -449,8 +445,11 @@ queue when the message is held.
... '{NONE}zyxcba', DeliveryMode.regular, 'en')
>>> requests.get_request(id_4) is not None
True
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -474,7 +473,8 @@ queue when the message is held.
<BLANKLINE>
to process the request.
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -498,13 +498,17 @@ The held subscription can also be discarded.
The request can be rejected, in which case a message is sent to the
subscriber.
+::
>>> moderator.handle_subscription(mlist, id_4, Action.reject,
... 'This is a closed list')
>>> print requests.get_request(id_4)
None
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -529,7 +533,8 @@ subscriber.
<BLANKLINE>
alist-owner@example.com
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -548,9 +553,13 @@ mailing list.
A message will be sent to the moderators telling them about the held
subscription and the fact that they may need to approve it.
+::
+
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -574,7 +583,8 @@ subscription and the fact that they may need to approve it.
<BLANKLINE>
to process the request.
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -593,29 +603,20 @@ being sent to the user and the other is a subscription notification that is
sent to the moderators. The only good way to tell which is which is to look
at the recipient list.
- >>> qmsg_1, qdata_1 = dequeue(expected_count=2)
- >>> qmsg_2, qdata_2 = dequeue()
- >>> if 'fperson@example.org' in qdata_1['recipients']:
- ... # The first message is the welcome message
- ... welcome_qmsg = qmsg_1
- ... welcome_qdata = qdata_1
- ... admin_qmsg = qmsg_2
- ... admin_qdata = qdata_2
- ... else:
- ... welcome_qmsg = qmsg_2
- ... welcome_qdata = qdata_2
- ... admin_qmsg = qmsg_1
- ... admin_qdata = qdata_1
+ >>> messages = get_queue_messages('virgin', sort_on='subject')
+ >>> len(messages)
+ 2
The welcome message is sent to the person who just subscribed.
+::
- >>> print welcome_qmsg.as_string()
+ >>> print messages[1].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Subject: Welcome to the "A Test List" mailing list
From: alist-request@example.com
- To: fperson@example.org
+ To: Frank Person <fperson@example.org>
X-No-Archive: yes
Message-ID: ...
Date: ...
@@ -647,18 +648,20 @@ The welcome message is sent to the person who just subscribed.
this email is not included here. There is also a button on your
options page that will send your current password to you.
<BLANKLINE>
- >>> dump_msgdata(welcome_qdata)
+
+ >>> dump_msgdata(messages[1].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
- recipients : set([u'fperson@example.org'])
+ recipients : set([u'Frank Person <fperson@example.org>'])
reduced_list_headers: True
verp : False
version : 3
The admin message is sent to the moderators.
+::
- >>> print admin_qmsg.as_string()
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -672,7 +675,8 @@ The admin message is sent to the moderators.
Frank Person <fperson@example.org> has been successfully subscribed to
A Test List.
<BLANKLINE>
- >>> dump_msgdata(admin_qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
envsender : changeme@example.com
listname : alist@example.com
@@ -727,12 +731,15 @@ notification.
>>> id_5 = moderator.hold_unsubscription(mlist, 'gperson@example.com')
>>> requests.get_request(id_5) is not None
True
- >>> virginq.files
+ >>> get_queue_messages('virgin')
[]
>>> mlist.admin_immed_notify = True
>>> id_6 = moderator.hold_unsubscription(mlist, 'hperson@example.com')
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -755,7 +762,8 @@ notification.
<BLANKLINE>
to process the request.
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -788,8 +796,11 @@ and the person remains a member of the mailing list.
... 'This list is a prison.')
>>> print requests.get_request(id_6)
None
- >>> qmsg, qdata = dequeue()
- >>> print qmsg.as_string()
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -814,7 +825,8 @@ and the person remains a member of the mailing list.
<BLANKLINE>
alist-owner@example.com
<BLANKLINE>
- >>> dump_msgdata(qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -840,23 +852,14 @@ There are now two messages in the virgin queue, one to the member who was just
unsubscribed and another to the moderators informing them of this membership
change.
- >>> qmsg_1, qdata_1 = dequeue(expected_count=2)
- >>> qmsg_2, qdata_2 = dequeue()
- >>> if 'gperson@example.com' in qdata_1['recipients']:
- ... # The first message is the goodbye message
- ... goodbye_qmsg = qmsg_1
- ... goodbye_qdata = qdata_1
- ... admin_qmsg = qmsg_2
- ... admin_qdata = qdata_2
- ... else:
- ... goodbye_qmsg = qmsg_2
- ... goodbye_qdata = qdata_2
- ... admin_qmsg = qmsg_1
- ... admin_qdata = qdata_1
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 2
The goodbye message...
+::
- >>> print goodbye_qmsg.as_string()
+ >>> print messages[0].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -869,7 +872,8 @@ The goodbye message...
<BLANKLINE>
So long!
<BLANKLINE>
- >>> dump_msgdata(goodbye_qdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : alist@example.com
nodecorate : True
@@ -879,8 +883,9 @@ The goodbye message...
version : 3
...and the admin message.
+::
- >>> print admin_qmsg.as_string()
+ >>> print messages[1].msg.as_string()
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
@@ -893,7 +898,8 @@ The goodbye message...
<BLANKLINE>
gperson@example.com has been removed from A Test List.
<BLANKLINE>
- >>> dump_msgdata(admin_qdata)
+
+ >>> dump_msgdata(messages[1].msgdata)
_parsemsg : False
envsender : changeme@example.com
listname : alist@example.com
diff --git a/src/mailman/rest/docs/configuration.rst b/src/mailman/rest/docs/configuration.rst
index ea00b688c..e572acec4 100644
--- a/src/mailman/rest/docs/configuration.rst
+++ b/src/mailman/rest/docs/configuration.rst
@@ -61,7 +61,7 @@ All readable attributes for a list are available on a sub-resource.
send_welcome_message: True
volume: 1
web_host: lists.example.com
- welcome_message_uri:
+ welcome_message_uri: mailman:///welcome.txt
Changing the full configuration
diff --git a/src/mailman/runners/docs/command.rst b/src/mailman/runners/docs/command.rst
index f2fa86fcf..43682056b 100644
--- a/src/mailman/runners/docs/command.rst
+++ b/src/mailman/runners/docs/command.rst
@@ -8,6 +8,7 @@ number of email commands out of the box. These are processed when a message
is sent to the list's ``-request`` address.
>>> mlist = create_list('test@example.com')
+ >>> mlist.send_welcome_messages = False
A command in the Subject
@@ -33,14 +34,14 @@ the sender. The command can be in the ``Subject`` header.
>>> command.run()
And now the response is in the ``virgin`` queue.
+::
- >>> from mailman.core.switchboard import Switchboard
- >>> virgin_queue = config.switchboards['virgin']
- >>> len(virgin_queue.files)
- 1
>>> from mailman.testing.helpers import get_queue_messages
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
+ 1
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
From: test-bounces@example.com
To: aperson@example.com
@@ -59,7 +60,8 @@ And now the response is in the ``virgin`` queue.
<BLANKLINE>
- Done.
<BLANKLINE>
- >>> dump_msgdata(item.msgdata)
+
+ >>> dump_msgdata(messages[0].msgdata)
_parsemsg : False
listname : test@example.com
nodecorate : True
@@ -85,10 +87,11 @@ message is plain text.
>>> inject_message(mlist, msg, switchboard='command')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
1
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
From: test-bounces@example.com
To: bperson@example.com
@@ -132,13 +135,10 @@ address, and the other is the results of his email command.
>>> inject_message(mlist, msg, switchboard='command', subaddress='join')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin', sort_on='subject')
+ >>> len(messages)
2
- >>> def sortkey(item):
- ... return str(item.msg['subject'])
- >>> messages = sorted(get_queue_messages('virgin'), key=sortkey)
-
>>> from mailman.interfaces.registrar import IRegistrar
>>> from zope.component import getUtility
>>> registrar = getUtility(IRegistrar)
@@ -152,6 +152,9 @@ address, and the other is the results of his email command.
Subject: The results of your email commands
Subject: confirm ...
+.. Clear the queue
+ >>> ignore = get_queue_messages('virgin')
+
Similarly, to leave a mailing list, the user need only email the ``-leave`` or
``-unsubscribe`` address (the latter is deprecated).
::
@@ -164,10 +167,11 @@ Similarly, to leave a mailing list, the user need only email the ``-leave`` or
>>> inject_message(mlist, msg, switchboard='command', subaddress='leave')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
1
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
From: test-bounces@example.com
To: dperson@example.com
@@ -198,10 +202,11 @@ The ``-confirm`` address is also available as an implicit command.
>>> inject_message(mlist, msg, switchboard='command', subaddress='confirm')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
1
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
From: test-bounces@example.com
To: dperson@example.com
@@ -241,10 +246,11 @@ looked at by the command queue.
>>> inject_message(mlist, msg, switchboard='command')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
1
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
...
<BLANKLINE>
@@ -272,10 +278,11 @@ The ``stop`` command is an alias for ``end``.
>>> inject_message(mlist, msg, switchboard='command')
>>> command.run()
- >>> len(virgin_queue.files)
+ >>> messages = get_queue_messages('virgin')
+ >>> len(messages)
1
- >>> item = get_queue_messages('virgin')[0]
- >>> print item.msg.as_string()
+
+ >>> print messages[0].msg.as_string()
Subject: The results of your email commands
...
<BLANKLINE>
diff --git a/src/mailman/runners/tests/test_confirm.py b/src/mailman/runners/tests/test_confirm.py
index 21dc653d2..34a2af523 100644
--- a/src/mailman/runners/tests/test_confirm.py
+++ b/src/mailman/runners/tests/test_confirm.py
@@ -52,6 +52,7 @@ class TestConfirm(unittest.TestCase):
# Register a subscription requiring confirmation.
registrar = getUtility(IRegistrar)
self._mlist = create_list('test@example.com')
+ self._mlist.send_welcome_message = False
self._token = registrar.register(self._mlist, 'anne@example.org')
self._commandq = config.switchboards['command']
self._runner = make_testable_runner(CommandRunner, 'command')
@@ -231,3 +232,32 @@ From: Anne Person <anne@example.org>
in_results = True
self.assertEqual(len(confirmation_lines), 1)
self.assertFalse('did not match' in confirmation_lines[0])
+
+ def test_welcome_message_after_confirmation(self):
+ # Confirmations with a welcome message set.
+ self._mlist.send_welcome_message = True
+ self._mlist.welcome_message_uri = 'mailman:///welcome.txt'
+ # 'confirm' in the Subject and in the To header should not try to
+ # confirm the token twice.
+ #
+ # Clear out the virgin queue so that the test below only sees the
+ # reply to the confirmation message.
+ get_queue_messages('virgin')
+ subject = 'Re: confirm {0}'.format(self._token)
+ to = 'test-confirm+{0}@example.com'.format(self._token)
+ msg = mfs("""\
+From: Anne Person <anne@example.org>
+
+""")
+ msg['Subject'] = subject
+ msg['To'] = to
+ self._commandq.enqueue(msg, dict(listname='test@example.com',
+ subaddress='confirm'))
+ self._runner.run()
+ # Now there's a email command notification and a welcome message. All
+ # we care about for this test is the welcome message.
+ messages = get_queue_messages('virgin', sort_on='subject')
+ self.assertEqual(len(messages), 2)
+ message = messages[1].msg
+ self.assertEqual(str(message['subject']),
+ 'Welcome to the "Test" mailing list')
diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py
index 674b0a91f..8d4ef83df 100644
--- a/src/mailman/styles/default.py
+++ b/src/mailman/styles/default.py
@@ -87,7 +87,7 @@ from: .*@uplinkpro.com
mlist.anonymous_list = False
mlist.description = ''
mlist.info = ''
- mlist.welcome_message_uri = ''
+ mlist.welcome_message_uri = 'mailman:///welcome.txt'
mlist.goodbye_message_uri = ''
mlist.subscribe_policy = 1
mlist.subscribe_auto_approval = []