
    iT,                     D    S SK r S SKJr  S SKJr  S SKJr   " S S5      rg)    N)packet)PubSubManager)EnvironBuilderc                   f    \ rS rSrSr0 r  SS jrSS jr  SS jrSS jr	S r
SS	 jrSS
 jrSrg)SocketIOTestClient   a  
This class is useful for testing a Flask-SocketIO server. It works in a
similar way to the Flask Test Client, but adapted to the Socket.IO server.

:param app: The Flask application instance.
:param socketio: The application's ``SocketIO`` instance.
:param namespace: The namespace for the client. If not provided, the client
                  connects to the server on the global namespace.
:param query_string: A string with custom query string arguments.
:param headers: A dictionary with custom HTTP headers.
:param auth: Optional authentication data, given as a dictionary.
:param flask_test_client: The instance of the Flask test client
                          currently in use. Passing the Flask test
                          client is optional, but is necessary if you
                          want the Flask user session and any other
                          cookies set in HTTP routes accessible from
                          Socket.IO events.
Nc                   ^ ^	^
 U 4S jm
S m	U	U
4S jnUT l         UT l        [        R                  " 5       R                  T l        T T R                  T R
                  '   ST l        UT l        0 T l	        / T l
        S T l        T
UR                  l        XR                  l        0 UR                  R                  T R
                  '   SUR                  l        SUR                  R"                  l        [%        UR                  R&                  [(        5      (       a  [+        S5      eUR                  R&                  R-                  5         T R/                  X4XVS9  g )Nc                   > UR                  5       n[        U[        5      (       d  [        R                  " US9nO4[        R                  " US   S9nUSS   H  nUR                  U5        M     TR                  R                  U 5      nU(       d  g UR                  [        R                  :X  d  UR                  [        R                  :X  a  UR                  S   S:X  d  UR                  S   S:X  aM  UR                  R                  UR                  S   UR                  S   UR                  =(       d    SS.5        g UR                  R                  UR                  S   UR                  SS  UR                  =(       d    SS.5        g UR                  [        R                  :X  d  UR                  [        R                   :X  a(  UR                  UR                  =(       d    SS.Ul        g UR                  [        R$                  [        R&                  4;   a#  S	UR(                  UR                  =(       d    S'   g g )
Nencoded_packetr      messagejson/)nameargs	namespace)r   r   F)encode
isinstancelistr   Packetadd_attachmentclientsgetpacket_typeEVENTBINARY_EVENTdataqueueappendr   ACK
BINARY_ACKacks
DISCONNECTCONNECT_ERROR	connected)eio_sidpktepktattclientselfs        W/home/admin/cozy_coffee/venv/lib/python3.13/site-packages/flask_socketio/test_client.py_mock_send_packet6SocketIOTestClient.__init__.<locals>._mock_send_packet   s   ::<DdD))mm48mm47;8C&&s+ $\\%%g.F&,,.OOv':'::88A;)+sxx{f/DLL'' # #%(]]%9c); <
 LL'' # #%(]]%9c); < FJJ.OOv'8'88'*xx,/MM,@SBV%6%68L8L$MM9>  !5#6 N    c                   > TbK  TR                  UR                  5        TR                  [        TR                  5      :X  a  T" U T5        S mg g [
        R                  " UR                  S9nUR                  S:X  a	  T" X5        g Umg )Nr   r   )r   r   attachment_countlenattachmentsr   r   )r'   eio_pktr(   _current_packetr.   s      r-   _mock_send_eio_packet:SocketIOTestClient.__init__.<locals>._mock_send_eio_packet@   sz    *..w||<"33O7789%g?&*O9
 mm7<<@''1,%g3&)Or0   r   Fz^Test client cannot be used with a message queue. Disable the queue on your test configuration.)r   query_stringheadersauth)appflask_test_clientuuiduuid4hexr'   r   callback_countersocketior&   r   r#   server_send_packet_send_eio_packetenvironasync_handlerseior   managerr   RuntimeError
initializeconnect)r,   r<   rB   r   r9   r:   r;   r=   r7   r6   r.   s   `        @@r-   __init__SocketIOTestClient.__init__   s   	?> 	* !2zz|''%)T\\" ! 
	'8$+@(02-).&-2*hoo--}==  0 1 1 	**,y$ 	 	1r0   c                 L    U R                   R                  U=(       d    SS5      $ )zCheck if a namespace is connected.

:param namespace: The namespace to check. The global namespace is
                 assumed if this argument is not provided.
r   F)r&   r   )r,   r   s     r-   is_connectedSocketIOTestClient.is_connectede   s      ~~!!)"2sE::r0   c                    SnU=(       d    SnU(       a  US   S:w  a  SU-   nXR-  nU R                   (       a)  U R                   R                  SXSS.S9nUR                  nO"[        U R                  XSS9R                  5       nU R                  US'   U R                   (       a\  [        U R                   S	5      (       a  U R                   R                  U5        O%U R                   R                  R                  U5        U R                  R                  R                  U R                  U5        [        R                  " [        R                   XAS
9nU R                  R                  R#                  U R                  UR%                  5       5        U R                  R                  R&                  R)                  U R                  U5      n	U	(       a  SU R*                  U'   gg)a  Connect the client.

:param namespace: The namespace for the client. If not provided, the
                  client connects to the server on the global
                  namespace.
:param query_string: A string with custom query string arguments.
:param headers: A dictionary with custom HTTP headers.
:param auth: Optional authentication data, given as a dictionary.

Note that it is usually not necessary to explicitly call this method,
since a connection is automatically established when an instance of
this class is created. An example where it this method would be useful
is when the application accepts multiple namespace connections.
z
/socket.ior   r   ? )pathr:   )r   kwargsz	flask.app_add_cookies_to_wsgir   TN)r=   _request_from_builder_argsrF   r   r<   get_environhasattrrW   
cookie_jarinject_wsgirB   rC   _handle_eio_connectr'   r   r   CONNECT_handle_eio_messager   rI   sid_from_eio_sidr&   )
r,   r   r9   r:   r;   urlreqrF   r(   sids
             r-   rL   SocketIOTestClient.connectm   sy     $	A#%"\1C!!((CC A D CCkkG$s55@[] #xx!!t--/EFF&&;;GD &&11==gF00wGmmFNNDF00szz|Lmm""**;;DLL<EG(,DNN9% r0   c                 4   U R                  U5      (       d  [        S5      e[        R                  " [        R                  US9nU R
                  R                  R                  U R                  UR                  5       5        U R                  U=(       d    S	 g)zDisconnect the client.

:param namespace: The namespace to disconnect. The global namespace is
                 assumed if this argument is not provided.
not connectedrX   r   N)rP   rJ   r   r   r$   rB   rC   r`   r'   r   r&   )r,   r   r(   s      r-   
disconnectSocketIOTestClient.disconnect   sk       ++//mmF--C00szz|LNN9+,r0   c                    UR                  SS5      nU R                  U5      (       d  [        S5      eUR                  SS5      nSnU(       a!  U =R                  S-  sl        U R                  n[        R
                  " [        R                  U/[        U5      -   XFS9nUR                  5       n[        U[        5      (       a:  U H3  n	U R                  R                  R                  U R                  U	5        M5     O0U R                  R                  R                  U R                  U5        U R                  b2  U R                  n
SU l        [        U
S   5      S:X  a  U
S   S	   $ U
S   $ g)
a  Emit an event to the server.

:param event: The event name.
:param *args: The event arguments.
:param callback: ``True`` if the client requests a callback, ``False``
                 if not. Note that client-side callbacks are not
                 implemented, a callback request will just tell the
                 server to provide the arguments to invoke the
                 callback, but no callback is invoked. Instead, the
                 arguments that the server provided for the callback
                 are returned by this function.
:param namespace: The namespace of the event. The global namespace is
                  assumed if this argument is not provided.
r   Nrg   callbackFr   )r   r   idr   r   )poprP   rJ   rA   r   r   r   r   r   r   rB   rC   r`   r'   r#   r3   )r,   eventr   rV   r   rk   rl   r(   encoded_pktr)   acks              r-   emitSocketIOTestClient.emit   s3    JJ{D1	  ++//::j%0!!Q&!&&BmmFLLwd/C&/8jjlk4((#$$88tL $ MM  44T\\;O99 ))CDI%(V%5%:3v;q> ![! !r0   c                 :    U(       a  SnOSnU R                  XQX4S9$ )a  Send a text or JSON message to the server.

:param data: A string, dictionary or list to send to the server.
:param json: ``True`` to send a JSON message, ``False`` to send a text
             message.
:param callback: ``True`` if the client requests a callback, ``False``
                 if not. Note that client-side callbacks are not
                 implemented, a callback request will just tell the
                 server to provide the arguments to invoke the
                 callback, but no callback is invoked. Instead, the
                 arguments that the server provided for the callback
                 are returned by this function.
:param namespace: The namespace of the event. The global namespace is
                  assumed if this argument is not provided.
r   r   )rk   r   )rq   )r,   r   r   rk   r   msgs         r-   sendSocketIOTestClient.send   s$      CCyyXyKKr0   c                    U R                  U5      (       d  [        S5      eU=(       d    SnU R                   Vs/ s H  o"S   U:X  d  M  UPM     nnU R                   Vs/ s H  o"U;  d  M
  UPM     snU l        U$ s  snf s  snf )a  Return the list of messages received from the server.

Since this is not a real client, any time the server emits an event,
the event is simply stored. The test code can invoke this method to
obtain the list of events that were received since the last call.

:param namespace: The namespace to get events from. The global
                  namespace is assumed if this argument is not
                  provided.
rg   r   r   )rP   rJ   r   )r,   r   r(   rs       r-   get_receivedSocketIOTestClient.get_received   sx       ++//$	 JJHJSk*:i*GSJH%)ZZ@Zca<cZ@
 I@s   A>A>!	B.B)r#   r<   rA   r&   r'   r=   r   rB   )NNNNN)N)NNNN)FFN)__name__
__module____qualname____firstlineno____doc__r   rM   rP   rL   rh   rq   ru   ry   __static_attributes__rT   r0   r-   r   r      sF    $ GCG<@F1P; BF.-`
-#!JL,r0   r   )r>   rB   r   socketio.pubsub_managerr   flask.testingr   r   rT   r0   r-   <module>r      s      1 (l lr0   