
    [i["                        d Z ddlmZ ddlZddlZddlZddlmZ ddlZ ed      Z	e	dz  dz  Z
dddZdd	Zdd
ZddZdddZd Zd Zy)u  tests/taskctl/test_self_approve.py
self-approve 차단 검증 (task-2467)

벨레스(개발6팀 테스터) 작성. 스바로그의 구현 완료 전 선작성(TDD).

케이스:
    1. test_self_approve_blocked — PR author == approver → ESCALATED + exit 1
    2. test_approve_with_different_human_passes — PR author != approver → HUMAN_APPROVED

환경 hook 요청 (스바로그 구현 측):
    - `TASKCTL_PR_AUTHOR_OVERRIDE` 환경변수: gh API 없이 PR author를 주입할 수 있는 hook.
      예) env["TASKCTL_PR_AUTHOR_OVERRIDE"] = "team-bot"
      → taskctl approve가 gh pr view 대신 이 값을 PR author로 사용.
    - 또는 `TASKCTL_SKIP_GH_VERIFY=1` 플래그로 gh 호출 전체 skip + 파라미터만으로 검증.
    )annotationsN)Pathz-/home/jay/workspace/.worktrees/task-2467-dev6scriptsz
taskctl.pyc                4   i t         j                  }t        |       |d<   |r|j                  |       | dz  dz  j	                  dd       | dz  dz  j	                  dd       | dz  dz  j	                  dd       | dz  d	z  j	                  dd       |S )
NWORKSPACE_ROOT.tasksstateT)parentsexist_okevidencememoryeventszorchestration-audit)osenvironstrupdatemkdir)tmp_path	extra_envenvs      P/home/jay/workspace/.worktrees/task-2520-dev4/tests/taskctl/test_self_approve.py_isolated_workspacer      s    
RZZ.CMC

97"))$)F:%,,TD,I8#**4$*G0077t7TJ    c                Z    t        j                  dt        t              g| z   dd|d      S )Npython3T   )capture_outputtextr   timeout)
subprocessrunr   TASKCTL)argsr   s     r   _runr$   )   s-    >>	CL!D($C r   c                    | dz  dz  | dz  }|j                         s
J d|        t        j                  |j                               S )Nr   r	   .jsonu   state 파일 없음: )existsjsonloads	read_text)r   task_idps      r   _stater-   0   sM    8g%7)5(99A88:2.qc22:::akkm$$r   c                   ddl }| dz  dz  | dz  }t        j                  |j                               }||d<   |j	                  dd       |j                         D ci c]  \  }}|dk7  s|| }}}t        j                  |dd	d
      }	|j                  |	j                  d            j                         }
|
|d<   |j                  t        j                  |dd             yc c}}w )u<   테스트 전용: state 강제 설정 + 체크섬 재계산.r   Nr   r	   r&   current_state	_checksumFT),:)ensure_ascii	sort_keys
separatorszutf-8   )r3   indent)hashlibr(   r)   r*   popitemsdumpssha256encode	hexdigest
write_text)r   r+   target_stater8   r,   r	   kvpayloadcanonchecksums              r   _force_state_with_checksumrF   6   s    8g%7)5(99AJJq{{}%E)E/	IIk4  %B1k1Aq!tBGBJJwUdzZE~~ell734>>@H!E+LLEa@A	 Cs    C*.C*c           
         d|gd|gd|gd|gd|dt        |      gfD ]  }t        ||      j                  dk7  s y t        | |d	       t	        | |      }|d
   dv S )ut   VERIFIED/GUARD_PASS 상태까지 강제 진입.

    Returns True if successfully in VERIFIED/GUARD_PASS state.
    initdispatchackr!   zpr-openz--prr   F
GUARD_PASSr/   >   VERIFIEDrK   )r   r$   
returncoderF   r-   )r   r   r+   	pr_numbercmdr	   s         r   _setup_to_verifiedrP   E   s    
 !J#8 5'"2GVS^<>  S>$$)	 x,?8W%E!%???r   c                   d}t        | |dd      }d}t        | ||d      }|st        j                  d       t	        d	|d
|g|      }|j
                  dk7  rt        | |      }|d   }|dv s
J d|        | dz  dz  |z  dz  }|j                         rt        j                  |j                               }	|	j                  d      dk(  sJ d|	j                  d              |	j                  dd      }
d|
j                         v s0d|
j                         v sd	|
j                         v s
J d|
        yyyyt        | |      }|d   dk(  rt        j                  d       yy)u   PR author == approver → ESCALATED 전이 + exit 1 + approval.json result=FAIL.

    구현 hook: TASKCTL_PR_AUTHOR_OVERRIDE 환경변수로 PR author 주입.
    hook 미구현 시 gh CLI 호출 실패로 graceful skip (ESCALATED 또는 exit 1).
    human-reviewer TASKCTL_PR_AUTHOR_OVERRIDEGH_TOKENr   ztask-selfapprove-01i  rN   1   GUARD_PASS 상태 진입 실패 — 환경 문제approve--byr   r/   >   PR_OPENrL   	ESCALATEDrK   u+   self-approve 차단 후 예상 외 상태: r   r   approval.jsonresultFAILu(   approval.json result가 FAIL이 아님: reasonselfauthoru4   approval.json reason이 self-approve 관련 없음: HUMAN_APPROVEDuq   TASKCTL_PR_AUTHOR_OVERRIDE hook 미구현 — MVP는 PR author 검증 없이 approve 허용 (스바로그 대기)N)r   rP   pytestskipr$   rM   r-   r'   r(   r)   r*   getlowerxfail)r   approverr   r+   okprocr	   currentapproval_evevra   s              r   test_self_approve_blockedrp   Z   s     H
h&.3 C $G	Hc7c	BBGH GVX6<D !x)(LL 	
9'C	
L
 )J6@?RK1134B66(#v- :266(;K:LM- VVHb)FV\\^+x6<<>/IYZ`ZfZfZhMh FvhOhMh/I+   x)!%55LL D 6r   c                   d}d}t        | |dd      }d}t        | ||d      }|st        j                  d	       t	        d
|d|g|      }|j
                  dk(  r
t        | |      }|d   dk(  sJ d|d           |j                  d      du sJ d       |j                  dg       }|D 	cg c]  }	|	j                  d      dv s|	 }
}	|
sJ d       | dz  dz  |z  dz  }|j                         rrt        j                  |j                               }|j                  d      dv sJ d|j                  d              d|v rd|v r|d   |d   k7  sJ d|d           y&y&y&y&|j                  }d |v sd!|v rt        j                  d"       y&d|v sd#|j                         v rt        j                  d$       y&t        j                  d%|d&d'         y&c c}	w )(u   PR author != approver → HUMAN_APPROVED 정상 전이.

    TASKCTL_PR_AUTHOR_OVERRIDE=bot-user, approver=human-reviewer → 승인 허용.
    또는 MVP에서 --by 파라미터만으로 승인 (GUARD_PASS → HUMAN_APPROVED).
    zteam-botrR   rS   rT   rW   ztask-selfapprove-02i  rX   rY   rZ   r[   r   r/   rd   u-   approve 성공 후 HUMAN_APPROVED가 아님: human_approvedTu"   human_approved 플래그 미설정transitionsto>   rd   u#   HUMAN_APPROVED 전이 이력 없음r   r   r^   r_   >   OKPASSAPPROVEDu   approval.json result 이상: 	pr_authorrj   u6   approval.json에 self-approve가 기록됨: pr_author=rK   rL   uJ   approve 명령이 GUARD_PASS 상태를 인식 못함 (상태명 불일치)byu1   --by 파라미터 미구현 (스바로그 대기)u   approve 실패 원인 불명: Ni,  )r   rP   re   rf   r$   rM   r-   rg   r'   r(   r)   r*   stderrrh   ri   )r   
bot_authorhuman_approverr   r+   rk   rl   r	   rs   thuman_approved_transitionrn   ro   rz   s                 r   (test_approve_with_different_human_passesr      s:    J%N
h&03 C $G	Hc7c	BBGH GV^<cBD !x)_%)99 	
;E/<R;ST	
9 yy)*d2X4XX2 iir2"%
aeeDk5G&GA%
! %
 )O*OO( )J6@?RK1134B66(#'AA /x0@/ABA b Z2%5+"Z.8 LRP[_L]^8 &6    6!Z6%9KKdev!7LLLMLL9&#,HI3%
s   .GG)N)r   r   r   zdict | Nonereturndict)r#   z	list[str]r   r   r   zsubprocess.CompletedProcess)r   r   r+   r   r   r   )r   r   r+   r   r@   r   r   None)   )
r   r   r   r   r+   r   rN   intr   bool)__doc__
__future__r   r(   r   r    pathlibr   re   	WORKSPACEr"   r   r$   r-   rF   rP   rp   r    r   r   <module>r      s_    #  	   @A	
i
,
.	%B@*2r8Jr   