------------------------------------------------------------
revno: 6521
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Tue 2007-07-03 01:09:53 -0400
message:
  Convert TestHold to a doctest and update code as necessary.  No general
  modernization of Hold.py was performed.
added:
  Mailman/docs/hold.txt
modified:
  Mailman/Handlers/Hold.py
  Mailman/ListAdmin.py
  Mailman/MailList.py
  Mailman/database/model/mailinglist.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/hold.txt'
--- a/Mailman/docs/hold.txt     1970-01-01 00:00:00 +0000
+++ b/Mailman/docs/hold.txt     2007-07-03 05:09:53 +0000
@@ -0,0 +1,373 @@
+Holding messages
+================
+
+One of the most important functions of Mailman is to moderate messages by
+holding some for approval before they will post to the mailing list.  Messages
+are held when they meet any of a number of criteria.
+
+    >>> import os
+    >>> import errno
+    >>> from Mailman.Handlers.Hold import process
+    >>> from Mailman.Queue.Switchboard import Switchboard
+    >>> from Mailman.configuration import config
+    >>> from Mailman.database import flush
+    >>> mlist = config.list_manager.create('[EMAIL PROTECTED]')
+    >>> mlist.preferred_language = 'en'
+    >>> mlist.real_name = '_XTest'
+    >>> # XXX This will almost certainly change once we've worked out the web
+    >>> # space layout for mailing lists now.
+    >>> mlist._data.web_page_url = 'http://lists.example.com/'
+    >>> flush()
+
+XXX The Hold handler requires that the mailing list be locked because it
+touches the pending database.  Eventually the pending database should be moved
+into the real database so that the lock is no longer necessary.
+
+    >>> mlist.Lock()
+
+Here's a helper function used when we don't care about what's in the virgin
+queue or in the pending database.
+
+    >>> switchboard = Switchboard(config.VIRGINQUEUE_DIR)
+    >>> def clear():
+    ...     for filebase in switchboard.files:
+    ...         msg, msgdata = switchboard.dequeue(filebase)
+    ...         switchboard.finish(filebase)
+    ...     for holdfile in os.listdir(config.DATA_DIR):
+    ...         if holdfile.startswith('heldmsg-'):
+    ...             os.unlink(os.path.join(config.DATA_DIR, holdfile))
+    ...     try:
+    ...         os.unlink(os.path.join(config.DATA_DIR, 'pending.db'))
+    ...     except OSError, e:
+    ...         if e.errno <> errno.ENOENT:
+    ...             raise
+
+
+Short circuiting
+----------------
+
+If the message metadata indicates that the message is pre-approved, then the
+handler returns immediately.
+
+    >>> from email import message_from_string
+    >>> from Mailman.Message import Message
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ...
+    ... An important message.
+    ... """, Message)
+    >>> msgdata = {'approved': True}
+    >>> process(mlist, msg, msgdata)
+    >>> print msg.as_string()
+    From: [EMAIL PROTECTED]
+    <BLANKLINE>
+    An important message.
+    <BLANKLINE>
+    >>> msgdata
+    {'approved': True}
+
+
+Administrivia
+-------------
+
+Mailman scans parts of the message for administrivia, meaning text that looks
+like an email command.  This is to prevent people sending 'help' or
+'subscribe' message, etc. to the list members.  First, we enable the scanning
+of administrivia for the list.
+
+    >>> mlist.administrivia = True
+    >>> flush()
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... Subject: unsubscribe
+    ...
+    ... """, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    Administrivia
+    >>> clear()
+
+
+Maximum number of recipients
+----------------------------
+
+Mailman will hold messages that have more than a specified number of explicit
+recipients.
+
+    >>> mlist.max_num_recipients = 5
+    >>> flush()
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED], [EMAIL PROTECTED]
+    ... Cc: [EMAIL PROTECTED]
+    ... Cc: [EMAIL PROTECTED] (Dan Person)
+    ... To: Elly Q. Person <[EMAIL PROTECTED]>
+    ...
+    ... Hey folks!
+    ... """, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    TooManyRecipients
+    >>> clear()
+
+
+Implicit destination
+--------------------
+
+Mailman will hold messages that have implicit destination, meaning that the
+mailing list's posting address isn't included in the explicit recipients.
+
+    >>> mlist.require_explicit_destination = True
+    >>> mlist.acceptable_aliases = ''
+    >>> flush()
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... Subject: An implicit message
+    ...
+    ... """, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    ImplicitDestination
+    >>> clear()
+
+A message gated from NNTP will obviously have an implicit destination.  Such
+gated messages will not be held for implicit destination because it's assumed
+that Mailman pulled it from the appropriate news group.
+
+    >>> msgdata = {'fromusenet': True}
+    >>> process(mlist, msg, msgdata)
+    >>> print msg.as_string()
+    From: [EMAIL PROTECTED]
+    Subject: An implicit message
+    <BLANKLINE>
+    >>> print msgdata
+    {'fromusenet': True}
+
+
+Suspicious headers
+------------------
+
+Suspicious headers are a way for Mailman to hold messages that match a
+particular regular expression.  This mostly historical feature is fairly
+confusing to users, and the list attribute that controls this is misnamed.
+
+    >>> mlist.bounce_matching_headers = 'From: .*person@(blah.)?example.com'
+    >>> flush()
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED]
+    ... Subject: An implicit message
+    ... 
+    ... """, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    SuspiciousHeaders
+    >>> clear()
+
+But if the header doesn't match the regular expression, it'll get posted just
+fine.  This one comes from a .org address.
+
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED]
+    ... Subject: An implicit message
+    ... 
+    ... """, Message)
+    >>> msgdata = {}
+    >>> process(mlist, msg, msgdata)
+    >>> print msgdata
+    {}
+
+Just a bit of clean up.
+
+    >>> mlist.bounce_matching_headers = None
+    >>> flush()
+
+
+Message size
+------------
+
+Mailman can hold messages that are bigger than a given size.  Generally this
+is used to prevent huge attachments from getting posted to the list.  This
+value is calculated in terms of KB (1024 bytes).
+
+    >>> mlist.max_message_size = 1
+    >>> flush()
+    >>> one_line = 'x' * 79
+    >>> big_body = '\n'.join([one_line] * 15)
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED]
+    ...
+    ... """ + big_body, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    MessageTooBig
+    >>> clear()
+
+
+Hold Notifications
+------------------
+
+Whenever Mailman holds a message, it sends notifications both to the list
+owner and to the original sender, as long as it is configured to do so.  We
+can show this by first holding a message.
+
+    >>> mlist.respond_to_post_requests = True
+    >>> mlist.admin_immed_notify = True
+    >>> flush()
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ...
+    ... """, Message)
+    >>> process(mlist, msg, {})
+    Traceback (most recent call last):
+    ...
+    ImplicitDestination
+
+There should be two messages in the virgin queue, one to the list owner and
+one to the original author.
+
+    >>> len(switchboard.files)
+    2
+    >>> qfiles = {}
+    >>> for filebase in switchboard.files:
+    ...     qmsg, qdata = switchboard.dequeue(filebase)
+    ...     switchboard.finish(filebase)
+    ...     qfiles[qmsg['to']] = qmsg, qdata
+    >>> qmsg, qdata = qfiles['[EMAIL PROTECTED]']
+    >>> print qmsg.as_string()
+    Subject: _xtest post from [EMAIL PROTECTED] requires approval
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    MIME-Version: 1.0
+    Content-Type: multipart/mixed; boundary="..."
+    Message-ID: ...
+    Date: ...
+    Precedence: bulk
+    <BLANKLINE>
+    --...
+    Content-Type: text/plain; charset="us-ascii"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: 7bit
+    <BLANKLINE>
+    As list administrator, your authorization is requested for the
+    following mailing list posting:
+    <BLANKLINE>
+        List:    [EMAIL PROTECTED]
+        From:    [EMAIL PROTECTED]
+        Subject: (no subject)
+        Reason:  Message has implicit destination
+    <BLANKLINE>
+    At your convenience, visit:
+    <BLANKLINE>
+        http://lists.example.com/admindb/[EMAIL PROTECTED]
+    <BLANKLINE>
+    to approve or deny the request.
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    Content-Type: text/plain; charset="us-ascii"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: 7bit
+    Subject: confirm ...
+    Sender: [EMAIL PROTECTED]
+    From: [EMAIL PROTECTED]
+    Date: ...
+    Message-ID: ...
+    <BLANKLINE>
+    If you reply to this message, keeping the Subject: header intact,
+    Mailman will discard the held message.  Do this if the message is
+    spam.  If you reply to this message and include an Approved: header
+    with the list password in it, the message will be approved for posting
+    to the list.  The Approved: header can also appear in the first line
+    of the body of the reply.
+    --...
+    >>> sorted(qdata.items())
+    [('_parsemsg', False), ('listname', '[EMAIL PROTECTED]'),
+     ('nodecorate', True), ('received_time', ...),
+     ('recips', ['[EMAIL PROTECTED]']),
+     ('reduced_list_headers', True),
+     ('tomoderators', 1), ('version', 3)]
+    >>> qmsg, qdata = qfiles['[EMAIL PROTECTED]']
+    >>> print qmsg.as_string()
+    MIME-Version: 1.0
+    Content-Type: text/plain; charset="us-ascii"
+    Content-Transfer-Encoding: 7bit
+    Subject: Your message to _xtest awaits moderator approval
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    Date: ...
+    Precedence: bulk
+    <BLANKLINE>
+    Your mail to '_xtest' with the subject
+    <BLANKLINE>
+        (no subject)
+    <BLANKLINE>
+    Is being held until the list moderator can review it for approval.
+    <BLANKLINE>
+    The reason it is being held:
+    <BLANKLINE>
+        Message has implicit destination
+    <BLANKLINE>
+    Either the message will get posted to the list, or you will receive
+    notification of the moderator's decision.  If you would like to cancel
+    this posting, please visit the following URL:
+    <BLANKLINE>
+        http://lists.example.com/confirm/[EMAIL PROTECTED]/...
+    <BLANKLINE>
+    <BLANKLINE>
+    >>> sorted(qdata.items())
+    [('_parsemsg', False), ('listname', '[EMAIL PROTECTED]'),
+     ('nodecorate', True), ('received_time', ...),
+     ('recips', ['[EMAIL PROTECTED]']),
+     ('reduced_list_headers', True), ('version', 3)]
+
+In addition, the pending database is holding the original messages, waiting
+for them to be disposed of by the original author or the list moderators.  The
+database is essentially a dictionary, with the keys being the randomly
+selected tokens included in the urls and the values being a 2-tuple where the
+first item is a type code and the second item is a message id.
+
+    >>> import re
+    >>> cookie = None
+    >>> qmsg, qdata = qfiles['[EMAIL PROTECTED]']
+    >>> for line in qmsg.get_payload().splitlines():
+    ...     mo = re.search('confirm/[^/]+/(?P<cookie>.*)$', line)
+    ...     if mo:
+    ...         cookie = mo.group('cookie')
+    ...         break
+    >>> data = mlist.pend_confirm(cookie)
+    >>> data
+    ('H', ...)
+    >>> filename = '[EMAIL PROTECTED]' % data[1]
+    >>> heldmsg = os.path.join(config.DATA_DIR, filename)
+
+Use helper function to read the held message.
+
+    >>> from Mailman.ListAdmin import readMessage
+    >>> msg = readMessage(heldmsg)
+    >>> print msg.as_string()
+    From: [EMAIL PROTECTED]
+    <BLANKLINE>
+    <BLANKLINE>
+ 
+Clean up.
+
+    >>> clear()
+    >>> mlist.Unlock()

=== modified file 'Mailman/Handlers/Hold.py'
--- a/Mailman/Handlers/Hold.py  2007-03-21 14:11:53 +0000
+++ b/Mailman/Handlers/Hold.py  2007-07-03 05:09:53 +0000
@@ -84,7 +84,7 @@
 
     def rejection_notice(self, mlist):
         listurl = mlist.GetScriptURL('listinfo', absolute=1)
-        request = mlist.GetRequestEmail()
+        request = mlist.request_address
         return _("""Please do *not* post administrative requests to the mailing
 list.  If you wish to subscribe, visit $listurl or send a message with the
 word `help' in it to the request address, $request, for further
@@ -133,7 +133,7 @@
     if msgdata.get('approved'):
         return
     # Get the sender of the message
-    listname = mlist.internal_name()
+    listname = mlist.list_name
     adminaddr = listname + '-admin'
     sender = msg.get_sender()
     # Special case an ugly sendmail feature: If there exists an alias of the
@@ -204,7 +204,7 @@
     if isinstance(exc, ClassType) or isinstance(exc, type):
         # Go ahead and instantiate it now.
         exc = exc()
-    listname = mlist.real_name
+    listname = mlist.list_name
     sender = msgdata.get('sender', msg.get_sender())
     usersubject = msg.get('subject')
     charset = Utils.GetCharSet(mlist.preferred_language)
@@ -213,9 +213,9 @@
     else:
         usersubject = _('(no subject)')
     message_id = msg.get('message-id', 'n/a')
-    owneraddr = mlist.GetOwnerEmail()
-    adminaddr = mlist.GetBouncesEmail()
-    requestaddr = mlist.GetRequestEmail()
+    owneraddr = mlist.owner_address
+    adminaddr = mlist.bounces_address
+    requestaddr = mlist.request_address
     # We need to send both the reason and the rejection notice through the
     # translator again, because of the games we play above
     reason = Utils.wrap(exc.reason_notice())
@@ -240,12 +240,17 @@
     # This message should appear to come from <list>-admin so as to handle any
     # bounce processing that might be needed.
     cookie = mlist.pend_new(Pending.HELD_MESSAGE, id)
+    # Get the language to send the response in.  If the sender is a member,
+    # then send it in the member's language, otherwise send it in the mailing
+    # list's preferred language.
+    member = mlist.members.get_member(sender)
+    lang = (member.preferred_language if member else mlist.preferred_language)
     if not fromusenet and ackp(msg) and mlist.respond_to_post_requests and \
-           mlist.autorespondToSender(sender, mlist.getMemberLanguage(sender)):
+           mlist.autorespondToSender(sender, lang):
         # Get a confirmation cookie
         d['confirmurl'] = '%s/%s' % (mlist.GetScriptURL('confirm', absolute=1),
                                      cookie)
-        lang = msgdata.get('lang', mlist.getMemberLanguage(sender))
+        lang = msgdata.get('lang', lang)
         subject = _('Your message to $listname awaits moderator approval')
         text = Utils.maketext('postheld.txt', d, lang=lang, mlist=mlist)
         nmsg = Message.UserNotification(sender, adminaddr, subject, text, lang)

=== modified file 'Mailman/ListAdmin.py'
--- a/Mailman/ListAdmin.py      2007-05-28 20:21:41 +0000
+++ b/Mailman/ListAdmin.py      2007-07-03 05:09:53 +0000
@@ -68,10 +68,6 @@
 
 
 class ListAdmin:
-    def InitVars(self):
-        # non-configurable data
-        self.next_request_id = 1
-
     def InitTempVars(self):
         self._db = None
         self._filename = os.path.join(self.full_path, 'request.pck')
@@ -114,7 +110,7 @@
             next = self.next_request_id
             self.next_request_id += 1
             if self._db.setdefault(next, missing) is missing:
-                yield next
+                return next
 
     def SaveRequestsDb(self):
         self._closedb()
@@ -183,7 +179,7 @@
             ext = 'pck'
         else:
             ext = 'txt'
-        filename = 'heldmsg-%s-%d.%s' % (self.internal_name(), id, ext)
+        filename = 'heldmsg-%s-%d.%s' % (self.fqdn_listname, id, ext)
         with open(os.path.join(config.DATA_DIR, filename), 'w') as fp:
             if config.HOLD_MESSAGES_AS_PICKLES:
                 cPickle.dump(msg, fp, 1)

=== modified file 'Mailman/MailList.py'
--- a/Mailman/MailList.py       2007-07-02 22:45:13 +0000
+++ b/Mailman/MailList.py       2007-07-03 05:09:53 +0000
@@ -155,19 +155,17 @@
             self._lock.lock()
 
     def Lock(self, timeout=0):
-        database.lock(self)
         self._lock.lock(timeout)
         self._memberadaptor.lock()
         # Must reload our database for consistency.  Watch out for lists that
         # don't exist.
         try:
-            self.Load(self.fqdn_listname)
+            self.Load()
         except Exception:
             self.Unlock()
             raise
 
     def Unlock(self):
-        database.unlock(self)
         self._lock.unlock(unconditionally=True)
         self._memberadaptor.unlock()
 
@@ -551,15 +549,12 @@
         # the lock (which is a serious problem!).  TBD: do we need to be more
         # defensive?
         self._lock.refresh()
-        # Commit the database transaction
-        database.save(self)
         # The member adaptor may have its own save operation
         self._memberadaptor.save()
         self.SaveRequestsDb()
         self.CheckHTMLArchiveDir()
 
     def Load(self):
-        database.load(self)
         self._memberadaptor.load()
 
 
@@ -1235,7 +1230,7 @@
             addr = addr.lower()
             localpart = addr.split('@')[0]
             if (# TBD: backwards compatibility: deprecated
-                    localpart == self.internal_name() or
+                    localpart == self.list_name or
                     # exact match against the complete list address
                     addr == self.fqdn_listname):
                 return True

=== modified file 'Mailman/database/model/mailinglist.py'
--- a/Mailman/database/model/mailinglist.py     2007-06-21 14:23:40 +0000
+++ b/Mailman/database/model/mailinglist.py     2007-07-03 05:09:53 +0000
@@ -40,6 +40,7 @@
     # Attributes not directly modifiable via the web u/i
     has_field('web_page_url',                               Unicode),
     has_field('admin_member_chunksize',                     Integer),
+    has_field('hold_and_cmd_autoresponses',                 PickleType),
     # Attributes which are directly modifiable via the web u/i.  The more
     # complicated attributes are currently stored as pickles, though that
     # will change as the schema and implementation is developed.
@@ -167,6 +168,8 @@
         listname, hostname = split_listname(fqdn_listname)
         self.list_name = listname
         self.host_name = hostname
+        # For the pending database
+        self.next_request_id = 1
         # Create several rosters for filtering out or querying the membership
         # table.
         from Mailman.database.model import roster
@@ -176,6 +179,10 @@
         self.members = roster.MemberRoster(self)
         self.regular_members = roster.RegularMemberRoster(self)
         self.digest_members = roster.DigestMemberRoster(self)
+        # Max autoresponses per day.  A mapping between addresses and a
+        # 2-tuple of the date of the last autoresponse and the number of
+        # autoresponses sent on that date.
+        self.hold_and_cmd_autoresponses = {}
 
     @property
     def fqdn_listname(self):

=== modified file 'Mailman/testing/test_handlers.py'
--- a/Mailman/testing/test_handlers.py  2007-07-02 22:45:13 +0000
+++ b/Mailman/testing/test_handlers.py  2007-07-03 05:09:53 +0000
@@ -39,7 +39,6 @@
 from Mailman.Handlers import Acknowledge
 from Mailman.Handlers import AfterDelivery
 from Mailman.Handlers import Approve
-from Mailman.Handlers import Hold
 from Mailman.Handlers import MimeDel
 from Mailman.Handlers import Moderate
 from Mailman.Handlers import Scrubber
@@ -134,164 +133,6 @@
 
 
 
-class TestHold(TestBase):
-    def setUp(self):
-        TestBase.setUp(self)
-        self._mlist.administrivia = 1
-        self._mlist.respond_to_post_requests = 0
-        self._mlist.admin_immed_notify = 0
-        # We're going to want to inspect this queue directory
-        self._sb = Switchboard(config.VIRGINQUEUE_DIR)
-
-    def tearDown(self):
-        for f in os.listdir(config.VIRGINQUEUE_DIR):
-            os.unlink(os.path.join(config.VIRGINQUEUE_DIR, f))
-        TestBase.tearDown(self)
-        try:
-            os.unlink(os.path.join(config.DATA_DIR, 'pending.db'))
-        except OSError, e:
-            if e.errno <> errno.ENOENT: raise
-        for f in [holdfile for holdfile in os.listdir(config.DATA_DIR)
-                  if holdfile.startswith('heldmsg-')]:
-            os.unlink(os.path.join(config.DATA_DIR, f))
-
-    def test_short_circuit(self):
-        msgdata = {'approved': 1}
-        rtn = Hold.process(self._mlist, None, msgdata)
-        # Not really a great test, but there's little else to assert
-        self.assertEqual(rtn, None)
-
-    def test_administrivia(self):
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-Subject: unsubscribe
-
-""", Message.Message)
-        self.assertRaises(Hold.Administrivia, Hold.process,
-                          self._mlist, msg, {})
-
-    def test_max_recips(self):
-        self._mlist.max_num_recipients = 5
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED], [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED] (Jimmy D. Person)
-To: Billy E. Person <[EMAIL PROTECTED]>
-
-Hey folks!
-""", Message.Message)
-        self.assertRaises(Hold.TooManyRecipients, Hold.process,
-                          self._mlist, msg, {})
-
-    def test_implicit_destination(self):
-        self._mlist.require_explicit_destination = 1
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-Subject: An implicit message
-
-""", Message.Message)
-        self.assertRaises(Hold.ImplicitDestination, Hold.process,
-                          self._mlist, msg, {})
-
-    def test_implicit_destination_fromusenet(self):
-        self._mlist.require_explicit_destination = 1
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-Subject: An implicit message
-
-""", Message.Message)
-        rtn = Hold.process(self._mlist, msg, {'fromusenet': 1})
-        self.assertEqual(rtn, None)
-
-    def test_suspicious_header(self):
-        self._mlist.bounce_matching_headers = 'From: 
.*person@(blah.)?example.org'
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Subject: An implicit message
-
-""", Message.Message)
-        self.assertRaises(Hold.SuspiciousHeaders, Hold.process,
-                          self._mlist, msg, {})
-
-    def test_suspicious_header_ok(self):
-        self._mlist.bounce_matching_headers = 'From: [EMAIL PROTECTED]'
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Subject: An implicit message
-
-""", Message.Message)
-        rtn = Hold.process(self._mlist, msg, {})
-        self.assertEqual(rtn, None)
-
-    def test_max_message_size(self):
-        self._mlist.max_message_size = 1
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-""", Message.Message)
-        self.assertRaises(Hold.MessageTooBig, Hold.process,
-                          self._mlist, msg, {})
-
-    def test_hold_notifications(self):
-        eq = self.assertEqual
-        self._mlist.respond_to_post_requests = 1
-        self._mlist.admin_immed_notify = 1
-        # Now cause an implicit destination hold
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-
-""", Message.Message)
-        self.assertRaises(Hold.ImplicitDestination, Hold.process,
-                          self._mlist, msg, {})
-        # Now we have to make sure there are two messages in the virgin queue,
-        # one to the sender and one to the list owners.
-        qfiles = {}
-        files = self._sb.files()
-        eq(len(files), 2)
-        for filebase in files:
-            qmsg, qdata = self._sb.dequeue(filebase)
-            to = qmsg['to']
-            qfiles[to] = qmsg, qdata
-        # BAW: We could be testing many other attributes of either the
-        # messages or the metadata files...
-        keys = qfiles.keys()
-        keys.sort()
-        eq(keys, ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]'])
-        # Get the pending cookie from the message to the sender
-        pmsg, pdata = qfiles['[EMAIL PROTECTED]']
-        confirmlines = pmsg.get_payload().split('\n')
-        cookie = confirmlines[-3].split('/')[-1]
-        # We also need to make sure there's an entry in the Pending database
-        # for the hold message.
-        data = self._mlist.pend_confirm(cookie)
-        eq(data, ('H', 1))
-        heldmsg = os.path.join(config.DATA_DIR, 'heldmsg-_xtest-1.pck')
-        self.failUnless(os.path.exists(heldmsg))
-        os.unlink(heldmsg)
-        holdfiles = [f for f in os.listdir(config.DATA_DIR)
-                     if f.startswith('heldmsg-')]
-        eq(len(holdfiles), 0)
-
-
-
 class TestMimeDel(TestBase):
     def setUp(self):
         TestBase.setUp(self)
@@ -968,7 +809,6 @@
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(TestApprove))
-    suite.addTest(unittest.makeSuite(TestHold))
     suite.addTest(unittest.makeSuite(TestMimeDel))
     suite.addTest(unittest.makeSuite(TestModerate))
     suite.addTest(unittest.makeSuite(TestScrubber))



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to