
    ix!                         d Z ddlZddlmc mZ ddlZddlZddl	m
Z
mZ ej                  j                  dd       ddlZd Zd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)uS   
통합 테스트: scripts/codex_gate_check.py
task-1837_5.1 - 닌기르수 작성
    N)	MagicMockpatchz/home/jay/workspace/scriptsc                  z   d} t        j                  |       }d}||u}|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}}|d	   }d
}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y)u@   ```json ... ``` 코드 블록에서 JSON을 추출해야 한다.z<Here is the result:
```json
{"pass": true, "risks": []}
```
Nis notz%(py0)s is not %(py3)sresultpy0py3assert %(py5)spy5passTisz%(py1)s is %(py4)spy1py4assert %(py6)spy6risks==z%(py1)s == %(py4)s
codex_gate_check_extract_json_from_output
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation
outputr	   @py_assert2@py_assert1@py_format4@py_format6@py_assert0@py_assert3@py_format5@py_format7s
             8/home/jay/workspace/tests/integration/test_codex_gate.py(test_extract_json_from_output_code_blockr2      s   OF77?F6666&>!T!>T!!!!>T!!!>!!!T!!!!!!!'? b ?b    ?b   ?   b           c                  N   d} t        j                  |       }d}||u}|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}}|d	   }d
}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   }t        |      }d}
||
k(  }|st        j                  d|fd||
f      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |
      dz  }dd|iz  }t        t        j                  |            dx}x}x}}
y)uJ   코드 블록 없이 직접 JSON 객체가 있을 때 추출해야 한다.zYSome text {"pass": false, "risks": [{"severity": "critical", "description": "test"}]} endNr   r   r	   r
   r   r   r   Fr   r   r   r   r   r      r   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)slen)r   py2r   py7zassert %(py9)spy9)r   r   r   r    r!   r"   r#   r$   r%   r&   r6   )r(   r	   r)   r*   r+   r,   r-   r.   r/   r0   @py_assert6@py_assert5@py_format8@py_format10s                 r1   )test_extract_json_from_output_direct_jsonr>      sC   hF77?F6666&>"U">U"""">U""">"""U"""""""g$3$1$1$$$$1$$$$$$3$$$3$$$$$$$$$1$$$$$$$r3   c                  x   t        j                  d      } d}| |u }|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)	uE   JSON이 없거나 잘못된 형식이면 None을 반환해야 한다.zNo JSON here at all.Nr   z%(py0)s is %(py3)sr	   r
   r   r   r   )r	   r)   r*   r+   r,   s        r1   2test_extract_json_from_output_invalid_returns_nonerA   "   sk    778NOF6T>6T66Tr3   c                  |   d} t        j                  |       }d}||u }|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)	u`   코드 블록 내 JSON이 파싱 불가이면 직접 JSON도 시도하고 없으면 None 반환.z,```json
{broken json
```
also no direct jsonNr   r@   r	   r
   r   r   r   )r(   r	   r)   r*   r+   r,   s         r1   2test_extract_json_from_output_broken_json_in_blockrC   (   so    >F77?F6T>6T66Tr3   c                  |   d} t        j                  |       }d}||u}|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}}|d	   }d
}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y)uY   코드 블록이 있으면 직접 JSON보다 코드 블록을 우선 처리해야 한다.z4```json
{"source": "block"}
```
{"source": "direct"}Nr   r   r	   r
   r   r   sourceblockr   r   r   r   r   r   r'   s
             r1   7test_extract_json_from_output_code_block_takes_priorityrG   /   s    FF77?F6666(&w&w&&&&w&&&&&&w&&&&&&&r3   c                    t        | dz        }t        j                  |g t        |             }|d   }d}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|d
   }d}||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}d |d   D        }t        |      }|sddt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |      t        j
                  |      dz  }t        t        j                  |            d	x}}y	)uR   task_file이 없으면 critical 리스크가 포함되고 pass=False여야 한다.znonexistent_task.mdr   Fr   r   r   r   r   NrE   maat_fallbackr   r   c              3   ,   K   | ]  }|d    dk(    ywseveritycriticalN .0rs     r1   	<genexpr>z=test_maat_fallback_check_task_file_missing.<locals>.<genexpr>?        Dqq}
*D   r   ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr   r7   r   )strr   _maat_fallback_checkr   r    r$   r%   r&   rV   r!   r"   r#   )	tmp_pathmissing_taskr	   r-   r.   r)   r/   r0   r*   s	            r1   *test_maat_fallback_check_task_file_missingr\   9   s-   x"778L22<S]SF&>"U">U"""">U""">"""U"""""""(...................DF7ODD3DDDDDDDDD3DDD3DDDDDDDDDDDDDDr3   c                    | dz  }|j                  dd       | dz  }|j                  dd       t        j                  t        |      t        |      gt        |             }|d   }d}||u }|slt	        j
                  d	|fd
||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }g }||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}y)uM   task_file이 존재하고 affected_files도 있으면 pass=True여야 한다.task.mdu'   # 설계 문서
내용이 있습니다.utf-8encodingzcode.pyzdef foo(): passr   Tr   r   r   r   r   Nr   r   r   rE   rI   )	
write_textr   rY   rX   r   r    r$   r%   r&   )	rZ   	task_fileaffectedr	   r-   r.   r)   r/   r0   s	            r1   .test_maat_fallback_check_task_file_exists_passre   B   sS   9$ICgV)#H)G<22IXXF &>!T!>T!!!!>T!!!>!!!T!!!!!!!'? b ?b    ?b   ?   b       (...................r3   c                 F   | dz  }|j                  dd       t        | dz        }t        j                  t        |      |gt        |             }|d   }d}||u }|slt	        j
                  d|fd	||f      t	        j                  |      t	        j                  |      d
z  }dd|iz  }t        t	        j                  |            dx}x}}|d   D 	cg c]  }	|	d   dk(  s|	d    }
}	d |
D        }t        |      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }t        t	        j                  |            dx}}yc c}	w )uy   task_file은 존재하지만 affected_files 중 기존 파일이 없으면 high 리스크 발생 (PASS, critical 아님).r^      # 설계 문서
내용r_   r`   not_here.pyr   Tr   r   r   r   r   Nr   rL   highdescriptionc              3   $   K   | ]  }d |v  
 yw)rh   NrN   )rP   ds     r1   rR   zAtest_maat_fallback_check_affected_file_missing.<locals>.<genexpr>\   s     6a}!6s   rU   rV   rW   )rb   rX   r   rY   r   r    r$   r%   r&   rV   r!   r"   r#   )rZ   rc   missing_filer	   r-   r.   r)   r/   r0   rQ   
high_descsr*   s               r1   .test_maat_fallback_check_affected_file_missingro   Q   s-   9$I2WEx-/0L22IHF &>!T!>T!!!!>T!!!>!!!T!!!!!!!,27OWqq}PV?V!M"WJW6:6636666666663666366666666666666 Xs   F%Fc                    | dz  }|j                  dd       t        j                  t        |      g t        |             }|d   }d}||u }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      d	z  }d
d|iz  }t        t	        j                  |            dx}x}}d |d   D        }t        |      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }t        t	        j                  |            dx}}y)uW   task_file이 존재하지만 비어있으면 critical 리스크가 발생해야 한다.zempty_task.mdz   r_   r`   r   Fr   r   r   r   r   Nc              3   ,   K   | ]  }|d    dk(    ywrK   rN   rO   s     r1   rR   z;test_maat_fallback_check_empty_task_file.<locals>.<genexpr>f   rS   rT   r   rU   rV   rW   )rb   r   rY   rX   r   r    r$   r%   r&   rV   r!   r"   r#   )	rZ   rc   r	   r-   r.   r)   r/   r0   r*   s	            r1   (test_maat_fallback_check_empty_task_filerr   _   s    ?*I1223y>2s8}UF&>"U">U"""">U""">"""U"""""""DF7ODD3DDDDDDDDD3DDD3DDDDDDDDDDDDDDr3   c                 6   | dz  }|j                  dd       t               }d|_        t        j                  dg dgd      |_        d	|_        t        d
|      5  t        j                  t        |      g t        |             }ddd       d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   	xY w)uM   Codex CLI가 pass=True JSON을 반환하면 결과도 pass=True여야 한다.r^   rg   r_   r`   r   TzGood design)r   r   suggestions subprocess.runreturn_valueNr   r   r   r   r   r   r   r   r   rE   codex_companionerror)rb   r   
returncodejsondumpsstdoutstderrr   r   rX   r   r    r$   r%   r&   	rZ   rc   mock_resultr	   r-   r.   r)   r/   r0   s	            r1   test_codex_gate_check_successr   k   s   9$I2WE+KK%% K
 K	k	: 
!22	NBH


 &>!T!>T!!!!>T!!!>!!!T!!!!!!!'? b ?b    ?b   ?   b       (00000000000000000000000'?"d"?d""""?d"""?"""d"""""""
 
s   *JJc                    | dz  }|j                  dd       t               }d|_        t        j                  dddgd	gd
      |_        d|_        t        d|      5  t        j                  t        |      g t        |             }ddd       d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}d |d   D        }	t        |	      }|sddt!        j"                         v st        j$                  t              rt        j                  t              ndt        j                  |	      t        j                  |      dz  }t        t        j                  |            dx}	}y# 1 sw Y   xY w)uH   Codex CLI가 critical 리스크를 반환하면 pass=False여야 한다.r^   u   # 설계 문서r_   r`   r   rM   zSQL injection risk)rL   rj   zFix it)r   rt   ru   rv   rw   Nr   Fr   r   r   r   r   rE   ry   r   r   c              3   ,   K   | ]  }|d    dk(    ywrK   rN   rO   s     r1   rR   z;test_codex_gate_check_with_critical_risk.<locals>.<genexpr>   rS   rT   r   rU   rV   rW   )rb   r   r{   r|   r}   r~   r   r   r   rX   r   r    r$   r%   r&   rV   r!   r"   r#   )
rZ   rc   r   r	   r-   r.   r)   r/   r0   r*   s
             r1   (test_codex_gate_check_with_critical_riskr      s   9$I*W=+KK):NOP z% K K	k	: 
!22	NBH


 &>"U">U"""">U""">"""U"""""""(00000000000000000000000DF7ODD3DDDDDDDDD3DDD3DDDDDDDDDDDDDD
 
s    *IIc                    | dz  }|j                  dd       t               }d|_        d|_        d|_        t        d|	      5  t        j                  t        |      g t        |             }d
d
d
       d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}x}}y
# 1 sw Y   xY w)uV   Codex CLI 비정상 종료(returncode!=0) 시 maat_fallback으로 전환해야 한다.r^   rg   r_   r`   r5   ru   zError: codex failedrv   rw   NrE   rI   r   r   r   r   r   rb   r   r{   r~   r   r   r   rX   r   r    r$   r%   r&   r   s	            r1   ;test_codex_gate_check_nonzero_returncode_falls_back_to_maatr      s    9$I2WE+KKK.K	k	: 
!22	NBH


 (...................
 
   *C88Dc                    ddl }| dz  }|j                  dd       t        d|j                  dd	
            5  t	        j                  t        |      g t        |             }ddd       d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   xY w)uC   Codex CLI 타임아웃 시 maat_fallback으로 전환해야 한다.r   Nr^   rg   r_   r`   rv   codexx   )cmdtimeoutside_effectrE   rI   r   r   r   r   r   )
subprocessrb   r   TimeoutExpiredr   rX   r   r    r$   r%   r&   )	rZ   r   rc   r	   r-   r.   r)   r/   r0   s	            r1   0test_codex_gate_check_timeout_falls_back_to_maatr      s    9$I2WE	Z-F-F7\_-F-`	a 
!22	NBH


 (...................
 
s   *C..C7c                    | dz  }|j                  dd       t        dt        d            5  t        j                  t	        |      g t	        |             }ddd       d	   }d
}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   xY w)u`   Codex CLI 실행파일 없을 때 FileNotFoundError → maat_fallback으로 전환해야 한다.r^   rg   r_   r`   rv   zcodex not foundr   NrE   rI   r   r   r   r   r   )
rb   r   FileNotFoundErrorr   rX   r   r    r$   r%   r&   )rZ   rc   r	   r-   r.   r)   r/   r0   s           r1   7test_codex_gate_check_file_not_found_falls_back_to_maatr      s    9$I2WE	->?P-Q	R 
!22	NBH


 (...................
 
s   *C""C+c                    | dz  }|j                  dd       t               }d|_        d|_        d|_        t        d|	      5  t        j                  t        |      g t        |             }d
d
d
       d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}x}}y
# 1 sw Y   xY w)uZ   Codex CLI가 JSON 파싱 불가 응답 반환 시 maat_fallback으로 전환해야 한다.r^   rg   r_   r`   r   zThis is not JSON at all!ru   rv   rw   NrE   rI   r   r   r   r   r   r   r   s	            r1   >test_codex_gate_check_invalid_json_response_falls_back_to_maatr      s    9$I2WE+KK3KK	k	: 
!22	NBH


 (...................
 
r   )__doc__builtinsr!   _pytest.assertion.rewrite	assertionrewriter   r|   sysunittest.mockr   r   pathinsertr   r2   r>   rA   rC   rG   r\   re   ro   rr   r   r   r   r   r   r   rN   r3   r1   <module>r      s}   
   
 * 0 1 
!%'E/7E#2E./$/
//r3   