
    Mfx                     \   d Z ddlZddlmZ ddlZddlmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZmZ dd	lmZmZ d
 Zej        j        d             Zd Zd Zd Zd Zej        j        d             Zej        j        d             Zej        j        d             Z ej        j        d             Z!ej        j        d             Z"ej        j        d             Z#ej        j        d             Z$d Z%d Z&d Z'ej        j        d             Z(ej        j        d             Z)d Z*dS )a  
Tests of django_plotly_dash.

These tests can be directly used or imported into eg the tests of the demo app.

The use of pytest is assumed.

Copyright (c) 2018 Gibbs Consulting and others - see CONTRIBUTIONS.md

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

    N)patch)InputStateOutputreverse)
DjangoDash)get_local_stateless_listget_local_stateless_by_name)DashAppfind_stateless_by_name)fill_in_test_appdash_contract_datac                  x    ddl m}   | d          }|sJ |j        sJ t          |          |j        k    sJ dS )z:Test the import and formation of the dash app orm wrappersr   StatelessApp	Some nameapp_nameN)django_plotly_dash.modelsr   r   str)r   stateless_as     W/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/django_plotly_dash/tests.pytest_dash_appr   ,   se     766666,444K{{3333333    c                 	   ddl m} t          d          }t          |d            |d          }|                                 t          |dd	d
          }|                                 dt                      v sJ t          d          |k    sJ t          d          |k    sJ |	                                i k    sJ i ddddddddddddddddddddddddddd dd!d"d#d$d%d&d'd(dd)d*d+dd,d-d.dd/d0d1dd2d3d4dd5d6d7dd8d9d:dd;d<d=dd>d?d@ddAdBddCdDddEdFddGdHddI}|
                                 |	                                |k    sJ |                    ddJ          sJ |                    dKdLdMdN          sJ |                    d2dN          sJ |                    dOdP          rJ |                    dQdRdS           |	                                |k    sJ |                    dTdJdU           dUdHd|dT<   |	                                |k    sJ t
          j                            dV          	                                i k    sJ |                                 t
          j                            dV          	                                |k    sJ |                                }|                                }|                    |i           \  }}	dW|v sJ |                    |dTdJdXii          \  }}	dW|vsJ dY|v sJ t'          dZd[d	i\          }
t)          j        t-          j        d]                    D ]}|d^         }|                     |
t)          j        |          d_`          }|j        dXk    sJ t)          j        |j                  }|da         }t;          |t<                    r|d         }|db                                         d                                         d         }||k    sJ |                                 i dddcdddddddd'dedddddddddddddddd dd!dfd#d$d%d&d'd(dd)d*d+dd,d-d.dd/d0d1dd2d<dgdd5d?d7dd8dAd:dd;dCdhdd>dEd@ddGdBdd*diddEdFdd0dHddI}t
          j                            dV          	                                |k    sJ djS )kzbTest the state management of a DashApp as well as the contract between the client and the Dash appr   r   DDashnameF)writer   r   zmy-appT)stateless_appinstance_nameslugsave_on_changeinp1l   L)n_clicksn_clicks_timestampinp1b   l   Ninp2   l   Nzout1-0   l   Lzout1-1   l   Lzout1-2   l   JMzout1-3   l   Mout1bzhttp://www.example.com/null   l   vN)hrefr&   r'   zout2-0   l   >Oout3   l   Pout4   l   ^Rout5   l   Sz{"_id":"inp-0","_type":"btn3"}	   l   Oz{"_id":"inp-0","_type":"btn4"}   l   2Qz{"_id":"inp-0","_type":"btn5"}   l   Rz{"_id":"inp-1","_type":"btn3"}
   l   Pz{"_id":"inp-1","_type":"btn4"}   l   Q   l   &S   l   jP   l   Q   l   S)z{"_id":"inp-1","_type":"btn5"}z{"_id":"inp-2","_type":"btn3"}z{"_id":"inp-2","_type":"btn4"}{"_id":"inp-2","_type":"btn5"}r&   btn3zinp-0)_type_idr'   	checklistz
other-propfoovaluerandomrC   d   )r"   z"n_clicks": 100   z"n_clicks": 200z'the_django_plotly_dash:update-componentidentkwargsrbodyapplication/jsoncontent_typeresultresponsel   XhHl    Il   Iz$http://www.example.com/1615103033482l   6Il   Il   IN) r   r   r	   r   saver   r
   r   r   current_statepopulate_valueshave_current_state_entryupdate_current_stateobjectsgethandle_current_stateas_dash_instanceserve_layoutaugment_initial_layoutr   jsonloadr   openpostdumpsstatus_codeloadscontent
isinstancelistpopitem)clientr   ddashr   
stateful_aexpected_statedash_instanceresplayoutmimetypeurlscenariorQ   rV   rU   ri   final_states                    r   &test_dash_stateful_app_client_contractrx   7   si    766666 G$$$EU%((((,000K{'2&t= = =J OO .000000&w//58888!'**e3333 ##%%++++_f1MRR _A]SS_1MRR_ Qm T T_ Qm T T	_
 Qm T T_ Qm T T_ (E,-6C E  E_ Qm T T_ 2]SS_ 2]SS_ 2]SS_ 7QO\9^ 9^_  7RO\9^ 9^!_$ 7RO\9^ 9^%_( 7RO\9^ 9^)_, 7RO\9^ 9^-_0 FHO\9^ 9^EGO\9^ 9^EGO\9^ 9^EGO\9^ 9^=_ _ _NF    ##%%7777..vzBBBBB../P/PRfggggg../OQefffff22;MMMMM ##E7H===##%%7777 ##$DjRUVVVDG_l7m7mN34##%%7777?[99GGIIROOOO##%%%?[99GGII^[[[[ //11M%%''D %;;D"EEFH&&&& %;;D(:s*;C= > >FHF****&&&& ;WhDW
X
X
XC I05c::;; * *;;sDJt$4$4CU;VV#s****:h.// (#fd## 	AYF:&..003;;==a@&     	''))))\6OO \-PP\OO\ !=QQ\ !=QQ	\
 !=QQ\ !=QQ\ %K)*3@B B\ !=QQ\ -PP\ -PP\ -PP\ 4"LY6[ 6[\  4"LY6[ 6[!\$ 4"LY6[ 6[%\( 4"LY6[ 6[)\, 4"LY6[ 6[-\0 CELY6[ 6[BDLY6[ 6[BDLY6[ 6[BDLY6[ 6[=\ \ \KB ?[99GGII[XXXXXXr   c                     t          d          } |                     t          dd          t          dd          t          dd          t          dd          t          dd          t	          dd                    d	             }|                     t          dd          t          dd          gt          dd          t          dd          t          dd          gt	          dd          g          d
             }| j        t          dd          t          dd          t          dd          gt          dd          t          dd          gdt	          dd          gd|ft          dd          t          dd          t          dd          gt          dd          t          dd          gdt	          dd          gd|fgk    sJ dS )zXTest the flexibility of the callback arguments order (handling of inputs/outputs/states)DashCallbackArgumentsr   onerH   twobazthreebilc                      d S N r   r   r   newz)test_dash_callback_arguments.<locals>.new   	     	r   c                      d S r   r   r   r   r   oldz)test_dash_callback_arguments.<locals>.old   r   r   N)inputsoutputprevent_initial_callstate)r	   callbackr   r   r   _callback_sets)rn   r   r   s      r   test_dash_callback_argumentsr      s4    3444E ^^ueueeUeUgueU    ^^	u			u				ue			ue			w			  
ue		    ue1D1D16ue1D1D16w1F1F1J 28u1E1E17u1E1E1G>B05eU0C0C/F&H &H &)%* 27ue1D1D16ue1D1D16w1F1F1J 28u1E1E17u1E1E1G>B05eU0C0C/F&H &H &)%*$& & & & & & &r   c                 $   d| _         ddlm}m}m}m}  |            dk    sJ  |            dk    sJ  |d          dk    sJ  |            rJ | `  |            dk    sJ  |            dk    sJ  |d          dk    sJ  |            rJ dS )z!Test handling of missing settingsNr   )pipe_ws_endpoint_namedpd_http_endpoint_roothttp_endpointinsert_demo_migrationszdpd/ws/channelz	dpd/viewsfredz^dpd/views/fred/$)PLOTLY_DASHdjango_plotly_dash.utilr   r   r   r   )settingsr   r   r   r   s        r   test_util_error_casesr     s     H||||||||||||  ""&66666!!##{2222=  $77777%%'''''  ""&66666!!##{2222=  $77777%%'''''''r   c                  N    ddl m} m}  |             dk    sJ  |            sJ dS )z'Test configuration options for the demor   r   r   z
ws/channelN)r   r   r   r   s     r   test_demo_routingr     sR     VUUUUUUU  ""l2222!!#######r   c                     ddl m}m}m}  |            | j        k    sJ  |            dk    sJ  |dd          dk    sJ dS )zTest local serve settingsr   )serve_locallystatic_asset_rootfull_asset_pathz
dpd/assetszfred.jimharryzdpd/assets/fred/jim/harryN)r   r   r   r   DEBUG)r   r   r   r   s       r   test_local_servingr   #  sz     ZYYYYYYYYY=??hn,,,,,....?:w//3NNNNNNNr   c                 j   ddl m} ddlm} dd|fD ]Q}ddd	ifd
ddiffD ]B\  }} |d|||          }|                     |          }|j        sJ |j        dk    sJ CRdD ]L}ddd	ifd
ddiffD ]=\  }} |d|||          }d}	 |                     |          }n	#  d}Y nxY w|sJ >MdS )@Check direct use of a stateless application using demo test datar   r   r,   main_view_labelrs   dependenciesapp-rM   SimpleExample simpleexample-1the_django_plotly_dash:rN   rL   routesFTNdjango.urlsr   r   r   r]   ri   rg   	rm   r   r   
route_nameprefixarg_mapru   rV   did_fails	            r   test_direct_accessr   ,  sr    $#####))))))A / /
!''/)B C!#g.?%@ A D 	/ 	/OFG''66::NW^___Czz#H####'3.....	/ "  
!''/)B C!#g.?%@ A D 
	 
	OFG''66::NW^___CH !::c?? OOOO
	 s   B$$B*c                     ddl m} d}dddifdddiffD ]h\  }} |d	|||
          }|                     |t          j        dddddddddgd          d          }|j        dk    sJ |j        dk    sJ idS )-Check updating of an app using demo test datar   r   update-componentr   rM   r   r   r   r   rN   zoutput-size.childrendropdown-colorrI   blueidpropertyrI   zdropdown-sizemediumr   r   rR   rS   sa   {"response":{"output-size":{"children":"The chosen T-shirt is a medium blue one."}},"multi":true}rL   N)r   r   re   rb   rf   ri   rg   )rm   r   r   r   r   ru   rV   s          r   test_updatingr   K  s$    $######J#go%>?'*;!<=@ + +ggvvzzJSZ[[[;;sDJ:P@PFMCI;K ;K APFMCK;M ;M:;0< 0< %= %= L^  _ _   $H  H  H  H  H#s*****+ +r   c                 V   ddl m} ddlm} dd|fD ]L}ddd	iffD ]B\  }} |d
|||          }|                     |          }|j        sJ |j        dk    sJ CMdD ]G}ddd	iffD ]=\  }} |d
|||          }d}	 |                     |          }n	#  d}Y nxY w|sJ >HdS )r   r   r   r,   r   rs   r   r   rM   dash_example_1r   rN   rL   r   FTNr   r   s	            r   test_injection_app_accessr   d  sV    $#####))))))A 	/ 	/
!''2B)C D  ! 	/ 	/OFG ''66::NW^___Czz#H####'3.....	/ " 
 

!''2B)C DF 		 		OFG''66::NW^___CH !::c?? OOOO		
 
s   BB c                    ddl m} d}dddiffD ]\  }} |d|||          }|                     |t          j        d	d
dddddddgd          d          }|j        dk    sJ t          j        |j                            d                    }d|v sJ |d         }d|v sJ d|d         v sJ |d         d         dk    sJ dS )zDCheck updating of an app using demo test data for multiple callbacksr   r   r   r   rM   multiple_callbacksr   rN   zE..output-one.children...output-two.children...output-three.children..buttonr&   10r   r   rI   z.purple-ish yellow with a hint of greeny oranger   rR   rS   rL   utf-8rV   
output-twochildrenz>Output 2: 10 purple-ish yellow with a hint of greeny orange []N	r   r   re   rb   rf   rg   rh   ri   decode)	rm   r   r   r   r   ru   rV   rr   resp_details	            r   *test_injection_updating_multiple_callbacksr     ss    $######J#g.B%CDF y yggvvzzJSZ[[[ ;;sDJ  :A"  #EG G	:;0< 0< %= %= L^  _ _ #s****z(*11'::;;T!!!!:&{****[66666<(48xxxxxx-y yr   c                 \   ddl m} d}dddiffD ]\  }} |d|||          }|                     |t          j        d	d
dddgd          d          }|j        dk    sJ t          j        |j                            d                    }dD ]}||d         d         d         v sJ |                     |t          j        dd
dddgd          d          }|j        dk    sJ t          j        |j                            d                    }|d         dddiik    sJ |                     |t          j        dd
dddgd          d          }|j        dk    sJ t          j        |j                            d                    }|d         dddiik    sJ dS )zMCheck updating of an app using demo test data for flexible expanded callbacksr   r   r   r   rM   flexible_expanded_callbacksr   rN   zoutput-one.childrenr   r&   r   r   r   rR   rS   rL   r   )dash_app_iddash_appcallback_contextrV   z
output-oner   zoutput-two.childrenr   okzoutput-three.childrenzoutput-threeNr   )	rm   r   r   r   r   ru   rV   rr   keys	            r    test_flexible_expanded_callbacksr     s    $######J#g.K%LMO *_ *_ggvvzzJSZ[[[ ;;sDJ9N" :;0< 0< %= %=
 L^  _ _ #s****z(*11'::;;B 	E 	EC$z*<8DDDDDD ;;sDJ9N" :;0< 0< %= %=
 L^  _ _ #s****z(*11'::;;J,T0B!CCCCC ;;sDJ9P" :;0< 0< %= %=
 L^  _ _ #s****z(*11'::;;J.:?\2]!^^^^^^U*_ *_r   c                 "   ddl m} d}dddiffD ]\  }} |d|||          }|                     |t          j        d	d
dddgd          d          }d}|j                            |          sJ |j        dk    sJ |                     |t          j        d	d
dddgd          d          }d}|j                            |          sJ |j        dk    sJ t          j	        t          d          5  |                     |t          j        dd
dddgd          d           ddd           n# 1 swxY w Y   t          j	        t          d          5  |                     |t          j        dd
dddgd          d           ddd           n# 1 swxY w Y   |                     |t          j        dd
dddgd          d          }d}|j                            |          sJ |j        dk    sJ t          j	        t          d          5  |                     |t          j        dddddgd          d           ddd           n# 1 swxY w Y   | j        }ddi|d<   |                                 |                     |t          j        dddddgd          d          }d}|j                            |          sJ |j        dk    sJ |j                            d          dk    sJ dS ) r   r   r   r   r   rM   r   r   rN   ztest-output-div.childrenzmy-dropdown1rI   TestItr   r   rR   rS   sM   {"response":{"test-output-div":{"children":[{"props":{"id":"line-area-graph2"rL   z..test-output-div.children..)matchNztest-output-div3.childrenz..test-output-div3.children..sN   {"response":{"test-output-div3":{"children":[{"props":{"id":"line-area-graph2"django_to_dash_contextztest-output-div2.childrenzmy-dropdown2zTest 789 contentdjango_plotly_dashsM   {"response":{"test-output-div2":{"children":[{"props":{"children":["You have s   Test 789 content)r   r   re   rb   rf   ri   
startswithrg   pytestraisesKeyErrorsessionrW   find)	rm   r   r   r   r   ru   rV   rStartr   s	            r   test_injection_updatingr     s    $######J#g.>%?@B M> M>ggvvzzJSZ[[[;;sDJ:T@NFMCK;M ;M :;0< 0< %= %=
 L^  _ _ b**622222#s**** ;;sDJ9S@NFMCK;M ;M :;0< 0< %= %= L^	  _ _ b**622222#s**** ]8+IJJJ 	_ 	_KKTZ2P@NFMCK;M ;M :;)< )< = = L^	  _ _ _	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ ]8+FGGG 	_ 	_KKTZ2M@NFMCK;M ;M :;)< )< = = L^	  _ _ _	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ 	_ ;;sDJ9X@NFMCK;M ;M :;0< 0< %= %= L^	  _ _ c**622222#s****]8+CDDD 	X 	XKKTZ3N9G?F<D4F 4F 34)5 )5 6 6 EW	  X X X	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X .)ACU(V$%;;sDJ:UAOGNDL<N <N ;<0= 0= %> %> M_	  ` `
 b**622222#s****$$%899A=====[M> M>s6   =3D<<E 	E 	"3F!!F%	(F%	$3I##I'	*I'	c                    ddl m}m}m}  |            sJ ddi| _         |            sJ ddi} |d|          }t          |          dk    sJ  |d|          }||k    sJ dd	i| _         |            rJ  |||          }t          |          dk    sJ ||k    sJ  |dd          J  |dd          J  ||d          J  ||d          J dS )
z[Test the setting that controls how initial arguments are propagated through to the dash appr   )initial_argument_locationstore_initial_argumentsget_initial_argumentscache_argumentsTtestfirstNr=   F)r   r   r   r   r   len)	r   rm   r   r   r   
test_valuecache_idfetched	cache_id2s	            r   test_argument_settingsr   2  sx    rqqqqqqqqq$$&&&&&-t4H$$&&&&&!J&&tZ88Hx==2##D(33Gj    -u5H((*****''
;;Iy>>By     #"4..666  t,,444""6400888  ..66666r   c                      ddl m}   |             }|J t          j        t                    5   |d           ddd           dS # 1 swxY w Y   dS )zTest no-op stateless lookupr   )stateless_app_lookup_hookNz
not an app)r   r   r   r   ImportError)r   lh_hooks     r   test_stateless_lookup_noopr   \  s     BAAAAA''))G	{	#	#                   s   AAAc                     ddl m} m}  |             }|                    d           |                    d           |                    d           |j        dk    sJ  |            }|                    d          dk    sJ dS )	z.Import and vaguely exercise middleware objectsr   )EmbeddedHolderContentCollectorsome_csssome_configsome_scriptsr   s   fredN)django_plotly_dash.middlewarer   r   add_css
add_configadd_scriptsconfig_encode)r   r   ehccs       r   test_middleware_artifactsr  g  s     ONNNNNNN			BJJzMM-   NN>"""9%%%%				B::f((((((r   c                  n    ddl m} m}m}  |             } |            } |            }|J |J |J dS )z/Import and vaguely exercise staticfiles findersr   )DashComponentFinderDashAppDirectoryFinderDashAssetFinderN)django_plotly_dash.findersr  r  r  )r  r  r  dcfdadfdafs         r   test_findersr  x  sn     hggggggggg



C!!##D
/

C????????r   c                     ddl m} ddlm}  |             	  |d          }|                     |          }|j        dk    sJ d S )Nr   )check_stateless_loadedr   Tz)the_django_plotly_dash:add_stateless_appsi.  )r   r  r   r   re   rg   )rm   r  r   ru   rV   s        r   test_app_loadingr    sz     A@@@@@###### 
'=
>
>C{{3H 3&&&&&&r   c                 H   ddl m} |                                }t          j        |d          5 }|                                 ddd           n# 1 swxY w Y   |j        \  }}d|d         v sJ d|d         v sJ d|d	         v sJ d
|d	         v sJ d|d	         v sJ dS )z@Check external_stylesheets and external_scripts ends up in indexr   )external_scripts_stylesheetsinterpolate_indexNz*https://codepen.io/chriddyp/pen/bWLwgP.csscsszHhttps://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.cssz-https://www.google-analytics.com/analytics.jsscriptsz*https://cdn.polyfill.io/v2/polyfill.min.jszGhttps://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.js)demo.plotly_appsr  r_   r   objectindex	call_args)rm   r  dashmock_rO   s         r   !test_external_scripts_stylesheetsr    s    >====='88::D	d/	0	0 D

               IAv76%=HHHHUY_`eYfffff:fY>OOOOO76);LLLLLTX^_hXiiiiiiis   AAAc                  >   t          dd          t          dd          g} t          dd          t          dd          g}d }t          j        || |          g k    sJ d }t          j        || |          dgk    sJ d	 }t          j        || |          g k    sJ d
 }t          j        || |          dgk    sJ d }t          j        || |          dgk    sJ d }t          j        || |          d k    sJ d }t          j        || |          d k    sJ d S )Nr{   rI   r|   r~   fourc                     d S r   r   )r{   r|   r~   r  s       r   callback_standardz2test_callback_decorator.<locals>.callback_standard      r   c                     d S r   r   )r{   r|   r~   r  extra_1s        r   r!  z2test_callback_decorator.<locals>.callback_standard  r"  r   r$  c                     d S r   r   )r{   argss     r   callback_argsz.test_callback_decorator.<locals>.callback_args  r"  r   c                    d S r   r   )r{   r$  r&  s      r   callback_args_extraz4test_callback_decorator.<locals>.callback_args_extra  r"  r   c                    d S r   r   )r{   r$  s     r   callback_args_extra_starz9test_callback_decorator.<locals>.callback_args_extra_star  r"  r   c                     d S r   r   r{   r|   r~   r  r$  rO   s         r   callback_kwargsz0test_callback_decorator.<locals>.callback_kwargs  r"  r   c                    d S r   r   r-  s         r   r.  z0test_callback_decorator.<locals>.callback_kwargs  r"  r   )r   r	   get_expanded_arguments)r   statesr!  r'  r)  r+  r.  s          r   test_callback_decoratorr2    s   E7##E7##F GW%%FG$$F   ,->OOSUUUUU   ,->OOT]S^^^^^   ,]FFKKrQQQQ   ,-@&&QQV_Uaaaaa   ,-EvvVV[dZfffff   ,_ffMMQUUUUU   ,_ffMMQUUUUUUUr   )+__doc__rb   unittest.mockr   r   dash.dependenciesr   r   r   r   r   r   r	   django_plotly_dash.dash_wrapperr
   r   r   r   r   &django_plotly_dash.tests_dash_contractr   r   r   mark	django_dbrx   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r2  r   r   r   <module>r:     s   :         2 2 2 2 2 2 2 2 2 2       ) ) ) ) ) ) a a a a a a a a E E E E E E E E W W W W W W W W4 4 4 ZY ZY ZY|.& .& .&b( ( (($ $ $O O O   < + + +0   > y y y@ 1_ 1_ 1_h T> T> T>n &7 &7 &7R  ) ) )"   ' ' '" j j j *V *V *V *V *Vr   