1
# Copyright (C) 2012 by the Free Software Foundation, Inc.
3
# This file is part of GNU Mailman.
5
# GNU Mailman is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free
7
# Software Foundation, either version 3 of the License, or (at your option)
10
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
# You should have received a copy of the GNU General Public License along with
16
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18
"""Test posting to a mailing list's -owner address."""
20
# XXX 2012-03-23 BAW: This is not necessarily the best place for this test.
21
# We really need a better place to collect these sort of end-to-end posting
22
# tests. They're not exactly integration tests, but they do touch lots of
23
# parts of the system.
25
from __future__ import absolute_import, print_function, unicode_literals
35
from operator import itemgetter
36
from zope.component import getUtility
38
from mailman.app.lifecycle import create_list
39
from mailman.config import config
40
from mailman.database.transaction import transaction
41
from mailman.interfaces.member import MemberRole
42
from mailman.interfaces.usermanager import IUserManager
43
from mailman.testing.helpers import (
47
from mailman.runners.incoming import IncomingRunner
48
from mailman.runners.outgoing import OutgoingRunner
49
from mailman.runners.pipeline import PipelineRunner
50
from mailman.testing.layers import SMTPLayer
54
class TestEmailToOwner(unittest.TestCase):
55
"""Test emailing a mailing list's -owner address."""
60
self._mlist = create_list('test@example.com')
61
# Add some owners, moderators, and members
62
manager = getUtility(IUserManager)
64
anne = manager.create_address('anne@example.com')
65
bart = manager.create_address('bart@example.com')
66
cris = manager.create_address('cris@example.com')
67
dave = manager.create_address('dave@example.com')
68
self._mlist.subscribe(anne, MemberRole.member)
69
self._mlist.subscribe(anne, MemberRole.owner)
70
self._mlist.subscribe(bart, MemberRole.moderator)
71
self._mlist.subscribe(bart, MemberRole.owner)
72
self._mlist.subscribe(cris, MemberRole.moderator)
73
self._mlist.subscribe(dave, MemberRole.member)
74
self._inq = make_testable_runner(IncomingRunner, 'in')
75
self._pipelineq = make_testable_runner(PipelineRunner, 'pipeline')
76
self._outq = make_testable_runner(OutgoingRunner, 'out')
77
# Python 2.7 has assertMultiLineEqual. Let this work without bounds.
79
self.eq = getattr(self, 'assertMultiLineEqual', self.assertEqual)
81
def test_owners_get_email(self):
82
# XXX 2012-03-23 BAW: We can't use a layer here because we need both
83
# the SMTPLayer and LMTPLayer and these are incompatible. There's no
84
# way to make zope.test* happy without causing errors or worse. Live
85
# with this hack until we can rip all that layer crap out and use
86
# something like testresources.
88
get_lmtp_client(quiet=True)
89
lmtpd = TestableMaster(wait)
91
# Post a message to the list's -owner address, and all the owners will
92
# get a copy of the message.
93
lmtp = get_lmtp_client(quiet=True)
94
lmtp.lhlo('remote.example.org')
95
lmtp.sendmail('zuzu@example.org', ['test-owner@example.com'], """\
96
From: Zuzu Person <zuzu@example.org>
97
To: test-owner@example.com
103
# There should now be one message sitting in the incoming queue.
104
# Check that, then process it. Don't use get_queue_messages() since
105
# that will empty the queue.
106
self.assertEqual(len(config.switchboards['in'].files), 1)
108
# There should now be one message sitting in the pipeline queue.
109
# Process that one too.
110
self.assertEqual(len(config.switchboards['pipeline'].files), 1)
111
self._pipelineq.run()
112
# The message has made its way to the outgoing queue. Again, check
113
# and process that one.
114
self.assertEqual(len(config.switchboards['out'].files), 1)
116
# The SMTP server has now received three messages, one for each of the
117
# owners and moderators. Of course, Bart is both an owner and a
118
# moderator, so he'll get only one copy of the message. Dave does not
119
# get a copy of the message.
120
messages = sorted(SMTPLayer.smtpd.messages, key=itemgetter('x-rcptto'))
121
self.assertEqual(len(messages), 3)
122
self.assertEqual(messages[0]['x-rcptto'], 'anne@example.com')
123
self.assertEqual(messages[1]['x-rcptto'], 'bart@example.com')
124
self.assertEqual(messages[2]['x-rcptto'], 'cris@example.com')
125
# And yet, all three messages are addressed to the -owner address.
126
for message in messages:
127
self.assertEqual(message['to'], 'test-owner@example.com')
128
# All three messages will have two X-MailFrom headers. One is added
129
# by the LMTP server accepting Zuzu's original message, and will
130
# contain her posting address, i.e. zuzu@example.com. The second one
131
# is added by the lazr.smtptest server that accepts Mailman's VERP'd
132
# message to the individual recipient. By verifying both, we prove
133
# that Zuzu sent the original message, and that Mailman is VERP'ing
134
# the copy to all the owners.
136
messages[0].get_all('x-mailfrom'),
137
['zuzu@example.org', 'test-bounces+anne=example.com@example.com'])
139
messages[1].get_all('x-mailfrom'),
140
['zuzu@example.org', 'test-bounces+bart=example.com@example.com'])
142
messages[2].get_all('x-mailfrom'),
143
['zuzu@example.org', 'test-bounces+cris=example.com@example.com'])