B
    u9a"ö  ã               @   s¢  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZmZ d dlZd dlmZ yd dlZW n ek
r¤   dZY nX dZej ej e¡d¡Zedk	rÐejZnG dd„ deƒZG d	d
„ d
ƒZe ¡  efZedk	reej f7 ZG dd„ deej!ƒZ"e #ed¡G dd„ de"ƒƒZ$G dd„ de j%ƒZ&dd„ Z'G dd„ dƒZ(G dd„ de(ƒZ)G dd„ dƒZ*G dd„ de*ƒZ+G dd„ de+ƒZ,G dd„ de+ƒZ-G d d!„ d!ƒZ.G d"d#„ d#e.e(ej!ƒZ/G d$d%„ d%e.e(ej!ƒZ0G d&d'„ d'e(ej!ƒZ1G d(d)„ d)e)ej!ƒZ2G d*d+„ d+ej!ƒZ3G d,d-„ d-ej!ƒZ4G d.d/„ d/ej!ƒZ5G d0d1„ d1ƒZ6e #ed¡G d2d3„ d3e5ƒƒZ7G d4d5„ d5ej!ƒZ8e9d6krže :¡  dS )7é    N)Úsupport)ÚNNTPÚ	GroupInfo)Úpatché   zkeycert3.pemc               @   s   e Zd ZdZdZdS )ÚSSLErrorz6Non-existent exception class when we lack SSL support.zThis will never be raised.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úreason© r   r   ú"/usr/lib/python3.7/test_nntplib.pyr      s   r   c               @   sÒ   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Ze dd¡dd„ ƒZdd„ Zd/d d!„Ze dd"¡d#d$„ ƒZd%d&„ Zd'd(„ Zd)d*„ Zed+d,„ ƒZd-d.„ ZdS )0ÚNetworkedNNTPTestsMixinc             C   s   | j  ¡ }|  tt|ƒ¡ d S )N)ÚserverZ
getwelcomeÚassertEqualÚstrÚtype)ÚselfÚwelcomer   r   r   Útest_welcome(   s    
z$NetworkedNNTPTestsMixin.test_welcomec             C   sB   | j  ¡ \}}|  | d¡|¡ x|D ]}|  tt|ƒ¡ q&W d S )Nz100 )r   ÚhelpÚ
assertTrueÚ
startswithr   r   r   )r   ÚrespÚlinesÚliner   r   r   Ú	test_help,   s    
z!NetworkedNNTPTestsMixin.test_helpc             C   sH   | j  ¡ \}}t|ƒdkrD|  tt|d ƒ¡ |  tt|d jƒ¡ d S )Nr   )r   ÚlistÚlenr   r   r   r   Úgroup)r   r   Úgroupsr   r   r   Ú	test_list2   s    z!NetworkedNNTPTestsMixin.test_listc             C   sL   | j  | j¡\}}t|ƒdkrH|  tt|d ƒ¡ |  tt|d jƒ¡ d S )Nr   )	r   r   Ú	GROUP_PATr   r   r   r   r   r    )r   r   r!   r   r   r   Útest_list_active8   s    z(NetworkedNNTPTestsMixin.test_list_activec          	   C   sB   |   tj¡}| j d¡ W d Q R X |jj}|  | d¡|¡ d S )NZXYZZYz500 )	ÚassertRaisesÚnntplibÚNNTPPermanentErrorr   Z	_shortcmdÚ	exceptionÚresponser   r   )r   Úcmr   r   r   r   Útest_unknown_command>   s    z,NetworkedNNTPTestsMixin.test_unknown_commandc             C   sX   t j ¡ t jdd }| j |¡\}}t|ƒdkrT|  |d t¡ |  |d j	t
¡ d S )Né   )Zdaysr   )ÚdatetimeÚdateZtodayZ	timedeltar   Z	newgroupsr   ÚassertIsInstancer   r    r   )r   Údtr   r!   r   r   r   Útest_newgroupsD   s
    z&NetworkedNNTPTestsMixin.test_newgroupsc                s`   ‡ fdd„}ˆ j  ˆ j¡}||ƒ ˆ  d|¡ ˆ j  ˆ j¡}||ƒ ˆ j  d¡}ˆ  |d¡ d S )Nc                s   ˆ   | t¡ ˆ  ˆ j| ¡ d S )N)r/   r   ÚassertNotInÚ
GROUP_NAME)Údesc)r   r   r   Ú_check_descN   s    z=NetworkedNNTPTestsMixin.test_description.<locals>._check_descÚPythonzzk.brrtt.bazÚ )r   Údescriptionr3   ÚassertInr#   r   )r   r5   r4   r   )r   r   Útest_descriptionM   s    z(NetworkedNNTPTestsMixin.test_descriptionc             C   s^   | j  | j¡\}}|  | d¡p(| d¡|¡ |  |t¡ || j }|  || j  	| j¡¡ d S )Nz215 z282 )
r   Údescriptionsr#   r   r   r/   Údictr3   r   r8   )r   r   Zdescsr4   r   r   r   Útest_descriptions]   s    
z)NetworkedNNTPTestsMixin.test_descriptionsc             C   s€   | j  | j¡}|  dt|ƒ¡ |\}}}}}|  || j¡ |  |t¡ |  |t¡ |  |t¡ |  ||¡ |  | 	d¡|¡ d S )Né   z211 )
r   r    r3   r   r   r/   ÚintÚassertLessEqualr   r   )r   Úresultr   ÚcountÚfirstÚlastr    r   r   r   Ú
test_groupf   s    z"NetworkedNNTPTestsMixin.test_groupc             C   s<   | j  ¡ \}}|  |tj¡ |  |jd¡ |  |jd¡ d S )NiË  iî  )r   r.   r/   r-   ÚassertGreaterEqualZyearr@   )r   r   r.   r   r   r   Ú	test_dateq   s    z!NetworkedNNTPTestsMixin.test_datec          
   C   sT   |   |t¡ |  | ¡ dddddddh¡ x$| ¡ D ]}|   |ttd ƒf¡ q4W d S )NÚsubjectÚfromr.   z
message-idÚ
referencesz:bytesz:lines)r/   r<   rF   ÚkeysÚvaluesr   r   )r   Úart_dictÚvr   r   r   Ú_check_art_dictx   s    
z'NetworkedNNTPTestsMixin._check_art_dictc       	      C   sz   | j  | j¡\}}}}}| j  |d |¡\}}t|ƒdkrD|  d¡ |d \}}|  ||d ¡ |  ||¡ |  |¡ d S )Nr>   r   zno articles retrieved)	r   r    r3   Úxoverr   ÚskipTestrF   r@   rO   )	r   r   rB   rC   rD   Únamer   Úart_numrM   r   r   r   Ú
test_xoverƒ   s    
z"NetworkedNNTPTestsMixin.test_xoverTzHtemporarily skipped until a permanent solution is found for issue #28971c       
      C   s   | j  | j¡\}}}}}|d }| j  |d f¡\}}|d \}}	|  |	¡ | j  ||f¡\}}|d \}}	|  ||¡ |  ||¡ |  |	¡ d S )Né
   r   éÿÿÿÿ)r   r    r3   ÚoverrO   rF   r@   )
r   r   rB   rC   rD   rR   Ústartr   rS   rM   r   r   r   Ú	test_overŽ   s    
z!NetworkedNNTPTestsMixin.test_overc             C   sP   | j  | j¡\}}}}}| j  d|¡\}}x |D ]}|  tt|d ƒ¡ q0W d S )NrH   é   )r   r    r3   Zxhdrr   r   r   )r   r   rB   rC   rD   rR   r   r   r   r   r   Ú	test_xhdr¡   s    
z!NetworkedNNTPTestsMixin.test_xhdrNc             C   sV   |   |tj¡ |d k	r$|  |j|¡ x|jD ]}|   |t¡ q,W |  |jd d¡ d S )NrV   )ó   .s   .
s   .
)r/   r&   ZArticleInfor   Znumberr   Úbytesr2   )r   r   ÚarticlerS   r   r   r   r   Úcheck_article_resp§   s    z*NetworkedNNTPTestsMixin.check_article_respzFIXME: see bpo-32128c                sR  | j  | j¡\}}}}}xl|||d fD ]P}y| j  |¡\}}W n4 tjk
rt } z|j d¡sb‚ w(W d d }~X Y nX P q(W |  d¡ |  	| d¡|¡ |  
|||¡ | j  |¡\}}	|  	| d¡|¡ |  
||	|¡ | j  |¡\}}
|  	| d¡|¡ |  
||
|¡ dd„ ‰ ‡ fd	d
„|jD ƒ}‡ fdd
„|
jD ƒ}|  ||dg |	j ¡ d S )NrZ   z423 z(could not find a suitable article numberz221 z222 z220 c             S   s
   |   d¡S )Ns   X-Antivirus)r   )r   r   r   r   Ú<lambda>È   ó    z@NetworkedNNTPTestsMixin.test_article_head_body.<locals>.<lambda>c                s   g | ]}ˆ |ƒs|‘qS r   r   )Ú.0r   )Ú	blacklistr   r   ú
<listcomp>É   s    zBNetworkedNNTPTestsMixin.test_article_head_body.<locals>.<listcomp>c                s   g | ]}ˆ |ƒs|‘qS r   r   )rb   r   )rc   r   r   rd   Ë   s    ra   )r   r    r3   Úheadr&   ÚNNTPTemporaryErrorr)   r   rQ   r   r_   Úbodyr^   r   r   )r   r   rB   rC   rD   rR   rS   re   Úerg   r^   Zfiltered_head_linesZfiltered_linesr   )rc   r   Útest_article_head_body°   s,    
z.NetworkedNNTPTestsMixin.test_article_head_bodyc                sD   ‡ fdd„}ˆ   ˆ jjd¡ |ˆ j ¡ ƒ ˆ j ¡ \}}||ƒ d S )Nc                s(   | d }ˆ   |ttf¡ ˆ  d|¡ d S )NÚLISTzOVERVIEW.FMT)r/   r   Útupler9   )ÚcapsZ	caps_list)r   r   r   Ú_check_capsÓ   s    z>NetworkedNNTPTestsMixin.test_capabilities.<locals>._check_capsé   )rF   r   Únntp_versionÚgetcapabilitiesZcapabilities)r   rm   r   rl   r   )r   r   Útest_capabilitiesÏ   s
    z)NetworkedNNTPTestsMixin.test_capabilitiesc             C   s&   d}d}| j tj| jj||dd d S )NZnotarealuserZnotarealpasswordF)ÚuserÚpasswordÚusenetrc)r%   r&   Ú	NNTPErrorr   Úlogin)r   ZbaduserZbadpwr   r   r   Útest_zloginÝ   s    z#NetworkedNNTPTestsMixin.test_zloginc             C   s$   t | ƒ}z| j ¡  W d d |_X d S )N)r   r   Úquit)r   Úclsr   r   r   Útest_zzquitê   s    z#NetworkedNNTPTestsMixin.test_zzquitc             C   sN   dd„ }x@t | ƒD ]4}| d¡s"qt| |ƒ}t|ƒs6qt| |||ƒƒ qW d S )Nc                s   t  ˆ ¡‡ fdd„ƒ}|S )Nc          	      s$   t  | j¡ ˆ | ƒ W d Q R X d S )N)r   Útransient_internetÚ	NNTP_HOST)r   )Úmethr   r   Úwrapped÷   s    zHNetworkedNNTPTestsMixin.wrap_methods.<locals>.wrap_meth.<locals>.wrapped)Ú	functoolsÚwraps)r}   r~   r   )r}   r   Ú	wrap_methö   s    z7NetworkedNNTPTestsMixin.wrap_methods.<locals>.wrap_methZtest_)Údirr   ÚgetattrÚcallableÚsetattr)ry   r   rR   r}   r   r   r   Úwrap_methodsò   s    

z$NetworkedNNTPTestsMixin.wrap_methodsc          
      sÖ   ‡ fdd„}yz| j | jtdd ‰ |  |ƒ ¡ |  ˆ  ¡ ¡ W d Q R X |  |ƒ ¡ | j | jtdd‰ ˆ  ¡  W d Q R X |  |ƒ ¡ W nJ tk
rÐ } z,t 	d|j
¡r¾t d|› d| j›¡‚‚ W d d }~X Y nX d S )Nc            	      s8   t ˆ dƒsdS yˆ  ¡  W n ttfk
r2   dS X dS )NÚfileFT)Úhasattrr   ÚOSErrorÚEOFErrorr   )r   r   r   Úis_connected  s    
zANetworkedNNTPTestsMixin.test_with_statement.<locals>.is_connectedF)Útimeoutrt   z(?i)KEY.TOO.SMALLzGot z connecting to )Ú
NNTP_CLASSr|   ÚTIMEOUTr   r   ÚassertFalserx   r   ÚreÚsearchr   ÚunittestÚSkipTest)r   r‹   Ússl_errr   )r   r   Útest_with_statement  s    	z+NetworkedNNTPTestsMixin.test_with_statement)N)r   r	   r
   r   r   r"   r$   r+   r1   r:   r=   rE   rG   rO   rT   r’   ZskipIfrY   r[   r_   ri   rq   rw   rz   Úclassmethodr†   r•   r   r   r   r   r   &   s*   		
	r   c               @   s4   e Zd ZdZdZdZeZedd„ ƒZ	edd„ ƒZ
dS )	ÚNetworkedNNTPTestsznews.trigofacile.comzfr.comp.lang.pythonzfr.comp.lang.*c             C   s¶   t  d¡ t  | j¡– y| j| jtdd| _W nv tk
r~ } z0t 	d|j
¡rlt | › d|› d| j›¡‚‚ W d d }~X Y n* tk
r¦   t | › d| j›¡‚Y nX W d Q R X d S )NZnetworkF)rŒ   rt   z(?i)KEY.TOO.SMALLz got z connecting to z  got EOF error on connecting to )r   Zrequiresr{   r|   r   rŽ   r   r   r   r‘   r   r’   r“   Ú
EOF_ERRORS)ry   r”   r   r   r   Ú
setUpClass1  s    

zNetworkedNNTPTests.setUpClassc             C   s   | j d k	r| j  ¡  d S )N)r   rx   )ry   r   r   r   ÚtearDownClassB  s    
z NetworkedNNTPTests.tearDownClassN)r   r	   r
   r|   r3   r#   r   r   r–   r™   rš   r   r   r   r   r—   )  s   r—   zrequires SSL supportc               @   s,   e Zd ZdZdZdZeeddƒZdZ	dZ
dS )ÚNetworkedNNTP_SSLTestsznntp.aioe.orgzcomp.lang.pythonzcomp.lang.*ÚNNTP_SSLN)r   r	   r
   r|   r3   r#   rƒ   r&   r   r"   Útest_starttlsr   r   r   r   r›   G  s   r›   c               @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )Ú_NNTPServerIOz¤A raw IO object allowing NNTP commands to be received and processed
    by a handler.  The handler can push responses which can then be read
    from the IO object.c             C   s>   t j | ¡ t  ¡ | _t  ¡ | _|| _| j | jj| j	¡ d S )N)
ÚioÚ	RawIOBaseÚ__init__ÚBytesIOÚc2sÚs2cÚhandlerrX   ÚreadlineÚ	push_data)r   r¥   r   r   r   r¡   d  s
    

z_NNTPServerIO.__init__c             C   s   dS )NTr   )r   r   r   r   Úreadablem  s    z_NNTPServerIO.readablec             C   s   dS )NTr   )r   r   r   r   Úwritablep  s    z_NNTPServerIO.writablec             C   s4   | j  ¡ }| j  dd¡ | j  |¡ | j  |¡ dS )z.Push (buffer) some data to send to the client.r   rn   N)r¤   ÚtellÚseekÚwrite)r   ÚdataÚposr   r   r   r§   s  s    
z_NNTPServerIO.push_datac             C   s4   | j  ¡ }| j  |¡ | j  |¡ | j ¡  t|ƒS )zThe client sends us some data)r£   rª   r¬   r«   r¥   Úprocess_pendingr   )r   Úbr®   r   r   r   r¬   z  s
    

z_NNTPServerIO.writec             C   s2   | j  ¡  | j t|ƒ¡}t|ƒ}||d|…< |S )z#The client wants to read a responseN)r¥   r¯   r¤   Úreadr   )r   Úbufr°   Únr   r   r   Úreadinto‚  s
    
z_NNTPServerIO.readintoN)
r   r	   r
   r   r¡   r¨   r©   r§   r¬   r´   r   r   r   r   rž   _  s   	rž   c             C   s   t | ƒ}t ||¡}||fS )N)rž   rŸ   ÚBufferedRWPair)r¥   Úsior‡   r   r   r   Úmake_mock_file‹  s    r·   c                   s4   e Zd ZdZ‡ fdd„Z‡ fdd„Zdd„ Z‡  ZS )ÚMockedNNTPTestsMixinNc                s   t ƒ  ¡  |  ¡  d S )N)ÚsuperÚsetUpÚmake_server)r   )Ú	__class__r   r   rº   —  s    
zMockedNNTPTestsMixin.setUpc                s   t ƒ  ¡  | `d S )N)r¹   ÚtearDownr   )r   )r¼   r   r   r½   ›  s    
zMockedNNTPTestsMixin.tearDownc             O   s6   |   ¡ | _t| jƒ\| _}tj|df|ž|Ž| _| jS )Nztest.server)Úhandler_classr¥   r·   r¶   r&   Z	_NNTPBaser   )r   ÚargsÚkwargsr‡   r   r   r   r»   Ÿ  s    
z MockedNNTPTestsMixin.make_server)r   r	   r
   r¾   rº   r½   r»   Ú__classcell__r   r   )r¼   r   r¸   “  s   r¸   c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚMockedNNTPWithReaderModeMixinc                s   t ƒ  ¡  | jdd d S )NT)Z
readermode)r¹   rº   r»   )r   )r¼   r   r   rº   §  s    
z#MockedNNTPWithReaderModeMixin.setUp)r   r	   r
   rº   rÁ   r   r   )r¼   r   rÂ   ¦  s   rÂ   c               @   sþ   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd8dd„Zdd„ Zd d!„ Zd9d"d#„Zd$d%„ Zd&d'„ Zdd(œd)d*„Zdd(œd+d,„Zd-Zd.Zed/ e Zd:d0d1„Zd;d2d3„Zd<d4d5„Zd6d7„ ZdS )=ÚNNTPv1HandlerzA handler for RFC 977z200 NNTP mock serverc             C   s0   d| _ d| _|| _|| _d| _d| _|  ¡  d S )NFT)Úin_bodyÚallow_postingÚ	_readlineÚ
_push_dataÚ
_logged_inÚ
_user_sentÚhandle_welcome)r   r¦   r§   r   r   r   rX   ±  s    zNNTPv1Handler.startc             C   s   t |ddƒS )Nzutf-8Úsurrogateescape)r   )r   r­   r   r   r   Ú_decode»  s    zNNTPv1Handler._decodec          
   C   s4  | j rfx*|  ¡ }|sd S | j |¡ |dkrP qW z| j\}}||d| jiŽ W d d | _d | _d| _ X xÈ|  |  ¡ ¡}|s~d S | d¡s–td |¡ƒ‚|d d… }| 	¡ ^}}t
| d| ¡  d ƒ}|d krÔ|  ¡  qhy||Ž  W n4 tk
r } ztd |¡ƒ|‚W d d }~X Y qhX | j rh||f| _g | _qhW d S )	Ns   .
rg   Fz
z line doesn't end with \r\n: {!r}éþÿÿÿZhandle_zcommand failed: {!r})rÄ   rÆ   rg   ÚappendZbody_callbackrÌ   ÚendswithÚ
ValueErrorÚformatÚsplitrƒ   ÚupperÚhandle_unknownÚ	Exception)r   r   r}   ÚtokensÚcmdrh   r   r   r   r¯   ¾  s@    


"
zNNTPv1Handler.process_pendingc             C   s
   d| _ dS )z7Flag that the client is expected to post a request bodyTN)rÄ   )r   r   r   r   Úexpect_bodyä  s    zNNTPv1Handler.expect_bodyc             C   s   |   |¡ dS )zPush some binary dataN)rÇ   )r   r­   r   r   r   r§   è  s    zNNTPv1Handler.push_datac             C   s4   t  |¡}d | ¡ ¡d }| d¡}|  |¡ dS )zPush a string literalz
zutf-8N)ÚtextwrapÚdedentÚjoinÚ
splitlinesÚencoder§   )r   Zlitr   r   r   Úpush_litì  s    

zNNTPv1Handler.push_litc             C   s   |   d¡ d S )Nz	500 What?)rÞ   )r   r   r   r   rÔ   ó  s    zNNTPv1Handler.handle_unknownc             C   s   |   | j¡ d S )N)rÞ   r   )r   r   r   r   rÊ   ö  s    zNNTPv1Handler.handle_welcomec             C   s   |   d¡ d S )Nz205 Bye!)rÞ   )r   r   r   r   Úhandle_QUITù  s    zNNTPv1Handler.handle_QUITc             C   s   |   d¡ d S )Nz111 20100914001155)rÞ   )r   r   r   r   Úhandle_DATEü  s    zNNTPv1Handler.handle_DATEc             C   s(   |dkr|   d¡ n|   d |¡¡ d S )Nzfr.comp.lang.pythonz$211 486 761 1265 fr.comp.lang.pythonz411 No such group {})rÞ   rÑ   )r   r    r   r   r   Úhandle_GROUPÿ  s    zNNTPv1Handler.handle_GROUPc             C   s   |   d¡ d S )NzÉ            100 Legal commands
              authinfo user Name|pass Password|generic <prog> <args>
              date
              help
            Report problems to <root@example.org>
            .)rÞ   )r   r   r   r   Úhandle_HELP  s    zNNTPv1Handler.handle_HELPNc             C   sJ   |d kr|   d¡ n2|dkr(|   d¡ n|dkr<|   d¡ n
|   d¡ d S )Nz412 No newsgroup selectedÚ3000234z"223 3000234 <45223423@example.com>z<45223423@example.com>z223 0 <45223423@example.com>z430 No Such Article Found)rÞ   )r   Úmessage_specr   r   r   Úhandle_STAT  s    zNNTPv1Handler.handle_STATc             C   s   |   d¡ d S )Nz*223 3000237 <668929@example.org> retrieved)rÞ   )r   r   r   r   Úhandle_NEXT  s    zNNTPv1Handler.handle_NEXTc             C   s   |   d¡ d S )Nz,223 3000234 <45223423@example.com> retrieved)rÞ   )r   r   r   r   Úhandle_LAST  s    zNNTPv1Handler.handle_LASTc             C   s¦   |d kr|   d¡ nŽ|dkr<|dkr0|   d¡ q¢|   d¡ nf|dkrP|   d¡ nR|dkr˜|d k	sdt‚|d	krx|   d
¡ q¢|dkrŒ|   d¡ q¢|   d¡ n
|   d¡ d S )NaÑ                  215 Newsgroups in form "group high low flags".
                comp.lang.python 0000052340 0000002828 y
                comp.lang.python.announce 0000001153 0000000993 m
                free.it.comp.lang.python 0000000002 0000000002 y
                fr.comp.lang.python 0000001254 0000000760 y
                free.it.comp.lang.python.learner 0000000000 0000000001 y
                tw.bbs.comp.lang.python 0000000304 0000000304 y
                .ÚACTIVEz*distutils*zñ                    215 Newsgroups in form "group high low flags"
                    gmane.comp.python.distutils.devel 0000014104 0000000001 m
                    gmane.comp.python.distutils.cvs 0000000000 0000000001 m
                    .zW                    215 Newsgroups in form "group high low flags"
                    .zOVERVIEW.FMTa                  215 Order of fields in overview database.
                Subject:
                From:
                Date:
                Message-ID:
                References:
                Bytes:
                Lines:
                Xref:full
                .Ú
NEWSGROUPSzcomp.lang.pythonzš                    215 Descriptions in form "group description".
                    comp.lang.python	The Python computer language.
                    .zcomp.lang.python*zý                    215 Descriptions in form "group description".
                    comp.lang.python.announce	Announcements about the Python language. (Moderated)
                    comp.lang.python	The Python computer language.
                    .zW                    215 Descriptions in form "group description".
                    .z501 Unknown LIST keyword)rÞ   ÚAssertionError)r   ÚactionZparamr   r   r   Úhandle_LIST  s.    
zNNTPv1Handler.handle_LISTc             C   s‚   |dkr$|dkr$|dkr$|   d¡ nZ|dkrH|dkrH|dkrH|   d¡ n6|dkrt|dkrt|dkrt|   d	d
 d ¡ n
|   d¡ d S )Nzcomp.lang.pythonZ20100913Z082004a                  230 list of newsarticles (NNTP v2) created after Mon Sep 13 08:20:04 2010 follows
                <a4929a40-6328-491a-aaaf-cb79ed7309a2@q2g2000vbk.googlegroups.com>
                <f30c0419-f549-4218-848f-d7d0131da931@y3g2000vbm.googlegroups.com>
                .Z100913a                  230 list of newsarticles (NNTP v1) created after Mon Sep 13 08:20:04 2010 follows
                <a4929a40-6328-491a-aaaf-cb79ed7309a2@q2g2000vbk.googlegroups.com>
                <f30c0419-f549-4218-848f-d7d0131da931@y3g2000vbm.googlegroups.com>
                .)Z20100101Z100101Z090000ztoo long linei¸  z
.zK                230 An empty list of newsarticles follows
                .)rÞ   )r   r    Údate_strÚtime_strr   r   r   Úhandle_NEWNEWST  s    

zNNTPv1Handler.handle_NEWNEWSc             C   s"   |dkr|   d¡ n
|   d¡ d S )Nz57-59uL  224 Overview information for 57-58 follows
57	Re: ANN: New Plone book with strong Python (and Zope) themes throughout	Doug Hellmann <doug.hellmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>	Sat, 19 Jun 2010 18:04:08 -0400	<4FD05F05-F98B-44DC-8111-C6009C925F0C@gmail.com>	<hvalf7$ort$1@dough.gmane.org>	7103	16	Xref: news.gmane.org gmane.comp.python.authors:57
58	Looking for a few good bloggers	Doug Hellmann <doug.hellmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>	Thu, 22 Jul 2010 09:14:14 -0400	<A29863FA-F388-40C3-AA25-0FD06B09B5BF@gmail.com>		6683	16	
59	Re: Message d'erreur incomprÃ©hensible (par moi)	Eric Brunel <eric.brunel@pragmadev.nospam.com>	Wed, 15 Sep 2010 18:09:15 +0200	<eric.brunel-2B8B56.18091515092010@news.wanadoo.fr>	<4c90ec87$0$32425$ba4acef3@reader.news.orange.fr>	1641	27	Xref: saria.nerim.net fr.comp.lang.python:1265
.
z1                224 No articles
                .)rÞ   )r   rä   r   r   r   Úhandle_XOVERs  s
    zNNTPv1Handler.handle_XOVER)rg   c            C   sL   |d kr.| j r"|  d¡ |  ¡  qH|  d¡ n| j s8t‚|  d¡ || _d S )Nz+340 Input article; end with <CR-LF>.<CR-LF>z440 Posting not permittedz240 Article received OK)rÅ   rÞ   rØ   rê   Úposted_body)r   rg   r   r   r   Úhandle_POST“  s    



zNNTPv1Handler.handle_POSTc            C   sT   |d kr6| j r*|dkr*|  d¡ |  ¡  qP|  d¡ n| j s@t‚|  d¡ || _d S )Nz+<i.am.an.article.you.will.want@example.com>z%335 Send it; end with <CR-LF>.<CR-LF>z435 Article not wantedz235 Article transferred OK)rÅ   rÞ   rØ   rê   rñ   )r   Ú
message_idrg   r   r   r   Úhandle_IHAVEŸ  s    



zNNTPv1Handler.handle_IHAVEz×        From: "Demo User" <nobody@example.net>
        Subject: I am just a test article
        Content-Type: text/plain; charset=UTF-8; format=flowed
        Message-ID: <i.am.an.article.you.will.want@example.com>ui           This is just a test article.
        ..Here is a dot-starting line.

        -- Signed by AndrÃ©.z

c             C   sd   |d kr|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nz"220 3000237 <45223423@example.com>z<45223423@example.com>z220 0 <45223423@example.com>rã   z"220 3000234 <45223423@example.com>z430 No Such Article FoundÚ.)rÞ   Úsample_article)r   rä   r   r   r   Úhandle_ARTICLEº  s    
zNNTPv1Handler.handle_ARTICLEc             C   sd   |d kr|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nz"221 3000237 <45223423@example.com>z<45223423@example.com>z221 0 <45223423@example.com>rã   z"221 3000234 <45223423@example.com>z430 No Such Article Foundrõ   )rÞ   Úsample_head)r   rä   r   r   r   Úhandle_HEADÇ  s    
zNNTPv1Handler.handle_HEADc             C   sd   |d kr|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nz"222 3000237 <45223423@example.com>z<45223423@example.com>z222 0 <45223423@example.com>rã   z"222 3000234 <45223423@example.com>z430 No Such Article Foundrõ   )rÞ   Úsample_body)r   rä   r   r   r   Úhandle_BODYÔ  s    
zNNTPv1Handler.handle_BODYc             C   sj   | j r|  d¡ nT|dkr>| jr,|  d¡ qf|  d¡ d| _n(|dkrX|  d¡ d| _ ntd |¡ƒ‚d S )	Nz502 Already Logged Inrr   z 482 User Credential Already Sentz381 Password RequiredTÚpassz281 Login SuccessfulzUnknown cred type {})rÈ   rÞ   rÉ   rÕ   rÑ   )r   Z	cred_typer­   r   r   r   Úhandle_AUTHINFOá  s    

zNNTPv1Handler.handle_AUTHINFO)N)NN)N)N)N) r   r	   r
   r   r   rX   rÌ   r¯   rØ   r§   rÞ   rÔ   rÊ   rß   rà   rá   râ   rå   ræ   rç   rì   rï   rð   rò   rô   rø   rú   rö   r÷   rù   rû   rý   r   r   r   r   rÃ   ¬  s:   
&	


6 


rÃ   c               @   s*   e Zd ZdZdd„ Zdd„ Zd	dd„ZdS )
ÚNNTPv2Handlerz"A handler for RFC 3977 (NNTP "v2")c             C   s0   d}| j s|  | d¡¡ n|  | d¡¡ d S )Na              101 Capability list:
            VERSION 2 3
            IMPLEMENTATION INN 2.5.1{}
            HDR
            LIST ACTIVE ACTIVE.TIMES DISTRIB.PATS HEADERS NEWSGROUPS OVERVIEW.FMT
            OVER
            POST
            READER
            .z
            AUTHINFO USERr7   )rÈ   rÞ   rÑ   )r   Úfmtr   r   r   Úhandle_CAPABILITIESô  s    
z!NNTPv2Handler.handle_CAPABILITIESc             C   s   t dƒ‚d S )Nz3MODE READER sent despite READER has been advertised)rÕ   )r   Ú_r   r   r   Úhandle_MODE  s    zNNTPv2Handler.handle_MODENc             C   s
   |   |¡S )N)rð   )r   rä   r   r   r   Úhandle_OVER  s    zNNTPv2Handler.handle_OVER)N)r   r	   r
   r   r   r  r  r   r   r   r   rþ   ñ  s   rþ   c                   s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚCapsAfterLoginNNTPv2Handlerz3A handler that allows CAPABILITIES only after loginc                s    | j s|  d¡ n
tƒ  ¡  d S )Nz480 You must log in.)rÈ   rÞ   r¹   r   )r   )r¼   r   r   r     s    z/CapsAfterLoginNNTPv2Handler.handle_CAPABILITIES)r   r	   r
   r   r   rÁ   r   r   )r¼   r   r    s   r  c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚModeSwitchingNNTPv2Handlerz$A server that starts in transit modec             C   s
   d| _ d S )NF)Ú	_switched)r   r   r   r   r¡     s    z#ModeSwitchingNNTPv2Handler.__init__c             C   s0   d}| j r|  | d¡¡ n|  | d¡¡ d S )Na              101 Capability list:
            VERSION 2 3
            IMPLEMENTATION INN 2.5.1
            HDR
            LIST ACTIVE ACTIVE.TIMES DISTRIB.PATS HEADERS NEWSGROUPS OVERVIEW.FMT
            OVER
            POST
            {}READER
            .r7   zMODE-)r  rÞ   rÑ   )r   rÿ   r   r   r   r     s    
z.ModeSwitchingNNTPv2Handler.handle_CAPABILITIESc             C   s&   | j s|dkst‚d| _ |  d¡ d S )NÚreaderTz200 Posting allowed)r  rê   rÞ   )r   Zwhatr   r   r   r  ,  s    z&ModeSwitchingNNTPv2Handler.handle_MODEN)r   r	   r
   r   r¡   r   r  r   r   r   r   r    s   r  c                   s  e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5Zd6d7„ Zd8d9„ Zd:d;„ Z d<d=„ Z!d>d?„ Z"d@dA„ Z#‡  Z$S )BÚNNTPv1v2TestsMixinc                s   t ƒ  ¡  d S )N)r¹   rº   )r   )r¼   r   r   rº   4  s    zNNTPv1v2TestsMixin.setUpc             C   s   |   | jj| jj¡ d S )N)r   r   r   r¥   )r   r   r   r   r   7  s    zNNTPv1v2TestsMixin.test_welcomec             C   s<   | j dkr|  d| jj¡ | j dd¡ |  d| jj¡ d S )Nrn   ÚAUTHINFOÚtestuserÚtestpw)ro   r9   r   Ú_capsrv   r2   )r   r   r   r   Útest_authinfo:  s    
z NNTPv1v2TestsMixin.test_authinfoc             C   s:   | j  ¡ \}}|  |d¡ |  |t dddddd¡¡ d S )Nz111 20100914001155iÚ  é	   é   r   é   é7   )r   r.   r   r-   )r   r   r.   r   r   r   rG   B  s    zNNTPv1v2TestsMixin.test_datec             C   s6   |   | jj¡ | j ¡ }|  |d¡ |  | jj¡ d S )Nz205 Bye!)r   r¶   Úclosedr   rx   r   r   )r   r   r   r   r   Ú	test_quitG  s    
zNNTPv1v2TestsMixin.test_quitc             C   s2   | j  ¡ \}}|  |d¡ |  |ddddg¡ d S )Nz100 Legal commandsz8  authinfo user Name|pass Password|generic <prog> <args>z  datez  helpz%Report problems to <root@example.org>)r   r   r   )r   r   r   r   r   r   r   M  s    zNNTPv1v2TestsMixin.test_helpc             C   s~   | j  ¡ \}}|  t|ƒd¡ |d }|  |tddddƒ¡ | j  d¡\}}|  t|ƒd¡ |d	 }|  |td
dddƒ¡ d S )Né   rZ   zcomp.lang.python.announceZ
0000001153Z
0000000993Úmz*distutils*rn   r   z!gmane.comp.python.distutils.develZ
0000014104Z
0000000001)r   r   r   r   r   )r   r   r!   Úgr   r   r   r"   W  s    
zNNTPv1v2TestsMixin.test_listc          	   C   sÖ   | j  d¡\}}}|  |d¡ |  |d¡ |  |d¡ | j  d¡\}}}|  |d¡ |  |d¡ |  |d¡ |  tj¡}| j  d¡ W d Q R X |  |jjd¡ |  tj¡}| j  ¡  W d Q R X |  |jjd¡ d S )	NiªÇ- z"223 3000234 <45223423@example.com>z<45223423@example.com>z223 0 <45223423@example.com>r   z<non.existent.id>z430 No Such Article Foundz412 No newsgroup selected)r   Ústatr   r%   r&   rf   r(   r)   )r   r   rS   ró   r*   r   r   r   Ú	test_state  s    zNNTPv1v2TestsMixin.test_statc             C   s8   | j  ¡ \}}}|  |d¡ |  |d¡ |  |d¡ d S )Nz*223 3000237 <668929@example.org> retrievedi­Ç- z<668929@example.org>)r   Únextr   )r   r   rS   ró   r   r   r   Ú	test_nextu  s    zNNTPv1v2TestsMixin.test_nextc             C   s8   | j  ¡ \}}}|  |d¡ |  |d¡ |  |d¡ d S )Nz,223 3000234 <45223423@example.com> retrievediªÇ- z<45223423@example.com>)r   rD   r   )r   r   rS   ró   r   r   r   Ú	test_last{  s    zNNTPv1v2TestsMixin.test_lastc             C   s4   | j  d¡}|  |d¡ | j  d¡}|  |d¡ d S )Nzcomp.lang.pythonzThe Python computer language.zcomp.lang.pythonxr7   )r   r8   r   )r   r4   r   r   r   r:     s    z#NNTPv1v2TestsMixin.test_descriptionc             C   sn   | j  d¡\}}|  |d¡ |  |ddi¡ | j  d¡\}}|  |dddœ¡ | j  d¡\}}|  |i ¡ d S )Nzcomp.lang.pythonz-215 Descriptions in form "group description".zThe Python computer language.zcomp.lang.python*z4Announcements about the Python language. (Moderated))zcomp.lang.pythonzcomp.lang.python.announcezcomp.lang.pythonx)r   r;   r   )r   r   r!   r   r   r   r=   ‡  s    

z$NNTPv1v2TestsMixin.test_descriptionsc          	   C   sœ   | j  d¡\}}}}}|  | d¡|¡ |  |d¡ |  |d¡ |  |d¡ |  |d¡ |  tj¡}| j  d¡ W d Q R X |j}|  |j	 d¡|j	¡ d S )Nzfr.comp.lang.pythonz211 iù  iñ  iæ  zcomp.lang.python.develz411 No such group)
r   r    r   r   r   r%   r&   rf   r(   r)   )r   r   rB   rC   rD   r    r*   Úexcr   r   r   rE   •  s    zNNTPv1v2TestsMixin.test_groupc             C   s   t   dddddd¡}| j d|¡\}}d | j¡}|  ||¡ |  |d	d
g¡ t   dddddd¡}| j d|¡\}}|  |d¡ |  |g ¡ d S )NiÚ  r  é   é   é   é   zcomp.lang.pythonzS230 list of newsarticles (NNTP v{0}) created after Mon Sep 13 08:20:04 2010 followszB<a4929a40-6328-491a-aaaf-cb79ed7309a2@q2g2000vbk.googlegroups.com>zB<f30c0419-f549-4218-848f-d7d0131da931@y3g2000vbm.googlegroups.com>zfr.comp.lang.pythonz)230 An empty list of newsarticles follows)r-   r   ÚnewnewsrÑ   ro   r   )r   r0   r   ZidsZexpectedr   r   r   Útest_newnews¢  s    zNNTPv1v2TestsMixin.test_newnewsc             C   sZ   |   t|ƒd¡ |   |d  d¡d¡ |   |d d¡ |   |d d¡ |   |d	 d
¡ d S )Nr   rV   zutf-8u   -- Signed by AndrÃ©.rÍ   ra   éýÿÿÿs   .Here is a dot-starting line.éüÿÿÿs   This is just a test article.)r   r   Údecode)r   r   r   r   r   Ú_check_article_bodyµ  s
    z&NNTPv1v2TestsMixin._check_article_bodyc             C   s4   |   t|ƒd¡ |   |d d¡ |   |d d¡ d S )Nr   r   s&   From: "Demo User" <nobody@example.net>é   s7   Message-ID: <i.am.an.article.you.will.want@example.com>)r   r   )r   r   r   r   r   Ú_check_article_head¼  s    z&NNTPv1v2TestsMixin._check_article_headc             C   sH   |   t|ƒd¡ |  |d d… ¡ |  |dd … ¡ |   |d d¡ d S )Nr  r   r$  ra   )r   r   r(  r&  )r   r   r   r   r   Ú_check_article_dataÁ  s    z&NNTPv1v2TestsMixin._check_article_datac          	   C   s  | j  ¡ \}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ |  tj¡}| j  d¡ W d Q R X |  |jjd	¡ d S )
Nz"220 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>iªÇ- z"220 3000234 <45223423@example.com>z220 0 <45223423@example.com>r   z<non-existent@example.com>z430 No Such Article Found)	r   r^   r   r)  r%   r&   rf   r(   r)   )r   r   ÚinforS   ró   r   r*   r   r   r   Útest_articleÇ  s*    





zNNTPv1v2TestsMixin.test_articlec             C   sŒ   t  ¡ }| jj|d\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |g ¡ | ¡ }|  | d¡t|ƒ¡ |  | 	d¡t|ƒ¡ d S )N)r‡   z"220 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>sK   From: "Demo User" <nobody@example.net>
Subject: I am just a test article
sU   This is just a test article.
.Here is a dot-starting line.

-- Signed by AndrÃ©.
)
rŸ   r¢   r   r^   r   Úgetvaluer   r   ÚasciirÏ   )r   Úfr   r*  rS   ró   r   r­   r   r   r   Útest_article_fileâ  s    

z$NNTPv1v2TestsMixin.test_article_filec          	   C   s  | j  ¡ \}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ |  tj¡}| j  d¡ W d Q R X |  |jjd	¡ d S )
Nz"221 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>iªÇ- z"221 3000234 <45223423@example.com>z221 0 <45223423@example.com>r   z<non-existent@example.com>z430 No Such Article Found)	r   re   r   r(  r%   r&   rf   r(   r)   )r   r   r*  rS   ró   r   r*   r   r   r   Ú	test_head÷  s*    





zNNTPv1v2TestsMixin.test_headc             C   sŒ   t  ¡ }| jj|d\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |g ¡ | ¡ }|  | d¡t|ƒ¡ |  	| 
d¡t|ƒ¡ d S )N)r‡   z"221 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>sK   From: "Demo User" <nobody@example.net>
Subject: I am just a test article
sU   This is just a test article.
.Here is a dot-starting line.

-- Signed by AndrÃ©.
)rŸ   r¢   r   re   r   r,  r   r   r-  r   rÏ   )r   r.  r   r*  rS   ró   r   r­   r   r   r   Útest_head_file  s    

z!NNTPv1v2TestsMixin.test_head_filec          	   C   s  | j  ¡ \}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ | j  d¡\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |¡ |  tj¡}| j  d¡ W d Q R X |  |jjd	¡ d S )
Nz"222 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>iªÇ- z"222 3000234 <45223423@example.com>z222 0 <45223423@example.com>r   z<non-existent@example.com>z430 No Such Article Found)	r   rg   r   r&  r%   r&   rf   r(   r)   )r   r   r*  rS   ró   r   r*   r   r   r   Ú	test_body&  s*    





zNNTPv1v2TestsMixin.test_bodyc             C   sŒ   t  ¡ }| jj|d\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |g ¡ | ¡ }|  | d¡t|ƒ¡ |  	| 
d¡t|ƒ¡ d S )N)r‡   z"222 3000237 <45223423@example.com>i­Ç- z<45223423@example.com>sK   From: "Demo User" <nobody@example.net>
Subject: I am just a test article
sU   This is just a test article.
.Here is a dot-starting line.

-- Signed by AndrÃ©.
)rŸ   r¢   r   rg   r   r,  r   r   r-  r   rÏ   )r   r.  r   r*  rS   ró   r   r­   r   r   r   Útest_body_fileA  s    

z!NNTPv1v2TestsMixin.test_body_filec             C   s”   |   | d¡|¡ |  t|ƒd¡ |d \}}|  |d¡ |  |ddddd	d
dddœ¡ |d \}}|  |d d ¡ |d \}}|  |d d¡ d S )Nz224 r'  r   é9   zEDoug Hellmann <doug.hellmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>zGRe: ANN: New Plone book with strong Python (and Zope) themes throughoutzSat, 19 Jun 2010 18:04:08 -0400z0<4FD05F05-F98B-44DC-8111-C6009C925F0C@gmail.com>z<hvalf7$ort$1@dough.gmane.org>Z7103Z16z+news.gmane.org gmane.comp.python.authors:57)rI   rH   r.   z
message-idrJ   z:bytesz:linesÚxrefrZ   r5  rn   rH   u0   Re: Message d'erreur incomprÃ©hensible (par moi))r   r   r   r   )r   r   Ú	overviewsrS   rW   r   r   r   Úcheck_over_xover_respU  s$    

z(NNTPv1v2TestsMixin.check_over_xover_respc             C   s"   | j  dd¡\}}|  ||¡ d S )Nr4  é;   )r   rP   r7  )r   r   r6  r   r   r   rT   j  s    zNNTPv1v2TestsMixin.test_xoverc             C   s    | j  d¡\}}|  ||¡ d S )N)r4  r8  )r   rW   r7  )r   r   r6  r   r   r   rY   n  s    zNNTPv1v2TestsMixin.test_overs  From: "Demo User" <nobody@example.net>
Subject: I am just a test article
Content-Type: text/plain; charset=UTF-8; format=flowed
Message-ID: <i.am.an.article.you.will.want@example.com>

This is just a test article.
.Here is a dot-starting line.

-- Signed by AndrÃ©.
c             C   sl   | j j}|  t|ƒd¡ |  |d d¡ |  |d d¡ |  |d d¡ |  |d d	¡ |  |d
 d¡ d S )NrU   rV   s   .
rÍ   s   -- Signed by AndrÃ©.
r#  s   
r$  s    ..Here is a dot-starting line.
r   s(   From: "Demo User" <nobody@example.net>
)r¥   rñ   r   r   )r   r   r   r   r   Ú_check_posted_body  s    z%NNTPv1v2TestsMixin._check_posted_bodyc            G   sd   | j }|||ƒf }d | j_||Ž }|  ¡  | j  dd¡}|||ƒf }d | j_||Ž }|  ¡  |S )Ns   
ó   
)Úsample_postr¥   rñ   r9  Úreplace)r   ÚfuncÚfile_factoryr¿   ÚpostZ	func_argsr   r   r   r   Ú_check_post_ihave_subŠ  s    z(NNTPv1v2TestsMixin._check_post_ihave_subc             G   sÀ   | j |f|ždtiŽ}|  ||¡ | j |f|ždtiŽ}|  ||¡ | j |f|ždtjiŽ}|  ||¡ dd„ }| j |f|žd|iŽ}|  ||¡ dd„ }| j |f|žd|iŽ}|  ||¡ d S )Nr>  c             S   s   t | jddƒS )NT)Úkeepends)ÚiterrÜ   )r°   r   r   r   Ú	iterlines¥  s    z6NNTPv1v2TestsMixin.check_post_ihave.<locals>.iterlinesc             S   s   t | jddƒS )NF)rA  )rB  rÜ   )r°   r   r   r   rC  ª  s    )r@  r]   r   Ú	bytearrayrŸ   r¢   )r   r=  Zsuccess_respr¿   r   rC  r   r   r   Úcheck_post_ihaveš  s    z#NNTPv1v2TestsMixin.check_post_ihavec          	   C   sR   |   | jjd¡ d| j_|  tj¡}| j | j¡ W d Q R X |  	|j
jd¡ d S )Nz240 Article received OKFz440 Posting not permitted)rE  r   r?  r¥   rÅ   r%   r&   rf   r;  r   r(   r)   )r   r*   r   r   r   Ú	test_post¯  s    
zNNTPv1v2TestsMixin.test_postc          	   C   sN   |   | jjdd¡ |  tj¡}| j d| j¡ W d Q R X |  |jj	d¡ d S )Nz235 Article transferred OKz+<i.am.an.article.you.will.want@example.com>z<another.message.id>z435 Article not wanted)
rE  r   Zihaver%   r&   rf   r;  r   r(   r)   )r   r*   r   r   r   Ú
test_ihave·  s    
zNNTPv1v2TestsMixin.test_ihavec             C   s.   t   dddddd¡}|  tj| jjd|¡ d S )NiÚ  rZ   r  r   zcomp.lang.python)r-   r%   r&   ÚNNTPDataErrorr   r!  )r   r0   r   r   r   Útest_too_long_lines¿  s    z&NNTPv1v2TestsMixin.test_too_long_lines)%r   r	   r
   rº   r   r  rG   r  r   r"   r  r  r  r:   r=   rE   r"  r&  r(  r)  r+  r/  r0  r1  r2  r3  r7  rT   rY   r;  r9  r@  rE  rF  rG  rI  rÁ   r   r   )r¼   r   r  2  sB   
r  c               @   s    e Zd ZdZdZeZdd„ ZdS )ÚNNTPv1Testsz*Tests an NNTP v1 server (no capabilities).rZ   c             C   s:   | j  ¡ }|  |i ¡ |  | j jd¡ |  | j jd ¡ d S )NrZ   )r   rp   r   ro   Únntp_implementation)r   rl   r   r   r   Ú	test_capsË  s    
zNNTPv1Tests.test_capsN)r   r	   r
   r   ro   rÃ   r¾   rL  r   r   r   r   rJ  Å  s   rJ  c               @   s    e Zd ZdZdZeZdd„ ZdS )ÚNNTPv2Testsz,Tests an NNTP v2 server (with capabilities).rn   c             C   sb   | j  ¡ }|  |ddgddgdgg dddd	d
dgg g g dœ¡ |  | j jd¡ |  | j jd¡ d S )NÚ2Ú3ZINNz2.5.1ZUSERrè   zACTIVE.TIMESzDISTRIB.PATSZHEADERSré   zOVERVIEW.FMT)ÚVERSIONZIMPLEMENTATIONr	  ZHDRrj   ZOVERZPOSTÚREADERr'  z	INN 2.5.1)r   rp   r   ro   rK  )r   rl   r   r   r   rL  Ø  s    

zNNTPv2Tests.test_capsN)r   r	   r
   r   ro   rþ   r¾   rL  r   r   r   r   rM  Ò  s   rM  c               @   s    e Zd ZdZdZeZdd„ ZdS )ÚCapsAfterLoginNNTPv2TestszCTests a probably NNTP v2 server with capabilities only after login.rn   c             C   s2   |   | jji ¡ | j dd¡ |  d| jj¡ d S )Nr
  r  rP  )r   r   r  rv   r9   )r   r   r   r   Útest_caps_only_after_loginï  s    z4CapsAfterLoginNNTPv2Tests.test_caps_only_after_loginN)r   r	   r
   r   ro   r  r¾   rS  r   r   r   r   rR  é  s   rR  c               @   s    e Zd ZdZdZeZdd„ ZdS )ÚSendReaderNNTPv2TestszoSame tests as for v2 but we tell NTTP to send MODE READER to a server
    that isn't in READER mode by default.rn   c             C   s   |   d| jj¡ d S )NrQ  )r9   r   r  )r   r   r   r   Ú(test_we_are_in_reader_mode_after_connectý  s    z>SendReaderNNTPv2Tests.test_we_are_in_reader_mode_after_connectN)r   r	   r
   r   ro   r  r¾   rU  r   r   r   r   rT  õ  s   rT  c               @   sP   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Ze	 
ed¡dd„ ƒZdS )Ú	MiscTestsc                sV   ‡ fdd„}|ddƒ |ddƒ |ddƒ |ddƒ |dd	ƒ |d
dƒ |ddƒ d S )Nc                s   ˆ   t | ¡|¡ d S )N)r   r&   Údecode_header)Úar°   )r   r   r   Úgives  s    z+MiscTests.test_decode_header.<locals>.givesr7   za plain headerz with extra  spaces z%=?ISO-8859-15?Q?D=E9buter_en_Python?=u   DÃ©buter en Pythonz=?utf-8?q?Re=3A_=5Bsqlite=5D_probl=C3=A8me_avec_ORDER_BY_sur_des_cha?= =?utf-8?q?=C3=AEnes_de_caract=C3=A8res_accentu=C3=A9es?=uP   Re: [sqlite] problÃ¨me avec ORDER BY sur des chaÃ®nes de caractÃ¨res accentuÃ©esz,Re: =?UTF-8?B?cHJvYmzDqG1lIGRlIG1hdHJpY2U=?=u   Re: problÃ¨me de matriceu0   Re: Message d'erreur incomprÃ©hensible (par moi)r   )r   rY  r   )r   r   Útest_decode_header  s    



zMiscTests.test_decode_headerc             C   sD  dddddddg}|   t |¡dd	d
ddddg¡ dddddddg}|   t |¡dd	d
ddddg¡ dddddddg}|   t |¡dd	d
ddddg¡ dddddddddg	}|   t |¡dd	d
ddddddg	¡ dddddddddg	}|   t |¡dd	d
ddddddg	¡ ddddddddg}|   t |¡dd	d
dddddg¡ d S )NzSubject:zFrom:zDate:zMessage-ID:zReferences:z:bytesz:linesrH   rI   r.   z
message-idrJ   zBytes:zLines:zsubject:zFROM:zDaTe:zmessage-ID:zBYTES:z	Xref:fullzDistribution:fullr5  Zdistributionz	Xref:FULLzDistribution:FULL)r   r&   Z_parse_overview_fmt)r   r   r   r   r   Útest_parse_overview_fmt  s@    











z!MiscTests.test_parse_overview_fmtc             C   s¾   t jdg }dg}t  ||¡}|\\}}|  |d¡ |  |dddddd	d
ddœ¡ dg}t  ||¡}|\\}}|  |d d ¡ dg}t  ||¡}|\\}}|  |d d¡ |  |d d¡ d S )Nr5  z·3000234	I am just a test article	"Demo User" <nobody@example.com>	6 Oct 1998 04:38:40 -0500	<45223423@example.com>	<45454@example.net>	1234	17	Xref: news.example.com misc.test:3000363iªÇ- zI am just a test articlez "Demo User" <nobody@example.com>z6 Oct 1998 04:38:40 -0500z<45223423@example.com>z<45454@example.net>Z1234Z17z"news.example.com misc.test:3000363)rH   rI   r.   z
message-idrJ   z:bytesz:linesr5  z3000234	I am just a test article	"Demo User" <nobody@example.com>	6 Oct 1998 04:38:40 -0500	<45223423@example.com>	<45454@example.net>	1234	17		z„3000234	I am just a test article	"Demo User" <nobody@example.com>	6 Oct 1998 04:38:40 -0500	<45223423@example.com>	 	1234	17	Xref: 	rJ   ú r7   )r&   Z_DEFAULT_OVERVIEW_FMTZ_parse_overviewr   )r   rÿ   r   ZoverviewrS   Zfieldsr   r   r   Útest_parse_overview;  s.    



zMiscTests.test_parse_overviewc          	      sh   ‡ fdd„}|dd dddddd	ƒ |d
ddddddd	ƒ |dddddddd	ƒ |dddddddd	ƒ d S )Nc                s   ˆ   t | |¡tj|Ž ¡ d S )N)r   r&   Z_parse_datetimer-   )rX  r°   Úc)r   r   r   rY  j  s    z,MiscTests.test_parse_datetime.<locals>.givesZ19990623135624iÏ  r  é   r  é8   é   Ú19990623Ú135624Ú990623Z090623iÙ  r   )r   rY  r   )r   r   Útest_parse_datetimei  s
    zMiscTests.test_parse_datetimec          	      sŽ   ‡ fdd„}|ddddddd	d
ƒ |dddddddd
ƒ |ddddddddƒ ‡ fdd„}|dddd	dƒ |dddddƒ |dddddƒ d S )Nc       	         sF   t   | |||||¡}ˆ  t |¡||f¡ ˆ  t |d¡||f¡ d S )NF)r-   r   r&   Ú_unparse_datetime)	ÚyÚMÚdÚhr  Úsrí   rî   r0   )r   r   r   rY  w  s
    
z.MiscTests.test_unparse_datetime.<locals>.givesiÏ  r  r_  r  r`  ra  rb  rc  iÐ  Z20000623iÚ  r>   rZ   rn   r'  Z20100605Ú010203c                s@   t  | ||¡}ˆ  t |¡||f¡ ˆ  t |d¡||f¡ d S )NF)r-   r.   r   r&   rf  )rg  rh  ri  rí   rî   r0   )r   r   r   rY    s
    
Ú000000r   )r   rY  r   )r   r   Útest_unparse_datetimet  s    zMiscTests.test_unparse_datetimec          	      sŽ   ‡ fdd„}|ddddddd	d
ƒ |dddddddd
ƒ |ddddddddƒ ‡ fdd„}|dddd	dƒ |dddddƒ |dddddƒ d S )Nc       	         s0   t   | |||||¡}ˆ  t |d¡||f¡ d S )NT)r-   r   r&   rf  )	rg  rh  ri  rj  r  rk  rí   rî   r0   )r   r   r   rY  Ž  s    z5MiscTests.test_unparse_datetime_legacy.<locals>.givesiÏ  r  r_  r  r`  ra  rd  rc  iÐ  Z000623iÚ  r>   rZ   rn   r'  Z100605rl  c                s*   t  | ||¡}ˆ  t |d¡||f¡ d S )NT)r-   r.   r   r&   rf  )rg  rh  ri  rí   rî   r0   )r   r   r   rY  –  s    rm  r   )r   rY  r   )r   r   Útest_unparse_datetime_legacy‹  s    z&MiscTests.test_unparse_datetime_legacyzrequires SSL supportc             C   s   |   ttdƒ¡ d S )Nrœ   )r   rˆ   r&   )r   r   r   r   Útest_ssl_supportž  s    zMiscTests.test_ssl_supportN)r   r	   r
   rZ  r[  r]  re  rn  ro  r’   Ú
skipUnlessÚsslrp  r   r   r   r   rV    s   (.rV  c               @   s   e Zd ZdZdd„ ZdS )ÚPublicAPITestsz>Ensures that the correct values are exposed in the public API.c             C   sP   |   ttdƒ¡ dddddddd	g}td k	r6| d
¡ |  ttjƒt|ƒ¡ d S )NÚ__all__r   ru   ÚNNTPReplyErrorrf   r'   ÚNNTPProtocolErrorrH  rW  rœ   )r   rˆ   r&   rr  rÎ   r   Úsetrt  )r   Z
target_apir   r   r   Útest_module_all_attribute¦  s    

z(PublicAPITests.test_module_all_attributeN)r   r	   r
   r   rx  r   r   r   r   rs  £  s   rs  c               @   sH   e Zd ZdZejZddd„Zdd„ Zdd„ Z	d	d
„ Z
dd„ Zdd„ ZdS )ÚMockSocketTestszaTests involving a mock socket object

    Used where the _NNTPServerIO file object is not enough.Nc          
      s–   G ‡ fdd„dƒ}G ‡‡‡fdd„dƒ‰ d‰g ‰t d|ƒ. |  ||¡ | jd||d W d Q R X W d Q R X |  ˆ¡ xˆD ]}|  |j¡ q~W d S )	Nc                   s   e Zd Z‡ fdd„ZdS )zNMockSocketTests.check_constructor_error_conditions.<locals>.mock_socket_modulec                s   ˆ ƒ S )Nr   )ZaddressrŒ   )Ú
MockSocketr   r   Úcreate_connection¼  s    z`MockSocketTests.check_constructor_error_conditions.<locals>.mock_socket_module.create_connectionN)r   r	   r
   r{  r   )rz  r   r   Úmock_socket_module»  s   r|  c                   s&   e Zd Z‡fdd„Z‡ ‡fdd„ZdS )zFMockSocketTests.check_constructor_error_conditions.<locals>.MockSocketc                s   d‰ d S )NTr   )r   )Úsocket_closedr   r   ÚcloseÀ  s    zLMockSocketTests.check_constructor_error_conditions.<locals>.MockSocket.closec                s    ˆƒ }t |ƒ\}}ˆ  |¡ |S )N)r·   rÎ   )ÚsocketÚmoder¥   r  r‡   )Úfilesr¾   r   r   ÚmakefileÄ  s    
zOMockSocketTests.check_constructor_error_conditions.<locals>.MockSocket.makefileN)r   r	   r
   r~  r‚  r   )r  r¾   r}  r   r   rz  ¿  s   rz  Fznntplib.socketZdummy)rr   rs   )r   ZassertRaisesRegexÚ
nntp_classr   r  )r   r¾   Zexpected_error_typeZexpected_error_msgrv   rs   r|  r.  r   )rz  r  r¾   r}  r   Ú"check_constructor_error_conditions¶  s    $

z2MockSocketTests.check_constructor_error_conditionsc             C   s&   G dd„ dt ƒ}|  |tj|j¡ d S )Nc               @   s   e Zd ZdZdS )z1MockSocketTests.test_bad_welcome.<locals>.HandlerzBad WelcomeN)r   r	   r
   r   r   r   r   r   ÚHandlerÕ  s   r…  )rÃ   r„  r&   rv  r   )r   r…  r   r   r   Útest_bad_welcomeÓ  s    z MockSocketTests.test_bad_welcomec             C   s&   G dd„ dt ƒ}|  |tj|j¡ d S )Nc               @   s   e Zd ZdZdS )zEMockSocketTests.test_service_temporarily_unavailable.<locals>.Handlerz#400 Service temporarily unavailableN)r   r	   r
   r   r   r   r   r   r…  Ü  s   r…  )rÃ   r„  r&   rf   r   )r   r…  r   r   r   Ú$test_service_temporarily_unavailableÚ  s    z4MockSocketTests.test_service_temporarily_unavailablec             C   s&   G dd„ dt ƒ}|  |tj|j¡ d S )Nc               @   s   e Zd ZdZdS )zEMockSocketTests.test_service_permanently_unavailable.<locals>.Handlerz#502 Service permanently unavailableN)r   r	   r
   r   r   r   r   r   r…  ã  s   r…  )rÃ   r„  r&   r'   r   )r   r…  r   r   r   Ú$test_service_permanently_unavailableá  s    z4MockSocketTests.test_service_permanently_unavailablec                s,   G ‡ fdd„dt ƒ}d‰ |  |tjˆ ¡ d S )Nc                   s   e Zd Z‡ fdd„ZdS )z6MockSocketTests.test_bad_capabilities.<locals>.Handlerc                s   |   ˆ ¡ d S )N)rÞ   )r   )Úcapabilities_responser   r   r   ë  s    zJMockSocketTests.test_bad_capabilities.<locals>.Handler.handle_CAPABILITIESN)r   r	   r
   r   r   )r‰  r   r   r…  ê  s   r…  z201 bad capability)rÃ   r„  r&   ru  )r   r…  r   )r‰  r   Útest_bad_capabilitiesè  s    z%MockSocketTests.test_bad_capabilitiesc                s8   d}d}G ‡ fdd„dt ƒ}d‰ |  |tjˆ ||¡ d S )Nzt@e.comZpythonc                   s   e Zd Z‡ fdd„ZdS )z3MockSocketTests.test_login_aborted.<locals>.Handlerc                s   |   ˆ ¡ d S )N)rÞ   )r   r¿   )Úauthinfo_responser   r   rý   ö  s    zCMockSocketTests.test_login_aborted.<locals>.Handler.handle_AUTHINFON)r   r	   r
   rý   r   )r‹  r   r   r…  õ  s   r…  z503 Mechanism not recognized)rÃ   r„  r&   r'   )r   rv   rs   r…  r   )r‹  r   Útest_login_abortedñ  s    z"MockSocketTests.test_login_aborted)NN)r   r	   r
   r   r&   r   rƒ  r„  r†  r‡  rˆ  rŠ  rŒ  r   r   r   r   ry  ¯  s   
	ry  c               @   s   e Zd ZdZdd„ ZdS )Úbypass_contextz'Bypass encryption and actual SSL modulec             K   s   | S )Nr   )Úsockr¿   r   r   r   Úwrap_socketÿ  s    zbypass_context.wrap_socketN)r   r	   r
   r   r  r   r   r   r   r  ý  s   r  c               @   s   e Zd Zedd„ ƒZdS )ÚMockSslTestsc              O   s   t j| dti|—ŽS )NZssl_context)r&   rœ   r  )r®   Úkwr   r   r   rƒ    s    zMockSslTests.nntp_classN)r   r	   r
   Ústaticmethodrƒ  r   r   r   r   r    s   r  c               @   s0   e Zd Zdd„ Zdd„ Ze ed¡dd„ ƒZdS )	ÚLocalServerTestsc             C   st   t   ¡ }t |¡}| ¡  tj| j|fd| _| j ¡  |  	| jj
¡ ttj|dd ¡ | _|  	| jjd d d ¡ d S )N)Útargetr¿   F)rt   )r  r   Z	bind_portZlistenÚ	threadingZThreadÚ
run_serverZ
backgroundrX   Z
addCleanuprÛ   r   ZHOSTÚ	__enter__ÚnntpÚ__exit__)r   rŽ  Zportr   r   r   rº   
  s    

zLocalServerTests.setUpc          	   C   sô   | |  ¡ \}}W d Q R X t ¡ Æ}| |¡ | | d¡¡}| d¡ xš| ¡ }|dkrh| d¡ qL|dkr¾| ¡  | d¡ t 	¡ }| 
t¡ |j|dd}| |¡ | | d¡¡}qL|d	krÔ| d
¡ P qLtd |¡ƒ‚qLW W d Q R X d S )NÚrbs   200 Server ready
s   CAPABILITIES
s.   101 Capability list:
VERSION 2
STARTTLS
.
s
   STARTTLS
s   382 Begin TLS negotiation now
T)Zserver_sides   QUIT
s
   205 Bye!
zUnexpected command {!r})ZacceptÚ
contextlibÚ	ExitStackÚenter_contextr‚  Zsendallr¦   r~  rr  Z
SSLContextZload_cert_chainÚcertfiler  rÐ   rÑ   )r   rŽ  Zclientr  Zcleanupr  r×   Úcontextr   r   r   r–    s0    







zLocalServerTests.run_serverzrequires SSL supportc             C   s`   | j j}| j j}| j  ¡  |  || j j¡ |  || j j¡ |  | j jtj¡ |  t	| j j¡ d S )N)
r˜  r‡   rŽ  ZstarttlsZassertNotEqualr/   rr  Z	SSLSocketr%   rÐ   )r   r‡   rŽ  r   r   r   r   6  s    
zLocalServerTests.test_starttlsN)	r   r	   r
   rº   r–  r’   rq  rr  r   r   r   r   r   r“  	  s    r“  Ú__main__);rŸ   r  r-   rÙ   r’   r   r›  Zos.pathÚosr   r•  Ztestr   r&   r   r   Zunittest.mockr   rr  ÚImportErrorrŽ   ÚpathrÛ   ÚdirnameÚ__file__rž  r   rÕ   r   r†   rŠ   r˜   ZSSLEOFErrorZTestCaser—   rq  r›   r    rž   r·   r¸   rÂ   rÃ   rþ   r  r  r  rJ  rM  rR  rT  rV  rs  ry  r  r  r“  r   Úmainr   r   r   r   Ú<module>   sx   

 |
,  G
    #N<
