
    ;j'                        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mZ ddl	m
Z
 ddlZ e
e      j                         j                  d   Zedz  dz  Zdefd	Zdefd
ZdedededdfdZdedefdZdedee   fdZdedededededz  dedz  defdZdee   dededefdZ ej8                         d        Zd Zd Zd Z d Z!d Z"d  Z#y)!u  
test_stash_lifecycle_dryrun.py
task: task-2571 TODO-7 T-2

검증 목표:
- spec §3 dry-run 기본값 검증
- FINISH_TASK_STASH_APPROVE 미설정 시 stash 변경 없음
- spec §2 결정 흐름 참조구현(reference implementation)으로 dry-run 결정 검증
- audit log 포맷 검증 (approval_mode == "dry-run", action == "dry-run-pop")

작성자: 하누만 (개발4팀 QA)
    N)datetimetimezone)Path   scriptszstash_audit.pyreturnc                     t        j                  d      } t               }t        j                  g d| d|       t        j                  g d| d|       t        j                  g d| d|       t        |       dz  j                  d	       t        j                  g d
| d|       t        j                  g d| d|       | S )u$   격리된 임시 git repo 초기화.zstash-lifecycle-test-)prefix)gitinit-qz-bmainTcwdcheckenv)r   configz
user.emailtest@example.com)r   r   z	user.nametesta.txthello)r   addr   )r   commitr   -mr   )tempfilemkdtemp_git_env
subprocessrunr   
write_text)dr   s     /tests/regression/test_stash_lifecycle_dryrun.py_init_temp_repor#   "   s     78A
*CNN6ATsSNNFAUY_bcNN9qRUV	!Ww""7+NN*3GNN8atQTUH    c                  j    t         j                  j                         } d| d<   d| d<   d| d<   d| d<   | S )u"   git 명령 실행용 환경변수.r   GIT_AUTHOR_NAMEr   GIT_AUTHOR_EMAILGIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL)osenvironcopy)r   s    r"   r   r   /   sC    
**//
C#C0C &C!3CJr$   repo_dirmessagefilenamec                     t               }t        |       |z  }|j                  d| d       t        j                  dd|g| d|       t        j                  dddd	|g| d|       y
)u3   파일 하나 dirty 상태로 만들고 stash push.zdirty: 
r   r   Tr   stashpushr   N)r   r   r    r   r   )r-   r.   r/   r   fpaths        r"   _stash_pushr5   9   sf    
*CNX%E	wwir*+NNE5(+3ONNE7FD':PTZ]^r$   c                    t        j                  t        j                  t	        t
              dd| gdd      }|j                  dk(  s!J d|j                   d|j                          t        j                  |j                        S )u7   stash_audit.py --json 실행 후 파싱된 dict 반환.z--jsonz--workspaceT)capture_outputtextr   u#   stash_audit.py 실행 실패 (exit=z
)
stderr: )r   r   sys
executablestrSTASH_AUDIT_PY
returncodestderrjsonloadsstdoutr-   results     r"   _run_audit_jsonrD   B   s    ^^	^,hxPF
 ! 
-f.?.?-@ A==/	#! ::fmm$$r$   c                     t        j                  g d| ddt                     }|j                  dk7  s|j                  j                         sg S |j                  j                         j                         S )u   git stash list 반환.)r   r2   listT)r   r7   r8   r   r   )r   r   r   r=   rA   strip
splitlinesrB   s     r"   _stash_listrI   P   sa    ^^ JF AV]]%8%8%:	== ++--r$   sourceapprovepr_verifiedidx_in_drop_listetidtask_idc                 b    | dk(  r|ryy| dk(  r|r|r||k(  ry|syy| dk(  r	|r|ry|syy| d	v ryy
)u  
    spec §2 결정 흐름 reference implementation.

    Returns:
        action 문자열:
            "dry-run-pop"   — APPROVE 미설정, pre-task
            "dry-run-drop"  — APPROVE 미설정, other-files
            "popped"        — APPROVE=1, pre-task
            "dropped"       — APPROVE=1, other-files + idx_in_drop_list
            "preserved"     — wip / quarantine / unknown, 또는 조건 미충족 finish-task
            "skipped"       — 알 수 없는 source
    zpre-taskpoppeddry-run-popzfinish-task	preservedzother-filesdroppedzdry-run-drop)wip
quarantineunknownskipped rJ   rK   rL   rM   rN   rO   s         r"   decide_actionr[   b   s]    ( { '!11r$   entriesc           
      \   g }d}| D ]_  }|d   }|j                  d      }|d   }t        ||dd||      }	|dk(  r|dz  }|j                  ||||j                  d	d
      |	d       a t        j                  t
        j                        j                         ||rdndt        |       ||dS )uj   
    spec §2/§3 기반 dispatch 시뮬레이션.
    audit log 포맷(§4.2)에 맞는 dict 반환.
    r   rJ   rO   indexFrZ   rW      reason )r^   rJ   rO   r`   actionapproveddry-runtimestamp_utcrO   approval_modestash_count_before	decisionsskipped_unknown_count)	getr[   appendr   nowr   utc	isoformatlen)
r\   rK   rO   ri   rj   erJ   rN   idxrb   s
             r"   simulate_dispatchrs      s    
 I 8uuYj"
 Y!Q&!eeHb)
 	#4 "hll3==?'.I!'l!6 r$   c               #   p   K   t               } t        | dd       |  t        j                  | d       yw)u-   pre-task stash 1건만 시드된 임시 repo.zWIP: pre-task-2571 stash samplezb.txtT)ignore_errorsN)r#   r5   shutilrmtree)r-   s    r"   pretask_reporx      s0       H;WE
N
MM($/s   46c                    t        |       }t        |      dk(  s
J d|        t        |       }|j                  dg       }t        |      dk(  sJ t        |       }t        |      dk(  sJ dt        |       dt        |              y)ur   
    dry-run 시뮬레이션 후 stash 수가 변하지 않아야 한다.
    (실제 pop/drop 없음 검증)
    r_   u%   시드 후 stash 수가 1이 아님: r\   u;   dry-run 시뮬레이션 후 stash 수가 변경됨: before=z, after=N)rI   rp   rD   rk   )rx   beforedatar\   afters        r"   test_dryrun_stash_not_modifiedr}      s    
 &Fv;!MDVHMM <(Dhhy"%Gw<1%Eu:? 
Ec&k]RZ[^_d[eZfg?r$   c                    t        |       }|j                  dg       }t        |      dk(  sJ t        |dd      }|d   dk(  sJ d|d           t        |d	         dk(  sJ |d	   d
   }|d   dk(  sJ d|d           y)ud   
    APPROVE 미설정 상태에서 pre-task stash 의 action 은 dry-run-pop 이어야 한다.
    r\   r_   F	task-2571rK   rO   rg   rd   u'   approval_mode 기대: dry-run, 실제: ri   r   rb   rR   u$   action 기대: dry-run-pop, 실제: N)rD   rk   rp   rs   )rx   r{   r\   logdecisions        r"   +test_dryrun_decision_pretask_is_dry_run_popr      s     <(Dhhy"%Gw<1
GUK
HC9, 
1#o2F1GH, s; A%%%;"HH. 
.x/A.BC.r$   c           	          t        |       }|j                  dg       }t        |dd      }g d}|D ]*  }||v rJ d| dt        |j	                                        y)	uX   
    시뮬레이션 audit log 가 spec §4.2 필수 필드를 포함해야 한다.
    r\   Fr   r   re   u   audit log 에 'u   ' 필드 없음
log keys: N)rD   rk   rs   rF   keys)rx   r{   r\   r   required_fieldsfields         r"   )test_dryrun_audit_log_has_required_fieldsr      ss     <(Dhhy"%G
GUK
HCSO  
| 	
eW$?SXXZ@P?QR	
|
r$   c                     t        |       }|j                  dg       }t        |dd      }|d   }d|v sd|v sd|v s
J d	|        y
y
y
)uW   
    timestamp_utc 가 UTC timezone-aware ISO 형식이어야 한다 (spec §4.3).
    r\   Fr   r   rf   z+00:00ZUTCu>   timestamp_utc 가 timezone-aware 가 아닌 것으로 보임: NrD   rk   rs   )rx   r{   r\   r   ts_strs        r"   ,test_dryrun_audit_log_timestamp_is_utc_awarer     sh     <(Dhhy"%G
GUK
HC!F#-5F? 
HQB?-r$   c                     t        |       }|j                  dg       }t        |dd      }|d   d   d   |d   d   k(  sJ d|d   d   d    d	|d   d    d
       y)uB   decisions[0].source 가 entries[0].source 와 일치해야 한다.r\   Fr   r   ri   r   rJ   zdecision source (z) != entry source ()Nr   rx   r{   r\   r   s       r"   )test_dryrun_decision_source_matches_entryr     s    <(Dhhy"%G
GUK
HC{Ax(GAJx,@@ 
C,Q/9: ; H-.a	1@r$   c                     t        |       }|j                  dg       }t        |dd      }|d   dk(  sJ |d   d   d	   d
k(  sJ d|d   d   d	           y)u   
    APPROVE=1 로 설정 시 pre-task action 이 'popped' 으로 변경되어야 한다
    (reference implementation 검증).
    r\   Tr   r   rg   rc   ri   r   rb   rQ   u-   APPROVE=1 시 action 기대: popped, 실제: Nr   r   s       r"   1test_dryrun_approve_flag_changes_action_to_poppedr     s}    
 <(Dhhy"%G
GT;
GC:---{Ax(H4 
7K8H8KH8U7VW4r$   )$__doc__r?   r*   rv   r   r9   r   r   r   pathlibr   pytest__file__resolveparentsWORKTREE_ROOTr<   r;   r#   dictr   r5   rD   rF   rI   boolr[   rs   fixturerx   r}   r   r   r   r   r   rY   r$   r"   <module>r      sm    	   
  '  X&&(003*-==
 
$ _# _ _s _t _%c %d %.# .$s) .$,,, , 	,
 *, 4Z, 	,^(tDz (D (3 (4 (^ 0 0&(
 	r$   