
    6i                      d   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
 ddlmZmZ ej                  j                  dej                  j!                  ej                  j#                  e      d             dZ e
e      j(                  j(                  dz  dz  Zdd	Zd
ede
fdZd Zd Zd Zd Zy)u   
task-1947: blog_writer.py codex/gpt provider → codex-companion.mjs 전환 단위 테스트
테스터: 모리건 (개발3팀)
    N)Path)	MagicMockpatchz..zT/home/jay/.claude/plugins/cache/openai-codex/codex/1.0.3/scripts/codex-companion.mjs	dashboardzblog_writer.pyc                 D    t               }| |_        ||_        ||_        |S N)r   
returncodestdoutstderr)r	   r
   r   mocks       =/home/jay/workspace/tests/test_blog_writer_codex_companion.py_make_mock_resultr      s#    ;D DODKDKK    modeltmp_pathc                 b   |dz  }|dz  }|j                          t        d|      5 }t        dd      5  t        d      5  t        d|d	z        5  t        d
|dz        5  t        d      5  ddlm}  |dgdd| ||       |cddd       cddd       cddd       cddd       cddd       cddd       S # 1 sw Y   nxY wddd       n# 1 sw Y   nxY wddd       n# 1 sw Y   nxY wddd       n# 1 sw Y   nxY wddd       n# 1 sw Y   nxY wddd       y# 1 sw Y   yxY w)uC   _background_blog_generate를 mock 환경에서 실행하는 헬퍼.status.jsonlocksubprocess.runreturn_value.dashboard.blog_writer._build_naver_blog_prompt   테스트 프롬프트/dashboard.blog_writer._update_blog_write_status&dashboard.blog_writer._BLOG_HISTORY_DBblog.db(dashboard.blog_writer._IMAGE_OUTPUT_BASEimagessqlite3.connectr   _background_blog_generate   테스트키워드 	   정보형keywordsadditional_contenttoner   status_path	lock_pathN)touchr   dashboard.blog_writerr!   )r   mock_run_resultr   r)   r*   mock_runr!   s          r   _run_blog_generater/   !   s9   ]*K6!IOO 	_=AI<1	
 	?@ 	698LM 	688K	
 	  	D!*+!#	
 /                      s   D%DC;C&	"C.B<	C	C&		C; 	D)	D%<CC	C&	CC&		C;&C/+C;2	D;D D	D%D	D%%D.c                 
   t        d      }t        d||       }|j                  }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d}|j                  }|d	   d	   }|d	   }d
}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|d	          dz   d|
iz  }t        t        j                  |            dx}x}	}|d   }|t        k(  }	|	st        j                  d|	fd|t        f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}}	|d   }d}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|d          dz   d|
iz  }t        t        j                  |            dx}x}	}t        |      }	d}|	|k(  }|st        j                  d|fd|	|f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      dz  }t        j                  d t        |             d!z   d"|iz  }t        t        j                  |            dx}	x}}d}|dd }||v}	|	st        j                  d#|	fd$||f      t        j                  |      t        j                  |      dz  }
t        j                  d%      dz   d|
iz  }t        t        j                  |            dx}x}	}d&}||v}	|	st        j                  d#|	fd'||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }t        j                  d(      dz   d|iz  }t        t        j                  |            dx}}	y))uk   codex provider가 subprocess.run을 ['node', companion_path, 'task', ...] 형태로 호출하는지 확인.u   codex 생성 결과r
   codex.   subprocess.run이 호출되지 않았습니다,
>assert %(py2)s
{%(py2)s = %(py0)s.called
}r.   py0py2Nr   node==z%(py1)s == %(py4)spy1py45   첫 번째 인자가 'node'여야 합니다. 실제: 
>assert %(py6)spy6   z%(py1)s == %(py3)sCOMPANION_PATHr=   py3=   두 번째 인자가 companion_path여야 합니다. 실제: 
>assert %(py5)spy5   task5   세 번째 인자가 'task'여야 합니다. 실제:    z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slencmdr6   r=   rF   rA   6   명령어 인자 수가 4개여야 합니다. 실제: 
>assert %(py8)spy8not in)z%(py1)s not in %(py4)su>   명령어에 'codex exec' 패턴이 포함되면 안 됩니다execz%(py1)s not in %(py3)s8   명령어에 'exec' 인자가 포함되면 안 됩니다r   r/   called
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation	call_args_call_reprcomparerD   rO   r   mock_resultr.   @py_assert1@py_format3rd   rP   @py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_format4@py_format6@py_assert5@py_assert4@py_format9s                    r   "test_codex_provider_uses_companionrt   E   sg   #+@AK!';AH??L?LLLLLLLLL8LLL8LLL?LLLLLL""I
A,q/Cq6]V]6V]]]6V]]]6]]]V]]]TUXYZU[T\]]]]]]]]q6 6^#  6^          $    $    HAxP     q6]V]6V]]]6V]]]6]]]V]]]TUXYZU[T\]]]]]]]]s8]q]8q=]]]8q]]]]]]3]]]3]]]]]]s]]]s]]]8]]]q]]]RSVWZS[R\]]]]]]]]c#bq'c7'!ccc7'ccc7ccc'ccc#ccccccccX6XXX6XXX6XXXXXXXXXXXXXXXXXXXXr   c                 	   t        d      }t        d||       }|j                  }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d}|j                  }|d	   d	   }|d	   }d
}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|d	          dz   d|
iz  }t        t        j                  |            dx}x}	}|d   }|t        k(  }	|	st        j                  d|	fd|t        f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}}	|d   }d}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|d          dz   d|
iz  }t        t        j                  |            dx}x}	}t        |      }	d}|	|k(  }|st        j                  d|fd|	|f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      dz  }t        j                  d t        |             d!z   d"|iz  }t        t        j                  |            dx}	x}}d#}||v}	|	st        j                  d$|	fd%||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }t        j                  d&      dz   d|iz  }t        t        j                  |            dx}}	y)'uP   gpt(레거시) provider도 codex-companion.mjs를 통해 호출되는지 확인.u   gpt 생성 결과r1   gptr3   r4   r.   r5   Nr   r8   r9   r;   r<   r?   r@   rA   rB   rC   rD   rE   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rW   rU   rX   rY   rZ   rf   s                    r    test_gpt_provider_uses_companionrw   ^   s   #+>?K!%h?H??L?LLLLLLLLL8LLL8LLL?LLLLLL""I
A,q/Cq6]V]6V]]]6V]]]6]]]V]]]TUXYZU[T\]]]]]]]]q6 6^#  6^          $    $    HAxP     q6]V]6V]]]6V]]]6]]]V]]]TUXYZU[T\]]]]]]]]s8]q]8q=]]]8q]]]]]]3]]]3]]]]]]s]]]s]]]8]]]q]]]RSVWZS[R\]]]]]]]]X6XXX6XXX6XXXXXXXXXXXXXXXXXXXXr   c                     t         j                  }  |        }|st        j                  dt                dz   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} }t         j                  d      }d}||v}|st        j                  d	|fd
||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}g } d}||v}|}|rd}	|	|v}
|
}|snt        j                  d	|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }| j                  |       |rt        j                  d	
fd	|f      t        j                  |	      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }| j                  |       t        j                  | d      i z  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x} x}x}x}	}
t        |v } | st        j                  d| fdt        |f      d t	        j
                         v st        j                  t              rt        j                  t              nd dt	        j
                         v st        j                  |      rt        j                  |      ndd!z  }t        j                  d"t         d#      d$z   d%|iz  }t        t        j                  |            d} g } d&}||v }|}|sd'}	|	|v }
|
}|snt        j                  d|fd(||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }| j                  |       |st        j                  d|
fd)|	|f      t        j                  |	      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }| j                  |       t        j                  | d*      i z  }t        j                  d+      dz   d|iz  }t        t        j                  |            dx}x} x}x}x}	}
y),uh   blog_writer.py 소스 코드에 'codex exec' 또는 ['codex', 'exec'] 패턴이 없는지 정적 검증.u4   blog_writer.py 파일이 존재하지 않습니다: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}BLOG_WRITER_PATH)r6   r7   r>   Nzutf-8)encodingz
codex execrU   rX   sourcerE   us   소스 코드에 'codex exec' 문자열이 존재합니다. companion.mjs 전환 후에는 있으면 안 됩니다.rH   rI   z"codex", "exec"z'codex', 'exec')z%(py3)s not in %(py5)srF   rI   %(py7)spy7)z%(py10)s not in %(py12)spy10py12%(py14)spy14r   uu   소스 코드에 ["codex", "exec"] 패턴이 존재합니다. companion.mjs 전환 후에는 있으면 안 됩니다.z
>assert %(py17)spy17in)z%(py0)s in %(py2)srD   r5   u    소스 코드에 companion_path(uE   )가 없습니다. 전환이 적용되지 않았을 수 있습니다.z
>assert %(py4)sr>   z"node"z'node'z%(py3)s in %(py5)sz%(py10)s in %(py12)srB   uz   소스 코드에 'node' 명령어 문자열이 없습니다. companion.mjs 전환이 올바르지 않을 수 있습니다.)ry   existsr\   r]   r^   r_   r`   ra   rb   rc   	read_textre   append_format_booloprD   )rh   rk   rm   r{   rj   rl   ro   rp   rr   @py_assert9@py_assert11@py_format8@py_format13@py_format15@py_format16@py_format18ri   s                    r   test_no_codex_exec_patternr   u   s   ""o"$o$oo(\]m\n&ooooooooooooo"ooo$oooooo'''9F  <v%  <v           &     &    	~    
 F* /@ /@/N   F          %+    %+     /@    0A      IO    IO        	D     
 V#  >V                $    $    +>*::  	A    
8 8v  V!3   8v                   V    "*      .4    .4        	E     r   c                 b	   t        ddd      }| dz  }| dz  }|j                          g fd}t        d|	      5  t        d
d	      5  t        d|      5  t        d| dz        5  t        d| dz        5  t        d      5  ddlm}  |dgddd||       ddd       ddd       ddd       ddd       ddd       ddd       D cg c]  }|j                  d      dk(  s| }}t        |      }d}	||	kD  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      d z  }t        j                  d!      d"z   d#|iz  }t        t        j                  |            dx}x}
}	|d   j                  d$d      }g }d%}||v }
|
}|
sd&}||v }|}|sd'}||v }|}|s t        j                  d(|
fd)||f      t        j                  |      d*t        j                         v st        j                  |      rt        j                  |      nd*d+z  }d,d-|iz  }|j!                  |       |
st        j                  d(fd.|f      t        j                  |      d*t        j                         v st        j                  |      rt        j                  |      nd*d/z  }d0d1|iz  }|j!                  |       |st        j                  d(fd2|f      t        j                  |      d*t        j                         v st        j                  |      rt        j                  |      nd*d3z  }d4d5|iz  }|j!                  |       t        j"                  |d      i z  }t        j                  d6|       d7z   d8|iz  }t        t        j                  |            dx}x}x}x}
x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY wc c}w )9ub   codex companion이 returncode != 0으로 실패할 때 status가 failed로 기록되는지 확인.rB   r#   u   companion 실행 오류 발생)r	   r
   r   r   r   c                 (    j                  |       y r   )r   )_pathdatacaptured_status_callss     r   capture_statusz5test_companion_error_handling.<locals>.capture_status   s    $$T*r   r   r   r   r   r   )side_effectr   r   r   r   r   r   r    r"   r$   r2   r%   Nstatusfailed)>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)srO   failed_callsrQ   u^   companion 실패 시 status='failed'로 _update_blog_write_status가 호출되어야 합니다rS   rT   errorCodexCLIu   오류r   r   	error_msgr|   r}   r~   r   r   r   r   )z%(py17)s in %(py19)s)r   py19z%(py21)spy21uO   에러 메시지에 Codex 오류 관련 내용이 없습니다. 실제 에러: z
>assert %(py24)spy24)r   r+   r   r,   r!   getrO   r\   re   r^   r_   r`   ra   r]   rb   rc   r   r   )r   rg   r)   r*   r   r!   cr   rl   rq   rr   rn   rs   r   rh   rj   r   r   @py_assert16@py_assert18rp   r   r   r   @py_format20@py_format22@py_format23@py_format25r   s                               @r   test_companion_error_handlingr      sV   #qDdeK]*K6!IOO+ 	[9
<1	

 	=&	

 	698LM
 	8(X:MN
 	 
 	D 	"*+!#	
#
 
 
 
 
 
6  5T!h88SATLT| q q    q                             !    	i    
 Q##GR0I7 7i 5 5I#5  Y9N   7i                     5I    $)      -6    -6     Y    :B      FO    FO        ZZcYde      E
 
 
 
 
 
 
 
 
 
 
 
6 Us   RRR*Q8	:Q+QQ+$Q8	,R4R<RR,*R,Q(#Q++Q50Q8	8R=RR
RR	RR))r   u(   생성된 블로그 글 내용입니다.r#   )__doc__builtinsr^   _pytest.assertion.rewrite	assertionrewriter\   ossyspathlibr   unittest.mockr   r   pathinsertjoindirname__file__rD   parentry   r   strr/   rt   rw   r   r    r   r   <module>r      s   
  	 
  * 277<< 94@ A [  >((//+=@PP c d HY2Y.>1r   