
    iM                        d Z ddlZddlmc mZ ddlZddlm	Z	 ddl
mZmZ  e	e      j                  j                  ZddlZedz  Zej&                  j)                  de      ZdZeeuZes ej0                  defdeef      d	 ej2                         v s ej4                  e      r ej6                  e      nd	 ej6                  e      d
z  Zddeiz  Z e ej>                  e            dxZZej&                  jA                  e      Z!ejD                  ZdZ#ee#uZ$e$s ej0                  de$fdee#f      d	 ej2                         v s ej4                  e      r ej6                  e      nd	 ej6                  e       ej6                  e#      dz  Zddeiz  Z% e ej>                  e%            dxZxZ$Z#ejD                  jM                  e!        G d d      Z' G d d      Z( G d d      Z)y)u/  
test_done_protocol.py

.done 프로토콜 수정 검증 테스트 (task-616.1 설계 반영)

테스트 항목:
- log_protocol() 단위 테스트
- 통합 테스트 시나리오 (새 설계: send_telegram_notification 기반)
- done-watcher 로직 시뮬레이션 (새 설계: escalation/acked 기반)
    N)Path)	MagicMockpatchnotify-completion.pynotify_completion)is not)z%(py0)s is not %(py3)sspecpy0py3assert %(py5)spy5)z2%(py2)s
{%(py2)s = %(py0)s.loader
} is not %(py5)sr   py2r   zassert %(py7)spy7c                   @    e Zd ZdZdeddfdZdeddfdZdeddfdZy)TestLogProtocolu&   log_protocol() 함수 단위 테스트tmp_pathreturnNc                 N   |dz  }|j                   } |       }| }|sddt        j                         v st        j                  |      rt        j
                  |      ndt        j
                  |      t        j
                  |      dz  }t        t        j                  |            dx}x}}t        j                  t        dt        |            5  t        j                  dd       ddd       |j                   } |       }|sd	dt        j                         v st        j                  |      rt        j
                  |      ndt        j
                  |      t        j
                  |      dz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)
u   로그 파일 자동 생성done-protocol.logzEassert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}log_pathr   r   py4NDONE_PROTOCOL_LOGz
task-010.1ztest messagezAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
})exists@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationr   objectr   strlog_protocol)selfr   r   @py_assert1@py_assert3@py_assert5@py_format6@py_format5s           Q/home/jay/workspace/.worktrees/task-2374-dev7/scripts/tests/test_done_protocol.pytest_creates_log_filez%TestLogProtocol.test_creates_log_file!   s	   11??$?$$$$$$$$$$$8$$$8$$$?$$$$$$$$$$\\+-@#h-P 	I**<H	I         x   x             	I 	Is   FF$c                    |dz  }t        j                  t        dt        |            5  t        j	                  dd       ddd       |j                  d      }d}||v }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}|j                         }|j                  }	d}
 |	|
      }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |
      t        j                  |      dz  }t        t        j                  |            dx}	x}
}d}||v }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)u5   [ISO8601] [notify-completion] task_id: message 포맷r   r   z
task-011.1u   상태 전이 완료Nutf-8encodingz[notify-completion]inz%(py1)s in %(py3)scontentpy1r   r   r   [zLassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}line)r   r   r   py6u6   ] [notify-completion] task-011.1: 상태 전이 완료)r   r$   r   r%   r&   	read_textr   _call_reprcomparer!   r   r   r    r"   r#   strip
startswith)r'   r   r   r6   @py_assert0@py_assert2@py_format4r+   r:   r(   r)   r*   @py_format7s                r-   test_log_formatzTestLogProtocol.test_log_format)   sD   11\\+-@#h-P 	Q**<9OP	Q$$g$6$/$////$///$////////////////&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&%0%0000%000%0000000000000000}}#s#s########t###t######s##########GOG4OOOOG4OOOGOOOOOO4OOO4OOOOOOO	Q 	Qs   N??O	c                    |dz  }|j                  dd       t        j                  t        dt	        |            5  t        j                  dd       ddd       |j                  d      }d	}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}|j                         D cg c]  }|j!                         s| }	}t#        |	      }d}
||
k(  }|st        j                  d|fd||
f      dt        j                         v st        j                  t"              rt        j                  t"              nddt        j                         v st        j                  |	      rt        j                  |	      ndt        j                  |      t        j                  |
      dz  }dd|iz  }t        t        j                  |            dx}x}}
y# 1 sw Y   xY wc c}w )u.   기존 로그에 추가 (덮어쓰기 안 함)r   u   [기존 로그 항목]
r0   r1   r   z
task-012.1u
   새 항목Nu   [기존 로그 항목]r3   r5   r6   r7   r   r      ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenlinesr   r8   r   r;   zassert %(py8)spy8)
write_textr   r$   r   r%   r&   r<   r   r=   r!   r   r   r    r"   r#   
splitlinesr>   rI   )r'   r   r   r6   r@   rA   rB   r+   lrJ   r*   @py_assert4rC   @py_format9s                 r-   test_appends_to_existing_logz,TestLogProtocol.test_appends_to_existing_log8   s   116I\\+-@#h-P 	G**<F	G$$g$6'2'72222'7222'222222722272222222&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&#..0>qAGGI>>5zQzQzQss55zQ	G 	G
 ?s   K7
L L7L)__name__
__module____qualname____doc__r   r.   rD   rR        r-   r   r      sA    0!d !t !P P P
T 
d 
rX   r   c                       e Zd ZdZ ed      dededdfd       Z ed      dededdfd       Zdeddfd	Z	 ed      dededdfd
       Z
 ed      dededdfd       Z ed      dededdfd       Zy)TestDoneProtocolIntegrationuA   통합 테스트 시나리오 (새 설계: .done.notified 없음)subprocess.runmock_runr   r   Nc           	      2   dt         dt         dt         dt        fd}||_        |dz  dz  j                  dd	       t	        d
ddg      5  t	        j
                  dddd      5  t	        j                   t        dt        |            5  t	        j                   t        dd      5 }t        j                          ddd       ddd       ddd       ddd       j                  }d}||k\  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j&                  d   d   dd \  }
}d}||v }|st        j                  d |fd!||f      t        j                  |      d"t        j                         v st        j                  |      rt        j                  |      nd"d#z  }t        j                   d$      d%z   d&|iz  }t#        t        j$                  |            dx}}d'}||v }|st        j                  d |fd!||f      t        j                  |      d"t        j                         v st        j                  |      rt        j                  |      nd"d#z  }t        j                   d(      d%z   d&|iz  }t#        t        j$                  |            dx}}d)}||v}|st        j                  d*|fd+||f      t        j                  |      d"t        j                         v st        j                  |      rt        j                  |      nd"d#z  }d,d&|iz  }t#        t        j$                  |            dx}}d-}||v}|st        j                  d*|fd+||f      t        j                  |      d"t        j                         v st        j                  |      rt        j                  |      nd"d#z  }d,d&|iz  }t#        t        j$                  |            dx}}|dz  dz  }d.}||z  }|j(                  } |       }| }|sd/d0t        j                         v st        j                  |      rt        j                  |      nd0t        j                  |      t        j                  |      t        j                  |      d1z  }t#        t        j$                  |            dx}x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)2u3   정상 플로우: send_telegram_notification 호출cmd_args_kwargsr   c                 P   ~~t               }d|_        d|_        t        | t              r_dj                  d | D              }d|v r%d|v r!t        j                  ddd d d      |_        |S t        j                  d	d
i      |_        |S t        j                  d	d
i      |_        |S )Nr     c              3   2   K   | ]  }t        |        y wNr%   .0cs     r-   	<genexpr>zhTestDoneProtocolIntegration.test_normal_flow_sends_telegram_only.<locals>.side_effect.<locals>.<genexpr>R        "7a3q6"7   chain_manager.pycheckFin_chainis_lastchain_idnext_task_idstatusok	r   
returncodestderr
isinstancelistjoinjsondumpsstdoutr^   r_   r`   resultcmd_strs        r-   side_effectzUTestDoneProtocolIntegration.test_normal_flow_sends_telegram_only.<locals>.side_effectL       w[F !FFM#t$(("73"77%0W5G$(JJ%*u$`de%FM M %)JJ$/?$@FM M !%

Hd+; <MrX   memoryeventsTparentsexist_oksys.argvr   z
task-030.1
os.environtest-keytest-bot-tokenCOKACDIR_KEY_ANUANU_BOT_TOKENWORKSPACE_ROOTsend_telegram_notificationFreturn_valueN   >=z2%(py2)s
{%(py2)s = %(py0)s.call_count
} >= %(py5)s	mock_sendr   u1   send_telegram_notification이 호출되어야 함
>assert %(py7)sr   r   rF   r3   r5   message_argr7   u   메시지에 task_id 포함
>assert %(py5)sr      완료u   메시지에 '완료' 포함
done.clearnot inz%(py1)s not in %(py3)sr   done.notifiedztask-030.1.done.notifiedzQassert not %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = (%(py0)s / %(py2)s).exists
}()
}
events_dirr   r   r   r   )r$   r   r   mkdirr   dictr   r%   main
call_countr   r=   r   r   r    r!   _format_assertmsgr"   r#   call_args_listr   )r'   r\   r   r   r   r(   rP   r)   r+   @py_format8_r   r@   rA   rB   r   @py_assert6@py_assert8rQ   s                      r-   $test_normal_flow_sends_telegram_onlyz@TestDoneProtocolIntegration.test_normal_flow_sends_telegram_onlyH   s   	V 	V 	 	9 	"  +	H	x	'..td.K *5|DE	%JJ|*Wg%hi	% LL*,<c(mL	% LL*,HW\]		% bk""$	% 	% 	% 	% ##]q]#q(]]]#q]]]]]]y]]]y]]]#]]]q]]]*]]]]]]]] #11!4Q7;;I|{*III|{III|IIIIII{III{IIII,IIIIIIIFx;&FFFx;FFFxFFFFFF;FFF;FFFF(FFFFFFF.|;....|;...|......;...;.......1k1111k111111111k111k1111111 (83
!;EJ!;;E;CCECEEEEEEEEEEEJEEEJEEE!;EEECEEEEEEEEEEE+	% 	% 	% 	% 	% 	% 	% 	%sT   V%%U?
U2'U%	<U2U?V%U/*U22U<7U??V		VVc           	         dt         dt         dt         dt        fd}||_        |dz  dz  j                  dd	       t	        d
ddg      5  t	        j
                  dddd      5  t	        j                   t        dt        |            5  t	        j                   t        dd      5 }t        j                          ddd       ddd       ddd       ddd       |dz  dz  }d}||z  }|j                  } |       }	|	 }
|
st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |	      dz  }t!        t        j"                  |            dx}x}x}x}	}
|j$                  D cg c]2  }t'        |d   d   t(              rt+        d |d   d   D              r|4 }}t-        |      }d}||k\  }|st        j.                  d|fd||f      d t        j                         v st        j                  t,              rt        j                  t,              nd d!t        j                         v st        j                  |      rt        j                  |      nd!t        j                  |      t        j                  |      d"z  }t        j                  d#      d$z   d%|iz  }t!        t        j"                  |            dx}x}}j0                  }d}||k\  }|st        j.                  d|fd&||f      d't        j                         v st        j                  |      rt        j                  |      nd't        j                  |      t        j                  |      d(z  }t        j                  d)      d*z   d+|iz  }t!        t        j"                  |            dx}x}}y# 1 sw Y   WxY w# 1 sw Y   \xY w# 1 sw Y   axY w# 1 sw Y   fxY wc c}w ),uW   체인 중간: dispatch.py 호출, 텔레그램 알림 전송, .done.notified 미생성r^   r_   r`   r   c                    ~~t               }d|_        d|_        t        | t              rdj                  d | D              }d|v r%d|v r!t        j                  ddd	d
d      |_        |S d|v r%d|v r!t        j                  dddd
d      |_        |S t        j                  ddi      |_        |S t        j                  ddi      |_        |S )Nr   rb   rc   c              3   2   K   | ]  }t        |        y wre   rf   rg   s     r-   rj   zsTestDoneProtocolIntegration.test_chain_middle_dispatches_and_sends_telegram.<locals>.side_effect.<locals>.<genexpr>   rk   rl   rm   rn   TFz	chain-031z
task-031.2ro   nextdispatchzmemory/tasks/task-031.2.mdz	dev1-team)action	task_fileteamtask_idrt   ru   rv   r   s        r-   r   z`TestDoneProtocolIntegration.test_chain_middle_dispatches_and_sends_telegram.<locals>.side_effect{   s    w[F !FFM#t$(("73"77%0W5G$(JJ(,',(3,8	%FM* M (72v7H$(JJ&0)E$/'3	%FM M %)JJ$/?$@FM M !%

Hd+; <MrX   r   r   Tr   r   r   z
task-031.1r   r   r   r   r   r   Fr   Nztask-031.1.done.notifiedu0   체인 중간에서 .done.notified 생성 금지S
>assert not %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = (%(py0)s / %(py2)s).exists
}()
}r   r   r   c              3   6   K   | ]  }d t        |      v   yw)zdispatch.pyNrf   )rh   xs     r-   rj   z^TestDoneProtocolIntegration.test_chain_middle_dispatches_and_sends_telegram.<locals>.<genexpr>   s     0ZQ#a&1H0Zs   r   r   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)srI   dispatch_callsrK   u#   dispatch.py 호출이 있어야 함z
>assert %(py8)srL   r   r   r   uA   체인 중간에서도 텔레그램 알림이 전송되어야 함r   r   )r$   r   r   r   r   r   r   r%   r   r   r   r   r   r   r    r!   r"   r#   r   ry   rz   anyrI   r=   r   )r'   r\   r   r   r   r   r(   r)   rP   r   r   rQ   ri   r   rA   r*   rC   r+   r   s                      r-   /test_chain_middle_dispatches_and_sends_telegramzKTestDoneProtocolIntegration.test_chain_middle_dispatches_and_sends_telegramw   s   	V 	V 	 	9 	>  +	H	x	'..td.K *5|DE	%JJ|*Wg%hi	% LL*,<c(mL	% LL*,HW\]		% bk""$	% 	% 	% 	% (83
 "<yJ!;;y;CCyCEyEEyEyyGyyyyyyyJyyyJyyy!;yyyCyyyEyyyyyyy  ..
!A$q'4(S0ZRSTURVWXRY0Z-Z 
 
 >"NaN"a'NNN"aNNNNNNsNNNsNNNNNN>NNN>NNN"NNNaNNN)NNNNNNNN ##mqm#q(mmm#qmmmmmmymmmymmm#mmmqmmm*mmmmmmmm+	% 	% 	% 	% 	% 	% 	% 	%
sZ   P8%%P+
P'P	<PP+P87QPPP(#P++P5	0P88Qc           
         dt         dt         dt         dt        fd}|dz  dz  }|j                  dd	       |d
z  }|j                  t	        j
                  ddd      d       t        d|      5  t        dddg      5  t        j                  dddi      5  t        j                   t        dt        |            5  t        j                          ddd       ddd       ddd       ddd       |j                  } |       }|st        j                  d      dz   dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }t%        t        j&                  |            dx}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u8   .done 파일은 notification 후에도 events/에 유지r^   r_   r`   r   c                 P   ~~t               }d|_        d|_        t        | t              r_dj                  d | D              }d|v r%d|v r!t        j                  ddd d d      |_        |S t        j                  d	d
i      |_        |S t        j                  d	d
i      |_        |S )Nr   rb   rc   c              3   2   K   | ]  }t        |        y wre   rf   rg   s     r-   rj   zhTestDoneProtocolIntegration.test_done_file_survives_notification.<locals>.side_effect.<locals>.<genexpr>   rk   rl   rm   rn   Fro   rt   ru   rv   r   s        r-   r   zUTestDoneProtocolIntegration.test_done_file_survives_notification.<locals>.side_effect   r   rX   r   r   Tr   ztask-033.1.donez
task-033.1	completedr   rt   r0   r1   r[   )r   r   r   r   r   r   r   NuE   .done 파일이 notification 후에도 events/에 유지되어야 함C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}	done_pathr   )r$   r   r   rM   r|   r}   r   r   r   r%   r   r   r   r   r   r   r    r!   r"   r#   )r'   r   r   r   r   r(   r)   r,   s           r-   $test_done_file_survives_notificationz@TestDoneProtocolIntegration.test_done_file_survives_notification   s   	V 	V 	 	9 	" (83
5!22	JJ<;GH 	 	
 "<	%*5|DE	% JJ|&8*%EF	% LL*,<c(mL		% ""$	% 	% 	% 	% j!j!jj#jjjjjjjyjjjyjjjjjj!jjjjjj	% 	% 	% 	% 	% 	% 	% 	%sT   3GG
%F> F2	F>G
%G2F;7F>>GG

G	GGc           	         dt         dt         dt         dt        fd}||_        |dz  dz  }|j                  dd	       |d
z  }t	        j
                  ddd      }|j                  |d       t        dddg      5  t        j                  dddi      5  t        j                   t        dt        |            5  t        j                          ddd       ddd       ddd       |j                  } |       }|st        j                  d      dz   dt        j                          v st        j"                  |      rt        j$                  |      ndt        j$                  |      t        j$                  |      dz  }	t'        t        j(                  |	            dx}}|j*                  }d} ||      }
|
|k(  }|st        j,                  d|fd|
|f      dt        j                          v st        j"                  |      rt        j$                  |      ndt        j$                  |      t        j$                  |      t        j$                  |
      dt        j                          v st        j"                  |      rt        j$                  |      nddz  }t        j                  d      d z   d!|iz  }t'        t        j(                  |            dx}x}x}
}d"}||z  }|j                  } |       }| }|st        j                  d#      d$z   d%t        j                          v st        j"                  |      rt        j$                  |      nd%t        j$                  |      t        j$                  |      t        j$                  |      d&z  }t'        t        j(                  |            dx}x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y    xY w)'u4   .done 파일이 rename/삭제되지 않는지 확인r^   r_   r`   r   c                 P   ~~t               }d|_        d|_        t        | t              r_dj                  d | D              }d|v r%d|v r!t        j                  ddd d d      |_        |S t        j                  d	d
i      |_        |S t        j                  d	d
i      |_        |S )Nr   rb   rc   c              3   2   K   | ]  }t        |        y wre   rf   rg   s     r-   rj   zrTestDoneProtocolIntegration.test_done_file_not_modified_after_notification.<locals>.side_effect.<locals>.<genexpr>   rk   rl   rm   rn   Fro   rt   ru   rv   r   s        r-   r   z_TestDoneProtocolIntegration.test_done_file_not_modified_after_notification.<locals>.side_effect   r   rX   r   r   Tr   ztask-034.1.donez
task-034.1r   r   r0   r1   r   r   r   r   r   r   Nu$   .done 파일이 삭제되면 안 됨r   r   r   rG   )zX%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.read_text
}(encoding=%(py4)s)
} == %(py8)soriginal_content)r   r   r   r;   rL   u+   .done 파일 내용이 변경되면 안 됨z
>assert %(py10)spy10ztask-034.1.done.clearu*   .done.clear 파일이 생성되면 안 됨r   r   r   )r$   r   r   r   r|   r}   rM   r   r   r   r%   r   r   r   r   r   r   r    r!   r"   r#   r<   r=   )r'   r\   r   r   r   r   r   r(   r)   r,   r*   @py_assert7rQ   @py_format11rP   r   r   s                    r-   .test_done_file_not_modified_after_notificationzJTestDoneProtocolIntegration.test_done_file_not_modified_after_notification   s   	V 	V 	 	9 	"  +(83
5!22	::,+&VW-@ *5|DE	%JJ|&8*%EF	% LL*,<c(mL	%
 ""$	% 	% 	% I!I!II#IIIIIIIyIIIyIIIIII!IIIIII""wGw"G4w48HHwww48Hwwwwwwywwwywww"wwwGwww4wwwwww8Hwww8HwwwwJwwwwwwww!8pJ!88p8@@p@BpBBpBppDpppppppJpppJppp!8ppp@pppBppppppp	% 	% 	% 	% 	% 	%s<   =O%O;OOOO	OO	OO(c           	      |   dt         dt         dt         dt        fd}||_        |dz  dz  }|j                  dd	       t	        d
ddg      5  t	        j
                  dddi      5  t	        j                   t        dt        |            5  t        j                          ddd       ddd       ddd       d}||z  }|j                  } |       }| }	|	st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }
t!        t        j"                  |
            dx}x}x}x}}	y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u=   .done.notified 파일이 절대 생성되지 않는지 확인r^   r_   r`   r   c                 P   ~~t               }d|_        d|_        t        | t              r_dj                  d | D              }d|v r%d|v r!t        j                  ddd d d      |_        |S t        j                  d	d
i      |_        |S t        j                  d	d
i      |_        |S )Nr   rb   rc   c              3   2   K   | ]  }t        |        y wre   rf   rg   s     r-   rj   zaTestDoneProtocolIntegration.test_no_done_notified_created.<locals>.side_effect.<locals>.<genexpr>  rk   rl   rm   rn   Fro   rt   ru   rv   r   s        r-   r   zNTestDoneProtocolIntegration.test_no_done_notified_created.<locals>.side_effect
  r   rX   r   r   Tr   r   r   z
task-035.1r   r   r   r   Nztask-035.1.done.notifiedu-   .done.notified 파일이 생성되면 안 됨r   r   r   )r$   r   r   r   r   r   r   r%   r   r   r   r   r   r   r    r!   r"   r#   )r'   r\   r   r   r   r(   r)   rP   r   r   rQ   s              r-   test_no_done_notified_createdz9TestDoneProtocolIntegration.test_no_done_notified_created  so   	V 	V 	 	9 	"  +(83
5 *5|DE	%JJ|&8*%EF	% LL*,<c(mL	%
 ""$	% 	% 	% "<vJ!;;v;CCvCEvEEvEvvGvvvvvvvJvvvJvvv!;vvvCvvvEvvvvvvv	% 	% 	% 	% 	% 	%s<   F1&%F%F F%(F1F"F%%F.	*F11F;c           	      
   dt         dt         dt         dt        fd}||_        |dz  dz  }|j                  dd	       t	        d
ddg      5  t	        j
                  dddd      5  t	        j                   t        dt        |            5  t	        j                   t        dd      5 }t        j                          ddd       ddd       ddd       ddd       j                  }d}||k\  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        j                   d      dz   d|	iz  }
t#        t        j$                  |
            dx}x}}|j&                  d   d   dd \  }}d}||v }|st        j                  d|fd ||f      t        j                  |      d!t        j                         v st        j                  |      rt        j                  |      nd!d"z  }t        j                   d#|       d$z   d%|iz  }	t#        t        j$                  |	            dx}}d&}||v }|st        j                  d|fd ||f      t        j                  |      d!t        j                         v st        j                  |      rt        j                  |      nd!d"z  }t        j                   d'|       d$z   d%|iz  }	t#        t        j$                  |	            dx}}d(}||v}|st        j                  d)|fd*||f      t        j                  |      d!t        j                         v st        j                  |      rt        j                  |      nd!d"z  }t        j                   d+|       d$z   d%|iz  }	t#        t        j$                  |	            dx}}d,}||v}|st        j                  d)|fd*||f      t        j                  |      d!t        j                         v st        j                  |      rt        j                  |      nd!d"z  }t        j                   d-|       d$z   d%|iz  }	t#        t        j$                  |	            dx}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y    xY w).u_   독립 작업에서 send_telegram_notification이 호출되고 구형 프롬프트가 없는지r^   r_   r`   r   c                 P   ~~t               }d|_        d|_        t        | t              r_dj                  d | D              }d|v r%d|v r!t        j                  ddd d d      |_        |S t        j                  d	d
i      |_        |S t        j                  d	d
i      |_        |S )Nr   rb   rc   c              3   2   K   | ]  }t        |        y wre   rf   rg   s     r-   rj   zqTestDoneProtocolIntegration.test_independent_task_sends_telegram_not_wake.<locals>.side_effect.<locals>.<genexpr>4  rk   rl   rm   rn   Fro   rt   ru   rv   r   s        r-   r   z^TestDoneProtocolIntegration.test_independent_task_sends_telegram_not_wake.<locals>.side_effect.  r   rX   r   r   Tr   r   r   z
task-036.1r   r   r   r   r   r   r   Nr   r   r   r   r   uE   독립 작업에서 send_telegram_notification이 호출되어야 함r   r   r   rF   r3   r5   r   r7   u    메시지에 task_id가 없음: r   r   r   u!   메시지에 '완료'가 없음: r   r   r   u3   wake_anu_session 구형 프롬프트가 전송됨: r   u-   done.notified 참조 메시지가 전송됨: )r$   r   r   r   r   r   r   r%   r   r   r   r=   r   r   r    r!   r   r"   r#   r   )r'   r\   r   r   r   r   r(   rP   r)   r+   r   r   r   r@   rA   rB   s                   r-   -test_independent_task_sends_telegram_not_wakezITestDoneProtocolIntegration.test_independent_task_sends_telegram_not_wake*  sa   	V 	V 	 	9 	"  +(83
5 *5|DE	%JJ|*Wg%hi	% LL*,<c(mL	% LL*,HW[\		% aj""$	% 	% 	% 	% ##qqq#q(qqq#qqqqqqqyqqqyqqq#qqqqqqq*qqqqqqqq #11!4Q7;;\|{*\\\|{\\\|\\\\\\{\\\{\\\\.N{m,\\\\\\\Yx;&YYYx;YYYxYYYYYY;YYY;YYYY*KK=(YYYYYYY s|;.sss|;sss|ssssss;sss;ssss2efqer0ssssssspk1pppkpppppppppkpppkpppp5bcnbo3ppppppp%	% 	% 	% 	% 	% 	% 	% 	%sT   S4'%S'S)S	>SS'S4SSS$S''S1	,S44S>)rS   rT   rU   rV   r   r   r   r   r   r   r   r   r   rW   rX   r-   rZ   rZ   E   s+   K
,FY ,FRV ,F[_ ,F ,F\ :n	 :n]a :nfj :n :nx%kT %kd %kN (qy (q\` (qei (q (qT !wi !w4 !wTX !w !wF +qi +q[_ +qdh +q +qrX   rZ   c                       e Zd ZdZ	 ddededededef
dZdededed	edef
d
Z	deddfdZ
deddfdZdeddfdZdeddfdZy)TestDoneWatcherLogicuR   done-watcher 새 설계 로직 시뮬레이션 테스트 (escalation/acked 기반)r   r   age_minutesescalation_thresholdr   c                 p    || dz  }|| dz  }|j                         sy|j                         ry||k\  S )u   
        .done 파일이 age_minutes 경과했을 때 에스컬레이션 여부 반환.
        threshold(기본 30분) 이상이면 True, 미만이면 False.
        .done.escalated가 이미 존재하면 중복 방지 → False.
        .done.done.escalatedF)r   )r'   r   r   r   r   r   escalated_paths          r-   _simulate_stale_done_escalationz4TestDoneWatcherLogic._simulate_stale_done_escalation\  sP     G9E!22	#	&AA!  "222rX   archive_diracked_age_hoursc                     || dz  }|j                         sy|dk\  r+|j                  dd       |j                  || dz         yy)uf   
        .done.acked가 acked_age_hours 이상이면 archive로 이동. 이동 여부 반환.
        .done.ackedF   Tr   )r   r   rename)r'   r   r   r   r   
acked_paths         r-   _simulate_acked_cleanupz,TestDoneWatcherLogic._simulate_acked_cleanupm  s_      WI["99
  "b dT:kwi{,CCDrX   r   Nc           
      |   |dz  dz  }|j                  dd       d}|| dz  j                  dd	       | j                  }d
} ||||      }d}||u }|sWt        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}| j                  }d} ||||      }d}||u }|sWt        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}y)u0   .done 파일 30분 이상 → 에스컬레이션r   r   Tr   z
task-050.1r   {}r0   r1      r   isz%(py8)s
{%(py8)s = %(py2)s
{%(py2)s = %(py0)s._simulate_stale_done_escalation
}(%(py3)s, %(py4)s, age_minutes=%(py6)s)
} is %(py11)sr'   r   r   r   r   r   r   r;   rL   py11assert %(py13)spy13N<   r   rM   r   r   r=   r   r   r    r!   r"   r#   r'   r   r   r   r(   r*   r   @py_assert10@py_assert9@py_format12@py_format14s              r-   test_stale_done_escalationz/TestDoneWatcherLogic.test_stale_done_escalationz  s   (83
5		'	'33D73K 33`UW`3JUWX`\``X\`````X\```````t```t```3``````J```J````````````UW```X```\````````33`UW`3JUWX`\``X\`````X\```````t```t```3``````J```J````````````UW```X```\`````````rX   c           
      |   |dz  dz  }|j                  dd       d}|| dz  j                  dd	       | j                  }d
} ||||      }d}||u }|sWt        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}| j                  }d} ||||      }d}||u }|sWt        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}y)u2   .done 파일 30분 미만 → 아무 동작 없음r   r   Tr   z
task-051.1r   r   r0   r1      r   Fr   r   r'   r   r   r   r   r   Nr   r   r   s              r-   %test_stale_done_under_30min_no_actionz:TestDoneWatcherLogic.test_stale_done_under_30min_no_action  s   (83
5		'	'33D73K 33aUWa3JUWXa\aaX\aaaaaX\aaaaaaataaataaa3aaaaaaJaaaJaaaaaaaaaaaaUWaaaXaaa\aaaaaaaa33`UV`3JUVW`[``W[`````W[```````t```t```3``````J```J````````````UV```W```[`````````rX   c           
         |dz  dz  }|j                  dd       d}|| dz  j                  dd	       || d
z  j                  dd	       | j                  }d} ||||      }d}||u }|sWt        j                  d|fd||f      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}x}}y)u/   .done.escalated 존재 시 중복 알림 없음r   r   Tr   z
task-052.1r   r   r0   r1   r   r   r   Fr   r   r'   r   r   r   r   r   Nr   r   s              r-   (test_escalated_marker_prevents_duplicatez=TestDoneWatcherLogic.test_escalated_marker_prevents_duplicate  sN   (83
5		'	'33D73K		1	1==dW=U 33aUWa3JUWXa\aaX\aaaaaX\aaaaaaataaataaa3aaaaaaJaaaJaaaaaaaaaaaaUWaaaXaaa\aaaaaaaaarX   c                    |dz  dz  }|j                  dd       |dz  dz  }d}|| dz  j                  dd	
       | j                  |||d      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}| d}||z  }
|
j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}
x}}| j                  |||d      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}| d}||z  }
|
j                  } |       }| }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}
x}x}}| d}||z  }
|
j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}
x}}y)u.   .done.acked 24시간 이상 → archive 이동r   r   Tr   archivez
task-053.1r   r   r0   r1      )r   Fr   )z%(py0)s is %(py3)smovedr
   r   r   Nu2   24시간 미만에는 archive 이동 없어야 함zO
>assert %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = (%(py0)s / %(py2)s).exists
}()
}r   r   r   u7   24시간 이상이면 events/에서 제거되어야 함r   u   archive/로 이동되어야 함r   )r   rM   r   r   r=   r   r   r    r!   r"   r#   r   r   )r'   r   r   r   r   r  rA   r(   rB   r+   r)   rP   r   r   r   rQ   s                   r-   test_acked_cleanup_after_24hz1TestDoneWatcherLogic.test_acked_cleanup_after_24h  s   (83
5)I5		-	-99$9Q ,,Zg_a,bu~uuu 'y4t
44t4<<t<>t>tt@ttttttt
ttt
ttt4ttt<ttt>tttttt ,,Zg_a,bu}uuu$+9K!8}J!88}8@@}@B}BB}B}}D}}}}}}}J}}}J}}}!8}}}@}}}B}}}}}}}!(	5b55b5==b=?b?bbAbbbbbbbbbbbbb5bbb=bbb?bbbbbbrX   )r   )rS   rT   rU   rV   r   r%   intboolr   r   r   r   r   r  rW   rX   r-   r   r   Y  s    \ ]_33),3;>3VY3	3"$ T TW jm rv 
a4 
aD 
a
ad 
at 
a
b 
b$ 
bcT cd crX   r   )*rV   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r|   pathlibr   unittest.mockr   r   __file__parent_SCRIPTS_DIRimportlib.util	importlib_MODULE_PATHutilspec_from_file_locationr	   rA   r(   r=   r   r    r!   rB   r+   r"   r#   module_from_specr   loaderrP   r)   r   exec_moduler   rZ   r   rW   rX   r-   <module>r     s^  	    * H~$$++ 44~~--.A<P t4   t4     t   t   4      NN33D9 {{ $ {$   {$     t   t   {  $         ) *$ $NQq QqhWc WcrX   