a
    äze‰ù  ã                   @   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Zd dlmZ d dlmZ d dlmZmZ d dlmZ zd dlZW n ey®   dZY n0 e	j e	j e¡d¡ZedurÖejZnG dd„ deƒZG d	d
„ d
ƒZe ¡  efZ edu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ejƒ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#ƒZ0G d$d%„ d%e0e*ej"ƒZ1G d&d'„ d'e0e*ej"ƒZ2G d(d)„ d)e*ej"ƒZ3G d*d+„ d+e+ej"ƒZ4G d,d-„ d-ej"ƒZ5G d.d/„ d/ej"ƒZ6G d0d1„ d1ej"ƒZ7G d2d3„ d3ƒZ8e $ed¡G d4d5„ d5e7ƒƒZ9G d6d7„ d7ej"ƒZ:e;d8kr¶e <¡  dS )9é    N)Úsupport)Úsocket_helper)ÚNNTPÚ	GroupInfo)Úpatchz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.9/test/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d1d 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/d0„ ZdS )2Ú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   s>   | j  ¡ \}}|  | d¡|¡ |D ]}|  tt|ƒ¡ q$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 r   )	r   r    Ú	GROUP_PATr!   r   r   r   r   r"   r#   r   r   r   Útest_list_active8   s    z(NetworkedNNTPTestsMixin.test_list_activec                 C   sV   |   tj¡}| j d¡ W d   ƒ n1 s.0    Y  |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                    sb   ‡ fdd„}ˆ j  ˆ j¡}||ƒ ˆ  ˆ j|¡ ˆ j  ˆ j¡}||ƒ ˆ j  d¡}ˆ  |d¡ d S )Nc                    s   ˆ   | t¡ ˆ  ˆ j| ¡ d S r   )r2   r   ÚassertNotInÚ
GROUP_NAME)Údesc©r   r   r   Ú_check_descN   s    z=NetworkedNNTPTestsMixin.test_description.<locals>._check_desczzk.brrtt.bazÚ )r   Údescriptionr6   ÚassertInÚDESCr&   r   )r   r9   r7   r   r8   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   r2   Údictr6   r   r;   )r   r   Zdescsr7   r   r   r   Útest_descriptions]   s    ÿ
z)NetworkedNNTPTestsMixin.test_descriptionsc                 C   s€   | j  | j¡}|  dt|ƒ¡ |\}}}}}|  || j¡ |  |t¡ |  |t¡ |  |t¡ |  ||¡ |  | 	d¡|¡ d S )Né   ú211 )
r   r"   r6   r   r!   r2   Ú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   r1   r2   r0   ÚassertGreaterEqualZyearrE   ©r   r   r1   r   r   r   Ú	test_dateq   s    z!NetworkedNNTPTestsMixin.test_datec                 C   sF   |   |t¡ |  | ¡ h d£¡ | ¡ D ]}|   |ttd ƒf¡ q(d S )N>   Úfromú:linesÚsubjectú:bytesr1   Ú
referencesú
message-id)r2   r@   rK   Ú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 )NrB   r   zno articles retrieved)	r   r"   r6   Úxoverr!   ÚskipTestrK   rE   rX   )	r   r   rG   rH   rI   Únamer   Úart_numrV   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"   r6   ÚoverrX   rK   rE   )
r   r   rG   rH   rI   r[   Ústartr   r\   rV   r   r   r   Ú	test_overŽ   s    
z!NetworkedNNTPTestsMixin.test_overc                 C   sL   | j  | j¡\}}}}}| j  d|¡\}}|D ]}|  tt|d ƒ¡ q.d S )NrP   é   )r   r"   r6   Zxhdrr   r   r   )r   r   rG   rH   rI   r[   r   r   r   r   r   Ú	test_xhdr¡   s    z!NetworkedNNTPTestsMixin.test_xhdrNc                 C   sR   |   |tj¡ |d ur$|  |j|¡ |jD ]}|   |t¡ q*|  |jd d¡ d S )Nr_   )ó   .s   .
ó   .
)r2   r)   ZArticleInfor   Znumberr   Úbytesr5   )r   r   Úarticler\   r   r   r   r   Úcheck_article_resp§   s    
z*NetworkedNNTPTestsMixin.check_article_respzFIXME: see bpo-32128c                    s\  | j  | j¡\}}}}}|||d fD ]^}z| j  |¡\}}W n@ tjy~ } z&|j d¡s^‚ W Y d }~q&W Y d }~n
d }~0 0  qq&|  d¡ |  	| d¡|¡ |  
|||¡ | j  |¡\}}	|  	| d¡|¡ |  
||	|¡ | j  |¡\}}
|  	| d¡|¡ |  
||
|¡ dd„ ‰ ‡ fd	d
„|jD ƒ}‡ fdd
„|
jD ƒ}|  ||dg |	j ¡ d S )Nrc   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   ©Z	blacklistr   r   Ú
<listcomp>É   s   ÿzBNetworkedNNTPTestsMixin.test_article_head_body.<locals>.<listcomp>c                    s   g | ]}ˆ |ƒs|‘qS r   r   rl   rn   r   r   ro   Ë   s   ÿrk   )r   r"   r6   Úheadr)   ÚNNTPTemporaryErrorr,   r   rZ   r   ri   Úbodyrh   r   r   )r   r   rG   rH   rI   r[   r\   rp   Úerr   rh   Zfiltered_head_linesZfiltered_linesr   rn   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ÚLISTúOVERVIEW.FMT)r2   r    Útupler<   )ÚcapsZ	caps_listr8   r   r   Ú_check_capsÓ   s    z>NetworkedNNTPTestsMixin.test_capabilities.<locals>._check_capsé   )rK   r   Únntp_versionÚgetcapabilitiesZcapabilities)r   ry   r   rx   r   r8   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 |_nd |_0 d S r   )r   r   Úquit)r   Úclsr   r   r   Útest_zzquitê   s    z#NetworkedNNTPTestsMixin.test_zzquitc                 C   sJ   dd„ }t | ƒD ]4}| d¡s qt| |ƒ}t|ƒs4qt| |||ƒƒ qd S )Nc                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                    s8   t  | j¡ ˆ | ƒ W d   ƒ n1 s*0    Y  d S r   )r   Útransient_internetÚ	NNTP_HOSTr8   ©Ú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)r…   rŽ   r[   rŠ   r   r   r   Úwrap_methodsò   s    

z$NetworkedNNTPTestsMixin.wrap_methodsc                 C   s@   |   t¡" | j| jddd W d   ƒ n1 s20    Y  d S )Nr   F©Útimeoutr€   )r(   Ú
ValueErrorÚ
NNTP_CLASSrˆ   r8   r   r   r   Útest_timeout  s    z$NetworkedNNTPTestsMixin.test_timeoutc              
      s  ‡ fdd„}z®| j | jtjdd‰ ˆ * |  |ƒ ¡ |  ˆ  ¡ ¡ W d   ƒ n1 sV0    Y  |  |ƒ ¡ | j | jtjdd‰ ˆ  ˆ  ¡  W d   ƒ n1 s¢0    Y  |  |ƒ ¡ W nN ty } z4t	 
d|j¡ròt d|› d| j›¡‚‚ W Y d }~n
d }~0 0 d S )Nc                	      s8   t ˆ dƒsdS zˆ  ¡  W n ttfy2   Y dS 0 dS )NÚfileFT)Úhasattrr   ÚOSErrorÚEOFErrorr   ©r   r   r   Úis_connected  s    
zANetworkedNNTPTestsMixin.test_with_statement.<locals>.is_connectedFr”   ú(?i)KEY.TOO.SMALLzGot ú connecting to )r—   rˆ   r   ÚINTERNET_TIMEOUTr   r   ÚassertFalser„   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.   r4   r>   rA   rJ   rM   rX   r]   r¥   ZskipIfrb   rd   ri   rt   r}   rƒ   r†   Úclassmethodr“   r˜   r¨   r   r   r   r   r   &   s2   		


	


r   c                   @   s8   e Zd ZdZdZdZdZeZe	dd„ ƒZ
e	dd„ ƒZd	S )
ÚNetworkedNNTPTestsznews.trigofacile.comúfr.comp.lang.pythonzfr.comp.lang.*ÚPythonc                 C   sÌ   t  d¡ t | j¡¢ z| j| jt jdd| _W nv ty‚ } z8t	 
d|j¡rlt | › d|› d| j›¡‚‚ W Y d }~n0d }~0  ty¨   t | › d| j›¡‚Y n0 W d   ƒ n1 s¾0    Y  d S )NZnetworkFr”   rŸ   z got r    z  got EOF error on connecting to )r   Zrequiresr   r‡   rˆ   r—   r¡   r   r   r£   r¤   r   r¥   r¦   Ú
EOF_ERRORS)r…   r§   r   r   r   Ú
setUpClass<  s"    
þÿ
ÿzNetworkedNNTPTests.setUpClassc                 C   s   | j d ur| j  ¡  d S r   )r   r„   )r…   r   r   r   ÚtearDownClassN  s    
z NetworkedNNTPTests.tearDownClassN)r   r	   r
   rˆ   r6   r&   r=   r   r—   r©   r®   r¯   r   r   r   r   rª   3  s   
rª   úrequires SSL supportc                   @   s0   e Zd 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	aioe.testzaioe.*ÚtestÚNNTP_SSLN)r   r	   r
   rˆ   r6   r&   r=   r   r)   r—   r%   Útest_starttlsr   r   r   r   r±   S  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 r   )
ÚioÚ	RawIOBaseÚ__init__ÚBytesIOÚc2sÚs2cÚhandlerra   ÚreadlineÚ	push_data)r   r¼   r   r   r   r¸   s  s
    

z_NNTPServerIO.__init__c                 C   s   dS ©NTr   r8   r   r   r   Úreadable|  s    z_NNTPServerIO.readablec                 C   s   dS r¿   r   r8   r   r   r   Úwritable  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   rz   N)r»   ÚtellÚseekÚwrite)r   ÚdataÚposr   r   r   r¾   ‚  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Ä   ‰  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µ   n  s   	rµ   c                 C   s   t | ƒ}t ||¡}||fS r   )rµ   r¶   ÚBufferedRWPair)r¼   Úsior™   r   r   r   Úmake_mock_fileš  s    rÏ   c                   @   s   e Zd Zddd„Zdd„ ZdS )Ú
NNTPServerNc                 C   s   || _ || _|  |¡ d S r   )r™   ÚhostZ
_base_init)r   ÚfrÑ   Ú
readermoder   r   r   r¸   ¤  s    zNNTPServer.__init__c                 C   s   | j  ¡  | ` d S r   )r™   Úcloser8   r   r   r   Ú_close©  s    
zNNTPServer._close)N)r   r	   r
   r¸   rÕ   r   r   r   r   rÐ   ¢  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 r   ©ÚsuperÚsetUpÚmake_serverr8   ©Ú	__class__r   r   rÙ   ²  s    
zMockedNNTPTestsMixin.setUpc                    s   t ƒ  ¡  | `d S r   )rØ   ÚtearDownr   r8   rÛ   r   r   rÝ   ¶  s    
zMockedNNTPTestsMixin.tearDownc                 O   s:   |   ¡ | _t| jƒ\| _}t|dg|¢R i |¤Ž| _| jS )Nztest.server)Úhandler_classr¼   rÏ   rÎ   rÐ   r   )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)rÓ   r×   r8   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   ra   Ì  s    zNNTPv1Handler.startc                 C   s   t |ddƒS )Núutf-8Úsurrogateescape)r   ©r   rÅ   r   r   r   Ú_decodeÖ  s    zNNTPv1Handler._decodec              
   C   s@  | j rt|  ¡ }|sd S | j |¡ |dkrq.qz0| j\}}||d| jiŽ W d | _d | _d| _ nd | _d | _d| _ 0 |  |  ¡ ¡}|sŠd S | d¡s¢td |¡ƒ‚|d d… }| 	¡ ^}}t
| d| ¡  d ƒ}|d u rà|  ¡  qtz||Ž  W n6 ty" } ztd |¡ƒ|‚W Y d }~qtd }~0 0 | j rt||f| _g | _qtd S )	Nrf   rr   Fú
z line doesn't end with \r\n: {!r}éþÿÿÿZhandle_zcommand failed: {!r})rä   ræ   rr   ÚappendZbody_callbackrî   Úendswithr–   ÚformatÚsplitr   ÚupperÚhandle_unknownÚ	Exception)r   r   rŠ   ÚtokensÚcmdrs   r   r   r   rÇ   Ù  sB    
þ

&
zNNTPv1Handler.process_pendingc                 C   s
   d| _ dS )z7Flag that the client is expected to post a request bodyTN)rä   r8   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¾     s    zNNTPv1Handler.push_datac                 C   s4   t  |¡}d | ¡ ¡d }| d¡}|  |¡ dS )zPush a string literalrï   rë   N)Ú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   r8   r   r   r   rö     s    zNNTPv1Handler.handle_unknownc                 C   s   |   | j¡ d S r   )r   r   r8   r   r   r   rê     s    zNNTPv1Handler.handle_welcomec                 C   s   |   d¡ d S ©Nz205 Bye!r  r8   r   r   r   Úhandle_QUIT  s    zNNTPv1Handler.handle_QUITc                 C   s   |   d¡ d S )Nú111 20100914001155r  r8   r   r   r   Úhandle_DATE  s    zNNTPv1Handler.handle_DATEc                 C   s(   |dkr|   d¡ n|   d |¡¡ d S )Nr«   z$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  r8   r   r   r   Úhandle_HELP   s    zNNTPv1Handler.handle_HELPNc                 C   sJ   |d u r|   d¡ n2|dkr(|   d¡ n|dkr<|   d¡ n
|   d¡ d S )Nú412 No newsgroup selectedÚ3000234ú"223 3000234 <45223423@example.com>ú<45223423@example.com>ú223 0 <45223423@example.com>ú430 No Such Article Foundr  ©r   Zmessage_specr   r   r   Úhandle_STAT)  s    zNNTPv1Handler.handle_STATc                 C   s   |   d¡ d S )Nú*223 3000237 <668929@example.org> retrievedr  r8   r   r   r   Úhandle_NEXT3  s    zNNTPv1Handler.handle_NEXTc                 C   s   |   d¡ d S )Nú,223 3000234 <45223423@example.com> retrievedr  r8   r   r   r   Úhandle_LAST6  s    zNNTPv1Handler.handle_LASTc                 C   sš   |d u r|   d¡ n‚|dkr<|dkr0|   d¡ q–|   d¡ nZ|dkrP|   d¡ nF|dkrŒ|d	krl|   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
                .ÚACTIVEú*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"
                    .rv   a                  215 Order of fields in overview database.
                Subject:
                From:
                Date:
                Message-ID:
                References:
                Bytes:
                Lines:
                Xref:full
                .Ú
NEWSGROUPSúcomp.lang.pythonzš                    215 Descriptions in form "group description".
                    comp.lang.python	The Python computer language.
                    .ú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 keywordr  )r   ÚactionZparamr   r   r   Úhandle_LIST9  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v rt|dkrt|   d	d
 d ¡ n
|   d¡ d S )Nr  Z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_NEWNEWSo  s"    ÿÿÿþ
ÿzNNTPv1Handler.handle_NEWNEWSc                 C   s"   |dkr|   d¡ n
|   d¡ d S )Nz57-59uK  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.io 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   Úhandle_XOVERŽ  s
    ÿzNNTPv1Handler.handle_XOVER)rr   c                C   sB   |d u r.| j r"|  d¡ |  ¡  q>|  d¡ n|  d¡ || _d S )Nz+340 Input article; end with <CR-LF>.<CR-LF>ú440 Posting not permittedú240 Article received OK©rå   r   rú   Úposted_body)r   rr   r   r   r   Úhandle_POST®  s    


zNNTPv1Handler.handle_POSTc                C   sJ   |d u r6| j r*|dkr*|  d¡ |  ¡  qF|  d¡ n|  d¡ || _d S )Nú+<i.am.an.article.you.will.want@example.com>z%335 Send it; end with <CR-LF>.<CR-LF>ú435 Article not wantedú235 Article transferred OKr!  )r   Ú
message_idrr   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 u r|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nú"220 3000237 <45223423@example.com>r  ú220 0 <45223423@example.com>r	  ú"220 3000234 <45223423@example.com>r  Ú.)r   Úsample_articler  r   r   r   Úhandle_ARTICLEÕ  s    
zNNTPv1Handler.handle_ARTICLEc                 C   sd   |d u r|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nú"221 3000237 <45223423@example.com>r  ú221 0 <45223423@example.com>r	  ú"221 3000234 <45223423@example.com>r  r,  )r   Úsample_headr  r   r   r   Úhandle_HEADâ  s    
zNNTPv1Handler.handle_HEADc                 C   sd   |d u r|   d¡ n6|dkr(|   d¡ n"|dkr<|   d¡ n|   d¡ d S |   | j¡ |   d¡ d S )Nú"222 3000237 <45223423@example.com>r  ú222 0 <45223423@example.com>r	  ú"222 3000234 <45223423@example.com>r  r,  )r   Úsample_bodyr  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 Inr~   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   ra   rî   rÇ   rú   r¾   r   rö   rê   r  r  r  r  r  r  r  r  r  r  r#  r(  r2  r7  r-  r.  r3  r8  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 USERr:   )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 r   )r  r  r   r   r   Úhandle_OVER#  s    zNNTPv2Handler.handle_OVER)N)r   r	   r
   r   r>  r@  rA  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>  r8   rÛ   r   r   r>  *  s    z/CapsAfterLoginNNTPv2Handler.handle_CAPABILITIES)r   r	   r
   r   r>  rá   r   r   rÛ   r   rB  '  s   rB  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)Ú	_switchedr8   r   r   r   r¸   4  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
            .r:   zMODE-)rE  r   ró   r<  r   r   r   r>  7  s    
z.ModeSwitchingNNTPv2Handler.handle_CAPABILITIESc                 C   s   d| _ |  d¡ d S )NTz200 Posting allowed)rE  r   )r   Zwhatr   r   r   r@  G  s    z&ModeSwitchingNNTPv2Handler.handle_MODEN)r   r	   r
   r   r¸   r>  r@  r   r   r   r   rC  1  s   rC  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 r   )rØ   rÙ   r8   rÛ   r   r   rÙ   O  s    zNNTPv1v2TestsMixin.setUpc                 C   s   |   | jj| jj¡ d S r   )r   r   r   r¼   r8   r   r   r   r   R  s    zNNTPv1v2TestsMixin.test_welcomec                 C   s<   | j dkr|  d| jj¡ | j dd¡ |  d| jj¡ d S )Nrz   ÚAUTHINFOÚtestuserÚtestpw)r{   r<   r   Ú_capsr‚   r5   r8   r   r   r   Útest_authinfoU  s    
z NNTPv1v2TestsMixin.test_authinfoc                 C   s:   | j  ¡ \}}|  |d¡ |  |t dddddd¡¡ d S )Nr  éÚ  é	   é   r   é   é7   )r   r1   r   r0   rL   r   r   r   rM   ]  s    zNNTPv1v2TestsMixin.test_datec                 C   s6   |   | jj¡ | j ¡ }|  |d¡ |  | jj¡ d S r  )r¢   rÎ   Úclosedr   r„   r   r   )r   r   r   r   r   Ú	test_quitb  s    
zNNTPv1v2TestsMixin.test_quitc                 C   s.   | j  ¡ \}}|  |d¡ |  |g d¢¡ d S )Nz100 Legal commands)z8  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   h  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é   rc   úcomp.lang.python.announceZ
0000001153Z
0000000993Úmr  rz   r   z!gmane.comp.python.distutils.develZ
0000014104Z
0000000001)r   r    r   r!   r   )r   r   r$   Úgr   r   r   r%   r  s     ÿÿÿÿzNNTPv1v2TestsMixin.test_listc                 C   sþ   | j  d¡\}}}|  |d¡ |  |d¡ |  |d¡ | j  d¡\}}}|  |d¡ |  |d¡ |  |d¡ |  tj¡}| j  d¡ W d   ƒ n1 sš0    Y  |  |jjd¡ |  tj¡}| j  ¡  W d   ƒ n1 sà0    Y  |  |jjd¡ d S )	NéªÇ- r
  r  r  r   z<non.existent.id>r  r  )r   Ústatr   r(   r)   rq   r+   r,   )r   r   r\   r'  r-   r   r   r   Ú	test_stat€  s    *(zNNTPv1v2TestsMixin.test_statc                 C   s8   | j  ¡ \}}}|  |d¡ |  |d¡ |  |d¡ d S )Nr  é­Ç- z<668929@example.org>)r   Únextr   ©r   r   r\   r'  r   r   r   Ú	test_next  s    zNNTPv1v2TestsMixin.test_nextc                 C   s8   | j  ¡ \}}}|  |d¡ |  |d¡ |  |d¡ d S )Nr  rW  r  )r   rI   r   r\  r   r   r   Ú	test_last–  s    zNNTPv1v2TestsMixin.test_lastc                 C   s4   | j  d¡}|  |d¡ | j  d¡}|  |d¡ d S )Nr  úThe Python computer language.úcomp.lang.pythonxr:   )r   r;   r   )r   r7   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 )Nr  z-215 Descriptions in form "group description".r_  r  z4Announcements about the Python language. (Moderated))r  rT  r`  )r   r?   r   r#   r   r   r   rA   ¢  s    ÿþz$NNTPv1v2TestsMixin.test_descriptionsc                 C   s°   | j  d¡\}}}}}|  | d¡|¡ |  |d¡ |  |d¡ |  |d¡ |  |d¡ |  tj¡}| j  d¡ W d   ƒ n1 s†0    Y  |j}|  |j	 d¡|j	¡ d S )Nr«   rC   iù  iñ  iæ  zcomp.lang.python.develz411 No such group)
r   r"   r   r   r   r(   r)   rq   r+   r,   )r   r   rG   rH   rI   r"   r-   Úexcr   r   r   rJ   °  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 )NrL  rM  é   é   é   é   r  zS230 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>r«   z)230 An empty list of newsarticles follows)r0   r   Únewnewsró   r{   r   )r   r3   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 )Nre  r_   rë   u   -- Signed by AndrÃ©.rð   rk   éýÿÿÿ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 )Nre  r   s&   From: "Demo User" <nobody@example.net>é   s7   Message-ID: <i.am.an.article.you.will.want@example.com>)r   r!   rk  r   r   r   Ú_check_article_head×  s    z&NNTPv1v2TestsMixin._check_article_headc                 C   sH   |   t|ƒd¡ |  |d d… ¡ |  |dd … ¡ |   |d d¡ d S )NrM  re  ri  rk   )r   r!   rn  rl  rk  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   ƒ n1 s0    Y  |  |jjd	¡ d S )
Nr)  rZ  r  rW  r+  r*  r   ú<non-existent@example.com>r  )	r   rh   r   ro  r(   r)   rq   r+   r,   ©r   r   Úinfor\   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™   r)  rZ  r  óK   From: "Demo User" <nobody@example.net>
Subject: I am just a test article
óU   This is just a test article.
.Here is a dot-starting line.

-- Signed by AndrÃ©.
)
r¶   r¹   r   rh   r   Úgetvaluer   r   Úasciirò   ©r   rÒ   r   rr  r\   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   ƒ n1 s0    Y  |  |jjd	¡ d S )
Nr/  rZ  r  rW  r1  r0  r   rp  r  )	r   rp   r   rn  r(   r)   rq   r+   r,   rq  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 )Nrt  r/  rZ  r  ru  rv  )r¶   r¹   r   rp   r   rw  r   r   rx  r¢   rò   ry  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   ƒ n1 s0    Y  |  |jjd	¡ d S )
Nr4  rZ  r  rW  r6  r5  r   rp  r  )	r   rr   r   rl  r(   r)   rq   r+   r,   rq  r   r   r   Ú	test_bodyA  s*    





,zNNTPv1v2TestsMixin.test_bodyc                 C   sŒ   t  ¡ }| jj|d\}}|  |d¡ |\}}}|  |d¡ |  |d¡ |  |g ¡ | ¡ }|  | d¡t|ƒ¡ |  	| 
d¡t|ƒ¡ d S )Nrt  r4  rZ  r  ru  rv  )r¶   r¹   r   rr   r   rw  r¢   r   rx  r   rò   ry  r   r   r   Útest_body_file\  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 rm  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.io gmane.comp.python.authors:57)rN   rP   r1   rS   rR   rQ   rO   Úxrefrc   r€  rz   rP   õ0   Re: Message d'erreur incomprÃ©hensible (par moi))r   r   r   r!   )r   r   Ú	overviewsr\   r`   r   r   r   Úcheck_over_xover_respp  s(    ø

ÿz(NNTPv1v2TestsMixin.check_over_xover_respc                 C   s"   | j  dd¡\}}|  ||¡ d S )Nr  é;   )r   rY   rƒ  ©r   r   r‚  r   r   r   r]   …  s    zNNTPv1v2TestsMixin.test_xoverc                 C   s    | j  d¡\}}|  ||¡ d S )N)r  r„  )r   r`   rƒ  r…  r   r   r   rb   ‰  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 )Nr^   r_   rf   rð   s   -- Signed by AndrÃ©.
rh  ó   
ri  s    ..Here is a dot-starting line.
r   s(   From: "Demo User" <nobody@example.net>
)r¼   r"  r   r!   rk  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 )Nr†  ó   
)Úsample_postr¼   r"  r‡  Ú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 |g|¢R dtiŽ}|  ||¡ | j |g|¢R dtiŽ}|  ||¡ | j |g|¢R dtjiŽ}|  ||¡ dd„ }| j |g|¢R d|iŽ}|  ||¡ dd„ }| j |g|¢R 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 )NFr  r‘  r“  r   r   r   r”  Å  s    )rŽ  rg   r   Ú	bytearrayr¶   r¹   )r   r‹  Zsuccess_resprß   r   r”  r   r   r   Úcheck_post_ihaveµ  s    z#NNTPv1v2TestsMixin.check_post_ihavec                 C   sf   |   | jjd¡ d| j_|  tj¡}| j | j¡ W d   ƒ n1 sH0    Y  |  	|j
jd¡ d S )Nr   Fr  )r–  r   r  r¼   rå   r(   r)   rq   r‰  r   r+   r,   ©r   r-   r   r   r   Ú	test_postÊ  s    ,
ÿzNNTPv1v2TestsMixin.test_postc                 C   sb   |   | jjdd¡ |  tj¡ }| j d| j¡ W d   ƒ n1 sD0    Y  |  |jj	d¡ d S )Nr&  r$  z<another.message.id>r%  )
r–  r   Zihaver(   r)   rq   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 )NrL  rc   rM  r   r  )r0   r(   r)   ÚNNTPDataErrorr   rf  )r   r3   r   r   r   Útest_too_long_linesÚ  s    
ÿz&NNTPv1v2TestsMixin.test_too_long_lines)%r   r	   r
   rÙ   r   rK  rM   rR  r   r%   rY  r]  r^  r>   rA   rJ   rg  rl  rn  ro  rs  rz  r{  r|  r}  r~  rƒ  r]   rb   r‰  r‡  rŽ  r–  r˜  r™  r›  rá   r   r   rÛ   r   rF  M  sD   
ÿrF  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).rc   c                 C   s:   | j  ¡ }|  |i ¡ |  | j jd¡ |  | j jd ¡ d S )Nrc   ©r   r|   r   r{   Znntp_implementation©r   rx   r   r   r   Ú	test_capsæ  s    
zNNTPv1Tests.test_capsN)r   r	   r
   r   r{   rã   rÞ   rŸ  r   r   r   r   rœ  à  s   rœ  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).rz   c                 C   sZ   | j  ¡ }|  |ddgddgdgg g d¢g g g dœ¡ |  | j jd¡ |  | j jd	¡ d S )
NÚ2Ú3ZINNz2.5.1ZUSER)r  zACTIVE.TIMESzDISTRIB.PATSZHEADERSr  rv   )ÚVERSIONZIMPLEMENTATIONrG  ZHDRru   ZOVERZPOSTÚREADERrm  z	INN 2.5.1r  rž  r   r   r   rŸ  ó  s    
÷zNNTPv2Tests.test_capsN)r   r	   r
   r   r{   r;  rÞ   rŸ  r   r   r   r   r   í  s   r   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.rz   c                 C   s2   |   | jji ¡ | j dd¡ |  d| jj¡ d S )NrH  rI  r£  )r   r   rJ  r‚   r<   r8   r   r   r   Útest_caps_only_after_login
  s    z4CapsAfterLoginNNTPv2Tests.test_caps_only_after_loginN)r   r	   r
   r   r{   rB  rÞ   r¦  r   r   r   r   r¥    s   r¥  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.rz   c                 C   s   |   d| jj¡ d S )Nr¤  )r<   r   rJ  r8   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   r{   rC  rÞ   r¨  r   r   r   r   r§    s   r§  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 r   )r   r)   Údecode_header)ÚarÈ   r8   r   r   Úgives  s    z+MiscTests.test_decode_header.<locals>.givesr:   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 matricer  r   ©r   r¬  r   r8   r   Útest_decode_header  s    



þÿÿzMiscTests.test_decode_headerc                 C   s¸   g d¢}|   t |¡g d¢¡ g d¢}|   t |¡g d¢¡ g d¢}|   t |¡g d¢¡ g d¢}|   t |¡g d¢¡ g d¢}|   t |¡g d¢¡ g d¢}|   t |¡g d	¢¡ d S )
N)úSubject:úFrom:úDate:úMessage-ID:úReferences:rQ   rO   )rP   rN   r1   rS   rR   rQ   rO   )r¯  r°  r±  r²  r³  úBytes:úLines:)zsubject:zFROM:zDaTe:zmessage-ID:r³  zBYTES:rµ  )	r¯  r°  r±  r²  r³  rQ   rO   ú	Xref:fullzDistribution:full)	rP   rN   r1   rS   rR   rQ   rO   r€  Zdistribution)	r¯  r°  r±  r²  r³  r´  rµ  z	Xref:FULLzDistribution:FULL)r¯  r°  r±  r²  r³  r´  rµ  r¶  ©rP   rN   r1   rS   rR   rQ   rO   r€  )r   r)   Z_parse_overview_fmtrk  r   r   r   Útest_parse_overview_fmt.  s0    ÿÿÿÿÿÿ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 )Nr€  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:3000363rW  zI am just a test articlez "Demo User" <nobody@example.com>z6 Oct 1998 04:38:40 -0500r  z<45454@example.net>Z1234Z17z"news.example.com misc.test:3000363r·  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: 	rR   ú r:   )r)   Z_DEFAULT_OVERVIEW_FMTZ_parse_overviewr   )r   r=  r   Zoverviewr\   Úfieldsr   r   r   Útest_parse_overviewV  s6    ÿ
øÿ
ÿ
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 r   )r   r)   Z_parse_datetimer0   )r«  rÈ   Úcr8   r   r   r¬  …  s    ÿz,MiscTests.test_parse_datetime.<locals>.givesZ19990623135624éÏ  rS  é   rb  é8   é   Ú19990623Ú135624Ú990623Z090623iÙ  r   r­  r   r8   r   Útest_parse_datetime„  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 rD  ©r0   r   r)   Ú_unparse_datetime©	ÚyÚMÚdÚhrU  Úsr  r  r3   r8   r   r   r¬  ’  s    ÿÿz.MiscTests.test_unparse_datetime.<locals>.givesr½  rS  r¾  rb  r¿  rÀ  rÁ  rÂ  éÐ  Z20000623rL  rB   rc   rz   rm  Z20100605Ú010203c                    s@   t  | ||¡}ˆ  t |¡||f¡ ˆ  t |d¡||f¡ d S rD  ©r0   r1   r   r)   rÆ  ©rÈ  rÉ  rÊ  r  r  r3   r8   r   r   r¬  œ  s    ÿÿÚ000000r   r­  r   r8   r   Útest_unparse_datetime  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 r¿   rÅ  rÇ  r8   r   r   r¬  ©  s    ÿz5MiscTests.test_unparse_datetime_legacy.<locals>.givesr½  rS  r¾  rb  r¿  rÀ  rÃ  rÂ  rÍ  Z000623rL  rB   rc   rz   rm  Z100605rÎ  c                    s*   t  | ||¡}ˆ  t |d¡||f¡ d S r¿   rÏ  rÐ  r8   r   r   r¬  ±  s    ÿrÑ  r   r­  r   r8   r   Útest_unparse_datetime_legacy¦  s    z&MiscTests.test_unparse_datetime_legacyr°   c                 C   s   |   ttdƒ¡ d S )Nr³   )r   rš   r)   r8   r   r   r   Útest_ssl_support¹  s    zMiscTests.test_ssl_supportN)r   r	   r
   r®  r¸  r»  rÄ  rÒ  rÓ  r¥   Ú
skipUnlessÚsslrÔ  r   r   r   r   r©    s   (.
r©  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   sD   |   ttdƒ¡ g d¢}td ur*| d¡ |  ttjƒt|ƒ¡ d S )NÚ__all__)r   r   ÚNNTPReplyErrorrq   r*   ÚNNTPProtocolErrorrš  rª  r³   )r   rš   r)   rÖ  rñ   r   ÚsetrØ  )r   Z
target_apir   r   r   Útest_module_all_attributeÁ  s
    
z(PublicAPITests.test_module_all_attributeN)r   r	   r
   r   rÜ  r   r   r   r   r×  ¾  s   r×  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|ƒL |  ||¡  | jd||d W d   ƒ n1 sn0    Y  W d   ƒ n1 sŒ0    Y  |  ˆ¡ ˆD ]}|  |j¡ q¤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 r   r   )Úaddressr•   ©Ú
MockSocketr   r   Úcreate_connection×  s    z`MockSocketTests.check_constructor_error_conditions.<locals>.mock_socket_module.create_connectionN)r   r	   r
   rá  r   rß  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 r¿   r   r8   )Úsocket_closedr   r   rÔ   Û  s    zLMockSocketTests.check_constructor_error_conditions.<locals>.MockSocket.closec                    s    ˆƒ }t |ƒ\}}ˆ  |¡ |S r   )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   rà  Ú  s   rà  Fznntplib.socketÚdummy)r~   r   )r   ZassertRaisesRegexÚ
nntp_classr   rQ  )r   rÞ   Zexpected_error_typeZexpected_error_msgr‚   r   râ  rÒ   r   )rà  ræ  rÞ   rã  r   Ú"check_constructor_error_conditionsÑ  s    
ÿL
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)   rÚ  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 unavailableNrë  r   r   r   r   rì  ÷  s   rì  )rã   rê  r)   rq   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 unavailableNrë  r   r   r   r   rì  þ  s   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 r   r  r8   ©Z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)   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 r   r  )r   rß   ©Z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   r‚   r   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   rÝ  Ê  s    ý
	rÝ  c                   @   s   e Zd ZdZdd„ ZdS )Úbypass_contextz'Bypass encryption and actual SSL modulec                 K   s   | S r   r   )Ú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)r€   )rä  r   Z	bind_portÚlistenÚ	threadingÚThreadÚ
run_serverZ
backgroundra   Z
addCleanuprý   r   ZHOSTÚ	__enter__ÚnntpÚ__exit__)r   rö  Úportr   r   r   rÙ   %  s    
ÿ
zLocalServerTests.setUpc                 C   s  | |  ¡ \}}W d   ƒ n1 s&0    Y  t ¡ Ì}| |¡ | | d¡¡}| d¡ | ¡ }|dkrz| d¡ q^|dkrÐ| ¡  | d¡ t 	¡ }| 
t¡ |j|dd}| |¡ | | d¡¡}q^|d	kræ| d
¡ qöq^td |¡ƒ‚q^W d   ƒ n1 s0    Y  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})ÚacceptÚ
contextlibÚ	ExitStackÚenter_contextrç  Úsendallr½   rÔ   rÖ  Z
SSLContextZload_cert_chainÚcertfiler÷  r–   ró   )r   rö  Úclientr?  ÚcleanupÚreaderrù   Úcontextr   r   r   r   1  s2    *


ÿ

ÿ

zLocalServerTests.run_serverr°   c                 C   s`   | j j}| j j}| j  ¡  |  || j j¡ |  || j j¡ |  | j jtj¡ |  t	| j j¡ d S r   )
r  r™   rö  ZstarttlsZassertNotEqualr2   rÖ  Z	SSLSocketr(   r–   )r   r™   rö  r   r   r   r´   Q  s    
zLocalServerTests.test_starttlsN)	r   r	   r
   rÙ   r   r¥   rÕ  rÖ  r´   r   r   r   r   rû  $  s    
rû  Ú__main__)=r¶   rä  r0   rû   r¥   rŒ   r  r)   Zos.pathÚosr£   rþ  r²   r   Ztest.supportr   r   r   Zunittest.mockr   rÖ  ÚImportErrorÚpathrý   ÚdirnameÚ__file__r  r   r÷   r   r“   rœ   r­   ZSSLEOFErrorZTestCaserª   rÕ  r±   r·   rµ   rÏ   rÐ   rÖ   râ   rã   r;  rB  rC  rF  rœ  r   r¥  r§  r©  r×  rÝ  rõ  rø  rû  r   Úmainr   r   r   r   Ú<module>   s~   

  
 
,  G
   ÿ #N
<
