o
    b                    @   s  d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZmZmZ ddlm Z  ddl!m"Z"m#Z# ddl$m%Z%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddl@mAZAmBZB z
ddlCmDZDmEZE W n eFy   dZDdZEY nw dd ZGG dd deBZHG dd dZIG dd  d eAZJG d!d" d"eAZKG d#d$ d$eBZLee,jMe,jNe,jOG d%d& d&ZPee,jMe,jNG d'd( d(ZQG d)d* d*e,jRZSG d+d, d,eSe,jTZUG d-d. d.e,jVZWG d/d0 d0e,jXZYG d1d2 d2ZZG d3d4 d4eZeBZ[G d5d6 d6eAZ\G d7d8 d8eZeBZ]ee"G d9d: d:Z^G d;d< d<Z_G d=d> d>eZeBZ`G d?d@ d@eBZaG dAdB dBeZeBZbG dCdD dDeBZcG dEdF dFe,jXZdG dGdH dHeZeBZeG dIdJ dJZfG dKdL dLefZgG dMdN dNegeAZhG dOdP dPegeAZiG dQdR dRefeAZjG dSdT dTefeAZkG dUdV dVefeAZlG dWdX dXefeBZmG dYdZ dZefeAZnG d[d\ d\efeAZoG d]d^ d^e,jVZpee,jqG d_d` d`e8jrZsG dadb dbeBeZZtG dcdd ddeBZuG dedf dfeBeZZvG dgdh dheZeBZwee,jxG didj djeBeZZyG dkdl dlZzee,j{G dmdn dnZ|ee,j}G dodp dpZ~G dqdr dreBZeeD dsee'e(d dtG dudv dveZeBZG dwdx dxePZG dydz dzeZeBZG d{d| d|eBZG d}d~ d~ZG dd deBZG dd deBZG dd dZG dd deeAZG dd deeBZG dd deAZdS )z"
Test case for twisted.mail.imap4
    N)OrderedDictBytesIO)chain)ListOptionalTupleType)skipIf)implementer)verifyClassverifyObject)'InMemoryUsernamePasswordDatabaseDontUse)CramMD5CredentialsIUsernameHashedPasswordIUsernamePasswordUnauthorizedLogin)IRealmPortal)defererror
interfacesreactor)Clock)imap4)
MessageSet)IChallengeResponseIClientAuthenticationICloseableMailboxIMAP)loopback)failurelogutil)	iterbytesnativeStringnetworkString)StringTransport StringTransportWithDisconnection)SynchronousTestCaseTestCase)ClientTLSContextServerTLSContextc                 C   s   | fddS )Nc                 S   s   | S N )resultfr.   r.   =/usr/lib/python3/dist-packages/twisted/mail/test/test_imap.py<lambda>8       zstrip.<locals>.<lambda>r.   )r0   r.   r.   r1   strip7      r4   c                   @   sv   e Zd Zddgddgddgddgd	d
ggZdd Zdd Zdd Zdd Zdd Zdd Z	dd Z
dd Zdd ZdS )IMAP4UTF7TestsHello world   Hello worldzHello & worlds   Hello &- world   Helloÿworld   Hello&AP8-worldu   ÿþýüs   &AP8A,gD9APw-u   ~peter/mail/日本語/台北s   ~peter/mail/&ZeVnLIqe-/&U,BTFw-c                 C   "   d}|  |dd|d dS )z
        Specifying an error policy to C{unicode.encode} with the
        I{imap4-utf-7} codec should produce the same result as not
        specifying the error policy.
        r7   imap4-utf-7strictNassertEqualencodeselftextr.   r.   r1   test_encodeWithErrorsG   s   z$IMAP4UTF7Tests.test_encodeWithErrorsc                 C   r;   )zO
        Similar to L{test_encodeWithErrors}, but for C{bytes.decode}.
        r8   r<   r=   Nr?   decoderB   bytesr.   r.   r1   test_decodeWithErrorsR   s   z$IMAP4UTF7Tests.test_decodeWithErrorsc                 C   s   d}|  |dd dS )z
        Unicode strings that contain an ampersand (C{&}) can be
        encoded to bytes with the I{imap4-utf-7} codec.
        u
   &Hello&½&r<   s   &-Hello&-&AL0-&-Nr>   rA   r.   r.   r1   test_encodeAmpersand[   s
   z#IMAP4UTF7Tests.test_encodeAmpersandc                 C   s   |  ddd dS )z
        An I{imap4-utf-7} encoded string that does not shift back to
        ASCII (i.e., it lacks a final C{-}) can be decoded.
        s   &AL0r<      ½NrE   rB   r.   r.   r1   !test_decodeWithoutFinalASCIIShiftf   s   z0IMAP4UTF7Tests.test_decodeWithoutFinalASCIIShiftc                 C   s&   t dtd}| | d dS )zl
        C{codecs.getreader('imap4-utf-7')} returns the I{imap4-utf-7} stream
        reader class.
        r<   r:   r9   N)codecs	getreaderr   r?   read)rB   readerr.   r.   r1   test_getreaderp   s   zIMAP4UTF7Tests.test_getreaderc                 C   s2   t  }td|}|d | | d dS )zl
        C{codecs.getwriter('imap4-utf-7')} returns the I{imap4-utf-7} stream
        writer class.
        r<   r9   r:   N)r   rN   	getwriterwriter?   getvalue)rB   outputwriterr.   r.   r1   test_getwriterx   s   
zIMAP4UTF7Tests.test_getwriterc                 C   s&   | j D ]\}}| |d| qdS )z
        The I{imap4-utf-7} can be used to encode a unicode string into a byte
        string according to the IMAP4 modified UTF-7 encoding rules.
        r<   N)testsr?   r@   rB   inputrV   r.   r.   r1   test_encode      zIMAP4UTF7Tests.test_encodec                 C   s&   | j D ]\}}| ||d qdS )z
        The I{imap4-utf-7} can be used to decode a byte string into a unicode
        string according to the IMAP4 modified UTF-7 encoding rules.
        r<   N)rY   r?   rF   rZ   r.   r.   r1   test_decode   r]   zIMAP4UTF7Tests.test_decodec                 C   s|   t tddtddD ]}t| }| |t|d | t||d q| ddd | ddd dS )	z
        The IMAP4 modified UTF-7 implementation encodes all printable
        characters which are in ASCII using the corresponding ASCII byte.
            &   '      r<   &s   &-N)r   rangechrr@   r?   rF   )rB   ocharbyter.   r.   r1   test_printableSingletons   s   z'IMAP4UTF7Tests.test_printableSingletonsN)__name__
__module____qualname__rY   rD   rI   rJ   rM   rR   rX   r\   r^   rh   r.   r.   r.   r1   r6   ;   s$    	

r6   c                   @   ,   e Zd Zdd Zdd Zdd Zdd Zd	S )
BufferingConsumerc                 C   
   g | _ d S r-   )bufferrL   r.   r.   r1   __init__      
zBufferingConsumer.__init__c                 C   s$   | j | | jr| j  d S d S r-   )ro   appendconsumerresumeProducingrG   r.   r.   r1   rT      s   zBufferingConsumer.writec                 C   s   || _ | j   d S r-   )rs   rt   )rB   rs   	streamingr.   r.   r1   registerProducer      z"BufferingConsumer.registerProducerc                 C   s
   d | _ d S r-   )rs   rL   r.   r.   r1   unregisterProducer   rq   z$BufferingConsumer.unregisterProducerN)ri   rj   rk   rp   rT   rv   rx   r.   r.   r.   r1   rm      s
    rm   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )MessageProducerTestsc                    sr   d t  }d|d< d|d< d|d< d|d	< t|d
d  dd }t t|} fdd}||S )Ns   This is body text.  Rar.sender@hostfromrecipient@domaintobooga booga boosubject
text/plaincontent-typer.   {   c                    s(    |  djd   d S )N    sf   {119}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: text/plain

)assertIdenticalr?   joinro   r/   bodycprB   r.   r1   
cbProduced   s   
z7MessageProducerTests.testSinglePart.<locals>.cbProducedr   FakeyMessagerm   r   MessageProducerbeginProducingaddCallback)rB   headersmsgdr   r.   r   r1   testSinglePart   s   


z#MessageProducerTests.testSinglePartc                    s   d}dt  }d|d< d|d< d|d< d	|d
< t  }d|d< d|d
< t|dd |dt|dd d d g}t  t| } fdd}||S )Nr   &   Contained body message text.  Squarge.rz   r{   r|   r}   r~   r   %multipart/alternative; boundary="xyz"r   this is subject textr   r.   r   c                    ,    |  d jd d  d S )Nr   s   {239}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: multipart/alternative; boundary="xyz"


--xyz
Subject: this is subject text
Content-Type: text/plain

   
--xyz--
failUnlessIdenticalr?   r   ro   r   r   	innerBodyr   rB   r.   r1   r      s   


z<MessageProducerTests.testSingleMultiPart.<locals>.cbProducedr   rB   	outerBodyr   innerHeadersr   r   r   r.   r   r1   testSingleMultiPart   s.   	


z(MessageProducerTests.testSingleMultiPartc                    s   d}ddt  }d|d< d|d< d|d	< d
|d< t  }d|d	< d|d< t  }d|d	< d|d< t|dd |dt|dd d d t|dd d d g}t  t| } fdd}||S )Nr   r   .   Secondary <i>message</i> text of squarge body.rz   r{   r|   r}   r~   r   r   r   r   r   <b>this is subject</b>	text/htmlr.   r   c                    s4    |  d jd d  d  d S )Nr   s   {354}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: multipart/alternative; boundary="xyz"


--xyz
Subject: this is subject text
Content-Type: text/plain

sE   
--xyz
Subject: <b>this is subject</b>
Content-Type: text/html

r   r   r   r   
innerBody1
innerBody2r   rB   r.   r1   r     s   


z>MessageProducerTests.testMultipleMultiPart.<locals>.cbProducedr   )rB   r   r   r   innerHeaders2r   r   r   r.   r   r1   testMultipleMultiPart   s:   


z*MessageProducerTests.testMultipleMultiPartc                    s   d}dt  }d|d< d|d< d|d< d	|d
< t  }d|d< d|d
< t|dd|dt|ddddg}t  t|dd _ } fdd}||S )z>
        A boundary is generated if none is provided.
        r   r   rz   r{   r|   r}   r~   r   multipart/alternativer   r   r   r.   Nr   c                   S   s
   t dS )Nz$aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa)uuidUUIDr.   r.   r.   r1   r2   K     
 z?MessageProducerTests.test_multiPartNoBoundary.<locals>.<lambda>c                    r   )Nr   s	  {341}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: multipart/alternative; boundary="----=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"


------=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Subject: this is subject text
Content-Type: text/plain

s-   
------=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--
r   r   r   r.   r1   r   O  s   
zAMessageProducerTests.test_multiPartNoBoundary.<locals>.cbProduced)r   r   rm   r   r   _uuid4r   r   r   r.   r   r1   test_multiPartNoBoundary1  s0   	



z-MessageProducerTests.test_multiPartNoBoundaryc                    s   d}dt  }d|d< d|d< d|d< d	|d
< t  }d|d< d|d
< t|dd|dt|ddddg}t  t| } fdd}||S )z>
        A boundary without does not have them added.
        r   r   rz   r{   r|   r}   r~   r   z#multipart/alternative; boundary=xyzr   r   r   r.   Nr   c                    r   )Nr   s   {237}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: multipart/alternative; boundary=xyz


--xyz
Subject: this is subject text
Content-Type: text/plain

r   r   r   r   r.   r1   r     s   
z?MessageProducerTests.test_multiPartNoQuotes.<locals>.cbProducedr   r   r.   r   r1   test_multiPartNoQuotesf  s.   	


z+MessageProducerTests.test_multiPartNoQuotesN)ri   rj   rk   r   r   r   r   r   r.   r.   r.   r1   ry      s    -65ry   c                   @      e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&S )'MessageSetTestsz"
    Tests for L{MessageSet}.
    c                 C   s  t  }t  }| || | |d |d }| t|d | t|dg |d }| t|d | t|g d |d }| || | t|| g d |d | t|d | t|g d | || |d	d
 | t|d | t|g d dS )a4  
        Test the following properties of L{MessageSet} addition and
        equality:

            1. Two empty L{MessageSet}s are equal to each other;

            2. A L{MessageSet} is not equal to any other object;

            2. Adding a L{MessageSet} and another L{MessageSet} or an
               L{int} representing a single message or a sequence of
               L{int}s representing a sequence of message numbers
               produces a new L{MessageSet} that:

            3. Has a length equal to the number of messages within
               each sequence of message numbers;

            4. Yields each message number in ascending order when
               iterated over;

            6. L{MessageSet.add} with a single message or a start and
               end message satisfies 3 and 4 above.
        r.      r      r   r      r         )r   r   r   r            )r   r   r   r   r   r   r   N)r   r?   assertNotEquallenlistadd)rB   m1m2r.   r.   r1   !test_equalityIterationAndAddition  s(   
z1MessageSetTests.test_equalityIterationAndAdditionc                 C   s   |  tttdd dS )z
        A L{MessageSet} that has a range that ends with L{None} raises
        a L{TypeError} when its length is requested.
        r   N)assertRaises	TypeErrorr   r   rL   r.   r.   r1   test_lengthWithWildcardRange     z,MessageSetTests.test_lengthWithWildcardRangec                 C   s   t tdd dS )zD
        L{MessageSet.__repr__} does not raise an exception
        r   r   N)reprr   rL   r.   r.   r1   test_reprSanity  s   zMessageSetTests.test_reprSanityc                 C   sX   t dt dt ddt ddg}g d}t||D ]\}}| t|| qdS )z
        In a L{MessageSet}, in the presence of wildcards, if the
        highest message id is known, the wildcard should get replaced
        by that high value.
           *   1:*s   3:*r   s   *:2)*1:*z3:6z2:6Nr   parseIdListzipr?   strrB   inputsoutputsirf   r.   r.   r1   &test_stringRepresentationWithWildcards  s   

z6MessageSetTests.test_stringRepresentationWithWildcardsc                 C   sD   t dt dg}ddg}t||D ]\}}| t|| qdS )z
        In a L{MessageSet}, inverting the high and low numbers in a
        range doesn't affect the meaning of the range.  For example,
        3:2 displays just like 2:3, because according to the RFC they
        have the same meaning.
           2:3s   3:22:3Nr   r   r.   r.   r1   &test_stringRepresentationWithInversion  s   z6MessageSetTests.test_stringRepresentationWithInversionc                 C   s>   t d}| t|d | t|d | t|dg dS )z
        Creating a L{MessageSet} with a single message number adds
        only that message to the L{MessageSet}; its serialized form
        includes only that message number, its length is one, and it
        yields only that message number.
        r   1Nr   r?   r   r   r   rB   mr.   r.   r1   "test_createWithSingleMessageNumber  s   z2MessageSetTests.test_createWithSingleMessageNumberc                 C   sB   t dd}| t|d | t|d | t|g d dS )a?  
        Creating a L{MessageSet} with both a start and end message
        number adds the sequence between to the L{MessageSet}; its
        serialized form consists that range, its length is the length
        of the sequence, and it yields the message numbers inclusively
        between the start and end.
        r   
   z1:10)
r   r   r   r   r   r   r   r   	   r   Nr   r   r.   r.   r1   test_createWithSequence  s   
z'MessageSetTests.test_createWithSequencec                 C   s:   t d}| t|d | t|d | tt| dS )z
        Creating a L{MessageSet} with a single L{None}, representing
        C{*}, adds C{*} to the range; its serialized form includes
        only C{*}, its length is one, but it cannot be iterated over
        because its endpoint is unknown.
        Nr   r   )r   r?   r   r   r   r   r   r   r.   r.   r1   test_createWithSingleWildcard!  s   z-MessageSetTests.test_createWithSingleWildcardc                 C   sH   t d}d|_| t|dg t dd}d|_| t|g d dS )z
        Setting L{MessageSet.last} replaces L{None}, representing
        C{*}, with that number, making that L{MessageSet} iterable.
        Nr   r   r   r   )r   lastr?   r   )rB   singleMessageReplacedrangeReplacedr.   r.   r1   test_setLastSingleWildcard-  s   
z*MessageSetTests.test_setLastSingleWildcardc                 C   s4   t dd}|dd d|_| t|g d dS )zL
        Setting L{MessageSet.last} replaces L{None} in all ranges.
        r   Nr   r   r   r   r   r   r   )r   r   r   r?   r   r   r.   r.   r1   test_setLastWithWildcardRange:  s   
z-MessageSetTests.test_setLastWithWildcardRangec                 C   sF   t dd}d|_| t d|_W d   dS 1 sw   Y  dS )z9
        L{MessageSet.last} cannot be set twice.
        r   Nr   r   )r   r   r   
ValueErrorr   r.   r.   r1   test_setLastTwiceFailsC  s
   
"z&MessageSetTests.test_setLastTwiceFailsc                 C   sh   t d}d|_|d | t|ddg | t|d g d |dd | t|g d dS )a  
        Adding a L{None}, representing C{*}, or a sequence that
        includes L{None} to a L{MessageSet} whose
        L{last<MessageSet.last>} property has been set replaces all
        occurrences of L{None} with the value of
        L{last<MessageSet.last>}.
        r   r   N)Nr   )r   r   r   r   )r   r   r   )r   r   r   r?   r   )rB   hasLastr.   r.   r1   test_lastOverridesNoneInAddL  s   
z+MessageSetTests.test_lastOverridesNoneInAddc                 C   s"   t dd}d|_| |jd dS )zF
        Accessing L{MessageSet.last} returns the last value.
        r   Nr   )r   r   r?   r   r.   r.   r1   test_getLast_  s   
zMessageSetTests.test_getLastc                 C   s   t  }|d | t|dg t  }|d | t|d t  }|d | t|g d t  }|d | t|d t  }|t dd | t|g d dS )z
        L{MessageSet.extend} accepts as its arugment an L{int} or
        L{None}, or a sequence L{int}s or L{None}s of length two, or
        another L{MessageSet}, combining its argument with its
        instance's existing ranges.
        r   Nr   r   r   NNr   )r   extendr?   r   r   )rB   extendWithIntextendWithNoneextendWithSequenceOfIntsextendWithSequenceOfNonesextendWithMessageSetr.   r.   r1   test_extendg  s   



zMessageSetTests.test_extendc                 C   s   t dd}t ddt dd }| d| | d| |d }| t d|v  W d   n1 s3w   Y  |d }|dd | t d|v  W d   dS 1 sWw   Y  dS )	z
        A L{MessageSet} contains a number if the number falls within
        one of its ranges, and raises L{TypeError} if any range
        contains L{None}.
        r   r   r   r   r   N)r      r   )r   assertInassertNotInr   r   r   )rB   hasFivedoesNotHaveFivehasFiveButHasNonehasFiveButHasNoneInSequencer.   r.   r1   test_contains  s   


"zMessageSetTests.test_containsc                 C   s   t dd}t dd}|| }|t dd }| t|d g d | t|d	 g d
 | t|d g d | t|d g d | t|d	 g d | t|t d g d dS )z
        Adding a sequence of message numbers to a L{MessageSet} that
        begins or ends immediately before or after an existing
        sequence in that L{MessageSet}, or overlaps one, merges the two.
        r   r   r   r   r   r   )r   r   )r   r   r   r   )r   r   r   )r   r   )r   r   r   r   )r   r   )r   r   r   r   r   )r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   N)r   r?   r   )rB   
mergeAftermergeBeforemergeBetweenSequencemergeBetweenNumberr.   r.   r1   test_rangesMerged  s   

z!MessageSetTests.test_rangesMergedc                 C   sZ   |  tddtdd |  ttddg d tdd}d|_|  t|ddg dS )a  
        Test the C{seq-range} examples from Section 9, "Formal Syntax"
        of RFC 3501::

            Example: 2:4 and 4:2 are equivalent and indicate values
                     2, 3, and 4.

            Example: a unique identifier sequence range of
                     3291:* includes the UID of the last message in
                     the mailbox, even if that value is less than 3291.

        @see: U{http://tools.ietf.org/html/rfc3501#section-9}
        r   r   r   r   r   i  Ni  )r?   r   r   r   r   r.   r.   r1   test_seq_rangeExamples  s
   
z&MessageSetTests.test_seq_rangeExamplesc                 C   s   t dt dd t d t dd }d|_| dd	d
 |D d t ddt dd }d|_| ddd
 |D d dS )a  
        Test the C{sequence-set} examples from Section 9, "Formal
        Syntax" of RFC 3501.  In particular, L{MessageSet} reorders
        and coalesces overlaps::

            Example: a message sequence number set of
                     2,4:7,9,12:* for a mailbox with 15 messages is
                     equivalent to 2,4,5,6,7,9,12,13,14,15

            Example: a message sequence number set of *:4,5:7
                     for a mailbox with 10 messages is equivalent to
                     10,9,8,7,6,5,4,5,6,7 and MAY be reordered and
                     overlap coalesced to be 4,5,6,7,8,9,10.

        @see: U{http://tools.ietf.org/html/rfc3501#section-9}
        r   r   r   r   r   N   ,c                 s       | ]}t |V  qd S r-   r   .0r   r.   r.   r1   	<genexpr>      z<MessageSetTests.test_sequence_setExamples.<locals>.<genexpr>z2,4,5,6,7,9,12,13,14,15r   r   c                 s   r  r-   r  r	  r.   r.   r1   r    r  z4,5,6,7,8,9,10)r   r   r?   r   )rB   fromFifteenMessagesfromTenMessagesr.   r.   r1   test_sequence_setExamples  s   " z)MessageSetTests.test_sequence_setExamplesN)ri   rj   rk   __doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r.   r.   r.   r1   r     s(    3		r   c                   @   sP  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRS )SIMAP4HelperTestszA
    Tests for various helper utilities in the IMAP4 module.
    c                 C   s   t tddgd dS )zI
        L{imap4.Command}'s C{repr} does not raise an exception.
        s   COMMANDs   arg   extraN)r   r   CommandrL   r.   r.   r1   test_commandRepr     z!IMAP4HelperTests.test_commandReprc                    sb   d t  t }t|} fdd}fdd}|| || ||S )Ns   xyzxyzxyzxyzxyzxyzxyzxyzxyzxyzc                    s0    |  dt  f dj | S )Ns   {%d}
%br   )r   r?   r   r   ro   r   br   r   rB   r.   r1   r     s    z6IMAP4HelperTests.test_fileProducer.<locals>.cbProducedc                    s       | S r-   )rt   r   )r   r.   r1   cbResume  s   z4IMAP4HelperTests.test_fileProducer.<locals>.cbResume)rm   r   r   FileProducerr   r   )rB   r0   r   r   r  r.   r  r1   test_fileProducer  s   




z"IMAP4HelperTests.test_fileProducerc                 C   s   dg dddggdg dg dgdg d	g d
gg}|D ]%\}}}t |d}|D ]
}| || q)|D ]
}| || q6qd S )Nfoo/%gum/barzfoo/barzoo/lalagum/barzfoo/gumx/barzfoo/gum/bazfoo/xgum/barfoo/gum/barfoo/x%x/barfoobarzfuz fuz fuzz	foo/*/barfoo/xyz/barz
foo/xx/baz)foo/xyx/bar
foo/xx/barfoo/xxxxxxxxxxxxxx/barfoo/xyz*abc/barr#  zfoo/abc/barzfoo/xyzab/cbarzfoo/xyza/bcbarzfoo/xyzabc/barzfoo/xyz/abc/barzfoo/xyz/123/abc/bar/r   wildcardToRegexpassertFalsematch
assertTruerB   caseswildcardfailsucceedxr.   r.   r1   test_wildcard  s*   zIMAP4HelperTests.test_wildcardc                 C   s   dg dg dgdg dg dgdg dg d	gg}|D ]'\}}}t |d }|D ]}| ||| q)|D ]}| ||| q7qd S )
Nr  r  )r  r  zfoo/x/gum/barr  r   )r$  r%  r&  zfoo/x/x/barr'  r(  r)  r+  r0  r.   r.   r1   test_wildcardNoDelim   s*   z%IMAP4HelperTests.test_wildcardNoDelimc                 C   sL   ddddfg}|D ]\}}t |}| t|dt|d q
dS )z
        L{imap4._formatHeaders} accepts a C{dict} of header name/value pairs and
        returns a string representing those headers in the standard multiline,
        C{":"}-separated format.
        Value1Value2)Header1Header2s"   Header2: Value2
Header1: Value1
TN)r   _formatHeadersr?   sorted
splitlines)rB   r1  r[   expectedrV   r.   r.   r1   test_headerFormatter:  s   
z%IMAP4HelperTests.test_headerFormatterc                 C   s   g d}ddgddgg dg dg dg dg d	g d
g dg ddgddgdgg ddgg ddgg ddgg}g d}|D ]}|  tjtj| q@t||D ]\}}| t|| qQd S )N)s   Hello Worlds   Hello "World!"s   World "Hello" "How are you?"s   "Hello world" How "are you?"s   foo bar "baz buz" NILs   foo bar "baz buz" "NIL"s   foo NIL "baz buz" bars   foo "NIL" "baz buz" bars   "NIL" bar "baz buz" foos   oo \"oo\" oos   "oo \"oo\" oo"   oo 	 oos	   "oo 	 oo"   oo \t oos
   "oo \t oo"   oo \o oo
   "oo \o oo"rC  rD     Hello   Worlds   World!)rF  rE  s   How are you?)r8   s   Hows   are you?)   foo   bar   baz buzN)rG  rH  rI     NIL)rG  NrI  rH  )rG  rJ  rI  rH  )rJ  rH  rI  rG  )   oos   "oo"rK  
   oo "oo" oorK  rA  )rK  s   \trK  rB  )rK     \orK  rC  )s   "mismatched quotes   mismatched quote"s   mismatched"quotes   "oops here is" another")r   r   MismatchedQuotingsplitQuotedr   r?   )rB   r1  answerserrorsscaser?  r.   r.   r1   test_quotedSplitterM  s6   z$IMAP4HelperTests.test_quotedSplitterc                 C   s   g dg dg dddgdg ddgddg d	gd
ddd
g dd
ddd
g	dg dddgg}dgg ddgdgddgdgddggddgdgddgdgg}t ||D ]\}}| t|| qPd S )N)   a   b   c   d   e)
rU         "rV  rW  rZ  r[  rZ  rX  rY  )rU  rV  rW  rX  rY  rU  )rV  rW  rX  rV  )rW  rX  rY  r[  rZ  )r[  rZ  rV  rW  rZ  rZ  r[  s   abcde)rU  s   bc    des   abcr\  s   bcds   abs   cdes   a s    es    bc  )r   r?   r   collapseStrings)rB   r1  rP  rS  r?  r.   r.   r1   test_stringCollapser  s&   



z%IMAP4HelperTests.test_stringCollapserc                    s  d dgd } fdd}|dt||f ddg d	g|g |d
ddgdddddddg dgg dgg dgg dgg dg dgd d dg
dddddgd d ddd gg
 |d!d"g |d#d$g |d%d&g |d'd(g |d'd(g |d)d*d+g |d)d*d+g d S ),N   
s   xxr   c                    s   t | } ||g d S r-   )r   parseNestedParensr?   )rS  r?  parsedrL   r.   r1   check  s   
z0IMAP4HelperTests.test_parenParser.<locals>.checks8   (BODY.PEEK[HEADER.FIELDS.NOT (subject bcc cc)] {%d}
%b)	   BODY.PEEKs   HEADER.FIELDS.NOT)s   subjects   bccs   ccs  (FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700" RFC822.SIZE 4286 ENVELOPE ("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)" "IMAP4rev1 WG mtg summary and minutes" (("Terry Gray" NIL gray cac.washington.edu)) (("Terry Gray" NIL gray cac.washington.edu)) (("Terry Gray" NIL gray cac.washington.edu)) ((NIL NIL imap cac.washington.edu)) ((NIL NIL minutes CNRI.Reston.VA.US) ("John Klensin" NIL KLENSIN INFOODS.MIT.EDU)) NIL NIL <B27397-0100000@cac.washington.edu>) BODY (TEXT PLAIN (CHARSET US-ASCII) NIL NIL 7BIT 3028 92))   FLAGSs   \Seens   INTERNALDATEs   17-Jul-1996 02:44:25 -0700s   RFC822.SIZEs   4286s   ENVELOPEs%   Wed, 17 Jul 1996 02:23:25 -0700 (PDT)s$   IMAP4rev1 WG mtg summary and minutes)s
   Terry GrayNs   gray   cac.washington.edu)NNs   imapre  )NNs   minutess   CNRI.Reston.VA.US)s   John KlensinNs   KLENSINs   INFOODS.MIT.EDUs#   <B27397-0100000@cac.washington.edu>   BODYs   TEXT   PLAIN   CHARSETs   US-ASCIIs   7BITs   3028s   92s   ("oo \"oo\" oo")rL  s   ("oo \\ oo")s   oo \\ oos   ("oo \ oo")s   oo \ oos	   ("oo \o")s   oo \os   (oo \o)rK  rM  )r   r   )rB   rR  rb  r.   rL   r1   test_parenParser  s^   2z!IMAP4HelperTests.test_parenParserc              
   C   s   g dg dg dg dg dg dg dg dg d	g	}|D ]5\}}}| d
}t }|| | t|jd | t|jd t	|| | t
|jd | qd S )N)ENVELOPEEnvelopeenvelope)FLAGSFlagsflags)INTERNALDATEInternalDateinternaldate)RFC822.HEADERRFC822Headerzrfc822.header)RFC822.SIZE
RFC822Sizezrfc822.size)RFC822.TEXT
RFC822Textzrfc822.text)RFC822ry  rfc822)UIDr{  uid)BODYSTRUCTUREBodyStructurebodystructureasciir   r   )r@   r   _FetchParserparseStringr?   r   r/   r/  
isinstancegetattrr   )rB   r1  inpoutpasStringr   r.   r.   r1   test_fetchParserSimple  s$   

z'IMAP4HelperTests.test_fetchParserSimplec                 C   s   ddg dfgddg dfgddg d	fgg}|D ]2\}}t  }|| | t|j|d
  dd |jD }|  |d   | ||d  qd S )Ns   ALLr   )   flags   internaldate   rfc822.size   envelopes   FULLr   )r  r  r  r  s   bodys   FASTr   )r  r  r  r   c                 S   s   g | ]}t | d qS )r  )r   lowerr@   )r
  tokenr.   r.   r1   
<listcomp>  s    z;IMAP4HelperTests.test_fetchParserMacros.<locals>.<listcomp>r   )r   r  r  r?   r   r/   sort)rB   r1  r  r  r   expectedResultr.   r.   r1   test_fetchParserMacros  s   
	
z'IMAP4HelperTests.test_fetchParserMacrosc                 C   s  t j}| }|d | t|jd | t|jd |j | |jd j	d | |jd j
d  | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd d | }|d | t|jd | t|jd |j | |jd jd | t|jd d	 | }|d
 | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd j
jd | |jd j
jd | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd j
jd | |jd j
jd | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd j
jd | |jd j
jg d | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd j
jd | |jd j
jg d | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd j
jd | |jd j
jg d | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j|j | |jd jd | |jd jd | |jd jd | |jd jd | t|jd d | }|d | t|jd | t|jd |j | |jd j	d | t|jd j
|j | |jd jd | |jd j
jddg | |jd jd | |jd jd | |jd jd | t|jd d d S )Nrf  r   r   FBODYrc  Ts   BODY[]zBODY[]s   BODY[HEADER]r.   zBODY[HEADER]s   BODY.PEEK[HEADER]s+   BODY[HEADER.FIELDS (Subject Cc Message-Id)])s   SUBJECTs   CC
   MESSAGE-IDs0   BODY.PEEK[HEADER.FIELDS (Subject Cc Message-Id)]s4   BODY.PEEK[HEADER.FIELDS.NOT (Subject Cc Message-Id)]s/   BODY[HEADER.FIELDS.NOT (Subject Cc Message-Id)]s   BODY[1.MIME]<10.50>r   r   2   s?   BODY.PEEK[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>)r   r   r   r   r  s   DATEg   E   s:   BODY[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>)r   r  r  r?   r   r/   r/  r  Bodypeekheaderr   emptyHeadernegatefieldsrH   mimeMIMEpartpartialBeginpartialLength)rB   Pr   r.   r.   r1   test_fetchParserBody  s   








z%IMAP4HelperTests.test_fetchParserBodyc                 C   s|   t  }|d | t|jd | |jd jd | |jd |j | |jd j	|j
 | t|jd d dS )z
        Parsing a C{BODY} whose C{HEADER} values require quoting
        results in a object that perserves that quoting when
        serialized.
        s   BODY[HEADER.FIELDS ((Quoted)]r   r   Fs   BODY[HEADER.FIELDS ("(Quoted")]N)r   r  r  r?   r   r/   r  assertIsInstancer  r  r  rH   rB   r   r.   r.   r1   test_fetchParserQuotedHeader  s   
z-IMAP4HelperTests.test_fetchParserQuotedHeaderc                 C   s&   t  }|d | t|j dS )z=
        Parsing an empty string results in no data.
        r   N)r   r  r  r-  r   r/   r  r.   r.   r1   test_fetchParserEmptyString  s   
z,IMAP4HelperTests.test_fetchParserEmptyStringc                 C      t  }| t|jd dS )z\
        Parsing a string with an unknown attribute raises an
        L{Exception}.
        s   UNKNOWNNr   r  r   	Exceptionr  r  r.   r.   r1    test_fetchParserUnknownAttribute     z1IMAP4HelperTests.test_fetchParserUnknownAttributec                 C   r  )zf
        Parsing a string that prematurely ends in whitespace raises an
        L{Exception}.
        s   BODY[HEADER.FIELDS  Nr  r  r.   r.   r1   0test_fetchParserIncompleteStringEndsInWhitespace  r  zAIMAP4HelperTests.test_fetchParserIncompleteStringEndsInWhitespacec                 C   r  )z
        Parsing a string that contains an unexpected character rather
        than whitespace raises an L{Exception}.
        s   BODY[HEADER.FIELDS!]Nr  r  r.   r.   r1   "test_fetchParserExpectedWhitespace  r  z3IMAP4HelperTests.test_fetchParserExpectedWhitespacec                 C   s|   t  }|d | t|jd | |jd |j | |jd jd | |jd j	|j
 | t|jd d dS )z:
        A C{BODY} can contain a C{TEXT} section.
        s
   BODY[TEXT]r   r   FN)r   r  r  r?   r   r/   r  r  r  rC   TextrH   r  r.   r.   r1   test_fetchParserTextSection  s   
z,IMAP4HelperTests.test_fetchParserTextSectionc                 C   r  )z[
        Parsing a C{BODY} with an unknown section raises an
        L{Exception}.
        s   BODY[UNKNOWN]Nr  r  r.   r.   r1   test_fetchParserUnknownSection  r  z/IMAP4HelperTests.test_fetchParserUnknownSectionc                 C   4   t  }| t|jd t  }| t|jd dS )ze
        Parsing a C{BODY} with an unterminated section list raises an
        L{Exception}.
        s   BODY[HEADERs   BODY[HEADER.FIELDS (SUBJECT)Nr  r  r.   r.   r1   #test_fetchParserMissingSectionClose  s   z4IMAP4HelperTests.test_fetchParserMissingSectionClosec                 C   r  )z
        Parsing a C{BODY} whose C{HEADER.FIELDS} list does not begin
        with an open parenthesis (C{(}) or end with a close
        parenthesis (C{)}) raises an L{Exception}.
        s   BODY[HEADER.FIELDS Missing)]s   BODY[HEADER.FIELDS (Missing]Nr  r  r.   r.   r1   (test_fetchParserHeaderMissingParentheses  s   z9IMAP4HelperTests.test_fetchParserHeaderMissingParenthesesc                 C   r  )zk
        Parsing a C{BODY} with a range that lacks a period (C{.})
        raises an L{Exception}.
        s   BODY<01>Nr  r  r.   r.   r1   test_fetchParserDotlessPartial  r  z/IMAP4HelperTests.test_fetchParserDotlessPartialc                 C   r  )z
        Parsing a C{BODY} with a partial range that's missing its
        closing greater than sign (C{>}) raises an L{EXCEPTION}.
        s   BODY<0Nr  r  r.   r.   r1   test_fetchParserUnclosedPartial  r  z0IMAP4HelperTests.test_fetchParserUnclosedPartialc                 C   s.   dddt dddg}d}| t|| d S )Nr!  r"  baz   this is a file
buzbizs4   "foo" "bar" "baz" {16}
this is a file
 "buz" "biz")r   r?   r   collapseNestedLists)rB   inputStructurerV   r.   r.   r1   
test_files  s   	zIMAP4HelperTests.test_filesc                 C   s<   dt ddtddt ddg}d}| t || d S )	NrG  rH  s   bazr  s   this is
quoteds   buzr   sC   "foo" bar "baz" {16}
this is a file
 {15}
this is
quoted buz "")r   DontQuoteMer   r?   r  rZ   r.   r.   r1   test_quoteAvoider  s   z"IMAP4HelperTests.test_quoteAvoiderc                 C   s2   ddggfg}|D ]\}}|  t|| q	d S )Ns   ({10}
0123456789)s
   0123456789)r?   r   r`  )rB   r1  rS  r?  r.   r.   r1   test_literals  s
   
zIMAP4HelperTests.test_literalsc                 C   s   t jddt jddddt t jddt jddt jddt t jddt jddt jddt t t t jdd	d
dt jddddt jdddddt t jddt t jddg}g d}t||D ]
\}}| || qjd S )Nr   )flagged)r=  	unflaggeddeleted)r  today)before)unseen)new	yesterdayi  )r=  sincesmallertuesdayi'  )r=  r  larger)r=  r  r  r  spam)r   z1:5r|  )FLAGGEDz(DELETED UNFLAGGED)z(OR FLAGGED DELETED)z(BEFORE "today")z(OR DELETED (OR UNSEEN NEW))z(OR (NOT (OR (SINCE "yesterday" SMALLER 1000) (OR (BEFORE "tuesday" LARGER 10000) (OR (BEFORE "today" DELETED UNSEEN) (NOT (SUBJECT "spam")))))) (NOT (UID 1:5))))r   QueryOrNotr   r?   )rB   r   r   queryr?  r.   r.   r1   test_queryBuilder  s*   

$z"IMAP4HelperTests.test_queryBuilderc                 C      t jdd}| d| dS )z
        When passed the C{keyword} argument, L{imap4.Query} returns an unquoted
        string.

        @see: U{http://tools.ietf.org/html/rfc3501#section-9}
        @see: U{http://tools.ietf.org/html/rfc3501#section-6.4.4}
        twisted)keywordz(KEYWORD twisted)Nr   r  r?   rB   r  r.   r.   r1   test_queryKeywordFlagWithQuotes>     z0IMAP4HelperTests.test_queryKeywordFlagWithQuotesc                 C   r  )z
        When passed the C{unkeyword} argument, L{imap4.Query} returns an
        unquoted string.

        @see: U{http://tools.ietf.org/html/rfc3501#section-9}
        @see: U{http://tools.ietf.org/html/rfc3501#section-6.4.4}
        r  )	unkeywordz(UNKEYWORD twisted)Nr  r  r.   r.   r1   !test_queryUnkeywordFlagWithQuotesI  r  z2IMAP4HelperTests.test_queryUnkeywordFlagWithQuotesc                 C   s$   t jt ddd}| |d dS )z
        When passed a L{MessageSet}, L{imap4.Query} returns a query
        containing a quoted string representing the ID sequence.
        r   Nmessagesz(MESSAGES "1:*"))r   r  r   r?   r  r.   r.   r1   test_queryWithMesssageSetT  s   z*IMAP4HelperTests.test_queryWithMesssageSetc                 C   s   t jdd}| |d dS )zl
        When passed an L{int}, L{imap4.Query} returns a query
        containing a quoted integer.
        r   r  z(MESSAGES "1")Nr  r  r.   r.   r1   test_queryWithInteger\  s   z&IMAP4HelperTests.test_queryWithIntegerc                 C   s   |  tjtjtjdd dS )zq
        An L{imap4.Or} query with less than two arguments raises an
        L{imap4.IllegalQueryError}.
        r   r  N)r   r   IllegalQueryErrorr  r  rL   r.   r.   r1   test_queryOrIllegalQueryd  s   z)IMAP4HelperTests.test_queryOrIllegalQueryc                 C   sn   |  d|  dtjd
i |di |  d|  dtjd
i |dddd tdD f i d	S )z
        Helper to implement tests for value filtering of KEYWORD and UNKEYWORD
        queries.

        @param keyword: A native string giving the name of the L{imap4.Query}
            keyword argument to test.
        (z twistedrocks)ztwisted (){%*"\] rocksztwisted %s rocks c                 s   r  r-   )re   )r
  chr.   r.   r1   r    r  z9IMAP4HelperTests._keywordFilteringTest.<locals>.<genexpr>!   Nr.   )r?   upperr   r  r   rd   )rB   r  r.   r.   r1   _keywordFilteringTestk  s   	z&IMAP4HelperTests._keywordFilteringTestc                 C      |  d dS )a  
        When passed the C{keyword} argument, L{imap4.Query} returns an
        C{atom} that consists of one or more non-special characters.

        List of the invalid characters:

            ( ) { % * " \ ] CTL SP

        @see: U{ABNF definition of CTL and SP<https://tools.ietf.org/html/rfc2234>}
        @see: U{IMAP4 grammar<http://tools.ietf.org/html/rfc3501#section-9>}
        @see: U{IMAP4 SEARCH specification<http://tools.ietf.org/html/rfc3501#section-6.4.4>}
        r  Nr  rL   r.   r.   r1   test_queryKeywordFlag     z&IMAP4HelperTests.test_queryKeywordFlagc                 C   r  )a  
        When passed the C{unkeyword} argument, L{imap4.Query} returns an
        C{atom} that consists of one or more non-special characters.

        List of the invalid characters:

            ( ) { % * " \ ] CTL SP

        @see: U{ABNF definition of CTL and SP<https://tools.ietf.org/html/rfc2234>}
        @see: U{IMAP4 grammar<http://tools.ietf.org/html/rfc3501#section-9>}
        @see: U{IMAP4 SEARCH specification<http://tools.ietf.org/html/rfc3501#section-6.4.4>}
        r  Nr  rL   r.   r.   r1   test_queryUnkeywordFlag  r  z(IMAP4HelperTests.test_queryUnkeywordFlagc                 C   *   g d}|D ]}|  tjtj|d qdS )z|
        Trying to parse an invalid representation of a sequence range raises an
        L{IllegalIdentifierError}.
        )s   *:*rG  s   4:s   bar:590  Nr   r   IllegalIdentifierErrorr   rB   r   r[   r.   r.   r1   test_invalidIdListParser  s   z)IMAP4HelperTests.test_invalidIdListParserc                 C   r  )z
        Zeroes and negative values are not accepted in id range expressions. RFC
        3501 states that sequence numbers and sequence ranges consist of
        non-negative numbers (RFC 3501 section 9, the seq-number grammar item).
        )s   0:5s   0:0s   *:0   0s   -3:5s   1:-2s   -1r  Nr  r  r.   r.   r1   #test_invalidIdListParserNonPositive  s   z4IMAP4HelperTests.test_invalidIdListParserNonPositivec                 C   sZ  g d}t ddt ddt ddt dd t ddt dt ddt dt d t d t ddt ddt ddt dd	 t dt dd t dt dd t d
d	 t ddt d
 t d	d t ddg}g d}t||D ]\}}| t|| qmt||D ]*\}}|du r| ttt| qtt|}| ||d|d|d| qdS )zi
        The function to parse sequence ranges yields appropriate L{MessageSet}
        objects.
        )r   s   5:*s   1:2,5:*r      1s   1,2s   1,3,5s   1:10s   1:10,11s	   1:5,10:20s   1,5:10s   1,5:10,15:20s   1:10,15,20:25   4:2r   Nr   r   r   r         r     r   )NNNr   r   r   r   r   r     r         r   zlen(z) = z != )r   r   r?   r   r   r   r   r   )rB   r   r   lengthsr[   r?  Lr.   r.   r1   test_parseIdList  s2   "z!IMAP4HelperTests.test_parseIdListc                 C   s   |  ttjd dS )zu
        L{imap4.parseTime} raises L{ValueError} when given a a time
        string whose format is invalid.
        invalidNr   r   r   	parseTimerL   r.   r.   r1   test_parseTimeInvalidFormat  s   z,IMAP4HelperTests.test_parseTimeInvalidFormatc                 C   s&   g d}|D ]
}|  ttj| qdS )zv
        L{imap4.parseTime} raises L{ValueError} when given a time
        string composed of invalid values.
        )zinvalid-July-2017z2-invalid-2017z2-July-invalidNr  )rB   invalidStringsr  r.   r.   r1   test_parseTimeInvalidValues  s   z,IMAP4HelperTests.test_parseTimeInvalidValuesc                 C   sJ   t  }| | | | | d}t|| }| 	|| dS )z
        L{imap4.statusRequestHelper} builds a L{dict} mapping the
        requested status names to values extracted from the provided
        L{IMailboxIMAP}'s.
        )MESSAGESRECENTUIDNEXTUIDVALIDITYUNSEENN)
SimpleMailboxgetMessageCountgetRecentCount
getUIDNextgetUIDValiditygetUnseenCountr   statusRequestHelperkeysr?   )rB   mboxr?  r/   r.   r.   r1   test_statusRequestHelper  s   z)IMAP4HelperTests.test_statusRequestHelperN),ri   rj   rk   r  r  r  r6  r7  r@  rT  r^  ri  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r.   r.   r.   r1   r    sT    :Ot
#3r  c                   @   s   e Zd ZU dZg Zeeeeee	f  e
d< dZdZdZdd Zdd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd)ddZdd  Zd!d" Zd#d$ Zd%d& Zd'd( ZdS )*r  z\Flag1Flag2z\AnotherSysFlagLastFlagr  r   r   Fc                 C      g | _ | j j| _| j j| _d S r-   	listenersrr   addListenerremoveremoveListenerrL   r.   r.   r1   rp        
zSimpleMailbox.__init__c                 C      | j S r-   ro  rL   r.   r.   r1   getFlags$     zSimpleMailbox.getFlagsc                 C      dS )N*   r.   rL   r.   r.   r1   r  '     zSimpleMailbox.getUIDValidityc                 C      t | jd S Nr   r   r  rL   r.   r.   r1   r  *     zSimpleMailbox.getUIDNextc                 C   r(  )Nr   r.   rL   r.   r.   r1   r  -  r*  zSimpleMailbox.getMessageCountc                 C   r(  )Nr   r.   rL   r.   r.   r1   r  0  r*  zSimpleMailbox.getRecentCountc                 C   r(  )Nr   r.   rL   r.   r.   r1   r  3  r*  zSimpleMailbox.getUnseenCountc                 C   r$  r-   rwrL   r.   r.   r1   isWriteable6  r'  zSimpleMailbox.isWriteablec                 C      d S r-   r.   rL   r.   r.   r1   destroy9  r*  zSimpleMailbox.destroyc                 C   r(  )Nr*  r.   rL   r.   r.   r1   getHierarchicalDelimiter<  r*  z&SimpleMailbox.getHierarchicalDelimiterc                 C   v   i }d|v r|   |d< d|v r|  |d< d|v r"|   d |d< d|v r,|  |d< d|v r6|  |d< t|S )Nr  r  r  r   r  r  r  r  getUIDr  r   r4  rB   namesrr.   r.   r1   requestStatus?  s   
zSimpleMailbox.requestStatusNc                 C   s.   | j |||| jf |  jd7  _td S r,  r  rr   mUIDr   r4  rB   messagero  dater.   r.   r1   
addMessageM  s   
zSimpleMailbox.addMessagec                 C   J   g }| j D ]}d|d v r|| q|D ]}| j | qdd |D S )N\Deletedr   c                 S      g | ]}|d  qS r   r.   r	  r.   r.   r1   r  Y      z)SimpleMailbox.expunge.<locals>.<listcomp>r  rr   r!  rB   deleter   r.   r.   r1   expungeR  s   

zSimpleMailbox.expungec                 C   s
   d| _ d S NT)closedrL   r.   r.   r1   close[  rq   zSimpleMailbox.closec                 C   r2  r-   r.   rB   r  r|  r.   r.   r1   fetch^     zSimpleMailbox.fetchc                 C   r2  r-   r.   rB   r?  r.   r.   r1   r7  b  rP  zSimpleMailbox.getUIDc                 C   r2  r-   r.   rB   r  ro  moder|  r.   r.   r1   storef  rP  zSimpleMailbox.storer-   )ri   rj   rk   ro  r  r   r   rH   r   int__annotations__r=  r0  rL  rp   r&  r  r  r  r  r  r1  r3  r4  r;  rA  rJ  rM  rO  r7  rT  r.   r.   r.   r1   r    s.   
 
	r  c                   @   s   e Zd ZU dZdZg Zeeee	ee
f  ed< dZdZdZdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd(ddZd d! Zd"d# Zd$d% Zd&d' ZdS ))UncloseableMailboxz*
    A mailbox that cannot be closed.
    r  r  r   r   Fc                 C   r  r-   r  rL   r.   r.   r1   rp   w  r#  zUncloseableMailbox.__init__c                 C   r$  )zB
        The flags

        @return: A sequence of flags.
        r%  rL   r.   r.   r1   r&  |     zUncloseableMailbox.getFlagsc                 C   r(  )zF
        The UID validity value.

        @return: The value.
        r)  r.   rL   r.   r.   r1   r       z!UncloseableMailbox.getUIDValidityc                 C   r+  )z:
        The next UID.

        @return: The UID.
        r   r-  rL   r.   r.   r1   r       zUncloseableMailbox.getUIDNextc                 C   r(  )zG
        The number of messages.

        @return: The number.
        r   r.   rL   r.   r.   r1   r    rY  z"UncloseableMailbox.getMessageCountc                 C   r(  )D
        The recent messages.

        @return: The number.
        r   r.   rL   r.   r.   r1   r    rY  z!UncloseableMailbox.getRecentCountc                 C   r(  )r[  r   r.   rL   r.   r.   r1   r    rY  z!UncloseableMailbox.getUnseenCountc                 C   r$  )z`
        The recent messages.

        @return: Whether or not the mailbox is writable.
        r/  rL   r.   r.   r1   r1    rX  zUncloseableMailbox.isWriteablec                 C   r(  )z'
        Destroy this mailbox.
        Nr.   rL   r.   r.   r1   r3    s   zUncloseableMailbox.destroyc                 C   r(  )zU
        Return the hierarchical delimiter.

        @return: The delimiter.
        r*  r.   rL   r.   r.   r1   r4    rY  z+UncloseableMailbox.getHierarchicalDelimiterc                 C   r5  )z
        Return the mailbox's status.

        @param names: The status items to include.

        @return: A L{dict} of status data.
        r  r  r  r   r  r  r6  r8  r.   r.   r1   r;    s   
z UncloseableMailbox.requestStatusNc                 C   s.   | j |||| jf |  jd7  _tdS )a  
        Add a message to the mailbox.

        @param message: The message body.

        @param flags: The message flags.

        @param date: The message date.

        @return: A L{Deferred} that fires when the message has been
            added.
        r   Nr<  r>  r.   r.   r1   rA    s   
zUncloseableMailbox.addMessagec                 C   rB  )zj
        Delete messages marked for deletion.

        @return: A L{list} of deleted message IDs.
        rC  r   c                 S   rD  rE  r.   r	  r.   r.   r1   r    rF  z.UncloseableMailbox.expunge.<locals>.<listcomp>rG  rH  r.   r.   r1   rJ    s   

zUncloseableMailbox.expungec                 C   r2  r-   r.   rN  r.   r.   r1   rO    rP  zUncloseableMailbox.fetchc                 C   r2  r-   r.   rQ  r.   r.   r1   r7    rP  zUncloseableMailbox.getUIDc                 C   r2  r-   r.   rR  r.   r.   r1   rT    rP  zUncloseableMailbox.storer-   )ri   rj   rk   r  ro  r  r   r   rH   r   rU  rV  r=  r0  rL  rp   r&  r  r  r  r  r  r1  r3  r4  r;  rA  rJ  rO  r7  rT  r.   r.   r.   r1   rW  k  s.   
 
rW  c                   @   s&   e Zd ZdZeZdd ZdddZdS )	AccountWithoutNamespaceszL
    An in-memory account that does not provide L{INamespacePresenter}.
    c                 C      |   S r-   )mailboxFactory)rB   nameidr.   r.   r1   _emptyMailbox
     z&AccountWithoutNamespaces._emptyMailboxr   c                 C   s    t j| |}|d ur||_|S r-   )r   MemoryAccountselectr0  )rB   r_  r0  r  r.   r.   r1   rd    s   zAccountWithoutNamespaces.selectNr   )ri   rj   rk   r  r  r^  ra  rd  r.   r.   r.   r1   r\    s
    r\  c                   @      e Zd ZdZdS )AccountzD
    An in-memory account that provides L{INamespacePresenter}.
    Nri   rj   rk   r  r.   r.   r.   r1   rg        rg  c                   @   s$   e Zd ZedZdd Zdd ZdS )SimpleServer   testuserc                 O   s^   t jj| g|R i | t| d}t|}t }|dd || _|| _|	| d| _
d S )NaccountHolderrk     password-testF)r   IMAP4Serverrp   	TestRealmr   r   addUsercheckerportalregisterCheckertimeoutTest)rB   argskwrealmrs  r   r.   r.   r1   rp     s   


zSimpleServer.__init__c                 C   s   | j rd S tj| | d S r-   )ru  r   ro  lineReceivedrB   liner.   r.   r1   ry  (  s   zSimpleServer.lineReceivedN)ri   rj   rk   rg  
theAccountrp   ry  r.   r.   r.   r1   rj    s    rj  c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )SimpleClientNc                 C   s   t j| | || _g | _d S r-   )r   IMAP4Clientrp   deferredevents)rB   r  contextFactoryr.   r.   r1   rp   1  s   
zSimpleClient.__init__c                 C   s   | j d  d S r-   )r  callback)rB   capsr.   r.   r1   serverGreeting6     zSimpleClient.serverGreetingc                 C      | j d|g | j  d S )NmodeChangedr  rr   	transportloseConnection)rB   	writeabler.   r.   r1   r  9     zSimpleClient.modeChangedc                 C   r  )NflagsChangedr  rB   newFlagsr.   r.   r1   r  =  r  zSimpleClient.flagsChangedc                 C   s    | j d||g | j  d S )NnewMessagesr  )rB   existsrecentr.   r.   r1   r  A  s   zSimpleClient.newMessagesr-   )ri   rj   rk   rp   r  r  r  r  r.   r.   r.   r1   r}  0  s    
r}  c                   @   s^   e Zd ZU dZee ed< dZee ed< dd Z	dd Z
dd	 Zd
d Zdd Zdd ZdS )IMAP4HelperMixinN	serverCTX	clientCTXc                 C   sJ   t  }t| jd| _t|| jd| _|| _g t	_
td}t	|_|t_d S )Nr  rk  )r   Deferredrj  r  serverr}  r  client	connectedr  r  rg  mboxTyper|  )rB   r   r|  r.   r.   r1   setUpK  s   
zIMAP4HelperMixin.setUpc                 C   s   | ` | `| `d S r-   )r  r  r  rL   r.   r.   r1   tearDownV  s   zIMAP4HelperMixin.tearDownc                 C   s   | j j  d S r-   )r  r  r  )rB   ignorer.   r.   r1   _cbStopClient[  r  zIMAP4HelperMixin._cbStopClientc                 C   s0   | j j  | jj  t|dt|   d S )NProblem with )r  r  r  r  r"   errr   )rB   r!   r.   r.   r1   
_ebGeneral^  s   zIMAP4HelperMixin._ebGeneralc                 C   s   t | j| jS r-   )r    loopbackAsyncr  r  rL   r.   r.   r1   r    c  r  zIMAP4HelperMixin.loopbackc                 C   s.   | tj t|j}t|}| || dS )a.  
        Assert that the provided failure is an L{IMAP4Exception} with
        the given message.

        @param failure: A failure whose value L{IMAP4Exception}
        @type failure: L{failure.Failure}

        @param expected: The expected failure message.
        @type expected: L{bytes}
        N)trapr   IMAP4Exceptionr   valuer   r?   )rB   r!   r?  r?  r.   r.   r1   assertClientFailureMessagef  s   
z+IMAP4HelperMixin.assertClientFailureMessage)ri   rj   rk   r  r   r,   rV  r  r+   r  r  r  r  r    r  r.   r.   r.   r1   r  F  s   
 r  c                   @   s  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&dIdJ Z'dKdL Z(dMdN Z)dOdP Z*dQdR Z+dSdT Z,dUdV Z-dWdX Z.dYdZ Z/d[d\ Z0d]d^ Z1d_d` Z2dadb Z3dcdd Z4dedf Z5dgS )hIMAP4ServerTestsc                    s^   i   fdd}j t|j}t |g}d d d d| fddS )Nc                         fdd} j  | S )Nc                         |  jj  d S r-   updater  r  r  r   r  rB   r.   r1   gotCaps}     
zAIMAP4ServerTests.testCapability.<locals>.getCaps.<locals>.gotCapsr  getCapabilitiesr   r  r  r.   r1   getCaps|     z0IMAP4ServerTests.testCapability.<locals>.getCaps)	   IMAP4rev1	   NAMESPACE   IDLEc                         S r-   r?   _r  r?  rB   r.   r1   r2         z1IMAP4ServerTests.testCapability.<locals>.<lambda>)r  r   r4   
addErrbackr  r   gatherResultsr    rB   r  d1r   r.   r  r1   testCapabilityy  s   zIMAP4ServerTests.testCapabilityc                    sn   i  t jjd<  fdd}jt|j}t	
 |g}d d d dgd| fddS )N   CRAM-MD5c                     r  )Nc                    r  r-   r  r  r  r.   r1   r    r  zIIMAP4ServerTests.testCapabilityWithAuth.<locals>.getCaps.<locals>.gotCapsr  r  r  r.   r1   r    r  z8IMAP4ServerTests.testCapabilityWithAuth.<locals>.getCaps)r  r  r     AUTHc                    r  r-   r  r  r  expCaprB   r.   r1   r2     r  z9IMAP4ServerTests.testCapabilityWithAuth.<locals>.<lambda>)r   r  challengersr  r   r4   r  r  r   r  r    r  r.   r  r1   testCapabilityWithAuth  s   z'IMAP4ServerTests.testCapabilityWithAuthc                    sD   d _  fdd} jt| j   }| fddS )Nr   c                     s$    fdd}  j  t|  d S )Nc                      
   d _ d S r,  )	loggedOutr.   rL   r.   r1   setLoggedOut  rq   zAIMAP4ServerTests.testLogout.<locals>.logout.<locals>.setLoggedOut)r  logoutr   r4   )r  rL   r.   r1   r    s   z+IMAP4ServerTests.testLogout.<locals>.logoutc                    s      jdS r,  )r?   r  r  rL   r.   r1   r2         z-IMAP4ServerTests.testLogout.<locals>.<lambda>)r  r  r   r4   r  r  r    )rB   r  r   r.   rL   r1   
testLogout  s
   zIMAP4ServerTests.testLogoutc                    sD   d  _  fdd} jt| j   }| fddS )Nc                     s     fdd}  j  |  d S )Nc                    s   |  _  jj  d S r-   )	responsesr  r  r  )r  rL   r.   r1   setResponses  s   z=IMAP4ServerTests.testNoop.<locals>.noop.<locals>.setResponses)r  noopr   )r  rL   r.   r1   r    s   z'IMAP4ServerTests.testNoop.<locals>.noopc                    s      jg S r-   )r?   r  r  rL   r.   r1   r2     r  z+IMAP4ServerTests.testNoop.<locals>.<lambda>)r  r  r   r4   r  r  r    )rB   r  r   r.   rL   r1   testNoop  s
   zIMAP4ServerTests.testNoopc                    sB    fdd} j t| j}t|  g}| jS )Nc                         j dd} |  j d S Nrk  rn  )r  loginr   r  r   rL   r.   r1   r       z)IMAP4ServerTests.testLogin.<locals>.login)	r  r   r4   r  r  r   r  r    _cbTestLoginrB   r  r  r   r.   rL   r1   	testLogin  s   zIMAP4ServerTests.testLoginc                 C   &   |  | jjtj |  | jjd d S Nauthr?   r  accountrj  r|  staterB   ignoredr.   r.   r1   r       zIMAP4ServerTests._cbTestLoginc                    sF    fdd} j t| j}  }t||g}| jS )Nc                     r  Nrk  s   wrong-passwordr  r  addBothr  r  rL   r.   r1   r    r  z/IMAP4ServerTests.testFailedLogin.<locals>.login)	r  r   r4   r  r  r    r   r  _cbTestFailedLoginrB   r  r  d2r   r.   rL   r1   testFailedLogin  s
   z IMAP4ServerTests.testFailedLoginc                 C   s$   |  | jjd  |  | jjd d S )Nunauth)r?   r  r  r  r  r.   r.   r1   r       z#IMAP4ServerTests._cbTestFailedLoginc                    sN   d j _ fdd} jt| j}  }t	||g}| j
S )zj
        Attempting to log into a server that has no L{Portal} results
        in a failed login.
        Nc                     r  r  r  r  rL   r.   r1   r    r  z7IMAP4ServerTests.test_loginWithoutPortal.<locals>.login)r  rs  r  r   r4   r  r  r    r   r  r  r  r.   rL   r1   test_loginWithoutPortal  s   z(IMAP4ServerTests.test_loginWithoutPortalc                    sZ   dd }| j jj_ fdd} jt| j} 	 }t
||g}| jS )z
        The server responds with a C{BAD} response when its portal
        attempts to log a user in with checker that claims to support
        L{IAccount} but returns an an avatar interface that is not
        L{IAccount}.
        c                  _   s   dddd fS )NzNot IAccountzNot an accountc                   S   r2  r-   r.   r.   r.   r.   r1   r2         zVIMAP4ServerTests.test_nonIAccountAvatar.<locals>.brokenRequestAvatar.<locals>.<lambda>r.   )r  __r.   r.   r1   brokenRequestAvatar  r.  zDIMAP4ServerTests.test_nonIAccountAvatar.<locals>.brokenRequestAvatarc                     r  r  r  r  rL   r.   r1   r    r  z6IMAP4ServerTests.test_nonIAccountAvatar.<locals>.login)r  rs  rx  requestAvatarr  r   r4   r  r  r    r   r  r  )rB   r  r  r  r  r   r.   rL   r1   test_nonIAccountAvatar  s   z'IMAP4ServerTests.test_nonIAccountAvatarc                    s   G dd dt   fdd}|j_fdd}jt|}|jd |j fdd	}|j |	j
  }t||g}|jS )
z
        Any exception raised by L{IMAP4Server.authenticateLogin} that
        is not L{UnauthorizedLogin} is logged results in a C{BAD}
        response.
        c                   @   rf  )zAIMAP4ServerTests.test_loginException.<locals>.UnexpectedException2
            An unexpected exception.
            Nrh  r.   r.   r.   r1   UnexpectedException  ri  r  c                        d)NWhoopsr.   )userpasswdr  r.   r1   raisesUnexpectedException  rb  zGIMAP4ServerTests.test_loginException.<locals>.raisesUnexpectedExceptionc                          j ddS r  r  r  r.   rL   r.   r1   r    r.  z3IMAP4ServerTests.test_loginException.<locals>.logins   Server error: Whoopsc                          d S r-   r/  flushLoggedErrorsr  r  rB   r.   r1   assertErrorLogged  s   z?IMAP4ServerTests.test_loginException.<locals>.assertErrorLogged)r  r  authenticateLoginr  r   r4   r  r  r  r  r  r    r   r  r  )rB   r  r  r  r  r  r   r.   r  r1   test_loginException  s   z$IMAP4ServerTests.test_loginExceptionc                    sP   ddi j j_ fdd} jt| j}t	 
 |g}| jS )N
   {test}user   {test}passwordc                     s4    j dd} | tjdt   |  j d S )Nr  r  r  )r  r  r  r"   r  r   r   r  r  rL   r.   r1   r  !  s   z9IMAP4ServerTests.testLoginRequiringQuoting.<locals>.login)r  rr  usersr  r   r4   r  r  r   r  r    _cbTestLoginRequiringQuotingr  r.   rL   r1   testLoginRequiringQuoting  s
   z*IMAP4ServerTests.testLoginRequiringQuotingc                 C   r  r  r  r  r.   r.   r1   r  *  r  z-IMAP4ServerTests._cbTestLoginRequiringQuotingc                    s   d  _  fdd} fdd} jt|}|t| | j   }t||g}|j fdd}| j	ddggg g g |S )	Nc                      r  r  r  r.   rL   r.   r1   r  1  r.  z-IMAP4ServerTests.testNamespace.<locals>.loginc                         fdd}  j  | S )Nc                       |  _  d  d S r-   namespaceArgsr  rv  rL   r.   r1   gotNamespace5  rw   zGIMAP4ServerTests.testNamespace.<locals>.namespace.<locals>.gotNamespacer  	namespacer   r  rL   r.   r1   r  4     z1IMAP4ServerTests.testNamespace.<locals>.namespacec                    s2    j D ]}|D ]}|D ]} |t qqq j S r-   )r  r  r   )r  
namespacespairr  rL   r.   r1   assertAllPairsNativeStringsA  s   
zCIMAP4ServerTests.testNamespace.<locals>.assertAllPairsNativeStringsr  r*  )
r  r  r   r4   r  r  r    r   r  r?   )rB   r  r  r  r  r   r  r.   rL   r1   testNamespace.  s   zIMAP4ServerTests.testNamespacec                    s   t d j_d _ fdd} fdd} jt|}|t| | j  	 }t
||g}| fdd | jg g g g |S )	z
        A mailbox that does not provide L{INamespacePresenter} returns
        empty L{list}s for its personal, shared, and user namespaces.
        rk  Nc                      r  r  r  r.   rL   r.   r1   r  T  r.  z<IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.loginc                     r
  )Nc                    r  r-   r  r  rL   r.   r1   r  X  rw   zVIMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.namespace.<locals>.gotNamespacer  r  rL   r.   r1   r  W  r  z@IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.namespacec                        j S r-   )r  r  rL   r.   r1   r2   c  r3   z?IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.<lambda>)r\  r  r|  r  r  r   r4   r  r  r    r   r  r?   )rB   r  r  r  r  r   r.   rL   r1   test_mailboxWithoutNamespaceL  s   z-IMAP4ServerTests.test_mailboxWithoutNamespacec                    sr   t jd d  _ fdd} fdd} jt|}|t| | j  	 }t
||g jS )Ntest-mailboxc                      r  r  r  r.   rL   r.   r1   r  k  r.  z*IMAP4ServerTests.testSelect.<locals>.loginc                     &    fdd}  j d}||  |S )Nc                    r  r-   )selectedArgsr  r  rL   r.   r1   selectedo  rw   z=IMAP4ServerTests.testSelect.<locals>.select.<locals>.selectedr  )r  rd  r   )r  r   rL   r.   r1   rd  n     
z+IMAP4ServerTests.testSelect.<locals>.select)rj  r|  
addMailboxr  r  r   r4   r  r  r    r   r  _cbTestSelect)rB   r  rd  r  r  r.   rL   r1   
testSelectg  s   	zIMAP4ServerTests.testSelectc                    s    fdd} fdd} j t|  j t|  j  jd  j  j  j  j t j  	 g}|j fdd}|S )zh
        A client that selects a mailbox that does not exist receives a
        C{NO} response.
        c                      r  r  r  r.   rL   r.   r1   r    r.  z9IMAP4ServerTests.test_selectWithoutMailbox.<locals>.loginc                          j dS )Nr  r  rd  r.   rL   r.   r1   rd    r5   z:IMAP4ServerTests.test_selectWithoutMailbox.<locals>.select   No such mailboxc                          jj d S r-   )assertIsNoner  r  r  rL   r.   r1   assertNoMailboxSelected  s   zKIMAP4ServerTests.test_selectWithoutMailbox.<locals>.assertNoMailboxSelected)
r  r   r4   r  r  r  r  r   r  r    )rB   r  rd  connectionCompleter'  r.   rL   r1   test_selectWithoutMailbox}  s   z*IMAP4ServerTests.test_selectWithoutMailboxc              	   C   :   t jjd }| | jj| | | jdddddd d S )NTEST-MAILBOXr   r   r)  r  TEXISTSr  r  rm  
READ-WRITE)rj  r|  	mailboxesr?   r  r  r  rB   r  r  r.   r.   r1   r        zIMAP4ServerTests._cbTestSelectc                    sv   t jd d _ fdd} fdd} jt|}|t| | j  	 }t
||g}| jS )a  
        L{IMAP4Client.examine} issues an I{EXAMINE} command to the server and
        returns a L{Deferred} which fires with a C{dict} with as many of the
        following keys as the server includes in its response: C{'FLAGS'},
        C{'EXISTS'}, C{'RECENT'}, C{'UNSEEN'}, C{'READ-WRITE'}, C{'READ-ONLY'},
        C{'UIDVALIDITY'}, and C{'PERMANENTFLAGS'}.

        Unfortunately the server doesn't generate all of these so it's hard to
        test the client's handling of them here.  See
        L{IMAP4ClientExamineTests} below.

        See U{RFC 3501<http://www.faqs.org/rfcs/rfc3501.html>}, section 6.3.2,
        for details.
        r  Nc                      r  r  r  r.   rL   r.   r1   r    r.  z,IMAP4ServerTests.test_examine.<locals>.loginc                     r  )Nc                    r  r-   )examinedArgsr  r  rL   r.   r1   examined  rw   z@IMAP4ServerTests.test_examine.<locals>.examine.<locals>.examinedr  )r  examiner   )r3  r   rL   r.   r1   r4    r  z.IMAP4ServerTests.test_examine.<locals>.examine)rj  r|  r  r2  r  r   r4   r  r  r    r   r  _cbTestExamine)rB   r  r4  r  r  r   r.   rL   r1   test_examine  s   	zIMAP4ServerTests.test_examinec              	   C   r*  )Nr+  r   r   r)  r  Fr,  )rj  r|  r/  r?   r  r  r2  r0  r.   r.   r1   r5    r1  zIMAP4ServerTests._cbTestExaminec                    s   ddfdd fddfdd} fd	d
}g _ jt|t|} }t||g}|jS )N)testboxtest/boxztest/test/box/boxINBOX)r7  r8  c                          j d d S r,  r/   rr   r.   rL   r.   r1   cb  r  z'IMAP4ServerTests.testCreate.<locals>.cbc                    r;  Nr   r<  r!   rL   r.   r1   eb  r  z'IMAP4ServerTests.testCreate.<locals>.ebc                      r  r  r  r.   rL   r.   r1   r    r.  z*IMAP4ServerTests.testCreate.<locals>.loginc                     sB    D ]} j | }|t  q|jj d S r-   )r  creater   r4   r  addCallbacksr  r  )r_  r   r=  r@  r3  rB   r4  r.   r1   rA    s   z+IMAP4ServerTests.testCreate.<locals>.create)r/   r  r   r4   r    r   r  _cbTestCreate)rB   r  rA  r  r  r   r.   rC  r1   
testCreate  s   zIMAP4ServerTests.testCreatec                 C   sX   |  | jdgt| dgt|   ttjj}tg d}|  |dd |D  d S )Nr   r   )inboxr7  r8  testr9  c                 S      g | ]}|  qS r.   r  )r
  ar.   r.   r1   r    rF  z2IMAP4ServerTests._cbTestCreate.<locals>.<listcomp>)r?   r/   r   r=  rj  r|  r/  )rB   r  r4  r3  r  rP  r.   r.   r1   rD    s   &zIMAP4ServerTests._cbTestCreatec                       t jd  fdd} fdd} jt|}|t| j | j j  	 }t
||g}| fdd |S )N	delete/mec                      r  r  r  r.   rL   r.   r1   r    r.  z*IMAP4ServerTests.testDelete.<locals>.loginc                      r"  NrL  r  rI  r.   rL   r.   r1   rI    r5   z+IMAP4ServerTests.testDelete.<locals>.deletec                    s     ttjjg S r-   )r?   r   rj  r|  r/  r  rL   r.   r1   r2   	  rF  z-IMAP4ServerTests.testDelete.<locals>.<lambda>rj  r|  r  r  r   r4   rB  r  r  r    r   r  )rB   r  rI  r  r  r   r.   rL   r1   
testDelete  s   
zIMAP4ServerTests.testDeletec                    s   t jd t jd  fdd} fdd} fdd} jt|}|t| j || | j	  
 }t||g}| fd	d
 |S )z
        Attempting to delete a mailbox with hierarchically inferior
        names fails with an informative error.

        @see: U{https://tools.ietf.org/html/rfc3501#section-6.3.4}

        @return: A L{Deferred} with assertions.
        rI  rL  c                      r  r  r  r.   rL   r.   r1   r  	  r.  zGIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.loginc                      r"  NrI  rN  r.   rL   r.   r1   rI  	  r5   zHIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.deletec                    s&   |  tj  t| jtd d S )Ns-   Name "DELETE" has inferior hierarchical names)r  r   r  r?   r   r  r?  rL   r.   r1   assertIMAPException	  s
   zUIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.assertIMAPExceptionc                    s     ttjjddgS )NDELETEz	DELETE/ME)r?   r=  rj  r|  r/  r  rL   r.   r1   r2   +	  s    zJIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.<lambda>)rj  r|  r  r  r   r4   rB  r  r  r  r    r   r  )rB   r  rI  rR  loggedIn
loopedBackr   r.   rL   r1   'testDeleteWithInferiorHierarchicalNames
	  s   	

z8IMAP4ServerTests.testDeleteWithInferiorHierarchicalNamesc                       d  _  fdd} fdd} fdd} jt|}|t| j || | j j   }t	
||g}| fdd |S )	Nc                      r  r  r  r.   rL   r.   r1   r  4	  r.  z6IMAP4ServerTests.testIllegalInboxDelete.<locals>.loginc                      r"  )NrF  rN  r.   rL   r.   r1   rI  7	  r5   z7IMAP4ServerTests.testIllegalInboxDelete.<locals>.deletec                    
   |  _ d S r-   stashedr   rL   r.   r1   stash:	  rq   z6IMAP4ServerTests.testIllegalInboxDelete.<locals>.stashc                         t jtjS r-   r/  r  rZ  r!   Failurer  rL   r.   r1   r2   D	  rF  z9IMAP4ServerTests.testIllegalInboxDelete.<locals>.<lambda>rZ  r  r   r4   rB  r  r  r  r    r   r  )rB   r  rI  r[  r  r  r   r.   rL   r1   testIllegalInboxDelete1	     

z'IMAP4ServerTests.testIllegalInboxDeletec                    s    fdd} fdd} fdd}d  _  jt|}|t|| | j j   }t	
||g}| fdd |S )	Nc                      r  r  r  r.   rL   r.   r1   r  I	  r.  z5IMAP4ServerTests.testNonExistentDelete.<locals>.loginc                      r"  rM  rN  r.   rL   r.   r1   rI  L	  r5   z6IMAP4ServerTests.testNonExistentDelete.<locals>.deletec                    rX  r-   r?  r?  rL   r.   r1   deleteFailedO	  rq   z<IMAP4ServerTests.testNonExistentDelete.<locals>.deleteFailedc                    s     t jjtdS )Nr$  r?   r   r!   r  r  rL   r.   r1   r2   Y	  s    z8IMAP4ServerTests.testNonExistentDelete.<locals>.<lambda>)r!   r  r   r4   r  rB  r  r  r    r   r  )rB   r  rI  rb  r  r  r   r.   rL   r1   testNonExistentDeleteH	  s   
z&IMAP4ServerTests.testNonExistentDeletec                    s   t  }d|_tjd| tjd fdd}fdd}fdd	}d _jt|}|t|	| |
jj  }t||g}td
 | fdd |S )N)z	\NoselectrI  rL  c                      r  r  r  r.   rL   r.   r1   r  c	  r.  z1IMAP4ServerTests.testIllegalDelete.<locals>.loginc                      r"  rQ  rN  r.   rL   r.   r1   rI  f	  r5   z2IMAP4ServerTests.testIllegalDelete.<locals>.deletec                    rX  r-   r?  r?  rL   r.   r1   rb  i	  rq   z8IMAP4ServerTests.testIllegalDelete.<locals>.deleteFaileds<   Hierarchically inferior mailboxes exist and \Noselect is setc                    s    tjj S r-   rc  r  r?  rB   r.   r1   r2   u	  rF  z4IMAP4ServerTests.testIllegalDelete.<locals>.<lambda>)r  ro  rj  r|  r  r!   r  r   r4   r  rB  r  r  r    r   r  r   )rB   r   r  rI  rb  r  r  r   r.   re  r1   testIllegalDelete]	  s$   z"IMAP4ServerTests.testIllegalDeletec                    rK  )Noldmboxc                      r  r  r  r.   rL   r.   r1   r  {	  r.  z*IMAP4ServerTests.testRename.<locals>.loginc                      r  )Ns   oldmboxs   newnamer  renamer.   rL   r.   r1   ri  ~	  r.  z+IMAP4ServerTests.testRename.<locals>.renamec                    s     ttjj dgS )NNEWNAME)r?   r   rj  r|  r/  r  r  rL   r.   r1   r2   	  s    z-IMAP4ServerTests.testRename.<locals>.<lambda>rO  rB   r  ri  r  r  r   r.   rL   r1   
testRenamex	     
zIMAP4ServerTests.testRenamec                    rW  )	Nc                      r  r  r  r.   rL   r.   r1   r  	  r.  z6IMAP4ServerTests.testIllegalInboxRename.<locals>.loginc                      r  )NrF  frotzrh  r.   rL   r.   r1   ri  	  r.  z7IMAP4ServerTests.testIllegalInboxRename.<locals>.renamec                    rX  r-   rY  )stuffrL   r.   r1   r[  	  rq   z6IMAP4ServerTests.testIllegalInboxRename.<locals>.stashc                    r\  r-   r]  r  rL   r.   r1   r2   	  rF  z9IMAP4ServerTests.testIllegalInboxRename.<locals>.<lambda>r_  )rB   r  ri  r[  r  r  r   r.   rL   r1   testIllegalInboxRename	  ra  z'IMAP4ServerTests.testIllegalInboxRenamec                    s   t jd t jd  fdd} fdd} jt|}|t| j | j j  	 }t
||g}| jS )Nz
oldmbox/m1z
oldmbox/m2c                      r  r  r  r.   rL   r.   r1   r  	  r.  z6IMAP4ServerTests.testHierarchicalRename.<locals>.loginc                      r  )Nrg  newnamerh  r.   rL   r.   r1   ri  	  r.  z7IMAP4ServerTests.testHierarchicalRename.<locals>.rename)rj  r|  rA  r  r   r4   rB  r  r  r    r   r  _cbTestHierarchicalRenamerk  r.   rL   r1   testHierarchicalRename	  s   z'IMAP4ServerTests.testHierarchicalRenamec                 C   s:   t jj }g d}tt|}| |dd |D  d S )N)rq  z
newname/m1z
newname/m2c                 S   rH  r.   rI  )r
  rR  r.   r.   r1   r  	  rF  z>IMAP4ServerTests._cbTestHierarchicalRename.<locals>.<listcomp>)rj  r|  r/  r  r   r=  r?   )rB   r  mboxesr?  r.   r.   r1   rr  	  s   z*IMAP4ServerTests._cbTestHierarchicalRenamec                    sv    fdd} fdd} j t|}|t| j | j j   }t||g}| fdd |S )Nc                      r  r  r  r.   rL   r.   r1   r  	  r.  z-IMAP4ServerTests.testSubscribe.<locals>.loginc                      r"  Nz	this/mbox)r  	subscriber.   rL   r.   r1   rv  	  r5   z1IMAP4ServerTests.testSubscribe.<locals>.subscribec                         tjjdgS )N	THIS/MBOXr?   rj  r|  subscriptionsr  rL   r.   r1   r2   	      
z0IMAP4ServerTests.testSubscribe.<locals>.<lambda>)	r  r   r4   rB  r  r  r    r   r  )rB   r  rv  r  r  r   r.   rL   r1   testSubscribe	  s   
zIMAP4ServerTests.testSubscribec                    s   ddgt j_ fdd} fdd} jt|}|t| j | j j  	 }t
||g}| fdd |S )	Nrx  	THAT/MBOXc                      r  r  r  r.   rL   r.   r1   r  	  r.  z/IMAP4ServerTests.testUnsubscribe.<locals>.loginc                      r"  ru  )r  unsubscriber.   rL   r.   r1   r~  	  r5   z5IMAP4ServerTests.testUnsubscribe.<locals>.unsubscribec                    rw  )Nr}  ry  r  rL   r.   r1   r2   	  r{  z2IMAP4ServerTests.testUnsubscribe.<locals>.<lambda>)rj  r|  rz  r  r   r4   rB  r  r  r    r   r  )rB   r  r~  r  r  r   r.   rL   r1   testUnsubscribe	  rm  z IMAP4ServerTests.testUnsubscribec                    s   t jd t jd t jd  fdd} fdd}d  _ jt|}|t| j || j | j	 j  
 }t||g fdd	S )
Nroot/subthingzroot/another-thingznon-root/subthingc                      r  r  r  r.   rL   r.   r1   r  	  r.  z*IMAP4ServerTests._listSetup.<locals>.loginc                    rX  r-   listed)rP  rL   r.   r1   r  	  rq   z+IMAP4ServerTests._listSetup.<locals>.listedc                    r  r-   r  r  rL   r.   r1   r2   	  r3   z-IMAP4ServerTests._listSetup.<locals>.<lambda>)rj  r|  r  r  r  r   r4   rB  r  r  r    r   r  )rB   r0   r  r  r  r  r.   rL   r1   
_listSetup	  s   zIMAP4ServerTests._listSetupc                 C   s2   |D ]}|  |d td |  |d td q|S )z
        Assert a C{LIST} response's delimiter and mailbox are native
        strings.

        @param results: A list of tuples as returned by
            L{IMAP4Client.list} or L{IMAP4Client.lsub}.
        r   zdelimiter %r is not a strr   zmailbox %r is not a str)r  r   )rB   resultsr/   r.   r.   r1   'assertListDelimiterAndMailboxAreStrings	  s   z8IMAP4ServerTests.assertListDelimiterAndMailboxAreStringsc                    s,    fdd}  |}|j fdd}|S )Nc                      r  Nroot%)r  r   r.   rL   r.   r1   mailboxList
  r.  z.IMAP4ServerTests.testList.<locals>.mailboxListc                    sj   t tjddft tjddfg}tdD ]}| d\}}} t |||f| q | d|  d S )Nr*  ROOT/SUBTHINGzROOT/ANOTHER-THINGr   r   zMore results than expected: )r=  r  ro  rd   popr   r-  )r  expectedContentsr  ro  	delimitermailboxrL   r.   r1   assertListContents	
  s   z5IMAP4ServerTests.testList.<locals>.assertListContents)r  r   )rB   r  r   r  r.   rL   r1   testList
  s
   
zIMAP4ServerTests.testListc                    sJ   t jd  fdd} |}| j | jtjddfg |S )Nr  c                      r  r  )r  lsubr.   rL   r.   r1   r  
  r.  z'IMAP4ServerTests.testLSub.<locals>.lsubr*  )	rj  r|  rv  r  r   r  r?   r  ro  )rB   r  r   r.   rL   r1   testLSub
  s   
zIMAP4ServerTests.testLSubc                    s   t jd  fdd} fdd} fdd}d  _ jt|}|t| j || j | j	 j  
 }t||g}| fdd	 |S )
Nr  c                      r  r  r  r.   rL   r.   r1   r  )
  r.  z*IMAP4ServerTests.testStatus.<locals>.loginc                          j ddddS )Nr  r  r  r  r  statusr.   rL   r.   r1   r  ,
     z+IMAP4ServerTests.testStatus.<locals>.statusc                    rX  r-   statusedr   rL   r.   r1   r  /
  rq   z-IMAP4ServerTests.testStatus.<locals>.statusedc                    s      jddddS )Nr   s   10r   )r  r  r  )r?   r  r  rL   r.   r1   r2   :
  s    z-IMAP4ServerTests.testStatus.<locals>.<lambda>)rj  r|  r  r  r  r   r4   rB  r  r  r    r   r  )rB   r  r  r  r  r  r   r.   rL   r1   
testStatus&
  s   
zIMAP4ServerTests.testStatusc                    s    fdd} fdd} fdd} fdd}d   _  _ jt|}|t| j ||| | j j   }t	
||g jS )	Nc                      r  r  r  r.   rL   r.   r1   r  A
  r.  z0IMAP4ServerTests.testFailedStatus.<locals>.loginc                      r  )Nzroot/nonexistentr  r  r  r  r.   rL   r.   r1   r  D
  s   z1IMAP4ServerTests.testFailedStatus.<locals>.statusc                    rX  r-   r  r   rL   r.   r1   r  I
  rq   z3IMAP4ServerTests.testFailedStatus.<locals>.statusedc                    rX  r-   r?  r?  rL   r.   r1   failedL
  rq   z1IMAP4ServerTests.testFailedStatus.<locals>.failed)r  r!   r  r   r4   rB  r  r  r    r   r  _cbTestFailedStatus)rB   r  r  r  r  r  r  r.   rL   r1   testFailedStatus@
  s   z!IMAP4ServerTests.testFailedStatusc                 C   s$   |  | jd  |  | jjjd d S )N)s   Could not open mailbox)r?   r  r!   r  rv  r  r.   r.   r1   r  W
     z$IMAP4ServerTests._cbTestFailedStatusc                       t td tjd fdd}tj fdd}j	t
|}|t
|j |jj  }t||g}|	j S )Nrfc822.messager  c                      r  r  r  r.   rL   r.   r1   r  _
  r.  z.IMAP4ServerTests.testFullAppend.<locals>.loginc                  3   sP    t  d} jd| ddV }t| W d    d S 1 s!w   Y  d S )Nrbr  )\SEEN\DELETEDz%Tue, 17 Jun 2003 11:22:16 -0600 (MDT))openr  rr   r   returnValuer?  r/   infilerB   r.   r1   rr   b
  s   "z/IMAP4ServerTests.testFullAppend.<locals>.append)r#   sibpath__file__rj  r|  r  r   inlineCallbacksr  r   r4   rB  r  r  r    r  _cbTestFullAppendrB   r  rr   r  r  r   r.   r  r1   testFullAppend[
  s   
zIMAP4ServerTests.testFullAppendc                 C   s   t jjd }| dt|j | ddgddf|jd dd   t|d}| | |jd d   W d    d S 1 sAw   Y  d S )Nr  r   r  r  s%   Tue, 17 Jun 2003 11:22:16 -0600 (MDT)r   r  	rj  r|  r/  r?   r   r  r  rP   rU   rB   r  r  mbr0   r.   r.   r1   r  v
  s    "z"IMAP4ServerTests._cbTestFullAppendc                    r  )Nr  PARTIAL/SUBTHINGc                      r  r  r  r.   rL   r.   r1   r  
  r.  z1IMAP4ServerTests.testPartialAppend.<locals>.loginc                  3   sn    t  d'} jtdtdtj f djj	| V }t
| W d    d S 1 s0w   Y  d S )Nr  s   APPENDz)PARTIAL/SUBTHING (\SEEN) "Right now" {%d}r.   )r  r  sendCommandr   r  r&   ospathgetsize_IMAP4Client__cbContinueAppendr   r  r  r  r.   r1   rr   
  s"   "z2IMAP4ServerTests.testPartialAppend.<locals>.append)r#   r  r  rj  r|  r  r   r  r  r   r4   rB  r  r  r    r  _cbTestPartialAppendr  r.   r  r1   testPartialAppend
  s   z"IMAP4ServerTests.testPartialAppendc                 C   s   t jjd }| dt|j | dgddf|jd dd   t|d}| | |jd d   W d    d S 1 s@w   Y  d S )Nr  r   r  s	   Right nowr   r  r  r  r.   r.   r1   r  
  s   " "z%IMAP4ServerTests._cbTestPartialAppendc                    s|   t jd  fdd} fdd} fdd} jt|}|t| j |t| j | j j  	 S )N   root/subthingc                      r  r  r  r.   rL   r.   r1   r  
  r.  z*IMAP4ServerTests._testCheck.<locals>.loginc                      r"  )Nr  r#  r.   rL   r.   r1   rd  
  r5   z+IMAP4ServerTests._testCheck.<locals>.selectc                      
    j  S r-   )r  rb  r.   rL   r.   r1   rb  
  rq   z*IMAP4ServerTests._testCheck.<locals>.check)
rj  r|  r  r  r   r4   rB  r  r  r    )rB   r  rd  rb  r   r.   rL   r1   
_testCheck
  s   zIMAP4ServerTests._testCheckc                 C   r]  )zf
        Trigger the L{imap.IMAP4Server._cbSelectWork} callback
        by selecting an mbox.
        )r  rL   r.   r.   r1   
test_check
  s   zIMAP4ServerTests.test_checkc                    s6   ddd} fdd}  td|   }||S )	zr
        Trigger the L{imap.IMAP4Server._ebSelectWork} errback
        by failing when we select an mbox.
        r   c                 S   s
   t d)Nencoding)r   IllegalMailboxEncoding)rB   r_  r0  r.   r.   r1   
failSelect
  rq   z3IMAP4ServerTests.test_checkFail.<locals>.failSelectc                    s$      } |d jjd d d S )Nr   r   s   SELECT failed: Server error)r   r?   r  rv  )r  failuresrL   r.   r1   checkResponse
     z6IMAP4ServerTests.test_checkFail.<locals>.checkResponserd  Nre  )patchrg  r  r   )rB   r  r  r   r.   rL   r1   test_checkFail
  s
   

zIMAP4ServerTests.test_checkFailc                    s   t  }g d|_tjd|  fdd} fdd} fdd} jt|}|t| j	 |t| j	 | j
 j	   }t||g j|S )	N)s	   Message 1)rC  AnotherFlagNr   s	   Message 2)r  Nr   )s	   Message 3)rC  Nr   r  c                      r  r  r  r.   rL   r.   r1   r  
  r.  z)IMAP4ServerTests.testClose.<locals>.loginc                      r"  )Ns   mailboxr#  r.   rL   r.   r1   rd  
  r5   z*IMAP4ServerTests.testClose.<locals>.selectc                      r  r-   )r  rM  r.   rL   r.   r1   rM  
  rq   z)IMAP4ServerTests.testClose.<locals>.close)r  r  rj  r|  r  r  r   r4   rB  r  r  r    r   r  _cbTestClose)rB   r   r  rd  rM  r   r  r.   rL   r1   	testClose
  s   
zIMAP4ServerTests.testClosec                 C   s4   |  t|jd |  |jd d | |j d S )Nr   r   r  )r?   r   r  r/  rL  rB   r  r   r.   r.   r1   r  
  s   zIMAP4ServerTests._cbTestClosec           	         s   t  }g d|_tjd|  fdd} fdd} fdd} fd	d
}d  _ jt|}|	t| j
 |	t| j
 |	| j
 |	 j j
   }t||g}| j|S )Nr  r  c                      r  r  r  r.   rL   r.   r1   r  
  r.  z+IMAP4ServerTests.testExpunge.<locals>.loginc                      r"  )Nr  r#  r.   rL   r.   r1   rd  
  r5   z,IMAP4ServerTests.testExpunge.<locals>.selectc                      r  r-   )r  rJ  r.   rL   r.   r1   rJ    rq   z-IMAP4ServerTests.testExpunge.<locals>.expungec                    s      jjd u  |  _d S r-   )r-  r  r  r  r  rL   r.   r1   expunged     
z.IMAP4ServerTests.testExpunge.<locals>.expunged)r  r  rj  r|  r  r  r  r   r4   rB  r  r  r    r   r  _cbTestExpunge)	rB   r   r  rd  rJ  r  r  r  r   r.   rL   r1   testExpunge
  s    
zIMAP4ServerTests.testExpungec                 C   s:   |  t|jd |  |jd d |  | jddg d S )Nr   r   r  r   )r?   r   r  r  r  r.   r.   r1   r    s   zIMAP4ServerTests._cbTestExpungeN)6ri   rj   rk   r  r  r  r  r  r  r  r  r  r  r  r	  r  r  r  r!  r)  r   r6  r5  rE  rD  rP  rV  r`  rd  rf  rl  rp  rs  rr  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   r  x  sh    	
#%'
$ r  c                   @   sH  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPS )QIMAP4ServerParsingTestsz6
    Test L{imap4.IMAP4Server}'s command parsing.
    c                 C   s.   t  | _t | _| j| j | j  d S r-   )r'   r  r   ro  r  makeConnectionclearrL   r.   r.   r1   r    s   
zIMAP4ServerParsingTests.setUpc                 C      | j tt  d S r-   r  connectionLostr!   r^  r   ConnectionDonerL   r.   r.   r1   r  %     z IMAP4ServerParsingTests.tearDownc                    sL   G dd dt   fdd}d| j_|| j_| jd | |   dS )zO
        L{imap4.IMAP4Server} logs exceptions raised by parse methods.
        c                   @   rf  )zSIMAP4ServerParsingTests.test_parseMethodExceptionLogged.<locals>.UnhandledException1
            An unhandled exception.
            Nrh  r.   r.   r.   r1   UnhandledException-  ri  r  c                        r-   r.   )r{  r  r.   r1   raisesValueError2  r*  zQIMAP4ServerParsingTests.test_parseMethodExceptionLogged.<locals>.raisesValueErrorcommand   invalidN)r  r  
parseStateparse_commandry  r/  r   )rB   r  r.   r  r1   test_parseMethodExceptionLogged(  s   z7IMAP4ServerParsingTests.test_parseMethodExceptionLoggedc                 C   s:   | j d | | j d | j tt	d dS )z
        L{imap4.IMAP4Server.parse_command} sends a C{BAD} response to
        a line that includes a tag but no command.
           001s   001 BAD Missing command
DoneN)
r  r  r?   r  r  r  r!   r^  r   r  rL   r.   r.   r1   test_missingCommand<  s
   z+IMAP4ServerParsingTests.test_missingCommandc                 C   "   | j d | | j d dS )zf
        L{imap4.IMAP4Server.parse_command} sends a C{BAD} response to
        an empty line.
        r   s   * BAD Null command
N)r  r  r?   r  r  rL   r.   r.   r1   test_emptyLineI  s   z&IMAP4ServerParsingTests.test_emptyLinec                    sJ    fdd}|| j _| j d|dg | | j d||g dS )aV  
        Assert that the given exception results in the expected
        response.

        @param exception: The exception to raise.
        @type exception: L{Exception}

        @param tag: The IMAP tag.

        @type: L{bytes}

        @param expectedResponse: The expected bad response.
        @type expectedResponse: L{bytes}
        c                    r  r-   r.   )tagcmdrest	exceptionr.   r1   raisesb  r*  zDIMAP4ServerParsingTests.assertParseExceptionResponse.<locals>.raisesrZ  r  N)r  dispatchCommandr  r   r?   r  r  rB   r  r  expectedResponser  r.   r  r1   assertParseExceptionResponseR  s    z4IMAP4ServerParsingTests.assertParseExceptionResponsec                 C      |  tddd dS )zt
        When a parsing method raises L{IllegalClientResponse}, the
        server sends a C{BAD} response.
        client responser  %   BAD Illegal syntax: client response
N)r  r   IllegalClientResponserL   r.   r.   r1   'test_parsingRaisesIllegalClientResponsek  
   z?IMAP4ServerParsingTests.test_parsingRaisesIllegalClientResponsec                 C   r  )zn
        When a parsing method raises L{IllegalOperation}, the server
        sends a C{NO} response.
        	operationr  !   NO Illegal operation: operation
N)r  r   IllegalOperationrL   r.   r.   r1   *test_parsingRaisesIllegalOperationResponsev  r  zBIMAP4ServerParsingTests.test_parsingRaisesIllegalOperationResponsec                 C   r  )zt
        When a parsing method raises L{IllegalMailboxEncoding}, the
        server sends a C{NO} response.
        r  r  #   NO Illegal mailbox name: encoding
N)r  r   r  rL   r.   r.   r1   (test_parsingRaisesIllegalMailboxEncoding  r  z@IMAP4ServerParsingTests.test_parsingRaisesIllegalMailboxEncodingc                 C   r  )zi
        L{imap4.IMAP4Server} responds to an unsupported command with a
        C{BAD} response.
        s   001 HULLABALOOs   001 BAD Unsupported command
N)r  ry  r?   r  r  rL   r.   r.   r1   test_unsupportedCommand  s   z/IMAP4ServerParsingTests.test_unsupportedCommandc                 C   s4   | j d | | j dtdd d  dS )z~
        L{imap4.IMAP4Server} responds with a C{BAD} response to a
        command with more arguments than expected.
        s   001 LOGIN A B Cs8   001 BAD Illegal syntax: Too many arguments for command:    Czutf-8r_  N)r  ry  r?   r  r  r   r@   rL   r.   r.   r1   test_tooManyArgumentsForCommand  s   z7IMAP4ServerParsingTests.test_tooManyArgumentsForCommandc                    sf    fdd}|  | jjd |f| jjdd  | j_| j|dd |  | j d||g dS )	aR  
        Assert that the given exception results in the expected
        response.

        @param exception: The exception to raise.
        @type exception: L{Exception}

        @param: The IMAP tag.

        @type: L{bytes}

        @param expectedResponse: The expected bad response.
        @type expectedResponse: L{bytes}
        c                    r  r-   r.   )serverInstancer  r  r  r  r.   r1   r    r*  zFIMAP4ServerParsingTests.assertCommandExceptionResponse.<locals>.raisesr  r   N   LOGINs   user passwdrZ  )r?   r  r  unauth_LOGINr  r  r  r   r  r.   r  r1   assertCommandExceptionResponse  s
    z6IMAP4ServerParsingTests.assertCommandExceptionResponsec                 C   r  )zm
        When a command raises L{IllegalClientResponse}, the
        server sends a C{BAD} response.
        r  r  r  N)r  r   r  rL   r.   r.   r1   'test_commandRaisesIllegalClientResponse  r  z?IMAP4ServerParsingTests.test_commandRaisesIllegalClientResponsec                 C   r  )zg
        When a command raises L{IllegalOperation}, the server sends a
        C{NO} response.
        r  r  r  N)r  r   r  rL   r.   r.   r1   *test_commandRaisesIllegalOperationResponse  r  zBIMAP4ServerParsingTests.test_commandRaisesIllegalOperationResponsec                 C   r  )zm
        When a command raises L{IllegalMailboxEncoding}, the server
        sends a C{NO} response.
        r  r  r  N)r  r   r  rL   r.   r.   r1   (test_commandRaisesIllegalMailboxEncoding  r  z@IMAP4ServerParsingTests.test_commandRaisesIllegalMailboxEncodingc                 C   s6   G dd dt }| |ddd | | | dS )z
        Wehn a command raises an unhandled exception, the server sends
        a C{BAD} response and logs the exception.
        c                   @   rf  )zXIMAP4ServerParsingTests.test_commandRaisesUnhandledException.<locals>.UnhandledExceptionr  Nrh  r.   r.   r.   r1   r    ri  r  	unhandledr  s   BAD Server error: unhandled
N)r  r  r/  r   )rB   r  r.   r.   r1   $test_commandRaisesUnhandledException  s   z<IMAP4ServerParsingTests.test_commandRaisesUnhandledExceptionc                 C   s*   d| j _| j d | | j d dS )zx
        A string literal whose length exceeds the maximum allowed
        length results in a C{BAD} response.
        r   s   001 LOGIN {5}
sE   001 BAD Illegal syntax: Literal too long! I accept at most 4 octets
N)r  _literalStringLimitry  r?   r  r  rL   r.   r.   r1   test_stringLiteralTooLong  s   z1IMAP4ServerParsingTests.test_stringLiteralTooLongc                 C   s"   dD ]}|  tj| jj| qdS )zQ
        An empty string argument raises L{imap4.IllegalClientResponse}.
        )r   r_  rZ  Nr   r   r  r  arg_astring)rB   r  r.   r.   r1   test_arg_astringEmptyLine  s
   z1IMAP4ServerParsingTests.test_arg_astringEmptyLinec                 C      |  tj| jjd dS )zh
        An unmatched quote in a string argument raises
        L{imap4.IllegalClientResponse}.
        s   "openNr  rL   r.   r.   r1   test_arg_astringUnmatchedQuotes
     z7IMAP4ServerParsingTests.test_arg_astringUnmatchedQuotesc                 C   r  )zn
        An unmatched brace in a string literal's size raises
        L{imap4.IllegalClientResponse}.
        s   {0Nr  rL   r.   r.   r1   &test_arg_astringUnmatchedLiteralBraces  r   z>IMAP4ServerParsingTests.test_arg_astringUnmatchedLiteralBracesc                 C   r  )zc
        A non-integral string literal size raises
        L{imap4.IllegalClientResponse}.
           {[object Object]}Nr  rL   r.   r.   r1   "test_arg_astringInvalidLiteralSize  r  z:IMAP4ServerParsingTests.test_arg_astringInvalidLiteralSizec                 C   r  )z@
        An empty atom raises L{IllegalClientResponse}.
        r   Nr   r   r  r  arg_atomrL   r.   r.   r1   test_arg_atomEmptyLine#  r  z.IMAP4ServerParsingTests.test_arg_atomEmptyLinec                 C   r  )zC
        A malformed atom raises L{IllegalClientResponse}.
        s    not an atom Nr  rL   r.   r.   r1   test_arg_atomMalformedAtom)  s   z2IMAP4ServerParsingTests.test_arg_atomMalformedAtomc                 C   r  )zN
        An empty parenthesized list raises L{IllegalClientResponse}.
        r   Nr   r   r  r  	arg_plistrL   r.   r.   r1   test_arg_plistEmptyLine1  r  z/IMAP4ServerParsingTests.test_arg_plistEmptyLinec                 C   ,   |  tj| jjd |  tj| jjd dS )ze
        A parenthesized with unmatched parentheses raises
        L{IllegalClientResponse}.
        s   (foos   foo)Nr  rL   r.   r.   r1   "test_arg_plistUnmatchedParentheses7     z:IMAP4ServerParsingTests.test_arg_plistUnmatchedParenthesesc                 C   r  )zH
        An empty file literal raises L{IllegalClientResponse}.
        r   Nr   r   r  r  arg_literalrL   r.   r.   r1   test_arg_literalEmptyLine?  r  z1IMAP4ServerParsingTests.test_arg_literalEmptyLinec                 C   r  )zZ
        A literal with unmatched braces raises
        L{IllegalClientResponse}.
        s   {10s   10}Nr  rL   r.   r.   r1   test_arg_literalUnmatchedBracesE  r  z7IMAP4ServerParsingTests.test_arg_literalUnmatchedBracesc                 C   r  )z\
        A non-integral literal size raises
        L{imap4.IllegalClientResponse}.
        r  Nr  rL   r.   r.   r1   "test_arg_literalInvalidLiteralSizeM  r  z:IMAP4ServerParsingTests.test_arg_literalInvalidLiteralSizec                 C   s$   d}| j |\}}| |d dS )zH
        A sequence set returns the unparsed portion of a line.
        s   1:* blah blah blahs   blah blah blahN)r  
arg_seqsetr?   )rB   sequencer  r  r.   r.   r1   test_arg_seqsetReturnsRestV  s   z2IMAP4ServerParsingTests.test_arg_seqsetReturnsRestc                 C   r  )zL
        An invalid sequence raises L{imap4.IllegalClientResponse}.
        s   x:yN)r   r   r  r  r#  rL   r.   r.   r1   test_arg_seqsetInvalidSequence^  r  z6IMAP4ServerParsingTests.test_arg_seqsetInvalidSequencec                 C   s0   d}| j |\}}| ||g | | dS )zJ
        A single flag that is not contained in a list is parsed.
        s   flagN)r  arg_flaglistr?   r-  )rB   flagra  r  r.   r.   r1   test_arg_flaglistOneFlagd  s   z0IMAP4ServerParsingTests.test_arg_flaglistOneFlagc                 C   r  )zk
        A list of flags with unmatched parentheses raises
        L{imap4.IllegalClientResponse}.
        s   (invalidNr   r   r  r  r'  rL   r.   r.   r1   &test_arg_flaglistMismatchedParentehsesm  s
   z>IMAP4ServerParsingTests.test_arg_flaglistMismatchedParentehsesc                 C   r  )zo
        A list of flags that contains a malformed flag raises
        L{imap4.IllegalClientResponse}.
        s	   (first  )s   (first  second)Nr*  rL   r.   r.   r1   test_arg_flaglistMalformedFlagx  s   z6IMAP4ServerParsingTests.test_arg_flaglistMalformedFlagc                 C   .   d}| j |\}}| | | || dS )z
        A line that does not begin with an open parenthesis (C{(}) is
        parsed as L{None}, and the remainder is the whole line.
        s   not (N)r  	opt_plistr&  r?   )rB   r{  plist	remainderr.   r.   r1   $test_opt_plistMissingOpenParenthesis     
z<IMAP4ServerParsingTests.test_opt_plistMissingOpenParenthesisc                 C   r-  )z
        A line that does not begin with a double quote (C{"}) is
        parsed as L{None}, and the remainder is the whole line.
        s   not "N)r  opt_datetimer&  r?   )rB   r{  dtr0  r.   r.   r1   !test_opt_datetimeMissingOpenQuote  r2  z9IMAP4ServerParsingTests.test_opt_datetimeMissingOpenQuotec                 C      d}|  tj| jj| dS )zx
        A line that does not have a closing double quote (C{"}) raises
        L{imap4.IllegalClientResponse}.
        s   "21-Jul-2017 19:37:07 -0700N)r   r   r  r  r3  rz  r.   r.   r1   "test_opt_datetimeMissingCloseQuote     z:IMAP4ServerParsingTests.test_opt_datetimeMissingCloseQuotec                 C   r6  )z
        A line that contains C{CHARSET} but no character set
        identifier raises L{imap4.IllegalClientResponse}.
        rh  N)r   r   r  r  opt_charsetrz  r.   r.   r1   !test_opt_charsetMissingIdentifier  r8  z9IMAP4ServerParsingTests.test_opt_charsetMissingIdentifierc                 C   0   d}| j |\}}| |d | |d dS )z
        A line that ends with a C{CHARSET} identifier is parsed as
        that identifier, and the remainder is the empty string.
        s   CHARSET UTF-8   UTF-8r   Nr  r9  r?   rB   r{  
identifierr0  r.   r.   r1   test_opt_charsetEndOfLine  s   z1IMAP4ServerParsingTests.test_opt_charsetEndOfLinec                 C   r;  )z
        A line that has additional data after a C{CHARSET} identifier
        is parsed as that identifier, and the remainder is that
        additional data.
        s   CHARSET UTF-8 remainderr<  s	   remainderNr=  r>  r.   r.   r1   test_opt_charsetWithRemainder  s   z5IMAP4ServerParsingTests.test_opt_charsetWithRemainderN)+ri   rj   rk   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r  r  r  r  r   r!  r"  r%  r&  r)  r+  r,  r1  r5  r7  r:  r@  rA  r.   r.   r.   r1   r    sR    						


r  c                   @   sp   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )IMAP4ServerSearchTestszS
    Tests for the behavior of the search_* functions in L{imap4.IMAP4Server}.
    c                 C   sD   t |  dg| _dg| _dg| _d| _tddig ddd	d | _d S )
Nz10-Dec-2009z13-Dec-2009z16-Dec-2009r   r@  zMon, 13 Dec 2009 21:25:10 GMTz13 Dec 2009 00:00:00 GMTr    )r  r  earlierQuerysameDateQuery
laterQueryseqr   r   rL   r.   r.   r1   r    s   

zIMAP4ServerSearchTests.setUpc                 C   <   |  | j| j| j| j | | j| j| j| j dS )z
        L{imap4.IMAP4Server.search_SENTBEFORE} returns True if the message date
        is earlier than the query date.
        N)r-  r  search_SENTBEFORErD  rG  r   r/  rF  rL   r.   r.   r1   test_searchSentBefore     z,IMAP4ServerSearchTests.test_searchSentBeforec                 C   s^   |  | jdg| j| jd | | jdg| j| jd | | jdg| j| jd dS )zq
        L{imap4.IMAP4Server.search_UID} returns True if the message UID is in
        the search range.
        r   )r   rC  s   2:*r   N)r-  r  
search_UIDrG  r   r/  rL   r.   r.   r1   test_searchWildcard  s
   "z*IMAP4ServerSearchTests.test_searchWildcardc                 C   s"   |  | jdg| j| jd dS )z
        L{imap4.IMAP4Server.search_UID} should return True if there is a
        wildcard, because a wildcard means "highest UID in the mailbox".
        s   1235:*)rC  r   N)r/  r  rL  rG  r   rL   r.   r.   r1   test_searchWildcardHigh  s   z.IMAP4ServerSearchTests.test_searchWildcardHighc                 C   s"   t d}| t|g d dS )|
        L{imap4.IMAP4Server.search_SENTON} returns True if the message date is
        the same as the query date.
        r  r  N)r   r   r?   r   )rB   msgsetr.   r.   r1   test_reversedSearchTerms  s   
z/IMAP4ServerSearchTests.test_reversedSearchTermsc                 C   sX   |  | j| j| j| j | | j| j| j| j |  | j| j| j| j dS )rO  N)	r-  r  search_SENTONrD  rG  r   r/  rE  rF  rL   r.   r.   r1   test_searchSentOn      z(IMAP4ServerSearchTests.test_searchSentOnc                 C   rH  )z~
        L{imap4.IMAP4Server.search_SENTSINCE} returns True if the message date
        is later than the query date.
        N)r/  r  search_SENTSINCErD  rG  r   r-  rF  rL   r.   r.   r1   test_searchSentSince  rK  z+IMAP4ServerSearchTests.test_searchSentSincec                 C   s   |  | jdg| j dg | j | j| jd |  | jdg| j dg | j | j| jd | | jdg| j dg | j | j| jd dS )z
        L{imap4.IMAP4Server.search_OR} returns true if either of the two
        expressions supplied to it returns true and returns false if neither
        does.
        	SENTSINCEr   SENTONN)r/  r  	search_ORrD  rF  rG  r   r-  rL   r.   r.   r1   test_searchOr  s0   z$IMAP4ServerSearchTests.test_searchOrc                 C   sL   |  | jdg| j | j| jd | | jdg| j | j| jd dS )z~
        L{imap4.IMAP4Server.search_NOT} returns the negation of the result
        of the expression supplied to it.
        rW  r   rX  N)r-  r  
search_NOTrD  rG  r   r/  rF  rL   r.   r.   r1   test_searchNot3  s   z%IMAP4ServerSearchTests.test_searchNotc                 C   X   |  | j| j| j| j |  | j| j| j| j | | j| j| j| j dS )z
        L{imap4.IMAP4Server.search_BEFORE} returns True if the
        internal message date is before the query date.
        N)	r-  r  search_BEFORErD  rG  r   rE  r/  rF  rL   r.   r.   r1   test_searchBeforeC  rT  z(IMAP4ServerSearchTests.test_searchBeforec                 C   sX   |  | j| j| j| j |  | j| j| j| j |  | j| j| j| j dS )z
        L{imap4.IMAP4Server.search_ON} returns True if the
        internal message date is the same as the query date.
        N)r-  r  	search_ONrD  rG  r   rE  rF  rL   r.   r.   r1   test_searchOnP  s    z$IMAP4ServerSearchTests.test_searchOnc                 C   r]  )z
        L{imap4.IMAP4Server.search_SINCE} returns True if the
        internal message date is greater than the query date.
        N)	r/  r  search_SINCErD  rG  r   rE  r-  rF  rL   r.   r.   r1   test_searchSinceY  s
    z'IMAP4ServerSearchTests.test_searchSinceN)ri   rj   rk   r  r  rJ  rM  rN  rQ  rS  rV  rZ  r\  r_  ra  rc  r.   r.   r.   r1   rB    s    		rB  c                   @   s&   e Zd ZdZdZdddZdd ZdS )rp  z
    A L{IRealm} for tests.

    @cvar theAccount: An C{Account} instance.  Tests can set this to
        ensure predictable account retrieval.
    Nc                    s(    r fdd_ dS fdd_ dS )ab  
        Create a realm for testing.

        @param accountHolder: (optional) An object whose C{theAccount}
            attribute will be returned instead of
            L{TestRealm.theAccount}.  Attribute access occurs on every
            avatar request, so any modifications to
            C{accountHolder.theAccount} will be reflected here.
        c                      r  r-   r|  r.   rl  r.   r1   r2   {  r3   z$TestRealm.__init__.<locals>.<lambda>c                      r  r-   rd  r.   rL   r.   r1   r2   }  r3   N)_getAccount)rB   rm  r.   )rm  rB   r1   rp   p  s   
zTestRealm.__init__c                 G   s   t j|  dd fS )Nc                   S   r2  r-   r.   r.   r.   r.   r1   r2     r  z)TestRealm.requestAvatar.<locals>.<lambda>)r   IAccountre  )rB   avatarIdmindr   r.   r.   r1   r       zTestRealm.requestAvatarr-   )ri   rj   rk   r  r|  rp   r  r.   r.   r.   r1   rp  e  s
    
rp  c                   @   s,   e Zd ZeefZddiZdd Zdd ZdS )TestCheckerrk     secretc                 C   s2   |j | jv rt|j| j|j  | j|j S d S r-   )usernamer  r   maybeDeferredcheckPasswordr   _cbCheckrB   credentialsr.   r.   r1   requestAvatarId  s   zTestChecker.requestAvatarIdc                 C   s   |r|S t  r-   r   )rB   r/   rl  r.   r.   r1   ro    s   zTestChecker._cbCheckN)	ri   rj   rk   r   r   credentialInterfacesr  rr  ro  r.   r.   r.   r1   rj    s
    rj  c                   @   s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)S )*AuthenticatorTestsc                 C   sN   t |  t }td|_t|| _| jt  | j| j	_d| _
|j| _d S )Nrk  r   )r  r  rp  rg  r|  r   rs  rt  rj  r  authenticatedr  )rB   rx  r.   r.   r1   r    s   



zAuthenticatorTests.setUpc                 C   s   t ttG dd d}| }tt| td|i}| j|_t }|| | 	|j
td | d|  |  |d | t| |  |  |tdd  | | d	 d
S )z
        L{imap4.IMAP4Server} accepts a L{dict} mapping challenge type
        names to L{twisted.mail.interfaces.IChallengeResponse}
        providers.
        c                   @   rl   )
z>AuthenticatorTests.test_customChallengers.<locals>.SPECIALAuthc                 S   r(  )N   SPECIALr.   rL   r.   r.   r1   getChallenge  r*  zKAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.getChallengec                 S   s   | d d\| _| _d S r,  )splitrl  passwordrB   responser.   r.   r1   setResponse     zJAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.setResponsec                 S   r(  NFr.   rL   r.   r.   r1   moreChallenges  r*  zMAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.moreChallengesc                 S   s   | j | _ d S r-   )ry  )rB   ry  r.   r.   r1   rn    r5   zLAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.checkPasswordN)ri   rj   rk   rw  r|  r  rn  r.   r.   r.   r1   SPECIALAuth  s
    r  rv  Connection done.s   AUTH=SPECIALs   001 AUTHENTICATE SPECIAL
s   username passwordr_  s"   001 OK Authentication successful
N)r   r   r   r   r   ro  rs  r'   r  
addCleanupr  r   r  r   r  r  dataReceivedbase64	b64encoderw  r?   )rB   r  specialr  r  r.   r.   r1   test_customChallengers  s    


z)AuthenticatorTests.test_customChallengersc                 C   sZ   t  }| j|_t }|| | |jtd |	  |
d | | d dS )z_
        An unsupported C{AUTHENTICATE} method results in a negative
        response.
        r  s   001 AUTHENTICATE UNKNOWN
s(   001 NO AUTHENTICATE method unsupported
N)r   ro  rs  r'   r  r  r  r   r  r  r  r?   r  )rB   r  r  r.   r.   r1   test_unsupportedMethod  s   

z)AuthenticatorTests.test_unsupportedMethodc                    sx   t j jjd< t d} j| d j_ fdd} j	t
|}| jd | j j t|  gS )zv
        An L{imap4.IMAP4Server} that is missing a L{Portal} responds
        negatively to an authentication
        r  rk  Nc                      r"  Nrk  r  authenticater.   rL   r.   r1   r    r5   z3AuthenticatorTests.test_missingPortal.<locals>.auths    Temporary authentication failure)r   LOGINCredentialsr  r  LOGINAuthenticatorr  registerAuthenticatorrs  r  r   r4   r  r  rB  r  r  r   r  r    )rB   cAuthr  r   r.   rL   r1   test_missingPortal  s   
z%AuthenticatorTests.test_missingPortalc                    s   t tG dd d}t tG dd d}| }tt| | jjd<  j|   fdd} j	t
|}| jdt|j d	 | j j t|  gS )
z
        When a challenger's
        L{getChallenge<IChallengeResponse.getChallenge>} method raises
        any exception, a C{NO} response is sent.
        c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	zRAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenges   A challenge failurec                 S   s
   t | jr-   )r   r?  rL   r.   r.   r1   rw    rq   z_AuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.getChallengec                 S   r(  zw
                Never called.

                @param response: See L{IChallengeResponse.setResponse}
                Nr.   rz  r.   r.   r1   r|    r  z^AuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.setResponsec                 S   r(  z/
                Never called.
                Nr.   rL   r.   r.   r1   r    r  zaAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.moreChallengesNri   rj   rk   r?  rw  r|  r  r.   r.   r.   r1   ValueErrorAuthChallenge  
    r  c                   @      e Zd Zdd Zdd ZdS )zRAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticatorc                 S   r(  )N   ERRORr.   rL   r.   r.   r1   getName  r*  zZAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticator.getNamec                 S   r(  )Ns   IGNOREDr.   )rB   secretchalr.   r.   r1   challengeResponse  r*  zdAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticator.challengeResponseN)ri   rj   rk   r  r  r.   r.   r.   r1   ValueErrorAuthenticator      r  r  c                      r"  r  r  r.   rL   r.   r1   r    r5   z?AuthenticatorTests.test_challengerRaisesException.<locals>.authzServer error: r  )r   r   r   r   r  r  r  r  r  r   r4   r  r  r   r?  r@   rB  r  r  r   r  r    )rB   r  r  badr  r   r.   rL   r1   test_challengerRaisesException  s    
z1AuthenticatorTests.test_challengerRaisesExceptionc                 C   s   t tG dd d}| }tt| t }| j|_||jd< t }|| | 	|j
td | d|  |  |d | t| |  |  |d | | dd	|jd
g dS )z
        A client that responds with a challenge that cannot be decoded
        as Base 64 receives an L{IllegalClientResponse}.
        c                   @   r  )	zEAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenges   Malformed Response - not base64c                 S   r(  )Ns   SomeChallenger.   rL   r.   r.   r1   rw  4  r*  zRAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.getChallengec                 S   r(  r  r.   rz  r.   r.   r1   r|  7  r  zQAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.setResponsec                 S   r(  r  r.   rL   r.   r.   r1   r  >  r  zTAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.moreChallengesNr  r.   r.   r.   r1   NotBase64AuthChallenge0  r  r  s	   NOTBASE64r  s   AUTH=NOTBASE64s   001 AUTHENTICATE NOTBASE64
s     Not base64
r   s   001 NO Authentication failed: r_  N)r   r   r   r   ro  rs  r  r'   r  r  r  r   r  r   r  r  r  r  r  rw  r?   r   r?  )rB   r  	notBase64r  r  r.   r.   r1   test_authNotBase64*  s(   




z%AuthenticatorTests.test_authNotBase64c                    s   t  }t|}| j_tj  jjd< }tt| t	d} j
|  fdd} jt|}| jd | j j t  |g}|S )z
        A challenger that causes the login to fail
        L{UnhandledCredentials} results in an C{NO} response.

        @return: A L{Deferred} that fires when the authorization has
            failed.
        r  rk  c                      r"  r  r  r.   rL   r.   r1   r  r  r5   z:AuthenticatorTests.test_unhandledCredentials.<locals>.auths+   Authentication failed: server misconfigured)rp  r   r  rs  r   r  r  r   r   r  r  r  r  r   r4   r  r  rB  r  r  r   r  r    )rB   rx  rs  	loginCredr  r  r  r   r.   rL   r1   test_unhandledCredentials]  s    

z,AuthenticatorTests.test_unhandledCredentialsc           
         s   G dd dt  G  fddd}t }t|}||  |j_tj jjd< }t	t
| td}j| fdd} fd	d
}jt|}|jd |t| |jj t |g}	|	S )z
        If the portal raises an exception other than
        L{UnauthorizedLogin} or L{UnhandledCredentials}, the server
        responds with a C{BAD} response and the exception is logged.
        c                   @   rf  )zKAuthenticatorTests.test_unexpectedLoginFailure.<locals>.UnexpectedExceptionr  Nrh  r.   r.   r.   r1   r    ri  r  c                       s$   e Zd ZdZeefZ fddZdS )zFAuthenticatorTests.test_unexpectedLoginFailure.<locals>.FailingCheckerzz
            A credentials checker whose L{requestAvatarId} method
            raises L{UnexpectedException}.
            c                    r  )NzUnexpected error.r.   rp  r  r.   r1   rr    rb  zVAuthenticatorTests.test_unexpectedLoginFailure.<locals>.FailingChecker.requestAvatarIdN)ri   rj   rk   r  r   r   rs  rr  r.   r  r.   r1   FailingChecker  s    r  r  rk  c                      r"  r  r  r.   rL   r.   r1   r    r5   z<AuthenticatorTests.test_unexpectedLoginFailure.<locals>.authc                      r  r-   r  r.   r  r.   r1   assertUnexpectedExceptionLogged  ri  zWAuthenticatorTests.test_unexpectedLoginFailure.<locals>.assertUnexpectedExceptionLoggeds'   Server error: login failed unexpectedly)r  rp  r   rt  r  rs  r   r  r  r   r   r  r  r  r  r   r4   r  r  rB  r  r  r   r  r    )
rB   r  rx  rs  r  r  r  r  r  r   r.   r  r1   test_unexpectedLoginFailure~  s(   

z.AuthenticatorTests.test_unexpectedLoginFailurec                    s   t  jjd< td} j|  fdd} fdd} jt	|}|
t	| j |
 j j   }t||g}| jS )Nr  rk  c                      r"  r  r  r.   rL   r.   r1   r    r5   z,AuthenticatorTests.testCramMD5.<locals>.authc                      r  r,  ru  r.   rL   r.   r1   authed  rq   z.AuthenticatorTests.testCramMD5.<locals>.authed)r   r  r  r   CramMD5ClientAuthenticatorr  r  r  r   r4   rB  r  r  r    r   r  _cbTestCramMD5)rB   r  r  r  r  r  r   r.   rL   r1   testCramMD5  s   
zAuthenticatorTests.testCramMD5c                 C   $   |  | jd |  | jj| j d S r,  r?   ru  r  r  r  r.   r.   r1   r    r  z!AuthenticatorTests._cbTestCramMD5c                    s   t  jjd< td} j|  fdd} fdd} fdd} jt	|}|
t	|t	| |
 j j t  |g}| jS )	Nr  rk  c                      r"  Ns   not the secretr  r.   rL   r.   r1   misauth  r5   z5AuthenticatorTests.testFailedCramMD5.<locals>.misauthc                      r  r,  r  r.   rL   r.   r1   r    rq   z4AuthenticatorTests.testFailedCramMD5.<locals>.authedc                      r  Nr  r.   rL   r.   r1   	misauthed  rq   z7AuthenticatorTests.testFailedCramMD5.<locals>.misauthed)r   r  r  r   r  r  r  r  r   r4   rB  r  r  r   r  r    _cbTestFailedCramMD5rB   r  r  r  r  r  r   r.   rL   r1   testFailedCramMD5  s   
z$AuthenticatorTests.testFailedCramMD5c                 C   "   |  | jd |  | jjd  d S r  r  r  r.   r.   r1   r       z'AuthenticatorTests._cbTestFailedCramMD5c                       t j  jjd< }tt| t d} j|  fdd} fdd} j	
t|}|t| j | j j t  |g}|
 jS )Nr  rk  c                      r"  r  r  r.   rL   r.   r1   r    r5   z*AuthenticatorTests.testLOGIN.<locals>.authc                      r  r,  r  r.   rL   r.   r1   r    rq   z,AuthenticatorTests.testLOGIN.<locals>.authed)r   r  r  r  r   r   r  r  r  r  r   r4   rB  r  r  r   r  r    _cbTestLOGIN)rB   r  r  r  r  r  r   r.   rL   r1   	testLOGIN     

zAuthenticatorTests.testLOGINc                 C   r  r,  r  r  r.   r.   r1   r    r  zAuthenticatorTests._cbTestLOGINc                       t j jjd< t d} j|  fdd} fdd} fdd} jt	|}|
t	|t	| |
 j j t  |g}| jS )	Nr  rk  c                      r"  r  r  r.   rL   r.   r1   r    r5   z3AuthenticatorTests.testFailedLOGIN.<locals>.misauthc                      r  r,  r  r.   rL   r.   r1   r    rq   z2AuthenticatorTests.testFailedLOGIN.<locals>.authedc                      r  r  r  r.   rL   r.   r1   r    rq   z5AuthenticatorTests.testFailedLOGIN.<locals>.misauthed)r   r  r  r  r  r  r  r  r   r4   rB  r  r  r   r  r    _cbTestFailedLOGINr  r.   rL   r1   testFailedLOGIN     
z"AuthenticatorTests.testFailedLOGINc                 C   r  r  r  r  r.   r.   r1   r  
  r  z%AuthenticatorTests._cbTestFailedLOGINc                    r  )Nrg  rk  c                      r"  r  r  r.   rL   r.   r1   r    r5   z*AuthenticatorTests.testPLAIN.<locals>.authc                      r  r,  r  r.   rL   r.   r1   r    rq   z,AuthenticatorTests.testPLAIN.<locals>.authed)r   PLAINCredentialsr  r  r   r   PLAINAuthenticatorr  r  r  r   r4   rB  r  r  r   r  r    _cbTestPLAIN)rB   	plainCredr  r  r  r  r   r.   rL   r1   	testPLAIN  r  zAuthenticatorTests.testPLAINc                 C   r  r,  r  r  r.   r.   r1   r  "  r  zAuthenticatorTests._cbTestPLAINc                    r  )	Nrg  rk  c                      r"  r  r  r.   rL   r.   r1   r  +  r5   z3AuthenticatorTests.testFailedPLAIN.<locals>.misauthc                      r  r,  r  r.   rL   r.   r1   r  .  rq   z2AuthenticatorTests.testFailedPLAIN.<locals>.authedc                      r  r  r  r.   rL   r.   r1   r  1  rq   z5AuthenticatorTests.testFailedPLAIN.<locals>.misauthed)r   r  r  r  r  r  r  r  r   r4   rB  r  r  r   r  r    _cbTestFailedPLAINr  r.   rL   r1   testFailedPLAIN&  r  z"AuthenticatorTests.testFailedPLAINc                 C   r  r  r  r  r.   r.   r1   r  :  r  z%AuthenticatorTests._cbTestFailedPLAINN)ri   rj   rk   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   rt    s*    +43!2rt  c                   @   r  )	SASLPLAINTestsz
    Tests for I{SASL PLAIN} authentication, as implemented by
    L{imap4.PLAINAuthenticator} and L{imap4.PLAINCredentials}.

    @see: U{http://www.faqs.org/rfcs/rfc2595.html}
    @see: U{http://www.faqs.org/rfcs/rfc4616.html}
    c                 C   s>   d}d}d}t |}|||}| |d| d |  dS )z
        L{PLAINAuthenticator.challengeResponse} returns challenge strings of
        the form::

            NUL<authn-id>NUL<secret>
        rk  rk  s	   challenge    N)r   r  r  r?   )rB   rl  r  r  r  r{  r.   r.   r1   #test_authenticatorChallengeResponseH  s   
z2SASLPLAINTests.test_authenticatorChallengeResponsec                 C   s2   t  }|d | |jd | |jd dS )z
        L{PLAINCredentials.setResponse} parses challenge strings of the
        form::

            NUL<authn-id>NUL<secret>
        s    testuser secretrk  rk  N)r   r  r|  r?   rl  ry  rB   credr.   r.   r1   test_credentialsSetResponseV  s   
z*SASLPLAINTests.test_credentialsSetResponsec                 C   sB   t  }| t j|jd | t j|jd | t j|jd dS )z
        L{PLAINCredentials.setResponse} raises L{imap4.IllegalClientResponse}
        when passed a string not of the expected form.
        s   hellos   hello worlds   hello world Zoom! N)r   r  r   r  r|  r  r.   r.   r1   test_credentialsInvalidResponseb  s   

z.SASLPLAINTests.test_credentialsInvalidResponseN)ri   rj   rk   r  r  r  r  r.   r.   r.   r1   r  ?  s
    r  c                   @   sl   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )UnsolicitedResponseTestsc                    \    fdd} fdd} j t|}|t| j t  |g}| jS )Nc                      r  r  r  r.   rL   r.   r1   r  s  r.  z5UnsolicitedResponseTests.testReadWrite.<locals>.loginc                      r;  r,  r  r  r.   rL   r.   r1   rT  v  r  z8UnsolicitedResponseTests.testReadWrite.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestReadWriterB   r  rT  r  r   r.   rL   r1   testReadWriter     z&UnsolicitedResponseTests.testReadWritec                 C      | j j}| |ddgg d S )Nr  r   r  r  r?   rB   r  Er.   r.   r1   r  ~     z)UnsolicitedResponseTests._cbTestReadWritec                    r  )Nc                      r  r  r  r.   rL   r.   r1   r    r.  z4UnsolicitedResponseTests.testReadOnly.<locals>.loginc                      r;  r>  r  r.   rL   r.   r1   rT    r  z7UnsolicitedResponseTests.testReadOnly.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestReadOnlyr  r.   rL   r1   testReadOnly  r  z%UnsolicitedResponseTests.testReadOnlyc                 C   r  )Nr  r   r  r  r.   r.   r1   r    r  z(UnsolicitedResponseTests._cbTestReadOnlyc                    sr   ddgg dgd fdd} fdd}j t|}|t|j t |g}|j S )	N	\AnsweredrC  \Recent)r   r   r   c                      r  r  r  r.   rL   r.   r1   r    r.  z6UnsolicitedResponseTests.testFlagChange.<locals>.loginc                      s   j   d S r-   )r  r  r.   ro  rB   r.   r1   rT    r  z9UnsolicitedResponseTests.testFlagChange.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestFlagChanger  r.   r  r1   testFlagChange  s   z'UnsolicitedResponseTests.testFlagChangec                 C   sJ   | j j}dd | D }|jdd d |jdd d | || d S )Nc                 S   s    g | ]}d |d |d igqS )r  r   r   r.   )r
  r5  r.   r.   r1   r    s     z>UnsolicitedResponseTests._cbTestFlagChange.<locals>.<listcomp>c                 S      | d S r>  r.   rf   r.   r.   r1   r2         z<UnsolicitedResponseTests._cbTestFlagChange.<locals>.<lambda>)keyc                 S   r  r>  r.   r  r.   r.   r1   r2     r  )r  r  itemsr  r?   )rB   r  ro  r  expectr.   r.   r1   r    s
   z*UnsolicitedResponseTests._cbTestFlagChangec                    r  )Nc                      r  r  r  r.   rL   r.   r1   r    r.  z7UnsolicitedResponseTests.testNewMessages.<locals>.loginc                      s    j dd  d S Nr   r  r  r.   rL   r.   r1   rT    r  z:UnsolicitedResponseTests.testNewMessages.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestNewMessagesr  r.   rL   r1   testNewMessages  r  z(UnsolicitedResponseTests.testNewMessagesc                 C      | j j}| |g dg d S )N)r  r   Nr  r  r.   r.   r1   r    r  z+UnsolicitedResponseTests._cbTestNewMessagesc                    r  )Nc                      r  r  r  r.   rL   r.   r1   r    r.  z=UnsolicitedResponseTests.testNewRecentMessages.<locals>.loginc                      s    j d d d S r  r  r.   rL   r.   r1   rT    r  z@UnsolicitedResponseTests.testNewRecentMessages.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestNewRecentMessagesr  r.   rL   r1   testNewRecentMessages  r  z.UnsolicitedResponseTests.testNewRecentMessagesc                 C   r  )Nr  Nr   r  r  r.   r.   r1   r    r  z1UnsolicitedResponseTests._cbTestNewRecentMessagesc                    r  )Nc                      r  r  r  r.   rL   r.   r1   r    r.  z@UnsolicitedResponseTests.testNewMessagesAndRecent.<locals>.loginc                      s    j dd d S )Nr  r   r  r.   rL   r.   r1   rT    r  zCUnsolicitedResponseTests.testNewMessagesAndRecent.<locals>.loggedIn)	r  r   r4   r  r  r   r  r    _cbTestNewMessagesAndRecentr  r.   rL   r1   testNewMessagesAndRecent  r  z1UnsolicitedResponseTests.testNewMessagesAndRecentc                 C   s$   | j j}| |g dg dg d S )N)r  r  Nr  r  r  r.   r.   r1   r    r  z4UnsolicitedResponseTests._cbTestNewMessagesAndRecentN)ri   rj   rk   r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   r  q  s    r  c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ClientCapabilityTestszT
    Tests for issuance of the CAPABILITY command and handling of its response.
    c                 C   s0   t  | _t | _| j| j | jd dS )zS
        Create an L{imap4.IMAP4Client} connected to a L{StringTransport}.
        s   * OK [IMAP4rev1]
N)r'   r  r   r~  protocolr  r  rL   r.   r.   r1   r    s   
zClientCapabilityTests.setUpc                    @    j jdd} j d  j d  fdd}|| |S )z
        A capability response consisting only of atoms without C{'='} in them
        should result in a dict mapping those atoms to L{None}.
        FuseCaches&   * CAPABILITY IMAP4rev1 LOGINDISABLED
   0001 OK Capability completed.
c                    s     | d d d d S )N)r  s   LOGINDISABLEDr  capabilitiesrL   r.   r1   gotCapabilities     z?ClientCapabilityTests.test_simpleAtoms.<locals>.gotCapabilitiesr  r  r  r   rB   capabilitiesResultr  r.   rL   r1   test_simpleAtoms  s   
z&ClientCapabilityTests.test_simpleAtomsc                    r  )a  
        A capability response consisting of atoms including C{'='} should have
        those atoms split on that byte and have capabilities in the same
        category aggregated into lists in the resulting dictionary.

        (n.b. - I made up the word "category atom"; the protocol has no notion
        of structure here, but rather allows each capability to define the
        semantics of its entry in the capability response in a freeform manner.
        If I had realized this earlier, the API for capabilities would look
        different.  As it is, we can hope that no one defines any crazy
        semantics which are incompatible with this API, or try to figure out a
        better API when someone does. -exarkun)
        Fr  s.   * CAPABILITY IMAP4rev1 AUTH=LOGIN AUTH=PLAIN
r  c                    s     | d ddgd d S )Nr  rg  )r  r  r  r  rL   r.   r1   r    s   zAClientCapabilityTests.test_categoryAtoms.<locals>.gotCapabilitiesr  r  r.   rL   r1   test_categoryAtoms  s   
z(ClientCapabilityTests.test_categoryAtomsc                    r  )z
        A capability response consisting of both simple and category atoms of
        the same type should result in a list containing L{None} as well as the
        values for the category.
        Fr  s0   * CAPABILITY IMAP4rev1 FOO FOO=BAR BAR=FOO BAR
r  c                    s      | d d dgdd gd d S )N   BAR   FOO)r  r  r  r  r  rL   r.   r1   r    s   z>ClientCapabilityTests.test_mixedAtoms.<locals>.gotCapabilitiesr  r  r.   rL   r1   test_mixedAtoms  s   
z%ClientCapabilityTests.test_mixedAtomsN)ri   rj   rk   r  r  r  r  r  r.   r.   r.   r1   r    s    	r  c                   @       e Zd ZdZdd Zdd ZdS )StillSimplerClientzH
    An IMAP4 client which keeps track of unsolicited flag changes.
    c                 C   s   t j|  i | _d S r-   )r   r~  rp   ro  rL   r.   r.   r1   rp   ,     
zStillSimplerClient.__init__c                 C   s   | j | d S r-   )ro  r  r  r.   r.   r1   r  0  r  zStillSimplerClient.flagsChangedN)ri   rj   rk   r  rp   r  r.   r.   r.   r1   r  '  s    r  c                   @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )HandCraftedTestsc                    sp   t  t     d fdd fdd fdd} dd} d	 || |S )
N   * OK [IMAP4rev1]c                    s       d d d S )Nr  s   0003 FETCH 1 (RFC822)r?   r  r>  r  rB   r  r.   r1   cbCheckTransport;  s   z>HandCraftedTests.testTrailingLiteral.<locals>.cbCheckTransportc                    s,     d} d  d | |S )Nr   s6   * 1 FETCH (RFC822 {10}
0123456789
 RFC822.SIZE 10)
s   0003 OK FETCH
)fetchMessager  r   r  r   )r   r  r.   r1   cbSelectA  s   


z6HandCraftedTests.testTrailingLiteral.<locals>.cbSelectc                    s"     d} d | |S NrF     0002 OK SELECT)rd  ry  r   r  )r   r  r.   r1   cbLoginJ  s   


z5HandCraftedTests.testTrailingLiteral.<locals>.cbLogin   blah   0001 OK LOGIN
)r'   r   r~  r  ry  r  r  r   )rB   r  r   r.   )r   r  r  rB   r  r1   testTrailingLiteral5  s   

	

z$HandCraftedTests.testTrailingLiteralc                 C   s   | j jdd t }| j | |  | j d | | d |  | j d | | d |  | j d | 	|  | j d | | d	 | | j j
d
 | j td dS )z]
        String literals whose data is not immediately available are
        parsed.
        rk  rn  s   01 LOGIN {8}
s   + Ready for 8 octets of text
s   testuser {13}
s   + Ready for 13 octets of text
s   passwords   -test
   01 OK LOGIN succeeded
r  r  N)r  rr  rq  r'   r  r  r  r?   r  	assertNotr  r  r   r  r  r.   r.   r1   test_fragmentedStringLiteralsU  s    z.HandCraftedTests.test_fragmentedStringLiteralsc                 C   s   ddi| j j_t }| j | |  | j d | | d |  | j d | | d | | j j	d | j 
td dS )	z3
        Empty string literals are parsed.
        r   s   01 LOGIN {0}
s   + Ready for 0 octets of text
s   {0}
r  r  r  N)r  rr  r  r'   r  r  r  r?   r  r  r  r   r  r  r.   r.   r1   test_emptyStringLiteralo  s   z(HandCraftedTests.test_emptyStringLiteralc                    t   t  t     d  fdd} fdd} fdd} fdd	}| t|t||S )
a^  
        If unsolicited data is received along with solicited data in the
        response to a I{FETCH} command issued by L{IMAP4Client.fetchSpecific},
        the unsolicited data is passed to the appropriate callback and not
        included in the result with which the L{Deferred} returned by
        L{IMAP4Client.fetchSpecific} fires.
        r
  c                          dd}  d | S Nr  r  r  r  r  r  r.   r1   r       
zRHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.loginc                          d}  d | S r  rd  ry  r  r  r.   r1   rd       

zSHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.selectc                     sz    j dddgd}  d  d  d  d  d	  d
  d  d  d  d | S )Nr   HEADER.FIELDSSUBJECT
headerType
headerArgss1   * 1 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {38}
s$   Subject: Suprise for your woman...
r_     )
s   * 1 FETCH (FLAGS (\Seen))
s1   * 2 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {75}
sI   Subject: What you been doing. Order your meds here . ,. handcuff madsen
   0003 OK FETCH completed
fetchSpecificr  r  r  r.   r1   rO    s    








zRHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.fetchc                    s^      d d  | dddggdggdddggdggd   jd	d
gi d S )Nr  ,   0003 FETCH 1:* BODY[HEADER.FIELDS (SUBJECT)]r  r$  r%  z&Subject: Suprise for your woman...

zKSubject: What you been doing. Order your meds here . ,. handcuff madsen

r   r   r   \Seenr?   r  r>  ro  resr   rB   r  r.   r1   rG    s&   	zQHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.testr'   r  r  ry  r   r4   rB   r  rd  rO  rG  r.   r3  r1   2test_unsolicitedResponseMixedWithSolicitedResponse  s   



zCHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponsec                    s   t  t     d  fdd} fdd} fdd}fdd	}| }|t| |t| || |S )
zf
        Literals should be recognized even when they are not preceded by
        whitespace.
        r
  c                     r  r  r  r  r  r.   r1   r    r   zFHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.loginc                     r!  )N   inboxr  r"  r  r7  r.   r1   rd    r#  zGHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.selectc                     s*    j dddgd}  d  d | S )Nr   r$  r%  r&  s8   * 1 FETCH (BODY[HEADER.FIELDS ({7}
SUBJECT)] "Hello")
r*  r+  r  r7  r.   r1   rO    s   
zFHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.fetchc                    s:       d d   | ddddggdggi d S )Nr  r-  r   r  r$  r%  Hellor  r   r  r.   r1   rG    s   zEHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.testr'   r   r~  r  ry  r   r4   )rB   r  rd  rO  rG  r   r.   r  rB   r  r1   &test_literalWithoutPrecedingWhitespace  s   


	
z7HandCraftedTests.test_literalWithoutPrecedingWhitespacec                    sp   t  t     d  fdd} fdd} fdd}| }|t| |t| |S )z
        If the server sends a literal length which cannot be parsed as an
        integer, L{IMAP4Client.lineReceived} should cause the protocol to be
        disconnected by raising L{imap4.IllegalServerResponse}.
        r
  c                     r  r  r  r  r7  r.   r1   r    r   z<HandCraftedTests.test_nonIntegerLiteralLength.<locals>.loginc                     r!  r  r"  r  r7  r.   r1   rd    r#  z=HandCraftedTests.test_nonIntegerLiteralLength.<locals>.selectc                      s@    j dddgd   d d tj jd d S )Nr   r$  r%  r&  r  r-  s   * 1 FETCH {xyz}
...)r,  r?   r  r>  r   r   IllegalServerResponser  r.   r;  r.   r1   rO    s   z<HandCraftedTests.test_nonIntegerLiteralLength.<locals>.fetchr:  )rB   r  rd  rO  r   r.   r;  r1   test_nonIntegerLiteralLength  s   

z-HandCraftedTests.test_nonIntegerLiteralLengthc                    sr   t  }t   |  d  fdd} fdd} fdd} fdd	}| t|t||S )
a  
        Any unrequested flag information received along with other requested
        information in an untagged I{FETCH} received in response to a request
        issued with L{IMAP4Client.fetchSpecific} is passed to the
        C{flagsChanged} callback.
        r
  c                     r  r  r  r  r  r.   r1   r  3  r   zLHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.loginc                     r!  r  r"  r  r  r.   r1   rd  8  r#  zMHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.selectc                     s\    j dddgd}  d  d  d  d  d	  d
  d | S )Nr   r$  r%  r&  s1   * 1 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {22}
s   Subject: subject one
s    FLAGS (\Recent))
s?   * 2 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS ("SUBJECT")] {22}
s   Subject: subject two
r)  r*  r+  r  r  r.   r1   rO  =  s   





zLHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.fetchc                    sJ    | dddggdggdddggdggd   jdgdgd d S )	Nr  r$  r%  zSubject: subject one
zSubject: subject two
r.  r  r/  )r?   ro  r1  r   rB   r.   r1   rG  N  s   	zKHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.testr4  )rB   r  r  rd  rO  rG  r.   r?  r1   ,test_flagsChangedInsideFetchSpecificResponse'  s   



z=HandCraftedTests.test_flagsChangedInsideFetchSpecificResponsec                    r  )
a  
        Any unrequested flag information received along with other requested
        information in an untagged I{FETCH} received in response to a request
        issued with L{IMAP4Client.fetchMessage} is passed to the
        C{flagsChanged} callback.
        r
  c                     r  r  r  r  r  r.   r1   r  x  r   zKHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.loginc                     r!  r  r"  r  r  r.   r1   rd  }  r#  zLHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.selectc                     sT     d}  d  d  d  d  d  d  d | S )	Nr   s   * 1 FETCH (RFC822 {24}
s   Subject: first subject
s    FLAGS (\Seen))
s.   * 2 FETCH (FLAGS (\Recent \Seen) RFC822 {25}
s   Subject: second subject
r)  r*  )r  r  r  r  r.   r1   rO    s   







zKHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.fetchc                    sP      d d  | ddiddid   jdgddgd d S )	Nr  s   0003 FETCH 1:* (RFC822)ry  zSubject: first subject
zSubject: second subject
r.  r/  r  r0  r1  r3  r.   r1   rG    s   zJHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.testr4  r5  r.   r3  r1   +test_flagsChangedInsideFetchMessageResponsel  s   



z<HandCraftedTests.test_flagsChangedInsideFetchMessageResponsec                 C   s   t  }t }||_|| |d td}|| |d}| 	|t
j |d | tj}| t|d | |d jjd d |S )z
        When decoding a base64 encoded authentication message from the server,
        decoding errors are logged and then the client closes the connection.
        sP   * OK [CAPABILITY IMAP4rev1 IDLE NAMESPACE AUTH=CRAM-MD5] Twisted IMAP4rev1 Readyrk  r  s   + Something bad! and bad
r   r   s   Something bad! and bad)r(   r   r~  r  r  ry  r  r  r  assertFailurer   r  r  r   r=  r?   r   r  rv  )rB   r  r  r  r   loggedr.   r.   r1   -test_authenticationChallengeDecodingException  s    




z>HandCraftedTests.test_authenticationChallengeDecodingExceptionN)ri   rj   rk   r  r  r  r6  r<  r>  r@  rA  rD  r.   r.   r.   r1   r	  4  s     L.+E8r	  c                   @   s.   e Zd ZU dZejZeej ed< dd Z	dS )PreauthIMAP4ClientMixinav  
    Mixin for L{SynchronousTestCase} subclasses which
    provides a C{setUp} method which creates an L{IMAP4Client}
    connected to a L{StringTransport} and puts it into the
    I{authenticated} state.

    @ivar transport: A L{StringTransport} to which C{client} is
        connected.

    @ivar client: An L{IMAP4Client} which is connected to
        C{transport}.
    clientProtocolc                 C   s0   t  | _|  | _| j| j | jd dS )zm
        Create an IMAP4Client connected to a fake transport and in the
        authenticated state.
        s   * PREAUTH Hello unittest
N)r'   r  rF  r  r  r  rL   r.   r.   r1   r    s   
zPreauthIMAP4ClientMixin.setUpN)
ri   rj   rk   r  r   r~  rF  r	   rV  r  r.   r.   r.   r1   rE    s   
 rE  c                   @      e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"S )#SelectionTestsMixinzl
    Mixin for test cases which defines tests which apply to both I{EXAMINE} and
    I{SELECT} support.
    c                 C   s2   t | j| jd}| | j d| j d  |S )z
        Issue either an I{EXAMINE} or I{SELECT} command (depending on
        C{self.method}), assert that the correct bytes are written to the
        transport, and return the L{Deferred} returned by whichever method was
        called.
        fooboxs   0001 s	    foobox
)r  r  methodr?   r  r  r  rB   r   r.   r.   r1   _examineOrSelect  s
   z$SelectionTestsMixin._examineOrSelectc                 G   s4   |D ]
}| j |d  q| j d| j d  dS )z
        Deliver the given (unterminated) response lines to C{self.client} and
        then deliver a tagged SELECT or EXAMINE completion line to finish the
        SELECT or EXAMINE response.
        r_  s   0001 OK [READ-ONLY] s    completed
N)r  r  r  )rB   linesr{  r.   r.   r1   	_response  s
   zSelectionTestsMixin._responsec                 C   .   |   }| d | | |ddd dS )a  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{EXISTS} response, the L{Deferred} return by L{IMAP4Client.select} or
        L{IMAP4Client.examine} fires with a C{dict} including the value
        associated with the C{'EXISTS'} key.
        s
   * 3 EXISTSFr   )r.  r-  NrL  rN  r?   successResultOfrK  r.   r.   r1   test_exists     
zSelectionTestsMixin.test_existsc                 C   $   |   }| d | |tj dS )a  
        If the server returns a non-integer EXISTS value in its response to a
        I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
        L{IllegalServerResponse}.
        s   * foo EXISTSNrL  rN  failureResultOfr   r=  rK  r.   r.   r1   test_nonIntegerExists     
z)SelectionTestsMixin.test_nonIntegerExistsc                 C   rO  )a  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{RECENT} response, the L{Deferred} return by L{IMAP4Client.select} or
        L{IMAP4Client.examine} fires with a C{dict} including the value
        associated with the C{'RECENT'} key.
        s
   * 5 RECENTFr   )r.  r  NrP  rK  r.   r.   r1   test_recent  rS  zSelectionTestsMixin.test_recentc                 C   rT  )a  
        If the server returns a non-integer RECENT value in its response to a
        I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
        L{IllegalServerResponse}.
        s   * foo RECENTNrU  rK  r.   r.   r1   test_nonIntegerRecent  rX  z)SelectionTestsMixin.test_nonIntegerRecentc                 C   rO  )a  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{UNSEEN} response, the L{Deferred} returned by L{IMAP4Client.select} or
        L{IMAP4Client.examine} fires with a C{dict} including the value
        associated with the C{'UNSEEN'} key.
        s)   * OK [UNSEEN 8] Message 8 is first unseenFr   )r.  r  NrP  rK  r.   r.   r1   test_unseen)  rS  zSelectionTestsMixin.test_unseenc                 C   rT  )a  
        If the server returns a non-integer UNSEEN value in its response to a
        I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
        L{IllegalServerResponse}.
        s-   * OK [UNSEEN foo] Message foo is first unseenNrU  rK  r.   r.   r1   test_nonIntegerUnseen4  rX  z)SelectionTestsMixin.test_nonIntegerUnseenc                 C   rO  )a)  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{UIDVALIDITY} response, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fires with a C{dict}
        including the value associated with the C{'UIDVALIDITY'} key.
        s#   * OK [UIDVALIDITY 12345] UIDs validFr  )r.  r  NrP  rK  r.   r.   r1   test_uidvalidity?  
   
z$SelectionTestsMixin.test_uidvalidityc                 C   rT  )a  
        If the server returns a non-integer UIDVALIDITY value in its response to
        a I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
        L{IllegalServerResponse}.
        s!   * OK [UIDVALIDITY foo] UIDs validNrU  rK  r.   r.   r1   test_nonIntegerUIDVALIDITYL  rX  z.SelectionTestsMixin.test_nonIntegerUIDVALIDITYc                 C   rO  )a!  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{UIDNEXT} response, the L{Deferred} returned by L{IMAP4Client.select}
        or L{IMAP4Client.examine} fires with a C{dict} including the value
        associated with the C{'UIDNEXT'} key.
        s&   * OK [UIDNEXT 4392] Predicted next UIDFi(  )r.  r  NrP  rK  r.   r.   r1   test_uidnextW  r^  z SelectionTestsMixin.test_uidnextc                 C   rT  )a  
        If the server returns a non-integer UIDNEXT value in its response to a
        I{SELECT} or I{EXAMINE} command, the L{Deferred} returned by
        L{IMAP4Client.select} or L{IMAP4Client.examine} fails with
        L{IllegalServerResponse}.
        s%   * OK [UIDNEXT foo] Predicted next UIDNrU  rK  r.   r.   r1   test_nonIntegerUIDNEXTd  rX  z*SelectionTestsMixin.test_nonIntegerUIDNEXTc                 C   rO  )  
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{FLAGS} response, the L{Deferred} returned by L{IMAP4Client.select} or
        L{IMAP4Client.examine} fires with a C{dict} including the value
        associated with the C{'FLAGS'} key.
        s2   * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)F)r  z\FlaggedrC  r/  z\Draft)r.  rm  NrP  rK  r.   r.   r1   
test_flagso  s   
zSelectionTestsMixin.test_flagsc                 C   rO  )rb  sN   * OK [PERMANENTFLAGS (\Starred)] Just one permanent flag in that list up thereF)z\Starred)r.  PERMANENTFLAGSNrP  rK  r.   r.   r1   test_permanentflags  s   z'SelectionTestsMixin.test_permanentflagsc                 C   ,   |   }| d | | |ddi dS )z
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{OK} with unrecognized response code text, parsing does not fail.
        s3   * OK [X-MADE-UP] I just made this response text up.r.  FNrP  rK  r.   r.   r1   test_unrecognizedOk  s   
z'SelectionTestsMixin.test_unrecognizedOkc                 C   rf  )z
        If the server response to a I{SELECT} or I{EXAMINE} command includes an
        I{OK} with no response code text, parsing does not fail.
        s   * OKr.  FNrP  rK  r.   r.   r1   test_bareOk  s   
zSelectionTestsMixin.test_bareOkN)ri   rj   rk   r  rL  rN  rR  rW  rY  rZ  r[  r\  r]  r_  r`  ra  rc  re  rg  rh  r.   r.   r.   r1   rH    s$    rH  c                   @      e Zd ZdZdZdZdS )IMAP4ClientExamineTestsa  
    Tests for the L{IMAP4Client.examine} method.

    An example of usage of the EXAMINE command from RFC 3501, section 6.3.2::

        S: * 17 EXISTS
        S: * 2 RECENT
        S: * OK [UNSEEN 8] Message 8 is first unseen
        S: * OK [UIDVALIDITY 3857529045] UIDs valid
        S: * OK [UIDNEXT 4392] Predicted next UID
        S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
        S: * OK [PERMANENTFLAGS ()] No permanent flags permitted
        S: A932 OK [READ-ONLY] EXAMINE completed
    r4  s   EXAMINENri   rj   rk   r  rJ  r  r.   r.   r.   r1   rj    s    rj  c                   @   ri  )IMAP4ClientSelectTestsa  
    Tests for the L{IMAP4Client.select} method.

    An example of usage of the SELECT command from RFC 3501, section 6.3.1::

        C: A142 SELECT INBOX
        S: * 172 EXISTS
        S: * 1 RECENT
        S: * OK [UNSEEN 12] Message 12 is first unseen
        S: * OK [UIDVALIDITY 3857529045] UIDs valid
        S: * OK [UIDNEXT 4392] Predicted next UID
        S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
        S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
        S: A142 OK [READ-WRITE] SELECT completed
    rd  s   SELECTNrk  r.   r.   r.   r1   rl    s    rl  c                   @   r  )IMAP4ClientExpungeTestsa  
    Tests for the L{IMAP4Client.expunge} method.

    An example of usage of the EXPUNGE command from RFC 3501, section 6.4.3::

        C: A202 EXPUNGE
        S: * 3 EXPUNGE
        S: * 3 EXPUNGE
        S: * 5 EXPUNGE
        S: * 8 EXPUNGE
        S: A202 OK EXPUNGE completed
    c                 C   s*   | j  }| | j d | j  |S )Ns   0001 EXPUNGE
)r  rJ  r?   r  r  r  rK  r.   r.   r1   _expunge  s   

z IMAP4ClientExpungeTests._expungec                 C   s2   |D ]}| j td| d q| j d d S )Nz* z EXPUNGEs   0001 OK EXPUNGE COMPLETED)r  ry  r&   )rB   sequenceNumbersnumberr.   r.   r1   rN    s   z!IMAP4ClientExpungeTests._responsec                 C   0   |   }| g d | | |g d dS )z
        L{IMAP4Client.expunge} sends the I{EXPUNGE} command and returns a
        L{Deferred} which fires with a C{list} of message sequence numbers
        given by the server's response.
        )r   r   r   r   N)rn  rN  r?   rQ  rK  r.   r.   r1   test_expunge     z$IMAP4ClientExpungeTests.test_expungec                 C   (   |   }| g d | |tj dS )z
        If the server responds with a non-integer where a message sequence
        number is expected, the L{Deferred} returned by L{IMAP4Client.expunge}
        fails with L{IllegalServerResponse}.
        )r   r   r!  r   N)rn  rN  rV  r   r=  rK  r.   r.   r1   test_nonIntegerExpunged     z/IMAP4ClientExpungeTests.test_nonIntegerExpungedN)ri   rj   rk   r  rn  rN  rr  ru  r.   r.   r.   r1   rm    s    
rm  c                   @   r  )IMAP4ClientSearchTestsa  
    Tests for the L{IMAP4Client.search} method.

    An example of usage of the SEARCH command from RFC 3501, section 6.4.4::

        C: A282 SEARCH FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"
        S: * SEARCH 2 84 882
        S: A282 OK SEARCH completed
        C: A283 SEARCH TEXT "string not in mailbox"
        S: * SEARCH
        S: A283 OK SEARCH completed
        C: A284 SEARCH CHARSET UTF-8 TEXT {6}
        C: XXXXXX
        S: * SEARCH 43
        S: A284 OK SEARCH completed
    c                 C   s*   | j tjdd}| | j d |S )NABCDEF)rC   s   0001 SEARCH (TEXT "ABCDEF")
)r  searchr   r  r?   r  r  rK  r.   r.   r1   _search  s   zIMAP4ClientSearchTests._searchc              	   C   s0   | j dtdtt|  | j d d S )Ns	   * SEARCH  s   0001 OK SEARCH completed)r  ry  r&   r   mapr   )rB   messageNumbersr.   r.   r1   rN    s   z IMAP4ClientSearchTests._responsec                 C   rq  )z
        L{IMAP4Client.search} sends the I{SEARCH} command and returns a
        L{Deferred} which fires with a C{list} of message sequence numbers
        given by the server's response.
        )r   r   r   N)rz  rN  r?   rQ  rK  r.   r.   r1   test_search  rs  z"IMAP4ClientSearchTests.test_searchc                 C   rt  )z
        If the server responds with a non-integer where a message sequence
        number is expected, the L{Deferred} returned by L{IMAP4Client.search}
        fails with L{IllegalServerResponse}.
        )r   r!  r   N)rz  rN  rV  r   r=  rK  r.   r.   r1   test_nonIntegerFound$  rv  z+IMAP4ClientSearchTests.test_nonIntegerFoundN)ri   rj   rk   r  rz  rN  r~  r  r.   r.   r.   r1   rw    s    
rw  c                   @   r   )'IMAP4ClientFetchTestszV
    Tests for the L{IMAP4Client.fetch} method.

    See RFC 3501, section 6.4.5.
    c                 C   s   | j d}| | j d | j d | j d | j d | j d | j d | | |dd	idd
iddiddid dS )a  
        L{IMAP4Client.fetchUID} sends the I{FETCH UID} command and returns a
        L{Deferred} which fires with a C{dict} mapping message sequence numbers
        to C{dict}s mapping C{'UID'} to that message's I{UID} in the server's
        response.
        1:7   0001 FETCH 1:7 (UID)
   * 2 FETCH (UID 22)s   * 3 FETCH (UID 23)   * 4 FETCH (UID 24)s   * 5 FETCH (UID 25)   0001 OK FETCH completedr{  22232425r   r   r   r   N)r  fetchUIDr?   r  r  ry  rQ  rK  r.   r.   r1   test_fetchUID6  s   z#IMAP4ClientFetchTests.test_fetchUIDc                 C   sH   | j d}| | j d | j d | j d | |tj dS )z
        If the server responds with a non-integer where a message sequence
        number is expected, the L{Deferred} returned by L{IMAP4Client.fetchUID}
        fails with L{IllegalServerResponse}.
        r   s   0001 FETCH 1 (UID)
s   * foo FETCH (UID 22)r  N	r  r  r?   r  r  ry  rV  r   r=  rK  r.   r.   r1   test_fetchUIDNonIntegerFoundI  s
   z2IMAP4ClientFetchTests.test_fetchUIDNonIntegerFoundc                 C   s`   | j d}| | j d | j d | j d | j d | j d | |tj dS )z
        If the server responds with an incomplete I{FETCH} response line, the
        L{Deferred} returned by L{IMAP4Client.fetchUID} fails with
        L{IllegalServerResponse}.
        r  r  r  s   * 3 FETCH (UID)r  r  Nr  rK  r.   r.   r1   test_incompleteFetchUIDResponseU  s   z5IMAP4ClientFetchTests.test_incompleteFetchUIDResponsec                 C   sT   | j d}| | j d | j d | j d | | |dddii dS )	a  
        L{IMAP4Client.fetchBody} sends the I{FETCH BODY} command and returns a
        L{Deferred} which fires with a C{dict} mapping message sequence numbers
        to C{dict}s mapping C{'RFC822.TEXT'} to that message's body as given in
        the server's response.
        3s   0001 FETCH 3 (RFC822.TEXT)
s&   * 3 FETCH (RFC822.TEXT "Message text")r  r   rw  zMessage textN)r  	fetchBodyr?   r  r  ry  rQ  rK  r.   r.   r1   test_fetchBodyc  s
   z$IMAP4ClientFetchTests.test_fetchBodyc                 C   X   | j d}| | j d | j d | j d | | |ddg dggi dS )	aI  
        L{IMAP4Client.fetchSpecific} sends the I{BODY[]} command if no
        parameters beyond the message set to retrieve are given.  It returns a
        L{Deferred} which fires with a C{dict} mapping message sequence numbers
        to C{list}s of corresponding message data given by the server's
        response.
        7   0001 FETCH 7 BODY[]
s   * 7 FETCH (BODY[] "Some body")r  r   r  	Some bodyNr  r,  r?   r  r  ry  rQ  rK  r.   r.   r1   test_fetchSpecificp  s
   "z(IMAP4ClientFetchTests.test_fetchSpecificc                 C   s\   | j jddd}| | j d | j d | j d | | |ddg d	ggi d
S )z
        L{IMAP4Client.fetchSpecific} issues a I{BODY.PEEK[]} command if passed
        C{True} for the C{peek} parameter.
        6T)r  s   0001 FETCH 6 BODY.PEEK[]
s   * 6 FETCH (BODY[] "Some body")r  r   r  r  Nr  rK  r.   r.   r1   test_fetchSpecificPeek~  s
   "z,IMAP4ClientFetchTests.test_fetchSpecificPeekc                 C   s^   | j jddd}| | j d | j d | j d | | |ddd	gd
ggi dS )a;  
        L{IMAP4Client.fetchSpecific}, when passed a sequence for
        C{headerNumber}, sends the I{BODY[N.M]} command.  It returns a
        L{Deferred} which fires with a C{dict} mapping message sequence numbers
        to C{list}s of corresponding message data given by the server's
        response.
        r  r   headerNumbers   0001 FETCH 7 BODY[1.2.3]
s#   * 7 FETCH (BODY[1.2.3] "Some body")r  r   r  z1.2.3r  Nr  rK  r.   r.   r1   test_fetchSpecificNumbered  s   z0IMAP4ClientFetchTests.test_fetchSpecificNumberedc                 C   ^   | j jddd}| | j d | j d | j d | | |dddgd	ggi d
S )a1  
        L{IMAP4Client.fetchSpecific}, when passed C{'TEXT'} for C{headerType},
        sends the I{BODY[TEXT]} command.  It returns a L{Deferred} which fires
        with a C{dict} mapping message sequence numbers to C{list}s of
        corresponding message data given by the server's response.
        8TEXTr'     0001 FETCH 8 BODY[TEXT]
s"   * 8 FETCH (BODY[TEXT] "Some body")r  r   r  r  Nr  rK  r.   r.   r1   test_fetchSpecificText     z,IMAP4ClientFetchTests.test_fetchSpecificTextc                 C   s`   | j jdddd}| | j d | j d | j d | | |dd	d
gdggi dS )ah  
        If passed a value for the C{headerNumber} parameter and C{'TEXT'} for
        the C{headerType} parameter, L{IMAP4Client.fetchSpecific} sends a
        I{BODY[number.TEXT]} request and returns a L{Deferred} which fires with
        a C{dict} mapping message sequence numbers to C{list}s of message data
        given by the server's response.
        4r  r   )r'  r  s   0001 FETCH 4 BODY[7.TEXT]
s$   * 4 FETCH (BODY[7.TEXT] "Some body")r  r   r  z7.TEXTr  Nr  rK  r.   r.   r1   test_fetchSpecificNumberedText  s   z4IMAP4ClientFetchTests.test_fetchSpecificNumberedTextc                 C   L   | j jddd}| | j d | j d | j d | |tj dS )z
        If the server responds to a I{BODY[TEXT]} request with a I{FETCH} line
        which is truncated after the I{BODY[TEXT]} tokens, the L{Deferred}
        returned by L{IMAP4Client.fetchUID} fails with
        L{IllegalServerResponse}.
        r  r  r  r  s   * 8 FETCH (BODY[TEXT])r  N	r  r,  r?   r  r  ry  rV  r   r=  rK  r.   r.   r1   (test_incompleteFetchSpecificTextResponse  
   z>IMAP4ClientFetchTests.test_incompleteFetchSpecificTextResponsec                 C   r  )a1  
        L{IMAP4Client.fetchSpecific}, when passed C{'MIME'} for C{headerType},
        sends the I{BODY[MIME]} command.  It returns a L{Deferred} which fires
        with a C{dict} mapping message sequence numbers to C{list}s of
        corresponding message data given by the server's response.
        r  r  r  s   0001 FETCH 8 BODY[MIME]
s"   * 8 FETCH (BODY[MIME] "Some body")r  r   r  r  Nr  rK  r.   r.   r1   test_fetchSpecificMIME  r  z,IMAP4ClientFetchTests.test_fetchSpecificMIMEc                 C   sd   | j jddddd}| | j d | j d | j d | | |d	d
dgddggi dS )aX  
        L{IMAP4Client.fetchSpecific}, when passed C{offset} and C{length},
        sends a partial content request (like I{BODY[TEXT]<offset.length>}).
        It returns a L{Deferred} which fires with a C{dict} mapping message
        sequence numbers to C{list}s of corresponding message data given by the
        server's response.
        9r  r  r   )r'  offsetlengths   0001 FETCH 9 BODY[TEXT]<17.3>
s    * 9 FETCH (BODY[TEXT]<17> "foo")r  r   r  z<17>r!  Nr  rK  r.   r.   r1   test_fetchSpecificPartial  s   z/IMAP4ClientFetchTests.test_fetchSpecificPartialc                 C   r  )a  
        If the server responds to a I{BODY[TEXT]} request with a I{FETCH} line
        which is truncated after the I{BODY[TEXT]<offset>} tokens, the
        L{Deferred} returned by L{IMAP4Client.fetchUID} fails with
        L{IllegalServerResponse}.
        r  r  r  r  s   * 8 FETCH (BODY[TEXT]<17>)r  Nr  rK  r.   r.   r1   +test_incompleteFetchSpecificPartialResponse  r  zAIMAP4ClientFetchTests.test_incompleteFetchSpecificPartialResponsec                 C   r  )	aA  
        If the body of a message begins with I{<} and ends with I{>} (as,
        for example, HTML bodies typically will), this is still interpreted
        as the body by L{IMAP4Client.fetchSpecific} (and particularly, not
        as a length indicator for a response to a request for a partial
        body).
        r  r  s&   * 7 FETCH (BODY[] "<html>test</html>")r  r   r  z<html>test</html>Nr  rK  r.   r.   r1   test_fetchSpecificHTML  s   z,IMAP4ClientFetchTests.test_fetchSpecificHTMLc                 C   s|   | j jd|d}| | j d|d d  | j d|d d  | j d | | |d	d
|g gdggi dS )a  
        Assert that the provided C{BODY} section, when invoked with no
        arguments, produces an empty list, and that it returns a
        L{Deferred} which fires with a C{dict} mapping message
        sequence numbers to C{list}s of corresponding message data
        given by the server's response.

        @param section: The C{BODY} section to test: either
            C{'HEADER.FIELDS'} or C{'HEADER.FIELDS.NOT'}
        @type section: L{str}
        10r  s   0001 FETCH 10 BODY[r  s    ()]
s   * 10 FETCH (BODY[s    ()] "")r  r   r  r  N)r  r,  r?   r  r  r@   ry  rQ  )rB   sectionr   r.   r.   r1   &assertFetchSpecificFieldsWithEmptyList  s   &z<IMAP4ClientFetchTests.assertFetchSpecificFieldsWithEmptyListc                 C   r  )az  
        L{IMAP4Client.fetchSpecific}, when passed C{'HEADER.FIELDS'}
        for C{headerType} but no C{headerArgs}, sends the
        I{BODY[HEADER.FIELDS]} command with no arguments.  It returns
        a L{Deferred} which fires with a C{dict} mapping message
        sequence numbers to C{list}s of corresponding message data
        given by the server's response.
        r$  Nr  rL   r.   r.   r1   ,test_fetchSpecificHeaderFieldsWithoutHeaders     	zBIMAP4ClientFetchTests.test_fetchSpecificHeaderFieldsWithoutHeadersc                 C   r  )a  
        L{IMAP4Client.fetchSpecific}, when passed
        C{'HEADER.FIELDS.NOT'} for C{headerType} but no C{headerArgs},
        sends the I{BODY[HEADER.FIELDS.NOT]} command with no
        arguments.  It returns a L{Deferred} which fires with a
        C{dict} mapping message sequence numbers to C{list}s of
        corresponding message data given by the server's response.
        zHEADER.FIELDS.NOTNr  rL   r.   r.   r1   /test_fetchSpecificHeaderFieldsNotWithoutHeaders&  r  zEIMAP4ClientFetchTests.test_fetchSpecificHeaderFieldsNotWithoutHeadersc                 C   r  )a=  
        L{IMAP4Client.fetchSpecific}, when passed C{'HEADER'} for
        C{headerType}, sends the I{BODY[HEADER]} command.  It returns
        a L{Deferred} which fires with a C{dict} mapping message
        sequence numbers to C{list}s of corresponding message data
        given by the server's response.
        11HEADERr  s   0001 FETCH 11 BODY[HEADER]
sJ   * 11 FETCH (BODY[HEADER] "From: someone@localhost
Subject: Some subject")r  r  r  z.From: someone@localhost
Subject: Some subjectNr  rK  r.   r.   r1   test_fetchSpecificHeader1  s    z.IMAP4ClientFetchTests.test_fetchSpecificHeaderN)ri   rj   rk   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   r  /  s(    r  c                   @   st   e Zd ZdZeZdd Zdd Zdd Zdd	 Z	d
d Z
dd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )IMAP4ClientStoreTestsa  
    Tests for the L{IMAP4Client.setFlags}, L{IMAP4Client.addFlags}, and
    L{IMAP4Client.removeFlags} methods.

    An example of usage of the STORE command, in terms of which these three
    methods are implemented, from RFC 3501, section 6.4.6::

        C: A003 STORE 2:4 +FLAGS (\Deleted)
        S: * 2 FETCH (FLAGS (\Deleted \Seen))
        S: * 3 FETCH (FLAGS (\Deleted))
        S: * 4 FETCH (FLAGS (\Deleted \Flagged \Seen))
        S: A003 OK STORE completed
    c                 C   sh   t | j|ddd}| | j d| d  | jd | jd | | |dd	d
dgii dS )am  
        Test a non-silent flag modifying method.  Call the method, assert that
        the correct bytes are sent, deliver a I{FETCH} response, and assert
        that the result of the Deferred returned by the method is correct.

        @param method: The name of the method to test.
        @param item: The data item which is expected to be specified.
        r  \Readr/  F   0001 STORE 3     (\Read \Seen)
s   * 3 FETCH (FLAGS (\Read \Seen))   0001 OK STORE completedr   rm  r  r/  Nr  r  r?   r  r  ry  rQ  rB   rJ  itemr   r.   r.   r1   
_flagsTest_  s   	"z IMAP4ClientStoreTests._flagsTestc                 C   sP   t | j|ddd}| | j d| d  | jd | | |i  dS )ag  
        Test a silent flag modifying method.  Call the method, assert that the
        correct bytes are sent, deliver an I{OK} response, and assert that the
        result of the Deferred returned by the method is correct.

        @param method: The name of the method to test.
        @param item: The data item which is expected to be specified.
        r  r  Tr  r  r  Nr  r  r.   r.   r1   _flagsSilentlyTestp  s   	z(IMAP4ClientStoreTests._flagsSilentlyTestc                 C   st   t | j|ddd}| | j d| d  | jd | jd | | |i  | | jjdd	d
gi dS )a  
        Test unsolicited data received in response to a silent flag modifying
        method.  Call the method, assert that the correct bytes are sent,
        deliver the unsolicited I{FETCH} response, and assert that the result
        of the Deferred returned by the method is correct.

        @param method: The name of the method to test.
        @param item: The data item which is expected to be specified.
        r  r  Tr  r  s   * 2 FETCH (FLAGS (\Read \Seen))r  r   r  r/  N)r  r  r?   r  r  ry  rQ  ro  r  r.   r.   r1   %_flagsSilentlyWithUnsolicitedDataTest  s   
z;IMAP4ClientStoreTests._flagsSilentlyWithUnsolicitedDataTestc                 C      |  dd dS )aQ  
        When passed a C{False} value for the C{silent} parameter,
        L{IMAP4Client.setFlags} sends the I{STORE} command with a I{FLAGS} data
        item and returns a L{Deferred} which fires with a C{dict} mapping
        message sequence numbers to C{dict}s mapping C{'FLAGS'} to the new
        flags of those messages.
        setFlagsrd  Nr  rL   r.   r.   r1   test_setFlags  s   z#IMAP4ClientStoreTests.test_setFlagsc                 C   r  )z
        When passed a C{True} value for the C{silent} parameter,
        L{IMAP4Client.setFlags} sends the I{STORE} command with a
        I{FLAGS.SILENT} data item and returns a L{Deferred} which fires with an
        empty dictionary.
        r     FLAGS.SILENTNr  rL   r.   r.   r1   test_setFlagsSilently     z+IMAP4ClientStoreTests.test_setFlagsSilentlyc                 C   r  )z
        If unsolicited flag data is received in response to a I{STORE}
        I{FLAGS.SILENT} request, that data is passed to the C{flagsChanged}
        callback.
        r  r  Nr  rL   r.   r.   r1   (test_setFlagsSilentlyWithUnsolicitedData     z>IMAP4ClientStoreTests.test_setFlagsSilentlyWithUnsolicitedDatac                 C   r  )z{
        L{IMAP4Client.addFlags} is like L{IMAP4Client.setFlags}, but sends
        I{+FLAGS} instead of I{FLAGS}.
        addFlagss   +FLAGSNr  rL   r.   r.   r1   test_addFlags     z#IMAP4ClientStoreTests.test_addFlagsc                 C   r  )z
        L{IMAP4Client.addFlags} with a C{True} value for C{silent} behaves like
        L{IMAP4Client.setFlags} with a C{True} value for C{silent}, but it
        sends I{+FLAGS.SILENT} instead of I{FLAGS.SILENT}.
        r     +FLAGS.SILENTNr  rL   r.   r.   r1   test_addFlagsSilently  r  z+IMAP4ClientStoreTests.test_addFlagsSilentlyc                 C   r  )z
        L{IMAP4Client.addFlags} behaves like L{IMAP4Client.setFlags} when used
        in silent mode and unsolicited data is received.
        r  r  Nr  rL   r.   r.   r1   (test_addFlagsSilentlyWithUnsolicitedData  r  z>IMAP4ClientStoreTests.test_addFlagsSilentlyWithUnsolicitedDatac                 C   r  )z~
        L{IMAP4Client.removeFlags} is like L{IMAP4Client.setFlags}, but sends
        I{-FLAGS} instead of I{FLAGS}.
        removeFlagss   -FLAGSNr  rL   r.   r.   r1   test_removeFlags  r  z&IMAP4ClientStoreTests.test_removeFlagsc                 C   r  )z
        L{IMAP4Client.removeFlags} with a C{True} value for C{silent} behaves
        like L{IMAP4Client.setFlags} with a C{True} value for C{silent}, but it
        sends I{-FLAGS.SILENT} instead of I{FLAGS.SILENT}.
        r     -FLAGS.SILENTNr  rL   r.   r.   r1   test_removeFlagsSilently  r  z.IMAP4ClientStoreTests.test_removeFlagsSilentlyc                 C   r  )z
        L{IMAP4Client.removeFlags} behaves like L{IMAP4Client.setFlags} when
        used in silent mode and unsolicited data is received.
        r  r  Nr  rL   r.   r.   r1   +test_removeFlagsSilentlyWithUnsolicitedData  r  zAIMAP4ClientStoreTests.test_removeFlagsSilentlyWithUnsolicitedDataN)ri   rj   rk   r  r  rF  r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   r  N  s    
	r  c                   @   r  )IMAP4ClientStatusTestsa_  
    Tests for the L{IMAP4Client.status} method.

    An example of usage of the STATUS command from RFC 3501, section
    5.1.2::

        C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
        S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
        S: A042 OK STATUS completed

    @see: U{https://tools.ietf.org/html/rfc3501#section-5.1.2}
    c                 C   s2   |  t| jjdd}| t|dtdh  dS )z
        Only allow sending the C{STATUS} names defined in RFC 3501.

        @see: U{https://tools.ietf.org/html/rfc3501#section-5.1.2}
        r  zIMPOSSIBLE?!zUnknown names: N)r   r   r  r  r?   r   r   )rB   excr.   r.   r1   testUnknownName  s   z&IMAP4ClientStatusTests.testUnknownNamec                 C   sJ   | j dd}| | j d | j d | j d | |tj dS )z
        C{STATUS} names that cannot be decoded as ASCII cause the
        status Deferred to fail with L{IllegalServerResponse}
        blurdybloopr  s$   0001 STATUS blurdybloop (MESSAGES)
s?   * STATUS blurdybloop (MESSAGES 1 ASCIINAME "OK" NOTASCII "NO")s   0001 OK STATUS completedN)	r  r  r?   r  r  ry  rV  r   r=  rK  r.   r.   r1   testUndecodableName  s   z*IMAP4ClientStatusTests.testUndecodableNameN)ri   rj   rk   r  r  r  r.   r.   r.   r1   r    s    r  c                   @   s4   e Zd ZdZeZdd Zdd Zdd Zdd	 Z	d
S )IMAP4ClientCopyTestsz
    Tests for the L{IMAP4Client.copy} method.

    An example of the C{COPY} command, which this method implements,
    from RFC 3501, section 6.4.7::

        C: A003 COPY 2:4 MEETING
        S: A003 OK COPY completed
    c                 C   J   | j jdddd}| | j d | j d | | |g df dS )	z
        L{IMAP4Client.copy} copies the messages identified by their
        sequence numbers to the mailbox, returning a L{Deferred} that
        succeeds with a true value.
        r   MEETINGFr     0001 COPY 2:3 MEETING
   0001 OK COPY completed   OK COPY completedNr  copyr?   r  r  ry  rQ  rK  r.   r.   r1   test_copySequenceNumbers     z-IMAP4ClientCopyTests.test_copySequenceNumbersc                 C   J   | j jdddd}| | j d | j d | | |jtj	 dS )z
        L{IMAP4Client.copy} returns a L{Deferred} that fails with an
        L{IMAP4Exception} when the messages specified by the given
        sequence numbers could not be copied to the mailbox.
        r   r  Fr  r     0001 BAD COPY failedN
r  r  r?   r  r  ry  r  rV  r   r  rK  r.   r.   r1   test_copySequenceNumbersFails'  r  z2IMAP4ClientCopyTests.test_copySequenceNumbersFailsc                 C   r  )	z
        L{IMAP4Client.copy} copies the messages identified by their
        UIDs to the mailbox, returning a L{Deferred} that succeeds
        with a true value.
        r   r  Tr     0001 UID COPY 2:3 MEETING
r  r  Nr  rK  r.   r.   r1   test_copyUIDs7  r  z"IMAP4ClientCopyTests.test_copyUIDsc                 C   r  )z
        L{IMAP4Client.copy} returns a L{Deferred} that fails with an
        L{IMAP4Exception} when the messages specified by the given
        UIDs could not be copied to the mailbox.
        r   r  Tr  r  r  Nr  rK  r.   r.   r1   test_copyUIDsFailsG  r  z'IMAP4ClientCopyTests.test_copyUIDsFailsN)
ri   rj   rk   r  r  rF  r  r  r  r  r.   r.   r.   r1   r  
  s    
r  c                   @   s   e Zd ZdZdZdd ZdS )FakeyServerrd  Nc                 C   r2  r-   r.   rL   r.   r.   r1   sendServerGreeting\  r*  zFakeyServer.sendServerGreeting)ri   rj   rk   r  timeoutr  r.   r.   r.   r1   r  X  s    r  c                   @   X   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )r   )r   ro  r@  _bodyr|  c                 C   s2   || _ || _|| _t|| _|| _|| _|| _d S r-   )r   ro  r  r   sizer@  r|  subpart)rB   r   ro  r@  r   r|  r  r.   r.   r1   rp   d  s   

zFakeyMessage.__init__c                 G      ||f| _ | jS r-   )got_headersr   )rB   r  r9  r.   r.   r1   
getHeadersm     
zFakeyMessage.getHeadersc                 C   r$  r-   r%  rL   r.   r.   r1   r&  q  r'  zFakeyMessage.getFlagsc                 C   r$  r-   )r@  rL   r.   r.   r1   getInternalDatet  r'  zFakeyMessage.getInternalDatec                 C   s
   t | jS r-   )r   r  rL   r.   r.   r1   getBodyFilew  rq   zFakeyMessage.getBodyFilec                 C   r$  r-   )r  rL   r.   r.   r1   getSizez  r'  zFakeyMessage.getSizec                 C   r$  r-   r  rL   r.   r.   r1   r7  }  r'  zFakeyMessage.getUIDc                 C   s
   | j d uS r-   )r  rL   r.   r.   r1   isMultipart  rq   zFakeyMessage.isMultipartc                 C   s   || _ | j| S r-   )got_subpartr  )rB   r  r.   r.   r1   
getSubPart  s   
zFakeyMessage.getSubPartN)ri   rj   rk   showAttributesrp   r  r&  r  r   r  r7  r  r  r.   r.   r.   r1   r   `  s    	r   c                   @   sF   e Zd ZdZdZdd Zdd Zdd Zdd	 Zd
d Z	dddZ
dS )NewStoreTestsNc                 C   s@   d  | _ | _t | _d| j_| | j_t | _	t
| j	| _d S Nrd  )received_messagesreceived_uidr   ro  r  r  r  r   r  r  r}  r  rL   r.   r.   r1   r    s   

zNewStoreTests.setUpc                 C   r2  r-   r.   rB   r5  r.   r.   r1   r     r*  zNewStoreTests.addListenerc                 C   r2  r-   r.   r
  r.   r.   r1   r"    r*  zNewStoreTests.removeListenerc                 O   r  r-   )	storeArgsr{  )rB   rv  rw  r.   r.   r1   rT    r  zNewStoreTests.storec                    sl    fdd} fdd} j t|| j j  fdd}tj j j	dd}|| |S )	Nc                      s      j j j jS r-   )functionr  ro  silentr|  r.   rL   r.   r1   r    r}  z+NewStoreTests._storeWork.<locals>.connectedc                    rX  r-   r   RrL   r.   r1   r/     rq   z(NewStoreTests._storeWork.<locals>.resultc                    s$      j j    j j d S r-   )r?   r/   r?  r  expectedArgsr  rL   r.   r1   rb    r  z'NewStoreTests._storeWork.<locals>.checkFnoisy
r  r   r4   r  r  r  r    loopbackTCPr  r  )rB   r  r/   rb  r   r.   rL   r1   
_storeWork  s   

zNewStoreTests._storeWorkr   c                 C   s   | j j| _d| _g d| _d| _|| _g dg dg dd| _dg didg didg did| _t	
 }|d |d |d |g dd	fd
d	if| _|  S )Nz1,5,9)z\Az\BCF)r   r   r   rm  r   r   r   r   r|  )r  r  r  r  ro  r  r|  r{  r?  r   r   r   r  r  )rB   r|  r   r.   r.   r1   testSetFlags  s&   







zNewStoreTests.testSetFlagsr  )ri   rj   rk   r/   r  r  r   r"  rT  r  r  r.   r.   r.   r1   r    s    	r  c                   @   r  )GetBodyStructureTestsz
    Tests for L{imap4.getBodyStructure}, a helper for constructing a list which
    directly corresponds to the wire information needed for a I{BODY} or
    I{BODYSTRUCTURE} response.
    c           
   
   C   s   d}d}d}d}d}d}d}t |d | d	 | d
 |||ddd|dd}t|}	| ||d|ddg|||t|g|	 dS )z
        L{imap4.getBodyStructure} accepts a L{IMessagePart} provider and returns
        a list giving the basic fields for the I{BODY} response for that
        message.
           hello, worldimagejpegus-asciisome kind of idgreat justicemaximumr*  
; charset=; x=yr   
content-idcontent-descriptioncontent-transfer-encodingr.   r   r   Ncharsetr5  yr   r   getBodyStructurer?   r   
rB   r   majorminorr&  r?  descriptionr  r   	structurer.   r.   r1   test_singlePart  s>   

	z%GetBodyStructureTests.test_singlePartc                 C   s   t i ddddd}t|}|dd \}}| d| | d| t ddiddddd}t|}|dd \}}| d| | d| t ddiddddd}	t|	}
|
dd \}}| d| | d| dS )	z
        L{imap4.getBodyStructure} returns L{None} for the major and
        minor MIME types of a L{IMessagePart} provider whose headers
        lack a C{Content-Type}, or have an empty value for it.
        r.   r   r   Nr   r   r  
)r   r   r)  assertIs)rB   missingmissingContentTypeStructuremissingMajormissingMinorr  emptyContentTypeStructure
emptyMajor
emptyMinornewlinenewlineContentTypeStructurenewlineMajornewlineMinorr.   r.   r1   test_emptyContentType  s   


z+GetBodyStructureTests.test_emptyContentTypec                 C   sL   t ddiddddd}t|}|dd \}}| |d | |d dS )z
        L{imap4.getBodyStructure} returns only a non-L{None} major
        MIME type for a L{IMessagePart} provider whose headers only
        have a main a C{Content-Type}.
        r   mainr.   r   r   Nr   )r   r   r)  r?   r1  )rB   r>  mainStructure	mainMajor	mainMinorr.   r.   r1   test_onlyMajorContentType  s
   
z/GetBodyStructureTests.test_onlyMajorContentTypec                 C   s   d}d}d}d}d}d}d}d}t |d	 | d
 | d ||||dddddd|dd}	tj|	dd}
| ||d|ddg|||t||dg dgddg|
 dS )z
        L{imap4.getBodyStructure} returns a list giving the basic and extended
        fields for a I{BODYSTRUCTURE} response if passed C{True} for the
        C{extended} parameter.
        r  r  r  r  r  r  r  abcdefabcdefr*  r   r!  zattachment; name=foo; size=barfrFrancer   r#  r$  r%  content-md5content-dispositioncontent-languagecontent-locationr.   r  r   NTextendedr&  r5  r'  
attachment)r_  r!  r  r"  r(  )rB   r   r+  r,  r&  r?  r-  r  md5r   r.  r.   r.   r1   test_singlePartExtended  sP   


z-GetBodyStructureTests.test_singlePartExtendedc                 C   sb   d}d}d}t d|d | idd|dd	}tj|d
d}| ||d	d	d	d	t|d	d	d	d	g| d	S )z
        For fields with no information contained in the message headers,
        L{imap4.getBodyStructure} fills in L{None} values in its result.
        r  r  r  r   r*  r.   r   r   NTrK  r(  )rB   r+  r,  r   r   r.  r.   r.   r1   test_singlePartWithMissingN  s   z0GetBodyStructureTests.test_singlePartWithMissingc           
      C   s   d}d}d}d}d}d}d}t |d | d	 | d
 |||ddd|dd}t|}	| ||d|ddg|||t|t| g|	 dS )z
        For a I{text/*} message, the number of lines in the message body are
        included after the common single-part basic fields.
        "   hello, world
how are you?
goodbye
rC   r  r  r  r  r  r*  r   r!  r"  r.   r   r   Nr&  r5  r'  )r   r   r)  r?   r   r>  r*  r.   r.   r1   test_textPart_  s@   



z#GetBodyStructureTests.test_textPartc                 C   s   d}d}d}d}d}d}d}t |d | d	 | d
 dd|||ddd|dd}t ddidddd|g}	t|	}
| dddddddt|t|dg
|
 dS )z
        For a I{message/rfc822} message, the common basic fields are followed
        by information about the contained message.
        rQ  rC   r  r  r  r  r  r*  r   r!  zAlice <alice@example.com>zBob <bob@example.com>)r   r{   r}   r#  r$  r%  r.   r  r   Nr   message/rfc822r   r?  rz  r   r   )r   r   r)  r?   getEnvelope)rB   r   r+  r,  r&  r?  r-  r  r   	containerr.  r.   r.   r1   test_rfc822Message  sZ   
z(GetBodyStructureTests.test_rfc822Messagec                 C   st   t ddddddddd	d
}t ddiddddd
}t ddidddd||g}| t|t|dgt| d
S )z
        For a I{multipart/*} message, L{imap4.getBodyStructure} returns a list
        containing the body structure information for each part of the message
        followed by an element giving the MIME subtype of the message.
        zimage/jpeg; x=yr  r  r  r"  r.   r      hello worldr   Nr   ztext/plain; charset=us-ascii
   some stuffA  zmultipart/related+  relatedr   r?   r   r)  rB   
oneSubPartanotherSubPartrU  r.   r.   r1   test_multiPart  sJ   z$GetBodyStructureTests.test_multiPartc              	   C   s   t ddddddddd	d
}t ddiddddd
}t ddddddddd||g}| tj|ddtj|dddddgdddggddgtj|dd d
S )a)  
        When passed a I{multipart/*} message and C{True} for the C{extended}
        argument, L{imap4.getBodyStructure} includes extended structure
        information from the parts of the multipart message and extended
        structure information about the multipart message itself.
        s   image/jpeg; x=ys   some kind of ids   great justices   maximum)   content-types
   content-ids   content-descriptions   content-transfer-encodingr.   r   rW  r   Nra  s   text/plain; charset=us-asciirX  rY  zmultipart/related; foo=baresSpainzattachment; name=monkeys)r   rI  rJ  rH  rZ  TrK  r[  r!  r"  rM  r_  monkeysr\  r]  r.   r.   r1   test_multiPartExtended  sX   
	z,GetBodyStructureTests.test_multiPartExtendedN)ri   rj   rk   r  r/  r=  rB  rO  rP  rR  rV  r`  re  r.   r.   r.   r1   r    s    (1(83r  c                   @   s  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdUddZ	dd Z
dUddZdd ZeejdZz	eejd W n ejyJ   dZY n
w eeje dZeeddd ZdUddZdd  ZdUd!d"Zd#d$ ZdUd%d&ZdUd'd(Zd)d* ZdUd+d,Zd-d. ZdUd/d0Zd1d2 Zd3d4 Z dUd5d6Z!d7d8 Z"dUd9d:Z#d;d< Z$dUd=d>Z%d?d@ Z&dAdB Z'dCdD Z(dUdEdFZ)dGdH Z*dUdIdJZ+dKdL Z,dUdMdNZ-dOdP Z.dUdQdRZ/dSdT Z0dS )VNewFetchTestsc                 C   sF   d  | _ | _d | _t | _d| j_| | j_t	 | _
t| j
| _d S r  )r  r	  r/   r   ro  r  r  r  r   r  r  r}  r  rL   r.   r.   r1   r  /  s   

zNewFetchTests.setUpc                 C   r2  r-   r.   r
  r.   r.   r1   r   9  r*  zNewFetchTests.addListenerc                 C   r2  r-   r.   r
  r.   r.   r1   r"  <  r*  zNewFetchTests.removeListenerc                 C   s&   || _ || _tttt| j| jS r-   )r  r	  iterr   rd   r   msgObjsrN  r.   r.   r1   rO  ?  s   zNewFetchTests.fetchc                    s   rt tt j jD ]\}}t|  j| d< q fdd} j fdd| j	
 j tj j jdd}| fdd |S )	Nr{  c                    rX  r-   r   r  rL   r.   r1   r/   I  rq   z(NewFetchTests._fetchWork.<locals>.resultc                    s      jS r-   r  r  r  rB   r|  r.   r1   r2   M  r  z*NewFetchTests._fetchWork.<locals>.<lambda>Fr  c                          j jS r-   r?   r/   r?  r5  rL   r.   r1   r2   S      )r   rd   r   rh  r   r7  r?  r  r   r  r  r  r    r  r  r  )rB   r|  r   r   r/   r   r.   rj  r1   
_fetchWorkD  s   zNewFetchTests._fetchWorkc              	      sn    fdd _ d _ti ddddd ti ddddd ti ddddd g _d	d
id	did	did _ dS )Nc                    s    j | S r-   r  r  )r   urL   r.   r1   r2   W  r  z,NewFetchTests.testFetchUID.<locals>.<lambda>r  r.   r   r    u'  r{  1234599910101)r   r   r   r   )r  r  r   rh  r?  ro  rL   r.   rL   r1   testFetchUIDV  s   
zNewFetchTests.testFetchUIDr   c                 C   sd   | j j| _d| _ti g ddddd ti g ddddd g| _dg didg did| _| |S )	Nr  )FlagAFlagB\FlagCr   1  )rz  rx  ry  r  rm  r   r   )r  
fetchFlagsr  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchFlagsf  s   



zNewFetchTests.testFetchFlagsc                 C   
   |  dS r,  )r~  rL   r.   r.   r1   testFetchFlagsUIDs  rq   zNewFetchTests.testFetchFlagsUIDc              
   C   s   | j j| _d| _ti ddddd ti ddddd ti dddd	d ti dd
ddd g| _ddiddiddiddid| _| |S )N13r.   s   Fri, 02 Nov 2003 21:25:10 GMTr   iZ  s   Thu, 29 Dec 2013 11:31:52 ESTe   s   Mon, 10 Mar 1992 02:44:30 CST   s   Sat, 11 Jan 2000 14:40:24 PSTi/  rp  z02-Nov-2003 21:25:10 +0000z29-Dec-2013 11:31:52 -0500z10-Mar-1992 02:44:30 -0600z11-Jan-2000 14:40:24 -0800)r   r   r   r   )r  fetchInternalDater  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchInternalDatev  s   

z#NewFetchTests.testFetchInternalDatec                 C   r  r,  )r  rL   r.   r.   r1   testFetchInternalDateUID  rq   z&NewFetchTests.testFetchInternalDateUIDN
es_AR.UTF8TFz'The es_AR.UTF8 locale is not installed.c                 C   s8   t t jd}t t jd | t jt j| | dS )zC
        The month name in the date is locale independent.
        Nr  r   )locale	setlocaleLC_ALLr  r  )rB   currentLocaler.   r.   r1   'test_fetchInternalDateLocaleIndependent  s   
z5NewFetchTests.test_fetchInternalDateLocaleIndependentc                 C   sv   | j j| _d| _tdddddddd	d	d
d g| _ddddg dgg dgg dgg dgd d d dg
ii| _| |S )N15zuser@domainzresu@domainthursdayzit is a messagezid-id-id-yayaya)r{   r}   r@  r   z
message-idr.   r   ix  r   rj  )NNr  domain)NNresur  )r  fetchEnveloper  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchEnvelope  s@   

zNewFetchTests.testFetchEnvelopec                 C   r  r,  )r  rL   r.   r.   r1   testFetchEnvelopeUID  rq   z"NewFetchTests.testFetchEnvelopeUIDc                 C   st   | j j| _d| _tdddddddd	d
dddddg| _ddddg ddddddddddggdd	gii| _| |S )a[  
        L{IMAP4Client.fetchBodyStructure} issues a I{FETCH BODYSTRUCTURE}
        command and returns a Deferred which fires with a structure giving the
        result of parsing the server's response.  The structure is a list
        reflecting the parenthesized data sent by the server, as described by
        RFC 3501, section 7.4.2.
        3:9,10:*#text/plain; name=thing; key="value"this-is-the-content-id!describing-the-content-goes-here!8BITabcdef123456zattachment; filename=monkeysrb  zhttp://example.com/monkeysrF  r.   r     Body
Text
Goes
Here
 Nr   r}  rC   plainr  r  r_  thing20r  rM  filenamerd  r  fetchBodyStructurer  r  r   rh  r?  ro  rj  r.   r.   r1   test_fetchBodyStructure  sJ   



z%NewFetchTests.test_fetchBodyStructurec                 C   r  )z
        If passed C{True} for the C{uid} argument, C{fetchBodyStructure} can
        also issue a I{UID FETCH BODYSTRUCTURE} command.
        r   )r  rL   r.   r.   r1   testFetchBodyStructureUID  s   
z'NewFetchTests.testFetchBodyStructureUIDc                 C   s   | j j| _d| _tdddddddd	d
ddddd}tdddddddd|gg| _ddddg dddddddddgdd	gdddgdddgii| _| |S )z
        L{IMAP4Client.fetchBodyStructure} can also parse the response to a
        I{FETCH BODYSTRUCTURE} command for a multipart message.
        r  r  r  r  r  rD  123456abcdefinlinezouter space)r   r#  r$  r%  rI  rG  rH  rJ  r.   r   r  r  Nzmultipart/mixed; boundary="xyz"ennearby)r   rI  rJ  r   r}  rC   r  r  r  r  mixedboundaryxyzr  )rB   r|  innerMessager.   r.   r1    test_fetchBodyStructureMultipart  sl   


z.NewFetchTests.test_fetchBodyStructureMultipartc                 C   sV   | j j| _d| _ti ddddtddidddd d gg| _d	d
g dii| _| |S )N21r.   r      Yea whateverf r   	image/jpg   Body Body Bodyr   r  NNNNNN12r  fetchSimplifiedBodyr  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchSimplifiedBodyD  s*   

z%NewFetchTests.testFetchSimplifiedBodyc                 C   r  r,  )r  rL   r.   r.   r1   testFetchSimplifiedBodyUID^  rq   z(NewFetchTests.testFetchSimplifiedBodyUIDc                 C   sF   | j j| _d| _tddiddddd g| _dd	g d
ii| _| |S )Nr  r   r   r.   r   r  r  r   r  )rC   r  NNNNr  r   r  rj  r.   r.   r1   testFetchSimplifiedBodyTexta  s   

z)NewFetchTests.testFetchSimplifiedBodyTextc                 C   r  r,  )r  rL   r.   r.   r1   testFetchSimplifiedBodyTextUIDo  rq   z,NewFetchTests.testFetchSimplifiedBodyTextUIDc                 C   s   | j j| _d| _tddiddddtddidd	d
d d gg| _ddddd d d d dd d g dgg dgd d d d d d g
g ddg
ii| _| |S )Nr  r   rS  r.   r   r  r  r  r  r  r   r  r?  rz  r  NNN)r  jpgNNNN14r   r  rj  r.   r.   r1   testFetchSimplifiedBodyRFC822r  sZ   

z+NewFetchTests.testFetchSimplifiedBodyRFC822c                 C   r  r,  )r  rL   r.   r.   r1    testFetchSimplifiedBodyRFC822UID  rq   z.NewFetchTests.testFetchSimplifiedBodyRFC822UIDc                 C   s   | j j| _d| _tddidddddtdd	iddd
ddg}tddidddd|}tddidddd|g}|g| _ddg dg ddgdgii| _| dS )ah  
        L{IMAP4Client.fetchSimplifiedBody} returns a dictionary mapping message
        sequence numbers to fetch responses for the corresponding messages.  In
        particular, for a multipart message, the value in the dictionary maps
        the string C{"BODY"} to a list giving the body structure information for
        that message, in the form of a list of subpart body structure
        information followed by the subtype of the message (eg C{"alternative"}
        for a I{multipart/alternative} message).  This structure is self-similar
        in the case where a subpart is itself multipart.
        r  r   r   r.   s   dates   Stuffr{  Nr   s   Thingsi~  r   r   s
   Irrelevantr  zmultipart/mixeds   RootOfí r   r  )rC   r  NNNN5r   )rC   htmlNNNNr  r   alternativer  Fr  )rB   singlesr  r  r.   r.   r1   !test_fetchSimplifiedBodyMultipart  sJ   


z/NewFetchTests.test_fetchSimplifiedBodyMultipartc                 C   B   | j j| _d| _tddiddddd g| _dd	d
ii| _| |S )Nz1,3,7,10101r  Valuer.   r   s   BODY TEXT
[   r   ry  zHeader: Value

BODY TEXT
)r  r  r  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchMessage  s   

zNewFetchTests.testFetchMessagec                 C   r  r,  )r  rL   r.   r.   r1   testFetchMessageUID  rq   z!NewFetchTests.testFetchMessageUIDc                 C   sX   | j j| _d| _tdddddddd g| _ttddd}dd	|ii| _	| 
|S )
Nz9,6,2V1V2)H1H2r.   r   c   r   rs  )r  fetchHeadersr  r  r   rh  r%   r   r<  r?  ro  )rB   r|  r   r.   r.   r1   testFetchHeaders  s   

zNewFetchTests.testFetchHeadersc                 C   r  r,  )r  rL   r.   r.   r1   testFetchHeadersUID  rq   z!NewFetchTests.testFetchHeadersUIDc                 C   r  )Nz1,2,3,4,5,6,7r  r  r.   r  s   Body goes here
   r   rw  zBody goes here
)r  r  r  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchBody  s   

zNewFetchTests.testFetchBodyc                 C   r  r,  )r  rL   r.   r.   r1   testFetchBodyUID  rq   zNewFetchTests.testFetchBodyUIDc           	         s*   j j _d _d}d}d}t }d|d< d|d< d	|d
< d|d< t }d|d
< d|d< t }d|d
< d|d< t|dd|dt|dd|ddt|dd|ddgg _dddgdggi _ fdd} j	 fdd  j	|  j	 j
  j j tj j j dd}|	 fdd |S )zT
        Test the server's handling of requests for specific body sections.
        r   r  r   r   rz   r{   r|   r}   r~   r   r   r   r   r   r   r   r.   Nr   r   r  z&Contained body message text.  Squarge.c                    rX  r-   r   r  rL   r.   r1   r/   7  rq   z0NewFetchTests.testFetchBodyParts.<locals>.resultc                    s    j  jddS )Nr   r  ri  r  rL   r.   r1   r2   ;  rn  z2NewFetchTests.testFetchBodyParts.<locals>.<lambda>Fr  c                    rk  r-   rl  ignrL   r.   r1   r2   B  rn  r  r,  r  r  r   r   rh  r?  r  r   r  r  r  r    r  r  )	rB   r   r   r   r   r   r   r/   r   r.   rL   r1   testFetchBodyParts  sL   

z NewFetchTests.testFetchBodyPartsc                    s   j j_d_dg d}t }d|d< d|d< d|d	< d
|d< t|dd|ddg_dddgdggi_fdd}j	 fdd j	| j	j
 jj tjjj dd}|	fdd |S )z
        Single-part messages have an implicit first part which clients
        should be able to retrieve explicitly.  Test that a client
        requesting part 1 of a text/plain message receives the body of the
        text/plain part.
        r   r   s   DA bodyrz   r{   r|   r}   r~   r   r   r   r.   Nr   r   r  zDA bodyc                    rX  r-   r   r  rL   r.   r1   r/   Y  rq   z>NewFetchTests.test_fetchBodyPartOfNonMultipart.<locals>.resultc                    s   j j dS )Nr  ri  r  partsrB   r.   r1   r2   ]  rn  z@NewFetchTests.test_fetchBodyPartOfNonMultipart.<locals>.<lambda>Fr  c                    rk  r-   rl  r  rL   r.   r1   r2   d  rn  r  )rB   r   r   r/   r   r.   r  r1    test_fetchBodyPartOfNonMultipartE  s*   
z.NewFetchTests.test_fetchBodyPartOfNonMultipartc                 C   s>   | j j| _d| _ti ddddd g| _dddii| _| |S )	Nz	1:100,2:*r.   r   s   xxxxxxxxxxxxxxxxxxxxr   r   ru  r  )r  	fetchSizer  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchSizeg  s   

zNewFetchTests.testFetchSizec                 C   r  r,  )r  rL   r.   r.   r1   testFetchSizeUIDr  rq   zNewFetchTests.testFetchSizeUIDc                 C   s   | j j| _d| _ti ddddd ti dddd	d g| _g dd
dd d g dgg dgd d d d d d g
g ddg dddd d g dgg dgd d d d d d g
g ddd| _| |S )Nz1,3)z\XYZz\YZXAbcs%   Sun, 25 Jul 2010 06:20:30 -0400 (EDT)s   xyzxyzi  )z\Onez\TwoThrees   Mon, 14 Apr 2003 19:43:44 -0400s   abcabcabcabcrZ  z25-Jul-2010 06:20:30 -0400r  r  )NNNNNNr  )rm  rp  ru  rj  r  z14-Apr-2003 19:43:44 -0400r  r  r|  )r  	fetchFullr  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchFullu  sj   

&zNewFetchTests.testFetchFullc                 C   r  r,  )r  rL   r.   r.   r1   testFetchFullUID  rq   zNewFetchTests.testFetchFullUIDc                 C   s   | j j| _d| _ti ddddd ti ddddd g| _d d g d	gg d	gd d d d d d g
d
dg dd d g d	gg d	gd d d d d d g
d
dg dd| _| |S )Nz1,2:3r.   s   Mon, 14 Apr 2003 19:43:44 +0400s   Lalalars  s   Tue, 15 Apr 2003 19:43:44 +0200s   AlalaliN  r  r  z14-Apr-2003 19:43:44 +0400)rj  ru  rp  rm  z15-Apr-2003 19:43:44 +0200r|  )r  fetchAllr  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchAll  sR   

$zNewFetchTests.testFetchAllc                 C   r  r,  )r  rL   r.   r.   r1   testFetchAllUID  rq   zNewFetchTests.testFetchAllUIDc                 C   sD   | j j| _d| _ti ddddd g| _ddgdd	d
i| _| |S )Nr   )\Xs   19 Mar 2003 19:22:21 -0500r   r   r   r  z19-Mar-2003 19:22:21 -05000)rm  rp  ru  )r  	fetchFastr  r  r   rh  r?  ro  rj  r.   r.   r1   testFetchFast  s   

zNewFetchTests.testFetchFastc                 C   r  r,  )r  rL   r.   r.   r1   testFetchFastUID  rq   zNewFetchTests.testFetchFastUIDr  )1ri   rj   rk   r  r   r"  rO  ro  rw  r~  r  r  r  r  r  r  r  ErrornoEsARLocaler
   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r.   r.   r.   r1   rf  .  sb    





%
1

A

4
@	

1
"
=
1
rf  c                   @   rG  )#DefaultSearchTestszz
    Test the behavior of the server's SEARCH implementation, particularly in
    the face of unhandled search terms.
    c                 C   s   t  | _d| j_| | j_t | _t| j| _	t
i ddddd t
i ddddd t
i ddddd t
i ddddd t
i ddddd g| _d S )	Nrd  r.   r   rr  rs  r  i!N  i"N  )r   ro  r  r  r  r   r  r  r}  r  r   rh  rL   r.   r.   r1   r    s   


zDefaultSearchTests.setUpc                 C   s    t ttdt| jd | jS )zW
        Pretend to be a mailbox and let C{self.server} lookup messages on me.
        r   )r   r   rd   r   rh  rN  r.   r.   r1   rO    s    zDefaultSearchTests.fetchc                    sZ   fdd}j t|} fdd}|| |j |j   |S )a  
        Issue a search with given query and verify that the returned messages
        match the given expected messages.

        @param queryTerms: A string giving the search query.
        @param expectedMessages: A list of the message sequence numbers
            expected as the result of the search.
        @return: A L{Deferred} which fires when the test is complete.
        c                         j  S r-   r  ry  r.   
queryTermsrB   r.   r1   ry  !  r5   z8DefaultSearchTests._messageSetSearchTest.<locals>.searchc                    s    |   d S r-   r  r  )expectedMessagesrB   r.   r1   searched&  r  z:DefaultSearchTests._messageSetSearchTest.<locals>.searched)r  r   r4   r  r  r  r    )rB   r  r  ry  r   r  r.   )r  r  rB   r1   _messageSetSearchTest  s   
z(DefaultSearchTests._messageSetSearchTestc                 C      |  ddgS )z
        Test that a search which starts with a message set properly limits
        the search results to messages in that set.
        r   r   r  rL   r.   r.   r1   test_searchMessageSet/  s   z(DefaultSearchTests.test_searchMessageSetc                 C      |  dg dS )zv
        If the search filter ends with a star, all the message from the
        starting point are returned.
        z2:*r  r  rL   r.   r.   r1   test_searchMessageSetWithStar6  r  z0DefaultSearchTests.test_searchMessageSetWithStarc                 C   r  )z
        If the search filter starts with a star, the result should be identical
        with if the filter would end with a star.
        z*:2r  r  rL   r.   r.   r1   "test_searchMessageSetWithStarFirst=  r  z5DefaultSearchTests.test_searchMessageSetWithStarFirstc                 C   r  )z
        If the search filter ends with a star, all the message from the
        starting point are returned (also for the SEARCH UID case).
        zUID 10000:*r  r  rL   r.   r.   r1    test_searchMessageSetUIDWithStarD  r  z3DefaultSearchTests.test_searchMessageSetUIDWithStarc                 C   r  )z
        If the search filter starts with a star, the result should be identical
        with if the filter would end with a star (also for the SEARCH UID case).
        zUID *:10000r  r  rL   r.   r.   r1   %test_searchMessageSetUIDWithStarFirstK  r  z8DefaultSearchTests.test_searchMessageSetUIDWithStarFirstc                 C   r  )z
        A search filter of 1234:* should include the UID of the last message in
        the mailbox, even if its UID is less than 1234.
        zUID 30000:*r   r  rL   r.   r.   r1   ,test_searchMessageSetUIDWithStarAndHighStartR  rZ  z?DefaultSearchTests.test_searchMessageSetUIDWithStarAndHighStartc                 C   r  )z
        If the search filter contains nesting terms, one of which includes a
        message sequence set with a wildcard, IT ALL WORKS GOOD.
        z(6:*)r   r  rL   r.   r.   r1   test_searchMessageSetWithListZ  s   z0DefaultSearchTests.test_searchMessageSetWithListc                 C   s   |  dddgS )z
        If the search filter contains an I{OR} term, all messages
        which match either subexpression are returned.
        zOR 1 2r   r   r  rL   r.   r.   r1   rZ  d  r  z DefaultSearchTests.test_searchOrc                 C   r  )z
        If the search filter contains an I{OR} term with a
        subexpression which includes a message sequence set wildcard,
        all messages in that set are considered for inclusion in the
        results.
        z
OR 2:* 2:*r  r  rL   r.   r.   r1   test_searchOrMessageSetk  r  z*DefaultSearchTests.test_searchOrMessageSetc                 C   r  )z
        If the search filter contains a I{NOT} term, all messages
        which do not match the subexpression are returned.
        zNOT 3)r   r   r   r   r  rL   r.   r.   r1   r\  t  r  z!DefaultSearchTests.test_searchNotc                 C   r  )z
        If the search filter contains a I{NOT} term with a
        subexpression which includes a message sequence set wildcard,
        no messages in that set are considered for inclusion in the
        result.
        zNOT 2:*r   r  rL   r.   r.   r1   test_searchNotMessageSet{  s   z+DefaultSearchTests.test_searchNotMessageSetc                 C   r  )z
        If the search filter contains multiple terms implicitly
        conjoined with a message sequence set wildcard, only the
        intersection of the results of each term are returned.
        z2:* 3r   r  rL   r.   r.   r1   test_searchAndMessageSet  rZ  z+DefaultSearchTests.test_searchAndMessageSetc                    ^   d  fdd}j t|}|tj}fdd}|| |j   |S )z
        If the search criteria is not a valid key, a NO result is returned to
        the client (resulting in an error callback), and an IllegalQueryError is
        logged on the server side.
        FOOc                      r  r-   r  r.   r  r.   r1   ry    r5   z=DefaultSearchTests.test_searchInvalidCriteria.<locals>.searchc                    L    j j   jj   tj} t|d  t	dt	|  dS )
            Verify that the server logs an IllegalQueryError and the
            client raises an IMAP4Exception with 'Search failed:...'
            r   s)   SEARCH failed: Invalid search command FOON
r  r  r  r  r   r   r  r?   r   r   r  rQ  rL   r.   r1   errorReceived  s   zDDefaultSearchTests.test_searchInvalidCriteria.<locals>.errorReceived	r  r   r4   rB  r   r  r  r  r    rB   ry  r   r	  r.   r  r1   test_searchInvalidCriteria  s   
z-DefaultSearchTests.test_searchInvalidCriteriaN)ri   rj   rk   r  r  rO  r  r  r  r  r  r  r  r  rZ  r   r\  r  r  r  r.   r.   r.   r1   r    s$    
		r  c                   @   s`   e Zd Zdd Zdd Zdd ZeZdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd ZdS )FetchSearchStoreTestsc                 C   sX   d  | _ | _d | _d | _d | _d | _t | _d| j_	| | j_
t | _t| j| _d S r  )r?  r/   server_received_queryserver_received_uidserver_received_partsserver_received_messagesr   ro  r  r  r  r   r  r  r}  r  rL   r.   r.   r1   r    s   

zFetchSearchStoreTests.setUpc                 C   s&   |dgkr
t d|| _|| _| jS )Nr  z"FOO is not a valid search criteria)r   r  r  r  r?  )rB   r  r|  r.   r.   r1   ry    s
   

zFetchSearchStoreTests.searchc                 O   r2  r-   r.   )rB   rJ  rw  r.   r.   r1   r     r*  z!FetchSearchStoreTests.addListenerc                    sn    fdd} fdd} j t|| j j  fdd}tj j j	dd}|| |S )	Nc                      s    j j jdS )Nr  )r  ry  r  r.   rj  r.   r1   ry    r  z1FetchSearchStoreTests._searchWork.<locals>.searchc                    rX  r-   r   r  rL   r.   r1   r/     rq   z1FetchSearchStoreTests._searchWork.<locals>.resultc                    sR      j ju    j j   j j  t j	d j
 d S )Ncharmap)r-  r/   r?  r?   r|  r  r   r`  r  r@   r  r  rL   r.   r1   rb    s   z0FetchSearchStoreTests._searchWork.<locals>.checkFr  r  )rB   r|  ry  r/   rb  r   r.   rj  r1   _searchWork  s   

z!FetchSearchStoreTests._searchWorkc                 C   s:   t t jddt jddd| _g d| _d| _| dS )Nr   	substringr        r  r  )r   r   r   r   r   )r   r  r  r  r?  r|  r  rL   r.   r.   r1   
testSearch  s   


z FetchSearchStoreTests.testSearchc                 C   s:   t t jddt jddd| _d| _g d| _| dS )Nr  r  r  r  r  r   r   )r   r  r  r  r|  r?  r  rL   r.   r.   r1   testUIDSearch  s   


z#FetchSearchStoreTests.testUIDSearchc              	   C   sH   z| j | d W S  ttfy   | j |d   Y S  ty#   Y dS w )Nr{  r   r)  )r?  r   
IndexErrorKeyErrorrB   r   r.   r.   r1   r7    s   zFetchSearchStoreTests.getUIDc                 C   s   || _ t|| _| jS r-   )r  r   r  r?  rN  r.   r.   r1   rO    s   
zFetchSearchStoreTests.fetchc                    s`    fdd} j t|| j j  fdd}tj j j	dd}|| |S )Nc                    rX  r-   r   r  rL   r.   r1   r/     rq   z0FetchSearchStoreTests._fetchWork.<locals>.resultc                    s      j ju   jo j   jo j   jr, j D ]
\}}t||d< q! 	 j j  	 j j
  	 j j  	t jt j d S )Nr{  )r-  r/   r?  r  r  r  r|  r  r   r?   r  r   r   r  r  )r  kvrL   r.   r1   rb    s   

z/FetchSearchStoreTests._fetchWork.<locals>.checkFr  r  )rB   rO  r/   rb  r   r.   rL   r1   ro  
  s   

z FetchSearchStoreTests._fetchWorkc                    r  )z
        If, as part of a search, an ISearchableMailbox raises an
        IllegalQueryError (e.g. due to invalid search criteria), client sees a
        failure response, and an IllegalQueryError is logged on the server.
        r  c                      r  r-   r  r.   r  rB   r.   r1   ry  1  r5   z6FetchSearchStoreTests.test_invalidTerm.<locals>.searchc                    r  )r  r   s1   SEARCH failed: FOO is not a valid search criteriaNr  r  rL   r.   r1   r	  7  s   z=FetchSearchStoreTests.test_invalidTerm.<locals>.errorReceivedr
  r  r.   r!  r1   test_invalidTerm)  s   
z&FetchSearchStoreTests.test_invalidTermN)ri   rj   rk   r  ry  r   r"  r  r  r  r7  rO  ro  r"  r.   r.   r.   r1   r    s    			r  c                   @   r  )FakeMailboxc                 C   rn   r-   r  rL   r.   r.   r1   rp   O  rq   zFakeMailbox.__init__c                 C   s   | j |||f td S r-   )rv  rr   r   r4  )rB   r   ro  r@  r.   r.   r1   rA  R  r  zFakeMailbox.addMessageN)ri   rj   rk   rp   rA  r.   r.   r.   r1   r#  N  s    r#  c                   @   $   e Zd Zdd Zdd Zdd ZdS )FeaturefulMessagec                 C   r(  )Nro  r.   rL   r.   r.   r1   r&  Y  r*  zFeaturefulMessage.getFlagsc                 C   r(  )Nrr  r.   rL   r.   r.   r1   r  \  r*  z!FeaturefulMessage.getInternalDatec                 C   s   t dS )N   openr   rL   r.   r.   r1   r  _  rb  zFeaturefulMessage.openN)ri   rj   rk   r&  r  r  r.   r.   r.   r1   r%  W  s    r%  c                   @   r  )MessageCopierMailboxc                 C   rn   r-   )msgsrL   r.   r.   r1   rp   e  rq   zMessageCopierMailbox.__init__c                 C   s   | j | t| j S r-   )r(  rr   r   r  r.   r.   r1   r  h  r  zMessageCopierMailbox.copyN)ri   rj   rk   rp   r  r.   r.   r.   r1   r'  c  r  r'  c                   @   r$  )CopyWorkerTestsc                    sH   t  }|j}t  |dd tddD d } fdd}||S )Nc                 S   s   g | ]}|t  fqS r.   )r%  r	  r.   r.   r1   r  |  s    z9CopyWorkerTests.testFeaturefulMessage.<locals>.<listcomp>r   r  r  c                    sh    j D ]}|d  d |d d |d d q| D ]\}}| |d  q"d S )Nr   r&  r   ro  r   rr  )rv  r?   rP   r/  )r  rJ  r  r/   r   rB   r.   r1   cbCopy~  s   

z5CopyWorkerTests.testFeaturefulMessage.<locals>.cbCopy)r   ro  _IMAP4Server__cbCopyr#  rd   r   rB   rR  r0   r   r+  r.   r*  r1   testFeaturefulMessagen  s   


z%CopyWorkerTests.testFeaturefulMessagec                    sb   t  }|j}t  dd tddD }|dd ttdd|D d } fdd}||S )	Nc              	   S   s0   g | ]}t d t|iddd|f |d dqS )zHeader-Counterr.      Dates   Body %dr   N)r   r   r	  r.   r.   r1   r    s    z;CopyWorkerTests.testUnfeaturefulMessage.<locals>.<listcomp>r   r  c                 S      g | ]}|qS r.   r.   r
  imr.   r.   r1   r    rn  r  c                    s   g } j D ]}||d   |d d |d d q|  tdd tddD }|| | D ]\}}| |d  q9d S )	Nr   r   r.   r   r/  c                 s   s    | ]	}d ||f V  qdS )s   Header-Counter: %d

Body %dNr.   r	  r.   r.   r1   r    s    
zJCopyWorkerTests.testUnfeaturefulMessage.<locals>.cbCopy.<locals>.<genexpr>r  )rv  rr   rP   r?   r  r=  rd   r/  )r  seenrJ  expr  r/   r*  r.   r1   r+    s   

z7CopyWorkerTests.testUnfeaturefulMessage.<locals>.cbCopy)r   ro  r,  r#  rd   r   r   )rB   rR  r0   r(  r   r+  r.   r*  r1   testUnfeaturefulMessage  s   "
z'CopyWorkerTests.testUnfeaturefulMessagec                    sd   t  }|j}t  dd tddD |dd ttddD d } fdd}||S )	Nc                 S   s   g | ]}t  qS r.   )objectr	  r.   r.   r1   r        z5CopyWorkerTests.testMessageCopier.<locals>.<listcomp>r   r  c                 S   r0  r.   r.   r1  r.   r.   r1   r    rn  s   tagc              	      sH    | ttdgd tdd t jD ]
\}}|| qd S )Nr   r   r  )r?   r   r   rd   r(  r   )r  origr  r   r(  rB   r.   r1   r+    s   "z1CopyWorkerTests.testMessageCopier.<locals>.cbCopy)r   ro  r,  r'  rd   r   r   r-  r.   r9  r1   testMessageCopier  s   "
z!CopyWorkerTests.testMessageCopierN)ri   rj   rk   r.  r5  r:  r.   r.   r.   r1   r)  m  s    "r)  zOpenSSL not presentzReactor doesn't support SSLc                   @   sp   e Zd ZdZdZere Zere Zdd Zdd Zdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd ZdS )TLSTestsNc                 C   s   t j| j| jddS )NFr  )r    r  r  r  rL   r.   r.   r1   r      ri  zTLSTests.loopbackc           	         s   t jd g   fdd} fdd} fdd} fdd	} fd
d}dj_|||||gD ]
}jt| q8jj	j
  fdd} }|| |S )Nr8  c                           d  jddS r  )rr   r  r  r.   calledrB   r.   r1   r       
z)TLSTests.testAPileOfThings.<locals>.loginc                      r<  )Nr8     %)rr   r  r   r.   r=  r.   r1   r     r?  z(TLSTests.testAPileOfThings.<locals>.listc                      r<  )Nr8  r  )rr   r  r  r.   r=  r.   r1   r    r?  z*TLSTests.testAPileOfThings.<locals>.statusc                      s     d  jdS )Nr8  )rr   r  r4  r.   r=  r.   r1   r4    s   
z+TLSTests.testAPileOfThings.<locals>.examinec                      s     d  j S r-   )rr   r  r  r.   r=  r.   r1   r    s   

z*TLSTests.testAPileOfThings.<locals>.logoutTc                    s8    jjd  jjd  t t d S rK  )r?   r  
startedTLSr  r   r  r>  methodsrB   r.   r1   rb    s   z)TLSTests.testAPileOfThings.<locals>.check)rj  r|  r  r  requireTransportSecurityr  r   r4   rB  r  r  r    )	rB   r  r   r  r4  r  rJ  rb  r   r.   rB  r1   testAPileOfThings  s    
zTLSTests.testAPileOfThingsc                    s    j jdd g  jtd  j fdd fddj	 j
 j   }| fdd |S )Nrk  rn  c                    r"  )Nrn  r  r  rL   r.   r1   r2     r  z)TLSTests.testLoginLogin.<locals>.<lambda>c                    r  r-   )r  r  r  rL   r.   r1   r2     r   c                    s     tdS r,  )r?   r   rm  rB   successr.   r1   r2     rn  )r  rr  rq  r  r  r   r  r  r   rr   r  r  r  r    rK  r.   rF  r1   testLoginLogin  s$   
zTLSTests.testLoginLoginc                    sj   g  j t jj  fdd} j |  j j   }| fdd t| j gS )z
        Begin a C{STARTTLS} sequence and assert that it results in a
        TLS session.

        @return: A L{Deferred} that fires when the underlying
            connection between the client and server has been terminated.
        c                    s     tj jj d S r-   )r/  r   ISSLTransport
providedByr  r  r  rL   r.   r1   checkSecure  r  z6TLSTests.startTLSAndAssertSession.<locals>.checkSecurec                    s
     S r-   )r/  rm  rF  r.   r1   r2     r   z3TLSTests.startTLSAndAssertSession.<locals>.<lambda>)	r  r   r4   r  startTLSrr   r    r   r  )rB   rK  r   r.   rF  r1   startTLSAndAssertSession  s   z!TLSTests.startTLSAndAssertSessionc                 C   s(   |   }| j| j | j| j |S )z
        L{IMAP4Client.startTLS} triggers TLS negotiation and returns a
        L{Deferred} which fires after the client's transport is using
        encryption.
        )rM  r  r   r  r  r  )rB   disconnectedr.   r.   r1   test_startTLS  s   zTLSTests.test_startTLSc                 C   sn   G dd dt }|| j| jd| _|  }| jt| jj | j| j	d | j| j
 | j| j |S )z]
        A server that receives a second C{STARTTLS} sends a C{NO}
        response.
        c                   @      e Zd Zdd ZdS )z:TLSTests.test_doubleSTARTTLS.<locals>.DoubleSTARTTLSClientc                 S   s    | j st| S | tdS )Ns   STARTTLS)rA  r}  rL  r  r   r  rL   r.   r.   r1   rL  -  s   
zCTLSTests.test_doubleSTARTTLS.<locals>.DoubleSTARTTLSClient.startTLSN)ri   rj   rk   rL  r.   r.   r.   r1   DoubleSTARTTLSClient,      rQ  r  s   TLS already negotiated)r}  r  r  r  rM  r   r4   rL  r  r  r  r  )rB   rQ  rN  r.   r.   r1   test_doubleSTARTTLS&  s   zTLSTests.test_doubleSTARTTLSc                    sl   t jt jd j_tj fdd} jt	|  
 } jt	|  j j  j j |S )z
        Starting a TLS negotiation with an L{IMAP4Server} that already
        has C{LOGIN} and C{PLAIN} L{IChallengeResponse} factories uses
        those factories.
        )r  rg  c                  3   s>     j  V }  d|   d| d   d| d  d S )Nr  r  rg  )r  r  r   r  rL   r.   r1   assertLOGINandPLAINN  s
   zJTLSTests.test_startTLSWithExistingChallengers.<locals>.assertLOGINandPLAIN)r   r  r  r  r  r   r  r  r   r4   rM  r  r  r  )rB   rT  rN  r.   rL   r1   $test_startTLSWithExistingChallengersC  s   
z-TLSTests.test_startTLSWithExistingChallengersc                    s`   dd  j _ j fdd  j jd  j j  j j t	 
  jgS )z|
        A client that attempts to log in before issuing the
        C{STARTTLS} command receives a C{NO} response.
        c                   S   s   t g dfS )NzOK Begin TLS negotiation now)r   r4  r.   r.   r.   r1   r2   f  s    z3TLSTests.test_loginBeforeSTARTTLS.<locals>.<lambda>c                    r  )Ns   wrongs   timer  r  rL   r.   r1   r2   j  r  s!   LOGIN is disabled before STARTTLS)r  rL  r  r   r  r  r  r  r   r  r    rL   r.   rL   r1   test_loginBeforeSTARTTLS`  s   
z!TLSTests.test_loginBeforeSTARTTLSc                    s|   g  fdd}j | j fdd j  fdd j j j j  fdd} |S )Nc                    s   d j _d S r~  )r  canStartTLSr  rL   r.   r1   breakServerTLSz  r5   z3TLSTests.testFailedStartTLS.<locals>.breakServerTLSc                    r  r-   )r  rL  r  rL   r.   r1   r2   ~  r   z-TLSTests.testFailedStartTLS.<locals>.<lambda>c                    s     | tjS r-   )rr   r  r   r  )r  )r  r.   r1   r2     r7  c                    s        d tj d S r>  )r/  r   r   r  r  r  rB   r.   r1   rb    s   
z*TLSTests.testFailedStartTLS.<locals>.check)r  r   r  r  r  r    )rB   rX  rb  r.   rY  r1   testFailedStartTLSw  s   
zTLSTests.testFailedStartTLS)ri   rj   rk   r  r  r,   r+   r    rE  rH  rM  rO  rS  rU  rV  rZ  r.   r.   r.   r1   r;    s     )r;  c                   @   s    e Zd ZdZdZdZdd ZdS )SlowMailboxr   Nc                 C   s*   t  }| | j|jd | jd  |S )Nr.   )r   r  	callLaterhowSlowr  fetchDeferred)rB   r  r|  r   r.   r.   r1   rO    s   zSlowMailbox.fetch)ri   rj   rk   r]  r\  r^  rO  r.   r.   r.   r1   r[    s
    r[  c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )TimeoutTestsc                    sp   t   dj_dj_ jj_d_ fdd}fddjt	|}|
j t| gS )z{
        The *client* has a timeout mechanism which will close connections that
        are inactive for a period.
        Tr   Nc                     s&   j dd}  d |  | S )Nrk  rn  r   )r  r  advancer  r  r   rB   timedOutr.   r1   r    s   

z.TimeoutTests.test_serverTimeout.<locals>.loginc                    s     d  | tj d S r-   )r  r  r   TimeoutErrorr?  rL   r.   r1   rb    r  z1TimeoutTests.test_serverTimeout.<locals>.timedOut)r   r  ru  r  r  r\  r  r  r   r4   r  r  r   r  r    )rB   r  r   r.   ra  r1   test_serverTimeout  s   
zTimeoutTests.test_serverTimeoutc                    sZ   t    jj_fdd} fdd}jt|}|t| t| gS )z4
        The server times out a connection.
        c                      r  r  r  r.   rL   r.   r1   r    r.  z/TimeoutTests.test_serverTimesOut.<locals>.loginc                           jjd  d S Nr   r`  r  POSTAUTH_TIMEOUTr.   r?  r.   r1   
expireTime  r  z4TimeoutTests.test_serverTimesOut.<locals>.expireTime)	r   r\  r  r  r   r4   r   r  r    )rB   r  ri  r   r.   r?  r1   test_serverTimesOut  s   
z TimeoutTests.test_serverTimesOutc                    s    tjdt tjd tjjd t t	   j
j_
fdd}fdd}fdd	} fd
d}fdd}jt|}|t| |t| |t| |t| t| gS )z^
        The server unsets the selected mailbox when timing out a
        connection.
        r^  mailbox-testMAILBOX-TESTc                      r  r  r  r.   rL   r.   r1   r    r.  z7TimeoutTests.test_serverUnselectsMailbox.<locals>.loginc                      r"  Nrk  r#  r.   rL   r.   r1   rd    r5   z8TimeoutTests.test_serverUnselectsMailbox.<locals>.selectc                      s     jj d S r-   )r1  r  r  r.   r  rB   r.   r1   	assertSet  ri  z;TimeoutTests.test_serverUnselectsMailbox.<locals>.assertSetc                      re  rf  rg  r.   r?  r.   r1   ri    r  z<TimeoutTests.test_serverUnselectsMailbox.<locals>.expireTimec                      r%  r-   )r-  r  r  r.   rL   r.   r1   assertUnset  r  z=TimeoutTests.test_serverUnselectsMailbox.<locals>.assertUnset)r  rj  r|  rW  r  r/  r-  r   rJ  r   r\  r  r  r   r4   r   r  r    )rB   r  rd  ro  ri  rp  r   r.   r   r  rB   r1   test_serverUnselectsMailbox  s"   
z(TimeoutTests.test_serverUnselectsMailboxc                    s   t jd t jjd tt t   jj_fdd}fdd}fdd} fd	d
}fdd}j	
t|}|
t| |
t| |
t| |
t| t| gS )zi
        The server closes the selected, closeable mailbox when timing
        out a connection.
        rk  rl  c                      r  r  r  r.   rL   r.   r1   r    r.  z?TimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.loginc                      r"  rm  r#  r.   rL   r.   r1   rd    r5   z@TimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.selectc                           j d S r-   )r-  rL  r.   rn  r.   r1   assertMailboxOpen  r  zKTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.assertMailboxOpenc                      re  rf  rg  r.   r?  r.   r1   ri    r  zDTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.expireTimec                      rs  r-   )r/  rL  r.   rn  r.   r1   assertMailboxClosed  r  zMTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.assertMailboxClosed)rj  r|  r  r/  r   r   r   r\  r  r  r   r4   r   r  r    )rB   r  rd  rt  ri  ru  r   r.   rq  r1   #test_serverTimesOutAndClosesMailbox  s    

z0TimeoutTests.test_serverTimesOutAndClosesMailboxc                    s   t    jt_t t_ jj_ttj_	tj
d jd fdd}fdd}fdd}fd	d
} fdd}tj| jt|}|t| |t| |t| |j |j t| g}|S )zM
        The connection timeout does not take effect during fetches.
        rk  r   c                      r  r  r  r.   rL   r.   r1   r  #  r.  z7TimeoutTests.test_longFetchDoesntTimeout.<locals>.loginc                      s    j d  jdS )Nr   rk  )r  
setTimeoutr  rd  r.   rL   r.   r1   rd  &  s   z8TimeoutTests.test_longFetchDoesntTimeout.<locals>.selectc                      r"  )Nr   rp  r.   rL   r.   r1   rO  *  r5   z7TimeoutTests.test_longFetchDoesntTimeout.<locals>.fetchc                      s      jjd d S )Nr  )r   r  r  r.   rL   r.   r1   stillConnected-  ri  z@TimeoutTests.test_longFetchDoesntTimeout.<locals>.stillConnectedc                    s   t dD ]} d qd S )Nr   g      ?)rd   r`  )r  r   r  r.   r1   	cbAdvance0  s   z;TimeoutTests.test_longFetchDoesntTimeout.<locals>.cbAdvance)r   r\  r[  r   r  r^  r  rj  r|  r^  r  rw  r   r  r4   r  r  r  r  r    )rB   r  rd  rO  rx  ry  r  r   r.   r?  r1   test_longFetchDoesntTimeout  s*   

z(TimeoutTests.test_longFetchDoesntTimeoutc                    s   t  }t }| j|_|j| j_| j| g | jj  fdd| j_|dg| jjd gd   | 	 |d| jjd g | 
 dS )z{
        The *server* has a timeout mechanism which will close connections that
        are inactive for a period.
        c                    s    d  | fd S r,  )rr   )reasonconnLostlostr.   r1   r2   N  s
   z<TimeoutTests.test_idleClientDoesDisconnect.<locals>.<lambda>g        g      @r   g       @N)r   r(   r  r  r\  r  r  pumptimeOutr-  r/  )rB   r   r  r.   r|  r1   test_idleClientDoesDisconnect?  s   
z*TimeoutTests.test_idleClientDoesDisconnectN)	ri   rj   rk   rd  rj  rr  rv  rz  r  r.   r.   r.   r1   r_    s    '&)r_  c                   @   rP  )DisconnectionTestsc                 C   sB   t  }t }|| | |ddtj}|td |S )Nrk  zexample.comConnection closed)	r   r~  r(   r  rB  r  r   r  r  )rB   r   tr   r.   r.   r1   "testClientDisconnectFailsDeferreds]  s   
z5DisconnectionTests.testClientDisconnectFailsDeferredsN)ri   rj   rk   r  r.   r.   r.   r1   r  \  rR  r  c                   @   r  )SynchronousMailboxzb
    Trivial, in-memory mailbox implementation which can produce a message
    synchronously.
    c                 C   s
   || _ d S r-   r  )rB   r  r.   r.   r1   rp   n  rq   zSynchronousMailbox.__init__c                 c   s0    |rJ d|D ]}|| j |d  fV  q	d S )NzCannot handle uid requests.r   r  )rB   rP  r|  r   r.   r.   r1   rO  q  s
   zSynchronousMailbox.fetchN)ri   rj   rk   r  rp   rO  r.   r.   r.   r1   r  h  s    r  c                	   @   s|   e Zd ZdZei g ddddei g ddddei g ddddgZdd Zd	d
 Zdd fddZdd Z	dd Z
dd ZdS )PipeliningTestszM
    Tests for various aspects of the IMAP4 server's pipelining support.
    r   r  Nr     2c                 C   sV   g | _ t | _td d | j| _| j| j t| j	}d| j_
|| j_| j  d S r  )	iteratorsr'   r  r   ro  iterateInReactorr  r  r  r  r  r  r  )rB   r  r.   r.   r1   r    s   
zPipeliningTests.setUpc                 C   s   t  }| j||f |S )z
        A fake L{imap4.iterateInReactor} that records the iterators it
        receives.

        @param iterator: An iterator.

        @return: A L{Deferred} associated with this iterator.
        )r   r  r  rr   )rB   iteratorr   r.   r.   r1   r    s   	z PipeliningTests.iterateInReactorc                   C   r(  rK  r.   r.   r.   r.   r1   r2     r  zPipeliningTests.<lambda>c                 C   sn   | j r1| r3| j d d D ]}| jjr| jj  | jjsq| j dd d | j r5| sdS dS dS dS )a  
        Advance pending iterators enqueued with L{iterateInReactor} in
        a round-robin fashion, resuming the transport's producer until
        it has completed.  This ensures bodies are flushed.

        @param asLongAs: (optional) An optional predicate function.
            Flushing iterators continues as long as there are
            iterators and this returns L{True}.
        r   r   N)r  r  producerrt   r  r  )rB   asLongAser.   r.   r1   flushPending  s   
zPipeliningTests.flushPendingc                 C   r  r-   r  rL   r.   r.   r1   r    r  zPipeliningTests.tearDownc                 C   s   | j d |   | | j ddtdt| j	d 
  f dtdt| j	d 
  f d	td
t| j	d 
  f g dS )z
        Test that pipelined FETCH commands which can be responded to
        synchronously are responded to correctly.
        s9   01 FETCH 1 BODY[]
02 FETCH 2 BODY[]
03 FETCH 3 BODY[]
r      * 1 FETCH (BODY[] )
"01 OK FETCH completed
{5}


%sr      * 2 FETCH (BODY[] )
z"02 OK FETCH completed
{5}


%sr   s   * 3 FETCH (BODY[] )
z"03 OK FETCH completed
{5}


%sr   N)r  r  r  r?   r  r  r   r&   r%   r  r   rP   rL   r.   r.   r1   test_synchronousFetch  s8   z%PipeliningTests.test_synchronousFetchc                 C   s   | j d tttg d}| j|d | | j	 d
dtdt| jd   f g | j  | j jdd	 | | j	  |   | | j	 d
d
dtdt| jd   f g dS )z
        When a server status change occurs during an ongoing FETCH
        command, the server status is buffered until the FETCH
        completes.
        s   01 FETCH 1,2 BODY[]
)TTF)r  r   r  z{5}


%sr   T)r  r  s   * [READ-WRITE]
r  r   N)r  r  	functoolspartialnextrg  r  r?   r  r  r   r&   r%   r  r   rP   r  r  r-  )rB   twicer.   r.   r1   test_bufferedServerStatus  s@   
z)PipeliningTests.test_bufferedServerStatus)ri   rj   rk   r  r   r  r  r  r  r  r  r  r.   r.   r.   r1   r  w  s    #r  c                   @   r  )IMAP4ServerFetchTestszV
    This test case is for the FETCH tests that require
    a C{StringTransport}.
    c                 C   s,   t  | _t | _d| j_| j| j d S r  )r'   r  r   ro  r  r  r  rL   r.   r.   r1   r    s   
zIMAP4ServerFetchTests.setUpc                 C   sL   | j   | jd d}| | j  | | j   | jtd dS )a  
        If by any chance, extra bytes got appended at the end of a valid
        FETCH arguments, the client should get a BAD - arguments invalid
        response.

        See U{RFC 3501<http://tools.ietf.org/html/rfc3501#section-6.4.5>},
        section 6.4.5,
        s   0001 FETCH 1 FULLL
s+   0001 BAD Illegal syntax: Invalid Argument
r  N)	r  r  r  r  r?   r  r  r   r  )rB   r?  r.   r.   r1   "test_fetchWithPartialValidArgument  s   


z8IMAP4ServerFetchTests.test_fetchWithPartialValidArgumentN)ri   rj   rk   r  r  r  r.   r.   r.   r1   r    s    r  c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )LiteralTestsMixinz
    Shared tests for literal classes.

    @ivar literalFactory: A callable that returns instances of the
        literal under test.
    c                 C   s   t  | _dS )z
        Shared setup.
        N)r   r  r  rL   r.   r.   r1   r  5  s   zLiteralTestsMixin.setUpc                 C   s0   |  d| j}| d|d | | j dS )ze
        The literal returns L{None} when given less data than the
        literal requires.
        r  Ns
   incomplete)literalFactoryr  r1  rT   assertNoResult)rB   literalr.   r.   r1   test_partialWrite;  s   z#LiteralTestsMixin.test_partialWritec                 C   sF   d}|  t|| j}||}| |t | | | | j dS )zz
        The literal returns an empty L{bytes} instance when given
        exactly the data the literal requires.
           completeN)r  r   r  rT   r  rH   r-  r  rB   datar  leftoverr.   r.   r1   test_exactWriteD  s   

z!LiteralTestsMixin.test_exactWritec                 C   s0   d}|  td| j}||}| |d dS )zt
        The literal returns any left over L{bytes} when given more
        data than the literal requires.
        s   completeleftoverr     leftoverN)r  r   r  rT   r?   r  r.   r.   r1   test_overlongWriteQ  s   
z$LiteralTestsMixin.test_overlongWritec                 C   s,   |  d| j}d}||}| || dS )zo
        The literal returns an empty L{bytes} instance
        when given an empty L{bytes} instance.
        r   r  N)r  r  rT   r?   )rB   r  r  r  r.   r.   r1   test_emptyLiteral]  s   
z#LiteralTestsMixin.test_emptyLiteralN)	ri   rj   rk   r  r  r  r  r  r  r.   r.   r.   r1   r  -  s    	r  c                   @   s   e Zd ZdZejZdd ZdS )LiteralStringTestsz+
    Tests for L{self.literalFactory}.
    c                 C   s\   d}d}t t|| j}t|D ]}|| q|d | | j}| |||f dS )z
        Calling L{imap4.LiteralString.callback} with a line fires the
        instance's L{Deferred} with a 2-L{tuple} whose first element
        is the collected data and whose second is the provided line.
           datar  N)	r   LiteralStringr   r  r$   rT   r  rQ  r?   )rB   r  extrar  r   r/   r.   r.   r1   test_callbackq  s   
z LiteralStringTests.test_callbackN)ri   rj   rk   r  r   r  r  r  r.   r.   r.   r1   r  j  s    r  c                   @   s&   e Zd ZdZejZdd Zdd ZdS )LiteralFileTestsz)
    Tests for L{imap4.LiteralFile}.
    c                 C   st   d}d}t t|| j}t|D ]}|| q|d | | j}| t|d |\}}| |	 d dS )z
        Calling L{imap4.LiteralFile.callback} with a line fires the
        instance's L{Deferred} with a 2-L{tuple} whose first element
        is the file and whose second is the provided line.
        r  r  r   N)
r   LiteralFiler   r  r$   rT   r  rQ  r?   rP   rB   r  r  r  r   r/   dataFiler.   r.   r1   r    s   
zLiteralFileTests.test_callbackc                 C   s   d}d}|  tjdd tt|| j}t|D ]}|| q|d | | j}| 	t|d |\}}| 	|
 d dS )a=  
        A L{imap4.LiteralFile} whose size exceeds the maximum
        in-memory size spools its content to disk, and invoking its
        L{callback} with a line fires the instance's L{Deferred} with
        a 2-L{tuple} whose first element is the spooled file and whose second
        is the provided line.
        r  r  _memoryFileLimitr   r   N)r  r   r  r   r  r$   rT   r  rQ  r?   rP   r  r.   r.   r1   test_callbackSpooledToDisk  s   
z+LiteralFileTests.test_callbackSpooledToDiskN)	ri   rj   rk   r  r   r  r  r  r  r.   r.   r.   r1   r    s
    r  c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )WriteBufferTestsz)
    Tests for L{imap4.WriteBuffer}.
    c                 C   s   t  | _d S r-   )r'   r  rL   r.   r.   r1   r    r5   zWriteBufferTests.setUpc                 C   s4   t | j}d|j }|| | | j  dS )zd
        L{imap4.WriteBuffer} buffers writes that are smaller than its
        buffer size.
           xN)r   WriteBufferr  
bufferSizerT   r-  r  rB   bufr  r.   r.   r1   r    s   

z"WriteBufferTests.test_partialWritec                 C   s:   t | j}d|jd  }|| | | j | dS )z
        L{imap4.WriteBuffer} writes data without buffering it when
        the size of the data exceeds the size of its buffer.
        r  r   N)r   r  r  r  rT   r?   r  r  r.   r.   r1   r    s   
z#WriteBufferTests.test_overlongWritec                 C   sX   t | j}d|j }d}|| | | j  || | | j ||  dS )zp
        L{imap4.WriteBuffer} buffers writes until its buffer's size
        exceeds its maximum value.
        r     yN)r   r  r  r  rT   r-  r  r?   )rB   r  	firstData
secondDatar.   r.   r1   test_writesImplyFlush  s   


z&WriteBufferTests.test_writesImplyFlushc                 C   sN   t | j}d|j }|| | | j  |  | | j | dS )z{
        L{imap4.WriteBuffer.flush} flushes the buffer even when its
        size is smaller than the buffer size.
        r  N)	r   r  r  r  rT   r-  r  flushr?   r  r.   r.   r1   test_explicitFlush  s   

z#WriteBufferTests.test_explicitFlushc                 C   s(   t | j}|  | | j  dS )z_
        L{imap4.WriteBuffer.flush} has no effect if when the buffer is
        empty.
        N)r   r  r  r  r-  r  )rB   r  r.   r.   r1   test_explicitFlushEmptyBuffer  s   z.WriteBufferTests.test_explicitFlushEmptyBufferN)
ri   rj   rk   r  r  r  r  r  r  r  r.   r.   r.   r1   r    s    r  )r  r  rN   r  r  r  r   collectionsr   ior   	itertoolsr   typingr   r   r   r	   unittestr
   zope.interfacer   zope.interface.verifyr   r   twisted.cred.checkersr   twisted.cred.credentialsr   r   r   twisted.cred.errorr   twisted.cred.portalr   r   twisted.internetr   r   r   r   twisted.internet.taskr   twisted.mailr   twisted.mail.imap4r   twisted.mail.interfacesr   r   r   twisted.protocolsr    twisted.pythonr!   r"   r#   twisted.python.compatr$   r%   r&   twisted.test.proto_helpersr'   r(   twisted.trial.unittestr)   r*   twisted.test.ssl_helpersr+   r,   ImportErrorr4   r6   rm   ry   r   r  IMailboxInfoIMailboxICloseableMailboxr  rW  MemoryAccountWithoutNamespacesr\  rc  rg  ro  rj  r~  r}  r  r  r  rB  rp  rj  rt  r  r  r  r  r	  rE  rH  rj  rl  rm  rw  r  r  r  r  r  IMessageFancyStrMixinr   r  r  rf  r  ISearchableMailboxr  r#  IMessageFiler%  IMessageCopierr'  r)  IReactorSSLr;  r[  r_  r  r  r  r  r  r  r  r  r.   r.   r.   r1   <module>   s  e h  M      :S 2       )   ' (   .2gO    I.2  ! /N'B  f     S 7 		
Q M C =8