ó
    ñ:Éj0+  ã                   óò   • S r SSKrSSKJs  Jr  SSKrSSKrSSK	r	SSK
Jr  SSKJrJr  SSKJrJrJr  S rS rS rSS	 jrS
 rS rS rS rS rS rS rS rS rS r S r!S r"S r#S r$S r%S r&S r'S r(g)u–   Briques transverses : rate limit persistant, IP derriÃ¨re un proxy, config de production,
Ã©lection du leader, alertes, organizer (codes QR), e-mails.é    N)ÚHTTPException)ÚconfigÚsecurity)ÚenforceÚ
is_blockedÚ
record_hitc                  óÆ  • [        S5       H  n [        SSSS9  M     [        R                  " [        5       n[        SSSS9  S S S 5        WR
                  o"R                  nSoCU:H  oU(       dÏ  [        R                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=n=pT[        SSSS9  g ! , (       d  f       GN= f)Né   Úk1é<   ©Úmax_attemptsÚwindow_secondsi­  ©ú==)zN%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.value
}.status_code
} == %(py7)sÚe©Úpy0Úpy2Úpy4Úpy7úassert %(py9)sÚpy9Úk2)Úranger   ÚpytestÚraisesr   ÚvalueÚstatus_codeÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanation)Ú_r   Ú@py_assert1Ú@py_assert3Ú@py_assert6Ú@py_assert5Ú@py_format8Ú@py_format10s           ÚRD:\Ingenieria\TRABAJOS ONLINE\Projects\11- Photo School\backend\tests\test_core.pyÚCtest_rate_limit_blocks_after_max_and_is_shared_through_the_databaser0      sÕ   € Ü�1ŽXˆÜ� 1°RÔ8ñ ä	�Š”}Ô	%¨Ü� 1°RÒ8÷ 
&à�7‰7Ð%×ÑÐ% #Ð% #Ñ%×%×%×%Ò%Ð×%×%×%×%×%Õ%ˆ1×%×%×%Ñ%ˆ1×%×%Õ%ˆ7×%×%Ó%Ð×%×%Ó% #×%×%×%×%×%×%Õ%äˆD˜q°Ó4÷	 
&Ö	%ús   ¸EÅ
E c                  ó¦  • [        S5       H  n [        SSSS9  M     SSKJn  U" 5        nUR	                  S5      R                  5       S   nSoCU:H  oU(       do  [        R                  " S	U4S
X445      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pTS S S 5        SnSnSn	[        X„U	5      oª(       dÌ  SS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U	5      [        R                  " U
5      S.-  n[        [        R                  " U5      5      eS =n=n=pšg ! , (       d  f       Nú= f)Né   Úpersistr   r   r   ©Úget_dbz7SELECT COUNT(*) AS n FROM rate_hits WHERE key='persist'Únr   ©z%(py1)s == %(py4)s©Úpy1r   úassert %(py6)sÚpy6z>assert %(py8)s
{%(py8)s = %(py0)s(%(py2)s, %(py4)s, %(py6)s)
}r   ©r   r   r   r;   Úpy8)r   r   Úcore.dbr5   ÚexecuteÚfetchoner    r!   r%   r&   r'   r   r"   r#   r$   )r(   r5   ÚconnÚ@py_assert0r*   Ú@py_assert2Ú@py_format5Ú@py_format7r)   r,   Ú@py_assert7Ú@py_format9s               r/   Ú>test_rate_limit_state_survives_a_new_connection_like_a_restartrH      s  € Ü�1ŽXˆÜ�	¨¸"Ô=ñ õ Ù	Œ�TØ�|‰|ÐUÓV×_Ñ_ÓaÐbeÑfÐkÐjkÐkÐjkÑk×k×k×kÒkÐf×k×kÔkÐf×k×kÓkÐjk×k×k×k×k×k×kÓk÷ 
àÐ' Ð' BÐ'Œ:�i BÓ'Ð'Õ'×'×'×'×'×'Ñ'Œ:×'×'×'Ñ'Œ:×'×'Õ'�i×'×'Ó' ×'×'Ó' B×'×'Ó'Ð'×'×'×'×'×'×'÷ 
�ús   «B#GÇ
Gc                  óÀ  • SS K n SSKJn  [        S5        U" 5        nUR	                  SU R                  5       S-
  45        UR                  5         S S S 5        SnSnSn[        X4U5      of(       + ow(       dÌ  SS	[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS	[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S
.-  n[        [        R                  " U5      5      eS =n=n=n=pgg ! , (       d  f       GN= f)Nr   r4   Úoldz)UPDATE rate_hits SET ts=? WHERE key='old'éx   é   r   zBassert not %(py8)s
{%(py8)s = %(py0)s(%(py2)s, %(py4)s, %(py6)s)
}r   r<   )Útimer>   r5   r   r?   Úcommitr   r"   r#   r    r$   r%   r&   r'   )	rM   r5   rA   r)   r*   r,   rF   Ú@py_assert9r.   s	            r/   Útest_rate_limit_window_expiresrP   #   sÖ   € ÛÝÜˆuÔÙ	Œ�TØ�‰Ð@À4Ç9Á9Ã;ÐQTÑCTÐBVÔWØ�‰Œ÷ 
ð  Ð' Ð' BÐ'Œz˜% BÓ'Ð'Ô'Ð'Õ'×'×'×'×'×'Ñ'Œz×'×'×'Ñ'Œz×'×'Õ'˜%×'×'Ó' ×'×'Ó' B×'×'Ó'Ð'×'×'×'×'×'×'Ñ'÷ 
Žús   �5EÅ
Ec                 ój   • U(       a  SU0O0 n[         R                  " [         R                  " U S9US9$ )Nzx-forwarded-for)Úhost)ÚclientÚheaders©ÚtypesÚSimpleNamespace)ÚpeerÚxffrT   s      r/   Ú_reqrZ   /   s0   € Þ*-Ð  #Ñ&°2€GÜ× Ò ¬×(=Ò(=À4Ñ(HÐRYÑZÐZó    c                  óV  • [         R                  n SnSn[        X5      o0" U5      nSoTU:H  of(       Gdi  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U 5      S[
        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n =n=n=n=n=peg )
Nz203.0.113.9z1.2.3.4r   ©zy%(py11)s
{%(py11)s = %(py2)s
{%(py2)s = %(py0)s.client_ip
}(%(py9)s
{%(py9)s = %(py3)s(%(py5)s, %(py7)s)
})
} == %(py14)sr   rZ   ©r   r   Úpy3Úpy5r   r   Úpy11Úpy14úassert %(py16)sÚpy16©r   Ú	client_iprZ   r    r!   r"   r#   r$   r%   r&   r'   ©	r)   Ú@py_assert4r+   Ú@py_assert8Ú@py_assert10Ú@py_assert13Ú@py_assert12Ú@py_format15Ú@py_format17s	            r/   Ú;test_client_ip_ignores_forwarded_header_from_untrusted_peerro   4   sè   € Ü×ÑÐN =ÐN°)ÐNœd =Ó<ÐNÐÐ<Ó=ÐNÀÐNÀÑN×N×N×NÓNÐ=×N×N×N×N×NÕNŒ8×N×N×NÑNŒ8×N×NÕNÐ×N×N×N×N×NÔNœd×N×N×NÑNœd×N×NÕN =×N×NÓN°)×N×NÓNÐ<×N×NÓNÐ=×N×NÓNÀ×N×N×N×N×N×N×NÔNr[   c                  óV  • [         R                  n SnSn[        X5      o0" U5      nSoTU:H  of(       Gdi  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U 5      S[
        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n =n=n=n=n=peg )
Nú	127.0.0.1ú198.51.100.7r   r]   r   rZ   r^   rc   rd   re   rg   s	            r/   Ú;test_client_ip_uses_forwarded_header_behind_a_trusted_proxyrs   8   sè   € Ü×ÑÐR ;ÐR°ÐRœd ;Ó?ÐRÐÐ?Ó@ÐRÀNÐRÀNÑR×R×R×RÓRÐ@×R×R×R×R×RÕRŒ8×R×R×RÑRŒ8×R×RÕRÐ×R×R×R×R×RÔRœd×R×R×RÑRœd×R×RÕR ;×R×RÓR°×R×RÓRÐ?×R×RÓRÐ@×R×RÓRÀN×R×R×R×R×R×R×RÔRr[   c                  óV  • [         R                  n SnSn[        X5      o0" U5      nSoTU:H  of(       Gdi  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U 5      S[
        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n =n=n=n=n=peg )Nrq   z9.9.9.9, 198.51.100.7rr   r   r]   r   rZ   r^   rc   rd   re   rg   s	            r/   Ú8test_client_ip_cannot_be_spoofed_through_a_trusted_proxyru   <   sê   € ä×ÑÐ[ ;Ð[Ð0GÐ[œd ;ÓHÐ[ÐÐHÓIÐ[È^Ð[È^Ñ[×[×[×[Ó[ÐI×[×[×[×[×[Õ[Œ8×[×[×[Ñ[Œ8×[×[Õ[Ð×[×[×[×[×[Ô[œd×[×[×[Ñ[œd×[×[Õ[ ;×[×[Ó[Ð0G×[×[Ó[ÐH×[×[Ó[ÐI×[×[Ó[È^×[×[×[×[×[×[×[Ô[r[   c            
      ó$  • [         R                  n Sn[        U5      o " U5      nSoCU:H  oU(       GdT  [        R                  " SU4SX445      S[
        R                  " 5       ;   d  [        R                  " [         5      (       a  [        R                  " [         5      OS[        R                  " U 5      S[
        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n =n=n=n=pTg )	Nrq   r   )zn%(py9)s
{%(py9)s = %(py2)s
{%(py2)s = %(py0)s.client_ip
}(%(py7)s
{%(py7)s = %(py3)s(%(py5)s)
})
} == %(py12)sr   rZ   )r   r   r_   r`   r   r   Úpy12úassert %(py14)srb   re   )r)   rh   r+   ri   Ú@py_assert11rj   Ú@py_format13rm   s           r/   Ú'test_client_ip_without_forwarded_headerr{   A   sØ   € Ü×ÑÐ? ;Ð?œd ;Ó/Ð?ÐÐ/Ó0Ð?°KÐ?°KÑ?×?×?×?Ó?Ð0×?×?×?×?×?Õ?Œ8×?×?×?Ñ?Œ8×?×?Õ?Ð×?×?×?×?×?Ô?œd×?×?×?Ñ?œd×?×?Õ? ;×?×?Ó?Ð/×?×?Ó?Ð0×?×?Ó?°K×?×?×?×?×?×?×?Ò?r[   c                  óB  • [         R                  " S5      n / oR                  nSo2" U5      oDoT(       a  SofU ;  ownU(       Gd~  SS[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OS[
        R                  " U5      [
        R                  " U5      [
        R                  " U5      S.-  o�R                  U5        U(       a—  [
        R                  " SW4SWU 45      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS.-  n	S	S
U	0-  o¡R                  U
5        [
        R                  " US5      0 -  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=n=n=pg[         R                  nSo!" X 5      oÝ(       Gd  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OS[
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=p-[         R                  nSo!" X 5      oÝ(       + oÿ(       Gd  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OS[
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=pß[         R                  nSnS o1" X#5      oD(       + nU(       dÌ  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      [
        R                  " U5      [
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=n=nn[         R                  nSnSo1" X#5      oD(       + nU(       dÌ  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      [
        R                  " U5      [
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=n=nng )Nzun-mot-de-passezscrypt$zE%(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s.startswith
}(%(py6)s)
}Úh)r   r   r;   r=   ©únot in)z%(py11)s not in %(py13)s)ra   Úpy13z%(py15)sÚpy15r   zassert %(py18)sÚpy18zZassert %(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.verify_password
}(%(py4)s, %(py5)s)
}r   )r   r   r   r`   r   Úautrez^assert not %(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.verify_password
}(%(py4)s, %(py5)s)
}Úxz^assert not %(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.verify_password
}(%(py4)s, %(py6)s)
}r<   Úgarbage)r   Úhash_passwordÚ
startswithr"   r#   r    r$   r%   Úappendr!   Ú_format_boolopr&   r'   Úverify_password)r}   r)   r*   r,   rF   rB   rj   rl   rG   Ú@py_format14Ú@py_format16rn   Ú@py_format19r+   r-   ri   rO   r.   s                     r/   Útest_password_hash_roundtriprŽ   G   sM  € Ü×ÒÐ0Ó1€AÙA�<‰<ÐA˜	ÐAˆ<˜	Ó"ÑAÕ"Ð'8ÐAÀÑ'A×A×A×A×A×A×AÓAˆ1×A×A×AÑAˆ1×A×AÕAˆ<×A×AÓA˜	×A×AÓAÐ"×A×A×AÐAÖ"×A×AÓAÐ'8À×A×AÔAÐ'8×A×A×A×A×AÔAÀ×A×A×AÑAÀ×A×A×A×A×A×A×A×A×A×A×A×A×AÖAÜ×#Ñ#Ð9Ð$5Ð9Ð#Ð$5Ó9Ð9Ö9×9×9×9×9×9Ñ9Œ8×9×9×9Ñ9Œ8×9×9Õ9Ð#×9×9Ó9Ð$5×9×9×9×9×9Ô9°q×9×9×9Ñ9°q×9×9Õ9Ð9×9×9×9×9×9Ô9Ü×'Ñ'Ð3¨Ð3Ð'¨Ó3Ð3Ô3Ð3Ö3×3×3×3×3×3Ñ3Œx×3×3×3Ñ3Œx×3×3Õ3Ð'×3×3Ó3¨×3×3×3×3×3Ô3°×3×3×3Ñ3°×3×3Õ3Ð3×3×3×3×3×3Ö3Ü×'Ñ'Ð2¨Ð2¨TÐ2Ð'¨Ó2Ð2Ô2Ð2Ö2×2×2×2×2×2Ñ2Œx×2×2×2Ñ2Œx×2×2Õ2Ð'×2×2Ó2¨×2×2Ó2¨T×2×2Ó2Ð2×2×2×2×2×2×2Ñ2Ü×'Ñ'Ð7¨Ð7¨YÐ7Ð'¨Ó7Ð7Ô7Ð7Ö7×7×7×7×7×7Ñ7Œx×7×7×7Ñ7Œx×7×7Õ7Ð'×7×7Ó7¨×7×7Ó7¨Y×7×7Ó7Ð7×7×7×7×7×7×7Ò7r[   c            
      ó"  • [         R                  " SS5      u  p[         R                  nSo2" X0U5      oD(       GdM  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS[
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=p4[         R                  nSo2" X0U5      oD(       + of(       GdM  S	S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OSS[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS[
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=pF[         R                  nSo1S S
 o�S
   S:X  a  SOSo˜U	-   o¢" X0U
5      o»(       + oÌ(       Gd,  SS[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U 5      (       a  [
        R                  " U 5      OS[
        R                  " U5      [
        R                  " U	5      [
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=n=n	=n
=p¼[         R                  " SS5      u  pï[         R                  nSo2" X>U5      oD(       + of(       GdM  S	S[        R                  " 5       ;   d  [
        R                  " [         5      (       a  [
        R                  " [         5      OS[
        R                  " U5      [
        R                  " U5      S[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OSS[        R                  " 5       ;   d  [
        R                  " U5      (       a  [
        R                  " U5      OS[
        R                  " U5      S.-  n[        [
        R                  " U5      5      eS =n=n=pFg )NÚpayloadr   zdassert %(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.verify_signature
}(%(py4)s, %(py5)s, %(py6)s)
}r   ÚexpÚsig)r   r   r   r`   r;   r=   rƒ   zhassert not %(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s.verify_signature
}(%(py4)s, %(py5)s, %(py6)s)
}éÿÿÿÿÚ0Ú1zvassert not %(py12)s
{%(py12)s = %(py2)s
{%(py2)s = %(py0)s.verify_signature
}(%(py4)s, %(py5)s, (%(py7)s + %(py9)s))
})r   r   r   r`   r   r   rw   éûÿÿÿÚexp2Úsig2)
r   ÚsignÚverify_signaturer"   r#   r    r$   r%   r&   r'   )r‘   r’   r)   r*   rF   rG   rO   r.   r+   ri   rj   ry   rk   r‹   r—   r˜   s                   r/   Ú-test_signed_urls_expire_and_are_payload_boundr›   P   sE  € Ü�}Š}˜Y¨Ó+�H€CÜ×$Ñ$Ð9 YÐ9Ð$ Y°SÓ9Ð9Ö9×9×9×9×9×9Ñ9Œ8×9×9×9Ñ9Œ8×9×9Õ9Ð$×9×9Ó9 Y×9×9×9×9×9Ô9°×9×9×9Ñ9°×9×9×9×9×9Ö9°S×9×9×9Ñ9°S×9×9Õ9Ð9×9×9×9×9×9Ô9Ü×(Ñ(Ð;¨Ð;Ð(¨°sÓ;Ð;Ô;Ð;Ö;×;×;×;×;×;Ñ;Œx×;×;×;Ñ;Œx×;×;Õ;Ð(×;×;Ó;¨×;×;×;×;×;Ô;°#×;×;×;Ñ;°#×;×;×;×;×;Ö;°s×;×;×;Ñ;°s×;×;Õ;Ð;×;×;×;×;×;Ö;Ü×(Ñ(Ðe¨Ðe¸S¸b¸ÐeÐPRÉGÐWZËNÁSÐ`cÐeÐEcÑ9dÐeÐ(¨Ð9dÓeÐeÔeÐeÖe×e×e×e×e×eÑeŒx×e×e×eÑeŒx×e×eÕeÐ(×e×eÓe¨×e×e×e×e×eÔe°C×e×e×eÑe°C×e×eÕe¸×e×eÓeÐEc×e×eÓeÐe×e×e×e×e×e×eÔeÜ—’˜y¨"Ó-�J€DÜ×(Ñ(Ð?¨Ð?Ð(¨¸$Ó?Ð?Ô?Ð?Ö?×?×?×?×?×?Ñ?Œx×?×?×?Ñ?Œx×?×?Õ?Ð(×?×?Ó?¨×?×?×?×?×?Ô?°D×?×?×?Ñ?°D×?×?×?×?×?Ö?¸$×?×?×?Ñ?¸$×?×?Õ?Ð?×?×?×?×?×?×?r[   c           	      ó¨  • U R                  [        SS5        U R                  [        SS5        U R                  [        SS5        U R                  [        SS5        [        R                  o" 5       n[	        U5      nSoCU:H  oU(       Gd?  [
        R                  " S	U4S
X445      S[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OSS[        R                  " 5       ;   d  [
        R                  " [        5      (       a  [
        R                  " [        5      OS[
        R                  " U5      [
        R                  " U5      [
        R                  " U5      [
        R                  " U5      S.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=pTg )NÚADMIN_PASSWORDÚmeeconic2026ÚADMIN_JWT_SECRETz"change-me-generate-a-random-secretÚSTRIPE_SECRET_KEYÚ ÚSTRIPE_WEBHOOK_SECRETé   r   )zx%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.validate_production_config
}()
})
} == %(py10)sÚlenr   )r   r9   r_   r`   r   Úpy10zassert %(py12)srw   )Úsetattrr   r   Úvalidate_production_configr¤   r    r!   r"   r#   r$   r%   r&   r'   )ÚmonkeypatchrC   rh   r+   rO   ri   Ú@py_format11rz   s           r/   Ú3test_production_validation_flags_every_weak_settingrª   [   s  € Ø×ÑœÐ 0°.ÔAØ×ÑœÐ 2Ð4XÔYØ×ÑœÐ 3°RÔ8Ø×ÑœÐ 7¸Ô<Ü×2Ñ2Ð:Ð2Ó4Ð:Œ3Ð4Ó5Ð:¸Ð:¸Ñ:×:×:×:Ó:Ð5×:×:×:×:×:Õ:Œ3×:×:×:Ñ:Œ3×:×:×:×:×:Ö:Œx×:×:×:Ñ:Œx×:×:Õ:Ð2×:×:Ó:Ð4×:×:Ó:Ð5×:×:Ó:¸×:×:×:×:×:×:×:Ð:r[   c                 ó¼  • U R                  [        SS5        U R                  [        SS5        U R                  [        SS5        U R                  [        SS5        [        R                  o" 5       n/ o2U:H  oD(       d×  [        R
                  " S	U4S
X#45      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=pCg )Nr�   zun-vrai-mot-de-passe-longrŸ   Ú(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr    Ú	sk_live_xr¢   Úwhsec_xr   )zY%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.validate_production_config
}()
} == %(py7)sr   r   r   r   )r¦   r   r   r§   r    r!   r"   r#   r$   r%   r&   r'   )r¨   r)   r*   r+   r,   r-   r.   s          r/   Ú6test_production_validation_passes_with_a_strong_configr¯   c   s×   € Ø×ÑœÐ 0Ð2MÔNØ×ÑœÐ 2°HÔ=Ø×ÑœÐ 3°[ÔAØ×ÑœÐ 7¸ÔCÜ×.Ñ.Ð6Ð.Ó0Ð6°BÐ6°BÑ6×6×6×6Ò6Ð0×6×6×6×6×6Õ6Œ8×6×6×6Ñ6Œ8×6×6Õ6Ð.×6×6Ó6Ð0×6×6Ó6°B×6×6×6×6×6×6Ö6r[   c              ƒ   ót  #   • SS K nU R                  USS5        U R                  [        SS5        [        R                  " [
        SS9   UR                  UR                  5       IS h  v•N    S S S 5      IS h  v•N   S S S 5        g  N N! , IS h  v•N  (       d  f       N$= f! , (       d  f       g = f7f)Nr   ÚIS_PRODUCTIONTr�   Úadminz$Configuration de production invalide)Úmatch)Úmainr¦   r   r   r   ÚRuntimeErrorÚlifespanÚapp)r¨   r´   s     r/   Ú2test_production_refuses_to_start_with_a_bad_configr¸   k   sy   é € ÛØ×Ñ˜˜o¨tÔ4Ø×ÑœÐ 0°'Ô:Ü	�Š”|Ð+QÓ	RØ—=‘= §¡×*Õ*Ø÷ +×*÷ 
SÐ	Rß*×*×*Ò*ú÷ 
SÕ	Rüsf   ‚AB8Á
 B'Á*B	Á+B'Á.BÁ0B'Á;BÁ<B'Â 	B8Â	B'ÂB'ÂB$	ÂBÂB$	Â B'Â'
B5Â1B8c              ƒ   ó,  #   • SS K nU R                  [        SS5        U R                  [        SS5        UR                  UR                  5       IS h  v•N   [
        R                  " S5      I S h  v•N   [
        R                  " 5        Vs1 s H  o"R                  5       iM     nn1 SkoDU:*  oU(       d¥  [        R                  " SU4S	XC45      [        R                  " U5      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
S.-  nSSU0-  n[        [        R                   " U5      5      eS =pES S S 5      IS h  v•N   [
        R                  " S5      I S h  v•N   S [
        R                  " 5        5       n[#        U5      o™(       + oª(       d¢  SS[        R                  " 5       ;   d  [        R                  " ["        5      (       a  [        R                  " ["        5      OS[        R                  " U5      [        R                  " U	5      S.-  n[        [        R                   " U5      5      eS =n=pšg  GN GNùs  snf  GN	! , IS h  v•N  (       d  f       GN= f GN	7f)Nr   ÚBACKGROUND_TASKS_ENABLEDTÚORGANIZER_ENABLEDFg333333Ó?>   úleader-backupúleader-cleanupúleader-monitor)ú<=)z%(py1)s <= %(py3)sÚnames©r9   r_   úassert %(py5)sr`   gš™™™™™¹?c              3   ó^   #   • U  H#  oR                  5       R                  S 5      v •  M%     g7f)zleader-N)Úget_namer‡   )Ú.0Úts     r/   Ú	<genexpr>ÚJtest_lifespan_starts_and_stops_background_tasks_cleanly.<locals>.<genexpr>}   s$   é € ÐSÒ?R¸!—:‘:“<×*Ñ*¨9×5Ð5Ò?Rùs   ‚+-z0assert not %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}Úany©r   r   r   )r´   r¦   r   r¶   r·   ÚasyncioÚsleepÚ	all_tasksrÄ   r    r!   r%   r"   r#   r$   r&   r'   rÉ   )r¨   r´   rÆ   rÀ   rB   rC   Ú@py_format4Ú@py_format6r)   r*   r,   s              r/   Ú7test_lifespan_starts_and_stops_background_tasks_cleanlyrÐ   t   s‚  é € ÛØ×ÑœÐ :¸DÔAØ×ÑœÐ 3°UÔ;Ø�}‰}˜TŸX™X×&Õ&Ü�mŠm˜CÓ × Ð Ü'.×'8Ò'8Ô':Ó;Ò': !—‘–Ñ':ˆÐ;ÚDÐMÈÑM×M×M×MÒMÐD×M×MÔMÐD×M×M×M×M×MÔMÈ×M×M×MÑMÈ×M×M×M×M×M×MÓM÷ '×&ô �-Š-˜Ó
×ÐÙS¼w×?PÒ?PÔ?RÓSÐSŒsÐSÓSÐSÔSÐSÕS×S×S×S×S×SÑSŒs×S×S×SÑSŒs×S×SÕSÐS×S×SÓSÐS×S×S×S×S×SÕSò 'Ú ùÚ;÷ '×&×&Ò&úò ùsz   ‚AJÁI(ÁJÁI6Á2I+Á3I6ÂI.Â'B8I6ÅJÅ*I3Å+JÆJÆ	C JÉ+I6É.I6É3JÉ6JÉ<I?É=JÊ		Jc                 ób
  • SSK Jn  UR                  nSo2" U5      nSoTUL of(       dä  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=peUR                  nSo2" U5      oD(       d¯  SS[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n	[        [        R                  " U	5      5      eS =n=p4U R                  USS5        UR                  nSo2" U5      nSoTUL of(       dä  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=peUR                  nSo2" U5      oD(       + of(       d¯  SS[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n
[        [        R                  " U
5      5      eS =n=n=pFSSKJn  U" 5        nUR                  S5        UR!                  5         S S S 5        UR                  nSo2" U5      nSoTUL of(       dä  [        R                  " SU4SXE45      S[
        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=n=n=peg ! , (       d  f       GN= f)Nr   )Úleaderzt-lockT)Úis)zR%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s._try_acquire
}(%(py4)s)
} is %(py9)srÒ   )r   r   r   r;   r   zassert %(py11)sra   zKassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.is_leader
}(%(py4)s)
})r   r   r   r;   Ú_OWNERzautre-workerFzOassert not %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.is_leader
}(%(py4)s)
}r4   z8UPDATE leader_locks SET expires_at=0 WHERE name='t-lock')ÚcorerÒ   Ú_try_acquirer    r!   r"   r#   r$   r%   r&   r'   Ú	is_leaderr¦   r>   r5   r?   rN   )r¨   rÒ   r)   r*   r,   ri   rF   r.   Ú@py_format12rE   r-   r5   rA   s                r/   Ú+test_only_one_worker_can_hold_a_leader_lockrÙ   ‚   s	  € ÝØ×ÑÐ0˜xÐ0Ð˜xÓ(Ð0¨DÐ0¨DÐ0×0×0×0Ò0Ð(×0×0×0×0×0Õ0ˆ6×0×0×0Ñ0ˆ6×0×0Õ0Ð×0×0Ó0˜x×0×0Ó0Ð(×0×0Ó0¨D×0×0×0×0×0×0×0Ø×ÑÐ%˜HÐ%Ð˜HÓ%Ð%Õ%×%×%×%×%×%Ñ%ˆ6×%×%×%Ñ%ˆ6×%×%Õ%Ð×%×%Ó%˜H×%×%Ó%Ð%×%×%×%×%×%Ô%Ø×Ñ˜ ¨.Ô9Ø×ÑÐ1˜xÐ1Ð˜xÓ(Ð1¨EÐ1¨EÐ1×1×1×1Ò1Ð(×1×1×1×1×1Õ1ˆ6×1×1×1Ñ1ˆ6×1×1Õ1Ð×1×1Ó1˜x×1×1Ó1Ð(×1×1Ó1¨E×1×1×1×1×1×1×1Ø×ÑÐ) Ð)Ð Ó)Ð)Ô)Ð)Õ)×)×)×)×)×)Ñ)ˆv×)×)×)Ñ)ˆv×)×)Õ)Ð×)×)Ó) ×)×)Ó)Ð)×)×)×)×)×)Ö)ÝÙ	Œ�TØ�‰ÐOÔPØ�‰Œ÷ 
ð ×ÑÐ0˜xÐ0Ð˜xÓ(Ð0¨DÐ0¨DÐ0×0×0×0Ò0Ð(×0×0×0×0×0Õ0ˆ6×0×0×0Ñ0ˆ6×0×0Õ0Ð×0×0Ó0˜x×0×0Ó0Ð(×0×0Ó0¨D×0×0×0×0×0×0×0Ð0÷ 
Žús   Ï'"TÔ
T.c                 ó²  ^• SSK Jn  / mU R                  [        SS5        U R                  [        SS5        U R                  USU4S j5        SS KnU R                  US	S
 5        UR                  SSS5        UR                  SSS5        UR                  SSS5        SS/nTU:H  oD(       d¦  [        R                  " SU4STU45      S[        R                  " 5       ;   d  [        R                  " T5      (       a  [        R                  " T5      OS[        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =pCg )Nr   ©Úalert_serviceÚAPP_ENVÚ
productionÚALERT_EMAILúops@example.comÚ
_smtp_sendc                 ó&   >• TR                  U 5      $ ©N©rˆ   )ÚsubjectÚbodyÚsents     €r/   Ú<lambda>Ú:test_alerts_are_deduplicated_by_cooldown.<locals>.<lambda>—   s   ø€ È4Ï;É;ÐW^ÔK_r[   ÚThreadc                 ó8   ^ ^• [         R                  " UU 4S jS9$ )Nc                  ó   >• T" T 6 $ rã   © )ÚargsÚtargets   €€r/   rè   ÚLtest_alerts_are_deduplicated_by_cooldown.<locals>.<lambda>.<locals>.<lambda>™   s   ø€ ÑntÐvzÑn{r[   )ÚstartrU   )rï   rî   Údaemons   `` r/   rè   ré   ™   s   ù€ Ì%×J_ÒJ_Õf{ÒJ|r[   zsame-key-xyzzSujet 1ÚcorpszSujet 2zautre-cle-xyzzSujet 3r   )z%(py0)s == %(py3)srç   )r   r_   rÂ   r`   )ÚservicesrÜ   r¦   r   Ú	threadingÚnotifyr    r!   r"   r#   r$   r%   r&   r'   )r¨   rÜ   rõ   rC   r)   rÎ   rÏ   rç   s          @r/   Ú(test_alerts_are_deduplicated_by_cooldownr÷   ’   sö   ø€ Ý&Ø€DØ×Ñœ 	¨<Ô8Ø×Ñœ Ð/@ÔAØ×Ñ˜ |Ô5_Ô`ÛØ×Ñ˜	 8Ñ-|Ô}Ø×Ñ˜¨°GÔ<Ø×Ñ˜¨°GÔ<Ø×Ñ˜¨)°WÔ=Ø˜yÐ)Ð)ˆ4Ð)Ñ)×)×)×)Ò)ˆ4Ð)×)×)×)×)×)Õ)ˆ4×)×)×)Ñ)ˆ4×)×)Õ)Ð)×)×)×)×)×)×)Ò)r[   c                 óº   • SSK Jn  U R                  [        SS5        U R                  [        SS5        U R                  USS 5        UR	                  S	S
S5        g )Nr   rÛ   rÝ   rÞ   rß   rà   Ú_cooldown_okc                 óD   • S S 5       R                  [        S5      5      $ )Nc              3   ó$   #   • U  H  ov •  M     g 7frã   rí   )rÅ   r(   s     r/   rÇ   ÚRtest_alert_never_raises_even_if_smtp_blows_up.<locals>.<lambda>.<locals>.<genexpr>¤   s   é € À?ÊrÈ!ÄAÊrùs   ‚rí   Úboom)Úthrowrµ   )Úkeys    r/   rè   Ú?test_alert_never_raises_even_if_smtp_blows_up.<locals>.<lambda>¤   s   € Á?ÉrÃ?×CXÑCXÔYeÐflÓYmÔCnr[   ÚkÚsÚb)rô   rÜ   r¦   r   rö   )r¨   rÜ   s     r/   Ú-test_alert_never_raises_even_if_smtp_blows_upr      sO   € Ý&Ø×Ñœ 	¨<Ô8Ø×Ñœ Ð/@ÔAØ×Ñ˜ ~Ñ7nÔoØ×Ñ˜˜c 3Õ'r[   c              ƒ   ó¢  ^#   • SS K n/ mUR                  UR                  SSU4S jj5        UR                  R	                  S5      S 5       nSSKJnJn  U" U" UR                  SS9S	S
9 IS h  v•N nUR	                  S5      I S h  v•N nS S S 5      IS h  v•N   WR                  nSo˜U	:H  oª(       dº  [        R                  " SU
4SX‰45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U	5      S.-  nSSU0-  n[        [        R                   " U5      5      eS =n=p©UR"                  oˆ" 5       n
SS0oÚU:H  oî(       dÏ  [        R                  " SU4SX­45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U
5      [        R                  " U5      S.-  nSSU0-  n[        [        R                   " U5      5      eS =n=n
=píS T 5       n[%        U5      oª(       d¢  SS[        R                  " 5       ;   d  [        R                  " [$        5      (       a  [        R                  " [$        5      OS[        R                  " U5      [        R                  " U
5      S.-  n[        [        R                   " U5      5      eS =pŠg  GN» GN¥ GN˜! , IS h  v•N  (       d  f       GN®= f7f)Nr   rö   c                 ó&   >• TR                  U 5      $ rã   rä   )rÿ   rå   ræ   Úseens      €r/   rè   ÚFtest_unhandled_error_returns_500_and_raises_an_alert.<locals>.<lambda>«   s   ø€ ÐTX×T_ÑT_Ð`cÔTdr[   z
/api/_boomc               “   ó    #   • [        S5      e7f)NÚkaboom)rµ   rí   r[   r/   rý   ÚBtest_unhandled_error_returns_500_and_raises_an_alert.<locals>.boom­   s   é € ä˜8Ó$Ð$ùs   ‚)ÚASGITransportÚAsyncClientF)r·   Úraise_app_exceptionszhttp://t)Ú	transportÚbase_urliô  r   )z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sÚr)r   r   r`   zassert %(py7)sr   ÚdetailzErreur interne du serveur.)zC%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.json
}()
} == %(py7)sr   r   r   c              3   óB   #   • U  H  oR                  S 5      v •  M     g7f)zhttp-500N)r‡   )rÅ   r  s     r/   rÇ   ÚGtest_unhandled_error_returns_500_and_raises_an_alert.<locals>.<genexpr>¶   s   é € Ð6²¨A�|‰|˜J×'Ð'²ùs   ‚z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}rÉ   rÊ   )r¡   )r´   r¦   rÜ   r·   ÚgetÚhttpxr  r  r   r    r!   r"   r#   r$   r%   r&   r'   ÚjsonrÉ   )rS   r¨   r´   rý   r  r  Úcr  r)   rh   r*   rÏ   r-   r+   r,   r.   rD   r  s                    @r/   Ú4test_unhandled_error_returns_500_and_raises_an_alertr  ¨   s÷  øé € ÛØ€DØ×Ñ˜×*Ñ*¨HÖ6dÔeà	‡X�X‡\�\�,Óñ%ó  ð%÷ 1Ù¡]°t·x±xÐV[Ñ%\Ðgq×rÒrÐvwØ—%‘%˜Ó%×%ˆ÷ s×rà�=‰=Ð˜CÐ˜CÑ×××Òˆ=×××××Õˆ1×××Ñˆ1××Õˆ=××Ó˜C××××××ÓØ�6‰6Ð?ˆ6‹8Ð?˜Ð">Ð?Ð?Ð?Ñ?×?×?×?Ò?ˆ8×?×?×?×?×?Õ?ˆ1×?×?×?Ñ?ˆ1×?×?Õ?ˆ6×?×?Ó?ˆ8×?×?Ó?Ð?×?×?×?×?×?×?Õ?Ù6±Ó6Ð6Œ3Ð6Ó6Ð6Õ6×6×6×6×6×6Ñ6Œ3×6×6×6Ñ6Œ3×6×6Õ6Ð6×6×6Ó6Ð6×6×6×6×6×6Ó6ò	 sÚ%÷ s×r×rÒrüs[   ƒA-MÁ0L+Á1MÁ4L4Â	L.Â
L4ÂMÂL1ÂJMÌ.L4Ì1MÌ4MÌ:L=Ì;MÍMc            
      óè  • SSK Jn   U R                  SSSSSSS	S
./S5      n/ nSo3U;  oDoT(       a  SofU;  ownU(       Gdt  [        R                  " SU4SX145      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  nSSU0-  o’R                  U	5        U(       a—  [        R                  " SW4SWU45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  n
SSU
0-  o²R                  U5        [        R                  " US5      0 -  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=n=pgSoUU;   o3(       d¥  [        R                  " SU4SXQ45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS =pSg ) Nr   ©Úemail_servicez<script>alert(1)</script>Úabc12345úTST-1001z<img src=x onerror=alert(1)>rL   é	   F)Úformat_labelÚquantityÚ
unit_priceÚis_magicç      "@z<script>z
<img src=xr~   )z%(py3)s not in %(py5)sÚhtml_out©r_   r`   ú%(py7)sr   )z%(py10)s not in %(py12)s©r¥   rw   ú%(py14)srb   úassert %(py17)sÚpy17z&lt;script&gt;©Úin©z%(py1)s in %(py3)srÁ   rÂ   r`   ©rô   r  Ú_confirmation_htmlr    r!   r%   r"   r#   r$   rˆ   r‰   r&   r'   )r  r%  r)   rC   rh   rB   rO   ry   rÏ   r-   rz   rm   rŒ   Ú@py_format18rÎ   s                  r/   Ú+test_order_emails_escape_user_supplied_htmlr2  »   sY  € Ý&Ø×/Ñ/Ø# Z°Ø8ÀaÐWXÐfkÑ	lÐmÐorót€Hñ Gˆ:ÐF˜XÑ%×F¨,ÐF¸hÑ*F×F×F×FÕFˆ:×F×FÔFˆ:×F×F×F×F×FÔF˜X×F×F×FÑF˜X×F×F×F×F×F×F×FÔF¨,¸h×F×FÔF¨,×F×F×F×F×FÔF¸h×F×F×FÑF¸h×F×F×F×F×F×F×F×F×F×F×F×F×FÔFØÐ'˜xÑ'×'×'×'Ò'Ð×'×'Ô'Ð×'×'×'×'×'Ô'˜x×'×'×'Ñ'˜x×'×'×'×'×'×'Ô'r[   c            	      ó  • SSK Jn   U R                  SSS/ SSS5      nU R                  SSS/ S	S
S5      n/ nSoDU;   oUoe(       a  SowU;   oˆnU(       Gdt  [        R                  " SU4SXA45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  n	SSU	0-  o£R                  U
5        U(       a—  [        R                  " SW4SWU45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  nSSU0-  oÃR                  U5        [        R                  " US5      0 -  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=n=pxSofU;  oD(       d¥  [        R                  " SU4SXb45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  nSSU0-  n	[        [        R                  " U	5      5      eS =pdg )Nr   r  ÚAr  r  ç      @Túhttps://p.exampler$  Fu   tÃ©lÃ©chargementz https://p.example/?code=TST-1001r,  )z%(py3)s in %(py5)sÚdigitalr&  r'  r   )z%(py10)s in %(py12)sr(  r)  rb   r*  r+  r~   )z%(py1)s not in %(py3)sÚpaperrÁ   rÂ   r`   r/  )r  r7  r8  r)   rC   rh   rB   rO   ry   rÏ   r-   rz   rm   rŒ   r1  rÎ   s                   r/   ÚBtest_confirmation_email_mentions_downloads_only_for_digital_ordersr9  Ä   sq  € Ý&Ø×.Ñ.¨s°JÀ
ÈBÐPSÐUYÐ[nÓo€GØ×,Ñ,¨S°*¸jÈ"ÈcÐSXÐZmÓn€EÙZÐÐZ Ñ(×ZÐ-OÐZÐSZÑ-Z×Z×Z×ZÕZÐ×Z×ZÔZÐ×Z×Z×Z×Z×ZÔZ ×Z×Z×ZÑZ ×Z×Z×Z×Z×Z×Z×ZÔZÐ-OÐSZ×Z×ZÔZÐ-O×Z×Z×Z×Z×ZÔZÐSZ×Z×Z×ZÑZÐSZ×Z×Z×Z×Z×Z×Z×Z×Z×Z×Z×Z×Z×ZÔZØÐ* UÑ*×*×*×*Ò*Ð×*×*Ô*Ð×*×*×*×*×*Ô* U×*×*×*Ñ* U×*×*×*×*×*×*Ô*r[   c           
      óp  ^• SS K nSSKJn  SSKJn  US-  US-  peUR                  SS-  5        UR                  S5        XVS	.mU R                  US
U4S j5        SS0SS0SS0/nU R                  USS5        UR                  SSU5      nU V	V
s/ s H  u  pšU	PM	     nn	n
SS/oËU:H  oÝ(       do  [        R                  " SU4SX¼45      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pÜU R                  USS5        UR                  nSnSnU" UUU5      n/ nUU:H  nU(       GdE  [        R                  " SU4SUU45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=n=n=n=nng s  sn
n	f )Nr   )r   )Úmedia_serviceúbig.jpgú	small.jpgó   xiÀ'	 sè  yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy)r<  r=  Úsafe_photo_pathc                 ó&   >• TR                  U5      $ rã   )r  )ÚsidÚcodeÚnameÚpathss      €r/   rè   ÚGtest_order_email_attaches_originals_within_size_limit.<locals>.<lambda>Õ   s   ø€ ÐRW×R[ÑR[Ð\`ÔRar[   Úphoto_filenamezgone.jpgÚEMAIL_ATTACH_MAX_MBrL   r  zTST-1r   r7   r8   r:   r;   )zm%(py9)s
{%(py9)s = %(py2)s
{%(py2)s = %(py0)s._collect_attachments
}(%(py4)s, %(py6)s, %(py7)s)
} == %(py12)sr´   Úentitled)r   r   r   r;   r   r   rw   rx   rb   )r´   rÕ   r   rô   r;  Úwrite_bytesr¦   Ú_collect_attachmentsr    r!   r%   r&   r'   r"   r#   r$   )r¨   Útmp_pathr´   r   r;  ÚbigÚsmallrH  Úgotr6   r(   rB   r*   rC   rD   rE   r)   r,   ri   ry   rj   rz   rm   rD  s                          @r/   Ú5test_order_email_attaches_originals_within_size_limitrO  Ì   só  ø€ ÛÝÝ&à˜IÑ% x°+Ñ'=ˆØ‡O�O�D˜7‘NÔ#Ø	×Ñ�lÔ#ØÑ0€EØ×Ñ˜Ð'8Ô:aÔbØ! ;Ð/Ð2BÀJÐ1OÐRbÐdmÐQnÐo€Hð ×Ñ˜Ð 5°qÔ9Ø
×
#Ñ
# C¨°(Ó
;€CÙÔš#‘$�!‹A™#Ð:Ñ ;°	Ð":Ð:Ð":Ñ:×:×:×:Ò:Ð×:×:Ô:Ð×:×:Ó:Ð":×:×:×:×:×:×:Ó:ð ×Ñ˜Ð 5°qÔ9Ø×$Ñ$ÐB SÐB¨'ÐBÑ$ S¨'°8Ó<ÐBÀÐBÐ<ÀÑB×B×B×BÔBÐ<À×B×B×B×B×BÕBˆ4×B×B×BÑBˆ4×B×BÕBÐ$×B×BÓB S×B×BÓB¨'×B×B×B×B×BÔB°8×B×B×BÑB°8×B×BÕBÐ<×B×BÓBÀ×B×B×B×B×B×B×BÓBùó	 s   ÂJ2c                  ó¤  • SSK Jn   U R                  SSS/ SSSS	S
9nSo"U;   o3(       d¥  [        R                  " SU4SX!45      [        R
                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R
                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS =p#g )Nr   r  r4  r  r  r5  Tr6  r2   )Úattachedu   jointes Ã  cet e-mail (2)r,  r.  ÚoutrÁ   rÂ   r`   )rô   r  r0  r    r!   r%   r"   r#   r$   r&   r'   )r  rR  rB   rC   rÎ   rÏ   s         r/   Ú0test_confirmation_email_mentions_attached_photosrS  â   s†   € Ý&Ø
×
*Ñ
*¨3°
¸JÈÈCÐQUÐWjÐuvÐ
*Ð
w€CØ&Ð-¨#Ñ-×-×-×-Ò-Ð&×-×-Ô-Ð&×-×-×-×-×-Ô-¨#×-×-×-Ñ-¨#×-×-×-×-×-×-Ô-r[   rã   ))Ú__doc__Úbuiltinsr"   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter    rË   rV   r   Úfastapir   rÕ   r   r   Úcore.rate_limitr   r   r   r0   rH   rP   rZ   ro   rs   ru   r{   rŽ   r›   rª   r¯   r¸   rÐ   rÙ   r÷   r  r  r2  r9  rO  rS  rí   r[   r/   Ú<module>r[     sš   ðñ@ç  „ ƒÛ ã Ý !ç !ß ;Ñ ;ò
5ò(ò(ô[ò
OòSò\ò
@ò8ò@ò;ò7òò	Tò1ò *ò(ò7ò&(ò+òCó,.r[   