ó
    ŸUAj0%  ã                  ó¸  • S r SSKJ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  \R                  R                  S\" \" \5      R%                  5       R&                  S   S-  5      5         " S S\	R(                  5      rSSS	 jjrS
 rS rS rS rS r " S S5      rS rS rS r " S S5      r \!S:X  aÝ  SSK"r"SSK#r#Sr$\%" S \&" \'" 5       5      RQ                  5        5       5       H‹  u  r)r*\ " 5       r+\*RX                  RZ                  S\*RX                  R\                   r/0 r0S\/;   a  \+\0S'   S\/;   a  \" \"Rb                  " 5       5      \0S'    \*" S0 \0D6  \2" S\) 35        \+Rk                  5         M�     \Rl                  " \$(       a  SOS5        gg! \3 a$    \$S-  r$\2" S\) 35        \#Rh                  " 5          NZf = f! \+Rk                  5         f = f)ap  Phase 1 contract-alignment tests for the WolfPanel Agent API client.

Verifies the frozen v1 contract on the agent side:
  * paths under /api/v1/agent/*
  * X-Agent-Token header on agent-authenticated calls (never Bearer)
  * register response handling = {agent_token, server_id, status}

These tests capture the outgoing urllib Request without doing any network I/O.
é    )ÚannotationsN)ÚPathé   Úsrcc                  ó    • \ rS rSrS rS rSrg)Ú_FakeResponseé   c                ó   • U $ ©N© ©Úselfs    Ú9D:\Programs\laragon\www\wolf\agent\tests\test_contract.pyÚ	__enter__Ú_FakeResponse.__enter__   s   € Øˆó    c                ó   • g)NFr   )r   Úexcs     r   Ú__exit__Ú_FakeResponse.__exit__   s   € Ør   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   r   Ú__static_attributes__r   r   r   r   r      s   † òõr   r   c                óv   ^^• SSK n/ mSUU4S jjnU R                  UR                  R                  SU5        T$ )z;Patch urllib so RealApiClient calls are captured, not sent.r   Nc                ó”   >• TR                  U 5        [        [        R                  " T=(       d    0 5      R	                  S5      5      $ )Nzutf-8)Úappendr   ÚjsonÚdumpsÚencode)ÚrequestÚtimeoutÚbodyÚcaptureds     €€r   Úfake_urlopenÚ'_capture_requests.<locals>.fake_urlopen#   s2   ø€ Ø�‰˜Ô ÜœTŸZšZ¨¯
°Ó3×:Ñ:¸7ÓCÓDÐDr   Úurlopenr   )Ú
api_clientÚsetattrÚurllibr"   )Úmonkeypatchr$   r)   r&   r%   s    `  @r   Ú_capture_requestsr-      s<   ù€ ãà€H÷Eð Eð ×Ñ˜
×)Ñ)×1Ñ1°9¸lÔKØ€Or   c                óØ  • SS K n[        U SSSS.5      nUR                  S5      nUR                  SSS	.5      nUS   nUR                  nS
ovU:H  oˆ(       dº  [
        R                  " SU4SXg4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                  nSo†" U5      nS oËUL 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      [
        R                  " U5      S.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=pÜUR                  nSo†" U5      nS oËUL 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      [
        R                  " U5      S.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=pÜSSSS.nUU:H  of(       d¦  [
        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      S.-  nSSU0-  n	[        [
        R                  " U	5      5      eS =nng )Nr   Útr   Úactive)Úagent_tokenÚ	server_idÚstatusúhttps://api.example.comÚxÚ1)Úinstall_tokenÚagent_versionz-https://api.example.com/api/v1/agent/register©ú==©z0%(py2)s
{%(py2)s = %(py0)s.full_url
} == %(py5)sÚreq©Úpy0Úpy2Úpy5úassert %(py7)sÚpy7úX-agent-token©Úis©zP%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get_header
}(%(py4)s)
} is %(py9)s©r>   r?   Úpy4Úpy6Úpy9úassert %(py11)sÚpy11ÚAuthorization©z%(py0)s == %(py3)sÚresp©r>   Úpy3úassert %(py5)sr@   )r)   r-   ÚRealApiClientÚregisterÚfull_urlÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationÚ
get_header)r,   r)   r%   ÚclientrO   r<   Ú@py_assert1Ú@py_assert4Ú@py_assert3Ú@py_format6Ú@py_format8Ú@py_assert5Ú@py_assert8Ú@py_assert7Ú@py_format10Ú@py_format12Ú@py_assert2Ú@py_format4s                     r   Ú0test_register_targets_v1_path_and_no_auth_headerrl   +   sQ  € Ûä Ø S°qÀHÑMó€Hð ×%Ñ%Ð&?Ó@€FØ�?‰?¨SÀ3ÑGÓH€Dà
�1‰+€CØ�<‰<ÐJÐJÐJÐJÑJ×J×J×JÒJˆ<×J×J×J×J×JÕJˆ3×J×J×JÑJˆ3×J×JÕJˆ<×J×JÓJÐJ×J×J×J×J×J×JÓJà�>‰>Ð2˜/Ð2ˆ>˜/Ó*Ð2¨dÐ2¨dÐ2×2×2×2Ò2Ð*×2×2×2×2×2Õ2ˆ3×2×2×2Ñ2ˆ3×2×2Õ2ˆ>×2×2Ó2˜/×2×2Ó2Ð*×2×2Ó2¨d×2×2×2×2×2×2×2Ø�>‰>Ð2˜/Ð2ˆ>˜/Ó*Ð2¨dÐ2¨dÐ2×2×2×2Ò2Ð*×2×2×2×2×2Õ2ˆ3×2×2×2Ñ2ˆ3×2×2Õ2ˆ>×2×2Ó2˜/×2×2Ó2Ð*×2×2Ó2¨d×2×2×2×2×2×2×2à#&°QÀ(ÑKÐKˆ4ÐKÑK×K×K×KÒKˆ4ÐK×K×K×K×K×KÕKˆ4×K×K×KÑKˆ4×K×KÕKÐK×K×K×K×K×K×KÓKr   c                óX  • SS K n[        U 5      nUR                  S5      nUR                  SSS.SS9  US   nUR                  nSoeU:H  ow(       dº  [
        R                  " S	U4S
XV4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=pvUR                  nSou" U5      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      [
        R                  " U
5      [
        R                  " U5      S.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n
=pËUR                  nSou" U5      n
S oºUL 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      [
        R                  " U5      S.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n
=pËg )Nr   r4   r6   Úonline)r8   r3   úsecret-agent-token©Útokenz.https://api.example.com/api/v1/agent/heartbeatr9   r;   r<   r=   rA   rB   rC   )zP%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get_header
}(%(py4)s)
} == %(py9)srG   rK   rL   rM   rD   rF   )r)   r-   rS   Ú	heartbeatrU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   )r,   r)   r%   r_   r<   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   s                  r   Ú(test_heartbeat_uses_x_agent_token_headerrs   =   sæ  € Ûä  Ó-€HØ×%Ñ%Ð&?Ó@€FØ
×Ñ s°hÑ?ÐG[ÐÑ\à
�1‰+€CØ�<‰<ÐKÐKÐKÐKÑK×K×K×KÒKˆ<×K×K×K×K×KÕKˆ3×K×K×KÑKˆ3×K×KÕKˆ<×K×KÓKÐK×K×K×K×K×K×KÓKà�>‰>ÐB˜/ÐBˆ>˜/Ó*ÐBÐ.BÐBÐ.BÑB×B×B×BÒBÐ*×B×B×B×B×BÕBˆ3×B×B×BÑBˆ3×B×BÕBˆ>×B×BÓB˜/×B×BÓBÐ*×B×BÓBÐ.B×B×B×B×B×B×B×BØ�>‰>Ð2˜/Ð2ˆ>˜/Ó*Ð2¨dÐ2¨dÐ2×2×2×2Ò2Ð*×2×2×2×2×2Õ2ˆ3×2×2×2Ñ2ˆ3×2×2Õ2ˆ>×2×2Ó2˜/×2×2Ó2Ð*×2×2Ó2¨d×2×2×2×2×2×2×2Ð2r   c            	     óè  • SSK Jn   U " 5       R                  SS05      nUR                  o"" 5       n[	        U5      n1 SkoTU:H  of(       Gd7  [
        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      [
        R                  " U5      [
        R                  " U5      S
.-  nSSU0-  n[        [
        R                  " U5      5      eS =n=n=n=peSo™U;  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’So™U;  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’g )Nr   )ÚMockApiClientÚhostnameÚh>   r3   r2   r1   r9   )zb%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.keys
}()
})
} == %(py10)sÚsetrO   )r>   Úpy1rQ   r@   rB   Úpy10zassert %(py12)sÚpy12Úagent_id©únot in©z%(py1)s not in %(py3)s©ry   rQ   rR   r@   Úrefresh_token)r)   ru   rT   Úkeysrx   rV   rW   rX   rY   rZ   r[   r\   r]   )ru   rO   rj   ra   Ú@py_assert6Ú@py_assert9rf   Ú@py_format11Ú@py_format13Ú@py_assert0rk   rc   s               r   Ú!test_mock_register_response_shaperˆ   K   s�  € Ý(á‹?×#Ñ# Z°Ð$5Ó6€DØ�y‰yÐEˆy‹{ÐEŒ3ˆ{ÓÐEÒEÐEÐEÑE×E×E×EÓEÐ×E×E×E×E×EÕEŒ3×E×E×EÑEŒ3×E×E×E×E×EÖEˆt×E×E×EÑEˆt×E×EÕEˆy×E×EÓEˆ{×E×EÓEÐ×E×EÓEÐE×E×E×E×E×E×E×EØÐ!˜TÑ!×!×!×!Ò!ˆ:×!×!Ô!ˆ:×!×!×!×!×!Ô!˜T×!×!×!Ñ!˜T×!×!×!×!×!×!Ó!ØÐ& $Ñ&×&×&×&Ò&ˆ?×&×&Ô&ˆ?×&×&×&×&×&Ô& $×&×&×&Ñ& $×&×&×&×&×&×&Ô&r   c                ó*  • UR                  S[        U 5      5        UR                  SS5        SS KnSS KnUR	                  U5        UR                  5       nSSKJnJnJ	n  U" U5        U" USS5        U" U5      nSo˜U	:H  oª(       Gd  [        R                  " SU
4S	X‰4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      [        R                  " U	5      S.-  nSSU0-  n[!        [        R"                  " U5      5      eS =n=p©UR$                  R'                  5       nSoîU;   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èSoîU;  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èg )NÚWOLFPANEL_DEV_HOMEÚWOLFPANEL_API_MOCKr6   r   )Úensure_dirsÚload_agent_tokenÚstore_credentialsÚ42Úwp_agent_token_valuer9   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr�   Úcfg)r>   ry   rQ   rI   zassert %(py8)sÚpy8zWOLFPANEL_SERVER_ID=42)Úin)z%(py1)s in %(py3)sÚ	conf_textr€   rR   r@   r}   r   )ÚsetenvÚstrÚ	importlibÚconfigÚreloadÚload_configÚidentityrŒ   r�   rŽ   rV   rW   rX   rY   rZ   r[   r\   r]   Ú	conf_fileÚ	read_text)Útmp_pathr,   r—   Úconfig_moduler‘   rŒ   r�   rŽ   rj   re   ra   Ú@py_format7Ú@py_format9r”   r‡   rk   rc   s                    r   Ú3test_store_credentials_persists_server_id_and_tokenr¢   T   sÊ  € Ø×ÑÐ+¬S°«]Ô;Ø×ÑÐ+¨SÔ1Ûã"à×Ñ�]Ô#Ø
×
#Ñ
#Ó
%€CçIÑIá�ÔÙ�c˜4Ð!7Ô8á˜CÓ Ð:Ð$:Ð:Ð$:Ñ:×:×:×:Ó:Ð ×:×:×:×:×:Õ:Ð×:×:×:Ñ:Ð×:×:×:×:×:Ö:˜C×:×:×:Ñ:˜C×:×:Õ:Ð ×:×:Ó:Ð$:×:×:×:×:×:×:Ó:Ø—‘×'Ñ'Ó)€IØ#Ð0 yÑ0×0×0×0Ò0Ð#×0×0Ô0Ð#×0×0×0×0×0Ô0 y×0×0×0Ñ0 y×0×0×0×0×0×0Ó0à!Ð2¨Ñ2×2×2×2Ò2Ð!×2×2Ô2Ð!×2×2×2×2×2Ô2¨×2×2×2Ñ2¨×2×2×2×2×2×2Ô2r   c           	     ó\  • SS K n[        U SSS.5      nUR                  S5      nSnUR                  S/ S.U5        UR	                  SS	/ S
.U5        UR                  S/ S.U5        UR                  SS	S.U5        U Vs/ sH  oUR                  PM     nn/ SQovU:H  oˆ(       d¥  [        R                  " SU4SXg45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  n	SSU	0-  n
[        [        R                  " U
5      5      eS =p‡U GHU  nUR                   nSoÈ" U5      oÝU:H  oî(       G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[        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 =n=n=pÞUR                   nSoÈ" U5      nS nUUL oî(       då  [        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      [        R                  " U5      S.-  nSS U0-  n[        [        R                  " U5      5      eS =n=n=n=nnGMX     g s  snf )!Nr   r   Úrunning©Ú
session_idr3   r4   ro   Úfull)Ú	scan_typeÚexpected_categoriesr5   )r¦   ÚcategoryÚitems)r¦   Úsucceeded_categories)r¦   Úerror)z7https://api.example.com/api/v1/agent/discovery/sessionsz4https://api.example.com/api/v1/agent/discovery/itemsz7https://api.example.com/api/v1/agent/discovery/completez5https://api.example.com/api/v1/agent/discovery/failedr9   rN   ÚurlsrP   rR   r@   rC   )zP%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get_header
}(%(py4)s)
} == %(py8)sr<   rq   )r>   r?   rH   rI   r’   zassert %(py10)srz   rM   rD   rF   rG   rK   rL   )r)   r-   rS   Úopen_discovery_sessionÚupload_discovery_itemsÚcomplete_discoveryÚfail_discoveryrU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   )r,   r)   r%   r_   rq   Úrr®   rj   r`   rk   rc   r<   rb   re   rg   r¡   r…   rf   rh   ri   s                       r   Ú/test_discovery_endpoints_use_v1_paths_and_tokenr´   l   sŒ  € Ûä  ¸QÈ)Ñ.TÓU€HØ×%Ñ%Ð&?Ó@€FØ €Eà
×!Ñ!°ÈrÑ"RÐTYÔZØ
×!Ñ!°ÀÈbÑ"QÐSXÔYØ
×Ñ¨QÈÑKÈUÔSØ
×Ñ¨°SÑ9¸5ÔAá (Ó)¡˜1�JŒJ¡€DÐ)òð ð ñ ÷ ó ï
é ôˆ4÷ ò ï
é ÷õ ï
é ðˆ4÷ ö ï
é ðˆ4÷ ò ï
é ðð ÷ ÷ ÷ ñ ï
é ÷õ ô ˆØ�~‰~Ð7˜oÐ7ˆ~˜oÓ.Ð7°%Ñ7×7×7×7Ó7Ð.×7×7×7×7×7Õ7ˆs×7×7×7Ñ7ˆs×7×7Õ7ˆ~×7×7Ó7˜o×7×7Ó7Ð.×7×7×7×7×7Ô7°%×7×7×7Ñ7°%×7×7×7×7×7×7×7Ø�~‰~Ð6˜oÐ6ˆ~˜oÓ.Ð6°$Ð6Ð.°$Ð6×6×6×6Ò6Ð.°$×6×6×6×6×6Õ6ˆs×6×6×6Ñ6ˆs×6×6Õ6ˆ~×6×6Ó6˜o×6×6Ó6Ð.×6×6Ó6°$×6×6×6×6×6×6×6Ó6ò ùò *s   Â N)c                  ó:   • \ rS rSrSrS
S jrS rS rS rS r	Sr
g	)Ú_RecordingClienté„   zJFake ApiClient that records calls; categories in `fail_on` raise ApiError.c                ót   • SSK Jn  X l        [        U5      U l        S U l        / U l        S U l        S U l        g )Nr   )ÚApiError)	r)   r¹   Ú	_ApiErrorrx   Úfail_onÚopenedr«   Ú	completedÚfailed)r   r»   r¹   s      r   Ú__init__Ú_RecordingClient.__init__‡   s1   € Ý'à!ŒÜ˜7“|ˆŒØˆŒØˆŒ
ØˆŒØˆ�r   c                ó   • Xl         SSS.$ )Né   r¤   r¥   )r¼   ©r   Úpayloadrq   s      r   r¯   Ú'_RecordingClient.open_discovery_session‘   s   € ØŒØ¨9Ñ5Ð5r   c                ó¤   • US   U R                   ;   a  U R                  S5      eU R                  R                  U5        S[	        US   5      SS.$ )Nrª   ÚboomrÂ   r«   r   )r¦   ÚacceptedÚ
item_count)r»   rº   r«   r   ÚlenrÃ   s      r   r°   Ú'_RecordingClient.upload_discovery_items•   sL   € Ø�:Ñ $§,¡,Ó.Ø—.‘. Ó(Ð(Ø�
‰
×Ñ˜'Ô"Ø¬S°¸Ñ1AÓ-BÐRSÑTÐTr   c                ó   • Xl         SSSS.$ )NrÂ   r½   r   )r¦   r3   rÉ   )r½   rÃ   s      r   r±   Ú#_RecordingClient.complete_discovery›   s   € Ø ŒØ¨;ÀaÑHÐHr   c                ó   • Xl         SSS.$ )NrÂ   r¾   r¥   )r¾   rÃ   s      r   r²   Ú_RecordingClient.fail_discoveryŸ   s   € ØŒØ¨8Ñ4Ð4r   )rº   r½   r»   r¾   r«   r¼   N)r   )r   r   r   r   Ú__doc__r¿   r¯   r°   r±   r²   r   r   r   r   r¶   r¶   „   s    † ÙTôò6òUòIõ5r   r¶   c                 ó*  • SSK Jn Jn  SS0SS0SS0/SS	/S
.n[        5       nU" S USU " U5      SS9nUR                  S   nS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R                  S   n/ SQ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=pv[        S UR                   5       5      n
U
S   nSS0SS	0/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: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R                  S   n[        U5      n/ SQoÆU:H  oÝ(       d×  [
        R                  " SU4SXl4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R                  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 )"Nr   )Úcategories_from_inventoryÚupload_inventoryrv   rw   ÚnameÚaÚbé   éP   )Úserver_factsÚ	databasesÚ
open_portsr§   r/   rp   r¨   r9   ©z%(py1)s == %(py4)s©ry   rH   úassert %(py6)srI   r©   )rÚ   rÛ   rÙ   c              3  ó8   #   • U H  oS    S:X  d  M  Uv •  M     g7f)rª   rÛ   Nr   )Ú.0Úps     r   Ú	<genexpr>ÚAtest_upload_inventory_drives_full_session_flow.<locals>.<genexpr>´   s   é € ÐJ™L�q¨j©M¸\Ñ,I—‘šLùs   ‚‘	r«   Úvaluer3   r½   r¬   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sÚsorted)r>   r?   rH   rB   zassert %(py9)srJ   Úfailed_categories)Údiscovery.uploadrÒ   rÓ   r¶   r¼   rV   rW   r[   r\   r]   Únextr«   r½   rå   rX   rY   rZ   )rÒ   rÓ   Ú	inventoryr_   Úresultr‡   rb   rj   Ú@py_format5r    Úportsr`   rƒ   re   rd   rh   s                   r   Ú.test_upload_inventory_drives_full_session_flowrí   ¤   s
  € ßLð $ SÐ)Ø˜s�m f¨c ]Ð3Ø˜2�hñ€Iô
 Ó€FÙØˆf�fÑ7¸	ÓBÈ#ñ€Fð �=‰=˜Ñ%Ð/¨Ð/¨Ñ/×/×/×/Ò/Ð%×/×/Ô/Ð%×/×/Ó/¨×/×/×/×/×/×/Ó/Ø�=‰=Ð.Ñ/Ð^Ò3^Ð^Ð3^Ñ^×^×^×^Ò^Ð/×^×^Ô^Ð/×^×^Ó^Ð3^×^×^×^×^×^×^Ó^äÑJ˜FŸLšLÓJÓJ€EØ�‰>Ð;˜w¨˜m¨g°r¨]Ð;Ð;Ð;Ñ;×;×;×;Ò;ˆ>×;×;Ô;ˆ>×;×;Ó;Ð;×;×;×;×;×;×;Ó;Ø�(ÑÐ*˜{Ð*˜{Ñ*×*×*×*Ò*Ð×*×*Ô*Ð×*×*Ó*˜{×*×*×*×*×*×*Ó*Ø×"Ñ"Ð#9Ñ:ð Œ6Ð:Ó;ð ò @ð ð @ñ ÷ ó ïé ôÐ;÷ ò ïé ÷õ ïé ðŒ6÷ ö ïé ðŒ6÷ ò ïé ðÐ:÷ ð ïé ðÐ;÷ ð ïé ðð @÷ ÷ ÷ ñ ïé ÷÷ ñ ð ×ÑÐ/Ñ0Ð6°BÐ6°BÑ6×6×6×6Ò6Ð0×6×6Ô6Ð0×6×6Ó6°B×6×6×6×6×6×6Ô6r   c                 ó:  • SSK Jn   [        S1S9nSS0/SS0/S	.nU " S US
USS9  UR                  nS oCUL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                  S   nS/oXU: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                  S   nS/oXU: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 )Nr   ©rÓ   rÚ   ©r»   Údocrootú/arÔ   r5   )ÚwebsitesrÚ   r§   r/   rp   ©úis not)z5%(py2)s
{%(py2)s = %(py0)s.completed
} is not %(py5)sr_   r=   rA   rB   r¬   ró   r9   rÜ   rÝ   rÞ   rI   ræ   )rç   rÓ   r¶   r½   rV   rW   rX   rY   rZ   r[   r\   r]   )rÓ   r_   Ú
categoriesr`   ra   rb   rc   rd   r‡   rj   rë   r    s               r   Ú-test_upload_inventory_reports_failed_categoryr÷   ½   s^  € Ý1ä { mÑ4€FØ )¨4Ð0Ð1À&È#ÀÀÑP€JÙ�T˜6 6¨:¸SÒAà×ÑÐ' 4Ð' 4Ð'×'×'×'Ò'Ð×'×'×'×'×'Õ'ˆ6×'×'×'Ñ'ˆ6×'×'Õ'Ð×'×'Ó' 4×'×'×'×'×'×'Ó'Ø×ÑÐ2Ñ3ÐC¸
°|ÐC°|ÑC×C×C×CÒCÐ3×C×CÔCÐ3×C×CÓC°|×C×C×C×C×C×CÓCØ×ÑÐ/Ñ0ÐA°[°MÐA°MÑA×A×A×AÒAÐ0×A×AÔAÐ0×A×AÓA°M×A×A×A×A×A×AÔAr   c                 ó¸  • SSK Jn   [        S1S9nU " S USSSS0/0SS	9  UR                  nS o2UL oD(       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=pCUR                  nS o2ULoD(       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=pCUR                  S   nSoGU:H  oˆ(       do  [        R
                  " SU4SXt45      [        R                  " U5      [        R                  " U5      S.-  n	SSU	0-  n
[        [        R                  " U
5      5      eS =n=p„g )Nr   rï   ró   rð   r§   rñ   rò   r/   rp   rD   )z1%(py2)s
{%(py2)s = %(py0)s.completed
} is %(py5)sr_   r=   rA   rB   rô   )z2%(py2)s
{%(py2)s = %(py0)s.failed
} is not %(py5)sr¦   rÂ   r9   rÜ   rÝ   rÞ   rI   )rç   rÓ   r¶   r½   rV   rW   rX   rY   rZ   r[   r\   r]   r¾   )rÓ   r_   r`   ra   rb   rc   rd   r‡   rj   rë   r    s              r   Ú9test_upload_inventory_fails_session_when_nothing_succeedsrù   É   sg  € Ý1ä z lÑ3€FÙ�T˜6 6¨J¸)ÀTÐ9JÐ8KÐ+LÐTWÒXð ×ÑÐ#˜tÐ#˜tÐ#×#×#×#Ò#Ð×#×#×#×#×#Õ#ˆ6×#×#×#Ñ#ˆ6×#×#Õ#Ð×#×#Ó#˜t×#×#×#×#×#×#Ó#Ø�=‰=Ð$ Ð$ Ð$×$×$×$Ò$ˆ=×$×$×$×$×$Õ$ˆ6×$×$×$Ñ$ˆ6×$×$Õ$ˆ=×$×$Ó$ ×$×$×$×$×$×$Ó$Ø�=‰=˜Ñ&Ð+¨!Ð+¨!Ñ+×+×+×+Ò+Ð&×+×+Ô+Ð&×+×+Ó+¨!×+×+×+×+×+×+Ô+r   c                  ó0   • \ rS rSrSrS rS rS rS rSr	g)	Ú_MiniMonkeypatchéÕ   z?Minimal monkeypatch for running this file directly (no pytest).c                ó   • / U l         g r   ©Ú_undor   s    r   r¿   Ú_MiniMonkeypatch.__init__Ø   s	   € Øˆ�
r   c                óh   • U R                   R                  X[        X5      45        [        XU5        g r   )rÿ   r   Úgetattrr*   )r   ÚobjrÔ   rä   s       r   r*   Ú_MiniMonkeypatch.setattrÛ   s(   € Ø�
‰
×Ñ˜3¤g¨cÓ&8Ð9Ô:Ü�˜5Õ!r   c                ó”   • SS K nU R                  R                  SXR                  R	                  U5      45        X#R                  U'   g ©Nr   Úenv)Úosrÿ   r   ÚenvironÚget)r   rÔ   rä   r  s       r   r•   Ú_MiniMonkeypatch.setenvß   s5   € Ûà�
‰
×Ñ˜5 $¯
©
¯©°tÓ(<Ð=Ô>Ø �
‰
�4Òr   c                ó  • SS K n[        U R                  5       HI  u  p#nUS:X  a1  Uc  UR                  R	                  US 5        M-  XAR                  U'   M=  [        X#U5        MK     U R                  R                  5         g r  )r  Úreversedrÿ   r	  Úpopr*   Úclear)r   r  r  rÔ   Úolds        r   ÚundoÚ_MiniMonkeypatch.undoå   sb   € Ûä& t§z¡zÖ2‰NˆC�sØ�e‹|Ø‘;Ø—J‘J—N‘N 4¨Ö.à'*—J‘J˜tÓ$ä˜ 3Ö'ñ 3ð 	�
‰
×ÑÕr   rþ   N)
r   r   r   r   rÐ   r¿   r*   r•   r  r   r   r   r   rû   rû   Õ   s   † ÙIòò"ò!õr   rû   Ú__main__c              #  óZ   #   • U H"  u  pUR                  S 5      (       d  M  X4v •  M$     g7f)Útest_N)Ú
startswith)rà   ÚkÚvs      r   râ   râ   ø   s%   é € ð Ù2‘4�1°a·l±lÀ7×6K‹ˆ�Ò2ùs   ‚+¡
+r,   rž   zPASS zFAIL r   )r$   zdict | Noner   )7rÐ   Ú
__future__r   ÚbuiltinsrX   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterV   Úior   ÚsysÚpathlibr   ÚpathÚinsertr–   Ú__file__ÚresolveÚparentsÚBytesIOr   r-   rl   rs   rˆ   r¢   r´   r¶   rí   r÷   rù   rû   r   ÚtempfileÚ	tracebackÚfailuresrå   ÚdictÚglobalsr«   ÚfnameÚfuncÚmpÚ__code__Úco_varnamesÚco_argcountÚparamsÚkwargsÚmkdtempÚprintÚ	ExceptionÚ	print_excr  Úexitr   r   r   Ú<module>r9     sË  ðñõ #ç  „ ƒ	Û Û 
Ý à ‡�‡��‘3‘t˜H“~×-Ñ-Ó/×7Ñ7¸Ñ:¸UÑBÓCÔ Dô�B—J‘Jô öòLò$3ò'ò3ò07÷05ñ 5ò@7ò2	Bò	,÷ñ ð< ˆzÓÛÛà€HÙñ Ù¡£	›?×0Ñ0Ô2óö ‰ˆˆtñ ÓˆØ—‘×*Ñ*Ð+F¨T¯]©]×-FÑ-FÐGˆØˆØ˜FÓ"Ø$&ˆF�=Ñ!Ø˜ÓÙ!% h×&6Ò&6Ó&8Ó!9ˆF�:Ñð	Ù‰N�6ŠNÙ�E˜%˜�/Ô"ð �G‰GŽIñ%ð& ‡H‚H–(‰Q Õ"ð1 øð$ ó 	"Ø˜‰MˆHÙ�E˜%˜�/Ô"Ø×ÒÖ!ð	"ûð
 �G‰G�Iús$   ÅFÆ'GÇGÇGÇGÇG