HEX
Server: Apache
System: Linux scp1.abinfocom.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: confeduphaar (1010)
PHP: 8.1.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //proc/self/root/lib/python3/dist-packages/twisted/mail/test/__pycache__/test_imap.cpython-38.pyc
U


W[
�@s2dZddlZddlZddlZddlZddlZddlmZddlZddl	m
Z
ddlmZddl
mZddlmZmZddlmZdd	lmZdd
lmZddlmZddlmZdd
lmZddlmZmZmZddlm Z ddl!m"Z"ddl#m$Z$ddl#m%Z%m&Z&ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-ddl.m/Z/ddl0m1Z1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8m9Z9m:Z:ddl;m<Z<m=Z=zddl>m?Z?m@Z@WneAk
�r�dZ?Z@YnXdd�ZBGdd�de/jC�ZDGdd �d �ZEGd!d"�d"e/jF�ZGGd#d$�d$e/jF�ZHGd%d&�d&e/jC�ZIeejJejKejL�Gd'd(�d(��ZMeejJejK�Gd)d*�d*eN��ZOGd+d,�d,ejP�ZQGd-d.�d.eQejR�ZSGd/d0�d0ejTeN�ZUGd1d2�d2ejV�ZWGd3d4�d4�ZXGd5d6�d6eXe/jC�ZYGd7d8�d8e/jF�ZZGd9d:�d:eXe/jC�Z[ee2�Gd;d<�d<��Z\Gd=d>�d>�Z]Gd?d@�d@eXe/jC�Z^GdAdB�dBe/jC�Z_GdCdD�dDeXe/jC�Z`GdEdF�dFe/jC�ZaGdGdH�dHejV�ZbGdIdJ�dJeXe/jC�ZcGdKdL�dLeN�ZdGdMdN�dNed�ZeGdOdP�dPeee/jF�ZfGdQdR�dReee/jF�ZgGdSdT�dTede/jF�ZhGdUdV�dVede/jF�ZiGdWdX�dXede/jF�ZjGdYdZ�dZede/jC�ZkGd[d\�d\ede/jF�ZlGd]d^�d^ede/jF�ZmGd_d`�d`ejT�Zneejo�Gdadb�dbe%jp��ZqGdcdd�dde/jCeX�ZrGdedf�dfe/jC�ZsGdgdh�dhe/jCeX�ZtGdidj�djeXe/jC�Zueejv�Gdkdl�dle/jCeX��ZwGdmdn�dn�Zxeejy�Gdodp�dp��Zzeej{�Gdqdr�dr��Z|Gdsdt�dte/jC�Z}Gdudv�dveXe/jC�Z~Gdwdx�dxeM�ZGdydz�dzeXe/jC�Z�Gd{d|�d|e/jC�Z�Gd}d~�d~eN�Z�Gdd��d�e/jC�Z�e?dk�r�e~fD]Z�d�e�_��q�n&e��ed�dk�r�e~fD]Z�d�e�_��q�Gd�d��d�e/jC�Z�Gd�d��d�eN�Z�Gd�d��d�e�e/jF�Z�Gd�d��d�e�e/jC�Z�Gd�d��d�e/jF�Z�dS)�z"
Test case for twisted.mail.imap4
�N��BytesIO)�chain)�OrderedDict)�implementer)�verifyClass�verifyObject)�defer)�error)�
interfaces)�reactor)�Clock)�imap4)�IChallengeResponse�IClientAuthentication�ICloseableMailboxIMAP)�
MessageSet)�loopback��failure)�util�log)�
intToBytes�range�nativeString�
networkString�	iterbytes�_PY3)�unittest)�Portal�IRealm)�'InMemoryUsernamePasswordDatabaseDontUse��UnauthorizedLogin)�IUsernameHashedPassword�IUsernamePassword�CramMD5Credentials)�StringTransport� StringTransportWithDisconnection)�ClientTLSContext�ServerTLSContextcCs|fdd�S)NcSs|�S�N�)�result�fr,r,�=/usr/lib/python3/dist-packages/twisted/mail/test/test_imap.py�<lambda>9�zstrip.<locals>.<lambda>r,)r.r,r,r/�strip8sr2c@sveZdZddgddgddgddgd	d
ggZdd�Zd
d�Zdd�Zdd�Zdd�Zdd�Z	dd�Z
dd�Zdd�ZdS)�IMAP4UTF7Tests�Hello world�Hello worldz
Hello & worldsHello &- world�Helloÿworld�Hello&AP8-worlduÿþýüs
&AP8A,gD9APw-u~peter/mail/日本語/台北s~peter/mail/&ZeVnLIqe-/&U,BTFw-cCs"d}|�|�dd�|�d��dS)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.
        r4�imap4-utf-7�strictN��assertEqual�encode��self�textr,r,r/�test_encodeWithErrorsGs

�z$IMAP4UTF7Tests.test_encodeWithErrorscCs"d}|�|�dd�|�d��dS)zO
        Similar to L{test_encodeWithErrors}, but for C{bytes.decode}.
        r5r8r9N�r;�decode�r>�bytesr,r,r/�test_decodeWithErrorsSs

�z$IMAP4UTF7Tests.test_decodeWithErrorscCsd}|�|�d�d�dS)z�
        Unicode strings that contain an ampersand (C{&}) can be
        encoded to bytes with the I{imap4-utf-7} codec.
        u
&Hello&½&r8s&-Hello&-&AL0-&-Nr:r=r,r,r/�test_encodeAmpersand]s
�z#IMAP4UTF7Tests.test_encodeAmpersandcCs|�d�d�d�dS)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&AL0r8�½NrA�r>r,r,r/�!test_decodeWithoutFinalASCIIShiftis�z0IMAP4UTF7Tests.test_decodeWithoutFinalASCIIShiftcCs&t�d�td��}|�|��d�dS)zl
        C{codecs.getreader('imap4-utf-7')} returns the I{imap4-utf-7} stream
        reader class.
        r8r7r6N)�codecs�	getreaderrr;�read)r>�readerr,r,r/�test_getreadertszIMAP4UTF7Tests.test_getreadercCs2t�}t�d�|�}|�d�|�|��d�dS)zl
        C{codecs.getwriter('imap4-utf-7')} returns the I{imap4-utf-7} stream
        writer class.
        r8r6r7N)rrJ�	getwriter�writer;�getvalue)r>�output�writerr,r,r/�test_getwriter}s
zIMAP4UTF7Tests.test_getwritercCs&|jD]\}}|�|�d�|�qdS)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.
        r8N)�testsr;r<�r>�inputrRr,r,r/�test_encode�szIMAP4UTF7Tests.test_encodecCs&|jD]\}}|�||�d��qdS)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.
        r8N)rUr;rBrVr,r,r/�test_decode�szIMAP4UTF7Tests.test_decodecCs|ttdd�tdd��D]<}t|���}|�|t|��d��|�t|�|�d��q|�d�d�d�|�d�d�d�dS)	z�
        The IMAP4 modified UTF-7 implementation encodes all printable
        characters which are in ASCII using the corresponding ASCII byte.
        � �&�'�r8�&s&-N)rr�chrr<r;rB)r>�oZcharbyter,r,r/�test_printableSingletons�sz'IMAP4UTF7Tests.test_printableSingletonsN)
�__name__�
__module__�__qualname__rUr@rErFrIrNrTrXrYrar,r,r,r/r3=s"��	
			r3c@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
�BufferingConsumercCs
g|_dSr+)�bufferrHr,r,r/�__init__�szBufferingConsumer.__init__cCs |j�|�|jr|j��dSr+)rf�append�consumer�resumeProducingrCr,r,r/rP�szBufferingConsumer.writecCs||_|j��dSr+)rirj)r>riZ	streamingr,r,r/�registerProducer�sz"BufferingConsumer.registerProducercCs
d|_dSr+)rirHr,r,r/�unregisterProducer�sz$BufferingConsumer.unregisterProducerN)rbrcrdrgrPrkrlr,r,r,r/re�srec@s4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)�MessageProducerTestscsrd�t�}d|d<d|d<d|d<d|d	<t|d
d�dd�}t��t�|������}����fdd
�}|�|�S)NsThis is body text.  Rar.�sender@host�from�recipient@domain�to�booga booga boo�subject�
text/plain�content-typer,�{cs(��|����d��j�d��dS)Nr1sf{119}
From: sender@host
To: recipient@domain
Subject: booga booga boo
Content-Type: text/plain

)�assertIdenticalr;�joinrf�r-��body�c�pr>r,r/�
cbProduced�s
��z7MessageProducerTests.testSinglePart.<locals>.cbProduced�r�FakeyMessagerer�MessageProducer�beginProducing�addCallback)r>�headers�msg�dr~r,rzr/�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|dt|d
d�dd�g�}t��t�|������}����fdd�}|�|�S)Nr1�&Contained body message text.  Squarge.rnrorprqrrrs�%multipart/alternative; boundary="xyz"ru�this is subject textrtr,rvcs,��|����d��j�d�d�dS)Nr1s�{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;rxrfry�r|Z	innerBodyr}r>r,r/r~�s
���z<MessageProducerTests.testSingleMultiPart.<locals>.cbProducedr�r>�	outerBodyr��innerHeadersr�r�r~r,r�r/�testSingleMultiPart�s*
��

z(MessageProducerTests.testSingleMultiPartcs�d}d�d�t�}d|d<d|d<d|d	<d
|d<t�}d|d	<d
|d<t�}d|d	<d|d<t|dd|dt|dd�dd�t|dd�dd�g�}t��t�|������}�����fdd�}|�|�S)Nr1r��.Secondary <i>message</i> text of squarge body.rnrorprqrrrsr�rur�rt�<b>this is subject</b>�	text/htmlr,rvcs4��|����d��j�d�d�d�dS)Nr1s�{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�ry�r|�
innerBody1�
innerBody2r}r>r,r/r~#s
�����z>MessageProducerTests.testMultipleMultiPart.<locals>.cbProducedr)r>r�r�r��
innerHeaders2r�r�r~r,r�r/�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|dt|d
d�dd�g�}t��t�|��dd��_����}����fdd�}|�|�S)z>
        A boundary is generated if none is provided.
        r1r�rnrorprqrrrs�multipart/alternativerur�rtr,NrvcSs
t�d�S)Nz$aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa)�uuidZUUIDr,r,r,r/r0Tr1z?MessageProducerTests.test_multiPartNoBoundary.<locals>.<lambda>cs,��|����d��j�d�d�dS)Nr1s	{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�ryr�r,r/r~Xs

���zAMessageProducerTests.test_multiPartNoBoundary.<locals>.cbProduced)rr�rerr�Z_uuid4r�r�r�r,r�r/�test_multiPartNoBoundary>s,
��


z-MessageProducerTests.test_multiPartNoBoundaryc
s�d}d�t�}d|d<d|d<d|d<d	|d
<t�}d|d<d|d
<t|d
d|dt|d
d�dd�g�}t��t�|������}����fdd�}|�|�S)z>
        A boundary without does not have them added.
        r1r�rnrorprqrrrsz#multipart/alternative; boundary=xyzrur�rtr,Nrvcs,��|����d��j�d�d�dS)Nr1s�{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�ryr�r,r/r~�s

���z?MessageProducerTests.test_multiPartNoQuotes.<locals>.cbProducedrr�r,r�r/�test_multiPartNoQuotesps*
��

z+MessageProducerTests.test_multiPartNoQuotesN)rbrcrdr�r�r�r�r�r,r,r,r/rm�s
,52rmc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&S)'�MessageSetTestsz"
    Tests for L{MessageSet}.
    c
Cs&t�}t�}|�||�|�|d�|d}|�t|�d�|�t|�dg�|d}|�t|�d�|�t|�dddg�|d}|�||�|�t||�dddg�|�d�|�t|�d�|�t|�ddddg�|�||�|�dd	�|�t|�d
�|�t|�dddddd
d	g�dS)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�������N)rr;�assertNotEqual�len�list�add)r>Zm1Zm2r,r,r/�!test_equalityIterationAndAddition�s(
z1MessageSetTests.test_equalityIterationAndAdditioncCs|�tttdd��dS)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�rrHr,r,r/�test_lengthWithWildcardRange�sz,MessageSetTests.test_lengthWithWildcardRangecCsttdd��dS)zD
        L{MessageSet.__repr__} does not raise an exception
        r�r�N)�reprrrHr,r,r/�test_reprSanity�szMessageSetTests.test_reprSanitycCs\t�d�t�d�t�dd�t�dd�g}dddd	g}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:*s3:*r�s*:2�*�1:*z3:6z2:6N�r�parseIdList�zipr;�str�r>�inputs�outputs�ir`r,r,r/�&test_stringRepresentationWithWildcards�s

��z6MessageSetTests.test_stringRepresentationWithWildcardscCsDt�d�t�d�g}ddg}t||�D]\}}|�t|�|�q&dS)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:3s3:2�2:3Nr�r�r,r,r/�&test_stringRepresentationWithInversions��z6MessageSetTests.test_stringRepresentationWithInversioncCs>td�}|�t|�d�|�t|�d�|�t|�dg�dS)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�rr;r�r�r��r>�mr,r,r/�"test_createWithSingleMessageNumbersz2MessageSetTests.test_createWithSingleMessageNumberc
CsRtdd�}|�t|�d�|�t|�d�|�t|�ddddddd	d
ddg
�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��
z1:10r�r�r�r�r�r�r��	Nr�r�r,r,r/�test_createWithSequence#s
z'MessageSetTests.test_createWithSequencecCs:td�}|�t|�d�|�t|�d�|�tt|�dS)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�)rr;r�r�r�r�r�r�r,r,r/�test_createWithSingleWildcard1sz-MessageSetTests.test_createWithSingleWildcardcCsJtd�}d|_|�t|�dg�tdd�}d|_|�t|�dddg�dS)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�)r>ZsingleMessageReplacedZ
rangeReplacedr,r,r/�test_setLastSingleWildcard>s
z*MessageSetTests.test_setLastSingleWildcardcCs:tdd�}|�dd�d|_|�t|�dddddg�dS)zL
        Setting L{MessageSet.last} replaces L{None} in all ranges.
        r�Nr�r�r�r�)rr�r�r;r�r�r,r,r/�test_setLastWithWildcardRangeLs
z-MessageSetTests.test_setLastWithWildcardRangec	Cs0tdd�}d|_|�t��d|_W5QRXdS)z9
        L{MessageSet.last} cannot be set twice.
        r�Nr�r�)rr�r��
ValueErrorr�r,r,r/�test_setLastTwiceFailsVs
z&MessageSetTests.test_setLastTwiceFailscCsltd�}d|_|�d�|�t|�ddg�|�t|d�dddg�|�dd�|�t|�dddg�dS)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�)rr�r�r;r�)r>ZhasLastr,r,r/�test_lastOverridesNoneInAdd`s
z+MessageSetTests.test_lastOverridesNoneInAddcCs"tdd�}d|_|�|jd�dS)zF
        Accessing L{MessageSet.last} returns the last value.
        r�Nr�)rr�r;r�r,r,r/�test_getLastts
zMessageSetTests.test_getLastcCs�t�}|�d�|�t|�dg�t�}|�d�|�t|�d�t�}|�d�|�t|�dddg�t�}|�d�|�t|�d�t�}|�tdd��|�t|�dddg�dS)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�r��NN)r�extendr;r�r�)r>Z
extendWithIntZextendWithNoneZextendWithSequenceOfIntsZextendWithSequenceOfNonesZextendWithMessageSetr,r,r/�test_extend}s



zMessageSetTests.test_extendc	Cs�tdd�}tdd�tdd�}|�d|�|�d|�|d}|�t��d|kW5QRX|d}|�dd�|�t��d|kW5QRXdS)	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�assertInZassertNotInr�r�r�)r>ZhasFiveZdoesNotHaveFiveZhasFiveButHasNoneZhasFiveButHasNoneInSequencer,r,r/�
test_contains�s
zMessageSetTests.test_containscCs�tdd�}tdd�}||}|tdd�}|�t|d�dddd	g�|�t|d
�dddd	dg�|�t|d�ddddg�|�t|d�d	ddddg�|�t|d
�dddd	ddddg�|�t|td	��dddd	dddg�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�N)rr;r�)r>Z
mergeAfterZmergeBeforeZmergeBetweenSequenceZmergeBetweenNumberr,r,r/�test_rangesMerged�s

��z!MessageSetTests.test_rangesMergedcCs\|�tdd�tdd��|�ttdd��dddg�tdd�}d|_|�t|�ddg�dS)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�i�Ni�)r;rr�r�r�r,r,r/�test_seq_rangeExamples�s

z&MessageSetTests.test_seq_rangeExamplescCs�td�tdd�td�tdd�}d|_|�d�d	d
�|D��d�tdd�tdd�}d
|_|�d�dd
�|D��d�dS)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��,css|]}t|�VqdSr+�r���.0r�r,r,r/�	<genexpr>�sz<MessageSetTests.test_sequence_setExamples.<locals>.<genexpr>z2,4,5,6,7,9,12,13,14,15r�r�css|]}t|�VqdSr+r�r�r,r,r/r��sz4,5,6,7,8,9,10)rr�r;rx)r>ZfromFifteenMessagesZfromTenMessagesr,r,r/�test_sequence_setExamples�s(��������z)MessageSetTests.test_sequence_setExamplesN)rbrcrd�__doc__r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/r��s&4



	r�c@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd: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.
    cCstt�ddgd��dS)zI
        L{imap4.Command}'s C{repr} does not raise an exception.
        sCOMMANDsarg�extraN)r�r�CommandrHr,r,r/�test_commandReprsz!IMAP4HelperTests.test_commandReprcsbd�t��t��}t�|������}����fdd�}�fdd�}|�|�|�|�|�|�S)Nsxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzcs<��|����dtt���dd�d��j��|S)N�{�}�
r1)r�r;rr�rxrfry��br|r}r>r,r/r~s
�z6IMAP4HelperTests.test_fileProducer.<locals>.cbProducedcs���|Sr+)rjry)r}r,r/�cbResumesz4IMAP4HelperTests.test_fileProducer.<locals>.cbResume)rerrZFileProducerr�r�)r>r.r�r~r�r,r�r/�test_fileProducers



z"IMAP4HelperTests.test_fileProducercCs�dddddgddggdd	d
ddd
dgdddggdd
dddgdddggg}|D]J\}}}t�|d�}|D]}|�|�|��qf|D]}|�|�|��q�qLdS)N�foo/%gum/bar�foo/bar�oo/lalagum/bar�foo/gumx/bar�foo/gum/baz�foo/xgum/bar�foo/gum/bar�foo/x%x/bar�foo�bar�fuz fuz fuz�	foo/*/bar�foo/xyz/bar�
foo/xx/baz�foo/xyx/bar�
foo/xx/bar�foo/xxxxxxxxxxxxxx/bar�foo/xyz*abc/bar�foo/abc/bar�foo/xyzab/cbar�foo/xyza/bcbar�foo/xyzabc/bar�foo/xyz/abc/bar�foo/xyz/123/abc/bar�/�rZwildcardToRegexp�assertFalse�match�
assertTrue�r>�casesZwildcard�fail�succeed�xr,r,r/�
test_wildcard*s&
��
��
zIMAP4HelperTests.test_wildcardcCs�dddddgdddggd	d
ddd
ddgddddggdddddgdddggg}|D]N\}}}t�|d�}|D]}|�|�|�|�qj|D]}|�|�|�|�q�qPdS)Nr�r�r�r�r�r�r�z
foo/x/gum/barr�r�r�r�r�r�r�r�r�r�zfoo/x/x/barr�rrrrrrrrr,r,r/�test_wildcardNoDelim@s&
�
�
��
z%IMAP4HelperTests.test_wildcardNoDelimcCsLddd�dfg}|D]2\}}t�|�}|�t|�d��t|�d���qdS)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.
        ZValue1ZValue2)ZHeader1ZHeader2s"Header2: Value2
Header1: Value1
TN)r�_formatHeadersr;�sorted�
splitlines)r>rrW�expectedrRr,r,r/�test_headerFormatterVs��
�z%IMAP4HelperTests.test_headerFormattercCsddddddddd	d
ddd
ddddddg}ddgddgdddgdddgddddgddddgddddgddddgddddgdddgdgddgdgdd dgdgdd!dgdgdd!dgdgg}d"d#d$d%g}|D]}|�tjtj|�q�t||�D]\}}|�t�|�|�q�dS)&NsHello WorldsHello "World!"sWorld "Hello" "How are you?"s"Hello world" How "are you?"sfoo bar "baz buz" NILsfoo bar "baz buz" "NIL"sfoo NIL "baz buz" barsfoo "NIL" "baz buz" bars"NIL" bar "baz buz" foosoo \"oo\" oos"oo \"oo\" oo"soo 	 oos	"oo 	 oo"soo \t oos
"oo \t oo"soo \o oos
"oo \o oo"sHellosWorldsWorld!sHow are you?r5sHowsare you?�foo�barsbaz buzsNIL�oos"oo"�
oo "oo" oos\t�\os"mismatched quotesmismatched quote"smismatched"quotes"oops here is" another")r�rZMismatchedQuotingZsplitQuotedr�r;)r>r�answers�errors�s�caserr,r,r/�test_quotedSplittergsb�




��z$IMAP4HelperTests.test_quotedSplittercCs�dddddgddddddddddg
dddgddgddddgdgdddddggdddddddgddddg	ddddddddgddgg}dgdd	d
gdgd
gddgdgd
dggddgdgddgd
gg}t||�D]\}}|�t�|�|�q�dS)N�a�b�c�d�e� �"sabcdesbc sdesabcsbcdsabscdesa s es bc  )r�r;rZcollapseStrings)r>rrrrr,r,r/�test_stringCollapser�s(��


�
z%IMAP4HelperTests.test_stringCollapsercs.d�dgd�}�fdd�}|dtt|��d|dd	d
ddd
gg|g�|dddgdddddddddddggddddggddddggddddggddddgdddd ggddd!g
d"d#d$d%d&gddd'd(d)gg
�|d*d+g�|d,d-g�|d.d/g�|d0d1g�|d0d1g�|d2d3d4g�|d2d3d4g�dS)5Nr�sxxr�cst�|�}��||g�dSr+)r�parseNestedParensr;)rr�parsedrHr,r/�check�s
z0IMAP4HelperTests.test_parenParser.<locals>.checks0(BODY.PEEK[HEADER.FIELDS.NOT (subject bcc cc)] {s}
�)�	BODY.PEEKsHEADER.FIELDS.NOTssubjectsbccsccs(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INTERNALDATEs17-Jul-1996 02:44:25 -0700sRFC822.SIZEs4286sENVELOPEs%Wed, 17 Jul 1996 02:23:25 -0700 (PDT)s$IMAP4rev1 WG mtg summary and minutess
Terry Graysgrayscac.washington.edusimapsminutessCNRI.Reston.VA.USsJohn KlensinsKLENSINsINFOODS.MIT.EDUs#<B27397-0100000@cac.washington.edu>�BODYsTEXT�PLAIN�CHARSETsUS-ASCIIs7BITs3028s92s("oo \"oo\" oo")rs("oo \\ oo")soo \\ oos("oo \ oo")soo \ oos	("oo \o")soo \os(oo \o)rr)rxrr�)r>rr+r,rHr/�test_parenParser�sf
������

��	���z!IMAP4HelperTests.test_parenParsercCs�dddgdddgddd	gd
ddgd
ddgdddgdddgdddgdddgg	}|D]j\}}}|�d�}t��}|�|�|�t|j�d�|�t|jdt	||���|�t
|jd�|�qPdS)N�ENVELOPEZEnvelopeZenvelope�FLAGSZFlags�flags�INTERNALDATEZInternalDate�internaldate�
RFC822.HEADERZRFC822Headerz
rfc822.header�RFC822.SIZEZ
RFC822Sizezrfc822.size�RFC822.TEXTZ
RFC822Textzrfc822.text�RFC822�rfc822�UID�uid�
BODYSTRUCTUREZ
BodyStructureZ
bodystructure�asciir�r)r<r�_FetchParser�parseStringr;r�r-r
�
isinstance�getattrr�)r>r�inp�outpZasStringr}r,r,r/�test_fetchParserSimple�s"�

z'IMAP4HelperTests.test_fetchParserSimplecCs�ddddddgfgddddddd	gfgd
ddddgfgg}|D]d\}}t��}|�|�|�t|j�|d�d
d�|jD�}|��|d��|�||d�q>dS)NsALLr�sflagssinternaldatesrfc822.sizesenvelopesFULLr�sbodysFASTr�rcSsg|]}t|����d��qS)r@)r��lowerr<)r��tokenr,r,r/�
<listcomp>s�z;IMAP4HelperTests.test_fetchParserMacros.<locals>.<listcomp>r�)rrArBr;r�r-�sort)r>rrErFr}ZexpectedResultr,r,r/�test_fetchParserMacross&
�
��
�z'IMAP4HelperTests.test_fetchParserMacroscCs�tj}|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�|jdj
d�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdjd�|�t|jd�d	�|�}|�d
�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdj
jd�|�|jdj
jd�|�|jdjd�|�t|jd�d�|�}|�d
�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdj
jd�|�|jdj
jd�|�|jdjd�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdj
jd�|�|jdj
jdddg�|�|jdjd�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdj
jd�|�|jdj
jdddg�|�|jdjd�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdj
jd�|�|jdj
jdddg�|�|jdjd�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj|j��|�|jdjd�|�|jdjd�|�|jdjd�|�|jdjd�|�t|jd�d�|�}|�d�|�t|j�d�|�t|jd|j��|�|jdj	d�|�t|jdj
|j
��|�|jdjd�|�|jdj
jddg�|�|jdjd�|�|jdjd�|�|jdjd�|�t|jd�d�dS)Nr/r�rF�BODYr-TsBODY[]zBODY[]sBODY[HEADER]r,zBODY[HEADER]sBODY.PEEK[HEADER]s+BODY[HEADER.FIELDS (Subject Cc Message-Id)]sSUBJECTsCCs
MESSAGE-IDs0BODY.PEEK[HEADER.FIELDS (Subject Cc Message-Id)]s4BODY.PEEK[HEADER.FIELDS.NOT (Subject Cc Message-Id)]s/BODY[HEADER.FIELDS.NOT (Subject Cc Message-Id)]sBODY[1.MIME]<10.50>)rr��2s?BODY.PEEK[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>)rr�r�r�sDATE�g�Es:BODY[1.3.9.11.HEADER.FIELDS.NOT (Message-Id Date)]<103.69>)rrArBr;r�r-r
rC�Body�peek�headerr��empty�Header�negateZfieldsrDZmime�MIME�partZpartialBeginZ
partialLength)r>�Pr}r,r,r/�test_fetchParserBody$s�





��
��
��
��z%IMAP4HelperTests.test_fetchParserBodycCs|t��}|�d�|�t|j�d�|�|jdjd�|�|jd|j�|�|jdj	|j
�|�t|jd�d�dS)z�
        Parsing a C{BODY} whose C{HEADER} values require quoting
        results in a object that perserves that quoting when
        serialized.
        sBODY[HEADER.FIELDS ((Quoted)]r�rFsBODY[HEADER.FIELDS ("(Quoted")]N)rrArBr;r�r-rR�assertIsInstancerQrSrUrD�r>r}r,r,r/�test_fetchParserQuotedHeader�s
�z-IMAP4HelperTests.test_fetchParserQuotedHeadercCs&t��}|�d�|�t|j��dS)z=
        Parsing an empty string results in no data.
        r1N)rrArBrr�r-r\r,r,r/�test_fetchParserEmptyString�s
z,IMAP4HelperTests.test_fetchParserEmptyStringcCst��}|�t|jd�dS)z\
        Parsing a string with an unknown attribute raises an
        L{Exception}.
        sUNKNOWNN�rrAr��	ExceptionrBr\r,r,r/� test_fetchParserUnknownAttribute�sz1IMAP4HelperTests.test_fetchParserUnknownAttributecCst��}|�t|jd�dS)zf
        Parsing a string that prematurely ends in whitespace raises an
        L{Exception}.
        sBODY[HEADER.FIELDS  Nr_r\r,r,r/�0test_fetchParserIncompleteStringEndsInWhitespace�szAIMAP4HelperTests.test_fetchParserIncompleteStringEndsInWhitespacecCst��}|�t|jd�dS)z
        Parsing a string that contains an unexpected character rather
        than whitespace raises an L{Exception}.
        sBODY[HEADER.FIELDS!]Nr_r\r,r,r/�"test_fetchParserExpectedWhitespace�sz3IMAP4HelperTests.test_fetchParserExpectedWhitespacecCs|t��}|�d�|�t|j�d�|�|jd|j�|�|jdjd�|�|jdj	|j
�|�t|jd�d�dS)z:
        A C{BODY} can contain a C{TEXT} section.
        s
BODY[TEXT]r�rFN)rrArBr;r�r-r[rQrRr?ZTextrDr\r,r,r/�test_fetchParserTextSection�s
z,IMAP4HelperTests.test_fetchParserTextSectioncCst��}|�t|jd�dS)z[
        Parsing a C{BODY} with an unknown section raises an
        L{Exception}.
        s
BODY[UNKNOWN]Nr_r\r,r,r/�test_fetchParserUnknownSection�sz/IMAP4HelperTests.test_fetchParserUnknownSectioncCs4t��}|�t|jd�t��}|�t|jd�dS)ze
        Parsing a C{BODY} with an unterminated section list raises an
        L{Exception}.
        sBODY[HEADERsBODY[HEADER.FIELDS (SUBJECT)Nr_r\r,r,r/�#test_fetchParserMissingSectionClose�s��z4IMAP4HelperTests.test_fetchParserMissingSectionClosecCs4t��}|�t|jd�t��}|�t|jd�dS)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}.
        sBODY[HEADER.FIELDS Missing)]sBODY[HEADER.FIELDS (Missing]Nr_r\r,r,r/�(test_fetchParserHeaderMissingParentheses�s��z9IMAP4HelperTests.test_fetchParserHeaderMissingParenthesescCst��}|�t|jd�dS)zk
        Parsing a C{BODY} with a range that lacks a period (C{.})
        raises an L{Exception}.
        sBODY<01>Nr_r\r,r,r/�test_fetchParserDotlessPartial�s
�z/IMAP4HelperTests.test_fetchParserDotlessPartialcCst��}|�t|jd�dS)z�
        Parsing a C{BODY} with a partial range that's missing its
        closing greater than sign (C{>}) raises an L{EXCEPTION}.
        sBODY<0Nr_r\r,r,r/�test_fetchParserUnclosedPartials
�z0IMAP4HelperTests.test_fetchParserUnclosedPartialcCs.dddtd�ddg}d}|�t�|�|�dS)Nr�r�Zbaz�this is a file
ZbuzZbizs4"foo" "bar" "baz" {16}
this is a file
 "buz" "biz")rr;r�collapseNestedLists)r>ZinputStructurerRr,r,r/�
test_filess�zIMAP4HelperTests.test_filescCs<dt�d�dtd�dt�d�dg}d}|�t�|�|�dS)	Nrrsbazrjsthis is
quotedsbuzr1sC"foo" bar "baz" {16}
this is a file
 {15}
this is
quoted buz "")rZDontQuoteMerr;rkrVr,r,r/�test_quoteAvoiders�z"IMAP4HelperTests.test_quoteAvoidercCs2ddggfg}|D]\}}|�t�|�|�qdS)Ns({10}
0123456789)s
0123456789)r;rr))r>rrrr,r,r/�
test_literals,s
�zIMAP4HelperTests.test_literalscCs�tjdd�tjdddd�t�tjdd�tjdd��tjdd�t�tjdd�tjdd�tjdd��t�t�t�tjdd	d
d�tjddd
d�tjddddd�t�tjdd����t�tjdd���g}ddddddg}t||�D]\}}|�||�q�dS)Nr�)Zflagged)rZ	unflagged�deleted)roZtoday)�before)�unseen)�newZ	yesterdayi�)rZsince�smallerZtuesdayi')rrp�larger)rrqrorpZspam)rsz1:5�r>ZFLAGGEDz(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�OrZNotr�r;)r>r�r��queryrr,r,r/�test_queryBuilder5sD




�
���

����z"IMAP4HelperTests.test_queryBuildercCstjdd�}|�d|�dS)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�rrvr;�r>rxr,r,r/�test_queryKeywordFlagWithQuotesasz0IMAP4HelperTests.test_queryKeywordFlagWithQuotescCstjdd�}|�d|�dS)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}
        rz)�	unkeywordz(UNKEYWORD twisted)Nr|r}r,r,r/�!test_queryUnkeywordFlagWithQuotesmsz2IMAP4HelperTests.test_queryUnkeywordFlagWithQuotescCs$tjt�dd�d�}|�|d�dS)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:*"))rrvrr;r}r,r,r/�test_queryWithMesssageSetysz*IMAP4HelperTests.test_queryWithMesssageSetcCstjdd�}|�|d�dS)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,r/�test_queryWithInteger�sz&IMAP4HelperTests.test_queryWithIntegercCs|�tjtjtjdd��dS)zq
        An L{imap4.Or} query with less than two arguments raises an
        L{imap4.IllegalQueryError}.
        r�r�N)r�r�IllegalQueryErrorrwrvrHr,r,r/�test_queryOrIllegalQuery�s
�z)IMAP4HelperTests.test_queryOrIllegalQuerycCsb|�d|��ftjf|di��|�d|��ftjf|dd�dd�td�D��fi��dS)	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(%s twistedrocks)ztwisted (){%*"\] rocksztwisted %s rocks�css|]}t|�VqdSr+)r_)r�Zchr,r,r/r��sz9IMAP4HelperTests._keywordFilteringTest.<locals>.<genexpr>�!N)r;�upperrrvrxr)r>r{r,r,r/�_keywordFilteringTest�s	����z&IMAP4HelperTests._keywordFilteringTestcCs|�d�dS)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�rHr,r,r/�test_queryKeywordFlag�s
z&IMAP4HelperTests.test_queryKeywordFlagcCs|�d�dS)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>}
        rNr�rHr,r,r/�test_queryUnkeywordFlag�s
z(IMAP4HelperTests.test_queryUnkeywordFlagcCs.ddddg}|D]}|�tjtj|d�qdS)z|
        Trying to parse an invalid representation of a sequence range raises an
        L{IllegalIdentifierError}.
        s*:*rs4:sbar:5�90N�r�rZIllegalIdentifierErrorr��r>r�rWr,r,r/�test_invalidIdListParser�s��z)IMAP4HelperTests.test_invalidIdListParsercCs4dddddddg}|D]}|�tjtj|d�qd	S)
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).
        s0:5s0:0s*:0�0s-3:5s1:-2s-1r�Nr�r�r,r,r/�#test_invalidIdListParserNonPositive�s�
�z4IMAP4HelperTests.test_invalidIdListParserNonPositivecCs�ddddddddd	d
ddd
dg}tdd�tdd�tdd�tdd�tdd�td�tdd�td�td�td�tdd�tdd�tdd�tdd�td�tdd�td�tdd�tdd�tdd�td�tdd�tdd�g}ddddddddddddddg}t||�D]\}}|�t�|�|��q
t||�D]P\}}|dk�rZ|�ttt�|��n&tt�|��}|�||d|||f��q2dS)zi
        The function to parse sequence ranges yields appropriate L{MessageSet}
        objects.
        r�s5:*s1:2,5:*r��1s1,2s1,3,5s1:10s1:10,11s	1:5,10:20s1,5:10s1,5:10,15:20s
1:10,15,20:25�4:2r�Nr�r�r�r���r��r��r��
�zlen(%r) = %r != %r)rr�r;rr�r�r�r�)r>r�r�ZlengthsrWr�Lr,r,r/�test_parseIdList�sl���
�z!IMAP4HelperTests.test_parseIdListcCs|�ttjd�dS)zu
        L{imap4.parseTime} raises L{ValueError} when given a a time
        string whose format is invalid.
        �invalidN�r�r�rZ	parseTimerHr,r,r/�test_parseTimeInvalidFormat'sz,IMAP4HelperTests.test_parseTimeInvalidFormatcCs(dddg}|D]}|�ttj|�qdS)zv
        L{imap4.parseTime} raises L{ValueError} when given a time
        string composed of invalid values.
        zinvalid-July-2017z2-invalid-2017z2-July-invalidNr�)r>ZinvalidStringsr�r,r,r/�test_parseTimeInvalidValues/s�z,IMAP4HelperTests.test_parseTimeInvalidValuescCsJt�}|��|��|��|��|��d�}t�||���}|�	||�dS)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�getUnseenCountrZstatusRequestHelper�keysr;)r>�mboxrr-r,r,r/�test_statusRequestHelper=s�z)IMAP4HelperTests.test_statusRequestHelperN),rbrcrdr�r�r�rrrr r(r2rGrLrZr]r^rarbrcrdrerfrgrhrirlrmrnryr~r�r�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/r�sR<=t				
	


	,			8r�c@s�eZdZdZgZdZdZdZdd�Zdd�Z	d	d
�Z
dd�Zd
d�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd"dd�Zdd�Zd d!�ZdS)#r��z\Flag1ZFlag2z\AnotherSysFlagZLastFlagrr�FcCsg|_|jj|_|jj|_dSr+�Z	listenersrh�addListener�remove�removeListenerrHr,r,r/rg[s
zSimpleMailbox.__init__cCs|jSr+�r5rHr,r,r/�getFlagsaszSimpleMailbox.getFlagscCsdS)N�*r,rHr,r,r/r�eszSimpleMailbox.getUIDValiditycCst|j�dS�Nr��r�r�rHr,r,r/r�iszSimpleMailbox.getUIDNextcCsdS)Nr�r,rHr,r,r/r�mszSimpleMailbox.getMessageCountcCsdS)Nr�r,rHr,r,r/r�qszSimpleMailbox.getRecentCountcCsdS)Nr�r,rHr,r,r/r�uszSimpleMailbox.getUnseenCountcCs|jSr+��rwrHr,r,r/�isWriteableyszSimpleMailbox.isWriteablecCsdSr+r,rHr,r,r/�destroy}szSimpleMailbox.destroycCsdS)Nrr,rHr,r,r/�getHierarchicalDelimiter�sz&SimpleMailbox.getHierarchicalDelimitercCsvi}d|kr|��|d<d|kr,|��|d<d|krD|��d|d<d|krX|��|d<d|krl|��|d<t�|�S)Nr�r�r�r�r�r��r�r��getUIDr�r	r�r>�names�rr,r,r/�
requestStatus�szSimpleMailbox.requestStatusNcCs.|j�||||jf�|jd7_t�d�Sr��r�rh�mUIDr	r�r>�messager5�dater,r,r/�
addMessage�szSimpleMailbox.addMessagecCsJg}|jD]}d|dkr
|�|�q
|D]}|j�|�q*dd�|D�S)N�\Deletedr�cSsg|]}|d�qS�r�r,r�r,r,r/rJ�sz)SimpleMailbox.expunge.<locals>.<listcomp>�r�rhr��r>�deleter�r,r,r/�expunge�s
zSimpleMailbox.expungecCs
d|_dS�NT)�closedrHr,r,r/�close�szSimpleMailbox.close)N)rbrcrdr5r�r�r�r�rgr�r�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/r�Ss&

r�c@s�eZdZdZdZgZdZdZdZdd�Z	dd	�Z
d
d�Zdd
�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd!dd�Zdd �ZdS)"�UncloseableMailboxz*
    A mailbox that cannot be closed.
    r�rr�FcCsg|_|jj|_|jj|_dSr+r�rHr,r,r/rg�s
zUncloseableMailbox.__init__cCs|jS)zB
        The flags

        @return: A sequence of flags.
        r�rHr,r,r/r��szUncloseableMailbox.getFlagscCsdS)zF
        The UID validity value.

        @return: The value.
        r�r,rHr,r,r/r��sz!UncloseableMailbox.getUIDValiditycCst|j�dS)z:
        The next UID.

        @return: The UID.
        r�r�rHr,r,r/r��szUncloseableMailbox.getUIDNextcCsdS)zG
        The number of messages.

        @return: The number.
        r�r,rHr,r,r/r��sz"UncloseableMailbox.getMessageCountcCsdS)�D
        The recent messages.

        @return: The number.
        r�r,rHr,r,r/r��sz!UncloseableMailbox.getRecentCountcCsdS)r�r�r,rHr,r,r/r��sz!UncloseableMailbox.getUnseenCountcCs|jS)z`
        The recent messages.

        @return: Whether or not the mailbox is writable.
        r�rHr,r,r/r��szUncloseableMailbox.isWriteablecCsdS)z'
        Destroy this mailbox.
        Nr,rHr,r,r/r��szUncloseableMailbox.destroycCsdS)zU
        Return the hierarchical delimiter.

        @return: The delimiter.
        rr,rHr,r,r/r�sz+UncloseableMailbox.getHierarchicalDelimitercCsvi}d|kr|��|d<d|kr,|��|d<d|krD|��d|d<d|krX|��|d<d|krl|��|d<t�|�S)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�r�r�r,r,r/r�	sz UncloseableMailbox.requestStatusNcCs.|j�||||jf�|jd7_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,r/r�s
zUncloseableMailbox.addMessagecCsJg}|jD]}d|dkr
|�|�q
|D]}|j�|�q*dd�|D�S)zj
        Delete messages marked for deletion.

        @return: A L{list} of deleted message IDs.
        r�r�cSsg|]}|d�qSr�r,r�r,r,r/rJ=sz.UncloseableMailbox.expunge.<locals>.<listcomp>r�r�r,r,r/r�1s
zUncloseableMailbox.expunge)N)rbrcrdr�r5r�r�r�r�rgr�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/r��s&								
r�c@s&eZdZdZeZdd�Zddd�ZdS)	�AccountWithoutNamespaceszL
    An in-memory account that does not provide L{INamespacePresenter}.
    cCs|��Sr+)�mailboxFactory)r>�name�idr,r,r/�
_emptyMailboxFsz&AccountWithoutNamespaces._emptyMailboxr�cCs tj�||�}|dk	r||_|Sr+)r�
MemoryAccount�selectr�)r>r�r�r�r,r,r/r�JszAccountWithoutNamespaces.selectN)r�)rbrcrdr�r�r�r�r�r,r,r,r/r�Asr�c@seZdZdZdS)�AccountzD
    An in-memory account that provides L{INamespacePresenter}.
    N�rbrcrdr�r,r,r,r/r�Rsr�c@s$eZdZed�Zdd�Zdd�ZdS)�SimpleServer�testusercOsXtjj|f|�|�t|d�}t|�}t�}|�dd�||_||_|�	|�d|_
dS)N��
accountHolderr��
password-testF)r�IMAP4Serverrg�	TestRealmrr!�addUser�checker�portal�registerChecker�timeoutTest)r>�args�kw�realmr�r|r,r,r/rg[s

zSimpleServer.__init__cCs|jr
dStj�||�dSr+)r�rr��lineReceived�r>�liner,r,r/r�gszSimpleServer.lineReceivedN)rbrcrdr��
theAccountrgr�r,r,r,r/r�Ysr�c@s6eZdZddd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�SimpleClientNcCstj�||�||_g|_dSr+)r�IMAP4Clientrg�deferred�events)r>r��contextFactoryr,r,r/rgqszSimpleClient.__init__cCs|j�d�dSr+)r��callback)r>�capsr,r,r/�serverGreetingwszSimpleClient.serverGreetingcCs|j�d|g�|j��dS)N�modeChanged�r�rh�	transport�loseConnection)r>�	writeabler,r,r/r�{szSimpleClient.modeChangedcCs|j�d|g�|j��dS)N�flagsChangedr��r>ZnewFlagsr,r,r/r��szSimpleClient.flagsChangedcCs |j�d||g�|j��dS)N�newMessagesr�)r>�existsZrecentr,r,r/r�szSimpleClient.newMessages)N)rbrcrdrgr�r�r�rr,r,r,r/r�ps

r�c@sDeZdZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dS)�IMAP4HelperMixinNcCsJt��}t|jd�|_t||jd�|_||_gt	_
td�}t	|_|t_
dS)N�r�r�)r	�Deferredr��	serverCTX�serverr��	clientCTX�client�	connectedr�r�r�ZmboxTyper�)r>r�r�r,r,r/�setUp�szIMAP4HelperMixin.setUpcCs|`|`|`dSr+)rr	r
rHr,r,r/�tearDown�szIMAP4HelperMixin.tearDowncCs|jj��dSr+)r	r�r�)r>�ignorer,r,r/�
_cbStopClient�szIMAP4HelperMixin._cbStopClientcCs0|jj��|jj��t�|dt|��dS)N�
Problem with )r	r�r�rr�errr�)r>rr,r,r/�
_ebGeneral�szIMAP4HelperMixin._ebGeneralcCst�|j|j�Sr+)rZ
loopbackAsyncrr	rHr,r,r/r�szIMAP4HelperMixin.loopbackcCs2|�tj�t|j�}tr"t|�}|�||�dS)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��valuerr�r;)r>rrr�r,r,r/�assertClientFailureMessage�s

z+IMAP4HelperMixin.assertClientFailureMessage)rbrcrdrrrrrrrrr,r,r,r/r�src@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;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�IMAP4ServerTestscs^i���fdd�}�j�t|����j�}t����|g�}dddd��|����fdd��S)Ncs��fdd�}�j���|�S)Ncs��|��jj��dSr+��updaterr�r��r|�r�r>r,r/�gotCaps�s
zAIMAP4ServerTests.testCapability.<locals>.getCaps.<locals>.gotCaps�r	�getCapabilitiesr��rrr,r/�getCaps�sz0IMAP4ServerTests.testCapability.<locals>.getCaps)�	IMAP4rev1�	NAMESPACE�IDLEcs�����Sr+�r;��_�r�rr>r,r/r0�r1z1IMAP4ServerTests.testCapability.<locals>.<lambda>)r
r�r2�
addErrbackrr	�
gatherResultsr�r>r�d1r�r,r&r/�testCapability�szIMAP4ServerTests.testCapabilitycsni�t�jjd<��fdd�}�j�t|����j�}t�	��
�|g�}ddddgd��|����fdd��S)N�CRAM-MD5cs��fdd�}�j���|�S)Ncs��|��jj��dSr+rrrr,r/r�s
zIIMAP4ServerTests.testCapabilityWithAuth.<locals>.getCaps.<locals>.gotCapsrrrr,r/r�sz8IMAP4ServerTests.testCapabilityWithAuth.<locals>.getCaps)r r!r"�AUTHcs�����Sr+r#r$�r�ZexpCapr>r,r/r0�r1z9IMAP4ServerTests.testCapabilityWithAuth.<locals>.<lambda>)r&r�challengersr
r�r2r'rr	r(rr)r,r.r/�testCapabilityWithAuth�s�z'IMAP4ServerTests.testCapabilityWithAuthcsDd�_�fdd�}�j�t|����j����}|��fdd��S)Nrcs$�fdd�}�j���t|��dS)Ncs
d�_dSr�)�	loggedOutr,rHr,r/�setLoggedOut�szAIMAP4ServerTests.testLogout.<locals>.logout.<locals>.setLoggedOut)r	�logoutr�r2)r2rHr,r/r3�sz+IMAP4ServerTests.testLogout.<locals>.logoutcs���jd�Sr�)r;r1r$rHr,r/r0�r1z-IMAP4ServerTests.testLogout.<locals>.<lambda>)r1r
r�r2r'rr)r>r3r�r,rHr/�
testLogout�s
zIMAP4ServerTests.testLogoutcsDd�_�fdd�}�j�t|����j����}|��fdd��S)Ncs �fdd�}�j���|�dS)Ncs|�_�jj��dSr+)�	responsesrr�r�)r5rHr,r/�setResponses�sz=IMAP4ServerTests.testNoop.<locals>.noop.<locals>.setResponses)r	�noopr�)r6rHr,r/r7�sz'IMAP4ServerTests.testNoop.<locals>.noopcs���jg�Sr+)r;r5r$rHr,r/r0�r1z+IMAP4ServerTests.testNoop.<locals>.<lambda>)r5r
r�r2r'rr)r>r7r�r,rHr/�testNoop�s
zIMAP4ServerTests.testNoopcsB�fdd�}�j�t|����j�}t�|���g�}|��j�S)Ncs�j�dd�}|��j�dS�Nr�r�)r	�loginr�r�r�rHr,r/r:�sz)IMAP4ServerTests.testLogin.<locals>.login)	r
r�r2r'rr	r(r�_cbTestLogin�r>r:r*r�r,rHr/�	testLogin�szIMAP4ServerTests.testLogincCs&|�|jjtj�|�|jjd�dS�N�auth�r;r�accountr�r��state�r>�ignoredr,r,r/r<szIMAP4ServerTests._cbTestLogincsF�fdd�}�j�t|����j�}���}t�||g�}|��j�S)Ncs�j�dd�}|��j�dS�Nr�swrong-password�r	r:�addBothrr;rHr,r/r:	sz/IMAP4ServerTests.testFailedLogin.<locals>.login)	r
r�r2r'rrr	r(�_cbTestFailedLogin�r>r:r*�d2r�r,rHr/�testFailedLogins
z IMAP4ServerTests.testFailedLogincCs$|�|jjd�|�|jjd�dS)N�unauth)r;rrBrCrDr,r,r/rIsz#IMAP4ServerTests._cbTestFailedLogincsNd�j_�fdd�}�j�t|����j�}���}t�	||g�}|��j
�S)zj
        Attempting to log into a server that has no L{Portal} results
        in a failed login.
        Ncs�j�dd�}|��j�dSrFrGr;rHr,r/r:sz7IMAP4ServerTests.test_loginWithoutPortal.<locals>.login)rr�r
r�r2r'rrr	r(rIrJr,rHr/�test_loginWithoutPortalsz(IMAP4ServerTests.test_loginWithoutPortalcsZdd�}|�jjj_�fdd�}�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_sdddd�fS)NzNot IAccountzNot an accountcSsdSr+r,r,r,r,r/r01r1zVIMAP4ServerTests.test_nonIAccountAvatar.<locals>.brokenRequestAvatar.<locals>.<lambda>r,)r%�__r,r,r/�brokenRequestAvatar0szDIMAP4ServerTests.test_nonIAccountAvatar.<locals>.brokenRequestAvatarcs�j�dd�}|��j�dSr9rGr;rHr,r/r:5sz6IMAP4ServerTests.test_nonIAccountAvatar.<locals>.login)
rr�r��
requestAvatarr
r�r2r'rrr	r(rI)r>rPr:r*rKr�r,rHr/�test_nonIAccountAvatar(sz'IMAP4ServerTests.test_nonIAccountAvatarcs�Gdd�dt���fdd�}|�j_�fdd�}�j�t|��}|��jd�|j��fdd	��}|��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@seZdZdZdS)zAIMAP4ServerTests.test_loginException.<locals>.UnexpectedException�2
            An unexpected exception.
            Nr�r,r,r,r/�UnexpectedExceptionFsrTcs�d��dS)NZWhoopsr,)�user�passwd�rTr,r/�raisesUnexpectedExceptionKszGIMAP4ServerTests.test_loginException.<locals>.raisesUnexpectedExceptioncs�j�dd�Sr9�r	r:r,rHr,r/r:Psz3IMAP4ServerTests.test_loginException.<locals>.loginsServer error: Whoopscs�������dSr+�r
�flushLoggedErrorsr$�rTr>r,r/�assertErrorLoggedWsz?IMAP4ServerTests.test_loginException.<locals>.assertErrorLogged)r`rZauthenticateLoginr
r�r2r'rrrHrrr	r(rI)r>rXr:r*r]rKr�r,r\r/�test_loginException?sz$IMAP4ServerTests.test_loginExceptioncsPddi�jj_�fdd�}�j�t|����j�}t�	��
�|g�}|��j�S)N�
{test}user�{test}passwordcs4�j�dd�}|�tjdt���|��j�dS)Nr_r`r)r	r:r'rrr�r�rr;rHr,r/r:fsz9IMAP4ServerTests.testLoginRequiringQuoting.<locals>.login)rr��usersr
r�r2r'rr	r(r�_cbTestLoginRequiringQuotingr=r,rHr/�testLoginRequiringQuotingcs
z*IMAP4ServerTests.testLoginRequiringQuotingcCs&|�|jjtj�|�|jjd�dSr?rArDr,r,r/rbpsz-IMAP4ServerTests._cbTestLoginRequiringQuotingcs�d�_�fdd�}�fdd�}�j�t|��}|�t|��|��j����}t�||g�}|j�fdd��}|��j	ddggggg�|S)	Ncs�j�dd�Sr9rYr,rHr,r/r:wsz-IMAP4ServerTests.testNamespace.<locals>.logincs�fdd�}�j���|�S)Ncs|�_��d�dSr+��
namespaceArgsr�r�rHr,r/�gotNamespacezszGIMAP4ServerTests.testNamespace.<locals>.namespace.<locals>.gotNamespace�r	�	namespacer��rgrHr,r/riysz1IMAP4ServerTests.testNamespace.<locals>.namespacecs2�jD]$}|D]}|D]}��|t�qqq�jSr+)rer[r�)rEZ
namespacesZpairrrHr,r/�assertAllPairsNativeStrings�s

zCIMAP4ServerTests.testNamespace.<locals>.assertAllPairsNativeStringsr�r)
rer
r�r2r'rrr	r(r;)r>r:rir*rKr�rkr,rHr/�
testNamespaceuszIMAP4ServerTests.testNamespacecs�td��j_d�_�fdd�}�fdd�}�j�t|��}|�t|��|��j���	�}t
�||g�}|��fdd��|��jgggg�|S)	z�
        A mailbox that does not provide L{INamespacePresenter} returns
        empty L{list}s for its personal, shared, and user namespaces.
        r�Ncs�j�dd�Sr9rYr,rHr,r/r:�sz<IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.logincs�fdd�}�j���|�S)Ncs|�_��d�dSr+rdrfrHr,r/rg�szVIMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.namespace.<locals>.gotNamespacerhrjrHr,r/ri�sz@IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.namespacecs�jSr+)rer$rHr,r/r0�r1z?IMAP4ServerTests.test_mailboxWithoutNamespace.<locals>.<lambda>)
r�rr�rer
r�r2r'rrr	r(r;)r>r:rir*rKr�r,rHr/�test_mailboxWithoutNamespace�sz-IMAP4ServerTests.test_mailboxWithoutNamespacecsrtj�d�d�_�fdd�}�fdd�}�j�t|��}|�t|��|��j���	�}t
�||g���j�S)N�test-mailboxcs�j�dd�Sr9rYr,rHr,r/r:�sz*IMAP4ServerTests.testSelect.<locals>.logincs&�fdd�}�j�d�}|�|�|S)Ncs|�_��d�dSr+)�selectedArgsrrfrHr,r/�selected�sz=IMAP4ServerTests.testSelect.<locals>.select.<locals>.selectedrn)r	r�r�)rpr�rHr,r/r��s
z+IMAP4ServerTests.testSelect.<locals>.select)
r�r��
addMailboxror
r�r2r'rrr	r(�
_cbTestSelect)r>r:r�r*rKr,rHr/�
testSelect�szIMAP4ServerTests.testSelectcs��fdd�}�fdd�}�j�t|���j�t|���j��jd��j��j��j��j�t��j��	�g�}|j�fdd��}|S)zh
        A client that selects a mailbox that does not exist receives a
        C{NO} response.
        cs�j�dd�Sr9rYr,rHr,r/r:�sz9IMAP4ServerTests.test_selectWithoutMailbox.<locals>.logincs�j�d�S)Nrn�r	r�r,rHr,r/r��sz:IMAP4ServerTests.test_selectWithoutMailbox.<locals>.select�No such mailboxcs���jj�dSr+)�assertIsNonerr�r$rHr,r/�assertNoMailboxSelected�szKIMAP4ServerTests.test_selectWithoutMailbox.<locals>.assertNoMailboxSelected)
r
r�r2r'rrrr	r(r)r>r:r�ZconnectionCompleterwr,rHr/�test_selectWithoutMailbox�s
��z*IMAP4ServerTests.test_selectWithoutMailboxc	Cs:tjjd}|�|jj|�|�|jdddddd��dS)N�TEST-MAILBOXr�r�r�r�T��EXISTSr�r�r4�
READ-WRITE)r�r��	mailboxesr;rr�ro�r>rEr�r,r,r/rr�s�zIMAP4ServerTests._cbTestSelectcsvtj�d�d�_�fdd�}�fdd�}�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.
        rnNcs�j�dd�Sr9rYr,rHr,r/r:�sz,IMAP4ServerTests.test_examine.<locals>.logincs&�fdd�}�j�d�}|�|�|S)Ncs|�_��d�dSr+)�examinedArgsrrfrHr,r/�examined�sz@IMAP4ServerTests.test_examine.<locals>.examine.<locals>.examinedrn)r	�examiner�)r�r�rHr,r/r��s
z.IMAP4ServerTests.test_examine.<locals>.examine)
r�r�rqrr
r�r2r'rrr	r(�_cbTestExamine)r>r:r�r*rKr�r,rHr/�test_examine�szIMAP4ServerTests.test_examinec	Cs:tjjd}|�|jj|�|�|jdddddd��dS)Nryr�r�r�r�Frz)r�r�r}r;rr�rr~r,r,r/r�	s�zIMAP4ServerTests._cbTestExaminecs�d�d��fdd���fdd���fdd�}�����fd	d
�}g�_�j�t|���t|��}���}t�||g�}|��j���S)N)�testbox�test/boxztest/�test/box/boxZINBOX)r�r�cs�j�d�dSr��r-rhr,rHr,r/�cb	r1z'IMAP4ServerTests.testCreate.<locals>.cbcs�j�d�dS�Nrr�rrHr,r/�eb	r1z'IMAP4ServerTests.testCreate.<locals>.ebcs�j�dd�Sr9rYr,rHr,r/r:	sz*IMAP4ServerTests.testCreate.<locals>.logincsB��D]$}�j�|�}|�t������q|��j�j�dSr+)r	�creater�r2r'�addCallbacksrr)r�r��r�r�r
r>rr,r/r�	sz+IMAP4ServerTests.testCreate.<locals>.create)r-r
r�r2rr	r(�
_cbTestCreate)r>r:r�r*rKr�r,r�r/�
testCreate	szIMAP4ServerTests.testCreatecCs^|�|jdgt|�dgt|��ttjj�}tdddddg�}|�|dd	�|D��dS)
Nr�r�inboxr�r��testr�cSsg|]}|���qSr,�r�)r��ar,r,r/rJ-	sz2IMAP4ServerTests._cbTestCreate.<locals>.<listcomp>)r;r-r�rr�r�r})r>rErr
r�rr,r,r/r�(	s&
�zIMAP4ServerTests._cbTestCreatecs�tj�d��fdd�}�fdd�}�j�t|��}|�t|��j�|��j�j���	�}t
�||g�}|��fdd��|S)N�	delete/mecs�j�dd�Sr9rYr,rHr,r/r:3	sz*IMAP4ServerTests.testDelete.<locals>.logincs�j�d�S�Nr��r	r�r,rHr,r/r�5	sz+IMAP4ServerTests.testDelete.<locals>.deletecs��ttjj�g�Sr+)r;r�r�r�r}r$rHr,r/r0=	sz-IMAP4ServerTests.testDelete.<locals>.<lambda>�r�r�rqr
r�r2r�rrrr	r()r>r:r�r*rKr�r,rHr/�
testDelete0	s
�zIMAP4ServerTests.testDeletecs�tj�d�tj�d��fdd�}�fdd�}�fdd�}�j�t|��}|�t|��j�|�|�|��j	���
�}t�||g�}|��fd	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.
        r�r�cs�j�dd�Sr9rYr,rHr,r/r:N	szGIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.logincs�j�d�S�Nr�r�r,rHr,r/r�P	szHIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.deletecs&|�tj���t|j�td��dS)Ns-Name "DELETE" has inferior hierarchical names)rrrr;r�rrrHr,r/�assertIMAPExceptionS	s
�zUIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.assertIMAPExceptioncs��ttjj�ddg�S)NZDELETEz	DELETE/ME)r;rr�r�r}r$rHr,r/r0b	s�zJIMAP4ServerTests.testDeleteWithInferiorHierarchicalNames.<locals>.<lambda>)
r�r�rqr
r�r2r�rr'rrr	r()r>r:r�r��loggedInZ
loopedBackr�r,rHr/�'testDeleteWithInferiorHierarchicalNamesB	s	

�z8IMAP4ServerTests.testDeleteWithInferiorHierarchicalNamescs�d�_�fdd�}�fdd�}�fdd�}�j�t|��}|�t|��j�|�|�|��j�j����}t	�
||g�}|��fdd��|S)	Ncs�j�dd�Sr9rYr,rHr,r/r:j	sz6IMAP4ServerTests.testIllegalInboxDelete.<locals>.logincs�j�d�S)Nr�r�r,rHr,r/r�l	sz7IMAP4ServerTests.testIllegalInboxDelete.<locals>.deletecs
|�_dSr+��stashedryrHr,r/�stashn	sz6IMAP4ServerTests.testIllegalInboxDelete.<locals>.stashcs��t�jtj��Sr+�r
rCr�r�Failurer$rHr,r/r0w	s
�z9IMAP4ServerTests.testIllegalInboxDelete.<locals>.<lambda>�r�r
r�r2r�rrHrrr	r()r>r:r�r�r*rKr�r,rHr/�testIllegalInboxDeleteh	s
z'IMAP4ServerTests.testIllegalInboxDeletecs��fdd�}�fdd�}�fdd�}d�_�j�t|��}|�t|���|�|��j�j����}t	�
||g�}|��fdd��|S)	Ncs�j�dd�Sr9rYr,rHr,r/r:}	sz5IMAP4ServerTests.testNonExistentDelete.<locals>.logincs�j�d�Sr�r�r,rHr,r/r�	sz6IMAP4ServerTests.testNonExistentDelete.<locals>.deletecs
|�_dSr+rrrHr,r/�deleteFailed�	sz<IMAP4ServerTests.testNonExistentDelete.<locals>.deleteFailedcs��t�jj�td��S)Nru�r;r�rrr$rHr,r/r0�	s�z8IMAP4ServerTests.testNonExistentDelete.<locals>.<lambda>)rr
r�r2r'r�rrrr	r()r>r:r�r�r*rKr�r,rHr/�testNonExistentDelete|	sz&IMAP4ServerTests.testNonExistentDeletecs�t�}d|_tj�d|�tj�d��fdd�}�fdd�}�fdd	�}d�_�j�t|��}|�t|���	|�|�
�j�j���
�}t�||g�}td
��|���fdd��|S)
N)z	\Noselectr�r�cs�j�dd�Sr9rYr,rHr,r/r:�	sz1IMAP4ServerTests.testIllegalDelete.<locals>.logincs�j�d�Sr�r�r,rHr,r/r��	sz2IMAP4ServerTests.testIllegalDelete.<locals>.deletecs
|�_dSr+rrrHr,r/r��	sz8IMAP4ServerTests.testIllegalDelete.<locals>.deleteFaileds<Hierarchically inferior mailboxes exist and \Noselect is setcs��t�jj���Sr+r�r$�rr>r,r/r0�	sz4IMAP4ServerTests.testIllegalDelete.<locals>.<lambda>)r�r5r�r�rqrr
r�r2r'r�rrrr	r(r�)r>r�r:r�r�r*rKr�r,r�r/�testIllegalDelete�	s z"IMAP4ServerTests.testIllegalDeletecs�tj�d��fdd�}�fdd�}�j�t|��}|�t|��j�|��j�j���	�}t
�||g�}|��fdd��|S)N�oldmboxcs�j�dd�Sr9rYr,rHr,r/r:�	sz*IMAP4ServerTests.testRename.<locals>.logincs�j�dd�S)Nsoldmboxsnewname�r	�renamer,rHr,r/r��	sz+IMAP4ServerTests.testRename.<locals>.renamecs��ttjj���dg�S)NZNEWNAME)r;r�r�r�r}r�r$rHr,r/r0�	s�z-IMAP4ServerTests.testRename.<locals>.<lambda>r��r>r:r�r*rKr�r,rHr/�
testRename�	szIMAP4ServerTests.testRenamecs�d�_�fdd�}�fdd�}�fdd�}�j�t|��}|�t|��j�|�|�|��j�j����}t	�
||g�}|��fdd��|S)	Ncs�j�dd�Sr9rYr,rHr,r/r:�	sz6IMAP4ServerTests.testIllegalInboxRename.<locals>.logincs�j�dd�S)Nr�Zfrotzr�r,rHr,r/r��	sz7IMAP4ServerTests.testIllegalInboxRename.<locals>.renamecs
|�_dSr+r�)ZstuffrHr,r/r��	sz6IMAP4ServerTests.testIllegalInboxRename.<locals>.stashcs��t�jtj��Sr+r�r$rHr,r/r0�	sz9IMAP4ServerTests.testIllegalInboxRename.<locals>.<lambda>r�)r>r:r�r�r*rKr�r,rHr/�testIllegalInboxRename�	s
z'IMAP4ServerTests.testIllegalInboxRenamecs�tj�d�tj�d��fdd�}�fdd�}�j�t|��}|�t|��j�|��j�j���	�}t
�||g�}|��j�S)Nz
oldmbox/m1z
oldmbox/m2cs�j�dd�Sr9rYr,rHr,r/r:�	sz6IMAP4ServerTests.testHierarchicalRename.<locals>.logincs�j�dd�S)Nr��newnamer�r,rHr,r/r��	sz7IMAP4ServerTests.testHierarchicalRename.<locals>.rename)
r�r�r�r
r�r2r�rrrr	r(�_cbTestHierarchicalRenamer�r,rHr/�testHierarchicalRename�	sz'IMAP4ServerTests.testHierarchicalRenamecCs<tjj��}dddg}tt|��}|�|dd�|D��dS)Nr�z
newname/m1z
newname/m2cSsg|]}|���qSr,r�)r�rr,r,r/rJ�	sz>IMAP4ServerTests._cbTestHierarchicalRename.<locals>.<listcomp>)r�r�r}r�r�rr;)r>rEZmboxesrr,r,r/r��	s
z*IMAP4ServerTests._cbTestHierarchicalRenamecsv�fdd�}�fdd�}�j�t|��}|�t|��j�|��j�j����}t�||g�}|��fdd��|S)Ncs�j�dd�Sr9rYr,rHr,r/r:�	sz-IMAP4ServerTests.testSubscribe.<locals>.logincs�j�d�S�Nz	this/mbox)r	�	subscriber,rHr,r/r��	sz1IMAP4ServerTests.testSubscribe.<locals>.subscribecs��tjjdg�S)N�	THIS/MBOX�r;r�r��
subscriptionsr$rHr,r/r0�	s
�z0IMAP4ServerTests.testSubscribe.<locals>.<lambda>)	r
r�r2r�rrrr	r()r>r:r�r*rKr�r,rHr/�
testSubscribe�	szIMAP4ServerTests.testSubscribecs�ddgtj_�fdd�}�fdd�}�j�t|��}|�t|��j�|��j�j���	�}t
�||g�}|��fdd��|S)	Nr��	THAT/MBOXcs�j�dd�Sr9rYr,rHr,r/r:�	sz/IMAP4ServerTests.testUnsubscribe.<locals>.logincs�j�d�Sr�)r	�unsubscriber,rHr,r/r��	sz5IMAP4ServerTests.testUnsubscribe.<locals>.unsubscribecs��tjjdg�S)Nr�r�r$rHr,r/r0
s
�z2IMAP4ServerTests.testUnsubscribe.<locals>.<lambda>)r�r�r�r
r�r2r�rrrr	r()r>r:r�r*rKr�r,rHr/�testUnsubscribe�	sz IMAP4ServerTests.testUnsubscribecs�tj�d�tj�d�tj�d��fdd�}�fdd�}d�_�j�t|��}|�t|��j�|�|�j�|��j	�j���
�}t�||g���fdd	��S)
N�
root/subthingzroot/another-thingznon-root/subthingcs�j�dd�Sr9rYr,rHr,r/r:
sz*IMAP4ServerTests._listSetup.<locals>.logincs
|�_dSr+��listed)rrHr,r/r�
sz+IMAP4ServerTests._listSetup.<locals>.listedcs�jSr+r�r$rHr,r/r0
r1z-IMAP4ServerTests._listSetup.<locals>.<lambda>)
r�r�rqr�r
r�r2r�rrrr	r()r>r.r:r�r*rKr,rHr/�
_listSetup
szIMAP4ServerTests._listSetupcCs2|D](}|�|dtd�|�|dtd�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�zdelimiter %r is not a strr�zmailbox %r is not a str)r[r�)r>�resultsr-r,r,r/�'assertListDelimiterAndMailboxAreStrings
s��z8IMAP4ServerTests.assertListDelimiterAndMailboxAreStringscs,�fdd�}��|�}|j�fdd��}|S)Ncs�j�dd�S�N�root�%)r	r�r,rHr,r/�mailboxList/
sz.IMAP4ServerTests.testList.<locals>.mailboxListcsjttj�ddfttj�ddfg}td�D]*}|�d�\}}}��t|�||f|�q(��|d�|��dS)Nr�
ROOT/SUBTHINGzROOT/ANOTHER-THINGr�rz More results than expected: {!r})rr�r5r�popr�r�format)r�ZexpectedContentsr%r5Z	delimiter�mailboxrHr,r/�assertListContents2
s���z5IMAP4ServerTests.testList.<locals>.assertListContents)r�r�)r>r�r�r�r,rHr/�testList.
s

zIMAP4ServerTests.testListcsJtj�d��fdd�}��|�}|��j�|��jtjddfg�|S)Nr�cs�j�dd�Sr�)r	�lsubr,rHr,r/r�H
sz'IMAP4ServerTests.testLSub.<locals>.lsubr)	r�r�r�r�r�r�r;r�r5)r>r�r�r,rHr/�testLSubF
s
�zIMAP4ServerTests.testLSubcs�tj�d��fdd�}�fdd�}�fdd�}d�_�j�t|��}|�t|��j�|�|�j�|��j	�j���
�}t�||g�}|��fdd	��|S)
Nr�cs�j�dd�Sr9rYr,rHr,r/r:S
sz*IMAP4ServerTests.testStatus.<locals>.logincs�j�dddd�S)Nr�r�r�r��r	�statusr,rHr,r/r�U
sz+IMAP4ServerTests.testStatus.<locals>.statuscs
|�_dSr+��statusedryrHr,r/r�W
sz-IMAP4ServerTests.testStatus.<locals>.statusedcs���jdddd��S)Nr�s10r�)r�r�r�)r;r�r$rHr,r/r0a
s
�z-IMAP4ServerTests.testStatus.<locals>.<lambda>)
r�r�rqr�r
r�r2r�rrrr	r()r>r:r�r�r*rKr�r,rHr/�
testStatusQ
szIMAP4ServerTests.testStatuscs��fdd�}�fdd�}�fdd�}�fdd�}d�_�_�j�t|��}|�t|��j�|�||�|��j�j����}t	�
||g���j�S)	Ncs�j�dd�Sr9rYr,rHr,r/r:i
sz0IMAP4ServerTests.testFailedStatus.<locals>.logincs�j�dddd�S)Nzroot/nonexistentr�r�r�r�r,rHr,r/r�k
s
�z1IMAP4ServerTests.testFailedStatus.<locals>.statuscs
|�_dSr+r�ryrHr,r/r�n
sz3IMAP4ServerTests.testFailedStatus.<locals>.statusedcs
|�_dSr+rrrHr,r/�failedp
sz1IMAP4ServerTests.testFailedStatus.<locals>.failed)r�rr
r�r2r�rrrr	r(�_cbTestFailedStatus)r>r:r�r�r�r*rKr,rHr/�testFailedStatush
sz!IMAP4ServerTests.testFailedStatuscCs$|�|jd�|�|jjjd�dS)N)sCould not open mailbox)r;r�rrr�rDr,r,r/r�|
s��z$IMAP4ServerTests._cbTestFailedStatuscs�t�td��tj�d��fdd�}tj��fdd��}�j�	t
|��}|�t
|��j�|��j
�j����}t�||g�}|�	�j��S)N�rfc822.messager�cs�j�dd�Sr9rYr,rHr,r/r:�
sz.IMAP4ServerTests.testFullAppend.<locals>.loginc	3s8t�d��$}�j�d|dd�V}t�|�W5QRXdS)N�rbr�)�\SEEN�\DELETEDz%Tue, 17 Jun 2003 11:22:16 -0600 (MDT))�openr	rhr	�returnValue�r�r-��infiler>r,r/rh�
s�z/IMAP4ServerTests.testFullAppend.<locals>.append)r�sibpath�__file__r�r�rqr	�inlineCallbacksr
r�r2r�rrrr(�_cbTestFullAppend�r>r:rhr*rKr�r,r�r/�testFullAppend�
s
zIMAP4ServerTests.testFullAppendc	Csztjjd}|�dt|j��|�ddgddf|jddd��t|d��$}|�|��|jdd���W5QRXdS)Nr�r�r�r�s%Tue, 17 Jun 2003 11:22:16 -0600 (MDT)rr��	r�r�r}r;r�r�r�rLrQ�r>rEr�Zmbr.r,r,r/r��
s��z"IMAP4ServerTests._cbTestFullAppendcs�t�td��tj�d��fdd�}tj��fdd��}�j�	t
|��}|�t
|��j�|��j
�j����}t�||g�}|�	�j��S)Nr��PARTIAL/SUBTHINGcs�j�dd�Sr9rYr,rHr,r/r:�
sz1IMAP4ServerTests.testPartialAppend.<locals>.loginc3sVt�d��B}�j�t�dtdtj���f�d�jj	|��V}t
�|�W5QRXdS)Nr�sAPPENDz)PARTIAL/SUBTHING (\SEEN) "Right now" {%d}r,)r�r	�sendCommandrr�r�os�path�getsizeZ_IMAP4Client__cbContinueAppendr	r�r�r�r,r/rh�
s����z2IMAP4ServerTests.testPartialAppend.<locals>.append)rr�r�r�r�rqr	r�r
r�r2r�rrrr(�_cbTestPartialAppendr�r,r�r/�testPartialAppend�
sz"IMAP4ServerTests.testPartialAppendc	Csxtjjd}|�dt|j��|�dgddf|jddd��t|d��$}|�|��|jdd���W5QRXdS)Nr�r�r�s	Right nowrr�r�r�r,r,r/r��
s
�z%IMAP4ServerTests._cbTestPartialAppendcs|tj�d��fdd�}�fdd�}�fdd�}�j�t|��}|�t|��j�|�t|��j�|��j�j���	�S)N�
root/subthingcs�j�dd�Sr9rYr,rHr,r/r:�
sz*IMAP4ServerTests._testCheck.<locals>.logincs�j�d�S)Nr�rtr,rHr,r/r��
sz+IMAP4ServerTests._testCheck.<locals>.selectcs
�j��Sr+)r	r+r,rHr,r/r+�
sz*IMAP4ServerTests._testCheck.<locals>.check)
r�r�rqr
r�r2r�rrr)r>r:r�r+r�r,rHr/�
_testCheck�
szIMAP4ServerTests._testCheckcCs|��S)zf
        Trigger the L{imap.IMAP4Server._cbSelectWork} callback
        by selecting an mbox.
        )r�rHr,r,r/�
test_check�
szIMAP4ServerTests.test_checkcs6ddd�}�fdd�}��td|����}|�|�S)zr
        Trigger the L{imap.IMAP4Server._ebSelectWork} errback
        by failing when we select an mbox.
        r�cSst�d��dS)N�encoding)r�IllegalMailboxEncoding)r>r�r�r,r,r/�
failSelect�
sz3IMAP4ServerTests.test_checkFail.<locals>.failSelectcs$���}��|djjdd�dS)Nr�rsSELECT failed: Server error)r[r;rr�)r
�failuresrHr,r/�
checkResponse�
s�z6IMAP4ServerTests.test_checkFail.<locals>.checkResponser�)r�)�patchr�r�r�)r>r�r�r�r,rHr/�test_checkFail�
s

zIMAP4ServerTests.test_checkFailcs�t�}dddg|_tj�d|��fdd�}�fdd�}�fd	d
�}�j�t|��}|�t|��j	�|�t|��j	�|��j
�j	����}t�
||g���j|�S)N�s	Message 1)r��AnotherFlagNr�s	Message 2)r�Nr��s	Message 3)r�Nr�r�cs�j�dd�Sr9rYr,rHr,r/r:sz)IMAP4ServerTests.testClose.<locals>.logincs�j�d�S)Nsmailboxrtr,rHr,r/r�sz*IMAP4ServerTests.testClose.<locals>.selectcs
�j��Sr+)r	r�r,rHr,r/r�sz)IMAP4ServerTests.testClose.<locals>.close)r�r�r�r�rqr
r�r2r�rrrr	r(�_cbTestClose)r>r�r:r�r�r�rKr,rHr/�	testCloses�zIMAP4ServerTests.testClosecCs4|�t|j�d�|�|jdd�|�|j�dS)Nr�rr�)r;r�r�r
r��r>rEr�r,r,r/r�s�zIMAP4ServerTests._cbTestClosec	s�t�}dddg|_tj�d|��fdd�}�fdd�}�fd	d
�}�fdd�}d�_�j�t|��}|�	t|��j
�|�	t|��j
�|�	|�j
�|�	�j�j
����}t
�||g�}|��j|�S)
Nr�r�r�r�cs�j�dd�Sr9rYr,rHr,r/r:,sz+IMAP4ServerTests.testExpunge.<locals>.logincs�j�d�S)Nr�rtr,rHr,r/r�0sz,IMAP4ServerTests.testExpunge.<locals>.selectcs
�j��Sr+)r	r�r,rHr,r/r�4sz-IMAP4ServerTests.testExpunge.<locals>.expungecs���jjdk�|�_dSr+)rrr�r��r�rHr,r/�expunged8sz.IMAP4ServerTests.testExpunge.<locals>.expunged)r�r�r�r�rqr�r
r�r2r�rrrr	r(�_cbTestExpunge)	r>r�r:r�r�r�r*rKr�r,rHr/�testExpunge$s&�zIMAP4ServerTests.testExpungecCs:|�t|j�d�|�|jdd�|�|jddg�dS)Nr�rr�r�)r;r�r�r�r�r,r,r/rGszIMAP4ServerTests._cbTestExpungeN)6rbrcrdr+r0r4r8r>r<rLrIrNrRr^rcrbrlrmrsrxrrr�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�rrr,r,r,r/r�sf
	$

#	&

##rc@sHeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd: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.
    cCs.t�|_t��|_|j�|j�|j��dSr+)r'r�rr�r�makeConnection�clearrHr,r,r/rTs
zIMAP4ServerParsingTests.setUpcCs|j�t�t����dSr+�r�connectionLostrr�r
�ConnectionDonerHr,r,r/r[sz IMAP4ServerParsingTests.tearDowncsLGdd�dt���fdd�}d|j_||j_|j�d�|�|����dS)zO
        L{imap4.IMAP4Server} logs exceptions raised by parse methods.
        c@seZdZdZdS)zSIMAP4ServerParsingTests.test_parseMethodExceptionLogged.<locals>.UnhandledException�1
            An unhandled exception.
            Nr�r,r,r,r/�UnhandledExceptiondsr	cs��dSr+r,)r��r	r,r/�raisesValueErroriszQIMAP4ServerParsingTests.test_parseMethodExceptionLogged.<locals>.raisesValueError�command�invalidN)r`rZ
parseState�
parse_commandr�r
r[)r>rr,r
r/�test_parseMethodExceptionLogged_sz7IMAP4ServerParsingTests.test_parseMethodExceptionLoggedcCs:|j�d�|�|j��d�|j�t�t�	d���dS)z�
        L{imap4.IMAP4Server.parse_command} sends a C{BAD} response to
        a line that includes a tag but no command.
        �001s001 BAD Missing command
ZDoneN)
rrr;r�rrrr�r
rrHr,r,r/�test_missingCommandts��z+IMAP4ServerParsingTests.test_missingCommandcCs"|j�d�|�|j��d�dS)zf
        L{imap4.IMAP4Server.parse_command} sends a C{BAD} response to
        an empty line.
        r1s* BAD Null command
N)rrr;r�rrHr,r,r/�test_emptyLine�sz&IMAP4ServerParsingTests.test_emptyLinecsJ�fdd�}||j_|j�d�|dg��|�|j��d�||g��dS)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}
        cs��dSr+r,)�tag�cmd�rest��	exceptionr,r/�raises�szDIMAP4ServerParsingTests.assertParseExceptionResponse.<locals>.raisesr&r
N)r�dispatchCommandrrxr;r�r�r>rrZexpectedResponserr,rr/�assertParseExceptionResponse�s�z4IMAP4ServerParsingTests.assertParseExceptionResponsecCs|�t�d�dd�dS)zt
        When a parsing method raises L{IllegalClientResponse}, the
        server sends a C{BAD} response.
        �client responser�%BAD Illegal syntax: client response
N)rr�IllegalClientResponserHr,r,r/�'test_parsingRaisesIllegalClientResponse�s
�z?IMAP4ServerParsingTests.test_parsingRaisesIllegalClientResponsecCs|�t�d�dd�dS)zn
        When a parsing method raises L{IllegalOperation}, the server
        sends a C{NO} response.
        �	operationr�!NO Illegal operation: operation
N)rr�IllegalOperationrHr,r,r/�*test_parsingRaisesIllegalOperationResponse�s
�zBIMAP4ServerParsingTests.test_parsingRaisesIllegalOperationResponsecCs|�t�d�dd�dS)zt
        When a parsing method raises L{IllegalMailboxEncoding}, the
        server sends a C{NO} response.
        r�r�#NO Illegal mailbox name: encoding
N)rrr�rHr,r,r/�(test_parsingRaisesIllegalMailboxEncoding�s
�z@IMAP4ServerParsingTests.test_parsingRaisesIllegalMailboxEncodingcCs"|j�d�|�|j��d�dS)zi
        L{imap4.IMAP4Server} responds to an unsupported command with a
        C{BAD} response.
        s001 HULLABALOOs001 BAD Unsupported command
N)rr�r;r�rrHr,r,r/�test_unsupportedCommand�s�z/IMAP4ServerParsingTests.test_unsupportedCommandcCs4|j�d�|�|j��dtd��d�d�dS)z~
        L{imap4.IMAP4Server} responds with a C{BAD} response to a
        command with more arguments than expected.
        s001 LOGIN A B Cs8001 BAD Illegal syntax: Too many arguments for command: �Czutf-8r�N)rr�r;r�rr�r<rHr,r,r/�test_tooManyArgumentsForCommand�s���z7IMAP4ServerParsingTests.test_tooManyArgumentsForCommandcsf�fdd�}|�|jjd�|f|jjdd�|j_|j�|dd�|�|j��d�||g��dS)	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}
        cs��dSr+r,)ZserverInstancerrUrVrr,r/r�szFIMAP4ServerParsingTests.assertCommandExceptionResponse.<locals>.raisesrMr�N�LOGINsuser passwdr&)r;rrCZunauth_LOGINrr�rrxrr,rr/�assertCommandExceptionResponse�s�z6IMAP4ServerParsingTests.assertCommandExceptionResponsecCs|�t�d�dd�dS)zm
        When a command raises L{IllegalClientResponse}, the
        server sends a C{BAD} response.
        rrrN)r*rrrHr,r,r/�'test_commandRaisesIllegalClientResponses
�z?IMAP4ServerParsingTests.test_commandRaisesIllegalClientResponsecCs|�t�d�dd�dS)zg
        When a command raises L{IllegalOperation}, the server sends a
        C{NO} response.
        r rr!N)r*rr"rHr,r,r/�*test_commandRaisesIllegalOperationResponses
�zBIMAP4ServerParsingTests.test_commandRaisesIllegalOperationResponsecCs|�t�d�dd�dS)zm
        When a command raises L{IllegalMailboxEncoding}, the server
        sends a C{NO} response.
        r�rr$N)r*rr�rHr,r,r/�(test_commandRaisesIllegalMailboxEncodings
�z@IMAP4ServerParsingTests.test_commandRaisesIllegalMailboxEncodingcCs6Gdd�dt�}|�|d�dd�|�|�|��dS)z�
        Wehn a command raises an unhandled exception, the server sends
        a C{BAD} response and logs the exception.
        c@seZdZdZdS)zXIMAP4ServerParsingTests.test_commandRaisesUnhandledException.<locals>.UnhandledExceptionrNr�r,r,r,r/r	'sr	Z	unhandledrsBAD Server error: unhandled
N)r`r*r
r[)r>r	r,r,r/�$test_commandRaisesUnhandledException!s�z<IMAP4ServerParsingTests.test_commandRaisesUnhandledExceptioncCs*d|j_|j�d�|�|j��d�dS)zx
        A string literal whose length exceeds the maximum allowed
        length results in a C{BAD} response.
        r�s001 LOGIN {5}
sE001 BAD Illegal syntax: Literal too long! I accept at most 4 octets
N)rZ_literalStringLimitr�r;r�rrHr,r,r/�test_stringLiteralTooLong4s
�z1IMAP4ServerParsingTests.test_stringLiteralTooLongcCs"dD]}|�tj|jj|�qdS)zQ
        An empty string argument raises L{imap4.IllegalClientResponse}.
        )r1r�r&N�r�rrrZarg_astring)r>rTr,r,r/�test_arg_astringEmptyLineAs
�z1IMAP4ServerParsingTests.test_arg_astringEmptyLinecCs|�tj|jjd�dS)zh
        An unmatched quote in a string argument raises
        L{imap4.IllegalClientResponse}.
        s"openNr0rHr,r,r/�test_arg_astringUnmatchedQuotesJs�z7IMAP4ServerParsingTests.test_arg_astringUnmatchedQuotescCs|�tj|jjd�dS)zn
        An unmatched brace in a string literal's size raises
        L{imap4.IllegalClientResponse}.
        s{0Nr0rHr,r,r/�&test_arg_astringUnmatchedLiteralBracesSs�z>IMAP4ServerParsingTests.test_arg_astringUnmatchedLiteralBracescCs|�tj|jjd�dS)zc
        A non-integral string literal size raises
        L{imap4.IllegalClientResponse}.
        �{[object Object]}Nr0rHr,r,r/�"test_arg_astringInvalidLiteralSize\s�z:IMAP4ServerParsingTests.test_arg_astringInvalidLiteralSizecCs|�tj|jjd�dS)z@
        An empty atom raises L{IllegalClientResponse}.
        r1N�r�rrrZarg_atomrHr,r,r/�test_arg_atomEmptyLinees�z.IMAP4ServerParsingTests.test_arg_atomEmptyLinecCs|�tj|jjd�dS)zC
        A malformed atom raises L{IllegalClientResponse}.
        s
 not an atom Nr6rHr,r,r/�test_arg_atomMalformedAtomms�z2IMAP4ServerParsingTests.test_arg_atomMalformedAtomcCs|�tj|jjd�dS)zN
        An empty parenthesized list raises L{IllegalClientResponse}.
        r1N�r�rrrZ	arg_plistrHr,r,r/�test_arg_plistEmptyLineus�z/IMAP4ServerParsingTests.test_arg_plistEmptyLinecCs,|�tj|jjd�|�tj|jjd�dS)ze
        A parenthesized with unmatched parentheses raises
        L{IllegalClientResponse}.
        s(foosfoo)Nr9rHr,r,r/�"test_arg_plistUnmatchedParentheses}s��z:IMAP4ServerParsingTests.test_arg_plistUnmatchedParenthesescCs|�tj|jjd�dS)zH
        An empty file literal raises L{IllegalClientResponse}.
        r1N�r�rrrZarg_literalrHr,r,r/�test_arg_literalEmptyLine�s�z1IMAP4ServerParsingTests.test_arg_literalEmptyLinecCs,|�tj|jjd�|�tj|jjd�dS)zZ
        A literal with unmatched braces raises
        L{IllegalClientResponse}.
        s{10s10}Nr<rHr,r,r/�test_arg_literalUnmatchedBraces�s��z7IMAP4ServerParsingTests.test_arg_literalUnmatchedBracescCs|�tj|jjd�dS)z\
        A non-integral literal size raises
        L{imap4.IllegalClientResponse}.
        r4Nr<rHr,r,r/�"test_arg_literalInvalidLiteralSize�s�z:IMAP4ServerParsingTests.test_arg_literalInvalidLiteralSizecCs$d}|j�|�\}}|�|d�dS)zH
        A sequence set returns the unparsed portion of a line.
        s1:* blah blah blahsblah blah blahN)r�
arg_seqsetr;)r>Zsequencer%rr,r,r/�test_arg_seqsetReturnsRest�sz2IMAP4ServerParsingTests.test_arg_seqsetReturnsRestcCs|�tj|jjd�dS)zL
        An invalid sequence raises L{imap4.IllegalClientResponse}.
        sx:yN)r�rrrr@rHr,r,r/�test_arg_seqsetInvalidSequence�s�z6IMAP4ServerParsingTests.test_arg_seqsetInvalidSequencecCs0d}|j�|�\}}|�||g�|�|�dS)zJ
        A single flag that is not contained in a list is parsed.
        sflagN)r�arg_flaglistr;r)r>�flagr*rr,r,r/�test_arg_flaglistOneFlag�sz0IMAP4ServerParsingTests.test_arg_flaglistOneFlagcCs|�tj|jjd�dS)zk
        A list of flags with unmatched parentheses raises
        L{imap4.IllegalClientResponse}.
        s(invalidN�r�rrrrCrHr,r,r/�&test_arg_flaglistMismatchedParentehses�s
�z>IMAP4ServerParsingTests.test_arg_flaglistMismatchedParentehsescCs,|�tj|jjd�|�tj|jjd�dS)zo
        A list of flags that contains a malformed flag raises
        L{imap4.IllegalClientResponse}.
        s	(first )s(first second)NrFrHr,r,r/�test_arg_flaglistMalformedFlag�s��z6IMAP4ServerParsingTests.test_arg_flaglistMalformedFlagcCs.d}|j�|�\}}|�|�|�||�dS)z�
        A line that does not begin with an open parenthesis (C{(}) is
        parsed as L{None}, and the remainder is the whole line.
        snot (N)rZ	opt_plistrvr;)r>r�Zplist�	remainderr,r,r/�$test_opt_plistMissingOpenParenthesis�s
z<IMAP4ServerParsingTests.test_opt_plistMissingOpenParenthesiscCs.d}|j�|�\}}|�|�|�||�dS)z�
        A line that does not begin with a double quote (C{"}) is
        parsed as L{None}, and the remainder is the whole line.
        snot "N)r�opt_datetimervr;)r>r�ZdtrIr,r,r/�!test_opt_datetimeMissingOpenQuote�s
z9IMAP4ServerParsingTests.test_opt_datetimeMissingOpenQuotecCsd}|�tj|jj|�dS)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�rrrrKr�r,r,r/�"test_opt_datetimeMissingCloseQuote�s
�z:IMAP4ServerParsingTests.test_opt_datetimeMissingCloseQuotecCsd}|�tj|jj|�dS)z�
        A line that contains C{CHARSET} but no character set
        identifier raises L{imap4.IllegalClientResponse}.
        r1N)r�rrr�opt_charsetr�r,r,r/�!test_opt_charsetMissingIdentifier�s
�z9IMAP4ServerParsingTests.test_opt_charsetMissingIdentifiercCs0d}|j�|�\}}|�|d�|�|d�dS)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-8r1N�rrNr;�r>r��
identifierrIr,r,r/�test_opt_charsetEndOfLine�sz1IMAP4ServerParsingTests.test_opt_charsetEndOfLinecCs0d}|j�|�\}}|�|d�|�|d�dS)z�
        A line that has additional data after a C{CHARSET} identifier
        is parsed as that identifier, and the remainder is that
        additional data.
        sCHARSET UTF-8 remainderrPs	remainderNrQrRr,r,r/�test_opt_charsetWithRemainder

sz5IMAP4ServerParsingTests.test_opt_charsetWithRemainderN)+rbrcrdr�rrrrrrrr#r%r&r(r*r+r,r-r.r/r1r2r3r5r7r8r:r;r=r>r?rArBrErGrHrJrLrMrOrTrUr,r,r,r/rOsP


						


rc@speZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�ZdS)�IMAP4ServerSearchTestszS
    Tests for the behavior of the search_* functions in L{imap4.IMAP4Server}.
    cCsDt�|�dg|_dg|_dg|_d|_tddigddd	d�|_dS)
Nz10-Dec-2009z13-Dec-2009z16-Dec-2009rr�zMon, 13 Dec 2009 21:25:10 GMTz13 Dec 2009 00:00:00 GMTr���)rr�earlierQuery�
sameDateQuery�
laterQuery�seqr�r�rHr,r,r/r
s

�zIMAP4ServerSearchTests.setUpcCs<|�|j�|j|j|j��|�|j�|j|j|j��dS)z�
        L{imap4.IMAP4Server.search_SENTBEFORE} returns True if the message date
        is earlier than the query date.
        N)rrZsearch_SENTBEFORErXr[r�r
rZrHr,r,r/�test_searchSentBefore%
s��z,IMAP4ServerSearchTests.test_searchSentBeforecCs^|�|j�dg|j|jd��|�|j�dg|j|jd��|�|j�dg|j|jd��dS)zq
        L{imap4.IMAP4Server.search_UID} returns True if the message UID is in
        the search range.
        r�)r�rWs2:*r�N)rr�
search_UIDr[r�r
rHr,r,r/�test_searchWildcard0
s���z*IMAP4ServerSearchTests.test_searchWildcardcCs"|�|j�dg|j|jd��dS)z�
        L{imap4.IMAP4Server.search_UID} should return True if there is a
        wildcard, because a wildcard means "highest UID in the mailbox".
        s1235:*)rWr�N)r
rr]r[r�rHr,r,r/�test_searchWildcardHigh>
s�z.IMAP4ServerSearchTests.test_searchWildcardHighcCs$t�d�}|�t|�dddg�dS)�|
        L{imap4.IMAP4Server.search_SENTON} returns True if the message date is
        the same as the query date.
        r�r�r�r�N)rr�r;r�)r>�msgsetr,r,r/�test_reversedSearchTermsG
s
z/IMAP4ServerSearchTests.test_reversedSearchTermscCsX|�|j�|j|j|j��|�|j�|j|j|j��|�|j�|j|j|j��dS)r`N)	rrZ
search_SENTONrXr[r�r
rYrZrHr,r,r/�test_searchSentOnP
s���z(IMAP4ServerSearchTests.test_searchSentOncCs<|�|j�|j|j|j��|�|j�|j|j|j��dS)z~
        L{imap4.IMAP4Server.search_SENTSINCE} returns True if the message date
        is later than the query date.
        N)r
rZsearch_SENTSINCErXr[r�rrZrHr,r,r/�test_searchSentSince]
s��z+IMAP4ServerSearchTests.test_searchSentSincecCs�|�|j�dg|jdg|j|j|jd��|�|j�dg|jdg|j|j|jd��|�|j�dg|jdg|j|j|jd��dS)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
rZ	search_ORrXrZr[r�rrHr,r,r/�
test_searchOrh
sH
����
����
����z$IMAP4ServerSearchTests.test_searchOrcCsL|�|j�dg|j|j|jd��|�|j�dg|j|j|jd��dS)z~
        L{imap4.IMAP4Server.search_NOT} returns the negation of the result
        of the expression supplied to it.
        rer�rfN)rrZ
search_NOTrXr[r�r
rZrHr,r,r/�test_searchNot
s

�

�z%IMAP4ServerSearchTests.test_searchNotcCsX|�|j�|j|j|j��|�|j�|j|j|j��|�|j�|j|j|j��dS)z�
        L{imap4.IMAP4Server.search_BEFORE} returns True if the
        internal message date is before the query date.
        N)	rrZ
search_BEFORErXr[r�rYr
rZrHr,r,r/�test_searchBefore�
s���z(IMAP4ServerSearchTests.test_searchBeforecCsX|�|j�|j|j|j��|�|j�|j|j|j��|�|j�|j|j|j��dS)z�
        L{imap4.IMAP4Server.search_ON} returns True if the
        internal message date is the same as the query date.
        N)rrZ	search_ONrXr[r�rYrZrHr,r,r/�
test_searchOn�
s���z$IMAP4ServerSearchTests.test_searchOncCsX|�|j�|j|j|j��|�|j�|j|j|j��|�|j�|j|j|j��dS)z�
        L{imap4.IMAP4Server.search_SINCE} returns True if the
        internal message date is greater than the query date.
        N)	r
rZsearch_SINCErXr[r�rYrrZrHr,r,r/�test_searchSince�
s���z'IMAP4ServerSearchTests.test_searchSinceN)rbrcrdr�rr\r^r_rbrcrdrgrhrirjrkr,r,r,r/rV
s
		



rVc@s&eZdZdZdZddd�Zdd�ZdS)r�z�
    A L{IRealm} for tests.

    @cvar theAccount: An C{Account} instance.  Tests can set this to
        ensure predictable account retrieval.
    Ncs&�r�fdd��_n�fdd��_dS)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.
        cs�jSr+�r�r,r�r,r/r0�
r1z$TestRealm.__init__.<locals>.<lambda>cs�jSr+rlr,rHr,r/r0�
r1N)�_getAccount)r>r�r,)r�r>r/rg�
s
zTestRealm.__init__cGstj|��dd�fS)NcSsdSr+r,r,r,r,r/r0�
r1z)TestRealm.requestAvatar.<locals>.<lambda>)rZIAccountrm)r>ZavatarIdZmindrr,r,r/rQ�
szTestRealm.requestAvatar)N)rbrcrdr�r�rgrQr,r,r,r/r��
s
r�c@s,eZdZeefZddiZdd�Zdd�ZdS)�TestCheckerr��secretcCs2|j|jkr.t�|j|j|j��|j|j�SdSr+)�usernamerar	Z
maybeDeferred�
checkPasswordr��_cbCheck�r>Zcredentialsr,r,r/�requestAvatarId�
s
��zTestChecker.requestAvatarIdcCs|r|St��dSr+r")r>r-rpr,r,r/rr�
szTestChecker._cbCheckN)	rbrcrdr$r%�credentialInterfacesrartrrr,r,r,r/rn�
s�rnc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)S)*�AuthenticatorTestscCsNt�|�t�}td�|_t|�|_|j�t��|j|j	_d|_
|j|_dS)Nr�r)rrr�r�r�rr�r�rnr�
authenticatedrB)r>r�r,r,r/r�
s



zAuthenticatorTests.setUpcCs�ttt�Gdd�dt��}|�}tt|�t�d|i�}|j|_t�}|�	|�|�
|jt�
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@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
z>AuthenticatorTests.test_customChallengers.<locals>.SPECIALAuthcSsdS)N�SPECIALr,rHr,r,r/�getChallengeszKAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.getChallengecSs|�dd�\|_|_dSr�)�splitrp�password�r>�responser,r,r/�setResponseszJAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.setResponsecSsdS�NFr,rHr,r,r/�moreChallengesszMAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.moreChallengescSs|j|_dSr+)r{)r>r{r,r,r/rqszLAuthenticatorTests.test_customChallengers.<locals>.SPECIALAuth.checkPasswordN)rbrcrdryr~r�rqr,r,r,r/�SPECIALAuth�
sr�rx�Connection done.sAUTH=SPECIALs001 AUTHENTICATE SPECIAL
susername passwordr�s"001 OK Authentication successful
N)rrr%�objectrrr�r�r'r�
addCleanuprr
rr�rr�dataReceived�base64�	b64encoderyr;)r>r�Zspecialrr�r,r,r/�test_customChallengers�
s,

�
�
�z)AuthenticatorTests.test_customChallengerscCsZt��}|j|_t�}|�|�|�|jt�d��|�	�|�
d�|�|��d�dS)z_
        An unsupported C{AUTHENTICATE} method results in a negative
        response.
        r�s001 AUTHENTICATE UNKNOWN
s(001 NO AUTHENTICATE method unsupported
N)
rr�r�r'rr�rr
rrr�r;r)r>rr�r,r,r/�test_unsupportedMethod)s
�

�z)AuthenticatorTests.test_unsupportedMethodcsxtj�jjd<t�d�}�j�|�d�j_�fdd�}�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)r�Ncs�j�d�S�Nro�r	�authenticater,rHr,r/r@Isz3AuthenticatorTests.test_missingPortal.<locals>.auths Temporary authentication failure)r�LOGINCredentialsrr/�LOGINAuthenticatorr	�registerAuthenticatorr�r
r�r2r'rr�rrr	r(r)r>�cAuthr@r�r,rHr/�test_missingPortal=s
�z%AuthenticatorTests.test_missingPortalcs�tt�Gdd�dt��}tt�Gdd�dt��}|�}tt|�|�jjd<�j�|���fdd�}�j	�
t|��}|��j
dt|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@s(eZdZdZdd�Zdd�Zdd�ZdS)	zRAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallengesA challenge failurecSst|j��dSr+)r�r�rHr,r,r/ry_sz_AuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.getChallengecSsdS�zw
                Never called.

                @param response: See L{IChallengeResponse.setResponse}
                Nr,r|r,r,r/r~csz^AuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.setResponsecSsdS�z/
                Never called.
                Nr,rHr,r,r/r�kszaAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthChallenge.moreChallengesN�rbrcrdr�ryr~r�r,r,r,r/�ValueErrorAuthChallenge[sr�c@seZdZdd�Zdd�ZdS)zRAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticatorcSsdS)N�ERRORr,rHr,r,r/�getNamesszZAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticator.getNamecSsdS)NsIGNOREDr,)r>�secret�chalr,r,r/�challengeResponsevszdAuthenticatorTests.test_challengerRaisesException.<locals>.ValueErrorAuthenticator.challengeResponseN)rbrcrdr�r�r,r,r,r/�ValueErrorAuthenticatorpsr�r�cs�j�d�Sr�r�r,rHr,r/r@sz?AuthenticatorTests.test_challengerRaisesException.<locals>.authzServer error: r@)rrr�rrrr/r	r�r
r�r2r'rr�r�r<r�rrr	r(r)r>r�r�Zbadr@r�r,rHr/�test_challengerRaisesExceptionTs&
���z1AuthenticatorTests.test_challengerRaisesExceptioncCs�tt�Gdd�dt��}|�}tt|�t��}|j|_||jd<t�}|�	|�|�
|jt�
d��|�d|���|��|�d�|�t�|���|���|��|�d�|�|��d�d	|jd
g��dS)z�
        A client that responds with a challenge that cannot be decoded
        as Base 64 receives an L{IllegalClientResponse}.
        c@s(eZdZdZdd�Zdd�Zdd�ZdS)	zEAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallengesMalformed Response - not base64cSsdS)Ns
SomeChallenger,rHr,r,r/ry�szRAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.getChallengecSsdSr�r,r|r,r,r/r~�szQAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.setResponsecSsdSr�r,rHr,r,r/r��szTAuthenticatorTests.test_authNotBase64.<locals>.NotBase64AuthChallenge.moreChallengesNr�r,r,r,r/�NotBase64AuthChallenge�sr�s	NOTBASE64r�sAUTH=NOTBASE64s001 AUTHENTICATE NOTBASE64
s Not base64
r1s001 NO Authentication failed: r�N)rrr�rrr�r�r/r'rr�rr
rr�rrr�r�r�ryr;rxr�)r>r�Z	notBase64rr�r,r,r/�test_authNotBase64�s6


�
�

��z%AuthenticatorTests.test_authNotBase64cs�t�}t|�}|�j_tj�jjd<}tt|�t�	d�}�j
�|��fdd�}�j�
t|��}|��jd�|��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)r�cs�j�d�Sr�r�r,rHr,r/r@�sz:AuthenticatorTests.test_unhandledCredentials.<locals>.auths+Authentication failed: server misconfigured)r�rrr�rr�r/rrr�r	r�r
r�r2r'rr�rrr	r(r)r>r�r��	loginCredr�r@r*r�r,rHr/�test_unhandledCredentials�s

�z,AuthenticatorTests.test_unhandledCredentialsc
s�Gdd�dt��G�fdd�d�}t�}t|�}|�|��|�j_tj�jjd<}t	t
|�t�d�}�j�
|��fdd�}��fd	d
�}�j�t|��}|��jd�|�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@seZdZdZdS)zKAuthenticatorTests.test_unexpectedLoginFailure.<locals>.UnexpectedExceptionrSNr�r,r,r,r/rT�srTcs$eZdZdZeefZ�fdd�ZdS)zFAuthenticatorTests.test_unexpectedLoginFailure.<locals>.FailingCheckerzz
            A credentials checker whose L{requestAvatarId} method
            raises L{UnexpectedException}.
            cs�d��dS)NzUnexpected error.r,rsrWr,r/rt�szVAuthenticatorTests.test_unexpectedLoginFailure.<locals>.FailingChecker.requestAvatarIdN)rbrcrdr�r$r%rurtr,rWr,r/�FailingChecker�s
�r�r)r�cs�j�d�Sr�r�r,rHr,r/r@sz<AuthenticatorTests.test_unexpectedLoginFailure.<locals>.authcs�������dSr+rZr,r\r,r/�assertUnexpectedExceptionLogged	szWAuthenticatorTests.test_unexpectedLoginFailure.<locals>.assertUnexpectedExceptionLoggeds'Server error: login failed unexpectedly)r`r�rr�rr�rr�r/rrr�r	r�r
r�r2r'rr�rrr	r(r)
r>r�r�r�r�r�r@r�r*r�r,r\r/�test_unexpectedLoginFailure�s(

�z.AuthenticatorTests.test_unexpectedLoginFailurecs�t�jjd<t�d�}�j�|��fdd�}�fdd�}�j�t	|��}|�
t	|��j�|�
�j�j���
�}t�||g�}|��j�S)Nr,r�cs�j�d�Sr�r�r,rHr,r/r@sz,AuthenticatorTests.testCramMD5.<locals>.authcs
d�_dSr��rwr,rHr,r/�authedsz.AuthenticatorTests.testCramMD5.<locals>.authed)r&rr/r�CramMD5ClientAuthenticatorr	r�r
r�r2r�rrrr	r(�_cbTestCramMD5)r>r�r@r�r*rKr�r,rHr/�testCramMD5s
zAuthenticatorTests.testCramMD5cCs$|�|jd�|�|jj|j�dSr��r;rwrrBrDr,r,r/r�'sz!AuthenticatorTests._cbTestCramMD5cs�t�jjd<t�d�}�j�|��fdd�}�fdd�}�fdd�}�j�t	|��}|�
t	|�t	|��|�
�j�j�t
����|g�}|��j�S)	Nr,r�cs�j�d�S�Nsnot the secretr�r,rHr,r/�misauth1sz5AuthenticatorTests.testFailedCramMD5.<locals>.misauthcs
d�_dSr�r�r,rHr,r/r�3sz4AuthenticatorTests.testFailedCramMD5.<locals>.authedcs
d�_dS�N���r�r,rHr,r/�	misauthed5sz7AuthenticatorTests.testFailedCramMD5.<locals>.misauthed)r&rr/rr�r	r�r
r�r2r�rrr	r(r�_cbTestFailedCramMD5�r>r�r�r�r�r*r�r,rHr/�testFailedCramMD5,s
z$AuthenticatorTests.testFailedCramMD5cCs"|�|jd�|�|jjd�dSr�r�rDr,r,r/r�?sz'AuthenticatorTests._cbTestFailedCramMD5cs�tj�jjd<}tt|�t�d�}�j�|��fdd�}�fdd�}�j	�
t|��}|�t|��j
�|��j�j
�t����|g�}|�
�j�S)Nr)r�cs�j�d�Sr�r�r,rHr,r/r@Lsz*AuthenticatorTests.testLOGIN.<locals>.authcs
d�_dSr�r�r,rHr,r/r�Nsz,AuthenticatorTests.testLOGIN.<locals>.authed)rr�rr/rrr�r	r�r
r�r2r�rrr	r(r�_cbTestLOGIN)r>r�r�r@r�r*r�r,rHr/�	testLOGINDs

zAuthenticatorTests.testLOGINcCs$|�|jd�|�|jj|j�dSr�r�rDr,r,r/r�XszAuthenticatorTests._cbTestLOGINcs�tj�jjd<t�d�}�j�|��fdd�}�fdd�}�fdd�}�j�t	|��}|�
t	|�t	|��|�
�j�j�t
����|g�}|��j�S)	Nr)r�cs�j�d�Sr�r�r,rHr,r/r�bsz3AuthenticatorTests.testFailedLOGIN.<locals>.misauthcs
d�_dSr�r�r,rHr,r/r�fsz2AuthenticatorTests.testFailedLOGIN.<locals>.authedcs
d�_dSr�r�r,rHr,r/r�jsz5AuthenticatorTests.testFailedLOGIN.<locals>.misauthed)rr�rr/r�r	r�r
r�r2r�rrr	r(r�_cbTestFailedLOGINr�r,rHr/�testFailedLOGIN]s
z"AuthenticatorTests.testFailedLOGINcCs"|�|jd�|�|jjd�dSr�r�rDr,r,r/r�tsz%AuthenticatorTests._cbTestFailedLOGINcs�tj�jjd<}tt|�t�d�}�j�|��fdd�}�fdd�}�j	�
t|��}|�t|��j
�|��j�j
�t����|g�}|�
�j�S)Nr0r�cs�j�d�Sr�r�r,rHr,r/r@�sz*AuthenticatorTests.testPLAIN.<locals>.authcs
d�_dSr�r�r,rHr,r/r��sz,AuthenticatorTests.testPLAIN.<locals>.authed)r�PLAINCredentialsrr/rr�PLAINAuthenticatorr	r�r
r�r2r�rrr	r(r�_cbTestPLAIN)r>Z	plainCredr�r@r�r*r�r,rHr/�	testPLAINys

zAuthenticatorTests.testPLAINcCs$|�|jd�|�|jj|j�dSr�r�rDr,r,r/r��szAuthenticatorTests._cbTestPLAINcs�tj�jjd<t�d�}�j�|��fdd�}�fdd�}�fdd�}�j�t	|��}|�
t	|�t	|��|�
�j�j�t
����|g�}|��j�S)	Nr0r�cs�j�d�Sr�r�r,rHr,r/r��sz3AuthenticatorTests.testFailedPLAIN.<locals>.misauthcs
d�_dSr�r�r,rHr,r/r��sz2AuthenticatorTests.testFailedPLAIN.<locals>.authedcs
d�_dSr�r�r,rHr,r/r��sz5AuthenticatorTests.testFailedPLAIN.<locals>.misauthed)rr�rr/r�r	r�r
r�r2r�rrr	r(r�_cbTestFailedPLAINr�r,rHr/�testFailedPLAIN�s
z"AuthenticatorTests.testFailedPLAINcCs"|�|jd�|�|jjd�dSr�r�rDr,r,r/r��sz%AuthenticatorTests._cbTestFailedPLAINN)rbrcrdrr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/rv�
s(
378 2rvc@s(eZdZdZdd�Zdd�Zdd�ZdS)	�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}
    cCs>d}d}d}t�|�}|�||�}|�|d|d|�dS)z�
        L{PLAINAuthenticator.challengeResponse} returns challenge strings of
        the form::

            NUL<authn-id>NUL<secret>
        r�ros	challenge�N)rr�r�r;)r>rpr�r�r�r}r,r,r/�#test_authenticatorChallengeResponse�s
z2SASLPLAINTests.test_authenticatorChallengeResponsecCs2t��}|�d�|�|jd�|�|jd�dS)z�
        L{PLAINCredentials.setResponse} parses challenge strings of the
        form::

            NUL<authn-id>NUL<secret>
        stestusersecretr�roN)rr�r~r;rpr{�r>Zcredr,r,r/�test_credentialsSetResponse�s
z*SASLPLAINTests.test_credentialsSetResponsecCsBt��}|�tj|jd�|�tj|jd�|�tj|jd�dS)z�
        L{PLAINCredentials.setResponse} raises L{imap4.IllegalClientResponse}
        when passed a string not of the expected form.
        shelloshelloworldshelloworldZoom!N)rr�r�rr~r�r,r,r/�test_credentialsInvalidResponse�s ���z.SASLPLAINTests.test_credentialsInvalidResponseN)rbrcrdr�r�r�r�r,r,r,r/r��s
r�c@sleZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�ZdS)�UnsolicitedResponseTestscs\�fdd�}�fdd�}�j�t|��}|�t|����j�t����|g�}|��j�S)Ncs�j�dd�Sr9rYr,rHr,r/r:�sz5UnsolicitedResponseTests.testReadWrite.<locals>.logincs�j�d�dSr��rr�r,rHr,r/r��sz8UnsolicitedResponseTests.testReadWrite.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestReadWrite�r>r:r�r*r�r,rHr/�
testReadWrite�sz&UnsolicitedResponseTests.testReadWritecCs|jj}|�|ddgg�dS)Nr�r��r	r�r;�r>rE�Er,r,r/r��sz)UnsolicitedResponseTests._cbTestReadWritecs\�fdd�}�fdd�}�j�t|��}|�t|����j�t����|g�}|��j�S)Ncs�j�dd�Sr9rYr,rHr,r/r:�sz4UnsolicitedResponseTests.testReadOnly.<locals>.logincs�j�d�dSr�r�r,rHr,r/r��sz7UnsolicitedResponseTests.testReadOnly.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestReadOnlyr�r,rHr/�testReadOnly�sz%UnsolicitedResponseTests.testReadOnlycCs|jj}|�|ddgg�dS)Nr�rr�r�r,r,r/r��sz(UnsolicitedResponseTests._cbTestReadOnlycsrddggdgd���fdd�}��fdd�}�j�t|��}|�t|����j�t����|g�}|��j��S)	N�	\Answeredr��\Recent)r�r�r�cs�j�dd�Sr9rYr,rHr,r/r:	sz6UnsolicitedResponseTests.testFlagChange.<locals>.logincs�j���dSr+)rr�r,�r5r>r,r/r�sz9UnsolicitedResponseTests.testFlagChange.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestFlagChanger�r,r�r/�testFlagChanges�z'UnsolicitedResponseTests.testFlagChangecCsJ|jj}dd�|��D�}|jdd�d�|jdd�d�|�||�dS)NcSs g|]}d|d|dig�qS)r�rr�r,)r�rr,r,r/rJsz>UnsolicitedResponseTests._cbTestFlagChange.<locals>.<listcomp>cSs|dSr�r,�r`r,r,r/r0r1z<UnsolicitedResponseTests._cbTestFlagChange.<locals>.<lambda>)�keycSs|dSr�r,r�r,r,r/r0r1)r	r��itemsrKr;)r>rEr5r�Zexpectr,r,r/r�s
z*UnsolicitedResponseTests._cbTestFlagChangecs\�fdd�}�fdd�}�j�t|��}|�t|����j�t����|g�}|��j�S)Ncs�j�dd�Sr9rYr,rHr,r/r:sz7UnsolicitedResponseTests.testNewMessages.<locals>.logincs�j�dd�dS�Nr��rrr,rHr,r/r�sz:UnsolicitedResponseTests.testNewMessages.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestNewMessagesr�r,rHr/�testNewMessagessz(UnsolicitedResponseTests.testNewMessagescCs |jj}|�|dddgg�dS�Nrr�r�r�r,r,r/r�(sz+UnsolicitedResponseTests._cbTestNewMessagescs\�fdd�}�fdd�}�j�t|��}|�t|����j�t����|g�}|��j�S)Ncs�j�dd�Sr9rYr,rHr,r/r:.sz=UnsolicitedResponseTests.testNewRecentMessages.<locals>.logincs�j�dd�dSr�r�r,rHr,r/r�0sz@UnsolicitedResponseTests.testNewRecentMessages.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestNewRecentMessagesr�r,rHr/�testNewRecentMessages-sz.UnsolicitedResponseTests.testNewRecentMessagescCs |jj}|�|dddgg�dSr�r�r�r,r,r/r�9sz1UnsolicitedResponseTests._cbTestNewRecentMessagescs\�fdd�}�fdd�}�j�t|��}|�t|����j�t����|g�}|��j�S)Ncs�j�dd�Sr9rYr,rHr,r/r:?sz@UnsolicitedResponseTests.testNewMessagesAndRecent.<locals>.logincs�j�dd�dS)Nr�r�r�r,rHr,r/r�BszCUnsolicitedResponseTests.testNewMessagesAndRecent.<locals>.loggedIn)	r
r�r2r'rr	r(r�_cbTestNewMessagesAndRecentr�r,rHr/�testNewMessagesAndRecent>sz1UnsolicitedResponseTests.testNewMessagesAndRecentcCs(|jj}|�|dddgdddgg�dS)Nrr�r�r�r�r,r,r/r�Ksz4UnsolicitedResponseTests._cbTestNewMessagesAndRecentN)rbrcrdr�r�r�r�r�r�r�r�r�r�r�r�r,r,r,r/r��s
r�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�ClientCapabilityTestszT
    Tests for issuance of the CAPABILITY command and handling of its response.
    cCs0t�|_t��|_|j�|j�|j�d�dS)zS
        Create an L{imap4.IMAP4Client} connected to a L{StringTransport}.
        s* OK [IMAP4rev1]
N)r'r�rr��protocolrr�rHr,r,r/rUs
zClientCapabilityTests.setUpcs@�jjdd�}�j�d��j�d��fdd�}|�|�|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�ZuseCaches&* CAPABILITY IMAP4rev1 LOGINDISABLED
�0001 OK Capability completed.
cs��|ddd��dS)N)r s
LOGINDISABLEDr#�ZcapabilitiesrHr,r/�gotCapabilitiesgs�z?ClientCapabilityTests.test_simpleAtoms.<locals>.gotCapabilities�r�rr�r��r>ZcapabilitiesResultr�r,rHr/�test_simpleAtoms_s
z&ClientCapabilityTests.test_simpleAtomscs@�jjdd�}�j�d��j�d��fdd�}|�|�|S)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�cs��|dddgd��dS)Nr)r0)r r-r#r�rHr,r/r�s�zAClientCapabilityTests.test_categoryAtoms.<locals>.gotCapabilitiesr�r�r,rHr/�test_categoryAtomsns
z(ClientCapabilityTests.test_categoryAtomscs@�jjdd�}�j�d��j�d��fdd�}|�|�|S)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�cs ��|dddgddgd��dS)N�BAR�FOO)r r�r�r#r�rHr,r/r��s�z>ClientCapabilityTests.test_mixedAtoms.<locals>.gotCapabilitiesr�r�r,rHr/�test_mixedAtoms�s�
z%ClientCapabilityTests.test_mixedAtomsN)rbrcrdr�rr�r�r�r,r,r,r/r�Qs

r�c@s eZdZdZdd�Zdd�ZdS)�StillSimplerClientzH
    An IMAP4 client which keeps track of unsolicited flag changes.
    cCstj�|�i|_dSr+)rr�rgr5rHr,r,r/rg�szStillSimplerClient.__init__cCs|j�|�dSr+)r5rrr,r,r/r��szStillSimplerClient.flagsChangedN)rbrcrdr�rgr�r,r,r,r/r��sr�c@sTeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�ZdS)�HandCraftedTestscspt��t���������d���fdd����fdd����fdd�}��dd�}��d	�|�|�|S)
N�* OK [IMAP4rev1]cs�������dd�dS)Nr�s0003 FETCH 1 (RFC822)�r;rr�rE�r>r�r,r/�cbCheckTransport�s�z>HandCraftedTests.testTrailingLiteral.<locals>.cbCheckTransportcs,��d�}��d���d�|���|S)Nr�s6* 1 FETCH (RFC822 {10}
0123456789
 RFC822.SIZE 10)
s0003 OK FETCH
)�fetchMessager�r��rEr�)r|r�r,r/�cbSelect�s




z6HandCraftedTests.testTrailingLiteral.<locals>.cbSelectcs"��d�}��d�|���|S�Nr��0002 OK SELECT)r�r�r�r�)r|r�r,r/�cbLogin�s


z5HandCraftedTests.testTrailingLiteral.<locals>.cbLogin�blah�0001 OK LOGIN
)r'rr�rr�r:r�r�)r>r�r�r,)r|r�r�r>r�r/�testTrailingLiteral�s



z$HandCraftedTests.testTrailingLiteralcCs�|jj�dd�t�}|j�|�|��|j�d�|�|��d�|��|j�d�|�|��d�|��|j�d�|�	|���|j�d�|�|��d	�|�|jj
d
�|j�t�
d��dS)
z]
        String literals whose data is not immediately available are
        parsed.
        r�r�s01 LOGIN {8}
s+ Ready for 8 octets of text
stestuser {13}
s+ Ready for 13 octets of text
spasswords-test
�01 OK LOGIN succeeded
r@r�N)rr�r�r'rrr�r;rZ	assertNotrCrr
rr�r,r,r/�test_fragmentedStringLiterals�s z.HandCraftedTests.test_fragmentedStringLiteralscCs�ddi|jj_t�}|j�|�|��|j�d�|�|��d�|��|j�d�|�|��d�|�|jj	d�|j�
t�d��dS)	z3
        Empty string literals are parsed.
        r1s01 LOGIN {0}
s+ Ready for 0 octets of text
s{0}
r�r@r�N)
rr�rar'rrr�r;rrCrr
rr�r,r,r/�test_emptyStringLiteral�s
�z(HandCraftedTests.test_emptyStringLiteralcstt��t��������d��fdd�}�fdd�}�fdd�}���fdd	�}|��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�cs��dd�}��d�|S�Nr�r��r:r�r;rr,r/r:s
zRHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.logincs��d�}��d�|Sr��r�r�r;rr,r/r�s

zSHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.selectcsz�jdddgd�}��d���d���d���d���d	���d
���d���d���d���d�|S)
Nr��
HEADER.FIELDS�SUBJECT��
headerTypeZ
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}
sISubject: What you been doing. Order your meds here . ,. handcuff madsen
�0003 OK FETCH completed
��
fetchSpecificr�r;rr,r/�fetchs�









zRHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.fetchcs^�������dd���|dddggdggdddggdggd�����jd	d
gi�dS)Nr��,0003 FETCH 1:* BODY[HEADER.FIELDS (SUBJECT)]rMrrz&Subject: Suprise for your woman...

zKSubject: What you been doing. Order your meds here . ,. handcuff madsen

�r�r�r��\Seen�r;rrr5��res�r|r>r�r,r/r�s�
�
��zQHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponse.<locals>.test�r'r�rr�r�r2�r>r:r�rr�r,rr/�2test_unsolicitedResponseMixedWithSolicitedResponse�s

���zCHandCraftedTests.test_unsolicitedResponseMixedWithSolicitedResponsecs�t��t���������d��fdd�}�fdd�}�fdd�}��fdd	�}|�}|�t|��|�t|��|�|�|S)
zf
        Literals should be recognized even when they are not preceded by
        whitespace.
        r�cs��dd�}��d�|Sr�r�r;�r�r,r/r:>s
zFHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.logincs��d�}��d�|S)N�inboxr�r�r;rr,r/r�Bs

zGHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.selectcs*�jdddgd�}��d���d�|S)Nr�rrrs8* 1 FETCH (BODY[HEADER.FIELDS ({7}
SUBJECT)] "Hello")
rrr;rr,r/rFs��
zFHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.fetchcs:�������dd���|ddddggdggi�dS)Nr�r	r�rMrrZHellor�ryr�r,r/r�Ns��zEHandCraftedTests.test_literalWithoutPrecedingWhitespace.<locals>.test�r'rr�rr�r�r2)r>r:r�rr�r�r,�r�r>r�r/�&test_literalWithoutPrecedingWhitespace3s


z7HandCraftedTests.test_literalWithoutPrecedingWhitespacecspt��t���������d��fdd�}�fdd�}���fdd�}|�}|�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�cs��dd�}��d�|Sr�r�r;rr,r/r:is
z<HandCraftedTests.test_nonIntegerLiteralLength.<locals>.logincs��d�}��d�|Sr�r�r;rr,r/r�ms

z=HandCraftedTests.test_nonIntegerLiteralLength.<locals>.selectcs@�jdddgd��������dd���tj�jd�dS)Nr�rrrr�r	s* 1 FETCH {xyz}
...)rr;rrr�r�IllegalServerResponser�r,rr,r/rqs���z<HandCraftedTests.test_nonIntegerLiteralLength.<locals>.fetchr)r>r:r�rr�r,rr/�test_nonIntegerLiteralLength]s

z-HandCraftedTests.test_nonIntegerLiteralLengthcsrt�}t����|���d��fdd�}�fdd�}�fdd�}��fdd	�}|��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�cs��dd�}��d�|Sr�r�r;rr,r/r:�s
zLHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.logincs��d�}��d�|Sr�r�r;rr,r/r��s

zMHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.selectcs\�jdddgd�}��d���d���d���d���d	���d
���d�|S)Nr�rrrs1* 1 FETCH (BODY[HEADER.FIELDS ("SUBJECT")] {22}
sSubject: subject one
s FLAGS (\Recent))
s?* 2 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS ("SUBJECT")] {22}
sSubject: subject two
rrrr;rr,r/r�s�






zLHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.fetchcsJ��|dddggdggdddggdggd�����jdgdgd��dS)	NrMrrzSubject: subject one
zSubject: subject two
r
r�r)r;r5r
�r|r>r,r/r��s
�
��zKHandCraftedTests.test_flagsChangedInsideFetchSpecificResponse.<locals>.testr)r>r�r:r�rr�r,rr/�,test_flagsChangedInsideFetchSpecificResponse�s


���z=HandCraftedTests.test_flagsChangedInsideFetchSpecificResponsecstt��t��������d��fdd�}�fdd�}�fdd�}���fdd	�}|��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.fetchMessage} is passed to the
        C{flagsChanged} callback.
        r�cs��dd�}��d�|Sr�r�r;rr,r/r:�s
zKHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.logincs��d�}��d�|Sr�r�r;rr,r/r��s

zLHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.selectcsT��d�}��d���d���d���d���d���d���d�|S)	Nr�s* 1 FETCH (RFC822 {24}
sSubject: first subject
s FLAGS (\Seen))
s.* 2 FETCH (FLAGS (\Recent \Seen) RFC822 {25}
sSubject: second subject
rr)r�r�r;rr,r/r�s







zKHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.fetchcsP�������dd���|ddiddid�����jdgddgd��dS)	Nr�s0003 FETCH 1:* (RFC822)r;zSubject: first subject
zSubject: second subject
r
rr�rr
rr,r/r��s���zJHandCraftedTests.test_flagsChangedInsideFetchMessageResponse.<locals>.testrrr,rr/�+test_flagsChangedInsideFetchMessageResponse�s


���z<HandCraftedTests.test_flagsChangedInsideFetchMessageResponsecCs�t�}t��}||_|�|�|�d�t�d�}|�|�|�d�}|�	|t
j�|�d�|�
tj�}|�t|�d�|�|djjdd�|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 Readyr�r�s+ Something bad! and bad
r�rsSomething bad! and bad)r(rr�r�rr�r�r�r��
assertFailurer
rr�r[rr;r�rr�)r>r�r�r�r�Zloggedr,r,r/�-test_authenticationChallengeDecodingException�s 
�



z>HandCraftedTests.test_authenticationChallengeDecodingExceptionN)rbrcrdr�r�r�rrrrrrr,r,r,r/r��s 9*)93r�c@seZdZdZejZdd�ZdS)�PreauthIMAP4ClientMixina
    Mixin for L{unittest.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}.
    cCs0t�|_|��|_|j�|j�|j�d�dS)zm
        Create an IMAP4Client connected to a fake transport and in the
        authenticated state.
        s* PREAUTH Hello unittest
N)r'r��clientProtocolr	rr�rHr,r,r/r s
zPreauthIMAP4ClientMixin.setUpN)rbrcrdr�rr�r rr,r,r,r/rsrc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"S)#�SelectionTestsMixinzl
    Mixin for test cases which defines tests which apply to both I{EXAMINE} and
    I{SELECT} support.
    cCs2t|j|j�d�}|�|j��d|jd�|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.
        Zfooboxs0001 s	 foobox
)rDr	�methodr;r�rr�r>r�r,r,r/�_examineOrSelect1s�z$SelectionTestsMixin._examineOrSelectcGs4|D]}|j�|d�q|j�d|jd�dS)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�s0001 OK [READ-ONLY] s completed
N)r	r�r)r>�linesr�r,r,r/�	_response>s
�zSelectionTestsMixin._responsecCs.|��}|�d�|�|�|�ddd��dS)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�r$r&r;�successResultOfr#r,r,r/�test_existsJs
�zSelectionTestsMixin.test_existscCs$|��}|�d�|�|tj�dS)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�r$r&�failureResultOfrrr#r,r,r/�test_nonIntegerExistsXs
z)SelectionTestsMixin.test_nonIntegerExistscCs.|��}|�d�|�|�|�ddd��dS)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�Nr'r#r,r,r/�test_recentds
�zSelectionTestsMixin.test_recentcCs$|��}|�d�|�|tj�dS)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 RECENTNr*r#r,r,r/�test_nonIntegerRecentrs
z)SelectionTestsMixin.test_nonIntegerRecentcCs.|��}|�d�|�|�|�ddd��dS)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�Nr'r#r,r,r/�test_unseen~s
�zSelectionTestsMixin.test_unseencCs$|��}|�d�|�|tj�dS)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 unseenNr*r#r,r,r/�test_nonIntegerUnseen�s
z)SelectionTestsMixin.test_nonIntegerUnseencCs.|��}|�d�|�|�|�ddd��dS)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�Nr'r#r,r,r/�test_uidvalidity�s
�z$SelectionTestsMixin.test_uidvaliditycCs$|��}|�d�|�|tj�dS)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 validNr*r#r,r,r/�test_nonIntegerUIDVALIDITY�s
z.SelectionTestsMixin.test_nonIntegerUIDVALIDITYcCs.|��}|�d�|�|�|�ddd��dS)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�Nr'r#r,r,r/�test_uidnext�s
�z SelectionTestsMixin.test_uidnextcCs$|��}|�d�|�|tj�dS)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 UIDNr*r#r,r,r/�test_nonIntegerUIDNEXT�s
z*SelectionTestsMixin.test_nonIntegerUIDNEXTcCs.|��}|�d�|�|�|�ddd��dS)�
        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\Flaggedr�rz\Draft)r|r4Nr'r#r,r,r/�
test_flags�s���zSelectionTestsMixin.test_flagscCs.|��}|�d�|�|�|�ddd��dS)r5sN* OK [PERMANENTFLAGS (\Starred)] Just one permanent flag in that list up thereF)z\Starred)r|ZPERMANENTFLAGSNr'r#r,r,r/�test_permanentflags�s���z'SelectionTestsMixin.test_permanentflagscCs,|��}|�d�|�|�|�ddi�dS)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|FNr'r#r,r,r/�test_unrecognizedOk�s��z'SelectionTestsMixin.test_unrecognizedOkcCs,|��}|�d�|�|�|�ddi�dS)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|FNr'r#r,r,r/�test_bareOk�s
�zSelectionTestsMixin.test_bareOkN)rbrcrdr�r$r&r)r,r-r.r/r0r1r2r3r4r6r7r8r9r,r,r,r/r!,s"
r!c@seZdZdZdZdZdS)�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
    r�sEXAMINEN�rbrcrdr�r"rr,r,r,r/r:sr:c@seZdZdZdZdZdS)�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
    r�sSELECTNr;r,r,r,r/r<sr<c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�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
    cCs*|j��}|�|j��d�|j��|S)Ns0001 EXPUNGE
)r	r�r;r�rrr#r,r,r/�_expungeAs

z IMAP4ClientExpungeTests._expungecCs0|D]}|j�td|f��q|j�d�dS)Nz* %s EXPUNGEs0001 OK EXPUNGE COMPLETED)r	r�r)r>ZsequenceNumbersZnumberr,r,r/r&Hsz!IMAP4ClientExpungeTests._responsecCs8|��}|�ddddg�|�|�|�ddddg�dS)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�N)r>r&r;r(r#r,r,r/�test_expungeNsz$IMAP4ClientExpungeTests.test_expungecCs,|��}|�ddddg�|�|tj�dS)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�N)r>r&r+rrr#r,r,r/�test_nonIntegerExpungedYsz/IMAP4ClientExpungeTests.test_nonIntegerExpungedN)rbrcrdr�r>r&r?r@r,r,r,r/r=3s
r=c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�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
    cCs*|j�tjdd��}|�|j��d�|S)NZABCDEF)r?s0001 SEARCH (TEXT "ABCDEF")
)r	�searchrrvr;r�rr#r,r,r/�_searchws�zIMAP4ClientSearchTests._searchc	Cs0|j�dtd�tt|����|j�d�dS)Ns	* SEARCH � s0001 OK SEARCH completed)r	r�rrx�mapr�)r>ZmessageNumbersr,r,r/r&~s�z IMAP4ClientSearchTests._responsecCs4|��}|�dddg�|�|�|�dddg�dS)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)rCr&r;r(r#r,r,r/�test_search�sz"IMAP4ClientSearchTests.test_searchcCs*|��}|�dddg�|�|tj�dS)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)rCr&r+rrr#r,r,r/�test_nonIntegerFound�sz+IMAP4ClientSearchTests.test_nonIntegerFoundN)rbrcrdr�rCr&rFrGr,r,r,r/rAes
rAc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&S)'�IMAP4ClientFetchTestszV
    Tests for the L{IMAP4Client.fetch} method.

    See RFC 3501, section 6.4.5.
    cCs�|j�d�}|�|j��d�|j�d�|j�d�|j�d�|j�d�|j�d�|�|�|�dd	idd
iddiddid
��dS)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=Z22Z23Z24Z25)r�r�r�r�N)r	�fetchUIDr;r�rr�r(r#r,r,r/�
test_fetchUID�s��z#IMAP4ClientFetchTests.test_fetchUIDcCsH|j�d�}|�|j��d�|j�d�|j�d�|�|tj�dS)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�s0001 FETCH 1 (UID)
s* foo FETCH (UID 22)rMN�	r	rNr;r�rr�r+rrr#r,r,r/�test_fetchUIDNonIntegerFound�s
z2IMAP4ClientFetchTests.test_fetchUIDNonIntegerFoundcCs`|j�d�}|�|j��d�|j�d�|j�d�|j�d�|j�d�|�|tj�dS)z�
        If the server responds with an incomplete I{FETCH} response line, the
        L{Deferred} returned by L{IMAP4Client.fetchUID} fails with
        L{IllegalServerResponse}.
        rIrJrKs* 3 FETCH (UID)rLrMNrPr#r,r,r/�test_incompleteFetchUIDResponse�sz5IMAP4ClientFetchTests.test_incompleteFetchUIDResponsecCsT|j�d�}|�|j��d�|j�d�|j�d�|�|�|�dddii�dS)	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.
        �3s0001 FETCH 3 (RFC822.TEXT)
s&* 3 FETCH (RFC822.TEXT "Message text")rMr�r:zMessage textN)r	�	fetchBodyr;r�rr�r(r#r,r,r/�test_fetchBody�s�
�z$IMAP4ClientFetchTests.test_fetchBodycCsX|j�d�}|�|j��d�|j�d�|j�d�|�|�|�ddgdggi�dS)	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")rMr�rM�	Some bodyN�r	rr;r�rr�r(r#r,r,r/�test_fetchSpecific�s��z(IMAP4ClientFetchTests.test_fetchSpecificcCs\|jjddd�}|�|j��d�|j�d�|j�d�|�|�|�ddgd	ggi�d
S)z�
        L{IMAP4Client.fetchSpecific} issues a I{BODY.PEEK[]} command if passed
        C{True} for the C{peek} parameter.
        �6T)rRs0001 FETCH 6 BODY.PEEK[]
s* 6 FETCH (BODY[] "Some body")rMr�rMrXNrYr#r,r,r/�test_fetchSpecificPeek�s��z,IMAP4ClientFetchTests.test_fetchSpecificPeekcCs^|jjddd�}|�|j��d�|j�d�|j�d�|�|�|�ddd	gd
ggi�dS)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.
        rV)r�r�r���headerNumbers0001 FETCH 7 BODY[1.2.3]
s#* 7 FETCH (BODY[1.2.3] "Some body")rMr�rMz1.2.3rXNrYr#r,r,r/�test_fetchSpecificNumbereds��z0IMAP4ClientFetchTests.test_fetchSpecificNumberedcCs^|jjddd�}|�|j��d�|j�d�|j�d�|�|�|�dddgd	ggi�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")rMr�rMrXNrYr#r,r,r/�test_fetchSpecificTexts��z,IMAP4ClientFetchTests.test_fetchSpecificTextcCs`|jjdddd�}|�|j��d�|j�d�|j�d�|�|�|�dd	d
gdggi�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.
        �4rar�)rr^s0001 FETCH 4 BODY[7.TEXT]
s$* 4 FETCH (BODY[7.TEXT] "Some body")rMr�rMz7.TEXTrXNrYr#r,r,r/�test_fetchSpecificNumberedText(s��z4IMAP4ClientFetchTests.test_fetchSpecificNumberedTextcCsL|jjddd�}|�|j��d�|j�d�|j�d�|�|tj�dS)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`rarbrcs* 8 FETCH (BODY[TEXT])rMN�	r	rr;r�rr�r+rrr#r,r,r/�(test_incompleteFetchSpecificTextResponse:s�z>IMAP4ClientFetchTests.test_incompleteFetchSpecificTextResponsecCs^|jjddd�}|�|j��d�|j�d�|j�d�|�|�|�dddgd	ggi�d
S)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`rWrbs0001 FETCH 8 BODY[MIME]
s"* 8 FETCH (BODY[MIME] "Some body")rMr�rMrXNrYr#r,r,r/�test_fetchSpecificMIMEIs��z,IMAP4ClientFetchTests.test_fetchSpecificMIMEcCsd|jjddddd�}|�|j��d�|j�d�|j�d�|�|�|�d	d
dgddggi�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.
        �9rar�r�)r�offsetZlengths0001 FETCH 9 BODY[TEXT]<17.3>
s * 9 FETCH (BODY[TEXT]<17> "foo")rMr�rMz<17>r�NrYr#r,r,r/�test_fetchSpecificPartialZs ���z/IMAP4ClientFetchTests.test_fetchSpecificPartialcCsL|jjddd�}|�|j��d�|j�d�|j�d�|�|tj�dS)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`rarbrcs* 8 FETCH (BODY[TEXT]<17>)rMNrgr#r,r,r/�+test_incompleteFetchSpecificPartialResponsems�zAIMAP4ClientFetchTests.test_incompleteFetchSpecificPartialResponsecCsX|j�d�}|�|j��d�|j�d�|j�d�|�|�|�ddgdggi�dS)	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).
        rVrWs&* 7 FETCH (BODY[] "<html>test</html>")rMr�rMz<html>test</html>NrYr#r,r,r/�test_fetchSpecificHTML|s��z,IMAP4ClientFetchTests.test_fetchSpecificHTMLcCs||jjd|d�}|�|j��d|�d�d�|j�d|�d�d�|j�d�|�|�|�d	d
|ggdggi�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}
        Z10rbs0001 FETCH 10 BODY[r@s ()]
s* 10 FETCH (BODY[s ()] "")rMr�rMr�N)r	rr;r�rr<r�r()r>Zsectionr�r,r,r/�&assertFetchSpecificFieldsWithEmptyList�s���z<IMAP4ClientFetchTests.assertFetchSpecificFieldsWithEmptyListcCs|�d�dS)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.
        rN�rorHr,r,r/�,test_fetchSpecificHeaderFieldsWithoutHeaders�s	zBIMAP4ClientFetchTests.test_fetchSpecificHeaderFieldsWithoutHeaderscCs|�d�dS)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.
        zHEADER.FIELDS.NOTNrprHr,r,r/�/test_fetchSpecificHeaderFieldsNotWithoutHeaders�s	zEIMAP4ClientFetchTests.test_fetchSpecificHeaderFieldsNotWithoutHeaderscCs^|jjddd�}|�|j��d�|j�d�|j�d�|�|�|�dddgd	ggi�d
S)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.
        Z11ZHEADERrbs0001 FETCH 11 BODY[HEADER]
sJ* 11 FETCH (BODY[HEADER] "From: someone@localhost
Subject: Some subject")rMr�rMz.From: someone@localhost
Subject: Some subjectNrYr#r,r,r/�test_fetchSpecificHeader�s����z.IMAP4ClientFetchTests.test_fetchSpecificHeaderN)rbrcrdr�rOrQrRrUrZr\r_rdrfrhrirlrmrnrorqrrrsr,r,r,r/rH�s&
rHc@steZdZdZeZdd�Zdd�Zdd�Zdd	�Z	d
d�Z
dd
�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�ZdS)�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
    cCsht|j|�ddd�}|�|j��d|d�|j�d�|j�d�|�|�|�dd	d
dgii�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.
        rS��\ReadrF�
0001 STORE 3 � (\Read \Seen)
s* 3 FETCH (FLAGS (\Read \Seen))�0001 OK STORE completedr�r4rvrN�rDr	r;r�rr�r(�r>r"�itemr�r,r,r/�
_flagsTest�s	
��z IMAP4ClientStoreTests._flagsTestcCsPt|j|�ddd�}|�|j��d|d�|j�d�|�|�|�i�dS)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.
        rSruTrwrxryNrzr{r,r,r/�_flagsSilentlyTest�s	
�z(IMAP4ClientStoreTests._flagsSilentlyTestcCstt|j|�ddd�}|�|j��d|d�|j�d�|j�d�|�|�|�i�|�|jjdd	d
gi�dS)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.
        rSruTrwrxs* 2 FETCH (FLAGS (\Read \Seen))ryr�rvrN)rDr	r;r�rr�r(r5r{r,r,r/�%_flagsSilentlyWithUnsolicitedDataTest
s

�z;IMAP4ClientStoreTests._flagsSilentlyWithUnsolicitedDataTestcCs|�dd�dS)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.
        �setFlagsr.N�r}rHr,r,r/�
test_setFlagssz#IMAP4ClientStoreTests.test_setFlagscCs|�dd�dS)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~rHr,r,r/�test_setFlagsSilently)sz+IMAP4ClientStoreTests.test_setFlagsSilentlycCs|�dd�dS)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�rrHr,r,r/�(test_setFlagsSilentlyWithUnsolicitedData3sz>IMAP4ClientStoreTests.test_setFlagsSilentlyWithUnsolicitedDatacCs|�dd�dS)z{
        L{IMAP4Client.addFlags} is like L{IMAP4Client.setFlags}, but sends
        I{+FLAGS} instead of I{FLAGS}.
        �addFlagss+FLAGSNr�rHr,r,r/�
test_addFlags<sz#IMAP4ClientStoreTests.test_addFlagscCs|�dd�dS)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�rHr,r,r/�test_addFlagsSilentlyDsz+IMAP4ClientStoreTests.test_addFlagsSilentlycCs|�dd�dS)z�
        L{IMAP4Client.addFlags} behaves like L{IMAP4Client.setFlags} when used
        in silent mode and unsolicited data is received.
        r�r�Nr�rHr,r,r/�(test_addFlagsSilentlyWithUnsolicitedDataMsz>IMAP4ClientStoreTests.test_addFlagsSilentlyWithUnsolicitedDatacCs|�dd�dS)z~
        L{IMAP4Client.removeFlags} is like L{IMAP4Client.setFlags}, but sends
        I{-FLAGS} instead of I{FLAGS}.
        �removeFlagss-FLAGSNr�rHr,r,r/�test_removeFlagsUsz&IMAP4ClientStoreTests.test_removeFlagscCs|�dd�dS)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�rHr,r,r/�test_removeFlagsSilently]sz.IMAP4ClientStoreTests.test_removeFlagsSilentlycCs|�dd�dS)z�
        L{IMAP4Client.removeFlags} behaves like L{IMAP4Client.setFlags} when
        used in silent mode and unsolicited data is received.
        r�r�Nr�rHr,r,r/�+test_removeFlagsSilentlyWithUnsolicitedDatafszAIMAP4ClientStoreTests.test_removeFlagsSilentlyWithUnsolicitedDataN)rbrcrdr�r�r r}r~rr�r�r�r�r�r�r�r�r�r,r,r,r/rt�s

			rtc@s eZdZdZdd�Zdd�ZdS)�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}
    cCs6|�t|jjdd�}|�t|�dttdg���dS)z�
        Only allow sending the C{STATUS} names defined in RFC 3501.

        @see: U{https://tools.ietf.org/html/rfc3501#section-5.1.2}
        rEzIMPOSSIBLE?!zUnknown names: N)r�r�r	r�r;r�r��set)r>�excr,r,r/�testUnknownName~s�
�z&IMAP4ClientStatusTests.testUnknownNamecCsJ|j�dd�}|�|j��d�|j�d�|j�d�|�|tj�dS)z�
        C{STATUS} names that cannot be decoded as ASCII cause the
        status Deferred to fail with L{IllegalServerResponse}
        Zblurdybloopr�s$0001 STATUS blurdybloop (MESSAGES)
s?* STATUS blurdybloop (MESSAGES 1 ASCIINAME "OK" NOT�ASCII "NO")s0001 OK STATUS completedN)	r	r�r;r�rr�r+rrr#r,r,r/�testUndecodableName�s��z*IMAP4ClientStatusTests.testUndecodableNameN)rbrcrdr�r�r�r,r,r,r/r�os
r�c@s4eZdZdZeZdd�Zdd�Zdd�Zdd	�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
    cCsJ|jjdddd�}|�|j��d�|j�d�|�|�|�gdf�dS)	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��MEETINGFru�0001 COPY 2:3 MEETING
�0001 OK COPY completed�OK COPY completedN�r	�copyr;r�rr�r(r#r,r,r/�test_copySequenceNumbers�s��z-IMAP4ClientCopyTests.test_copySequenceNumberscCsJ|jjdddd�}|�|j��d�|j�d�|�|�|�jtj	�dS)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�Frur��0001 BAD COPY failedN�
r	r�r;r�rr�r[r+rrr#r,r,r/�test_copySequenceNumbersFails�s��z2IMAP4ClientCopyTests.test_copySequenceNumbersFailscCsJ|jjdddd�}|�|j��d�|j�d�|�|�|�gdf�dS)	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�Tru�0001 UID COPY 2:3 MEETING
r�r�Nr�r#r,r,r/�
test_copyUIDs�s��z"IMAP4ClientCopyTests.test_copyUIDscCsJ|jjdddd�}|�|j��d�|j�d�|�|�|�jtj	�dS)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�Trur�r�Nr�r#r,r,r/�test_copyUIDsFails�s��z'IMAP4ClientCopyTests.test_copyUIDsFailsN)
rbrcrdr�r�r r�r�r�r�r,r,r,r/r��s	r�c@seZdZdZdZdd�ZdS)�FakeyServerr�NcCsdSr+r,rHr,r,r/�sendServerGreeting�szFakeyServer.sendServerGreeting)rbrcrdrC�timeoutr�r,r,r,r/r��sr�c@sXeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�ZdS)r�)r�r5r��_bodyr>cCs2||_||_||_t|�|_||_||_||_dSr+)r�r5r�r��sizer�r>�subpart)r>r�r5r�r{r>r�r,r,r/rgs
zFakeyMessage.__init__cGs||f|_|jSr+)Zgot_headersr�)r>rVr�r,r,r/�
getHeaderss
zFakeyMessage.getHeaderscCs|jSr+r�rHr,r,r/r�szFakeyMessage.getFlagscCs|jSr+)r�rHr,r,r/�getInternalDateszFakeyMessage.getInternalDatecCs
t|j�Sr+)rr�rHr,r,r/�getBodyFileszFakeyMessage.getBodyFilecCs|jSr+)r�rHr,r,r/�getSize!szFakeyMessage.getSizecCs|jSr+rurHr,r,r/r�%szFakeyMessage.getUIDcCs
|jdk	Sr+)r�rHr,r,r/�isMultipart)szFakeyMessage.isMultipartcCs||_|j|Sr+)Zgot_subpartr�)r>rXr,r,r/�
getSubPart-szFakeyMessage.getSubPartN)
rbrcrdZshowAttributesrgr�r�r�r�r�r�r�r�r,r,r,r/r�s
r�c@sFeZdZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Z	dd
d�Z
dS)�
NewStoreTestsNcCs@d|_|_t��|_d|j_||j_t��|_	t
|j	�|_dS�Nr�)�received_messages�received_uidrr�rrCr�r	rr
r�r	rHr,r,r/r7s

zNewStoreTests.setUpcCsdSr+r,�r>rr,r,r/r�AszNewStoreTests.addListenercCsdSr+r,r�r,r,r/r�EszNewStoreTests.removeListenercOs||f|_|jSr+)�	storeArgsr})r>r�r�r,r,r/�storeIs
zNewStoreTests.storecsl�fdd�}�fdd�}�j�t|���|���j���j��fdd�}tj�j�j	dd�}|�|�|S)	Ncs���j�j�j�j�Sr+)�functionr�r5�silentr>r,rHr,r/r
Osz+NewStoreTests._storeWork.<locals>.connectedcs
|�_dSr+ry��RrHr,r/r-Rsz(NewStoreTests._storeWork.<locals>.resultcs$���j�j����j�j�dSr+)r;r-rr��expectedArgsr�rHr,r/r+[sz'NewStoreTests._storeWork.<locals>.checkF�Znoisy�
r
r�r2rr'rr�loopbackTCPrr	)r>r
r-r+r�r,rHr/�
_storeWorkNs���
zNewStoreTests._storeWorkrcCs�|jj|_d|_dddg|_d|_||_dddgdddgdddgd�|_ddddgiddddgiddddgid�|_t	�
�}|�d�|�d	�|�d
�|dddgdfddif|_|�
�S)
Nz1,5,9z\Az\B�CF)r�r�r�r4r�r�r�rr>)r	r�r�r�r5r�r>r}rrrr�r�r�)r>r>r�r,r,r/�testSetFlagscs&
��


zNewStoreTests.testSetFlags)r)rbrcrdr-r�rr�r�r�r�r�r,r,r,r/r�3s
r�c@sXeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�ZdS)�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

Cs�d}d}d}d}d}d}d}t|d|d	|d
|||d�dd
|dd�}t�|�}	|�||d|ddg|||t|�g|	�dS)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�ru�
content-id�content-description�content-transfer-encodingr,r1rvN�charsetr�y�r�r�getBodyStructurer;r��
r>r{�major�minorr�rS�descriptionr�r��	structurer,r,r/�test_singlePart�sD
�����
��z%GetBodyStructureTests.test_singlePartc
Cs�tiddddd�}t�|�}|dd�\}}|�d|�|�d|�tddiddddd�}t�|�}|dd�\}}|�d|�|�d|�tddiddddd�}	t�|	�}
|
dd�\}}|�d|�|�d|�dS)	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,r1rvNr�rur��
)r�rr��assertIs)
r>ZmissingZmissingContentTypeStructureZmissingMajorZmissingMinorrTZemptyContentTypeStructureZ
emptyMajorZ
emptyMinor�newlineZnewlineContentTypeStructureZnewlineMajorZnewlineMinorr,r,r/�test_emptyContentType�s


z+GetBodyStructureTests.test_emptyContentTypecCsLtddiddddd�}t�|�}|dd�\}}|�|d�|�|d�dS)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}.
        ru�mainr,r1rvNr�)r�rr�r;r�)r>r�Z
mainStructureZ	mainMajorZ	mainMinorr,r,r/�test_onlyMajorContentType�s

z/GetBodyStructureTests.test_onlyMajorContentTypecCs�d}d}d}d}d}d}d}d}t|d	|d
|d||||dd
dd�dd|dd�}	tj|	dd�}
|�||d|ddg|||t|�|dddddggd
dg|
�dS)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�Zabcdefabcdefrr�r�zattachment; name=foo; size=bar�frZFrance�rur�r�r��content-md5�content-disposition�content-language�content-locationr,r�rvNT�Zextendedr�rr��
attachmentr�r�r�r�r�)r>r{r�r�r�rSr�r�Zmd5r�r�r,r,r/�test_singlePartExtended�sV
����
���z-GetBodyStructureTests.test_singlePartExtendedc
Csbd}d}d}td|d|idd|dd	�}tj|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�rurr,r1rvNTr�r�)r>r�r�r{r�r�r,r,r/�test_singlePartWithMissing�s*
����z0GetBodyStructureTests.test_singlePartWithMissingc
Cs�d}d}d}d}d}d}d}t|d|d	|d
|||d�dd
|dd�}t�|�}	|�||d|ddg|||t|�t|���g|	�dS)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
r?r�r�r�r�r�rr�r�r�r,r1rvNr�rr�)r�rr�r;r�rr�r,r,r/�
test_textPart�sF
�����

��z#GetBodyStructureTests.test_textPartc
Cs�d}d}d}d}d}d}d}t|d|d	|d
dd|||d
�dd|dd�}tddidddd|g�}	t�|	�}
|�dddddddt�|�t�|�dg
|
�dS)z�
        For a I{message/rfc822} message, the common basic fields are followed
        by information about the contained message.
        r�r?r�r�r�r�r�rr�r�zAlice <alice@example.com>zBob <bob@example.com>)rurorqr�r�r�r,r�rvNru�message/rfc822r1r�r<rr�)r�rr�r;ZgetEnvelope)r>r{r�r�r�rSr�r�r��	containerr�r,r,r/�test_rfc822Messages\
�����
��
��z(GetBodyStructureTests.test_rfc822MessagecCsttddddd�dddd	d
�}tddiddd
dd
�}tddidddd||g�}|�t�|�t�|�dgt�|��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.
        zimage/jpeg; x=yr�r�r�r�r,r1�hello worldrvNruztext/plain; charset=us-ascii�
some stuff�Azmultipart/related�+�related�r�r;rr��r>Z
oneSubPartZanotherSubPartr�r,r,r/�test_multiPart1sN��������z$GetBodyStructureTests.test_multiPartc	Cs�tddddd�dddd	d
�}tddiddd
dd
�}tddddd�dddd||g�}|�tj|dd�tj|dd�dddgdddggddgtj|dd��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.
        simage/jpeg; x=yssome kind of ids
great justicesmaximum)�content-types
content-idscontent-descriptionscontent-transfer-encodingr,r1r�rvNr�stext/plain; charset=us-asciir�r�zmultipart/related; foo=bar�esZSpainzattachment; name=monkeys)rur�r�r�r�Tr�r�r�r�r�r��monkeysr�r�r,r,r/�test_multiPartExtendedMsZ������
��z,GetBodyStructureTests.test_multiPartExtendedN)
rbrcrdr�r�r�r�r�r�r�r�r�r�r,r,r,r/r�|s
!!r�c@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�ZdSdd�Z	dd�Z
dTdd�Zdd�Zdd�Z
e�ejd�Zze�ejd�Wnejk
r�de
_YnXe�eje�dUdd�Zdd�ZdVdd �Zd!d"�ZdWd#d$�ZdXd%d&�Zd'd(�ZdYd)d*�Zd+d,�ZdZd-d.�Zd/d0�Zd1d2�Zd[d3d4�Z d5d6�Z!d\d7d8�Z"d9d:�Z#d]d;d<�Z$d=d>�Z%d?d@�Z&dAdB�Z'd^dCdD�Z(dEdF�Z)d_dGdH�Z*dIdJ�Z+d`dKdL�Z,dMdN�Z-dadOdP�Z.dQdR�Z/dS)b�
NewFetchTestscCsFd|_|_d|_t��|_d|j_||j_t�	�|_
t|j
�|_dSr�)
r�r�r-rr�rrCr�r	rr
r�r	rHr,r,r/rps

zNewFetchTests.setUpcCsdSr+r,r�r,r,r/r�{szNewFetchTests.addListenercCsdSr+r,r�r,r,r/r�szNewFetchTests.removeListenercCs&||_||_tttt|j��|j��Sr+)r�r��iterr�rr��msgObjs�r>r�r>r,r,r/r�szNewFetchTests.fetchcs��r:ttt�j���j�D]\}}t|����j|d<q�fdd�}�j���fdd���|���j	��
�j�tj
�j�jdd�}|��fdd��|S)	Nr=cs
|�_dSr+ryr�rHr,r/r-�sz(NewFetchTests._fetchWork.<locals>.resultcs���j��Sr+�r�r�r$�r>r>r,r/r0�r1z*NewFetchTests._fetchWork.<locals>.<lambda>Fr�cs���j�j�Sr+�r;r-r�rrHr,r/r0�r1)r�rr�r�r�r�rr
r�rr'rrr�rr	)r>r>r�r�r-r�r,rr/�
_fetchWork�s���zNewFetchTests._fetchWorkc	sn�fdd��_d�_tiddddd�tiddddd�tiddddd�g�_d	d
id	did	did
��_��d�S)Ncs�j�|�Sr+�r	rN)r��urHr,r/r0�r1z,NewFetchTests.testFetchUID.<locals>.<lambda>rVr,r1r����u'r=Z12345Z999Z10101)rr�r�r)r�r�r�r�rrrHr,rHr/�testFetchUID�s��zNewFetchTests.testFetchUIDrcCsl|jj|_d|_tidddgdddd�tidddgdddd�g|_ddddgiddddgid	�|_|�|�S)
NrjZFlagAZFlagBz\FlagCr1�1�r�r4�rr�)r	Z
fetchFlagsr�r�r�r�rrrr,r,r/�testFetchFlags�s&
����zNewFetchTests.testFetchFlagscCs
|�d�Sr�)rrHr,r,r/�testFetchFlagsUID�szNewFetchTests.testFetchFlagsUIDc
Cs�|jj|_d|_tiddddd�tiddddd�tidddd	d�tidd
ddd�g|_dd
iddiddiddid�|_|�|�S)NZ13r,sFri, 02 Nov 2003 21:25:10 GMTr1i�ZsThu, 29 Dec 2013 11:31:52 EST�esMon, 10 Mar 1992 02:44:30 CST��sSat, 11 Jan 2000 14:40:24 PSTi/r6z02-Nov-2003 21:25:10 +0000z29-Dec-2013 11:31:52 -0500z10-Mar-1992 02:44:30 -0600z11-Jan-2000 14:40:24 -0800)rr�r�r�)r	ZfetchInternalDater�r�r�r�rrrr,r,r/�testFetchInternalDate�s
��z#NewFetchTests.testFetchInternalDatecCs
|�d�Sr�)rrHr,r,r/�testFetchInternalDateUID�sz&NewFetchTests.testFetchInternalDateUIDcCs8t�tjd�}t�tjd�|�tjtj|�|�d�S)zC
        The month name in the date is locale independent.
        N�
es_AR.UTF8r�)�locale�	setlocale�LC_ALLr�r)r>�
currentLocaler,r,r/�'test_fetchInternalDateLocaleIndependent�sz5NewFetchTests.test_fetchInternalDateLocaleIndependentNrz'The es_AR.UTF8 locale is not installed.cCs�|jj|_d|_tdddddd�dd	d	d
d�g|_ddddddd
dggddd
dggddd
dggddddggddddg
ii|_|�|�S)NZ15zuser@domainzresu@domainZthursdayzit is a messagezid-id-id-yayaya)rorqr�rsz
message-idr,r1ixrr3rUZdomainZresu)r	Z
fetchEnveloper�r�r�r�rrrr,r,r/�testFetchEnvelope�s>
���
���
zNewFetchTests.testFetchEnvelopecCs
|�d�Sr�)rrHr,r,r/�testFetchEnvelopeUIDsz"NewFetchTests.testFetchEnvelopeUIDcCsx|jj|_d|_tdddddddd	d
�ddd
dd�g|_ddddddddgdddddddddggdd	gii|_|�|�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!�8BITZabcdef123456zattachment; filename=monkeysr�zhttp://example.com/monkeysr�r,r��Body
Text
Goes
Here
�Nrr?r?�plainr�rr��thing�20rer��filenamer��r	ZfetchBodyStructurer�r�r�r�rrrr,r,r/�test_fetchBodyStructuresB
�	�


�
z%NewFetchTests.test_fetchBodyStructurecCs
|�d�S)z�
        If passed C{True} for the C{uid} argument, C{fetchBodyStructure} can
        also issue a I{UID FETCH BODYSTRUCTURE} command.
        r�)r&rHr,r,r/�testFetchBodyStructureUID)sz'NewFetchTests.testFetchBodyStructureUIDcCs�|jj|_d|_tdddddddd	d
�ddd
dd�}tdddd�dddd|g�g|_ddddddddgddddddddgdd	gddd gdddgii|_|�|�S)!z�
        L{IMAP4Client.fetchBodyStructure} can also parse the response to a
        I{FETCH BODYSTRUCTURE} command for a multipart message.
        rrrrrr�Z123456abcdefZinlinezouter space)rur�r�r�r�r�r�r�r,r1rr Nzmultipart/mixed; boundary="xyz"ZenZnearby)rur�r�rr?r?r!r�rr�r"r#re�mixed�boundaryZxyzr%)r>r>ZinnerMessager,r,r/� test_fetchBodyStructureMultipart1s`
�	�
����
z.NewFetchTests.test_fetchBodyStructureMultipartc
Cs`|jj|_d|_tiddddtddiddddd�g�g|_d	d
dddddddgii|_|�|�S)N�21r,r1�Yea whatever�fru�	image/jpg�Body Body BodyrrM�12�r	ZfetchSimplifiedBodyr�r�r�r�rrrr,r,r/�testFetchSimplifiedBodyQs
����z%NewFetchTests.testFetchSimplifiedBodycCs
|�d�Sr�)r2rHr,r,r/�testFetchSimplifiedBodyUIDbsz(NewFetchTests.testFetchSimplifiedBodyUIDc
CsR|jj|_d|_tddiddddd�g|_dd	d
ddddddd
gii|_|�|�S)Nr+rurtr,r1r,r-rrMr?r!r0r�r1rr,r,r/�testFetchSimplifiedBodyTextfs$
����z)NewFetchTests.testFetchSimplifiedBodyTextcCs
|�d�Sr�)r4rHr,r,r/�testFetchSimplifiedBodyTextUIDvsz,NewFetchTests.testFetchSimplifiedBodyTextUIDcCs�|jj|_d|_tddiddddtddidd	d
dd�g�g|_ddd
dddddddddddggdddggddddddg
dddddddgdg
ii|_|�|�S)Nr+rur�r,r1r,r-r.r�r/rrMr�r<r0r�ZjpgZ14r�r1rr,r,r/�testFetchSimplifiedBodyRFC822zsJ
��
�����z+NewFetchTests.testFetchSimplifiedBodyRFC822cCs
|�d�Sr�)r6rHr,r,r/� testFetchSimplifiedBodyRFC822UID�sz.NewFetchTests.testFetchSimplifiedBodyRFC822UIDcCs�|jj|_d|_tddiddddd�tdd	iddd
dd�g}tddidd
dd|�}tddidd
dd|g�}|g|_ddddddddddgddddddddgdgdgii|_|�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+rurtr,sdatesStuffr
Nr�sThingsi�~r�r1s
Irrelevantr�zmultipart/mixedsRootOfírrMr?r!�5r�Zhtmlr[�alternativer(Fr1)r>Zsinglesr9r(r,r,r/�!test_fetchSimplifiedBodyMultipart�s\
���
�����z/NewFetchTests.test_fetchSimplifiedBodyMultipartcCsB|jj|_d|_tddiddddd�g|_dd	d
ii|_|�|�S)Nz1,3,7,10101rU�Valuer,r1sBODY TEXT
�[rr;zHeader: Value

BODY TEXT
)r	r�r�r�r�r�rrrr,r,r/�testFetchMessage�s
��zNewFetchTests.testFetchMessagecCs
|�d�Sr�)r=rHr,r,r/�testFetchMessageUID�sz!NewFetchTests.testFetchMessageUIDcCsX|jj|_d|_tddd�ddddd�g|_tt�ddd���}dd	|ii|_	|�
|�S)
Nz9,6,2ZV1ZV2)ZH1ZH2r,r1�crr8)r	ZfetchHeadersr�r�r�r�rrrrr)r>r>r�r,r,r/�testFetchHeaders�s
���zNewFetchTests.testFetchHeaderscCs
|�d�Sr�)r@rHr,r,r/�testFetchHeadersUID�sz!NewFetchTests.testFetchHeadersUIDcCsB|jj|_d|_tddiddddd�g|_dd	d
ii|_|�|�S)Nz
1,2,3,4,5,6,7rUr;r,r�sBody goes here
�rr:zBody goes here
)r	rTr�r�r�r�rrrr,r,r/�
testFetchBody�s
��zNewFetchTests.testFetchBodycCs
|�d�Sr�)rCrHr,r,r/�testFetchBodyUID�szNewFetchTests.testFetchBodyUIDc	s*�jj�_d�_d}d}d}t�}d|d<d|d<d	|d
<d|d<t�}d
|d
<d|d<t�}d|d
<d|d<t|dd|dt|dd|dd�t|dd|dd�g�g�_dddgdggi�_�fdd�}�j�	�fdd���j�	|��j�	�j
��j��j�t
j�j�jdd�}|�	�fdd��|S)zT
        Test the server's handling of requests for specific body sections.
        r�r�r�r�rnrorprqrrrsr�rur�rtr�r�r,NrvrrMz&Contained body message text.  Squarge.cs
|�_dSr+ryr�rHr,r/r-sz0NewFetchTests.testFetchBodyParts.<locals>.resultcs�j�jdd�S)Nr�r]rr$rHr,r/r0r1z2NewFetchTests.testFetchBodyParts.<locals>.<lambda>Fr�cs���j�j�Sr+r�ZignrHr,r/r0r1�r	rr�r�rr�r�rr
r�rr'rrr�r)	r>r�r�r�r�r�r�r-r�r,rHr/�testFetchBodyParts�sN
���
�z NewFetchTests.testFetchBodyPartscs��jj�_d�_dg�d}t�}d|d<d|d<d|d	<d
|d<t|dd
|dd
�g�_dddgdggi�_�fdd�}�j�	��fdd���j�	|��j�	�j
��j��j�t
j�j�jdd�}|�	�fdd��|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�sDA bodyrnrorprqrrrsrtrur,NrvrrMzDA bodycs
|�_dSr+ryr�rHr,r/r-8sz>NewFetchTests.test_fetchBodyPartOfNonMultipart.<locals>.resultcs�j�j�d�S)Nr]rr$��partsr>r,r/r0<r1z@NewFetchTests.test_fetchBodyPartOfNonMultipart.<locals>.<lambda>Fr�cs���j�j�Sr+rrErHr,r/r0Br1rF)r>r�r�r-r�r,rHr/� test_fetchBodyPartOfNonMultipart#s8
��z.NewFetchTests.test_fetchBodyPartOfNonMultipartcCs>|jj|_d|_tiddddd�g|_dddii|_|�|�S)	Nz	1:100,2:*r,r1sxxxxxxxxxxxxxxxxxxxxrvrr9r#)r	Z	fetchSizer�r�r�r�rrrr,r,r/�
testFetchSizeFs
��zNewFetchTests.testFetchSizecCs
|�d�Sr�)rKrHr,r,r/�testFetchSizeUIDRszNewFetchTests.testFetchSizeUIDcCs�|jj|_d|_tiddddd�tidddd	d�g|_d
ddgd
ddddddggdddggddddddg
dddddddgd�dddgdddddddggdddggddddddg
dddddddgd�d�|_|�|�S)Nz1,3)�\XYZ�\YZX�Abcs%Sun, 25 Jul 2010 06:20:30 -0400 (EDT)sxyzxyzi�)�\One�\Two�ThreesMon, 14 Apr 2003 19:43:44 -0400sabcabcabcabcr�rMrNrOz25-Jul-2010 06:20:30 -0400r[)r4r6r9r3rMrPrQrRz14-Apr-2003 19:43:44 -0400r0r)r	Z	fetchFullr�r�r�r�rrrr,r,r/�
testFetchFullVs:
���	&�&��zNewFetchTests.testFetchFullcCs
|�d�Sr�)rSrHr,r,r/�testFetchFullUIDpszNewFetchTests.testFetchFullUIDcCs�|jj|_d|_tiddddd�tiddddd�g|_dddddggdddggddddddg
d	d
gd�dddddggdddggddddddg
d	dgd�d
�|_|�|�S)Nz1,2:3r,sMon, 14 Apr 2003 19:43:44 +0400sLalalarsTue, 15 Apr 2003 19:43:44 +0200sAlalali�Nr[z14-Apr-2003 19:43:44 +0400)r3r9r6r4z15-Apr-2003 19:43:44 +0200r)r	ZfetchAllr�r�r�r�rrrr,r,r/�testFetchAllts2
���&�&��
zNewFetchTests.testFetchAllcCs
|�d�Sr�)rUrHr,r,r/�testFetchAllUID�szNewFetchTests.testFetchAllUIDcCsD|jj|_d|_tiddddd�g|_ddgdd	d
�i|_|�|�S)Nr�)�\Xs19 Mar 2003 19:22:21 -0500r1r�rrWz19-Mar-2003 19:22:21 -0500�0)r4r6r9)r	Z	fetchFastr�r�r�r�rrrr,r,r/�
testFetchFast�s
���zNewFetchTests.testFetchFastcCs
|�d�Sr�)rYrHr,r,r/�testFetchFastUID�szNewFetchTests.testFetchFastUID)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)0rbrcrdrr�r�rrr	rr
rrrrrrr�Error�skiprrr&r'r*r2r3r4r5r6r7r:r=r>r@rArCrDrGrJrKrLrSrTrUrVrYrZr,r,r,r/r�os\

�



 


0


*#



r�c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"S)#�DefaultSearchTestszz
    Test the behavior of the server's SEARCH implementation, particularly in
    the face of unhandled search terms.
    cCs�t��|_d|j_||j_t��|_t|j�|_	t
iddddd�t
iddddd�t
iddddd�t
iddddd�t
iddddd�g|_dS)	Nr�r,r1rrr�i!Ni"N)rr�rrCr�r	rr
r�r	r�r�rHr,r,r/r�s

�zDefaultSearchTests.setUpcCs tttdt|j�d�|j��S)zW
        Pretend to be a mailbox and let C{self.server} lookup messages on me.
        r�)r�r�rr�r�r�r,r,r/r�szDefaultSearchTests.fetchcsZ��fdd�}�j�t|��}��fdd�}|�|�|��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.
        cs�j���Sr+�r	rBr,��
queryTermsr>r,r/rB�sz8DefaultSearchTests._messageSetSearchTest.<locals>.searchcs��|��dSr+r#r�)�expectedMessagesr>r,r/�searched�sz:DefaultSearchTests._messageSetSearchTest.<locals>.searched)r
r�r2rr'rr)r>r`rarBr�rbr,)rar`r>r/�_messageSetSearchTest�s

z(DefaultSearchTests._messageSetSearchTestcCs|�ddg�S)z�
        Test that a search which starts with a message set properly limits
        the search results to messages in that set.
        r�r��rcrHr,r,r/�test_searchMessageSet�sz(DefaultSearchTests.test_searchMessageSetcCs|�dddddg�S)zv
        If the search filter ends with a star, all the message from the
        starting point are returned.
        z2:*r�r�r�r�rdrHr,r,r/�test_searchMessageSetWithStar�sz0DefaultSearchTests.test_searchMessageSetWithStarcCs|�dddddg�S)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�r�r�rdrHr,r,r/�"test_searchMessageSetWithStarFirst�sz5DefaultSearchTests.test_searchMessageSetWithStarFirstcCs|�dddddg�S)z�
        If the search filter ends with a star, all the message from the
        starting point are returned (also for the SEARCH UID case).
        zUID 10000:*r�r�r�r�rdrHr,r,r/� test_searchMessageSetUIDWithStar�sz3DefaultSearchTests.test_searchMessageSetUIDWithStarcCs|�dddddg�S)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).
        zUID *:10000r�r�r�r�rdrHr,r,r/�%test_searchMessageSetUIDWithStarFirst�sz8DefaultSearchTests.test_searchMessageSetUIDWithStarFirstcCs|�ddg�S)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.
        zUID 30000:*r�rdrHr,r,r/�,test_searchMessageSetUIDWithStarAndHighStart�sz?DefaultSearchTests.test_searchMessageSetUIDWithStarAndHighStartcCs|�ddg�S)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�rdrHr,r,r/�test_searchMessageSetWithListsz0DefaultSearchTests.test_searchMessageSetWithListcCs|�dddg�S)z�
        If the search filter contains an I{OR} term, all messages
        which match either subexpression are returned.
        zOR 1 2r�r�rdrHr,r,r/rgsz DefaultSearchTests.test_searchOrcCs|�dddddg�S)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�r�r�rdrHr,r,r/�test_searchOrMessageSetsz*DefaultSearchTests.test_searchOrMessageSetcCs|�dddddg�S)z�
        If the search filter contains a I{NOT} term, all messages
        which do not match the subexpression are returned.
        zNOT 3r�r�r�r�rdrHr,r,r/rh!sz!DefaultSearchTests.test_searchNotcCs|�ddg�S)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.
        zNOT 2:*r�rdrHr,r,r/�test_searchNotMessageSet)sz+DefaultSearchTests.test_searchNotMessageSetcCs|�ddg�S)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.
        z2:* 3r�rdrHr,r,r/�test_searchAndMessageSet3sz+DefaultSearchTests.test_searchAndMessageSetcs^d���fdd�}�j�t|��}��|tj�}�fdd�}|�|�|��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.
        �FOOcs�j���Sr+r^r,r_r,r/rBCsz=DefaultSearchTests.test_searchInvalidCriteria.<locals>.searchcsL�jj���jj����tj�}��t|�d���t	d�t	|��dS)��
            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�rr[rr�r;r�r��r�rrHr,r/�
errorReceivedIs�zDDefaultSearchTests.test_searchInvalidCriteria.<locals>.errorReceived�	r
r�r2rrrr'rr�r>rBr�rsr,r_r/�test_searchInvalidCriteria<s
z-DefaultSearchTests.test_searchInvalidCriteriaN)rbrcrdr�rrrcrerfrgrhrirjrkrgrlrhrmrnrvr,r,r,r/r]�s"	

	r]c@s`eZdZdd�Zdd�Zdd�ZeZdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zdd�Zdd�Z
dS)�FetchSearchStoreTestscCsXd|_|_d|_d|_d|_d|_t��|_d|j_	||j_
t��|_
t|j
�|_dSr�)rr-�server_received_query�server_received_uid�server_received_parts�server_received_messagesrr�rrCr�r	rr
r�r	rHr,r,r/rds

zFetchSearchStoreTests.setUpcCs&|dgkrt�d��||_||_|jS)Nr�z"FOO is not a valid search criteria)rr�rxryr)r>rxr>r,r,r/rBrs


zFetchSearchStoreTests.searchcOsdSr+r,)r>r�r�r,r,r/r�|sz!FetchSearchStoreTests.addListenercsn��fdd�}�fdd�}�j�t|���|���j���j��fdd�}tj�j�j	dd�}|�|�|S)	Ncs�jj�j�d�S)Nru)r	rBrxr,rr,r/rB�sz1FetchSearchStoreTests._searchWork.<locals>.searchcs
|�_dSr+ryr�rHr,r/r-�sz1FetchSearchStoreTests._searchWork.<locals>.resultcsR���j�jk����j�j����j�j���t��j�	d���j
�dS)N�charmap)rr-rr;r>ryrr)rxr<rxr�rHr,r/r+�s�z0FetchSearchStoreTests._searchWork.<locals>.checkFr�r�)r>r>rBr-r+r�r,rr/�_searchWork�s���
z!FetchSearchStoreTests._searchWorkcCs>t�tjdd�tjddd��|_dddd	g|_d
|_|�d
�S)N�rsZ	substring�rS���rtrsr�r�r�r�r)rrwrvrxrr>r}rHr,r,r/�
testSearch�s
�z FetchSearchStoreTests.testSearchcCs<t�tjdd�tjddd��|_d|_dddg|_|�d�S)	Nr~rr�r�r�r�r�r�)rrwrvrxr>rr}rHr,r,r/�
testUIDSearch�s
�z#FetchSearchStoreTests.testUIDSearchc	CsPz|j|dWSttfk
r6|j|dYStk
rJYdSXdS)Nr=r�r�)rr��
IndexError�KeyError�r>r�r,r,r/r��szFetchSearchStoreTests.getUIDcCs||_t|�|_|jSr+)ryr�r{rr�r,r,r/r�s
zFetchSearchStoreTests.fetchcs`�fdd�}�j�t|���|���j���j��fdd�}tj�j�j	dd�}|�|�|S)Ncs
|�_dSr+ryr�rHr,r/r-�sz0FetchSearchStoreTests._fetchWork.<locals>.resultcs����j�jk��jo �j���jo0�j���jrX�j��D]\}}t|�|d<qB��	�j�j���	�j�j
���	�j�j���	t��j
�t��j��dS)Nr=)rr-rrIrKrzr>r�r�r;ryrr�r�r{)rE�k�vrHr,r/r+�s
�z/FetchSearchStoreTests._fetchWork.<locals>.checkFr�r�)r>rr-r+r�r,rHr/r�s���
z FetchSearchStoreTests._fetchWorkcs^d���fdd�}�j�t|��}��|tj�}�fdd�}|�|�|��j����|S)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.
        rocs�j���Sr+r^r,�rxr>r,r/rB�sz6FetchSearchStoreTests.test_invalidTerm.<locals>.searchcsL�jj���jj����tj�}��t|�d���t	d�t	|��dS)rpr�s1SEARCH failed: FOO is not a valid search criteriaNrqrrrHr,r/rs�s�z=FetchSearchStoreTests.test_invalidTerm.<locals>.errorReceivedrtrur,r�r/�test_invalidTerm�s
z&FetchSearchStoreTests.test_invalidTermN)rbrcrdrrBr�r�r}r�r�r�rrr�r,r,r,r/rwbs


	rwc@seZdZdd�Zdd�ZdS)�FakeMailboxcCs
g|_dSr+rfrHr,r,r/rgszFakeMailbox.__init__cCs|j�|||f�t�d�Sr+)r�rhr	r)r>r{r5r�r,r,r/r�
szFakeMailbox.addMessageN)rbrcrdrgr�r,r,r,r/r�sr�c@s$eZdZdd�Zdd�Zdd�ZdS)�FeaturefulMessagecCsdS)Nr5r,rHr,r,r/r�szFeaturefulMessage.getFlagscCsdS)Nr7r,rHr,r,r/r�sz!FeaturefulMessage.getInternalDatecCstd�S)N�openrrHr,r,r/r�szFeaturefulMessage.openN)rbrcrdr�r�r�r,r,r,r/r�sr�c@seZdZdd�Zdd�ZdS)�MessageCopierMailboxcCs
g|_dSr+)�msgsrHr,r,r/rg!szMessageCopierMailbox.__init__cCs|j�|�t|j�Sr+)r�rhr�r�r,r,r/r�%szMessageCopierMailbox.copyN)rbrcrdrgr�r,r,r,r/r�sr�c@s$eZdZdd�Zdd�Zdd�ZdS)�CopyWorkerTestscsHt��}|j}t��|dd�tdd�D�d��}��fdd�}|�|�S)NcSsg|]}|t�f�qSr,)r�r�r,r,r/rJ:sz9CopyWorkerTests.testFeaturefulMessage.<locals>.<listcomp>r�r�rcsh�jD]8}��|d��d���|dd���|dd�q|D]\}}��|���|d�qDdS)Nrr�r�r5r�r7)r�r;rLr
)r�r�r�r-�r�r>r,r/�cbCopy<s

z5CopyWorkerTests.testFeaturefulMessage.<locals>.cbCopy)rr��_IMAP4Server__cbCopyr�rr��r>rr.r�r�r,r�r/�testFeaturefulMessage,s

z%CopyWorkerTests.testFeaturefulMessagecsbt��}|j}t��dd�tdd�D�}|dd�ttdd�|�D�d��}��fdd�}|�|�S)	Nc	Ss2g|]*}tdt|�idddt|�|dd��qS)zHeader-Counterr,�DatesBody r�N)r�r�rr�r,r,r/rJPs�
�z;CopyWorkerTests.testUnfeaturefulMessage.<locals>.<listcomp>r�r�cSsg|]}|�qSr,r,�r�Zimr,r,r/rJVsrcs�g}�jD]6}|�|d�����|dd���|dd�q
|��dd�tdd�D�}|����||�|D]\}}��|���|d�qvdS)	Nrr�r,r�r�cSs$g|]}dt|�dt|��qS)sHeader-Counter: s	

Body )rr�r,r,r/rJ`szKCopyWorkerTests.testUnfeaturefulMessage.<locals>.cbCopy.<locals>.<listcomp>r�)r�rhrLr;rKrr
)r��seenr�Zexpr�r-r�r,r/r�Xs

z7CopyWorkerTests.testUnfeaturefulMessage.<locals>.cbCopy)rr�r�r�rr�r�)r>rr.r�r�r�r,r�r/�testUnfeaturefulMessageIs�"z'CopyWorkerTests.testUnfeaturefulMessagecsdt��}|j}t��dd�tdd�D��|dd�ttdd���D�d��}���fdd�}|�|�S)	NcSsg|]
}t��qSr,)r�r�r,r,r/rJrsz5CopyWorkerTests.testMessageCopier.<locals>.<listcomp>r�r�cSsg|]}|�qSr,r,r�r,r,r/rJssstagc	sH��|ttdgdtdd����t��j�D]\}}��||�q.dS)Nr�r�r�)r;r�r�rr�rw)r�Zorigrr�r�r�r>r,r/r�us"z1CopyWorkerTests.testMessageCopier.<locals>.cbCopy)rr�r�r�rr�r�r�r,r�r/�testMessageCopierks"z!CopyWorkerTests.testMessageCopierN)rbrcrdr�r�r�r,r,r,r/r�+s"r�c@sheZdZeoe�Zeoe�Zdd�Zdd�Zdd�Z	dd�Z
d	d
�Zdd�Zd
d�Z
dd�Zdd�ZdS)�TLSTestscCstj|j|jdd�S)NFr�)rr�rr	rHr,r,r/r�szTLSTests.loopbackc	s�tj�d�g���fdd�}��fdd�}��fdd�}��fdd	�}��fd
d�}d�j_|||||g��D]}�j�t|��qp�j��j	�j
����fd
d�}���}|�|�|S)Nrcs��d��j�dd�Sr9)rhr	r:r,��calledr>r,r/r:�s
z)TLSTests.testAPileOfThings.<locals>.logincs��d��j�dd�S)Nr�%)rhr	r�r,r�r,r/r��s
z(TLSTests.testAPileOfThings.<locals>.listcs��d��j�dd�S)Nrr�)rhr	r�r,r�r,r/r��s
z*TLSTests.testAPileOfThings.<locals>.statuscs��d��j�d�S)Nr)rhr	r�r,r�r,r/r��s
z+TLSTests.testAPileOfThings.<locals>.examinecs��d��j��Sr+)rhr	r3r,r�r,r/r3�s
z*TLSTests.testAPileOfThings.<locals>.logoutTcs8���jjd����jjd���t��t���dSr�)r;r�
startedTLSr	r�r��r��methodsr>r,r/r+�sz)TLSTests.testAPileOfThings.<locals>.check)r�r�rqr	ZrequireTransportSecurityr
r�r2r�rrr)	r>r:r�r�r�r3r"r+r�r,r�r/�testAPileOfThings�s 
zTLSTests.testAPileOfThingscs��jj�dd�g��j�t�d���j��fdd����fdd����j	���j
���j���
�}|���fdd��|S)Nr�r�cs�j�d�S)Nr�r�r$rHr,r/r0�r1z)TLSTests.testLoginLogin.<locals>.<lambda>cs
�j��Sr+)r	r3r$rHr,r/r0�r1cs��t��d�Sr�)r;r�r�r>Zsuccessr,r/r0�r1)rr�r�r	r�rr�r
r�rhrr'rrr#r,r�r/�testLoginLogin�s"
�
����zTLSTests.testLoginLogincsjg��j�t�jj���fdd�}�j�|��j��j����}|���fdd��t�|�jg�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.
        cs��tj��jj��dSr+)r
rZ
ISSLTransport�
providedByr	r�r�rHr,r/�checkSecure�s�z6TLSTests.startTLSAndAssertSession.<locals>.checkSecurecs
����Sr+)r
rr�r,r/r0�r1z3TLSTests.startTLSAndAssertSession.<locals>.<lambda>)	r
r�r2r	�startTLSrhrr	r()r>r�r�r,r�r/�startTLSAndAssertSession�sz!TLSTests.startTLSAndAssertSessioncCs(|��}|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.
        )r�r
r�rr'r)r>�disconnectedr,r,r/�
test_startTLS�szTLSTests.test_startTLScCsnGdd�dt�}||j|jd�|_|��}|j�t|jj��|j�|j	d�|j�|j
�|j�|j�|S)z]
        A server that receives a second C{STARTTLS} sends a C{NO}
        response.
        c@seZdZdd�ZdS)z:TLSTests.test_doubleSTARTTLS.<locals>.DoubleSTARTTLSClientcSs |jst�|�S|�t�d��S)NsSTARTTLS)r�r�r�r�rr�rHr,r,r/r��s
zCTLSTests.test_doubleSTARTTLS.<locals>.DoubleSTARTTLSClient.startTLSN)rbrcrdr�r,r,r,r/�DoubleSTARTTLSClient�sr�rsTLS already negotiated)r�r
rr	r�r�r2r�r'rrr)r>r�r�r,r,r/�test_doubleSTARTTLS�s�zTLSTests.test_doubleSTARTTLScsltjtjd��j_tj�fdd��}�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)r0c3s<�j��V}��d|���d|d���d|d�dS)Nr-r)r0)r	rr�r�rHr,r/�assertLOGINandPLAINszJTLSTests.test_startTLSWithExistingChallengers.<locals>.assertLOGINandPLAIN)rr�r�rr/r	r�r
r�r2r�rr'r)r>r�r�r,rHr/�$test_startTLSWithExistingChallengers�s�
z-TLSTests.test_startTLSWithExistingChallengerscs`dd��j_�j��fdd���j��jd��j��j��j��j�t�	��
��jg�S)z|
        A client that attempts to log in before issuing the
        C{STARTTLS} command receives a C{NO} response.
        cSst�gdf�S)NzOK Begin TLS negotiation now)r	rr,r,r,r/r0s�z3TLSTests.test_loginBeforeSTARTTLS.<locals>.<lambda>cs�j�dd�S)NswrongstimerYr$rHr,r/r0r1s!LOGIN is disabled before STARTTLS)r	r�r
r�r'rrrr	r(rrHr,rHr/�test_loginBeforeSTARTTLSs
��z!TLSTests.test_loginBeforeSTARTTLScs|g��fdd�}�j�|��j��fdd���j��fdd���j��j��j��j���fdd�}����|�S)Ncsd�j_dSr)rZcanStartTLSrErHr,r/�breakServerTLS-sz3TLSTests.testFailedStartTLS.<locals>.breakServerTLScs
�j��Sr+)r	r�rErHr,r/r01r1z-TLSTests.testFailedStartTLS.<locals>.<lambda>cs��|�tj��Sr+)rhrrr)r)r�r,r/r03r1cs �������dtj�dSr�)r
rwrrr��r�r>r,r/r+7s
z*TLSTests.testFailedStartTLS.<locals>.check)r
r�r'rrr)r>r�r+r,r�r/�testFailedStartTLS+s
�zTLSTests.testFailedStartTLSN)rbrcrdr*rr)rrr�r�r�r�r�r�r�r�r,r,r,r/r�~s

#r�c@s eZdZdZdZdZdd�ZdS)�SlowMailboxr�NcCs*t��}|�|j|jd�|j�d�|S)Nr,)r	r�	callLater�howSlowr��
fetchDeferred)r>r�r>r�r,r,r/rEszSlowMailbox.fetch)rbrcrdr�r�r�rr,r,r,r/r�>sr�c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
S)�TimeoutTestscspt��d�j_d�j_�j�j_d�_���fdd�}�fdd���j�t	|��}|�
�j�t�
|���g�S)z{
        The *client* has a timeout mechanism which will close connections that
        are inactive for a period.
        Tr�Ncs&�j�dd�}��d�|���|S)Nr�r�r�)r	r:�advancer'r;�r|r>�timedOutr,r/r:Zs

z.TimeoutTests.test_serverTimeout.<locals>.logincs��d�|�tj�dSr+)rrr
�TimeoutErrorrrHr,r/r�`s
z1TimeoutTests.test_serverTimeout.<locals>.timedOut)r
rr�r	r�r�ror
r�r2r'rr	r(r)r>r:r�r,r�r/�test_serverTimeoutOs
zTimeoutTests.test_serverTimeoutcsZt���j�j_�fdd�}��fdd�}�j�t|��}|�t|��t�|���g�S)z4
        The server times out a connection.
        cs�j�dd�Sr9rYr,rHr,r/r:psz/TimeoutTests.test_serverTimesOut.<locals>.logincs���jjd�dS�Nr��r�rZPOSTAUTH_TIMEOUTr,rr,r/�
expireTimessz4TimeoutTests.test_serverTimesOut.<locals>.expireTime)	r
r�rr
r�r2r	r(r)r>r:r�r�r,rr/�test_serverTimesOutis
z TimeoutTests.test_serverTimesOutcs���tjdt�tj�d�tjjd���t����t	���j
�j_
�fdd�}�fdd�}��fdd	�}��fd
d�}�fd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-TESTcs�j�dd�Sr9rYr,rHr,r/r:�sz7TimeoutTests.test_serverUnselectsMailbox.<locals>.logincs�j�d�S�Nr�rtr,rHr,r/r��sz8TimeoutTests.test_serverUnselectsMailbox.<locals>.selectcs����jj�dSr+)r�rr�r,�r�r>r,r/�	assertSet�sz;TimeoutTests.test_serverUnselectsMailbox.<locals>.assertSetcs���jjd�dSr�r�r,rr,r/r��sz<TimeoutTests.test_serverUnselectsMailbox.<locals>.expireTimecs���jj�dSr+)rrr�r,rHr,r/�assertUnset�sz=TimeoutTests.test_serverUnselectsMailbox.<locals>.assertUnset)r�r�r�r�rqr}rrr�r
r�rr
r�r2r	r(r)r>r:r�r�r�r�r�r,�r|r�r>r/�test_serverUnselectsMailboxs&
�
z(TimeoutTests.test_serverUnselectsMailboxcs�tj�d�tjjd�tt��t���j�j_�fdd�}�fdd�}��fdd�}��fd	d
�}��fdd�}�j	�
t|��}|�
t|��|�
t|��|�
t|��|�
t|��t�
|���g�S)
zi
        The server closes the selected, closeable mailbox when timing
        out a connection.
        r�r�cs�j�dd�Sr9rYr,rHr,r/r:�sz?TimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.logincs�j�d�Sr�rtr,rHr,r/r��sz@TimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.selectcs���j�dSr+)rr�r,r�r,r/�assertMailboxOpen�szKTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.assertMailboxOpencs���jjd�dSr�r�r,rr,r/r��szDTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.expireTimecs���j�dSr+)r
r�r,r�r,r/�assertMailboxClosed�szMTimeoutTests.test_serverTimesOutAndClosesMailbox.<locals>.assertMailboxClosed)r�r�rqr}rrr
r�rr
r�r2r	r(r)r>r:r�r�r�r�r�r,r�r/�#test_serverTimesOutAndClosesMailbox�s 

z0TimeoutTests.test_serverTimesOutAndClosesMailboxcs�t���jt_t��t_�j�j_ttj_	tj�
d��j�d��fdd�}�fdd�}�fdd�}�fd	d
�}�fdd�}tj�|��j
�t|��}|�t|��|�t|��|�t|��|��j�|��j�t�|���g�}|S)
zM
        The connection timeout does not take effect during fetches.
        r�r�cs�j�dd�Sr9rYr,rHr,r/r:�sz7TimeoutTests.test_longFetchDoesntTimeout.<locals>.logincs�j�d��j�d�S)Nr�r�)r�
setTimeoutr	r�r,rHr,r/r��sz8TimeoutTests.test_longFetchDoesntTimeout.<locals>.selectcs�j�d�S)Nr�rr,rHr,r/r�sz7TimeoutTests.test_longFetchDoesntTimeout.<locals>.fetchcs���jjd�dS)Nr�)r�rrCr,rHr,r/�stillConnected�sz@TimeoutTests.test_longFetchDoesntTimeout.<locals>.stillConnectedcstd�D]}��d�qdS)Nr�g�?)rr�)rEr�rr,r/�	cbAdvance�sz;TimeoutTests.test_longFetchDoesntTimeout.<locals>.cbAdvance)r
r�r�r	rr�rr�r�r�rqr�r�r
r2rr'rr(r)r>r:r�rr�r�r*r�r,rr/�test_longFetchDoesntTimeout�s*

z(TimeoutTests.test_longFetchDoesntTimeoutcs�t�}t�}|j|_|j|j_|j�|�g�|jj���fdd�|j_|�dg|jjdgd�|�	���|�d|jjdg�|�
��dS)z{
        The *server* has a timeout mechanism which will close connections that
        are inactive for a period.
        cs��d��|�fdSr�)rh)�reason�ZconnLostZlostr,r/r0r1z<TimeoutTests.test_idleClientDoesDisconnect.<locals>.<lambda>gg@r�g@N)r
r(rr�r�rrZpumpZtimeOutrr
)r>r|r�r,r�r/�test_idleClientDoesDisconnect�s
z*TimeoutTests.test_idleClientDoesDisconnectN)	rbrcrdr�r�r�r�r�r�r,r,r,r/r�Ms)'*r�c@seZdZdd�ZdS)�DisconnectionTestscCsBt��}t�}|�|�|�|�dd�tj�}|�t�d��|S)Nr�zexample.com�Connection closed)	rr�r(rrr:r
rr)r>r|�tr�r,r,r/�"testClientDisconnectFailsDeferredss
z5DisconnectionTests.testClientDisconnectFailsDeferredsN)rbrcrdr�r,r,r,r/r�sr�c@s eZdZdZdd�Zdd�ZdS)�SynchronousMailboxzb
    Trivial, in-memory mailbox implementation which can produce a message
    synchronously.
    cCs
||_dSr+r�)r>r�r,r,r/rg$szSynchronousMailbox.__init__ccs.|rtd��|D]}||j|dfVqdS)NzCannot handle uid requests.r�)�AssertionErrorr�)r>rar>r�r,r,r/r(szSynchronousMailbox.fetchN)rbrcrdr�rgrr,r,r,r/r�sr�c	@s|eZdZdZeigdddd�eigdddd�eigdddd�gZdd�Zd	d
�Zdd�fd
d�Zdd�Z	dd�Z
dd�ZdS)�PipeliningTestszM
    Tests for various aspects of the IMAP4 server's pipelining support.
    r1r�Nr��2cCsVg|_t�|_t�dd|j�|_|j�|j�t|j	�}d|j_
||j_|j��dSr�)
�	iteratorsr'r�rr��iterateInReactorrrr�r�rCr�r)r>r�r,r,r/r9s
zPipeliningTests.setUpcCst��}|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	rr�rh)r>�iteratorr�r,r,r/r�Js	z PipeliningTests.iterateInReactorcCsdSr�r,r,r,r,r/r0Xr1zPipeliningTests.<lambda>cCsR|jrN|�rN|jddD]}|jjr|jj��qq|j�d�d�d�qdS)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}.
        rr�N)r�r�Zproducerrjr�r�)r>�asLongAs�er,r,r/�flushPendingXs

zPipeliningTests.flushPendingcCs|j�t�t����dSr+rrHr,r,r/rjszPipeliningTests.tearDowncCs�|j�d�|��|�|j��d�dtdt|j	d�
����f�dtdt|j	d�
����f�d	td
t|j	d�
����f�g��dS)
z�
        Test that pipelined FETCH commands which can be responded to
        synchronously are responded to correctly.
        s901 FETCH 1 BODY[]
02 FETCH 2 BODY[]
03 FETCH 3 BODY[]
r1�* 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)rr�r�r;r�rrxrrr�r�rLrHr,r,r/�test_synchronousFetchns6���������z%PipeliningTests.test_synchronousFetchcCs�|j�d�t�ttdddg��}|j|d�|�|j�	�d�
dtdt|j
d�����f�g��|j��|jjdd	�|�|j�	��|��|�|j�	�d�
d
dtdt|j
d
�����f�g��dS)z�
        When a server status change occurs during an ongoing FETCH
        command, the server status is buffered until the FETCH
        completes.
        s01 FETCH 1,2 BODY[]
TF)r�r1r�z{5}


%sr)r�r�s* [READ-WRITE]
r�r�N)rr��	functools�partial�nextr�r�r;r�rrxrrr�r�rLrr�r)r>Ztwicer,r,r/�test_bufferedServerStatus�s:�����
���z)PipeliningTests.test_bufferedServerStatus)rbrcrdr�r�r�rr�r�rr�r�r,r,r,r/r�/s�$r�zOpenSSL not presentzReactor doesn't support SSLc@s eZdZdZdd�Zdd�ZdS)�IMAP4ServerFetchTestszV
    This test case is for the FETCH tests that require
    a C{StringTransport}.
    cCs,t�|_t��|_d|j_|j�|j�dSr�)r'r�rr�rrCrrHr,r,r/r�s
zIMAP4ServerFetchTests.setUpcCsL|j��|j�d�d}|�|j��|�|j��|j�t�d��dS)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,
        s0001 FETCH 1 FULLL
s+0001 BAD Illegal syntax: Invalid Argument
r�N)	r�rrr�r;rrr
r)r>rr,r,r/�"test_fetchWithPartialValidArgument�s


z8IMAP4ServerFetchTests.test_fetchWithPartialValidArgumentN)rbrcrdr�rr�r,r,r,r/r��sr�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�LiteralTestsMixinz�
    Shared tests for literal classes.

    @ivar literalFactory: A callable that returns instances of the
        literal under test.
    cCst��|_dS)z
        Shared setup.
        N)r	rr�rHr,r,r/r�szLiteralTestsMixin.setUpcCs0|�d|j�}|�d|�d��|�|j�dS)ze
        The literal returns L{None} when given less data than the
        literal requires.
        r�Ns
incomplete)�literalFactoryr�r�rP�assertNoResult)r>�literalr,r,r/�test_partialWrite�sz#LiteralTestsMixin.test_partialWritecCsFd}|�t|�|j�}|�|�}|�|t�|�|�|�|j�dS)zz
        The literal returns an empty L{bytes} instance when given
        exactly the data the literal requires.
        �completeN)r�r�r�rPr[rDrr��r>�datar��leftoverr,r,r/�test_exactWrites

z!LiteralTestsMixin.test_exactWritecCs0d}|�td�|j�}|�|�}|�|d�dS)zt
        The literal returns any left over L{bytes} when given more
        data than the literal requires.
        scompleteleftoverr��leftoverN)r�r�r�rPr;r�r,r,r/�test_overlongWrites
z$LiteralTestsMixin.test_overlongWritecCs,|�d|j�}d}|�|�}|�||�dS)zo
        The literal returns an empty L{bytes} instance
        when given an empty L{bytes} instance.
        rr�N)r�r�rPr;)r>r�r�r�r,r,r/�test_emptyLiteral#s
z#LiteralTestsMixin.test_emptyLiteralN)	rbrcrdr�rr�r�r�r�r,r,r,r/r��s

r�c@seZdZdZejZdd�ZdS)�LiteralStringTestsz+
    Tests for L{self.literalFactory}.
    cCs\d}d}t�t|�|j�}t|�D]}|�|�q"|�d�|�|j�}|�|||f�dS)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�rrPr�r(r;)r>r��extrar�r|r-r,r,r/�
test_callback7s
z LiteralStringTests.test_callbackN)rbrcrdr�rr�r�r�r,r,r,r/r�1sr�c@s&eZdZdZejZdd�Zdd�ZdS)�LiteralFileTestsz)
    Tests for L{imap4.LiteralFile}.
    cCstd}d}t�t|�|j�}t|�D]}|�|�q"|�d�|�|j�}|�t|�d�|\}}|�|�	�d�dS)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�rrPr�r(r;rL�r>r�r�r�r|r-ZdataFiler,r,r/r�Ss
zLiteralFileTests.test_callbackcCs�d}d}|�tjdd�t�t|�|j�}t|�D]}|�|�q2|�d�|�|j�}|�	t|�d�|\}}|�	|�
�d�dS)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�Z_memoryFileLimitr�r�N)r�rrr�r�rrPr�r(r;rLrr,r,r/�test_callbackSpooledToDiskjs
z+LiteralFileTests.test_callbackSpooledToDiskN)	rbrcrdr�rrr�r�rr,r,r,r/r�Lsr�c@s@eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dS)�WriteBufferTestsz)
    Tests for L{imap4.WriteBuffer}.
    cCst�|_dSr+)r'r�rHr,r,r/r�szWriteBufferTests.setUpcCs4t�|j�}d|j}|�|�|�|j���dS)zd
        L{imap4.WriteBuffer} buffers writes that are smaller than its
        buffer size.
        �xN)r�WriteBufferr��
bufferSizerPrr�r>�bufr�r,r,r/r��s

z"WriteBufferTests.test_partialWritecCs:t�|j�}d|jd}|�|�|�|j��|�dS)z�
        L{imap4.WriteBuffer} writes data without buffering it when
        the size of the data exceeds the size of its buffer.
        rr�N)rrr�rrPr;rrr,r,r/r��s
z#WriteBufferTests.test_overlongWritecCsXt�|j�}d|j}d}|�|�|�|j���|�|�|�|j��||�dS)zp
        L{imap4.WriteBuffer} buffers writes until its buffer's size
        exceeds its maximum value.
        r�yN)rrr�rrPrrr;)r>rZ	firstDataZ
secondDatar,r,r/�test_writesImplyFlush�s


z&WriteBufferTests.test_writesImplyFlushcCsNt�|j�}d|j}|�|�|�|j���|��|�|j��|�dS)z{
        L{imap4.WriteBuffer.flush} flushes the buffer even when its
        size is smaller than the buffer size.
        rN)	rrr�rrPrr�flushr;rr,r,r/�test_explicitFlush�s

z#WriteBufferTests.test_explicitFlushcCs(t�|j�}|��|�|j���dS)z_
        L{imap4.WriteBuffer.flush} has no effect if when the buffer is
        empty.
        N)rrr�rrr)r>rr,r,r/�test_explicitFlushEmptyBuffer�sz.WriteBufferTests.test_explicitFlushEmptyBufferN)
rbrcrdr�rr�r�r
rr
r,r,r,r/r�s

r)�r�r�rJr�rr��iorr��	itertoolsr�collectionsrZzope.interfacerZzope.interface.verifyrrZtwisted.internetr	r
rrZtwisted.internet.taskr
Ztwisted.mailrZtwisted.mail.interfacesrrrZtwisted.mail.imap4rZtwisted.protocolsrZtwisted.pythonrrrZtwisted.python.compatrrrrrrZ
twisted.trialrZtwisted.cred.portalrr Ztwisted.cred.checkersr!Ztwisted.cred.errorr#Ztwisted.cred.credentialsr$r%r&Ztwisted.test.proto_helpersr'r(Ztwisted.test.ssl_helpersr)r*�ImportErrorr2ZTestCaser3reZSynchronousTestCasermr�r�ZIMailboxInfoZIMailboxZICloseableMailboxr�r�r�ZMemoryAccountWithoutNamespacesr�r�r�r�r�r�r�rrrrVr�rnrvr�r�r�r�r�rr!r:r<r=rArHrtr�r�r�ZIMessageZ
FancyStrMixinr�r�r�r�r]ZISearchableMailboxrwr�ZIMessageFiler�ZIMessageCopierr�r�r�r�r�r�r�r�rr\ZIReactorSSLr�r�r�r�rr,r,r,r/�<module>s8 ldeUU9KG4qJj]���2�6�<�3�W	0It6B#SAH



!B: