U
    s@gL6                     @   sF  d Z ddlmZmZ ddlZddlmZ ddlmZ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 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! ddl m"Z"m#Z# ddl m$Z$m%Z%m&Z& ddl 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j,Z-G dd deZ.dS )z 
Tests for L{twisted.web.util}.
    )absolute_importdivisionN)Failure)SynchronousTestCaseTestCase)defer)_PY3
intToBytesnetworkString)resourceutil)FlattenerError)FOUND)Request)	TagLoaderflattenStringtags)DummyChannelDummyRequest)DeferredResource)_SourceFragmentElement_FrameElement)_StackElementFailureElementformatFailure)
redirectTo_SourceLineElementc                   @   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   ZresponseHeadersZgetRawHeadersselfrequestZ	targetURL r%   </usr/lib/python3/dist-packages/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_redirectToUnicodeURL4   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$   Zhtmlexpectedr%   r%   r&   test_legitimateRedirect=   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_maliciousRedirectO   s    
 
z&RedirectToTests.test_maliciousRedirectN)__name__
__module____qualname____doc__r'   r*   r/   r0   r%   r%   r%   r&   r      s
   	r   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   sL   dd }|j jd | _z
|  W n&   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&   lineNumberProbeAlsoBrokenn   s    z<FailureElementTests.setUp.<locals>.lineNumberProbeAlsoBroken   T)ZcaptureVarsN)__code__co_firstlinenobaser   failureframesframe)r#   r8   r%   r%   r&   setUpj   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render
sourceLine2   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                    s   t ttjtjddtjdddd j}dddg}td|}trhd	 fd
dt	|D 
d}nd	 fddt	|D }| j| |S )z
        L{_SourceFragmentElement} renders source lines at and around the line
        number indicated by a frame object.
        rB   rC   rE   ZsourceLinesu#       message = "This is a problem"u       raise Exception(message)zE# Figure out the line number from which the exception will be raised.N c                    s4   g | ],\}}d ddg|dk  j | d| f qS )?<div class="snippet%sLine"><span>%d</span><span>%s</span></div>rN   	Highlightr9              )r=   .0rB   rE   r#   r%   r&   
<listcomp>   s   zBFailureElementTests.test_sourceFragmentElement.<locals>.<listcomp>utf8c                    s:   g | ]2\}}d ddg|dk  j | d| df qS )rO   rN   rP   r9   rQ   rV   )r=   rJ   rR   rT   r%   r&   rU      s   )r   r   r   rG   rH   r@   r   r   join	enumeraterJ   rI   r    )r#   rK   sourcerL   ZstringToCheckForr%   rT   r&   test_sourceFragmentElement   s0    



	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}.
        filenamerC   N   <span>c   </span>)r   r   r   rH   r@   r   rI   r    r
   __file__rstripr#   rK   rL   r%   r%   r&   test_frameElementFilename   s    
z-FailureElementTests.test_frameElementFilenamec                 C   sF   t ttjdd| j}td|}|| jdt| j	d  d  |S )z
        The I{lineNumber} renderer of L{_FrameElement} renders the line number
        associated with the frame object used to initialize the
        L{_FrameElement}.
        rB   rC   Nr\   r9   r^   )
r   r   r   rH   r@   r   rI   r    r	   r=   ra   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}.
        ZfunctionrC   Ns&   <span>lineNumberProbeAlsoBroken</span>)r   r   r   rH   r@   r   rI   r    ra   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}.
        NrY   )r   r@   lookupRenderMethodr   rG   assertIsInstancer   assertIdenticalr    loaderloadr#   rK   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   r?   r   r9   )r   r>   r?   re   r   rG   rf   listr   rg   r@   ZassertNotEqualrh   ri   r    lenrj   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   r>   re   r   rG   rf   r   rg   ZstackFramesr?   r    rh   ri   rj   r%   r%   r&   test_failureElementTraceback  s    


z0FailureElementTests.test_failureElementTracebackc                 C   sJ   t | jttjdd}td|}tr,d}nd}|| jd| d  |S )zi
        The I{type} renderer of L{FailureElement} renders the failure's
        exception type.
        typerC   Ns   builtins.Exceptions   exceptions.Exceptionr\   r^   )	r   r>   r   r   rH   r   r   rI   r    )r#   rK   rL   excr%   r%   r&   test_failureElementType  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.
        valuerC   Ns   <span>This is a problem</span>)r   r>   r   r   rH   r   rI   r    ra   r%   r%   r&   test_failureElementValue+  s     
 z,FailureElementTests.test_failureElementValueN)r1   r2   r3   r4   rA   rM   rZ   rb   rc   rd   rm   rq   rs   rv   rx   r%   r%   r%   r&   r5   e   s   -r5   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   objectrT   r%   r%   r&   test_flattenerError>  s    z&FormatFailureTests.test_flattenerErrorc                 C   sv   zt dW n   tt }Y nX | |t trN| tdd |D  n| 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%   rS   Zchr%   r%   r&   	<genexpr>S  s     z7FormatFailureTests.test_returnsBytes.<locals>.<genexpr>c                 s   s   | ]}t |d k V  qdS r|   )ordr~   r%   r%   r&   r   U  s     s   &#160;N)	r6   r   r   rf   bytesr   Z
assertTrueallZassertIn)r#   rl   r%   r%   r&   test_returnsBytesF  s    z$FormatFailureTests.test_returnsBytesN)r1   r2   r3   r4   r{   r   r%   r%   r%   r&   ry   9  s   ry   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$   rL   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 )Nr9   ZfooZbarZbaz)r   ResourceZisLeafr   r   ZgetChildForRequestr    Zpostpath)r#   rsrL   r%   r%   r&   testDeferredResourcel  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   appendrD   r   r   r   r   r   r    )r#   Zrenderedr$   rl   deferredResourcer%   r%   r&   test_renderu  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failrD   r    ZfailureResultOfgcZcollectZflushLoggedErrors)r#   r$   rL   r>   r   errorsr%   r%   r&   test_renderNoFailure  s    


z*DeferredResourceTests.test_renderNoFailureN)r1   r2   r3   r4   r   r   r   r%   r%   r%   r&   r   g  s   	r   )/r4   Z
__future__r   r   r   Ztwisted.python.failurer   Ztwisted.trial.unittestr   r   Ztwisted.internetr   Ztwisted.python.compatr   r	   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   r5   ry   r   r   r   r%   r%   r%   r&   <module>   s,   H U"