
    Evg                        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 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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#m$Z$m%Z% d dl&m'Z' d dl(m)Z)m*Z*m+Z+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z: dZ;dZ<de<z  Z= e:d          Z> e:d          Z? e@e
jA        e
jB        e
jC        e
jD        e
jE        g          ZF G d deG          ZH G d  d!e          ZId" ZJd# ZKd$ ZL G d% d&e          ZM G d' d(e          ZNd) ZOd* ZPd+ ZQ G d, d-          ZR G d. d/eR          ZS G d0 d1          ZT G d2 d3eTeR          ZU G d4 d5eTeS          ZVdS )6    N)Iterable)copy)partial)
HTTPStatus)import_module)BytesIOIOBase)unquote_to_bytesurljoinurlparseurlsplit)sync_to_async)settings)ASGIRequest)BaseHandler)LimitedStreamWSGIRequest)DjangoJSONEncoder)got_request_exceptionrequest_finishedrequest_started)close_old_connections)HttpHeadersHttpRequest	QueryDictSimpleCookie)signals)ContextListresolve)force_bytes)SimpleLazyObject)	urlencode)_lazy_re_compile)AsyncClientAsyncRequestFactoryClientRedirectCycleErrorRequestFactoryencode_fileencode_multipartBoUnDaRyStRiNgz multipart/form-data; boundary=%sz.*; charset=([\w-]+);?z^application\/(.+\+)?jsonc                   "     e Zd ZdZ fdZ xZS )r(   z9The test client has been asked to follow a redirect loop.c                 p    t                                          |           || _        |j        | _        d S N)super__init__last_responseredirect_chain)selfmessager2   	__class__s      O/var/www/pixelcanvas.ch/venv/lib/python3.11/site-packages/django/test/client.pyr1   zRedirectCycleError.__init__>   s4    !!!*+:    )__name__
__module____qualname____doc__r1   __classcell__r6   s   @r7   r(   r(   ;   s>        CC; ; ; ; ; ; ; ; ;r8   r(   c                   6    e Zd ZdZd	dZd Zd
dZd
dZd ZdS )FakePayloada  
    A wrapper around BytesIO that restricts what can be read since data from
    the network can't be sought and cannot be read outside of its content
    length. This makes sure that views can't do anything under the test client
    that wouldn't work in real life.
    Nc                 z    t                      | _        d| _        d| _        ||                     |           d S d S )Nr   F)r   _FakePayload__content_FakePayload__lenread_startedwrite)r4   initial_bytess     r7   r1   zFakePayload.__init__L   sB     
!$JJ}%%%%% %$r8   c                     | j         S r/   )rC   )r4   s    r7   __len__zFakePayload.__len__S   s
    zr8   c                   | j         s!| j                            d           d| _         |dk    s|| j        }| j        |k    s
J d            | j                            |          }| xj        t          |          z  c_        |S Nr   TrI   zFCannot read more than the available bytes from the HTTP incoming data.)rD   rB   seekrC   readlenr4   sizecontents      r7   rM   zFakePayload.readV   s      	%N""" $D2:::DJ$S .%%d++

c'll"

r8   c                   | j         s!| j                            d           d| _         |dk    s|| j        }| j        |k    s
J d            | j                            |          }| xj        t          |          z  c_        |S rK   )rD   rB   rL   rC   readlinerN   rO   s      r7   rS   zFakePayload.readlinec   s      	%N""" $D2:::DJ$S .))$//

c'll"

r8   c                    | j         rt          d          t          |          }| j                            |           | xj        t          |          z  c_        d S )Nz.Unable to write a payload after it's been read)rD   
ValueErrorr!   rB   rE   rC   rN   )r4   brQ   s      r7   rE   zFakePayload.writep   sX     	OMNNNa..W%%%

c'll"



r8   r/   )rI   )	r9   r:   r;   r<   r1   rH   rM   rS   rE    r8   r7   r@   r@   D   sx         & & & &        # # # # #r8   r@   c              #     K   	 | E d {V  t          j        t                      |             t          j        t                     d S # t          j        t                      |             t          j        t                     w xY wr/   r   
disconnectr   connect)iterablecloses     r7   closing_iterator_wrapperr^   x   s      8#$9::: !677777 	#$9::: !67777s   A
 
>Bc                (  K   	 | 2 3 d {V }|W V  6 	 t          j        t                      |             t          j        t                     d S # t          j        t                      |             t          j        t                     w xY wr/   rY   )r\   r]   chunks      r7   aclosing_iterator_wrapperra      s      8# 	 	 	 	 	 	 	%KKKKK $8 	#$9::: !677777 	#$9::: !67777s   A A >Bc                     d|j         cxk    rdk     sn |j         dv r|j        rg |_        nd|_        | j        dk    r|j        rg |_        nd|_        |S )z
    Simulate the behavior of most web servers by removing the content of
    responses for HEAD requests, 1xx, 204, and 304 responses. Ensure
    compliance with RFC 9112 Section 6.3.
    d      )   i0  r8   HEAD)status_code	streamingstreaming_contentrQ   method)requestresponses     r7   conditional_content_removalrm      s     h"((((S((((H,@J,N,N 	#)+H&&"H~ 	#)+H&&"HOr8   c                   *     e Zd ZdZd fd	Zd Z xZS )ClientHandlerz
    An HTTP Handler that can be used for testing purposes. Use the WSGI
    interface to compose requests, but return the raw HttpResponse object with
    the originating WSGIRequest attached to its ``wsgi_request`` attribute.
    Tc                 H    || _          t                      j        |i | d S r/   enforce_csrf_checksr0   r1   r4   rr   argskwargsr6   s       r7   r1   zClientHandler.__init__   -    #6 $)&)))))r8   c                    | j         |                                  t          j        t                     t          j        | j        |           t          j        t                     t          |          }| j	         |_
        |                     |          }t          ||           ||_        |j        rG|j        r t!          |j        |j                  |_        nft'          |j        |j                  |_        nFt)          j        t                     |                                 t)          j        t                     |S )N)senderenviron)_middleware_chainload_middlewarer   rZ   r   sendr6   r[   r   rr   _dont_enforce_csrf_checksget_responserm   wsgi_requestrh   is_asyncra   ri   r]   r^   r   )r4   ry   rk   rl   s       r7   __call__zClientHandler.__call__   s=    !)  """"#8999DNGDDDD 5666g&&
 150H,H) $$W-- 	$GX666 !(  	<  -F.. .** .F.. .** '(=>>>NN$%:;;;r8   Tr9   r:   r;   r<   r1   r   r=   r>   s   @r7   ro   ro      sV         * * * * * *) ) ) ) ) ) )r8   ro   c                   *     e Zd ZdZd fd	Zd Z xZS )AsyncClientHandlerz"An async version of ClientHandler.Tc                 H    || _          t                      j        |i | d S r/   rq   rs   s       r7   r1   zAsyncClientHandler.__init__   rv   r8   c           	      X  K   | j         |                     d           d|v r|                    d          }nt          d          }t	          j        t                     t	          j        | j        |           d {V  t	          j	        t                     t          |t          |t          |                              }| j         |_        |                     |           d {V }t!          ||           ||_        |j        rG|j        r t)          |j        |j                  |_        nvt/          |j        |j                  |_        nVt1          j        t                      t3          |j        d                       d {V  t1          j	        t                     |S )NT)r   
_body_file )rx   scopeF)thread_sensitive)rz   r{   popr@   r   rZ   r   asendr6   r[   r   r   rN   rr   r}   get_response_asyncrm   asgi_requestrh   r   ra   ri   r]   r^   r   r   )r4   r   	body_filerk   rl   s        r7   r   zAsyncClientHandler.__call__   s      !)  $ ///5  		,//II#BI"#8999#4>GGGGGGGGGG 5666e]9c)nn%M%MNN 150H,H)0099999999#GX666 !( 	<  -F.. .** .F.. .** '(=>>>G-GGGIIIIIIIII$%:;;;r8   r   r   r>   s   @r7   r   r      sR        ,,* * * * * ** * * * * * *r8   r   c                     |                      dg                               |           d| vrt                      | d<   | d                             t          |                     dS )z
    Store templates and contexts that are rendered.

    The context is copied so that it is an accurate representation at the time
    of rendering.
    	templatescontextN)
setdefaultappendr   r   )storesignalrx   templater   ru   s         r7   store_rendered_templatesr   	  sf     
["%%,,X666&==i	)DMM*****r8   c           	         g }d d }|                                 D ] \  }}|t          d|z             ||          r%|                    t          | ||                     Jt	          |t
                    svt	          |t                    ra|D ]]} ||          r%|                    t          | ||                     2|                    fdd| z  d|z  d|fD                        ^|                    fd	d| z  d|z  d|fD                        |                     d
| z            dg           d                    |          S )a+  
    Encode multipart POST data from a dictionary of form values.

    The key will be used as the form data name; the value will be transmitted
    as content. If the value is a file, the contents of the file will be sent
    as an application/octet-stream; otherwise, str(value) will be sent.
    c                 6    t          | t          j                  S r/   r!   r   DEFAULT_CHARSETss    r7   to_bytesz"encode_multipart.<locals>.to_bytes       1h6777r8   c                 J    t          | d          ot          | j                  S )NrM   )hasattrcallablerM   )things    r7   is_filez!encode_multipart.<locals>.is_file$  s!    uf%%>(5:*>*>>r8   NzeCannot encode None for key '%s' as POST data. Did you mean to pass an empty string or omit the value?c              3   .   K   | ]} |          V  d S r/   rW   .0valr   s     r7   	<genexpr>z#encode_multipart.<locals>.<genexpr>7  s?       ! ! !! ! ! ! ! !r8   --%sz)Content-Disposition: form-data; name="%s"r   c              3   .   K   | ]} |          V  d S r/   rW   r   s     r7   r   z#encode_multipart.<locals>.<genexpr>A  s?              r8   z--%s--r8   s   
)items	TypeErrorextendr*   
isinstancestrr   join)boundarydatalinesr   keyvalueitemr   s          @r7   r+   r+     s    E8 8 8? ? ? jjll  
U==?BC   WU^^ 	LLXsE::;;;;E3'' 	Juh,G,G 	  74== LLXsD!A!ABBBBLL ! ! ! ! #X-G#M 	$! ! !    	 LL     X%?#E	       
LLHX())	
   <<r8   c                    d }t          |d          ot          |j        t                    }|r$t          j                            |j                  nd}t          |d          r|j        }n|rt          j	        |          d         }nd }|d}|p|} |d| z             |d|d	|d
           |d|z            d ||
                                          gS )Nc                 6    t          | t          j                  S r/   r   r   s    r7   r   zencode_file.<locals>.to_bytesU  r   r8   namer   content_typer   application/octet-streamr   z&Content-Disposition: form-data; name="z"; filename=""zContent-Type: %sr8   )r   r   r   r   ospathbasenamer   	mimetypes
guess_typerM   )r   r   filer   file_has_string_namefilenamer   s          r7   r*   r*   T  s   8 8 8
 #400OZ	35O5O.BJrw	***Ht^$$ (	  +H55a813H("##JM##xxxX	
 	
 	#l233 r8   c                       e Zd ZdZeddddZd Zd Zd Zd Z	d	 Z
	 dddddZded
fddddZ	 dddddZdddddZ	 	 	 dddddZ	 	 	 dddddZ	 	 	 dddddZ	 	 	 dddddZ	 	 	 dddddZdS )r)   aV  
    Class that lets you create mock Request objects for use in testing.

    Usage:

    rf = RequestFactory()
    get_request = rf.get('/hello/')
    post_request = rf.post('/submit/', {'foo': 'bar'})

    Once you have a request object you can pass it to any view function,
    just as if that view had been hooked up using a URLconf.
    N)json_encoderheadersquery_paramsc                   || _         || _        t                      | _        t	                      | _        |r,| j                            t          j        |                     |rt          |d          | j        d<   d S d S )NTdoseqQUERY_STRING)
r   defaultsr   cookiesr   errorsupdater   to_wsgi_namesr#   )r4   r   r   r   r   s        r7   r1   zRequestFactory.__init__  s     ) #~~ii 	EM  !:7!C!CDDD 	P,5l$,O,O,ODM.)))	P 	Pr8   c                     d                     t          d | j                                        D                                 ddddddd	d
dt	          d          | j        dddd| j        |S )z5
        The base environment for a request.
        z; c              3   8   K   | ]}|j         d |j        V  dS )=N)r   coded_valuer   morsels     r7   r   z/RequestFactory._base_environ.<locals>.<genexpr>  sG          &zzz6+=+=>     r8   /	127.0.0.1GETr   
testserver80zHTTP/1.1)   r   httpr8   TF)HTTP_COOKIE	PATH_INFOREMOTE_ADDRREQUEST_METHODSCRIPT_NAMESERVER_NAMESERVER_PORTSERVER_PROTOCOLzwsgi.versionwsgi.url_scheme
wsgi.inputzwsgi.errorszwsgi.multiprocesszwsgi.multithreadzwsgi.run_once)r   sortedr   valuesr@   r   r   r4   rk   s     r7   _base_environzRequestFactory._base_environ  s      99  "&,"5"5"7"7      &#')"%%c**;!% %")
 
* m+
, -
 	
r8   c                 6    t           | j        di |          S )#Construct a generic request object.rW   )r   r   r   s     r7   rk   zRequestFactory.request  s$    -4-8888999r8   c                     |t           u rt          t          |          S t                              |          }|r	|d         }nt
          j        }t          ||          S )Nr   )encoding)MULTIPART_CONTENTr+   BOUNDARYCONTENT_TYPE_REmatchr   r   r!   )r4   r   r   r   charsets        r7   _encode_datazRequestFactory._encode_data  sa    ,,,#Hd333 $)),77E 3("2tg6666r8   c                     t                               |          o!t          |t          t          t
          f          }|rt          j        || j                  n|S )zu
        Return encoded JSON if data is a dict, list, or tuple and content_type
        is application/json.
        )cls)	JSON_CONTENT_TYPE_REr   r   dictlisttuplejsondumpsr   )r4   r   r   should_encodes       r7   _encode_jsonzRequestFactory._encode_json  s[    
 -22<@@ 
Z4u%F
 F
 ;HQtz$D$56666TQr8   c                     |j         }|j        r|d|j        z   z  }t          |          }|                    d          S )N;
iso-8859-1)r   paramsr
   decode)r4   parsedr   s      r7   	_get_pathzRequestFactory._get_path  sE    {= 	(C&-''D%% {{<(((r8   Fr   r   c                b    |r|rt          d          |p|}|i n|} | j        d|f|||d|S )zConstruct a GET request.7query_params and data arguments are mutually exclusive.Nr   securer   r   rU   genericr4   r   r   r  r   r   extras          r7   getzRequestFactory.get  sw      	XD 	XVWWW+|)1rr|t|
 %
 
 
 
 	
r8   c                    |                      |i n||          }|                     ||          } | j        d|||f|||d|S )zConstruct a POST request.NPOSTr  )r  r   r  )	r4   r   r   r   r  r   r   r  	post_datas	            r7   postzRequestFactory.post  sw       t||LL%%dL99	t|		

 %	
 	
 	
 	
 		
r8   c                b    |r|rt          d          |p|}|i n|} | j        d|f|||d|S )zConstruct a HEAD request.r  Nrf   r  r  r  s          r7   headzRequestFactory.head  sw      	XD 	XVWWW+|)1rr|t|
 %
 
 
 
 	
r8   c                (     | j         d|f|||d|S )zConstruct a TRACE request.TRACEr  r  )r4   r   r  r   r   r  s         r7   tracezRequestFactory.trace  s=    t|
 %
 
 
 
 	
r8   r   r   c                ,     | j         d|||f|||d|S )zConstruct an OPTIONS request.OPTIONSr  r  r4   r   r   r   r  r   r   r  s           r7   optionszRequestFactory.options  sE     t|		

 %	
 	
 	
 	
 		
r8   c                X    |                      ||          } | j        d|||f|||d|S )zConstruct a PUT request.PUTr  r  r  r!  s           r7   putzRequestFactory.put5  sZ       |44t|		

 %	
 	
 	
 	
 		
r8   c                X    |                      ||          } | j        d|||f|||d|S )zConstruct a PATCH request.PATCHr  r%  r!  s           r7   patchzRequestFactory.patchM  sZ       |44t|		

 %	
 	
 	
 	
 		
r8   c                X    |                      ||          } | j        d|||f|||d|S )zConstruct a DELETE request.DELETEr  r%  r!  s           r7   deletezRequestFactory.deletee  sZ       |44t|		

 %	
 	
 	
 	
 		
r8   c                   t          t          |                    }	t          |t          j                  }|                     |	          ||rdnd|rdndd}
|r@|
                    t          t          |                    |t          |          d           |r'|                    t          j
        |                     |rt          |d          |d	<   |
                    |           |
                    d	          s2|	d
                                                             d          }||
d	<    | j        di |
S )$Construct an arbitrary HTTP request.443r   httpsr   )r   r   r   r   )CONTENT_LENGTHCONTENT_TYPEr   Tr   r      r  rW   )r   r   r!   r   r   r
  r   rN   r@   r   r   r#   r  encoder  rk   )r4   rj   r   r   r   r  r   r   r  r	  rquery_strings               r7   r  zRequestFactory.generic}  sU    #d))$$4!9:://$$*455*0<wwf	
 
  	HH&)#d))nn$0"-d"3"3     	=LL27;;<<< 	H$-l$$G$G$GE.!	uu^$$ 	-!!9++--44\BBL ,Ant|  a   r8   )NF)Fr   r   F)r9   r:   r;   r<   r   r1   r   rk   r   r  r
  r  r   r  r  r  r"  r&  r)  r,  r  rW   r8   r7   r)   r)   r  s.          'P P P P P"
 
 
B: : :
7 
7 
7R R R	) 	) 	) ',
8<4
 
 
 
 
( &
 
 
 
 
 
6 ',
8<4
 
 
 
 
"	
4d 	
 	
 	
 	
 	
 /
 
 
 
 
 
4 /
 
 
 
 
 
6 /
 
 
 
 
 
6 /
 
 
 
 
 
8 /'! '! '! '! '! '! '! '!r8   r)   c                   4    e Zd ZdZd Zd Z	 	 	 d
dddd	ZdS )r&   a  
    Class that lets you create mock ASGI-like Request objects for use in
    testing. Usage:

    rf = AsyncRequestFactory()
    get_request = rf.get("/hello/")
    post_request = rf.post("/submit/", {"foo": "bar"})

    Once you have a request object you can pass it to any view function,
    including synchronous ones. The reason we have a separate class here is:
    a) this makes ASGIRequest subclasses, and
    b) AsyncClient can subclass it.
    c           
          ddiddddgdddg d	| j         |}|d
                             dd                    t          d | j                                        D                                 f           |S )zThe base scope for a request.versionz3.0r   z1.1r   r   )r   r   r   )asgitypehttp_versionclientserverschemerj   r   r   s   cookies   ; c              3   ^   K   | ](}|j         d |j                            d          V  )dS )r   asciiN)r   r   r4  r   s     r7   r   z2AsyncRequestFactory._base_scope.<locals>.<genexpr>  sU        " %+JJJ0B0BCKKGTT     r8   )r   r   r   r   r   r   )r4   rk   r   s      r7   _base_scopezAsyncRequestFactory._base_scope  s     &!"A&*
 
 m
 
 	i

  &*l&9&9&;&;     
	
 
	
 
	
 r8   c           	          d|v r|                     d          }nt          d          }t           | j        di |t	          |t          |                              S )r   r   r   rW   )r   r@   r   rC  r   rN   )r4   rk   r   s      r7   rk   zAsyncRequestFactory.request  sg    
 7""L11II#BID''w''y#i..)Q)Q
 
 	
r8   r   r   FNr  c                   t          t          |                    }	t          |t          j                  }||                     |	          d|rdndf|rdnddgd}
|rs|
d                             d	t          t          |                                        d
          fd|                    d
          fg           t          |          |
d<   |rt          |d          |
d<   n)|                    dd          x}r||
d<   n|	d         |
d<   |r'|                    t          j        |                     |
dxx         d |                                D             z  cc<    | j        di |
S )r.  r   r/  r   r0  r   )s   hosts
   testserver)rj   r   r?  r@  r   r   s   content-lengthrB  s   content-typer   Tr   r6  r   Nr3  c                     g | ]A\  }}|                                                     d           |                    d          fBS )rB  latin1)lowerr4  )r   r   r   s      r7   
<listcomp>z/AsyncRequestFactory.generic.<locals>.<listcomp>
  sS     
 
 
U YY[[((%,,x*@*@A
 
 
r8   rW   )r   r   r!   r   r   r
  r   rN   r4  r@   r#   r   r   r   to_asgi_namesr   rk   )r4   rj   r   r   r   r  r   r   r  r	  r   r6  s               r7   r  zAsyncRequestFactory.generic  s    #d))$$4!9::NN6**"V$=EE>!'3ggV01
 
  	0iL&CII(=(=g(F(FG$l&9&9'&B&BC   *$//AlO 	* ),d C C CAn"YY~t<<<\ 	* ,An !'q	An 	=LL27;;<<<	) 
 
#kkmm
 
 
 	
 t|  a   r8   r7  )r9   r:   r;   r<   rC  rk   r  rW   r8   r7   r&   r&     sm           <
 
 
$ /,! ,! ,! ,! ,! ,! ,! ,!r8   r&   c                       e Zd ZdZd Zd Zed             Zd Zd Z	d Z
dd	Zdd
Zd ZddZddZd Zd Zd Zd ZddddddZd ZdS )ClientMixinzC
    Mixin with common methods between Client and AsyncClient.
    c                 6    t          j                    | _        dS )z3Store exceptions when they are generated by a view.N)sysexc_info)r4   ru   s     r7   store_exc_infozClientMixin.store_exc_info  s    r8   c                 f    | j         |_         | j         r| j         \  }}}d| _         | j        r|dS dS )z
        Look for a signaled exception, clear the current context exception
        data, re-raise the signaled exception, and clear the signaled exception
        from the local cache.
        N)rO  raise_request_exception)r4   rl   _	exc_values       r7   check_exceptionzClientMixin.check_exception  sP     !M= 	 "mOAy! DM+  		  	    r8   c                 :   t          t          j                  }| j                            t          j                  }|r|                    |j                  S |                                }|                                 |j	        | j        t          j        <   |S )z%Return the current session variables.)
r   r   SESSION_ENGINEr   r  SESSION_COOKIE_NAMESessionStorer   savesession_keyr4   enginecookiesessions       r7   r_  zClientMixin.session'  s     x677!!(">?? 	5&&v|444%%''5<5HX12r8   c                 J  K   t          t          j                  }| j                            t          j                  }|r|                    |j                  S |                                }|                                 d {V  |j	        | j        t          j        <   |S r/   )
r   r   rW  r   r  rX  rY  r   asaver[  r\  s       r7   asessionzClientMixin.asession3  s      x677!!(">?? 	5&&v|444%%''mmoo5<5HX12r8   c                 T    ddl m}  |di |}|r|                     |           dS dS )z
        Set the Factory to appear as if it has successfully logged into a site.

        Return True if login is possible or False if the provided credentials
        are incorrect.
        r   )authenticateTFrW   )django.contrib.authrd  _login)r4   credentialsrd  users       r7   loginzClientMixin.login=  sO     	544444|**k** 	KK4ur8   c                 p   K   ddl m}  |di | d{V }|r|                     |           d{V  dS dS )zSee login().r   )aauthenticateNTFrW   )re  rk  _alogin)r4   rg  rk  rh  s       r7   aloginzClientMixin.aloginL  su      555555"]11[11111111 	,,t$$$$$$$$$4ur8   Nc                 l    ||                                  }||_        |                     ||           d S r/   )_get_backendbackendrf  r4   rh  rp  s      r7   force_loginzClientMixin.force_loginV  s9    ?''))GD'"""""r8   c                 |   K   ||                                  }||_        |                     ||           d {V  d S r/   )ro  rp  rl  rq  s      r7   aforce_loginzClientMixin.aforce_login\  sO      ?''))Gll4)))))))))))r8   c                 n    ddl m} t          j        D ]!} ||          }t	          |d          r|c S "d S )Nr   )load_backendget_user)re  rv  r   AUTHENTICATION_BACKENDSr   )r4   rv  backend_pathrp  s       r7   ro  zClientMixin._get_backendb  sb    444444$< 	$ 	$L"l<00Gw
++ $####$	$ 	$r8   c                 0   ddl m} t                      }| j        r| j        |_        n2t	          t
          j                  }|                                |_         ||||           |j                                         | 	                    |           d S )Nr   )ri  )
re  ri  r   r_  r   r   rW  rY  rZ  _set_login_cookies)r4   rh  rp  ri  rk   r]  s         r7   rf  zClientMixin._loginj  s    ------ --< 	4"lGOO"8#:;;F$1133GOgtW%%%(((((r8   c                 l  K   ddl m} t                      }|                                  d {V }|r||_        n2t          t          j                  }|                                |_         ||||           d {V  |j        	                                 d {V  | 
                    |           d S )Nr   )rm  )re  rm  r   rb  r_  r   r   rW  rY  ra  r{  )r4   rh  rp  rm  rk   r_  r]  s          r7   rl  zClientMixin._aloginy  s      ...... --'''''' 	4%GOO"8#:;;F$1133GOfWdG,,,,,,,,,o##%%%%%%%%%(((((r8   c                     t           j        }|j        j        | j        |<   d dt           j        t           j        pd d d}| j        |                             |           d S )Nr   )zmax-ager   domainr  expires)r   rX  r_  r[  r   SESSION_COOKIE_DOMAINSESSION_COOKIE_SECUREr   )r4   rk   session_cookiecookie_datas       r7   r{  zClientMixin._set_login_cookies  sd    !5'.'B^$44<
 
 	^$++K88888r8   c                    ddl m}m} t                      }| j        r| j        |_         ||          |_        n2t          t          j                  }|	                                |_         ||           t                      | _        dS )z<Log out the user by removing the cookies and session object.r   )rw  logoutN)re  rw  r  r   r_  rh  r   r   rW  rY  r   r   )r4   rw  r  rk   r]  s        r7   r  zClientMixin.logout  s    88888888--< 	4"lGO#8G,,GLL"8#:;;F$1133GOw#~~r8   c                 V  K   ddl m}m} t                      }|                                  d{V }|r||_         ||           d{V |_        n2t          t          j	                  }|
                                |_         ||           d{V  t                      | _        dS )zSee logout().r   )	aget_useralogoutN)re  r  r  r   rb  r_  rh  r   r   rW  rY  r   r   )r4   r  r  rk   r_  r]  s         r7   r  zClientMixin.alogout  s      ::::::::--'''''' 	4%GO!*7!3!3333333GLL"8#:;;F$1133GOgg#~~r8   c                 <   t          |d          st                              |                    d                    s%t	          d|                    d          z            t          j        |j                            |j	                  fi ||_
        |j
        S )N_jsonzContent-Typez3Content-Type header is "%s", not "application/json")r   r   r   r  rU   r   loadsrQ   r  r   r  )r4   rl   r  s      r7   _parse_jsonzClientMixin._parse_json  s    x)) 	'--hll>.J.JKK  Ill>223   "Z ''(899 =B HN ~r8   r   r   r   r   r   c          	         |j         }|j        }|                    ||j        f           t	          |          }	|	j        r
|	j        |d<   |	j        r|	j        |d<   |	j        |d<   |	j        rt          |	j                  |d<   |	j	        }
|
s	|	j
        rd}
|
                    d          st          |j        d         |
          }
|j        t          j        t          j        fv r>|j        d                                         }|dvr
|	j        |d	<   t'          | |          }n| j        }t+          |	j                  }d
} ||
f||d||d|S )z9Follow a single redirect contained in response using GET.r   r   	HTTP_HOSTr   r   r   r   )r  r  r   NF)r   r   followr   r   )urlr3   r   rg   r   r@  hostnameportr   r   netloc
startswithr   rk   r   TEMPORARY_REDIRECTPERMANENT_REDIRECTrH  querygetattrr  r   )r4   rl   r   r   r   r   r  response_urlr3   r  r   request_methods               r7   _follow_redirectzClientMixin._follow_redirect  s     |!0|X-ABCCC|$$: 	2'*zE#$< 	.#&<E- !$E+8 	1#&sx==E- x 	
 	Ds## 	@8+K8$??D))$
 
 
 &-.>?EEGGN_44(+	n%$T>::NN!XNSY''DL~
%%
 
 
 
 	
r8   c                     |j         }|d         |dd         v rt          d|          t          |          dk    rt          d|          dS )zU
        Raise a RedirectCycleError if response contains too many redirects.
        rI   NzRedirect loop detected.)r2      zToo many redirects.)r3   r(   rN   )r4   rl   r3   s      r7   _ensure_redirects_not_cyclicz(ClientMixin._ensure_redirects_not_cyclic  sl     "0"!444 %%>hWWWW~## %%:(SSSS	 $#r8   r/   )r9   r:   r;   r<   rP  rU  propertyr_  rb  ri  rm  rr  rt  ro  rf  rl  r{  r  r  r  r  r  rW   r8   r7   rL  rL    s[        ' ' '      	 	 X	      # # # #* * * *$ $ $) ) ) )) ) ) )"9 9 9& & && & &
 
 
  7
 7
 7
 7
 7
rT T T T Tr8   rL  c                        e Zd ZdZ	 	 dddd fdZd Z	 	 	 dddd fdZdeddfddd fd	Z	 	 	 dddd fd
Z		 	 	 	 dddd fdZ
	 	 	 	 dddd fdZ	 	 	 	 dddd fdZ	 	 	 	 dddd fdZ	 	 	 dddd fdZ	 	 	 	 ddZ xZS )r'   a  
    A class that can act as a client for testing purposes.

    It allows the user to compose GET and POST requests, and
    obtain the response that the server gave to those requests.
    The server Response objects are annotated with the details
    of the contexts and templates that were rendered during the
    process of serving the request.

    Client objects are stateful - they will retain cookie (and
    thus session) details for the lifetime of the Client instance.

    This is not intended as a replacement for Twill/Selenium or
    the like - it is here to allow testing against the
    contexts and templates produced by a view, rather than the
    HTML rendered to the end-user.
    FTNr  c                     t                      j        d||d| t          |          | _        || _        d | _        d | _        d | _        d S Nr  rW   )r0   r1   ro   handlerrR  rO  r  r   r4   rr   rR  r   r   r   r6   s         r7   r1   zClient.__init__  sZ     	P|PPxPPP$%899'>$
r8   c                     | j         di }i }t          t          |          }dt                    z  }t          j                            ||           dt                    z  }t          j        | j        |           	 | 	                    |          }t          j        
                    |           t          j
        |           n:# t          j        
                    |           t          j
        |           w xY w|                     |           | |_        |_        |                    dg           |_        |                    d          |_        t          | j        |          |_        t'          |j        dd          t+          fd          |_        |j        r*t/          |j                  d	k    r|j        d
         |_        |j        r| j                            |j                   |S )a  
        Make a generic request. Compose the environment dictionary and pass
        to the handler, return the result of the handler. Assume defaults for
        the query environment, which can be overridden using the arguments to
        the request.
        template-render-%sdispatch_uidrequest-exception-%sr   r   urlconfNc                  2    t           d                   S )Nr   r  r   rk   r  s   r7   <lambda>z Client.request.<locals>.<lambda>O  s    GGK0'BBB r8   r   r   rW   )r   r   r   idr   template_renderedr[   r   rP  r  rZ   rU  r>  rk   r  r   r   r  r   r  r   r"   resolver_matchrN   r   r   )	r4   rk   ry   r   on_template_render
signal_uidexception_uidrl   r  s	    `      @r7   rk   zClient.request,  s    %$$//w// $%=tDD)BwKK7
!))*<:)VVV.G<%d&9VVVV	I||G,,H%00j0III!,-HHHHH %00j0III!,-HHHHHX&&&"!XXk26688I.. 0(;;(/DAA"2BBBBB#
 #
  	3H$4 5 5 : :'/2H 	2L 0111s   C 7D
c                    || _         || _         t                      j        |f||||d|}|r | j        |f|||d|}|S )-Request a response from the server using GET.r   r  r   r   r   r   r   )r  r   r0   r  _handle_redirects
r4   r   r   r  r  r   r   r  rl   r6   s
            r7   r  z
Client.get[  s     
577;
%
 
 
 
  	-t-#W< SX H r8   c          	          || _         || _         t                      j        |f|||||d|}	|r | j        |	f||||d|}	|	S ).Request a response from the server using POST.r   r   r  r   r   r  )r  r   r0   r  r  r4   r   r   r   r  r  r   r   r  rl   r6   s             r7   r  zClient.postw  s     
577<
%%
 
 
 
  	-t-))   H r8   c                    || _         || _         t                      j        |f||||d|}|r | j        |f|||d|}|S ).Request a response from the server using HEAD.r  r  )r  r   r0   r  r  r  s
            r7   r  zClient.head  s     
577<
%
 
 
 
  	-t-#W< SX H r8   r   r   c          	          || _         || _         t                      j        |f|||||d|}	|r | j        |	f||||d|}	|	S )1Request a response from the server using OPTIONS.r  r  )r  r   r0   r"  r  r  s             r7   r"  zClient.options  s     
"577?
%%
 
 
 
  	-t-))   H r8   c          	          || _         || _         t                      j        |f|||||d|}	|r | j        |	f||||d|}	|	S )(Send a resource to the server using PUT.r  r  )r  r   r0   r&  r  r  s             r7   r&  z
Client.put  s     
577;
%%
 
 
 
  	-t-))   H r8   c          	          || _         || _         t                      j        |f|||||d|}	|r | j        |	f||||d|}	|	S )*Send a resource to the server using PATCH.r  r  )r  r   r0   r)  r  r  s             r7   r)  zClient.patch  s     
 577=
%%
 
 
 
  	-t-))   H r8   c          	          || _         || _         t                      j        |f|||||d|}	|r | j        |	f||||d|}	|	S )$Send a DELETE request to the server.r  r  )r  r   r0   r,  r  r  s             r7   r,  zClient.delete  s     
!577>
%%
 
 
 
  	-t-))   H r8   c                    || _         || _         t                      j        |f||||d|}|r | j        |f|||d|}|S )#Send a TRACE request to the server.r  r  )r  r   r0   r  r  r  s
            r7   r  zClient.traceB  s     
 577=
%
 
 
 
  	-t-#W< SX H r8   c                     g |_         |j        t          v rD|j         } | j        |f||||d|}||_         |                     |           |j        t          v D|S )Y
        Follow any redirects by requesting responses from the server using GET.
        r  r3   rg   REDIRECT_STATUS_CODESr  r  r4   rl   r   r   r   r   r  r3   s           r7   r  zClient._handle_redirects^  s     #%"&;;;%4N,t,))   H '5H#--h777 "&;;; r8   FTNFFr   r   FFr   FFr   r   NN)r9   r:   r;   r<   r1   rk   r  r   r  r  r"  r&  r)  r,  r  r  r=   r>   s   @r7   r'   r'   	  s        ( " $
        - - -d        > &! ! ! ! ! ! ! !L        > /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L        >        r8   r'   c                        e Zd ZdZ	 	 dddd fdZd Z	 	 	 dddd fdZdeddfddd fd	Z	 	 	 dddd fd
Z		 	 	 	 dddd fdZ
	 	 	 	 dddd fdZ	 	 	 	 dddd fdZ	 	 	 	 dddd fdZ	 	 	 dddd fdZ	 	 	 	 ddZ xZS )r%   z
    An async version of Client that creates ASGIRequests and calls through an
    async request path.

    Does not currently support "follow" on its methods.
    FTNr  c                     t                      j        d||d| t          |          | _        || _        d | _        d | _        d | _        d S r  )r0   r1   r   r  rR  rO  r  r   r  s         r7   r1   zAsyncClient.__init__  sZ     	P|PPxPPP)*=>>'>$
r8   c                   K    | j         di }i }t          t          |          }dt                    z  }t          j                            ||           dt                    z  }t          j        | j        |           	 | 	                    |           d{V }t          j        
                    |           t          j
        |           n:# t          j        
                    |           t          j
        |           w xY w|                     |           | |_        |_        |                    dg           |_        |                    d          |_        t          | j        |          |_        t'          |j        dd          t+          fd          |_        |j        r*t/          |j                  d	k    r|j        d
         |_        |j        r| j                            |j                   |S )a   
        Make a generic request. Compose the scope dictionary and pass to the
        handler, return the result of the handler. Assume defaults for the
        query environment, which can be overridden using the arguments to the
        request.
        r  r  r  Nr   r   r  c                  2    t           d                   S )Nr   r  r   r  s   r7   r  z%AsyncClient.request.<locals>.<lambda>  s    GGFOW=== r8   r   r   rW   )rC  r   r   r  r   r  r[   r   rP  r  rZ   rU  r>  rk   r  r   r   r  r   r  r   r"   r  rN   r   r   )	r4   rk   r   r   r  r  r  rl   r  s	    `      @r7   rk   zAsyncClient.request  s      ! ++7++ $%=tDD)BwKK7
!))*<:)VVV.G<%d&9VVVV	I!\\%00000000H%00j0III!,-HHHHH %00j0III!,-HHHHHX&&&"!XXk26688I.. 0(;;(/DAA"2=====#
 #
  	3H$4 5 5 : :'/2H 	2L 0111s   
C 7Dc                   K   || _         || _         t                      j        |f||||d| d{V }|r | j        |f|||d| d{V }|S )r  r  Nr  )r  r   r0   r  _ahandle_redirectsr  s
            r7   r  zAsyncClient.get  s       
$
%
 
 
 
 
 
 
 
 
 
  	4T4#W< SX       H r8   c          	         K   || _         || _         t                      j        |f|||||d| d{V }	|r | j        |	f||||d| d{V }	|	S )r  r  Nr  )r  r   r0   r  r  r  s             r7   r  zAsyncClient.post  s       
%
%%
 
 
 
 
 
 
 
 
 
  	4T4))         H r8   c                   K   || _         || _         t                      j        |f||||d| d{V }|r | j        |f|||d| d{V }|S )r  r  Nr  )r  r   r0   r  r  r  s
            r7   r  zAsyncClient.head  s       
%
%
 
 
 
 
 
 
 
 
 
  	4T4#W< SX       H r8   r   r   c          	         K   || _         || _         t                      j        |f|||||d| d{V }	|r | j        |	f||||d| d{V }	|	S )r  r  Nr  )r  r   r0   r"  r  r  s             r7   r"  zAsyncClient.options  s       
(
%%
 
 
 
 
 
 
 
 
 
  	4T4))         H r8   c          	         K   || _         || _         t                      j        |f|||||d| d{V }	|r | j        |	f||||d| d{V }	|	S )r  r  Nr  )r  r   r0   r&  r  r  s             r7   r&  zAsyncClient.put>  s       
$
%%
 
 
 
 
 
 
 
 
 
  	4T4))         H r8   c          	         K   || _         || _         t                      j        |f|||||d| d{V }	|r | j        |	f||||d| d{V }	|	S )r  r  Nr  )r  r   r0   r)  r  r  s             r7   r)  zAsyncClient.patcha  s       
&
%%
 
 
 
 
 
 
 
 
 
  	4T4))         H r8   c          	         K   || _         || _         t                      j        |f|||||d| d{V }	|r | j        |	f||||d| d{V }	|	S )r  r  Nr  )r  r   r0   r,  r  r  s             r7   r,  zAsyncClient.delete  s       
'
%%
 
 
 
 
 
 
 
 
 
  	4T4))         H r8   c                   K   || _         || _         t                      j        |f||||d| d{V }|r | j        |f|||d| d{V }|S )r  r  Nr  )r  r   r0   r  r  r  s
            r7   r  zAsyncClient.trace  s       
&
%
 
 
 
 
 
 
 
 
 
  	4T4#W< SX       H r8   c                    K   g |_         |j        t          v rJ|j         } | j        |f||||d| d{V }||_         |                     |           |j        t          v J|S )r  r  Nr  r  s           r7   r  zAsyncClient._ahandle_redirects  s       #%"&;;;%4N2T2))         H '5H#--h777 "&;;; r8   r  r  r  r  r  )r9   r:   r;   r<   r1   rk   r  r   r  r  r"  r&  r)  r,  r  r  r=   r>   s   @r7   r%   r%   z  s         " $
        , , ,b        > &! ! ! ! ! ! ! !L        > /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L /! ! ! ! ! ! ! !L        >        r8   r%   )Wr   r   r   rN  collections.abcr   r   	functoolsr   r   r   	importlibr   ior   r	   urllib.parser
   r   r   r   asgiref.syncr   django.confr   django.core.handlers.asgir   django.core.handlers.baser   django.core.handlers.wsgir   r   django.core.serializers.jsonr   django.core.signalsr   r   r   	django.dbr   django.httpr   r   r   r   django.testr   django.test.utilsr   django.urlsr    django.utils.encodingr!   django.utils.functionalr"   django.utils.httpr#   django.utils.regex_helperr$   __all__r   r   r   r   	frozensetMOVED_PERMANENTLYFOUND	SEE_OTHERr  r  r  	Exceptionr(   r@   r^   ra   rm   ro   r   r   r+   r*   r)   r&   rL  r'   r%   rW   r8   r7   <module>r     s        				 



 $ $ $ $ $ $                   # # # # # #         F F F F F F F F F F F F & & & & & &             1 1 1 1 1 1 1 1 1 1 1 1 @ @ @ @ @ @ @ @ : : : : : : X X X X X X X X X X + + + + + + I I I I I I I I I I I I       ) ) ) ) ) )       - - - - - - 4 4 4 4 4 4 ' ' ' ' ' ' 6 6 6 6 6 6 6A ""#<==''(DEE !	$%%  ; ; ; ; ; ; ; ;1# 1# 1# 1# 1#& 1# 1# 1#h8 8 88 8 8  &4 4 4 4 4K 4 4 4n1 1 1 1 1 1 1 1h
+ 
+ 
+; ; ;|  <r! r! r! r! r! r! r! r!j	g! g! g! g! g!. g! g! g!TuT uT uT uT uT uT uT uTpn n n n n[. n n nbb b b b b+2 b b b b br8   