1 # Copyright (C) 2012-2016 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.
27 from mailman
.app
.lifecycle
import create_list
28 from mailman
.config
import config
29 from mailman
.database
.transaction
import transaction
30 from mailman
.interfaces
.member
import MemberRole
31 from mailman
.interfaces
.usermanager
import IUserManager
32 from mailman
.testing
.helpers
import (
33 TestableMaster
, get_lmtp_client
, make_testable_runner
)
34 from mailman
.runners
.incoming
import IncomingRunner
35 from mailman
.runners
.outgoing
import OutgoingRunner
36 from mailman
.runners
.pipeline
import PipelineRunner
37 from mailman
.testing
.layers
import SMTPLayer
38 from operator
import itemgetter
39 from zope
.component
import getUtility
42 class TestEmailToOwner(unittest
.TestCase
):
43 """Test emailing a mailing list's -owner address."""
48 self
._mlist
= create_list('test@example.com')
49 # Add some owners, moderators, and members
50 manager
= getUtility(IUserManager
)
52 anne
= manager
.create_address('anne@example.com')
53 bart
= manager
.create_address('bart@example.com')
54 cris
= manager
.create_address('cris@example.com')
55 dave
= manager
.create_address('dave@example.com')
56 self
._mlist
.subscribe(anne
, MemberRole
.member
)
57 self
._mlist
.subscribe(anne
, MemberRole
.owner
)
58 self
._mlist
.subscribe(bart
, MemberRole
.moderator
)
59 self
._mlist
.subscribe(bart
, MemberRole
.owner
)
60 self
._mlist
.subscribe(cris
, MemberRole
.moderator
)
61 self
._mlist
.subscribe(dave
, MemberRole
.member
)
62 self
._inq
= make_testable_runner(IncomingRunner
, 'in')
63 self
._pipelineq
= make_testable_runner(PipelineRunner
, 'pipeline')
64 self
._outq
= make_testable_runner(OutgoingRunner
, 'out')
66 def test_owners_get_email(self
):
67 # XXX 2012-03-23 BAW: We can't use a layer here because we need both
68 # the SMTPLayer and LMTPLayer and these are incompatible. There's no
69 # way to make zope.test* happy without causing errors or worse. Live
70 # with this hack until we can rip all that layer crap out and use
71 # something like testresources.
73 get_lmtp_client(quiet
=True)
74 lmtpd
= TestableMaster(wait
)
76 # Post a message to the list's -owner address, and all the owners will
77 # get a copy of the message.
78 lmtp
= get_lmtp_client(quiet
=True)
79 lmtp
.lhlo('remote.example.org')
80 lmtp
.sendmail('zuzu@example.org', ['test-owner@example.com'], b
"""\
81 From: Zuzu Person <zuzu@example.org>
82 To: test-owner@example.com
88 # There should now be one message sitting in the incoming queue.
89 # Check that, then process it. Don't use get_queue_messages() since
90 # that will empty the queue.
91 self
.assertEqual(len(config
.switchboards
['in'].files
), 1)
93 # There should now be one message sitting in the pipeline queue.
94 # Process that one too.
95 self
.assertEqual(len(config
.switchboards
['pipeline'].files
), 1)
97 # The message has made its way to the outgoing queue. Again, check
98 # and process that one.
99 self
.assertEqual(len(config
.switchboards
['out'].files
), 1)
101 # The SMTP server has now received three messages, one for each of the
102 # owners and moderators. Of course, Bart is both an owner and a
103 # moderator, so he'll get only one copy of the message. Dave does not
104 # get a copy of the message.
105 messages
= sorted(SMTPLayer
.smtpd
.messages
, key
=itemgetter('x-rcptto'))
106 self
.assertEqual(len(messages
), 3)
107 self
.assertEqual(messages
[0]['x-rcptto'], 'anne@example.com')
108 self
.assertEqual(messages
[1]['x-rcptto'], 'bart@example.com')
109 self
.assertEqual(messages
[2]['x-rcptto'], 'cris@example.com')
110 # And yet, all three messages are addressed to the -owner address.
111 for message
in messages
:
112 self
.assertEqual(message
['to'], 'test-owner@example.com')
113 # All three messages will have two X-MailFrom headers. One is added
114 # by the LMTP server accepting Zuzu's original message, and will
115 # contain her posting address, i.e. zuzu@example.com. The second one
116 # is added by the lazr.smtptest server that accepts Mailman's VERP'd
117 # message to the individual recipient. By verifying both, we prove
118 # that Zuzu sent the original message, and that Mailman is VERP'ing
119 # the copy to all the owners.
121 messages
[0].get_all('x-mailfrom'),
122 ['zuzu@example.org', 'test-bounces+anne=example.com@example.com'])
124 messages
[1].get_all('x-mailfrom'),
125 ['zuzu@example.org', 'test-bounces+bart=example.com@example.com'])
127 messages
[2].get_all('x-mailfrom'),
128 ['zuzu@example.org', 'test-bounces+cris=example.com@example.com'])