ó
    Éj¼
  ã                   ój   • S SK rS SKJs  Jr  S SKJr  S SKJ	r	J
r
  S rS rS rS rS rS	 rS
 rS rg)é    N)Úurlparse)Ú	DEMO_CODEÚNOCONSENT_CODEc              ƒ   óœ  #   • U R                  SU 35      I S h  v•N nU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      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=pTUR                  5       nUS	   o™U:H  oª(       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šUS   n	SoYUL 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S   n[        U5      nSoåU:H  oÿ(       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=pþUS   n	SoYU: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S    S!   n	S"oYU: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¥g  GN/7f)#Nú/api/portal/photos?code=éÈ   ©ú==)z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sÚr)Úpy0Úpy2Úpy5zassert %(py7)sÚpy7Úfamily_code)z%(py1)s == %(py3)sÚ	demo_code©Úpy1Úpy3úassert %(py5)sr   Úconsent_givenT©Úis©z%(py1)s is %(py4)s©r   Úpy4úassert %(py6)sÚpy6Úphotosé   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sÚlen)r   r   r   r   zassert %(py9)sÚpy9Úschool_nameu   Ã‰cole Test©z%(py1)s == %(py4)sÚpricingÚprint_10x15é	   )ÚgetÚstatus_codeÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationÚjsonr    )Úclientr   r   Ú@py_assert1Ú@py_assert4Ú@py_assert3Ú@py_format6Ú@py_format8ÚbodyÚ@py_assert0Ú@py_assert2Ú@py_format4Ú@py_format5Ú@py_format7Ú@py_assert6Ú@py_assert5Ú@py_format10s                    Ú[D:\Ingenieria\TRABAJOS ONLINE\Projects\11- Photo School\backend\tests\test_portal_photos.pyÚ"test_photos_known_code_returns_200rB      sz  é € Ø�j‰jÐ3°I°;Ð?Ó@×@€AØ�=‰=Ð˜CÐ˜CÑ×××Òˆ=×××××Õˆ1×××Ñˆ1××Õˆ=××Ó˜C××××××ÓØ�6‰6‹8€DØ�ÑÐ+ )Ñ+×+×+×+Ò+Ð×+×+Ô+Ð×+×+×+×+×+Ô+ )×+×+×+Ñ+ )×+×+×+×+×+×+Ó+Ø�Ñ Ð( DÐ( DÐ(×(×(×(Ò(Ð ×(×(Ô(Ð ×(×(Ó( D×(×(×(×(×(×(Ó(Ø�H‰~Ð#Œ3ˆ~ÓÐ# !Ð# !Ñ#×#×#×#Ò#Ð×#×#×#×#×#Õ#Œ3×#×#×#Ñ#Œ3×#×#Õ#ˆ~×#×#Ó#Ð×#×#Ó# !×#×#×#×#×#×#Õ#Ø�ÑÐ/ -Ð/ -Ñ/×/×/×/Ò/Ð×/×/Ô/Ð×/×/Ó/ -×/×/×/×/×/×/Ó/Ø�	‰?˜=Ñ)Ð.¨QÐ.¨QÑ.×.×.×.Ò.Ð)×.×.Ô.Ð)×.×.Ó.¨Q×.×.×.×.×.×.Ô.ò 	Aùs   ‚QšQ	›P/Qc              ƒ   ó"  #   • SSK Jn  U" 5        nUR                  S[        45        UR	                  5         S S S 5        U R                  S[         35      I S h  v•N nUR                  5       nUS   nSoeUL ow(       do  [        R                  " SU4SXV45      [        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n	[        [        R                  " U	5      5      eS =n=pvUS   n/ oeU:H  ow(       do  [        R                  " SU4SXV45      [        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n	[        [        R                  " U	5      5      eS =n=pvg ! , (       d  f       GNI= f GN17f)Nr   ©Úget_dbz0UPDATE families SET consent_at=NULL WHERE code=?r   r   Fr   r   r   r   r   r   r	   r#   )Úcore.dbrE   Úexecuter   Úcommitr'   r1   r)   r*   r.   r/   r0   )
r2   rE   Úconnr   r8   r9   r5   r:   r<   r=   s
             rA   Ú test_photos_hidden_until_consentrJ      s  é € ÝÙ	Œ�TØ�‰ÐGÌ.ÐIZÔ[Ø�‰Œ÷ 
ð �j‰jÐ3´NÐ3CÐDÓE×E€AØ�6‰6‹8€DØ�Ñ Ð) EÐ) EÐ)×)×)×)Ò)Ð ×)×)Ô)Ð ×)×)Ó) E×)×)×)×)×)×)Ó)Ø�‰>Ð˜RÐ˜RÑ×××Òˆ>××Ôˆ>××Ó˜R××××××Ô÷ 
Žúò 	Fùs(   ‚F�(E:¸#FÁFÁDFÅ:
F	Æ	Fc              ƒ   ó†  #   • U R                  S5      I S h  v•N oR                  nSo2U:H  oD(       d„  [        R                  " SU4SX#4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=pCg  N§7f)Nz /api/portal/photos?code=ZZZ-0000é”  r	   ©z3%(py3)s
{%(py3)s = %(py1)s.status_code
} == %(py6)s©r   r   r   úassert %(py8)sÚpy8©r'   r(   r)   r*   r.   r/   r0   ©r2   r9   r:   r?   r4   r=   Ú@py_format9s          rA   Ú$test_photos_unknown_code_returns_404rT      sx   é € Ø—*‘*Ð?Ó@×@ÐT×MÑMÐTÐQTÐTÐQTÑT×T×T×TÒTÐM×T×TÔTÐ@×T×TÓTÐM×T×TÓTÐQT×T×T×T×T×T×TÖTÑ@ùó   ‚C—B?˜B(Cc              ƒ   ó*  #   • SSK Jn  SSKJn  U" 5        nUR	                  SU" 5       U" 5       45        UR                  5         SSS5        U R                  S5      I Sh  v•N R                  5       nUS   n/ oeU:H  ow(       do  [        R                  " SU4S	XV45      [        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n	[        [        R                  " U	5      5      eS=n=pvUS   nSoeUL ow(       do  [        R                  " SU4SXV45      [        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n	[        [        R                  " U	5      5      eS=n=pvg! , (       d  f       GN@= f GN/7f)uL   Une famille sans photos reÃ§oit une liste vide, jamais d'images alÃ©atoires.r   rD   )Ú
utcnow_isoz„INSERT OR REPLACE INTO families (code, family_name, created_at, school_id, consent_at) VALUES ('EMP-4004','Vide',?, 'ecole-test', ?)Nz /api/portal/photos?code=EMP-4004r   r	   r#   r   r   r   Úphotos_pendingTr   r   )rF   rE   Úcore.timeutilrW   rG   rH   r'   r1   r)   r*   r.   r/   r0   )
r2   rE   rW   rI   r8   r9   r5   r:   r<   r=   s
             rA   Ú1test_photos_never_fall_back_to_placeholder_imagesrZ       s
  é € åÝ(Ù	Œ�TØ�‰ð EÙGQÃ|ÑU_ÓUaÐFbô	dà�‰Œ÷ 
ð —*‘*Ð?Ó@×@×FÑFÓH€DØ�‰>Ð˜RÐ˜RÑ×××Òˆ>××Ôˆ>××Ó˜R××××××ÓØÐ Ñ!Ð) TÐ) TÐ)×)×)×)Ò)Ð!×)×)Ô)Ð!×)×)Ó) T×)×)×)×)×)×)Ô)÷ 
Žúò Aùs)   ‚F–/E>ÁFÁ!FÁ"DFÅ>
FÆ	Fc              ƒ   óJ  #   • U R                  SU 35      I S h  v•N R                  5       S   nU GHh  nUS   oDR                  nSoe" U5      ow(       dy  S[        R                  " U5      [        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS =n=n=pg/ n	SoSS   o¥U
;   ofoF(       a  So³S   oËU;   oÝnU(       Gd	  [        R                  " S	U4S
XZ45      [        R                  " U5      [        R                  " U
5      S.-  nSSU0-  oùR                  U5        U(       ab  [        R                  " S	W4SWW45      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  nU	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
=n=pÜSoCS   nUU;  oU(       dp  [        R                  " SU4SUU45      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS =n=nnGMk     g  GN†7f)Nr   r   Úurlz/api/media/preview/zLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})r   r   r   r   zsig=zexp=©Úin)z%(py3)s in %(py6)s)r   r   z%(py8)srP   )z%(py11)s in %(py14)s)Úpy11Úpy14z%(py16)sÚpy16r   zassert %(py19)sÚpy19z/photos/)únot in)z%(py1)s not in %(py4)sr   r   r   )
r'   r1   Ú
startswithr)   r.   r/   r0   r*   ÚappendÚ_format_boolop)r2   r   r   Úpr9   r:   r4   r>   r7   r3   r?   Ú@py_assert10Ú@py_assert13Ú@py_assert12r=   rS   Ú@py_format15Ú@py_format17Ú@py_format18Ú@py_format20r5   r<   s                         rA   Ú1test_photo_urls_are_signed_previews_not_originalsro   -   sœ  é € Ø—J‘JÐ!9¸)¸ÐEÓF×F×LÑLÓNÈxÑX€FÜˆØ�‰xÐ9×"Ñ"Ð9Ð#8Ð9Ð"Ð#8Ó9Ð9Õ9×9×9Ð9ˆx×9×9Ó9Ð"×9×9Ó9Ð#8×9×9Ó9Ð9×9×9×9×9×9Ö9Ù8ˆvÐ8˜5™Ð8˜Ñ!×8 fÐ8°%±Ð8°Ñ&8×8×8×8Õ8ˆv×8×8Ô8ˆv×8×8Ó8˜×8×8×8×8×8×8×8Ò8 f°×8×8Ô8 f×8×8Ó8°×8×8×8×8×8×8×8×8×8×8×8×8×8×8ØÐ) 5¡Ð)ˆz Ñ)×)×)×)Ò)ˆz ×)×)Ô)ˆz×)×)Ó) ×)×)×)×)×)×)×)ò ò Gùs   ‚J#šJ ›JJ#c              ƒ   ó  #   • [        S5       Vs/ s H%  oR                  S5      I Sh  v•N R                  PM'     nnSo3U;   oD(       d¥  [        R                  " SU4SX24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=p4US   nSosU:H  oD(       do  [        R                  " SU4SX745      [        R
                  " U5      [        R
                  " U5      S.-  nSSU0-  n	[        [        R                  " U	5      5      eS=n=pGg GNOs  snf 7f)uL   EmpÃªche de scanner l'espace des codes famille (seuls les Ã‰CHECS comptent).é   z!/api/portal/photos?code=NOPE-0000Ni­  r]   )z%(py1)s in %(py3)sÚstatusesr   r   r   r   rL   r	   r#   r   r   r   )Úranger'   r(   r)   r*   r.   r+   r,   r-   r/   r0   )
r2   Ú_rr   r9   r:   r;   r6   r5   r<   r=   s
             rA   Ú+test_failed_lookups_are_rate_limited_per_ipru   5   sã   é € ä]bÐceÔ]fÓgÒ]fÐXY—z‘zÐ"EÓF×F×SÔSÑ]f€HÐgØÐ�(‰?×××Òˆ3××Ôˆ3×××××Ô�(×××Ñ�(××××××ÓØ�A‰;Ð˜#Ð˜#Ñ×××Òˆ;××Ôˆ;××Ó˜#××××××Ôò GùÒgùs&   ‚F �E;©E8
ªE;¼D<F Å8E;Å;F c              ƒ   óî  #   • [        S5       Vs/ s H(  o R                  SU 35      I S h  v•N R                  PM*     nn[        U5      nS1oTU:H  of(       Gd  [        R
                  " SU4SXE45      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS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=peg  GNAs  snf 7f)Né   r   r   r	   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚsetrr   )r   r   r   r   rO   rP   )rs   r'   r(   rx   r)   r*   r+   r,   r-   r.   r/   r0   )	r2   r   rt   rr   r:   r?   r4   r=   rS   s	            rA   Ú2test_successful_lookups_do_not_burn_the_rate_limitry   <   sÖ   é € Ü`eÐfhÔ`iÓjÒ`iÐ[\—z‘zÐ$<¸Y¸KÐ"HÓI×I×VÔVÑ`i€HÐjÜˆx‹=Ð!˜S˜EÐ!˜EÑ!×!×!×!Ó!ˆ=×!×!×!×!×!Õ!Œ3×!×!×!Ñ!Œ3×!×!×!×!×!Ö!ˆx×!×!×!Ñ!ˆx×!×!Õ!ˆ=×!×!Ó!˜E×!×!×!×!×!×!Ô!ò JùÒjùs&   ‚E5�E0¬E-
­E0¿D.E5Å-E0Å0E5c              ƒ   ó†  #   • U R                  S5      I S h  v•N oR                  nSo2U:H  oD(       d„  [        R                  " SU4SX#4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=pCg  N§7f)Nz!/api/portal/photos?code=../../etcrL   r	   rM   rN   rO   rP   rQ   rR   s          rA   Ú$test_path_traversal_code_is_rejectedr{   A   sx   é € Ø—*‘*Ð@ÓA×AÐU×NÑNÐUÐRUÐUÐRUÑU×U×U×UÒUÐN×U×UÔUÐA×U×UÓUÐN×U×UÓUÐRU×U×U×U×U×U×UÖUÑAùrU   )Úbuiltinsr+   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter)   Úurllib.parser   Úconftestr   r   rB   rJ   rT   rZ   ro   ru   ry   r{   © ó    rA   Ú<module>r„      s:   ðß  „ Õ !ç .ò/ò òUò
*ò*òò"ó
Vrƒ   