
    wjk                        d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
mZ ddlZddlmZ ddlmZmZmZmZ dZddZd	d
ddZd Zd Zd Zd Zy)u  task-2554+2 §5 신규 fixture #5: OWNER_GEMINI_TRIGGER_TOKEN env 부재 시 FAILED + audit.

회장 §명시 (2026-05-12): token_provider 가 빈 문자열을 반환하면 TokenBoundaryViolation
즉시 발생. http_post 0회. audit 에 PENDING 등 사전 기록도 발생하지 않음.

추가: env_override 에 BOT_GITHUB_TOKEN / GH_TOKEN / GITHUB_TOKEN / OWNER_PAT / PAT_TOKEN 등
forbidden token env 가 명시 전달되면 TokenBoundaryViolation. fallback 절대 X.
    )annotationsN)Path)OwnerTriggerAudit)FORBIDDEN_TOKEN_ENV_NAMESOwnerTriggerOnlyTOKEN_ENV_NAMETokenBoundaryViolation(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac                    dddt         dddddddd	}| d
z  }|j                  t        j                  |      d       |S )Nz anu_v2.owner_trigger_decision.v1ztask-2554+2-testi   TFr   "POST_GEMINI_REVIEW_TRIGGER_COMMENTz/gemini review)schematask_idprcurrent_head
queue_headcurrent_head_confirmedgemini_evidence_freshnudge_count_for_pr_headallowed_actioncomment_bodyallowedzdecision.jsonzutf-8)encoding)_HEAD_A
write_textjsondumps)tmp_pathdecisionps      H/home/jay/workspace/anu_v2/tests/test_owner_trigger_token_unavailable.py_write_decisionr"      sT    4%"&!&#$>(H 	?"ALLH%L8H    zowner-tokentokenc               X    g t        |       }fd}t        | |fd|      }||fS )Nc                H    j                  | |t        |      d       ddiS )N)methodpathbodystatus   )appenddictr(   r)   r*   headerspostss       r!   	http_postz _build_module.<locals>.http_post4   s$    d4jIJ#r#   c                      S N r$   s   r!   <lambda>z_build_module.<locals>.<lambda>;   s    u r#   workspace_rootr2   token_provideraudit)r   r   )r   r%   r:   r2   modr1   s    `   @r!   _build_moduler<   0   s>    Eh'E $	C ur#   c                "   t        |       }t        | d      \  }}}t        j                  t        t
              5  |j                  |ddt               ddd       g }||k(  }|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}}y# 1 sw Y   xY w)uO   token_provider 가 빈 문자열 → TokenBoundaryViolation 즉시 fail-closed. r$   matchordecision_pathownerrepocurrent_head_actualN==z%(py0)s == %(py3)sr1   py0py3assert %(py5)spy5)r"   r<   pytestraisesr	   r   trigger_gemini_reviewr   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)	r   rD   r;   r1   r:   @py_assert2@py_assert1@py_format4@py_format6s	            r!   0test_empty_token_raises_token_boundary_violationr_   A   s    #H-M%hb9C	-^	D 
!!' '	 	" 	

 5B;5B55B
 
s   DDc                :  	 t        |       }g 	t        |       }	fd}t        | |d |      }t        j                  t
              5  |j                  |ddt               ddd       g }	|k(  }|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}}y# 1 sw Y   xY w)uN   token_provider 가 None / int / dict 반환 시도 → TokenBoundaryViolation.c                2    j                  d| i       ddiS Nr(   r+   r,   r-   r/   s       r!   r2   zHtest_non_string_token_raises_token_boundary_violation.<locals>.http_postV       h'(#r#   c                      y r4   r5   r5   r#   r!   r6   zGtest_non_string_token_raises_token_boundary_violation.<locals>.<lambda>]       r#   r7   rA   rB   rC   NrH   rJ   r1   rK   rN   rO   )r"   r   r   rP   rQ   r	   rR   r   rS   rT   rU   rV   rW   rX   rY   rZ   )
r   rD   r:   r2   r;   r[   r\   r]   r^   r1   s
            @r!   5test_non_string_token_raises_token_boundary_violationrg   P   s    #H-MEh'E #	C 
-	. 
!!' '	 	" 	

 5B;5B55B
 
s   DDc           	     6   t        |       }t        |       \  }}}t        D ]D  }|di}t        j                  t
        |      5  |j                  |ddt        |       ddd       F g }||k(  }|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}}y# 1 sw Y   xY w)u^   env_override 에 BOT_GITHUB_TOKEN 등 forbidden token 이 명시되면 TokenBoundaryViolation.z
do-not-user?   rA   rB   )rD   rE   rF   rG   env_overrideNrH   rJ   r1   rK   rN   rO   )r"   r<   r   rP   rQ   r	   rR   r   rS   rT   rU   rV   rW   rX   rY   rZ   )r   rD   r;   r1   _	forbiddenri   r[   r\   r]   r^   s              r!   >test_forbidden_token_env_in_override_raises_boundary_violationrl   j   s    #H-M!(+MC. 		!<0]]1C 	%%+$+) & 	 		 5B;5B55B	 	s   DD	c                  
 t        |       }g 
t        |       }
fd}t        | |d |      }t        j                  t
              5  |j                  |ddt               ddd       t        |j                               }g }||k(  }|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}}g }
|k(  }|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}}y# 1 sw Y   pxY w)uo   token 부재 시 PENDING/POSTED/FAILED 어느 record 도 audit 에 남지 않음 (transaction 안에서 raise).c                2    j                  d| i       ddiS rb   rc   r/   s       r!   r2   zDtest_empty_token_does_not_record_pending_in_audit.<locals>.http_post   rd   r#   c                      y)Nr>   r5   r5   r#   r!   r6   zCtest_empty_token_does_not_record_pending_in_audit.<locals>.<lambda>   rf   r#   r7   rA   rB   rC   NrH   rJ   rowsrK   rN   rO   r1   )r"   r   r   rP   rQ   r	   rR   r   list
_iter_rowsrS   rT   rU   rV   rW   rX   rY   rZ   )r   rD   r:   r2   r;   rp   r[   r\   r]   r^   r1   s             @r!   1test_empty_token_does_not_record_pending_in_auditrs   |   sA   #H-MEh'E !	C 
-	. 
!!' '	 	" 	

   "#D42:424425B;5B55B
 
s   GG)r   r   returnr   )r   r   r%   str)__doc__
__future__r   builtinsrU   _pytest.assertion.rewrite	assertionrewriterS   r   pathlibr   rP   anu_v2.owner_trigger_auditr   anu_v2.owner_trigger_onlyr   r   r   r	   r   r"   r<   r_   rg   rl   rs   r5   r#   r!   <module>r      sT    #      8  & 3@ "4$r#   