
    di                    `    d Z ddlmZ ddlZddlZ G d d      Z G d d      Z G d d	      Zy)
uR  task-2457 Phase 2-A: pre-commit hook 테스트.

명세(루가 동시 작성 중인 hook 본체):
  차단 케이스 (exit 1, stderr "[BLOCKED] ..."):
    1. .tasks/locks/<task-id>.lock 부재 → "start_task_guard not passed"
    2. 현재 branch == main → "main direct commit prohibited"
    3. branch가 task 패턴 아님 (예: feature/foo) → "branch does not match task pattern"
    4. branch task-id != lock task-id → "branch/lock task-id mismatch"

  PASS 케이스 (exit 0):
    P1. lock 존재 + branch task-id 일치 + main 아님
    P2. TASKCTL_BYPASS=1 + TASKCTL_BYPASS_REASON 제공 → bypass evidence 기록 + PASS

  bypass evidence 검증 (.tasks/evidence/<task-id>/bypass-<ts>.json):
    - bypass=true / timestamp(ISO8601) / actor=$USER / reason=$TASKCTL_BYPASS_REASON
    - reason 누락 시 → 가드 자체 FAIL (exit 1)
    )annotationsNc                  $    e Zd Zd Zd Zd Zd Zy)TestPreCommitFailc                     ||d        ||d      }|j                   dk(  s!J d|j                  d|j                         d|j                  v sJ d|j                  v sJ y)	u#   1) lock 파일이 없으면 차단.task/task-2457-dev3
pre-commit   u$   lock 부재인데 통과됨. stdout= stderr=	[BLOCKED]zstart_task_guard not passedN
returncodestdoutstderr)selfgit_repocheckout_branchrun_hookresults        R/home/jay/workspace/.worktrees/task-2472+1-dev2/tests/git_hooks/test_pre_commit.pytest_lock_missing_blocksz*TestPreCommitFail.test_lock_missing_blocks   st    "78(L1  A% 	
26==2C8FMMK\]	
% fmm+++,===    c                     ||d      }|j                   dk(  s!J d|j                  d|j                         d|j                  v sJ d|j                  v sJ y)u*   2) main 브랜치 직접 commit은 차단.r   r	   u$   main commit인데 통과됨. stdout=r
   r   zmain direct commit prohibitedNr   )r   r   r   r   s       r   test_main_branch_blocksz)TestPreCommitFail.test_main_branch_blocks(   sk     (L1  A% 	
26==2C8FMMK\]	
% fmm+++.&--???r   c                     ||d        ||dd        ||d      }|j                   dk(  s!J d|j                  d|j                         d|j                  v sJ d	|j                  v sJ y
)u5   3) task 패턴이 아닌 branch (feature/foo) 차단.zfeature/foo	task-2457task_idbranchr   r	   u(   task 패턴 아닌데 통과됨. stdout=r
   r   z"branch does not match task patternNr   )r   r   r   	make_lockr   r   s         r   test_non_task_branch_blocksz-TestPreCommitFail.test_non_task_branch_blocks2   s     	-0(KF(L1  A% 	
6v}}6GxPVP]P]O`a	
% fmm+++3v}}DDDr   c                    ||d        ||dd       |dz  dz  dz  }t        j                  |j                  d            }d	|d
<   |j                  t        j                  |dd      d        ||d      }|j
                  dk(  s!J d|j                  d|j                         d|j                  v sJ d|j                  v sJ y)u&  4) branch task-id != lock 내부 task_id → 차단.

        주의: hook은 lock 파일을 `.tasks/locks/<branch-task-id>.lock` 경로로 찾는다.
        진짜 mismatch 시나리오는 그 파일이 존재하면서 내부 task_id 필드가
        다른 값을 가진 경우다.
        ztask/task-1000-dev3z	task-1000r   .taskslocksztask-1000.lockutf-8encodingz	task-2000r   F   )ensure_asciiindentr   r	   u.   branch/lock 불일치인데 통과됨. stdout=r
   r   zbranch/lock task-id mismatchN)jsonloads	read_text
write_textdumpsr   r   r   )r   r   r   r   r   	lock_pathpayloadr   s           r    test_branch_lock_mismatch_blocksz2TestPreCommitFail.test_branch_lock_mismatch_blocks@   s     	"78 	(	
 x''14DD	**Y00'0BC(	TZZeANY`a(L1  A% 	
<V]]<MXV\VcVcUfg	
% fmm+++->>>r   N)__name__
__module____qualname__r   r   r    r1    r   r   r   r      s    	>@E?r   r   c                      e Zd Zd Zd Zy)TestPreCommitPassc                    d} |||        ||d|        ||d      }|j                   dk(  s!J d|j                  d|j                         y)	u?   P1) lock 존재 + branch task-id 일치 + main 아님 → PASS.r   r   r   r   r   u)   정상 케이스인데 차단됨. stdout=r
   Nr   )r   r   r   r   r   r   r   s          r   test_valid_lock_branch_passesz/TestPreCommitPass.test_valid_lock_branch_passesc   sc     '&)(K?(L1  A% 	
77HQWQ^Q^Pab	
%r   c                   d} |||       ddd} ||d|      }|j                   dk(  s!J d|j                  d	|j                         |d
z  dz  dz  }|j                         sJ d       t	        |j                  d            }|s!J dt	        |j                                       t        j                  |d   j                  d            }	|	j                  d      du s
J d|	        |	j                  d      s
J d|	        |	d   }
d|
v r|
j                  d      sd|
v sd|
dd v s
J d|
       |	j                  d      t        j                  j                  d      k(  s9J d |	j                  d       d!t        j                  j                  d              |	j                  d"      dk(  sJ d#|	j                  d"             y)$u@   P2) TASKCTL_BYPASS=1 + reason 제공 → PASS + evidence 기록.r   1z"emergency hotfix for chairman demo)TASKCTL_BYPASSTASKCTL_BYPASS_REASONr   	env_extrar   u   bypass 통과 못함. stdout=r
   r"   evidencer   u/   evidence 디렉토리가 만들어지지 않음zbypass-*.jsonu-   bypass-*.json evidence 파일이 없음. dir=r$   r%   bypassTu   bypass 필드 != true: 	timestampu   timestamp 누락: TZ+-
   Nu%   timestamp 가 ISO8601 형식 아님: actorUSERu   actor 가 $USER 와 불일치: z vs reasonu   reason 불일치: )r   r   r   is_dirlistglobiterdirr*   r+   r,   getendswithosenviron)r   r   r   r   r   envr   evidence_dirbypass_filesdatatss              r   2test_bypass_with_reason_passes_and_writes_evidencezDTestPreCommitPass.test_bypass_with_reason_passes_and_writes_evidenceo   s    '&) "%I
 (LC@  A% 	
+FMM+<HV]]DUV	
%
  (*Z7+E""$W&WW$L--o>?kLTR^RfRfRhMiLjkk| zz,q/33W3EFxx!T)K-DTF+KK)xx$A(:4&&AA$+bybkk#.#)sbg~ 	
3B6:	
N xx BJJNN6$:: 	
-dhhw.?-@RZZ^^TZE[D\]	
: xx!%II 	
 (!3 67	
Ir   N)r2   r3   r4   r9   rX   r5   r   r   r7   r7   b   s    

$
r   r7   c                      e Zd Zd Zy)TestPreCommitBypassEvidencec                <   d} |||       ddi}i |}t         j                  j                  dd        ||d|      }|j                  dk(  s!J d	|j                  d
|j
                         d|j
                  v sJ d|j
                  j                         v sJ y)uJ   TASKCTL_BYPASS=1 만 있고 reason 없음 → 가드 자체 FAIL (exit 1).r   r<   r;   r=   Nr   r>   r	   u-   reason 없는 bypass인데 통과됨. stdout=r
   r   rJ   )rQ   rR   popr   r   r   lower)r   r   r   r   r   rS   env_fullr   s           r   !test_bypass_without_reason_blocksz=TestPreCommitBypassEvidence.test_bypass_without_reason_blocks   s     '&)%c7 	

.5(LHE  A% 	
;FMM;LHU[UbUbTef	
% fmm+++6==..0000r   N)r2   r3   r4   r_   r5   r   r   rZ   rZ      s    1r   rZ   )__doc__
__future__r   r*   rQ   r   r7   rZ   r5   r   r   <module>rb      s7   $ #  	@? @?L1
 1
n1 1r   