U
    2ÜŸjp/  ã                   @  sJ  d Z ddlm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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 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%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 e2ƒ Z3G dd„ deƒZ4G dd„ deƒZ5dS )z
Tests for L{twisted.web.tap}.
é    )ÚannotationsN)Úcast)ÚskipIf)Ú	endpointsÚreactor)ÚIReactorCoreÚIReactorUNIX)ÚFilePath)ÚrequireModule)Ú
ThreadPool)Ú
UsageError)ÚPBServerFactory)ÚTestCase)Údemo)ÚResourcePublisherÚUserDirectory)ÚPythonScript)ÚSite)ÚDataÚFile)ÚOptionsÚ_AddHeadersResourceÚmakePersonalServerFactoryÚmakeService)ÚDummyRequest)Ú	CGIScript)ÚWSGIResourcec                   @  s‚  e Zd ZdZddœdd„Zddœdd„Zee e	¡ d	ƒddœd
d„ƒZ
ddœdd„Zddœdd„Zddœdd„Zddœdd„Zee e	¡ d	ƒddœdd„ƒZee e	¡ d	ƒddœdd„ƒZddœdd„Zddœdd„Zddœdd„Zddœdd„Zeed ƒd!k	d"ƒddœd#d$„ƒZeed ƒd!kd%ƒddœd&d'„ƒZddœd(d)„Zddœd*d+„Zddœd,d-„Zddœd.d/„Zddœd0d1„Zd!S )2ÚServiceTestszD
    Tests for the service creation APIs in L{twisted.web.tap}.
    ztuple[FilePath[str], File]©Úreturnc                 C  s:   t |  ¡ ƒ}| ¡  tƒ }| d|jg¡ |d }||fS )aƒ  
        Helper for the I{--path} tests which creates a directory and creates
        an L{Options} object which uses that directory as its static
        filesystem root.

        @return: A two-tuple of a L{FilePath} referring to the directory and
            the value associated with the C{'root'} key in the L{Options}
            instance after parsing a I{--path} option.
        ú--pathÚroot)r	   ÚmktempÚmakedirsr   ÚparseOptionsÚpath)Úselfr%   Úoptionsr!   © r(   ú=/tmp/pip-unpacked-wheel-4b529toj/twisted/web/test/test_tap.pyÚ_pathOption-   s    
zServiceTests._pathOptionÚNonec                 C  s,   |   ¡ \}}|  |t¡ |  |j|j¡ dS )zŠ
        The I{--path} option causes L{Options} to create a root resource
        which serves responses from the specified path.
        N)r*   ÚassertIsInstancer   ÚassertEqualr%   ©r&   r%   r!   r(   r(   r)   Ú	test_path>   s    zServiceTests.test_pathz0The reactor does not support UNIX domain socketsc                 C  s´   t |  ¡ ƒ}| ¡  |  ¡ }tƒ }| dd| d|jg¡ t|ƒ}| ¡  |  |j	¡ |  
|jd jjt¡ |  |jd jjj|j¡ |  tj |¡¡ |  t t |¡j¡¡ dS )z¥
        The I{--path} option to L{makeService} causes it to return a service
        which will listen on the server address given by the I{--port} option.
        ú--portúunix:r    r   N)r	   r"   r#   r   r$   r%   r   ÚstartServiceÚ
addCleanupÚstopServicer,   ÚservicesÚfactoryÚresourcer   r-   Ú
assertTrueÚosÚexistsÚstatÚS_ISSOCKÚst_mode)r&   r%   Úportr'   Úservicer(   r(   r)   Útest_pathServerG   s    	zServiceTests.test_pathServerc                 C  s4   |   ¡ \}}| d¡ d¡ |  | dd¡t¡ dS )z—
        The I{--path} option creates a root resource which serves a
        L{CGIScript} instance for any child with the C{".cgi"} extension.
        zfoo.cgió    N)r*   ÚchildÚ
setContentr,   ÚgetChildr   r.   r(   r(   r)   Útest_cgiProcessor]   s    zServiceTests.test_cgiProcessorc                 C  s4   |   ¡ \}}| d¡ d¡ |  | dd¡t¡ dS )zš
        The I{--path} option creates a root resource which serves a
        L{PythonScript} instance for any child with the C{".epy"} extension.
        zfoo.epyrA   N)r*   rB   rC   r,   rD   r   r.   r(   r(   r)   Útest_epyProcessorf   s    zServiceTests.test_epyProcessorc                 C  sT   |   ¡ \}}| d¡ d¡ | dd¡}|  |t¡ |  |jd¡ |  |jd¡ dS )zº
        The I{--path} option creates a root resource which serves the
        C{resource} global defined by the Python source in any child with
        the C{".rpy"} extension.
        zfoo.rpysN   from twisted.web.static import Data
resource = Data('content', 'major/minor')
NÚcontentzmajor/minor)	r*   rB   rC   rD   r,   r   r-   ÚdataÚtype)r&   r%   r!   rB   r(   r(   r)   Útest_rpyProcessoro   s    
ÿzServiceTests.test_rpyProcessorc                 C  sD   t tddƒƒ}t|ƒ}|  |t¡ |  |jt¡ |  |jj|¡ dS )z‡
        L{makePersonalServerFactory} returns a PB server factory which has
        as its root object a L{ResourcePublisher}.
        s   foo barz
text/plainN)	r   r   r   r,   r   r!   r   ÚassertIdenticalÚsite)r&   rL   ZserverFactoryr(   r(   r)   Útest_makePersonalServerFactory   s
    z+ServiceTests.test_makePersonalServerFactoryc                 C  sl   |   ¡ }tƒ }| dd| dg¡ t|ƒ}| ¡  |  |j¡ |  tj	 
|¡¡ |  t t |¡j¡¡ dS )z±
        The I{--personal} option to L{makeService} causes it to return a
        service which will listen on the server address given by the I{--port}
        option.
        r0   r1   ú
--personalN)r"   r   r$   r   r2   r3   r4   r8   r9   r%   r:   r;   r<   r=   )r&   r>   r'   r?   r(   r(   r)   Útest_personalServerŒ   s    
z ServiceTests.test_personalServerc                 C  sH   t ƒ }| dg¡ tj tj dtj¡¡}|  |d d d|› �¡ dS )zÆ
        If the I{--port} option not specified but the I{--personal} option is,
        L{Options} defaults the port to C{UserDirectory.userSocketName} in the
        user's home directory.
        rN   ú~Úportsr   r1   N)	r   r$   r9   r%   Ú
expanduserÚjoinr   ZuserSocketNamer-   )r&   r'   r%   r(   r(   r)   Útest_defaultPersonalPathŸ   s    
z%ServiceTests.test_defaultPersonalPathc                 C  s8   t ƒ }| g ¡ |  t |d d d¡dd… d¡ dS )zl
        If the I{--port} option is not specified, L{Options} defaults the port
        to C{8080}.
        rQ   r   Né   )ZTCP)i�  N)r   r$   r-   r   Z_parseServer©r&   r'   r(   r(   r)   Útest_defaultPort®   s    
 ÿzServiceTests.test_defaultPortc                 C  sD   t ƒ }| ddddg¡ |  d|d d ¡ |  d|d d ¡ d	S )
zQ
        If the I{--http} option is given twice, there are two listeners
        z--listenztcp:8001ztcp:8002Z8001rQ   r   Z8002é   N©r   r$   ZassertInrV   r(   r(   r)   Útest_twoPorts¹   s    zServiceTests.test_twoPortsc                 C  s¶   t ƒ }| dtd g¡ |d }|  |t¡ |  |jt¡ |  t|j	t
ƒ¡ |  |jt¡ |  |j	j¡ tttƒ d¡ |  |j	j¡ |  |j	j¡ tttƒ d¡ |  |j	j¡ dS )zÁ
        The I{--wsgi} option takes the fully-qualifed Python name of a WSGI
        application object and creates a L{WSGIResource} at the root which
        serves that application.
        ú--wsgiz.applicationr!   ZstartupÚshutdownN)r   r$   Ú__name__r8   r   rK   Z_reactorr   Ú
isinstanceZ_threadpoolr   Z_applicationÚapplicationÚassertFalseÚstartedr   r   ZfireSystemEventZjoined)r&   r'   r!   r(   r(   r)   Ú	test_wsgiÂ   s    zServiceTests.test_wsgic                 C  sF   t ƒ }td dfD ].}|  t|jd|g¡}|  t|ƒd|›�¡ qdS )zn
        If I{--wsgi} is given an invalid name, L{Options.parseOptions}
        raises L{UsageError}.
        z.nosuchthingzfoo.r[   zNo such WSGI application: N)r   r]   ÚassertRaisesr   r$   r-   Ústr)r&   r'   ÚnameÚexcr(   r(   r)   Útest_invalidApplicationØ   s    z$ServiceTests.test_invalidApplicationzOpenSSL.SSLNzSSL module is available.c                 C  s.   t ƒ }|  t|jdg¡}|  d|jd ¡ dS )zp
        An L{UsageError} is raised when C{https} is requested but there is no
        support for SSL.
        ú--https=443zSSL support not installedr   N)r   rc   r   r$   r-   Úargs)r&   r'   Ú	exceptionr(   r(   r)   Útest_HTTPSFailureOnMissingSSLâ   s    z*ServiceTests.test_HTTPSFailureOnMissingSSLzSSL module is not available.c                 C  s>   t ƒ }| dg¡ |  d|d d ¡ |  d|d d ¡ dS )zM
        When SSL support is present, it accepts the --https option.
        rh   ÚsslrQ   r   Ú443NrY   rV   r(   r(   r)   Ú test_HTTPSAcceptedOnAvailableSSLî   s    z-ServiceTests.test_HTTPSAcceptedOnAvailableSSLc                 C  s0   t ƒ }| ddddg¡ |  |d ddg¡ dS )zE
        When --add-header is specific, the value is parsed.
        ú--add-headerúK1: V1úK2: V2ZextraHeaders©ÚK1ÚV1©ÚK2ÚV2N)r   r$   r-   rV   r(   r(   r)   Útest_add_header_parsingú   s    z$ServiceTests.test_add_header_parsingc                 C  s`   t ƒ }| ddddg¡ t|ƒ}|jd jj}|  |t¡ |  |j	ddg¡ |  |j
tj¡ dS )zj
        When --add-header is specified, the resource is a composition that adds
        headers.
        ro   rp   rq   r   rr   ru   N)r   r$   r   r5   r6   r7   r,   r   r-   Ú_headersZ_originalResourcer   ÚTest)r&   r'   r?   r7   r(   r(   r)   Útest_add_header_resource  s    z%ServiceTests.test_add_header_resourcec                 C  sd   t ƒ }| dg¡ t|ƒ |  | jg¡}|  |d d t¡ |  |d d d¡ |  t|ƒd¡ dS )z7
        Passing --notracebacks is deprecated.
        z--notracebacksr   ÚcategoryÚmessagez/--notracebacks was deprecated in Twisted 19.7.0rX   N)r   r$   r   ZflushWarningsÚtest_noTracebacksDeprecationr-   ÚDeprecationWarningÚlen)r&   r'   Úwarningsr(   r(   r)   r~     s    
 ÿz)ServiceTests.test_noTracebacksDeprecationc                 C  s2   t ƒ }| dg¡ t|ƒ}|  |jd jj¡ dS )zm
        Passing --display-tracebacks will enable traceback rendering on the
        generated Site.
        z--display-tracebacksr   N)r   r$   r   r8   r5   r6   ÚdisplayTracebacks©r&   r'   r?   r(   r(   r)   Útest_displayTracebacks  s    z#ServiceTests.test_displayTracebacksc                 C  s0   t ƒ }| g ¡ t|ƒ}|  |jd jj¡ dS )zt
        Not passing --display-tracebacks will leave traceback rendering on the
        generated Site off.
        r   N)r   r$   r   r`   r5   r6   r‚   rƒ   r(   r(   r)   Útest_displayTracebacksNotGiven(  s    
z+ServiceTests.test_displayTracebacksNotGiven)r]   Ú
__module__Ú__qualname__Ú__doc__r*   r/   r   r   Z
providedByr   r@   rE   rF   rJ   rM   rO   rT   rW   rZ   rb   rg   r
   rk   rn   rx   r{   r~   r„   r…   r(   r(   r(   r)   r   (   sF   	
þ		
þ
þ	

r   c                   @  s   e Zd Zddœdd„ZdS )ÚAddHeadersResourceTestsr+   r   c                 C  sZ   t t ¡ dddgƒ}tg ƒ}| d|¡ |  |j d¡ddg¡ |  |j d¡d	g¡ d
S )zc
        When getChildWithDefault is invoked, it adds the headers to the
        response.
        rr   ru   )rs   ÚV3Ú rs   rt   rŠ   rv   rw   N)r   r   rz   r   ZgetChildWithDefaultr-   ZresponseHeadersZgetRawHeaders)r&   r7   Úrequestr(   r(   r)   Útest_getChildWithDefault4  s     ÿz0AddHeadersResourceTests.test_getChildWithDefaultN)r]   r†   r‡   r�   r(   r(   r(   r)   r‰   3  s   r‰   )6rˆ   Ú
__future__r   r9   r;   Útypingr   Zunittestr   Ztwisted.internetr   r   Ztwisted.internet.interfacesr   r   Ztwisted.python.filepathr	   Ztwisted.python.reflectr
   Ztwisted.python.threadpoolr   Ztwisted.python.usager   Ztwisted.spread.pbr   Ztwisted.trial.unittestr   Ztwisted.webr   Ztwisted.web.distribr   r   Ztwisted.web.scriptr   Ztwisted.web.serverr   Ztwisted.web.staticr   r   Ztwisted.web.tapr   r   r   r   Ztwisted.web.test.requesthelperr   Ztwisted.web.twcgir   Ztwisted.web.wsgir   Úobjectr_   r   r‰   r(   r(   r(   r)   Ú<module>   s6     