
    (<i:@                        d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
mZ ej                  j                  dd      Zej                  j!                  d e ee      j&                  j&                  dz               ddlZej,                  j/                  d e ee      j&                  j&                  dz  d	z              Zej,                  j3                  e      Zej6                  j9                  e       ej:                  Zej<                  Zej>                  Zej@                  Z ejB                  Z!ejD                  Z"ejF                  Z# G d
 dejH                        Z% G d dejH                        Z& G d dejH                        Z' G d dejH                        Z( G d dejH                        Z) G d dejH                        Z*e+dk(  r ejF                  d       yy)u  
test_notify_completion.py — notify-completion.py 테스트

테스트 항목:
- TestGetAnuKey: 환경변수 있을 때 / 없을 때 (sys.exit(1))
- TestCheckChainStatus: 정상 응답, 타임아웃, 비정상 응답
- TestLogProtocol: done-protocol.log 기록 함수 테스트
- TestSendTelegramNotification: cokacdir subprocess 호출 확인
- TestMain: 체인 중간 Phase / 마지막 Phase / 일반 작업 분기
- TestDispatchExecution: dispatch.py subprocess 호출 통합 테스트
    N)Path)	MagicMockpatchCOKACDIR_CHAT_ID
6937032012scriptsnotify_completionnotify-completion.pyc                   (    e Zd ZdZddZddZddZy)TestGetAnuKeyu   get_anu_key 함수 테스트Nc                     t        j                  t        j                  ddi      5  t	               }ddd       | j                  d       y# 1 sw Y   xY w)u5   COKACDIR_KEY_ANU 환경변수 있으면 정상 반환COKACDIR_KEY_ANUztest-key-abc123N)r   dictosenvironget_anu_keyassertEqualselfresults     M/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_notify_completion.pytest_get_anu_key_successz&TestGetAnuKey.test_get_anu_key_success1   sH    ZZ

%79J$KL 	# ]F	#!23	# 	#s   AAc                    t         j                  j                         D ci c]  \  }}|dk7  s|| }}}t        j                  t         j                  |d      5  | j                  t              5 }t                ddd       ddd       | j                  j                  j                  d       yc c}}w # 1 sw Y   >xY w# 1 sw Y   BxY w)u:   COKACDIR_KEY_ANU 환경변수 없으면 sys.exit(1) 호출r   TclearN   )r   r   itemsr   r   assertRaises
SystemExitr   r   	exceptioncode)r   kvenv_without_keyctxs        r   test_get_anu_key_missing_exitsz,TestGetAnuKey.test_get_anu_key_missing_exits7   s    ,.JJ,<,<,>ZDAq!GYBY1a4ZZZZ

O4@ 	"":. #	 	++Q/	 [ 	 	s.   B6B6C4B<?C<C	CCc                 .   t        j                  t        j                  ddi      5  | j	                  t
              5 }t                ddd       ddd       | j                  j                  j                  d       y# 1 sw Y   8xY w# 1 sw Y   <xY w)u7   COKACDIR_KEY_ANU 빈 문자열이면 sys.exit(1) 호출r    Nr   )
r   r   r   r   r   r   r   r   r    r!   )r   r%   s     r   test_get_anu_key_empty_exitsz*TestGetAnuKey.test_get_anu_key_empty_exits?   su    ZZ

%7$<= 	"":. #	 	++Q/ 	 	s"   BA?B?B	BBreturnN)__name__
__module____qualname____doc__r   r&   r)        r   r   r   .   s    &400r1   r   c                   0    e Zd ZdZddZddZddZddZy)TestCheckChainStatusu#   check_chain_status 함수 테스트Nc                 j   ddddd}t               }d|_        t        j                  |      |_        t        d|      5  t        d	      }d
d
d
       | j                  d   d       | j                  |d   d       | j                  |d   d       | j                  |d   d       y
# 1 sw Y   ^xY w)u/   subprocess 성공 시 JSON 파싱 결과 반환TFchain-42
task-381.2in_chainis_lastchain_idnext_task_idr   subprocess.runreturn_value
task-381.1Nr8   r9   r:   r;   )r   
returncodejsondumpsstdoutr   check_chain_statusr   )r   fake_responsemock_resultr   s       r   test_check_chain_status_successz4TestCheckChainStatus.test_check_chain_status_successJ   s     "(	
  k!"!ZZ6#+> 	6'5F	6 	
+T2	*E2
+Z8/>	6 	6s    B))B2c                 .   t               }d|_        d|_        t        d|      5  t	        d      }ddd       | j                  d          | j                  |d          | j                  |d	          | j                  |d
          y# 1 sw Y   ZxY w)uF   subprocess 실패(returncode != 0) 시 in_chain=False 기본값 반환r   r(   r<   r=   r?   Nr8   r9   r:   r;   )r   r@   rC   r   rD   assertFalseassertIsNoner   rF   r   s      r   /test_check_chain_status_failure_returns_defaultzDTestCheckChainStatus.test_check_chain_status_failure_returns_default^   s    k!"#+> 	6'5F	6 	
+,	*+&,-&01	6 	6s   BBc                     t        dt        j                  dd            5  t        d      }ddd       | j	                  d          | j	                  |d	          y# 1 sw Y   2xY w)
u=   subprocess TimeoutExpired 시 in_chain=False 기본값 반환r<   python3   )cmdtimeoutside_effectr?   Nr8   r9   )r   
subprocessTimeoutExpiredrD   rI   r   s     r   /test_check_chain_status_timeout_returns_defaultzDTestCheckChainStatus.test_check_chain_status_timeout_returns_defaultl   sb    #1J1Jybd1ef 	6'5F	6 	
+,	*+		6 	6s   A  A)c                     t               }d|_        d|_        t        d|      5  t	        d      }ddd       | j                  d          | j                  |d          y# 1 sw Y   2xY w)	uB   subprocess 성공이지만 JSON 파싱 실패 시 기본값 반환r   znot valid json {r<   r=   r?   Nr8   r9   )r   r@   rC   r   rD   rI   rK   s      r   4test_check_chain_status_invalid_json_returns_defaultzITestCheckChainStatus.test_check_chain_status_invalid_json_returns_defaultt   sk    k!"/#+> 	6'5F	6 	
+,	*+		6 	6s   A##A,r*   )r,   r-   r.   r/   rG   rL   rV   rX   r0   r1   r   r3   r3   G   s    -?(2,
,r1   r3   c                   (    e Zd ZdZddZddZddZy)TestLogProtocolu   log_protocol 함수 테스트Nc                    t        j                         5 }t        |      dz  dz  }t        j                  t
        dt        |            5  t        dd       ddd       | j                  |j                                |j                  d      }| j                  d|       | j                  d|       ddd       y# 1 sw Y   gxY w# 1 sw Y   yxY w)	u1   log_protocol이 DONE_PROTOCOL_LOG에 기록한다logsdone-protocol.logDONE_PROTOCOL_LOGz
task-999.1ztest messageNzutf-8)encoding)tempfileTemporaryDirectoryr   r   object_modstrlog_protocol
assertTrueexists	read_textassertIn)r   tmpdirlog_pathcontents       r    test_log_protocol_writes_to_filez0TestLogProtocol.test_log_protocol_writes_to_file   s    ((* 	3fF|f,/BBHd$7XG ;\>:;OOHOO-.(('(:GMM,0MM.'2	3 	3; ;	3 	3s$   6C
B>AC
>C	C

Cc                 F   t        j                         5 }t        |      dz  dz  dz  }t        j                  t
        dt        |            5  t        dd       ddd       | j                  |j                                ddd       y# 1 sw Y   1xY w# 1 sw Y   yxY w)u,   logs 디렉토리가 없어도 자동 생성nonexistentsubdirr]   r^   z
task-888.1zdir creation testN)
r`   ra   r   r   rb   rc   rd   re   rf   rg   )r   rj   rk   s      r   %test_log_protocol_creates_parent_dirsz5TestLogProtocol.test_log_protocol_creates_parent_dirs   s    ((* 	/fF|m3h>ATTHd$7XG @\+>?@OOHOO-.		/ 	/@ @	/ 	/s#   9BB'BB	BB c                     t        dt        d            5  	 t        dd       ddd       y# t        $ r | j                  d       Y %w xY w# 1 sw Y   yxY w)u7   OSError 발생 시 예외를 무시하고 정상 반환zbuiltins.openzpermission deniedrR   z
task-777.1z
error testzlog_protocol raised OSErrorN)r   OSErrorre   fail)r   s    r   #test_log_protocol_silent_on_oserrorz3TestLogProtocol.test_log_protocol_silent_on_oserror   sY    ?8K0LM 	99\<8	9 	9  9		789		9 	9s&   A.AA
AAAr*   )r,   r-   r.   r/   rm   rq   ru   r0   r1   r   rZ   rZ      s    '	3/9r1   rZ   c                        e Zd ZdZddZddZy)TestSendTelegramNotificationuH   send_telegram_notification 함수 테스트 (cokacdir subprocess 호출)Nc                 B   t               }d|_        t        j                  t        j
                  ddi      5  t        d|      5 }t        t        d      }ddd       ddd       j                          | j                         y# 1 sw Y   3xY w# 1 sw Y   7xY w)u   requests.post 호출 확인   ANU_BOT_TOKEN
test-tokenrequests.postr=   u   테스트 메시지N)
r   status_coder   r   r   r   send_telegram_notification_TEST_CHAT_IDassert_called_oncerf   )r   mock_response	mock_postr   s       r   0test_send_telegram_notification_calls_subprocesszMTestSendTelegramNotification.test_send_telegram_notification_calls_subprocess   s    !$'!ZZ

_l$CD 	Z]C Zy3MCXYZ	Z 	$$&Z Z	Z 	Zs#   BB	B	B	BBc                 B   t               }d|_        t        j                  t        j
                  ddi      5  t        d|      5  	 t        t        d       ddd       ddd       y# t        $ r | j                  d       Y -w xY w# 1 sw Y   2xY w# 1 sw Y   yxY w)	u<   requests.post 실패 시에도 sys.exit 없이 정상 반환i  rz   r{   r|   r=   u	   메시지z7send_telegram_notification raised SystemExit on failureN)
r   r}   r   r   r   r   r~   r   r   rt   )r   r   s     r   2test_send_telegram_notification_no_exit_on_failurezOTestSendTelegramNotification.test_send_telegram_notification_no_exit_on_failure   s    !$'!ZZ

_l$CD 	Y]C YY.}kJY	Y 	Y " YIIWXYY Y	Y 	YsA   BB	A)B)BB	BB		B	BBr*   )r,   r-   r.   r/   r   r   r0   r1   r   rw   rw      s    R 	Yr1   rw   c                   T    e Zd ZdZddededz  ddfdZddZddZdd	Z	dd
Z
ddZy)TestMainu   main 함수 분기 테스트Nargvenvr+   c                    dt         d}|r|j                  |       t        j                  t        j
                  |      5  t        ddg|z         5  t                ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)u<   main()을 지정 argv와 환경변수로 실행하는 헬퍼test-keyr   r   sys.argvr
   N)r   updater   r   r   r   main)r   r   r   base_envs       r   	_run_mainzTestMain._run_main   st    (2VOOC ZZ

H- 	z$:#;d#BC 	 	 	 	s$   A:A.A:.A7	3A::Bc                 ~   ddddd}dddd	d
}t        j                         5 }t        |      dz  dz  }|j                  dd       t	        j
                  t        d|      5  t	        j
                  t        d|      5  t	        j
                  t        d|      5  t	        j
                  t        d      5 }t	        dt        ddd            5 }| j                  dg       |j                          |j                  D cg c]  }t        d |d   D              s| }}| j                  t        |      dkD         ddd       ddd       ddd       ddd       ddd       ddd       yc c}w # 1 sw Y   7xY w# 1 sw Y   ;xY w# 1 sw Y   ?xY w# 1 sw Y   CxY w# 1 sw Y   GxY w# 1 sw Y   yxY w)uG   체인 중간 Phase → dispatch + send_telegram_notification 호출됨TFr5   r6   r7   dispatchz/tmp/test.md	dev1-teamnormalaction	task_fileteamlevelmemoryeventsparentsexist_okWORKSPACE_ROOTrD   r=   dispatch_next_phaser~   r<   r   r(   r@   rC   stderrr?   c              3   6   K   | ]  }d t        |      v   ywzdispatch.pyNrd   .0args     r   	<genexpr>z5TestMain.test_main_chain_mid_phase.<locals>.<genexpr>        KvjmM]`ad]eLeKv   N)r`   ra   r   mkdirr   rb   rc   r   r   r   call_args_listanyrf   len)	r   
chain_infodispatch_resultrj   
events_dir	mock_sendmock_runcdispatch_callss	            r   test_main_chain_mid_phasez"TestMain.test_main_chain_mid_phase   s    "(	

 !'	
 ((* 	9ff08;JTD9 T#3V<9T#7jQ9 T#8W9 T#?@	9 EN&Y!TV_a5bc9
 hp~. ,,.-5-D-D!wKvqrstquKvHv!!w!wN 3a 789 9 9 9 9		9 	9  "x9 9 9 9 9 9 9 9 9 9		9 	9s   A F3#F' FF	8F1E7E2E2"E7F	F	FF'!F32E77F <FFF	FFF$ F''F0	,F33F<c           	         ddddd}t        j                         5 }t        j                  t        d|      5  t        j                  t        d|      5  t        j                  t        d      5 }| j                  d	g       |j                          |j                  d
   }| j                  d	|d          ddd       ddd       ddd       ddd       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   yxY w)u8   마지막 Phase → send_telegram_notification 호출됨Tr5   Nr7   r   rD   r=   r~   z
task-381.3r   r   )	r`   ra   r   rb   rc   r   r   	call_argsri   )r   r   rj   r   r   s        r   test_main_chain_last_phasez#TestMain.test_main_chain_last_phase   s     " 	

 ((* 
	:fT#3V<	:T#7jQ	: T#?@	: EN~.,,.%//2	lIaL9	: 	: 	:
	: 
	:	: 	: 	: 	: 	: 	:
	: 
	:sS   C<C0C$0AC	7C$?C0C<C!C$$C-)C00C9	5C<<Dc           	         ddddd}t        j                         5 }t        j                  t        d|      5  t        j                  t        d|      5  t        j                  t        d      5 }| j                  dg       |j                          ddd       ddd       ddd       ddd       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   yxY w)	uE   일반 작업(체인 아님) → send_telegram_notification 호출됨FNr7   r   rD   r=   r~   ztask-999)r`   ra   r   rb   rc   r   r   r   r   rj   r   s       r   test_main_not_in_chainzTestMain.test_main_not_in_chain   s      	

 ((* 	/fT#3V</T#7jQ/ T#?@/ EN
|,,,./ / /	/ 	// / / / / /	/ 	/sR   CCC 0#B4	C C#C4B=9C  C	CC	CC!c                 ~   ddddd}t        j                         5 }t        j                  t        d|      5  t        j                  t        d|      5  t        j                  t        d      5 }t        j
                  t        j                  dt        d	      5  t        d
g d      5  t                ddd       ddd       |j                          ddd       ddd       ddd       ddd       y# 1 sw Y   BxY w# 1 sw Y   FxY w# 1 sw Y   :xY w# 1 sw Y   >xY w# 1 sw Y   BxY w# 1 sw Y   yxY w)u@   --anu-key CLI 인자로 키를 직접 전달해도 정상 동작FNr7   r   rD   r=   r~   zenv-keyr   r   )r
   task-123z	--anu-keyzcli-key)r`   ra   r   rb   rc   r   r   r   r   r   r   r   s       r   test_main_uses_cli_anu_keyz#TestMain.test_main_uses_cli_anu_key  s   "'Et]ab
((* 	/fT#3V</T#7jQ/ T#?@/ ENZZJJ)2V  z+gh 	 ,,./ / /	/ 	/ 	 / / / / / /	/ 	/s   D3D'D0,D	D+C76D>D	DD'&D37D <DDD	DDD$ D''D0	,D33D<c                 ,   ddddd}t        j                         5 }t        |      dz  dz  }|j                  dd       t        j
                  j                         D ci c]  \  }}|dk7  s|| }}}t        |d	<   t        j                  t        d
|      5  t        j                  t        j
                  |d      5  t        j                  t        d|      5  t        j                  t        dd      5  t        dddg      5  t                ddd       ddd       ddd       ddd       ddd       ddd       yc c}}w # 1 sw Y   8xY w# 1 sw Y   <xY w# 1 sw Y   @xY w# 1 sw Y   DxY w# 1 sw Y   HxY w# 1 sw Y   yxY w)u8   COKACDIR_KEY_ANU 없어도 sys.exit 없이 정상 실행FNr7   r   r   Tr   r   r   r   r   rD   r=   r~   r   r
   r   )r`   ra   r   r   r   r   r   r   r   rb   rc   r   r   )r   r   rj   r   r"   r#   r$   s          r   'test_main_missing_anu_key_does_not_exitz0TestMain.test_main_missing_anu_key_does_not_exit!  sm   "'Et]ab
((* 	ff08;JTD902

0@0@0B^1aK]F]q!t^O^2?O./ T#3V<

2::dC T#7jQ T#?eT	 :(>
'KL F   	 	 _        	 	s   AF
"E0E5'F
'E>E2 E&	=EEEE&	'E2/E>7F
F
EEE#E&	&E/+E22E;7E>>F	F

F)Nr*   )r,   r-   r.   r/   listr   r   r   r   r   r   r   r0   r1   r   r   r      s=    &d    9D:*/$/$r1   r   c                        e Zd ZdZddZddZy)TestDispatchExecutionu*   dispatch.py 실제 호출 통합 테스트Nc                     ddddd}dddd	d
}t        j                         5 }t        |      dz  dz  }|j                  dd       t	        j
                  t        d|      5  t	        j
                  t        d|      5  t	        j
                  t        d|      5  t	        j
                  t        d      5  t	        d      5 }t        ddd      |_        t	        j                  t        j                  dt        d      5  t	        dddg      5  t                ddd       ddd       |j                  D cg c]  }t        d |d   D              s| }}| j!                  t#        |      dkD  d       ddd       ddd       ddd       ddd       ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   xY wc c}w # 1 sw Y   OxY w# 1 sw Y   SxY w# 1 sw Y   WxY w# 1 sw Y   [xY w# 1 sw Y   _xY w# 1 sw Y   yxY w)uN   chain 중간 Phase, action=dispatch → dispatch.py가 subprocess로 호출됨TFr5   r6   r7   r   z./home/jay/workspace/memory/tasks/task-381.2.mdr   r   r   r   r   r   r   rD   r=   r   r~   r<   r   r(   r   r   r   r   r
   r?   Nc              3   6   K   | ]  }d t        |      v   ywr   r   r   s     r   r   zQTestDispatchExecution.test_mid_chain_dispatch_calls_subprocess.<locals>.<genexpr>\  r   r   u9   dispatch.py가 subprocess로 호출되지 않았습니다)r`   ra   r   r   r   rb   rc   r   r>   r   r   r   r   r   r   r   rf   r   )r   r   r   rj   r   r   r   r   s           r   (test_mid_chain_dispatch_calls_subprocessz>TestDispatchExecution.test_mid_chain_dispatch_calls_subprocess9  s    "(	

 !I	
 ((* 	vff08;JTD9 T#3V<vT#7jQv T#8Wv T#?@	v
 &'v
 ,4(1QrRT(U%ZZJJ)3W  z,BL+QR 	 .6-D-D!wKvqrstquKvHv!!w!wN 3a 79tu#v v v v v		v 	v" 	  "x!v v v v v v v v v v		v 	vs   A H#G8 G,G 	8G?GF7F+F7%G;GG G:GG 	
G,G8H+F40F77G <GGGGG 	 G)%G,,G51G88H	=HHc                 J   ddddd}dddd	d
}t        j                         5 }t        j                  t        d|      5  t        j                  t        d|      5  t        j                  t        d|      5  t        j                  t        d      5 }t        d      5 }t        ddd      |_        t        j                  t        j                  ddi      5  t        dddg      5  t                ddd       ddd       ddd       ddd       ddd       ddd       ddd       j                          ddd       y# 1 sw Y   RxY w# 1 sw Y   VxY w# 1 sw Y   ZxY w# 1 sw Y   ^xY w# 1 sw Y   bxY w# 1 sw Y   fxY w# 1 sw Y   jxY w# 1 sw Y   yxY w)uV   dispatch.py 호출 실패(returncode=1) → 텔레그램 알림은 여전히 전송됨TFr5   r6   r7   r   z/tmp/test-task.mdr   r   r   r   rD   r=   r   r~   r<   r   r(   zdispatch errorr   r   r   r   r
   r?   N)r`   ra   r   rb   rc   r   r>   r   r   r   r   r   )r   r   r   rj   r   r   s         r   +test_dispatch_failure_sends_telegram_anywayzATestDispatchExecution.test_dispatch_failure_sends_telegram_anyway_  s    "(	

 !,	
 ((* 	+fT#3V<T#7jQ T#8W T#?@	 EN&'
 ,4(1QrRb(c%ZZ

-?,LM z,BL+QR      ((*	+ 	+           	+ 	+s   FFF9E5	E) :EE)E4E<EE)E5	FF$FE
EEEE&"E))E2.E5	5E>:FF
FF	FF"r*   )r,   r-   r.   r/   r   r   r0   r1   r   r   r   6  s    4$vL+r1   r   __main__   )	verbosity),r/   rA   r   rT   sysr`   unittestpathlibr   unittest.mockr   r   r   getr   pathinsertrd   __file__parentimportlib.util	importlibutilspec_from_file_location_specmodule_from_specrc   loaderexec_moduler   rD   re   r~   r   end_task_timerr   TestCaser   r3   rZ   rw   r   r   r,   r0   r1   r   <module>r      s  
  	  
    *

1<@ 3tH~,,33i?@ A  	..X$$y03IIJ	 ~~&&u-    ,,   !<< .. $$yy0H%% 027,8,, 7,t9h'' 9@Y8#4#4 Y2yx   yxG+H-- G+T zHMMA r1   