
    ji                      x   d Z ddlZddlmZ ddlmZmZ ddlZddlm	Z	 ej                  j                  d e ee      j                               ddlmZmZmZ ej&                  dedefd	       Zej&                  dedefd
       Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)u  TDD 테스트 — iptc_tagger.py IPTC/XMP 메타데이터 삽입 유틸리티.

테스트 범위:
- make_xmp_packet(): XMP 패킷 생성 (내용, 형식, trainedAlgorithmicMedia 포함)
- encode_iptc_iim(): IPTC IIM 바이트 인코딩
- tag_image(): PNG/JPEG 파일 태깅
    N)Path)	MagicMockpatch)Image)encode_iptc_iimmake_xmp_packet	tag_imagetmp_pathreturnc                 x    t        j                  ddd      }| dz  }|j                  t        |      d       |S )u)   테스트용 작은 PNG 이미지 생성.RGBd   r   )   r   r   colorztest.pngPNGformatr   newsavestrr
   imgps      :/home/jay/workspace/tools/ai-image-gen/test_iptc_tagger.py
sample_pngr      s9     ))E:[
9C:AHHSVEH"H    c                 x    t        j                  ddd      }| dz  }|j                  t        |      d       |S )u*   테스트용 작은 JPEG 이미지 생성.r   r   )r   r   r   r   ztest.jpgJPEGr   r   r   s      r   sample_jpegr"   #   s9     ))E:[
9C:AHHSVFH#Hr   c                   <    e Zd ZddZddZddZddZddZddZy)	TestMakeXmpPacketNc                 $    t               }d|v sJ y)u@   make_xmp_packet() 반환값에 'trainedAlgorithmicMedia' 포함.trainedAlgorithmicMediaNr   selfresults     r   'test_contains_trained_algorithmic_mediaz9TestMakeXmpPacket.test_contains_trained_algorithmic_media2   s     "(F222r   c                 $    t               }d|v sJ y)u4   반환값에 'Iptc4xmpExt:DigitalSourceType' 포함.zIptc4xmpExt:DigitalSourceTypeNr'   r(   s     r   $test_contains_xmp_iptc_ext_namespacez6TestMakeXmpPacket.test_contains_xmp_iptc_ext_namespace7   s     ".&888r   c                 (    t        d      }d|v sJ y)uC   make_xmp_packet(title='테스트') 반환값에 '테스트' 포함.	   테스트titleNr'   r(   s     r   !test_contains_title_when_providedz3TestMakeXmpPacket.test_contains_title_when_provided<   s     {3f$$$r   c                 *    t        dg      }d|v sJ y)uN   make_xmp_packet(keywords=['AI-generated']) 반환값에 'AI-generated' 포함.AI-generatedkeywordsNr'   r(   s     r   test_contains_keyword_in_outputz1TestMakeXmpPacket.test_contains_keyword_in_outputA   s     >*:;'''r   c                 <    t               }t        |t              sJ y)u   반환값이 str 타입.N)r   
isinstancer   r(   s     r   test_returns_stringz%TestMakeXmpPacket.test_returns_stringF   s     "&#&&&r   c                 >    t               }|j                  d      sJ y)u$   반환값이 '<?xpacket' 로 시작.z	<?xpacketN)r   
startswithr(   s     r   test_xpacket_wrappingz'TestMakeXmpPacket.test_xpacket_wrappingK   s     "  ---r   r   N)	__name__
__module____qualname__r+   r-   r2   r7   r:   r=    r   r   r$   r$   1   s     3
9
%
(
'
.r   r$   c                   ,    e Zd ZddZddZddZddZy)TestEncodeIptcIimNc                 <    t               }t        |t              sJ y)u,   encode_iptc_iim() 반환값이 bytes 타입.N)r   r9   bytesr(   s     r   test_returns_bytesz$TestEncodeIptcIim.test_returns_bytesW   s     "&%(((r   c                 $    t               }d|v sJ y)u(   반환값에 IPTC 마커 b'\x1c' 포함.   Nr   r(   s     r   test_contains_iptc_markerz+TestEncodeIptcIim.test_contains_iptc_marker\   s     "&   r   c                 (    t        d      }d|v sJ y)u=   title 있으면 record=2, dataset=5 (b'\x1c\x02\x05') 포함.u   테스트 타이틀r0   s   NrJ   r(   s     r   )test_with_title_contains_record2_dataset5z;TestEncodeIptcIim.test_with_title_contains_record2_dataset5a   s     '<=&(((r   c                 *    t        dg      }d|v sJ y)u@   keyword 있으면 record=2, dataset=25 (b'\x1c\x02\x19') 포함.r4   r5   s   NrJ   r(   s     r   ,test_with_keyword_contains_record2_dataset25z>TestEncodeIptcIim.test_with_keyword_contains_record2_dataset25f   s     >*:;&(((r   r>   )r?   r@   rA   rG   rK   rM   rO   rB   r   r   rD   rD   V   s    )
!
)
)r   rD   c                   L    e Zd ZdeddfdZdeddfdZdeddfdZdeddfdZy)TestTagImagePngr   r   Nc                 0    t        |ddg      }||k(  sJ y)u8   PNG 태깅 시 입력 경로와 동일한 경로 반환.r/   r4   r1   r6   Nr	   r)   r   r*   s      r   test_returns_same_path_pngz*TestTagImagePng.test_returns_same_path_pngr   s!    :[NCST###r   c                 >    t        |       |j                         sJ y)u   태깅 후 파일이 존재함.Nr	   exists)r)   r   s     r   test_png_tagged_file_existsz+TestTagImagePng.test_png_tagged_file_existsw   s    *  """r   c                 P    t        |d       t        j                  |      }|J y)u1   태깅 후 PIL Image.open()으로 열 수 있음.u   읽기 테스트r0   N)r	   r   open)r)   r   r   s      r   "test_png_is_readable_after_taggingz2TestTagImagePng.test_png_is_readable_after_tagging|   s%    *$67jj$r   c                     t        |ddg       t        j                  |      }|j                  D ch c])  }d|j	                         v sd|j	                         v s(|+ }}t        |      dkD  sJ yc c}w )u/   태깅된 PNG의 info에 XMP 관련 키 존재.u   XMP 테스트r4   rS   xmpxmlr   N)r	   r   r\   infolowerlen)r)   r   r   kxmp_keyss        r   test_png_metadata_contains_xmpz.TestTagImagePng.test_png_metadata_contains_xmp   sh    *O~>NOjj$"xxT!5AGGI+=!'')ASATT8}q    Us   )A4A4)r?   r@   rA   r   rV   rZ   r]   rf   rB   r   r   rQ   rQ   q   sN    $T $d $
#d #t #
T d ! !$ !r   rQ   c                   ,    e Zd ZdeddfdZdeddfdZy)TestTagImageJpegr"   r   Nc                 ,    t        |d      }||k(  sJ y)u%   JPEG 태깅 시 동일 경로 반환.u   JPEG 테스트r0   NrT   )r)   r"   r*   s      r   test_returns_same_path_jpegz,TestTagImageJpeg.test_returns_same_path_jpeg   s    ;.>?$$$r   c                 >    t        |       |j                         sJ y)u   태깅 후 파일 존재.NrX   )r)   r"   s     r   test_jpeg_tagged_file_existsz-TestTagImageJpeg.test_jpeg_tagged_file_exists   s    +!!###r   )r?   r@   rA   r   rj   rl   rB   r   r   rh   rh      s(    %t % %
$ $ $r   rh   c                   <    e Zd ZdeddfdZdeddfdZdeddfdZy)TestTagImageEdgeCasesr
   r   Nc                     |dz  }t        j                  t              5  t        |       ddd       y# 1 sw Y   yxY w)u4   존재하지 않는 파일 전달 시 예외 발생.z	ghost.pngN)pytestraises	Exceptionr	   )r)   r
   nonexistents      r   &test_nonexistent_file_raises_exceptionz<TestTagImageEdgeCases.test_nonexistent_file_raises_exception   s5    ,]]9% 	#k"	# 	# 	#s   4=r   c                 (    t        d      }d|v sJ y)uJ   keywords=None 전달 시 'AI-generated' 자동 포함 (XMP 패킷 확인).Nr5   r4   r'   )r)   r   r_   s      r   *test_default_keywords_include_ai_generatedz@TestTagImageEdgeCases.test_default_keywords_include_ai_generated   s    t,$$$r   c                 >    t        |      }t        |t              sJ y)u   반환값이 Path 타입.N)r	   r9   r   rU   s      r   test_returns_path_typez,TestTagImageEdgeCases.test_returns_path_type   s    :&&$'''r   )r?   r@   rA   r   rt   rv   rx   rB   r   r   rn   rn      s;    #t # #%T %d %
( ($ (r   rn   )__doc__syspathlibr   unittest.mockr   r   rp   PILr   pathinsertr   __file__parentiptc_taggerr   r   r	   fixturer   r"   r$   rD   rQ   rh   rn   rB   r   r   <module>r      s      *   3tH~,,- . C C  $   $ 4  . .J) )6! !>	$ 	$"( (r   