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._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)
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>')
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))
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>')
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
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")
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')
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'], '*****@*****.**')
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
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, '*****@*****.**')
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')
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')
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 """)
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')
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 """)
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")
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)
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()
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)
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 = {}
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
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)
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
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')
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] """)
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)
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']
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_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] """ )
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')
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> """)
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> """)
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] """)
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> """)
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')
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> """)
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> """)
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> """)
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'], '*****@*****.**')
def setUp(self): self._mlist = create_list('*****@*****.**') self._commandq = config.switchboards['command'] self._runner = make_testable_runner(CommandRunner, 'command')
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('*****@*****.**')