Beispiel #1
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._request_db = IListRequests(self._mlist)
        self._msg = specialized_message_from_string("""\
From: [email protected]
To: [email protected]
Subject: hold me
Message-ID: <alpha>

""")
        self._in = make_testable_runner(IncomingRunner, 'in')
        self._pipeline = make_testable_runner(PipelineRunner, 'pipeline')
        self._out = make_testable_runner(OutgoingRunner, 'out')
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._request_db = IListRequests(self._mlist)
        self._msg = specialized_message_from_string("""\
From: [email protected]
To: [email protected]
Subject: hold me
Message-ID: <alpha>

""")
        self._in = make_testable_runner(IncomingRunner, 'in')
        self._pipeline = make_testable_runner(PipelineRunner, 'pipeline')
        self._out = make_testable_runner(OutgoingRunner, 'out')
Beispiel #3
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._msg = specialized_message_from_string("""\
From: [email protected]
To: [email protected]
Subject: hold me
Message-ID: <alpha>

""")
        self._in = make_testable_runner(IncomingRunner, 'in')
        self._pipeline = make_testable_runner(PipelineRunner, 'pipeline')
        self._out = make_testable_runner(OutgoingRunner, 'out')
        # Python 2.7 has assertMultiLineEqual.  Let this work without bounds.
        self.maxDiff = None
        self.eq = getattr(self, 'assertMultiLineEqual', self.assertEqual)
Beispiel #4
0
    def test_crash_event(self):
        runner = make_testable_runner(CrashingRunner, 'in')
        # When an exception occurs in Runner._process_one_file(), a zope.event
        # gets triggered containing the exception object.
        msg = mfs("""\
From: [email protected]
To: [email protected]
Message-ID: <ant>

""")
        config.switchboards['in'].enqueue(msg, listid='test.example.com')
        with event_subscribers(self._got_event):
            runner.run()
        # We should now have exactly one event, which will contain the
        # exception, plus additional metadata containing the mailing list,
        # message, and metadata.
        self.assertEqual(len(self._events), 1)
        event = self._events[0]
        self.assertIsInstance(event, RunnerCrashEvent)
        self.assertEqual(event.mailing_list, self._mlist)
        self.assertEqual(event.message['message-id'], '<ant>')
        self.assertEqual(event.metadata['listid'], 'test.example.com')
        self.assertIsInstance(event.error, RuntimeError)
        self.assertEqual(str(event.error), 'borked')
        self.assertIsInstance(event.runner, CrashingRunner)
        # The message should also have ended up in the shunt queue.
        items = get_queue_messages('shunt', expected_count=1)
        self.assertEqual(items[0].msg['message-id'], '<ant>')
Beispiel #5
0
    def setUp(self):
        config.push('french', """
        [mailman]
        default_language: fr
        """)
        self.addCleanup(config.pop, 'french')
        self._mlist = create_list('*****@*****.**')
        self._mlist.send_welcome_message = False
        self._mlist.preferred_language = 'fr'
        self._mlist.digest_size_threshold = 0
        self._process = config.handlers['to-digest'].process
        self._runner = make_testable_runner(DigestRunner)
        # Add a French version of the digest masthead.
        tempdir = TemporaryDirectory()
        self.addCleanup(tempdir.cleanup)
        french_path = os.path.join(tempdir.name, 'fr', 'masthead.txt')
        os.makedirs(os.path.dirname(french_path))
        with open(french_path, 'w', encoding='utf-8') as fp:
            print("""\
Envoyez vos messages pour la liste $display_name à
\t$got_list_email

Pour vous (dés)abonner par courriel, envoyez un message avec « help » dans
le corps ou dans le sujet à
\t$got_request_email

Vous pouvez contacter l'administrateur de la liste à l'adresse
\t$got_owner_email

Si vous répondez, n'oubliez pas de changer l'objet du message afin
qu'il soit plus spécifique que « Re: Contenu du groupe de $display_name...
""", file=fp)
        getUtility(ITemplateManager).set(
            'list:member:digest:masthead', self._mlist.list_id,
            'file:///{}/$language/masthead.txt'.format(tempdir.name))
Beispiel #6
0
    def test_crash_event(self):
        runner = make_testable_runner(CrashingRunner, 'in')
        # When an exception occurs in Runner._process_one_file(), a zope.event
        # gets triggered containing the exception object.
        msg = mfs("""\
From: [email protected]
To: [email protected]
Message-ID: <ant>

""")
        config.switchboards['in'].enqueue(msg, listid='test.example.com')
        with event_subscribers(self._got_event):
            runner.run()
        # We should now have exactly one event, which will contain the
        # exception, plus additional metadata containing the mailing list,
        # message, and metadata.
        self.assertEqual(len(self._events), 1)
        event = self._events[0]
        self.assertTrue(isinstance(event, RunnerCrashEvent))
        self.assertEqual(event.mailing_list, self._mlist)
        self.assertEqual(event.message['message-id'], '<ant>')
        self.assertEqual(event.metadata['listid'], 'test.example.com')
        self.assertTrue(isinstance(event.error, RuntimeError))
        self.assertEqual(str(event.error), 'borked')
        self.assertTrue(isinstance(event.runner, CrashingRunner))
        # The message should also have ended up in the shunt queue.
        shunted = get_queue_messages('shunt')
        self.assertEqual(len(shunted), 1)
        self.assertEqual(shunted[0].msg['message-id'], '<ant>')
Beispiel #7
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._now = now()
        # Enable just the dummy archiver.
        config.push('dummy', """
        [archiver.dummy]
        class: mailman.runners.tests.test_archiver.DummyArchiver
        enable: no
        [archiver.prototype]
        enable: no
        [archiver.mhonarc]
        enable: no
        [archiver.mail_archive]
        enable: no
        """)
        self._archiveq = config.switchboards['archive']
        self._msg = mfs("""\
From: [email protected]
To: [email protected]
Subject: My first post
Message-ID: <first>
X-Message-ID-Hash: 4CMWUN6BHVCMHMDAOSJZ2Q72G5M32MWB

First post!
""")
        self._runner = make_testable_runner(ArchiveRunner)
        IListArchiverSet(self._mlist).get('dummy').is_enabled = True
Beispiel #8
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._now = now()
        # Enable just the dummy archiver.
        config.push(
            'dummy', """
        [archiver.dummy]
        class: mailman.runners.tests.test_archiver.DummyArchiver
        enable: no
        [archiver.prototype]
        enable: no
        [archiver.mhonarc]
        enable: no
        [archiver.mail_archive]
        enable: no
        """)
        self._archiveq = config.switchboards['archive']
        self._msg = mfs("""\
From: [email protected]
To: [email protected]
Subject: My first post
Message-ID: <first>
Message-ID-Hash: 4CMWUN6BHVCMHMDAOSJZ2Q72G5M32MWB

First post!
""")
        self._runner = make_testable_runner(ArchiveRunner)
        IListArchiverSet(self._mlist).get('dummy').is_enabled = True
    def setUp(self):
        self._mlist = create_list("*****@*****.**")
        self._mlist.send_welcome_message = False
        self._bounceq = config.switchboards["bounces"]
        self._runner = make_testable_runner(BounceRunner, "bounces")
        self._anne = getUtility(IUserManager).create_address("*****@*****.**")
        self._member = self._mlist.subscribe(self._anne, MemberRole.member)
        self._msg = message_from_string(
            """\
From: [email protected]
To: [email protected]
Message-Id: <first>

"""
        )
        self._msgdata = dict(listid="test.example.com")
        self._processor = getUtility(IBounceProcessor)
        config.push(
            "site owner",
            """
        [mailman]
        site_owner: [email protected]
        """,
        )
        self.addCleanup(config.pop, "site owner")
Beispiel #10
0
 def setUp(self):
     with transaction():
         self._mlist = create_list('*****@*****.**')
         self._mlist.send_goodbye_message = False
         self._mlist.send_welcome_message = False
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
Beispiel #11
0
 def test_digest_messages(self):
     # In LP: #1130697, the digest runner creates MIME digests using the
     # stdlib MIMEMutlipart class, however this class does not have the
     # extended attributes we require (e.g. .sender).  The fix is to use a
     # subclass of MIMEMultipart and our own Message subclass; this adds
     # back the required attributes.  (LP: #1130696)
     #
     # Start by creating the raw ingredients for the digests.  This also
     # runs the digest runner, thus producing the digest messages into the
     # virgin queue.
     make_digest_messages(self._mlist)
     # Run the virgin queue processor, which runs the cook-headers and
     # to-outgoing handlers.  This should produce no error.
     error_log = LogFileMark('mailman.error')
     runner = make_testable_runner(VirginRunner, 'virgin')
     runner.run()
     error_text = error_log.read()
     self.assertEqual(len(error_text), 0, error_text)
     self.assertEqual(len(get_queue_messages('shunt')), 0)
     messages = get_queue_messages('out')
     self.assertEqual(len(messages), 2)
     # Which one is the MIME digest?
     mime_digest = None
     for bag in messages:
         if bag.msg.get_content_type() == 'multipart/mixed':
             assert mime_digest is None, 'Found two MIME digests'
             mime_digest = bag.msg
     # The cook-headers handler ran.
     self.assertIn('x-mailman-version', mime_digest)
     self.assertEqual(mime_digest['precedence'], 'list')
     # The list's -request address is the original sender.
     self.assertEqual(bag.msgdata['original_sender'],
                      '*****@*****.**')
Beispiel #12
0
 def test_digest_messages(self):
     # In LP: #1130697, the digest runner creates MIME digests using the
     # stdlib MIMEMutlipart class, however this class does not have the
     # extended attributes we require (e.g. .sender).  The fix is to use a
     # subclass of MIMEMultipart and our own Message subclass; this adds
     # back the required attributes.  (LP: #1130696)
     #
     # Start by creating the raw ingredients for the digests.  This also
     # runs the digest runner, thus producing the digest messages into the
     # virgin queue.
     make_digest_messages(self._mlist)
     # Run the virgin queue processor, which runs the cook-headers and
     # to-outgoing handlers.  This should produce no error.
     error_log = LogFileMark('mailman.error')
     runner = make_testable_runner(VirginRunner, 'virgin')
     runner.run()
     error_text = error_log.read()
     self.assertEqual(len(error_text), 0, error_text)
     self.assertEqual(len(get_queue_messages('shunt')), 0)
     messages = get_queue_messages('out')
     self.assertEqual(len(messages), 2)
     # Which one is the MIME digest?
     mime_digest = None
     for bag in messages:
         if bag.msg.get_content_type() == 'multipart/mixed':
             assert mime_digest is None, 'Found two MIME digests'
             mime_digest = bag.msg
     # The cook-headers handler ran.
     self.assertIn('x-mailman-version', mime_digest)
     self.assertEqual(mime_digest['precedence'], 'list')
     # The list's -request address is the original sender.
     self.assertEqual(bag.msgdata['original_sender'],
                      '*****@*****.**')
Beispiel #13
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._mlist.digest_size_threshold = 1
     self._digestq = config.switchboards['digest']
     self._shuntq = config.switchboards['shunt']
     self._virginq = config.switchboards['virgin']
     self._runner = make_testable_runner(DigestRunner, 'digest')
     self._process = config.handlers['to-digest'].process
Beispiel #14
0
 def setUp(self):
     registrar = getUtility(IRegistrar)
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
     with transaction():
         # Register a subscription requiring confirmation.
         self._mlist = create_list('*****@*****.**')
         self._mlist.send_welcome_message = False
         self._token = registrar.register(self._mlist, '*****@*****.**')
Beispiel #15
0
 def setUp(self):
     registrar = getUtility(IRegistrar)
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
     with transaction():
         # Register a subscription requiring confirmation.
         self._mlist = create_list('*****@*****.**')
         self._mlist.send_welcome_message = False
         self._token = registrar.register(self._mlist, '*****@*****.**')
Beispiel #16
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._mlist.send_welcome_message = False
     self._mailbox_path = os.path.join(self._mlist.data_path, 'digest.mmdf')
     # The mailing list needs at least one digest recipient.
     member = subscribe(self._mlist, 'Anne')
     member.preferences.delivery_mode = DeliveryMode.plaintext_digests
     self._subject_number = 1
     self._runner = make_testable_runner(DigestRunner, 'digest')
Beispiel #17
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     # Add some owners, moderators, and members
     manager = getUtility(IUserManager)
     with transaction():
         anne = manager.create_address('*****@*****.**')
         bart = manager.create_address('*****@*****.**')
         cris = manager.create_address('*****@*****.**')
         dave = manager.create_address('*****@*****.**')
         self._mlist.subscribe(anne, MemberRole.member)
         self._mlist.subscribe(anne, MemberRole.owner)
         self._mlist.subscribe(bart, MemberRole.moderator)
         self._mlist.subscribe(bart, MemberRole.owner)
         self._mlist.subscribe(cris, MemberRole.moderator)
         self._mlist.subscribe(dave, MemberRole.member)
     self._inq = make_testable_runner(IncomingRunner, 'in')
     self._pipelineq = make_testable_runner(PipelineRunner, 'pipeline')
     self._outq = make_testable_runner(OutgoingRunner, 'out')
Beispiel #18
0
    def test_mime_digest_format(self):
        # Make sure that the format of the MIME digest is as expected.
        self._mlist.digest_size_threshold = 0.6
        self._mlist.volume = 1
        self._mlist.next_digest_number = 1
        self._mlist.send_welcome_message = False
        # Subscribe some users receiving digests.
        anne = subscribe(self._mlist, 'Anne')
        anne.preferences.delivery_mode = DeliveryMode.mime_digests
        bart = subscribe(self._mlist, 'Bart')
        bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
        # Fill the digest.
        process = config.handlers['to-digest'].process
        size = 0
        for i in range(1, 5):
            text = Template("""\
From: [email protected]
To: [email protected]
Subject: Test message $i
List-Post: <*****@*****.**>

Here is message $i
""").substitute(i=i)
            msg = message_from_string(text)
            process(self._mlist, msg, {})
            size += len(text)
            if size >= self._mlist.digest_size_threshold * 1024:
                break
        # Run the digest runner to create the MIME and RFC 1153 digests.
        runner = make_testable_runner(DigestRunner)
        runner.run()
        items = get_queue_messages('virgin', expected_count=2)
        # Find the MIME one.
        mime_digest = None
        for item in items:
            if item.msg.is_multipart():
                assert mime_digest is None, 'We got two MIME digests'
                mime_digest = item.msg
        fp = StringIO()
        # Verify the structure is what we expect.
        structure(mime_digest, fp)
        self.assertMultiLineEqual(
            fp.getvalue(), """\
multipart/mixed
    text/plain
    text/plain
    multipart/digest
        message/rfc822
            text/plain
        message/rfc822
            text/plain
        message/rfc822
            text/plain
        message/rfc822
            text/plain
    text/plain
""")
Beispiel #19
0
 def setUp(self):
     self._style = TestStyle()
     self._style_manager = getUtility(IStyleManager)
     self._style_manager.register(self._style)
     # Now we can create the mailing list.
     self._mlist = create_list('*****@*****.**', style_name='test')
     self._bounceq = config.switchboards['bounces']
     self._processor = getUtility(IBounceProcessor)
     self._runner = make_testable_runner(BounceRunner, 'bounces')
Beispiel #20
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     # Add some owners, moderators, and members
     manager = getUtility(IUserManager)
     with transaction():
         anne = manager.create_address('*****@*****.**')
         bart = manager.create_address('*****@*****.**')
         cris = manager.create_address('*****@*****.**')
         dave = manager.create_address('*****@*****.**')
         self._mlist.subscribe(anne, MemberRole.member)
         self._mlist.subscribe(anne, MemberRole.owner)
         self._mlist.subscribe(bart, MemberRole.moderator)
         self._mlist.subscribe(bart, MemberRole.owner)
         self._mlist.subscribe(cris, MemberRole.moderator)
         self._mlist.subscribe(dave, MemberRole.member)
     self._inq = make_testable_runner(IncomingRunner, 'in')
     self._pipelineq = make_testable_runner(PipelineRunner, 'pipeline')
     self._outq = make_testable_runner(OutgoingRunner, 'out')
Beispiel #21
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._mlist.send_welcome_message = False
     self._mailbox_path = os.path.join(self._mlist.data_path, 'digest.mmdf')
     # The mailing list needs at least one digest recipient.
     member = subscribe(self._mlist, 'Anne')
     member.preferences.delivery_mode = DeliveryMode.plaintext_digests
     self._subject_number = 1
     self._runner = make_testable_runner(DigestRunner, 'digest')
Beispiel #22
0
 def setUp(self):
     self._style = TestStyle()
     self._style_manager = getUtility(IStyleManager)
     self._style_manager.register(self._style)
     # Now we can create the mailing list.
     self._mlist = create_list('*****@*****.**', style_name='test')
     self._bounceq = config.switchboards['bounces']
     self._processor = getUtility(IBounceProcessor)
     self._runner = make_testable_runner(BounceRunner, 'bounces')
Beispiel #23
0
    def test_mime_digest_format(self):
        # Make sure that the format of the MIME digest is as expected.
        self._mlist.digest_size_threshold = 0.6
        self._mlist.volume = 1
        self._mlist.next_digest_number = 1
        self._mlist.send_welcome_message = False
        # Subscribe some users receiving digests.
        anne = subscribe(self._mlist, 'Anne')
        anne.preferences.delivery_mode = DeliveryMode.mime_digests
        bart = subscribe(self._mlist, 'Bart')
        bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
        # Fill the digest.
        process = config.handlers['to-digest'].process
        size = 0
        for i in range(1, 5):
            text = Template("""\
From: [email protected]
To: [email protected]
Subject: Test message $i
List-Post: <*****@*****.**>

Here is message $i
""").substitute(i=i)
            msg = message_from_string(text)
            process(self._mlist, msg, {})
            size += len(text)
            if size >= self._mlist.digest_size_threshold * 1024:
                break
        # Run the digest runner to create the MIME and RFC 1153 digests.
        runner = make_testable_runner(DigestRunner)
        runner.run()
        items = get_queue_messages('virgin')
        self.assertEqual(len(items), 2)
        # Find the MIME one.
        mime_digest = None
        for item in items:
            if item.msg.is_multipart():
                assert mime_digest is None, 'We got two MIME digests'
                mime_digest = item.msg
        fp = StringIO()
        # Verify the structure is what we expect.
        structure(mime_digest, fp)
        self.assertMultiLineEqual(fp.getvalue(), """\
multipart/mixed
    text/plain
    text/plain
    message/rfc822
        text/plain
    message/rfc822
        text/plain
    message/rfc822
        text/plain
    message/rfc822
        text/plain
    text/plain
""")
Beispiel #24
0
 def setUp(self):
     self._style = TestStyle()
     self._style_manager = getUtility(IStyleManager)
     self._style_manager.register(self._style)
     self.addCleanup(self._style_manager.unregister, self._style)
     # Now we can create the mailing list.
     self._mlist = create_list("*****@*****.**", style_name="test")
     self._bounceq = config.switchboards["bounces"]
     self._processor = getUtility(IBounceProcessor)
     self._runner = make_testable_runner(BounceRunner, "bounces")
Beispiel #25
0
 def setUp(self):
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
     with transaction():
         # Register a subscription requiring confirmation.
         self._mlist = create_list('*****@*****.**')
         self._mlist.send_welcome_message = False
         anne = getUtility(IUserManager).create_address('*****@*****.**')
         registrar = ISubscriptionManager(self._mlist)
         self._token, token_owner, member = registrar.register(anne)
Beispiel #26
0
 def _go(self, message):
     lmtp = get_lmtp_client(quiet=True)
     lmtp.lhlo('remote.example.org')
     lmtp.sendmail('*****@*****.**', ['*****@*****.**'], message)
     lmtp.close()
     # The message will now be sitting in the `in` queue.  Run the incoming
     # runner once to process it, which should result in the nonmember
     # showing up.
     inq = make_testable_runner(IncomingRunner, 'in')
     inq.run()
Beispiel #27
0
 def _go(self, message):
     lmtp = get_lmtp_client(quiet=True)
     lmtp.lhlo('remote.example.org')
     lmtp.sendmail('*****@*****.**', ['*****@*****.**'], message)
     lmtp.close()
     # The message will now be sitting in the `in` queue.  Run the incoming
     # runner once to process it, which should result in the nonmember
     # showing up.
     inq = make_testable_runner(IncomingRunner, 'in')
     inq.run()
Beispiel #28
0
 def setUp(self):
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
     with transaction():
         # Register a subscription requiring confirmation.
         self._mlist = create_list('*****@*****.**')
         self._mlist.send_welcome_message = False
         anne = getUtility(IUserManager).create_address('*****@*****.**')
         registrar = IRegistrar(self._mlist)
         self._token, token_owner, member = registrar.register(anne)
Beispiel #29
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = {}
Beispiel #30
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._mlist.digests_enabled = True
     self._mlist.digest_size_threshold = 100000
     self._mlist.send_welcome_message = False
     self._command = CliRunner()
     self._handler = config.handlers['to-digest']
     self._runner = make_testable_runner(DigestRunner, 'digest')
     # The mailing list needs at least one digest recipient.
     member = subscribe(self._mlist, 'Anne')
     member.preferences.delivery_mode = DeliveryMode.plaintext_digests
Beispiel #31
0
 def setUp(self):
     config.push('french', """
     [mailman]
     default_language: fr
     """)
     self.addCleanup(config.pop, 'french')
     self._mlist = create_list('*****@*****.**')
     self._mlist.preferred_language = 'fr'
     self._mlist.digest_size_threshold = 0
     self._process = config.handlers['to-digest'].process
     self._runner = make_testable_runner(DigestRunner)
Beispiel #32
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = {}
Beispiel #33
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._mlist.digests_enabled = True
     self._mlist.digest_size_threshold = 100000
     self._mlist.send_welcome_message = False
     self._command = Digests()
     self._handler = config.handlers['to-digest']
     self._runner = make_testable_runner(DigestRunner, 'digest')
     # The mailing list needs at least one digest recipient.
     member = subscribe(self._mlist, 'Anne')
     member.preferences.delivery_mode = DeliveryMode.plaintext_digests
Beispiel #34
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._retryq = config.switchboards['retry']
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(RetryRunner, 'retry')
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = dict(listid='test.example.com')
Beispiel #35
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._retryq = config.switchboards['retry']
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(RetryRunner, 'retry')
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = dict(listid='test.example.com')
Beispiel #36
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.posting_chain = 'test posting'
        self._mlist.owner_chain = 'test owner'
        config.chains['test posting'] = Chain('posting')
        config.chains['test owner'] = Chain('owner')
        self._in = make_testable_runner(IncomingRunner, 'in')
        self._msg = mfs("""\
From: [email protected]
To: [email protected]

""")
Beispiel #37
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.posting_chain = 'test posting'
        self._mlist.owner_chain = 'test owner'
        config.chains['test posting'] = Chain('posting')
        config.chains['test owner'] = Chain('owner')
        self._in = make_testable_runner(IncomingRunner, 'in')
        self._msg = mfs("""\
From: [email protected]
To: [email protected]

""")
Beispiel #38
0
 def setUp(self):
     self._mlist = create_list("*****@*****.**")
     # Add some owners, moderators, and members
     manager = getUtility(IUserManager)
     with transaction():
         anne = manager.create_address("*****@*****.**")
         bart = manager.create_address("*****@*****.**")
         cris = manager.create_address("*****@*****.**")
         dave = manager.create_address("*****@*****.**")
         self._mlist.subscribe(anne, MemberRole.member)
         self._mlist.subscribe(anne, MemberRole.owner)
         self._mlist.subscribe(bart, MemberRole.moderator)
         self._mlist.subscribe(bart, MemberRole.owner)
         self._mlist.subscribe(cris, MemberRole.moderator)
         self._mlist.subscribe(dave, MemberRole.member)
     self._inq = make_testable_runner(IncomingRunner, "in")
     self._pipelineq = make_testable_runner(PipelineRunner, "pipeline")
     self._outq = make_testable_runner(OutgoingRunner, "out")
     # Python 2.7 has assertMultiLineEqual.  Let this work without bounds.
     self.maxDiff = None
     self.eq = getattr(self, "assertMultiLineEqual", self.assertEqual)
Beispiel #39
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.linked_newsgroup = 'example.test'
        self._msg = mfs("""\
From: [email protected]
To: [email protected]
Subject: A newsgroup posting
Message-ID: <ant>

Testing
""")
        self._runner = make_testable_runner(nntp.NNTPRunner, 'nntp')
        self._nntpq = config.switchboards['nntp']
Beispiel #40
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.posting_pipeline = 'test posting'
        self._mlist.owner_pipeline = 'test owner'
        config.pipelines['test posting'] = MyTestPipeline('posting', self)
        config.pipelines['test owner'] = MyTestPipeline('owner', self)
        self._pipeline = make_testable_runner(PipelineRunner, 'pipeline')
        self._markers = []
        self._msg = mfs("""\
From: [email protected]
To: [email protected]

""")
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.posting_pipeline = 'test posting'
        self._mlist.owner_pipeline = 'test owner'
        config.pipelines['test posting'] = MyTestPipeline('posting', self)
        config.pipelines['test owner'] = MyTestPipeline('owner', self)
        self._pipeline = make_testable_runner(PipelineRunner, 'pipeline')
        self._markers = []
        self._msg = mfs("""\
From: [email protected]
To: [email protected]

""")
Beispiel #42
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.linked_newsgroup = 'example.test'
        self._msg = mfs("""\
From: [email protected]
To: [email protected]
Subject: A newsgroup posting
Message-ID: <ant>

Testing
""")
        self._runner = make_testable_runner(nntp.NNTPRunner, 'nntp')
        self._nntpq = config.switchboards['nntp']
Beispiel #43
0
    def setUp(self):
        self._mlist = create_list("*****@*****.**")
        self._mlist.posting_chain = "test posting"
        self._mlist.owner_chain = "test owner"
        config.chains["test posting"] = Chain("posting")
        config.chains["test owner"] = Chain("owner")
        self._in = make_testable_runner(IncomingRunner, "in")
        self._msg = mfs(
            """\
From: [email protected]
To: [email protected]

"""
        )
Beispiel #44
0
 def test_connect_with_other_failure(self, class_mock):
     # In this failure mode, the message stays queued, so we can only run
     # the nntp runner once.
     def once(runner):
         # I.e. stop immediately, since the queue will not be empty.
         return True
     runner = make_testable_runner(nntp.NNTPRunner, 'nntp', predicate=once)
     self._nntpq.enqueue(self._msg, {}, listid='test.example.com')
     mark = LogFileMark('mailman.error')
     runner.run()
     log_message = mark.readline()[:-1]
     self.assertTrue(log_message.endswith(
         'NNTP unexpected exception for [email protected]'))
     items = get_queue_messages('nntp', expected_count=1)
     self.assertEqual(items[0].msgdata['listid'], 'test.example.com')
     self.assertEqual(items[0].msg['subject'], 'A newsgroup posting')
Beispiel #45
0
 def test_connect_with_other_failure(self, class_mock):
     # In this failure mode, the message stays queued, so we can only run
     # the nntp runner once.
     def once(runner):
         # I.e. stop immediately, since the queue will not be empty.
         return True
     runner = make_testable_runner(nntp.NNTPRunner, 'nntp', predicate=once)
     self._nntpq.enqueue(self._msg, {}, listid='test.example.com')
     mark = LogFileMark('mailman.error')
     runner.run()
     log_message = mark.readline()[:-1]
     self.assertTrue(log_message.endswith(
         'NNTP unexpected exception for [email protected]'))
     items = get_queue_messages('nntp', expected_count=1)
     self.assertEqual(items[0].msgdata['listid'], 'test.example.com')
     self.assertEqual(items[0].msg['subject'], 'A newsgroup posting')
Beispiel #46
0
    def setUp(self):
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push('fake outgoing', """
        [mta]
        outgoing: mailman.runners.tests.test_outgoing.raise_socket_error
        """)
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #47
0
    def setUp(self):
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push('fake outgoing', """
        [mta]
        outgoing: mailman.runners.tests.test_outgoing.raise_socket_error
        """)
        self.addCleanup(config.pop, 'fake outgoing')
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #48
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._bounceq = config.switchboards['bounces']
        self._runner = make_testable_runner(BounceRunner, 'bounces')
        self._anne = getUtility(IUserManager).create_address(
            '*****@*****.**')
        self._member = self._mlist.subscribe(self._anne, MemberRole.member)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = dict(listname='*****@*****.**')
        self._processor = getUtility(IBounceProcessor)
        config.push('site owner', """
        [mailman]
        site_owner: [email protected]
        """)
Beispiel #49
0
    def setUp(self):
        global temporary_failures, permanent_failures
        del temporary_failures[:]
        del permanent_failures[:]
        self._processor = getUtility(IBounceProcessor)
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push('fake outgoing', """
       [mta]
       outgoing: mailman.runners.tests.test_outgoing.raise_SomeRecipientsFailed
        """)
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #50
0
    def setUp(self):
        self._mlist = create_list('*****@*****.**')
        self._mlist.send_welcome_message = False
        self._bounceq = config.switchboards['bounces']
        self._runner = make_testable_runner(BounceRunner, 'bounces')
        self._anne = getUtility(IUserManager).create_address(
            '*****@*****.**')
        self._member = self._mlist.subscribe(self._anne, MemberRole.member)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
        self._msgdata = dict(listid='test.example.com')
        self._processor = getUtility(IBounceProcessor)
        config.push('site owner', """
        [mailman]
        site_owner: [email protected]
        """)
        self.addCleanup(config.pop, 'site owner')
Beispiel #51
0
    def setUp(self):
        global temporary_failures, permanent_failures
        del temporary_failures[:]
        del permanent_failures[:]
        self._processor = getUtility(IBounceProcessor)
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push('fake outgoing', """
       [mta]
       outgoing: mailman.runners.tests.test_outgoing.raise_SomeRecipientsFailed
        """)
        self.addCleanup(config.pop, 'fake outgoing')
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #52
0
    def setUp(self):
        global captured_mlist, captured_msg, captured_msgdata
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push(
            'fake outgoing', """
        [mta]
        outgoing: mailman.runners.tests.test_outgoing.capture
        """)
        # Reset the captured data.
        captured_mlist = None
        captured_msg = None
        captured_msgdata = None
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out')
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #53
0
    def setUp(self):
        global captured_mlist, captured_msg, captured_msgdata
        # Push a config where actual delivery is handled by a dummy function.
        # We generally don't care what this does, since we're just testing the
        # setting of the 'verp' key in the metadata.
        config.push('fake outgoing', """
        [mta]
        outgoing: mailman.runners.tests.test_outgoing.capture
        """)
        self.addCleanup(config.pop, 'fake outgoing')
        # Reset the captured data.
        captured_mlist = None
        captured_msg = None
        captured_msgdata = None
        self._mlist = create_list('*****@*****.**')
        self._outq = config.switchboards['out']
        self._runner = make_testable_runner(OutgoingRunner, 'out')
        self._msg = message_from_string("""\
From: [email protected]
To: [email protected]
Message-Id: <first>

""")
Beispiel #54
0
 def test_digest_messages(self):
     # In LP: #1130697, the digest runner creates MIME digests using the
     # stdlib MIMEMutlipart class, however this class does not have the
     # extended attributes we require (e.g. .sender).  The fix is to use a
     # subclass of MIMEMultipart and our own Message subclass; this adds
     # back the required attributes.  (LP: #1130696)
     self._mlist.send_welcome_message = False
     # Subscribe some users receiving digests.
     anne = subscribe(self._mlist, 'Anne')
     anne.preferences.delivery_mode = DeliveryMode.mime_digests
     bart = subscribe(self._mlist, 'Bart')
     bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
     # Start by creating the raw ingredients for the digests.  This also
     # runs the digest runner, thus producing the digest messages into the
     # virgin queue.
     make_digest_messages(self._mlist)
     # Run the virgin queue processor, which runs the cook-headers and
     # to-outgoing handlers.  This should produce no error.
     error_log = LogFileMark('mailman.error')
     runner = make_testable_runner(VirginRunner, 'virgin')
     runner.run()
     error_text = error_log.read()
     self.assertEqual(len(error_text), 0, error_text)
     get_queue_messages('shunt', expected_count=0)
     items = get_queue_messages('out', expected_count=2)
     # Which one is the MIME digest?
     mime_digest = None
     for item in items:
         if item.msg.get_content_type() == 'multipart/mixed':
             assert mime_digest is None, 'Found two MIME digests'
             mime_digest = item.msg
     # The cook-headers handler ran.
     self.assertIn('x-mailman-version', mime_digest)
     self.assertEqual(mime_digest['precedence'], 'list')
     # The list's -request address is the original sender.
     self.assertEqual(item.msgdata['original_sender'],
                      '*****@*****.**')
Beispiel #55
0
 def test_digest_messages(self):
     # In LP: #1130697, the digest runner creates MIME digests using the
     # stdlib MIMEMutlipart class, however this class does not have the
     # extended attributes we require (e.g. .sender).  The fix is to use a
     # subclass of MIMEMultipart and our own Message subclass; this adds
     # back the required attributes.  (LP: #1130696)
     self._mlist.send_welcome_message = False
     # Subscribe some users receiving digests.
     anne = subscribe(self._mlist, 'Anne')
     anne.preferences.delivery_mode = DeliveryMode.mime_digests
     bart = subscribe(self._mlist, 'Bart')
     bart.preferences.delivery_mode = DeliveryMode.plaintext_digests
     # Start by creating the raw ingredients for the digests.  This also
     # runs the digest runner, thus producing the digest messages into the
     # virgin queue.
     make_digest_messages(self._mlist)
     # Run the virgin queue processor, which runs the cook-headers and
     # to-outgoing handlers.  This should produce no error.
     error_log = LogFileMark('mailman.error')
     runner = make_testable_runner(VirginRunner, 'virgin')
     runner.run()
     error_text = error_log.read()
     self.assertEqual(len(error_text), 0, error_text)
     get_queue_messages('shunt', expected_count=0)
     items = get_queue_messages('out', expected_count=2)
     # Which one is the MIME digest?
     mime_digest = None
     for item in items:
         if item.msg.get_content_type() == 'multipart/mixed':
             assert mime_digest is None, 'Found two MIME digests'
             mime_digest = item.msg
     # The cook-headers handler ran.
     self.assertIn('x-mailman-version', mime_digest)
     self.assertEqual(mime_digest['precedence'], 'list')
     # The list's -request address is the original sender.
     self.assertEqual(item.msgdata['original_sender'],
                      '*****@*****.**')
Beispiel #56
0
 def setUp(self):
     self._mlist = create_list('*****@*****.**')
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
Beispiel #57
0
    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 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', expected_count=1)
        msg = items[0].msg
        # Confirmations come first, so this one goes to the subscriber.
        self.assertEqual(msg['to'], '*****@*****.**')
        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'] = '*****@*****.**'
        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', expected_count=2)
        if items[0].msg['to'] == '*****@*****.**':
            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'], '*****@*****.**')
        self.assertEqual(
            moderator_msg['subject'],
            'New subscription request to Test from [email protected]')
        lines = moderator_msg.get_payload().splitlines()
        self.assertEqual(lines[-2].strip(),
                         'For:  Bart Person <*****@*****.**>')
        self.assertEqual(lines[-1].strip(), 'List: [email protected]')
        # 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: [email protected]
Subject: Re: confirm {}
Date: n/a
Message-ID: n/a

- Results:
Confirmed

- Done.
""".format(token))
 def setUp(self):
     self._commandq = config.switchboards['command']
     self._runner = make_testable_runner(CommandRunner, 'command')
     with transaction():
         # Register a subscription requiring confirmation.
         self._mlist = create_list('*****@*****.**')