U
    �Acj;  ã                   @   s*  d 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mZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZmZ ddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ G dd„ de
ƒZ%G dd„ de	ƒZ&G dd„ de
ƒZ'G dd„ de
ƒZ(G dd„ dej)ƒZ*G dd„ de	ƒZ+dS )z 
Tests for L{twisted.web.util}.
é    N)Údefer)ÚnetworkString)ÚFailure)ÚSynchronousTestCaseÚTestCase)ÚresourceÚutil)ÚFlattenerError)ÚFOUND)ÚRequest)Ú	TagLoaderÚflattenStringÚtags)ÚDummyChannelÚDummyRequest)	ÚDeferredResourceÚFailureElementÚParentRedirectÚ_FrameElementÚ_SourceFragmentElementÚ_SourceLineElementÚ_StackElementÚformatFailureÚ
redirectToc                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚRedirectToTestsz"
    Tests for L{redirectTo}.
    c                 C   s^   t tƒ dƒ}d|_d}t||ƒ |  |jt¡ |  |j d¡|g¡ |  |j d¡dg¡ dS )z¾
        L{redirectTo} will set the C{Location} and C{Content-Type} headers on
        its request, and set the response code to C{FOUND}, so the browser will
        be redirected.
        Tó   GETs   http://target.example.com/4321s   locations   content-types   text/html; charset=utf-8N)	r   r   Úmethodr   ÚassertEqualÚcoder
   ÚresponseHeadersÚgetRawHeaders©ÚselfÚrequestZ	targetURL© r$   ú>/tmp/pip-unpacked-wheel-nrvc_22y/twisted/web/test/test_util.pyÚtest_headersAndCode&   s    

 ÿ
þz#RedirectToTests.test_headersAndCodec                 C   s*   t tƒ dƒ}d|_d}|  tt||¡ dS )zW
        L{redirectTo} will raise TypeError if unicode object is passed in URL
        Tr   zhttp://target.example.com/4321N)r   r   r   ÚassertRaisesÚ	TypeErrorr   r!   r$   r$   r%   Útest_redirectToUnicodeURL9   s    z)RedirectToTests.test_redirectToUnicodeURLc                 C   s(   t dgƒ}td|ƒ}d}|  ||¡ dS )zq
        Legitimate URLs are fully interpolated in the `redirectTo` response body without transformation
        ó    s   https://twisted.org/sÚ   
<html>
    <head>
        <meta http-equiv="refresh" content="0;URL=https://twisted.org/">
    </head>
    <body bgcolor="#FFFFFF" text="#000000">
    <a href="https://twisted.org/">click here</a>
    </body>
</html>
N©r   r   r   ©r"   r#   ÚhtmlÚexpectedr$   r$   r%   Útest_legitimateRedirectB   s    


z'RedirectToTests.test_legitimateRedirectc                 C   s(   t dgƒ}td|ƒ}d}|  ||¡ dS )zm
        Malicious URLs are HTML-escaped before interpolating them in the `redirectTo` response body
        r*   s?   https://twisted.org/"><script>alert(document.location)</script>sX  
<html>
    <head>
        <meta http-equiv="refresh" content="0;URL=https://twisted.org/&quot;&gt;&lt;script&gt;alert(document.location)&lt;/script&gt;">
    </head>
    <body bgcolor="#FFFFFF" text="#000000">
    <a href="https://twisted.org/&quot;&gt;&lt;script&gt;alert(document.location)&lt;/script&gt;">click here</a>
    </body>
</html>
Nr+   r,   r$   r$   r%   Útest_maliciousRedirectT   s    
 ÿ
z&RedirectToTests.test_maliciousRedirectN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   r)   r/   r0   r$   r$   r$   r%   r   !   s
   	r   c                   @   s8   e Zd ZdZeedœdd„Zdd„ Zdd„ Zd	d
„ ZdS )ÚParentRedirectTestsz!
    Test L{ParentRedirect}.
    )ÚrequestPathÚreturnc                 C   sV   t tƒ dƒ}d|_| d¡ d¡|_tƒ }| |¡ |j 	d¡}|dk	sLt
‚|\}|S )zÉ
        Render a response to a request with path *requestPath*

        @param requestPath: A slash-separated path like C{b'/foo/bar'}.

        @returns: The value of the I{Location} header.
        Tr   ó   /s   LocationN)r   r   r   ÚlstripÚsplitZprepathr   Úrenderr   r    ÚAssertionError)r"   r6   r#   r   ÚheadersÚlocationr$   r$   r%   ÚdoLocationTestn   s    
z"ParentRedirectTests.doLocationTestc                 C   s(   |   d|  d¡¡ |   d|  d¡¡ dS )zi
        At the URL root issue a redirect to the current URL, removing any query
        string.
        ó   http://10.0.0.1/r8   s   /?biff=baffN©r   r?   ©r"   r$   r$   r%   Útest_locationRoot‚   s    z%ParentRedirectTests.test_locationRootc                 C   s(   |   d|  d¡¡ |   d|  d¡¡ dS )zt
        A request for a resource one level down from the URL root produces
        a redirect to the root.
        r@   s   /foos   /foo?bar=sproiiingNrA   rB   r$   r$   r%   Útest_locationToRootŠ   s
     ÿz'ParentRedirectTests.test_locationToRootc                 C   s:   |   d|  d¡¡ |   d|  d¡¡ |   d|  d¡¡ dS )zp
        Requests for resources directly under the path C{/foo/} produce
        redirects to C{/foo/}.
        s   http://10.0.0.1/foo/s   /foo/s   /foo/bars   /foo/bar?biz=bazNrA   rB   r$   r$   r%   Útest_locationUpOne”   s     ÿz&ParentRedirectTests.test_locationUpOneN)	r1   r2   r3   r4   Úbytesr?   rC   rD   rE   r$   r$   r$   r%   r5   i   s
   
r5   c                   @   sh   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d„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚFailureElementTestszn
    Tests for L{FailureElement} and related helpers which can render a
    L{Failure} as an HTML string.
    c                 C   sT   dd„ }|j jd | _z
|ƒ  W n. tk
rN   tdd�| _| jjd | _Y nX dS )zO
        Create a L{Failure} which can be used by the rendering tests.
        c                  S   s   d} t | ƒ‚d S )NzThis is a problem)Ú	Exception)Úmessager$   r$   r%   ÚlineNumberProbeAlsoBroken«   s    z<FailureElementTests.setUp.<locals>.lineNumberProbeAlsoBrokené   T)ZcaptureVarséÿÿÿÿN)Ú__code__Úco_firstlinenoÚbaseÚBaseExceptionr   ÚfailureÚframesÚframe)r"   rJ   r$   r$   r%   ÚsetUp¦   s    
zFailureElementTests.setUpc                 C   sN   t tt tjdd�tjdd�¡ƒddƒ}td|ƒ}d}| | j| d¡¡ |S )	zN
        L{_SourceLineElement} renders a source line and line number.
        Ú
lineNumber©r;   Ú
sourceLineé2   z    print 'hello'Nu:   <div><span>50</span><span> Â  Â print 'hello'</span></div>zutf-8)	r   r   r   ÚdivÚspanr   ÚaddCallbackr   Úencode)r"   ÚelementÚdr.   r$   r$   r%   Útest_sourceLineElement¸   s    ÿû
ÿz*FailureElementTests.test_sourceLineElementc           	      C   sÄ   t ttjtjdd�tjdd�dd�ƒ| jƒ}dddg}td|ƒ}d}t|ƒD ]Z\}}d	}|d
krŠ|| ddg|d
k | j	| d| ¡7 }qL|| d| j	| d| ¡7 }qL| 
d¡}| | j|¡ |S )zƒ
        L{_SourceFragmentElement} renders source lines at and around the line
        number indicated by a frame object.
        rU   rV   rW   ZsourceLinesu#    Â  Â message = "This is a problem"u    Â  Â raise Exception(message)Ú Nz?<div class="snippet{}Line"><span>{}</span><span>{}</span></div>rK   Z	Highlightu    Â  Â  Â  Â Úutf8)r   r   r   rY   rZ   rS   r   Ú	enumerateÚformatrO   r\   r[   r   )	r"   r]   Úsourcer^   ZstringToCheckForrU   rW   ÚtemplateZbytesToCheckForr$   r$   r%   Útest_sourceFragmentElementË   s@    

ýÿøý
ý  ÿ
z.FailureElementTests.test_sourceFragmentElementc                 C   sF   t ttjdd�ƒ| jƒ}td|ƒ}| | jdtt	 
d¡ƒ d ¡ |S )z­
        The I{filename} renderer of L{_FrameElement} renders the filename
        associated with the frame object used to initialize the
        L{_FrameElement}.
        ÚfilenamerV   Nó   <span>Úcó   </span>)r   r   r   rZ   rS   r   r[   r   r   Ú__file__Úrstrip©r"   r]   r^   r$   r$   r%   Útest_frameElementFilenameõ   s    
üz-FailureElementTests.test_frameElementFilenamec                 C   s@   t ttjdd�ƒ| jƒ}td|ƒ}| | jd| jd f ¡ |S )z²
        The I{lineNumber} renderer of L{_FrameElement} renders the line number
        associated with the frame object used to initialize the
        L{_FrameElement}.
        rU   rV   Ns   <span>%d</span>rK   )	r   r   r   rZ   rS   r   r[   r   rO   rm   r$   r$   r%   Útest_frameElementLineNumber  s    
z/FailureElementTests.test_frameElementLineNumberc                 C   s4   t ttjdd�ƒ| jƒ}td|ƒ}| | jd¡ |S )z°
        The I{function} renderer of L{_FrameElement} renders the line number
        associated with the frame object used to initialize the
        L{_FrameElement}.
        ÚfunctionrV   Ns&   <span>lineNumberProbeAlsoBroken</span>)r   r   r   rZ   rS   r   r[   r   rm   r$   r$   r%   Útest_frameElementFunction  s    
z-FailureElementTests.test_frameElementFunctionc                 C   s\   t d| jƒ}| d¡}t ¡ }|d|ƒ}|  |t¡ |  |j| j¡ |  |g|j	 
¡ ¡ dS )zÓ
        The I{source} renderer of L{_FrameElement} renders the source code near
        the source filename/line number associated with the frame object used to
        initialize the L{_FrameElement}.
        Nrd   )r   rS   ÚlookupRenderMethodr   rY   ÚassertIsInstancer   ÚassertIdenticalr   ÚloaderÚload©r"   r]   ZrendererÚtagÚresultr$   r$   r%   Útest_frameElementSource  s    

z+FailureElementTests.test_frameElementSourcec                 C   sÆ   t d| jjdd… ƒ}| d¡}t ¡ }|d|ƒ}|  |t¡ |  |d t¡ |  	|d j
| jjd ¡ |  |d t¡ |  	|d j
| jjd ¡ |  |d j ¡ |d j ¡ ¡ |  dt|ƒ¡ dS )zœ
        The I{frames} renderer of L{_StackElement} renders each stack frame in
        the list of frames used to initialize the L{_StackElement}.
        Né   rR   r   rK   )r   rQ   rR   rr   r   rY   rs   Úlistr   rt   rS   ZassertNotEqualru   rv   r   Úlenrw   r$   r$   r%   Útest_stackElement)  s    

 z%FailureElementTests.test_stackElementc                 C   s\   t | jƒ}| d¡}t ¡ }|d|ƒ}|  |t¡ |  |j| jj	¡ |  
|g|j ¡ ¡ dS )zƒ
        The I{traceback} renderer of L{FailureElement} renders the failure's
        stack frames using L{_StackElement}.
        Ú	tracebackN)r   rQ   rr   r   rY   rs   r   rt   ZstackFramesrR   r   ru   rv   rw   r$   r$   r%   Útest_failureElementTraceback;  s    


z0FailureElementTests.test_failureElementTracebackc                 C   s@   t | jttjdd�ƒƒ}td|ƒ}d}| | jd| d ¡ |S )zi
        The I{type} renderer of L{FailureElement} renders the failure's
        exception type.
        ÚtyperV   Ns   builtins.Exceptionrh   rj   ©r   rQ   r   r   rZ   r   r[   r   )r"   r]   r^   Úexcr$   r$   r%   Útest_failureElementTypeH  s
    
z+FailureElementTests.test_failureElementTypec                 C   s4   t | jttjdd�ƒƒ}td|ƒ}| | jd¡ |S )zi
        The I{value} renderer of L{FailureElement} renders the value's exception
        value.
        ÚvaluerV   Ns   <span>This is a problem</span>r‚   rm   r$   r$   r%   Útest_failureElementValueS  s    
z,FailureElementTests.test_failureElementValueN)r1   r2   r3   r4   rT   r_   rf   rn   ro   rq   rz   r~   r€   r„   r†   r$   r$   r$   r%   rG       s   *rG   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚFormatFailureTestsz‰
    Tests for L{twisted.web.util.formatFailure} which returns an HTML string
    representing the L{Failure} instance passed to it.
    c                 C   s   |   tttƒ ¡ dS )z}
        If there is an error flattening the L{Failure} instance,
        L{formatFailure} raises L{FlattenerError}.
        N)r'   r	   r   ÚobjectrB   r$   r$   r%   Útest_flattenerErrord  s    z&FormatFailureTests.test_flattenerErrorc                 C   s`   zt dƒ‚W n tk
r*   ttƒ ƒ}Y nX |  |t¡ |  tdd„ |D ƒƒ¡ |  d|¡ dS )zÕ
        The return value of L{formatFailure} is a C{str} instance (not a
        C{unicode} instance) with numeric character references for any non-ASCII
        characters meant to appear in the output.
        zFake bugc                 s   s   | ]}|d k V  qdS )é€   Nr$   )Ú.0Úchr$   r$   r%   Ú	<genexpr>w  s     z7FormatFailureTests.test_returnsBytes.<locals>.<genexpr>s   &#160;N)	rH   rP   r   r   rs   rF   Ú
assertTrueÚallZassertIn)r"   ry   r$   r$   r%   Útest_returnsBytesk  s    z$FormatFailureTests.test_returnsBytesN)r1   r2   r3   r4   r‰   r�   r$   r$   r$   r%   r‡   ^  s   r‡   c                   @   s   e Zd Zdd„ Zdd„ ZdS )Ú
SDResourcec                 C   s
   || _ d S ©N)Údefault)r"   r“   r$   r$   r%   Ú__init__}  s    zSDResource.__init__c                 C   s"   t  | j¡}t |¡}| ||¡S r’   )r   Úsucceedr“   r   r   ÚgetChildWithDefault)r"   Únamer#   r^   r   r$   r$   r%   r–   €  s    
zSDResource.getChildWithDefaultN)r1   r2   r3   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 )	ÚDeferredResourceTestsz(
    Tests for L{DeferredResource}.
    c                 C   sF   t  ¡ }d|_t|ƒ}tdddgƒ}t  ||¡ |  |jddg¡ d S )NrK   ZfooÚbarZbaz)r   ÚResourceZisLeafr‘   r   ZgetChildForRequestr   Zpostpath)r"   ÚrÚsr^   r$   r$   r%   ÚtestDeferredResource‹  s    z*DeferredResourceTests.testDeferredResourcec                 C   sF   g }t g ƒ}|j|_t ¡ }tt |¡ƒ}| |¡ |  ||g¡ dS )z­
        L{DeferredResource} uses the request object's C{render} method to
        render the resource which is the result of the L{Deferred} being
        handled.
        N)	r   Úappendr;   r   rš   r   r   r•   r   )r"   Úrenderedr#   ry   ÚdeferredResourcer$   r$   r%   Útest_render“  s    
z!DeferredResourceTests.test_renderc                 C   sh   t g ƒ}| ¡ }ttƒ ƒ}tt |¡ƒ}| |¡ |  |  	|¡|¡ ~t
 ¡  |  t¡}|  |g ¡ dS )z°
        If the L{Deferred} fails, L{DeferredResource} reports the failure via
        C{processingFailed}, and does not cause an unhandled error to be
        logged.
        N)r   ZnotifyFinishr   ÚRuntimeErrorr   r   Zfailr;   r   ZfailureResultOfÚgcZcollectZflushLoggedErrors)r"   r#   r^   rQ   r    Úerrorsr$   r$   r%   Útest_renderNoFailure¢  s    


z*DeferredResourceTests.test_renderNoFailureN)r1   r2   r3   r4   r�   r¡   r¥   r$   r$   r$   r%   r˜   †  s   r˜   ),r4   r£   Ztwisted.internetr   Ztwisted.python.compatr   Ztwisted.python.failurer   Ztwisted.trial.unittestr   r   Ztwisted.webr   r   Ztwisted.web.errorr	   Ztwisted.web.httpr
   Ztwisted.web.serverr   Ztwisted.web.templater   r   r   Ztwisted.web.test.requesthelperr   r   Ztwisted.web.utilr   r   r   r   r   r   r   r   r   r   r5   rG   r‡   rš   r‘   r˜   r$   r$   r$   r%   Ú<module>   s&   ,H7 ?
