U
    Æ½„bÇ9  ã                   @   sÐ  d dl Z d dlmZ d dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ d dlmZ d.dd„Zedk	�r
G dd„ dejjjj ƒZ!G dd„ dƒZ"G dd„ dej#j$ƒZ%G dd„ dej&ƒZ'ndd„ Z'edk	�r0G dd„ dejƒZ(ndd„ Z(G dd„ deƒZ)G dd„ deƒZ*G d d!„ d!e)eƒZ+G d"d#„ d#ej,ƒZ-G d$d%„ d%ej.ƒZ/G d&d'„ d'ej0ƒZ1G d(d)„ d)ej2ƒZ3d*d+„ Z4G d,d-„ d-ej0ƒZ5dS )/é    N)Úimport_module)Úsettings©ÚImproperlyConfigured)ÚWSGIHandler)Úoverride_settingsÚ	testcases)ÚClient)ÚClientHandler)ÚRequestFactory)Úforce_bytes)Ú	urlencode)ÚcoreapiÚrequests)Úapi_settingsc                 C   s   || _ || _d S ©N)Z_force_auth_userZ_force_auth_token)ÚrequestÚuserÚtoken© r   ú7/tmp/pip-unpacked-wheel-iohwuy7z/rest_framework/test.pyÚforce_authenticate   s    r   c                   @   s   e Zd Zdd„ ZdS )Ú
HeaderDictc                 C   s
   |   |¡S r   )Ú
getheaders)ÚselfÚkeyÚdefaultr   r   r   Úget_all   s    zHeaderDict.get_allN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r      s   r   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚMockOriginalResponsec                 C   s   t |ƒ| _d| _d S )NF)r   ÚmsgÚclosed)r   Úheadersr   r   r   Ú__init__    s    
zMockOriginalResponse.__init__c                 C   s   | j S r   ©r#   ©r   r   r   r   Úisclosed$   s    zMockOriginalResponse.isclosedc                 C   s
   d| _ d S )NTr&   r'   r   r   r   Úclose'   s    zMockOriginalResponse.closeN)r   r   r    r%   r(   r)   r   r   r   r   r!      s   r!   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDjangoTestAdapterz¤
        A transport adapter for `requests`, that makes requests via the
        Django WSGI app, rather than making actual HTTP requests over the network.
        c                 C   s   t ƒ | _tƒ | _d S r   )r   ÚappÚDjangoRequestFactoryÚfactoryr'   r   r   r   r%   /   s    zDjangoTestAdapter.__init__c                 C   s¦   |j }|j}i }|jdk	r@t|jdƒr6|j ¡ |d< n
|j|d< d|jkrX|jd |d< |j ¡ D ].\}}| ¡ }|dkr|qb||d| dd	¡ < qb| j	j
||f|ŽjS )
zb
            Given a `requests.PreparedRequest` instance, return a WSGI environ dict.
            NÚreadÚdatazcontent-typeÚcontent_type)Z
CONNECTIONzCONTENT-LENGTHzCONTENT-TYPEzHTTP_%sú-Ú_)ÚmethodÚurlÚbodyÚhasattrr.   r$   ÚitemsÚupperÚreplacer-   ÚgenericÚenviron)r   r   r3   r4   Úkwargsr   Úvaluer   r   r   Úget_environ3   s    


zDjangoTestAdapter.get_environc                    sX   i ‰ d‡ fdd„	}|   |¡}|  ||¡}t d |¡¡ˆ d< tjjjf ˆ Ž}|  	||¡S )zR
            Make an outgoing request to the Django WSGI application.
            Nc                    sL   |   d¡\}}}t|ƒˆ d< |ˆ d< |ˆ d< dˆ d< dˆ d< t|ƒˆ d	< d S )
Nú ÚstatusÚreasonr$   é   ÚversionFÚpreload_contentÚoriginal_response)Ú	partitionÚintr!   )Zwsgi_statusZwsgi_headersÚexc_infor@   r2   rA   ©Z
raw_kwargsr   r   Ústart_responseS   s    z.DjangoTestAdapter.send.<locals>.start_responseó    r5   )N)
r>   r+   ÚioÚBytesIOÚjoinr   ÚpackagesÚurllib3ÚHTTPResponseÚbuild_response)r   r   Úargsr<   rJ   r;   Zwsgi_responseÚrawr   rI   r   ÚsendM   s    

zDjangoTestAdapter.sendc                 C   s   d S r   r   r'   r   r   r   r)   g   s    zDjangoTestAdapter.closeN)r   r   r    Ú__doc__r%   r>   rU   r)   r   r   r   r   r*   *   s
   r*   c                       s(   e Zd Z‡ fdd„Z‡ fdd„Z‡  ZS )ÚRequestsClientc                    s0   t ƒ j||Ž tƒ }|  d|¡ |  d|¡ d S )Nzhttp://zhttps://)Úsuperr%   r*   Úmount)r   rS   r<   Úadapter©Ú	__class__r   r   r%   k   s    zRequestsClient.__init__c                    s,   |  d¡std| ƒ‚tƒ j||f|ž|ŽS )NÚhttpzPMissing "http:" or "https:". Use a fully qualified URL, eg "http://testserver%s")Ú
startswithÚ
ValueErrorrX   r   )r   r3   r4   rS   r<   r[   r   r   r   q   s    
zRequestsClient.request)r   r   r    r%   r   Ú__classcell__r   r   r[   r   rW   j   s   rW   c                  O   s   t dƒ‚d S )Nz:requests must be installed in order to use RequestsClient.r   ©rS   r<   r   r   r   rW   w   s    c                       s(   e Zd Z‡ fdd„Zedd„ ƒZ‡  ZS )ÚCoreAPIClientc                    s0   t ƒ | _tjj| jd�g|d< tƒ j||Ž d S )N)ÚsessionÚ
transports)rW   Ú_sessionr   rd   ZHTTPTransportrc   rX   r%   ©r   rS   r<   r[   r   r   r%   }   s    zCoreAPIClient.__init__c                 C   s   | j S r   )re   r'   r   r   r   rc   ‚   s    zCoreAPIClient.session)r   r   r    r%   Úpropertyrc   r`   r   r   r[   r   rb   |   s   rb   c                  O   s   t dƒ‚d S )Nz8coreapi must be installed in order to use CoreAPIClient.r   ra   r   r   r   rb   ‡   s    c                       sŠ   e Zd ZejZejZd‡ fdd„	Zddd„Z	ddd„Z
dd	d
„Zddd„Zddd„Zddd„Zd dd„Zd!‡ fdd„	Z‡ fdd„Z‡  ZS )"ÚAPIRequestFactoryFc                    s6   || _ i | _| jD ]}|| j|j< qtƒ jf |Ž d S r   )Úenforce_csrf_checksÚrenderer_classesÚrenderer_classes_listÚformatrX   r%   )r   ri   ÚdefaultsÚclsr[   r   r   r%   �   s
    
zAPIRequestFactory.__init__Nc                 C   s¾   |dkrd|fS |dks(|dks(t dƒ‚|r:t|tjƒ}n||pB| j}|| jkspt d |d dd„ | jD ƒ¡¡ƒ‚| j| ƒ }| |¡}|j	}|j
r d ||j
¡}t|tƒr¶| |j
¡}||fS )	zP
        Encode the data returning a two tuple of (bytes, content_type)
        NÚ z1You may not set both `format` and `content_type`.zqInvalid format '{}'. Available formats are {}. Set TEST_REQUEST_RENDERER_CLASSES to enable extra request formats.z, c                 S   s   g | ]}d | d  ‘qS )ú'r   )Ú.0Úfmtr   r   r   Ú
<listcomp>®   s     z2APIRequestFactory._encode_data.<locals>.<listcomp>z{}; charset={})ÚAssertionErrorr   r   ÚDEFAULT_CHARSETÚdefault_formatrj   rl   rN   ÚrenderÚ
media_typeÚcharsetÚ
isinstanceÚstrÚencode)r   r/   rl   r0   ÚretZrendererr   r   r   Ú_encode_data–   s2    ÿ
üÿ

 ÿ
zAPIRequestFactory._encode_datac                 K   s^   dt |p
i dd�i}|sDd|krDt| d¡d ƒ}| d¡}||d< | |¡ | jd|f|ŽS )NÚQUERY_STRINGT)Údoseqú?é   z
iso-8859-1ÚGET)r   r   ÚsplitÚdecodeÚupdater:   )r   Úpathr/   ÚextraÚrZquery_stringr   r   r   ÚgetÃ   s     ÿ

zAPIRequestFactory.getc                 K   s&   |   |||¡\}}| jd|||f|ŽS )NÚPOST©r~   r:   ©r   r‡   r/   rl   r0   rˆ   r   r   r   ÚpostÐ   s    zAPIRequestFactory.postc                 K   s&   |   |||¡\}}| jd|||f|ŽS )NÚPUTrŒ   r�   r   r   r   ÚputÔ   s    zAPIRequestFactory.putc                 K   s&   |   |||¡\}}| jd|||f|ŽS )NÚPATCHrŒ   r�   r   r   r   ÚpatchØ   s    zAPIRequestFactory.patchc                 K   s&   |   |||¡\}}| jd|||f|ŽS )NÚDELETErŒ   r�   r   r   r   ÚdeleteÜ   s    zAPIRequestFactory.deletec                 K   s&   |   |||¡\}}| jd|||f|ŽS )NÚOPTIONSrŒ   r�   r   r   r   Úoptionsà   s    zAPIRequestFactory.optionsro   úapplication/octet-streamc                    s,   |d k	rt |ƒ|d< tƒ j|||||f|ŽS )NÚCONTENT_TYPE)r{   rX   r:   )r   r3   r‡   r/   r0   Úsecurerˆ   r[   r   r   r:   ä   s        ÿÿzAPIRequestFactory.genericc                    s   t ƒ jf |Ž}| j |_|S r   )rX   r   ri   Z_dont_enforce_csrf_checks)r   r<   r   r[   r   r   r   í   s    
zAPIRequestFactory.request)F)NN)N)NNN)NNN)NNN)NNN)NNN)ro   r—   F)r   r   r    r   ZTEST_REQUEST_RENDERER_CLASSESrk   ZTEST_REQUEST_DEFAULT_FORMATrv   r%   r~   rŠ   rŽ   r�   r’   r”   r–   r:   r   r`   r   r   r[   r   rh   ‹   s   
-





    ÿ	rh   c                       s,   e Zd ZdZ‡ fdd„Z‡ fdd„Z‡  ZS )ÚForceAuthClientHandlerzj
    A patched version of ClientHandler that can enforce authentication
    on the outgoing requests.
    c                    s   d | _ d | _tƒ j||Ž d S r   )Ú_force_userÚ_force_tokenrX   r%   rf   r[   r   r   r%   ù   s    zForceAuthClientHandler.__init__c                    s   t || j| jƒ tƒ  |¡S r   )r   r›   rœ   rX   Úget_response)r   r   r[   r   r   r�   þ   s    z#ForceAuthClientHandler.get_response)r   r   r    rV   r%   r�   r`   r   r   r[   r   rš   ó   s   rš   c                       sœ   e Zd Zd‡ fdd„	Zdd„ Zddd„Z‡ fd	d
„Zd‡ fdd„	Zd‡ fdd„	Zd‡ fdd„	Z	d‡ fdd„	Z
d‡ fdd„	Zd ‡ fdd„	Z‡ fdd„Z‡  ZS )!Ú	APIClientFc                    s"   t ƒ jf |Ž t|ƒ| _i | _d S r   )rX   r%   rš   ÚhandlerÚ_credentials)r   ri   rm   r[   r   r   r%     s    
zAPIClient.__init__c                 K   s
   || _ dS )zK
        Sets headers that will be used on every outgoing request.
        N)r    ©r   r<   r   r   r   Úcredentials  s    zAPIClient.credentialsNc                 C   s$   || j _|| j _|dkr |  ¡  dS )zd
        Forcibly authenticates outgoing requests with the given
        user and/or token.
        N)rŸ   r›   rœ   Úlogout)r   r   r   r   r   r   r     s    zAPIClient.force_authenticatec                    s   |  | j¡ tƒ jf |ŽS r   )r†   r    rX   r   r¡   r[   r   r   r     s    zAPIClient.requestc                    s.   t ƒ j|fd|i|—Ž}|r*| j|f|Ž}|S )Nr/   )rX   rŠ   Ú_handle_redirects)r   r‡   r/   Úfollowrˆ   Úresponser[   r   r   rŠ      s    zAPIClient.getc                    s2   t ƒ j|f|||dœ|—Ž}|r.| j|f|Ž}|S ©N)r/   rl   r0   )rX   rŽ   r¤   ©r   r‡   r/   rl   r0   r¥   rˆ   r¦   r[   r   r   rŽ   &  s    ÿ  ÿÿzAPIClient.postc                    s2   t ƒ j|f|||dœ|—Ž}|r.| j|f|Ž}|S r§   )rX   r�   r¤   r¨   r[   r   r   r�   .  s    ÿ  ÿÿzAPIClient.putc                    s2   t ƒ j|f|||dœ|—Ž}|r.| j|f|Ž}|S r§   )rX   r’   r¤   r¨   r[   r   r   r’   6  s    ÿ  ÿÿzAPIClient.patchc                    s2   t ƒ j|f|||dœ|—Ž}|r.| j|f|Ž}|S r§   )rX   r”   r¤   r¨   r[   r   r   r”   >  s    ÿ  ÿÿzAPIClient.deletec                    s2   t ƒ j|f|||dœ|—Ž}|r.| j|f|Ž}|S r§   )rX   r–   r¤   r¨   r[   r   r   r–   F  s    ÿ  ÿÿzAPIClient.optionsc                    s*   i | _ d | j_d | j_| jr&tƒ  ¡  d S r   )r    rŸ   r›   rœ   rc   rX   r£   r'   r[   r   r   r£   N  s
    zAPIClient.logout)F)NN)NF)NNNF)NNNF)NNNF)NNNF)NNNF)r   r   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eZdS )ÚAPITransactionTestCaseN©r   r   r    rž   Zclient_classr   r   r   r   r©   Y  s   r©   c                   @   s   e Zd ZeZdS )ÚAPITestCaseNrª   r   r   r   r   r«   ]  s   r«   c                   @   s   e Zd ZeZdS )ÚAPISimpleTestCaseNrª   r   r   r   r   r¬   a  s   r¬   c                   @   s   e Zd ZeZdS )ÚAPILiveServerTestCaseNrª   r   r   r   r   r­   e  s   r­   c                 C   s    t | dƒr| j| j_n| j`d S ©NÚ_module_urlpatterns)r6   r¯   Ú_moduleÚurlpatterns©rn   r   r   r   Úcleanup_url_patternsi  s    
r³   c                       s>   e Zd ZdZe‡ fdd„ƒZejdk r6e‡ fdd„ƒZ‡  Z	S )ÚURLPatternsTestCaseaC  
    Isolate URL patterns on a per-TestCase basis. For example,

    class ATestCase(URLPatternsTestCase):
        urlpatterns = [...]

        def test_something(self):
            ...

    class AnotherTestCase(URLPatternsTestCase):
        urlpatterns = [...]

        def test_something_else(self):
            ...
    c                    sv   t | jƒ| _t| jd�| _t| jdƒr0| jj| _| j| j_| j ¡  t	j
dkrh|  | jj¡ |  t| ¡ tƒ  ¡  d S )N)ZROOT_URLCONFr±   ©é   r   )r   r   r°   r   Ú	_overrider6   r±   r¯   ÚenableÚdjangoÚVERSIONZaddClassCleanupÚdisabler³   rX   Ú
setUpClassr²   r[   r   r   r¼   €  s    



zURLPatternsTestCase.setUpClassrµ   c                    s4   t ƒ  ¡  | j ¡  t| dƒr*| j| j_n| j`d S r®   )rX   ÚtearDownClassr·   r»   r6   r¯   r°   r±   r²   r[   r   r   r½   ”  s
    


z!URLPatternsTestCase.tearDownClass)
r   r   r    rV   Úclassmethodr¼   r¹   rº   r½   r`   r   r   r[   r   r´   p  s   
r´   )NN)6rL   Ú	importlibr   r¹   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.core.handlers.wsgir   Zdjango.testr   r   Zdjango.test.clientr	   ZDjangoClientr
   r   r,   Zdjango.utils.encodingr   Zdjango.utils.httpr   Zrest_framework.compatr   r   Zrest_framework.settingsr   r   rO   rP   Ú_collectionsÚHTTPHeaderDictr   r!   ÚadaptersÚHTTPAdapterr*   ÚSessionrW   rb   rh   rš   rž   ZTransactionTestCaser©   ZTestCaser«   ZSimpleTestCaser¬   ZLiveServerTestCaser­   r³   r´   r   r   r   r   Ú<module>   s@   

@
hT