
    i:%                     <   d Z ddlZddlZddlmZ ddlZej                  j                  d e ee	      j                  j                  j                               ddlmZmZmZ  G d d      Z G d d      Z G d	 d
      Zedk(  r ej&                  e	dg       yy)u#   utils/redact.py 테스트 스위트    N)Path)RedactingFormatterredact_sensitive_textsetup_redacted_loggingc                       e 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d Zd Zd Zd Zd Zd Zd Zd Zy)TestRedactSensitiveTextu(   redact_sensitive_text() 패턴 테스트c                 $    t        d      dk(  sJ y)u(   일반 텍스트는 변경 없이 통과zhello worldNr   selfs    H/home/jay/workspace/.worktrees/task-2116-dev1/utils/tests/test_redact.pytest_passthrough_plain_textz3TestRedactSensitiveText.test_passthrough_plain_text   s    $]3}DDD    c                     t        d      J y)u   None 입력은 None 반환Nr
   r   s    r   test_none_returns_nonez.TestRedactSensitiveText.test_none_returns_none   s    $T*222r   c                 $    t        d      dk(  sJ y)u   빈 문자열 통과 Nr
   r   s    r   test_empty_stringz)TestRedactSensitiveText.test_empty_string   s    $R(B...r   c                 (    t        d      }|dk(  sJ y)u*   비문자열은 str()로 변환 후 처리*   42Nr
   )r   results     r   test_non_string_coercedz/TestRedactSensitiveText.test_non_string_coerced   s    &r*~~r   c                 B    d}t        |      }d|vsJ d|v sJ d|v sJ y)u%   sk-로 시작하는 API 키 마스킹%key=sk-abcdefghijklmnopqrstuvwxyz1234!sk-abcdefghijklmnopqrstuvwxyz1234zsk-abc1234Nr
   r   textr   s      r   test_sk_token_maskedz,TestRedactSensitiveText.test_sk_token_masked$   s;    6&t,2&@@@6!!!r   c                 *    d}t        |      }d|vsJ y)u"   sk-ant- Anthropic 토큰 마스킹z6ANTHROPIC_API_KEY=sk-ant-api03-verylongkeyhere12345678zapi03-verylongkeyhere12345678Nr
   r   s      r   test_sk_ant_token_maskedz0TestRedactSensitiveText.test_sk_ant_token_masked,   s    G&t,.f<<<r   c                 *    d}t        |      }d|vsJ y)u   ghp_ GitHub PAT 마스킹z(token=ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcd"ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdNr
   r   s      r   test_github_pat_classic_maskedz6TestRedactSensitiveText.test_github_pat_classic_masked3   s    9&t,36AAAr   c                 *    d}t        |      }d|vsJ y)u#   github_pat_ 세밀한 PAT 마스킹+github_pat_ABCDEFGHIJKLMNOPQRSTUVWXYZ123456 ABCDEFGHIJKLMNOPQRSTUVWXYZ123456Nr
   r   s      r   #test_github_pat_fine_grained_maskedz;TestRedactSensitiveText.test_github_pat_fine_grained_masked9   s    <&t,1???r   c                 *    d}t        |      }d|vsJ y)u    AKIA AWS Access Key ID 마스킹z&AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLEAKIAIOSFODNN7EXAMPLENr
   r   s      r   test_aws_access_key_maskedz2TestRedactSensitiveText.test_aws_access_key_masked@   s    7&t,%V333r   c                 *    d}t        |      }d|vsJ y)u   sk_live_ Stripe 키 마스킹z'STRIPE_KEY=sk_live_abcdefghijklmnopqrstsk_live_abcdefghijklmnopqrstNr
   r   s      r   test_stripe_live_key_maskedz3TestRedactSensitiveText.test_stripe_live_key_maskedG   s    8&t,-V;;;r   c                 6    d}t        |      }d|vsJ d|v sJ y)u%   KEY=value 형태 ENV 할당 마스킹z0OPENAI_API_KEY=super_secret_key_value_here_12345!super_secret_key_value_here_12345zOPENAI_API_KEY=Nr
   r   s      r   test_env_assignment_api_keyz3TestRedactSensitiveText.test_env_assignment_api_keyN   s-    A&t,2&@@@ F***r   c                 *    d}t        |      }d|vsJ y)u1   KEY='value' 따옴표 포함 ENV 할당 마스킹z4DATABASE_PASSWORD='my_very_long_secret_password_xyz' my_very_long_secret_password_xyzNr
   r   s      r   test_env_assignment_quotedz2TestRedactSensitiveText.test_env_assignment_quotedU   s    E&t,1???r   c                 *    d}t        |      }d|vsJ y)u   JSON apiKey 필드 마스킹z*{"apiKey": "supersecretlongvalue12345678"}supersecretlongvalue12345678Nr
   r   s      r   test_json_api_key_fieldz/TestRedactSensitiveText.test_json_api_key_field\   s    ;&t,-V;;;r   c                 *    d}t        |      }d|vsJ y)u   JSON token 필드 마스킹z0{"token": "bearer_token_value_very_long_string"}#bearer_token_value_very_long_stringNr
   r   s      r   test_json_token_fieldz-TestRedactSensitiveText.test_json_token_fieldb   s    A&t,4FBBBr   c                 6    d}t        |      }d|vsJ d|v sJ y)u&   Authorization: Bearer 헤더 마스킹z5Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpeyJhbGciOiJSUzI1NiIsInR5cCI6IkpzAuthorization: BearerNr
   r   s      r   test_auth_bearer_headerz/TestRedactSensitiveText.test_auth_bearer_headeri   s-    F&t,0>>>&&000r   c                 6    d}t        |      }d|vsJ d|v sJ y)u   Telegram bot 토큰 마스킹z0bot123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi	123456789Nr
   r   s      r   test_telegram_bot_tokenz/TestRedactSensitiveText.test_telegram_bot_tokenq   s-    A&t,4FBBBf$$$r   c                 6    d}t        |      }d|vsJ d|v sJ y)u'   PEM 형식 Private Key 블록 마스킹zN-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA
-----END RSA PRIVATE KEY-----MIIEpAIBAAKCAQEAz[REDACTED PRIVATE KEY]Nr
   r   s      r   test_private_key_blockz.TestRedactSensitiveText.test_private_key_blocky   s-    a&t,!///'6111r   c                 B    d}t        |      }d|vsJ d|v sJ d|v sJ y)u2   PostgreSQL 연결 문자열 비밀번호 마스킹z4postgresql://user:mysecretpassword@localhost:5432/dbmysecretpasswordzpostgresql://user:z
@localhostNr
   r   s      r   test_postgres_connection_stringz7TestRedactSensitiveText.test_postgres_connection_string   s;    E&t,!///#v---v%%%r   c                 *    d}t        |      }d|vsJ y)u-   MySQL 연결 문자열 비밀번호 마스킹z-mysql://admin:p@ssw0rd123@db.example.com/mydbzp@ssw0rd123Nr
   r   s      r   test_mysql_connection_stringz4TestRedactSensitiveText.test_mysql_connection_string   s    >&t,F***r   c                 4    d}t        |      }d|v sd|vsJ yy)u/   18자 미만 토큰은 *** 로 완전 마스킹zAPI_KEY=short_val_xz***short_val_xNr
   r   s      r   test_short_token_fully_maskedz5TestRedactSensitiveText.test_short_token_fully_masked   s,     %&t,-v"==="=r   c                 P    |j                  dd       d}t        |      }||k(  sJ y)u?   DISABLE_REDACT_SECRETS=1 환경변수로 마스킹 비활성화DISABLE_REDACT_SECRETS1r   N)setenvr   )r   monkeypatchr   r   s       r   test_env_disabled_via_envvarz4TestRedactSensitiveText.test_env_disabled_via_envvar   s.    3S92&t,~~r   N)__name__
__module____qualname____doc__r   r   r   r   r    r"   r%   r)   r,   r/   r2   r5   r8   r;   r>   rB   rE   rH   rJ   rM   rS    r   r   r   r      ss    2E3/ =B@4<+@<C1%2&+>r   r   c                       e Zd ZdZd Zd Zy)TestRedactingFormatteru-   RedactingFormatter 로그 포맷터 테스트c           	          t        d      }t        j                  dt        j                  ddddd	      }|j	                  |      }d
|vsJ y)u'   로그 메시지에서 비밀 마스킹%(message)sfmttestr   r   r   rX   Nnamelevelpathnamelinenomsgargsexc_infor   r   logging	LogRecordINFOformatr   	formatterrecordoutputs       r   #test_formatter_masks_secrets_in_logz:TestRedactingFormatter.test_formatter_masks_secrets_in_log   sU    &=9	"",,7
 !!&)2&@@@r   c           	          t        d      }t        j                  dt        j                  ddddd	      }|j	                  |      }d|v sJ y)
u(   일반 메시지는 변경 없이 통과r\   r]   r_   r   r   znormal log messagerX   Nr`   rh   rm   s       r    test_formatter_passes_plain_textz7TestRedactingFormatter.test_formatter_passes_plain_text   sU    &=9	"",,$
 !!&)#v---r   N)rT   rU   rV   rW   rq   rs   rX   r   r   rZ   rZ      s    7A.r   rZ   c                   "    e Zd ZdZd Zd Zd Zy)TestSetupRedactedLoggingu)   setup_redacted_logging() 통합 테스트c                 d   t        j                  d      }|j                  j                          t        j                         }|j                  t        j                  d             |j                  |       t        |       |j                  D ]  }t        |j                  t              rJ  y)u*   기존 로거에 RedactingFormatter 적용ztest.setup_redactr\   N)ri   	getLoggerhandlersclearStreamHandlersetFormatter	Formatter
addHandlerr   
isinstancern   r   r   loggerhandlerhs       r   test_applies_to_existing_loggerz8TestSetupRedactedLogging.test_applies_to_existing_logger   s    ""#67'')W..}=>'"v&  	?Aakk+=>>>	?r   c                 h   t        j                         }t        |j                        }t        j                         }|j                  t        j                  d             |j                  |       	 t                |j                  D ]  }t        |j                  t              rJ  	 |j                  |       t        |j                        D ]  }||vs|j                  |        y# |j                  |       t        |j                        D ]  }||vs|j                  |        w xY w)u0   인수 없이 호출 시 루트 로거에 적용r\   N)ri   rw   listrx   rz   r{   r|   r}   r   r~   rn   r   removeHandler)r   rootoriginal_handlerstest_handlerr   s        r   &test_applies_to_root_logger_by_defaultz?TestSetupRedactedLogging.test_applies_to_root_logger_by_default   s	     " / ,,.!!'"3"3M"BC%
	*"$]] C!!++/ABBBC |,$--( *--&&q)* |,$--( *--&&q)*s   43C. (C. ..D1D1c                    t        j                  d      }|j                  j                          t        j                         }|j                  |       t        |       |j                  D ]  }t        |j                  t              rJ  y)u5   formatter가 없는 핸들러도 오류 없이 처리ztest.no_formatterN)
ri   rw   rx   ry   rz   r}   r   r~   rn   r   r   s       r   *test_no_error_on_handler_without_formatterzCTestSetupRedactedLogging.test_no_error_on_handler_without_formatter   sq    ""#67'')'" 	v& 	?Aakk+=>>>	?r   N)rT   rU   rV   rW   r   r   r   rX   r   r   ru   ru      s    3?*,?r   ru   __main__z-v)rW   ri   syspathlibr   pytestpathinsertstr__file__parentutils.redactr   r   r   r   rZ   ru   rT   mainrX   r   r   <module>r      s    )  
   3tH~,,33::; < Z ZO Od. .D4? 4?n zFKK4 ! r   