
    mj                        d dl mZ d dlZd dlmc mZ d dlm	Z	 d dl
Z
d dlmZmZ dd	Zdd
ZddZddZddZddZddZddZddZe
j                            dg d          d d            ZddZddZddZddZddZddZddZ dS )!    )annotationsN)Path)assert_safe	scan_pathtmp_pathr   returnNonec                   | dz                       d           t          |           }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}}d S )Nzfinance.sqlite3znot realc              3  (   K   | ]}d |j         v V  dS )forbidden_file_typeNreason.0fs     F/home/agent/.hermes/repos/FinanceManager/tests/unit/test_git_safety.py	<genexpr>z9test_git_safety_blocks_sqlite_database.<locals>.<genexpr>   s*      CCQ$0CCCCCC    ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anypy0py2py4

write_textr   r   @py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationr   findings@py_assert1@py_assert3@py_format5s        r   &test_git_safety_blocks_sqlite_databaser)   
   s    !!--j999""HCC(CCCC3CCCCCCCCCCCCCCCC3CCCCC3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCr   c                (   | dz                       d           | dz                       d           t          |           }t          |          }d}||k    }|st          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  }dd|iz  }t          t          j
        |                    d x}x}}t          j        t                    5  t          |            d d d            d S # 1 swxY w Y   d S )Nz.envz
TOKEN=demozclient_secret.json{}   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slenr%   r   py1py3py6assert %(py8)spy8)r   r   r.   r   _call_reprcomparer   r   r    r!   r"   r#   pytestraises
ValueErrorr   )r   r%   @py_assert2@py_assert5@py_assert4@py_format7@py_format9s          r   *test_git_safety_blocks_env_and_credentialsr>      s   ""<000$$00666""Hx==A=A=A33xx=A	z	"	"  H                 s   *FFFc                   | dz  dz  }|                     d           |dz                      d           t          |           }g }||k    }|st          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  }dd|iz  }t          t          j
        |                    d x}x}}d S )Nexamples	syntheticTparentszaccounts.csvplatform_name
Demo
==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr   r   r/   r3   r4   mkdirr   r   r   r5   r   r   r    r!   r"   r#   )r   r@   r9   r:   r;   r<   r=   s          r   )test_git_safety_allows_synthetic_examplesrJ      se   *${2HNN4N   **+BCCCX$"$"$$$$$$$$$$"$$$$$$$$$$$$9$$$$$9$$$$$$$$$$$$$X$$$$$X$$$$$$$$$$"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$r   c                &   | dz  dz  }|                     d           |dz                      d           |dz                      d           | d	z  }|                                  |d
z                      d           t          |           }g }||k    }|st          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  }dd|iz  }t          t          j
        |                    d x}x}}d S )NtestsfixturesTrB   zsynthetic_accounts.csvrD   zsynthetic_payload.jsonz{"kind":"synthetic"}zconfig.examplezsettings.jsonz{"token":"replace-me"}rE   rG   r   r   r/   r3   r4   rH   )r   rM   config_exampler9   r:   r;   r<   r=   s           r   Atest_git_safety_allows_tests_fixtures_and_config_example_csv_jsonrO       s   '!J.HNN4N   ((445LMMM((445KLLL 00No%112JKKKX$"$"$$$$$$$$$$"$$$$$$$$$$$$9$$$$$9$$$$$$$$$$$$$X$$$$$X$$$$$$$$$$"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$r   c                     dz  dz  dz  j                             d                               d            dz  dz  }|                    d           t                     } f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}x}}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}}d S )Ndocszfinance-manager-2.0z>FinanceManager_Umsetzungs_und_Zielkonzept_v2.2_2026-08-01.docxTrB   s   canonical concept placeholderz
other.docxs   must stay blockedc              3  x   K   | ]4}|j                                                                       k    V  5d S )N)pathrelative_toas_posix)r   r   	canonicalr   s     r   r   zQtest_git_safety_allows_only_the_canonical_product_concept_docx.<locals>.<genexpr>9   sD      ZZA16Y228<<EEGGGZZZZZZr   z0assert not %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}r   r   c              3  B   K   | ]}|j         d k    o
|j        dk    V  dS )zdocs/other.docxzforbidden_file_type:.docxNrS   r   r   s     r   r   zQtest_git_safety_allows_only_the_canonical_product_concept_docx.<locals>.<genexpr>:   s8      ii[\qv**Vqx;V/Viiiiiir   r   parentrI   write_bytesr   r   r   r   r   r    r!   r"   r#   )	r   blockedr%   r&   r'   r:   @py_format6r(   rV   s	   `       @r   >test_git_safety_allows_only_the_canonical_product_concept_docxr^   +   s   
	
	  K	K  4(((:;;;,.G,---""HZZZZZQYZZZZsZZZZZZZZZZZZZZZZZZZsZZZZZsZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZii`hiiii3iiiiiiiiiiiiiiii3iiiii3iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiir   c                   | dz  dz  dz  }|                     d           |dz                      d           t          |           }g }||k    }|st          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  }dd|iz  }t          t          j
        |                    d x}x}}d S )Nsrcjarvis_financeimportsTrB   znormal_module.pyzxfrom __future__ import annotations

def parse_token_name(token_name: str) -> str:
    return token_name.strip().lower()
rE   rG   r   r   r/   r3   r4   rH   )r   r`   r9   r:   r;   r<   r=   s          r   ;test_git_safety_does_not_false_positive_normal_source_filesrc   =   sv   
U
-
-	
9CIIdI))	2  
 X$"$"$$$$$$$$$$"$$$$$$$$$$$$9$$$$$9$$$$$$$$$$$$$X$$$$$X$$$$$$$$$$"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$r   c                x   | dz                                    | dz  dz                      d           | dz                      d           | dz                                    | dz  dz                      d           t          |           }d	 |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}}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}}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}}d S )Ndataportfolio.csvzreal-ishzGithub_token_secret.txtplaceholderruntimez
cache.jsonr+   c                    g | ]	}|j         
S  r   r   s     r   
<listcomp>zOtest_git_safety_blocks_runtime_dirs_db_json_and_token_names.<locals>.<listcomp>O   s    ***Aqx***r   c              3     K   | ]}d |v V  	dS )&runtime_or_real_data_directory_blockedNrj   r   rs     r   r   zNtest_git_safety_blocks_runtime_dirs_db_json_and_token_names.<locals>.<genexpr>P   s(      NN71<NNNNNNr   r   r   r   c              3     K   | ]}d |v V  	dS )forbidden_secret_like_filenameNrj   rn   s     r   r   zNtest_git_safety_blocks_runtime_dirs_db_json_and_token_names.<locals>.<genexpr>Q   s(      FF/14FFFFFFr   c              3     K   | ]}d |v V  	dS )csv_json_only_allowedNrj   rn   s     r   r   zNtest_git_safety_blocks_runtime_dirs_db_json_and_token_names.<locals>.<genexpr>R   s(      ==&!+======r   )rI   r   r   r   r   r   r   r    r!   r"   r#   )r   r%   reasonsr&   r'   r(   s         r   ;test_git_safety_blocks_runtime_dirs_db_json_and_token_namesru   H   s   (44Z@@@))55mDDD	  """	L(44T:::""H*****GNNgNNNN3NNNNNNNNNNNNNNNN3NNNNN3NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFgFFFF3FFFFFFFFFFFFFFFF3FFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF==W====3================3=====3=================================r   c                   | dz                       d           t          |           }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}}d S )N	notes.txtz1token=github_pat_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc              3  ,   K   | ]}|j         d k    V  dS )zsecret_pattern:github_patNr   r   s     r   r   z=test_git_safety_blocks_github_pat_patterns.<locals>.<genexpr>X   *      II1qx66IIIIIIr   r   r   r   r   r$   s        r   *test_git_safety_blocks_github_pat_patternsrz   U   s    ''(FGGG""HIIIIII3IIIIIIIIIIIIIIII3IIIII3IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIr   c                   | dz                       d           t          |           }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}}d S )Nrw   z.token=ghp_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBc              3  ,   K   | ]}|j         d k    V  dS )zsecret_pattern:github_ghpNr   r   s     r   r   z=test_git_safety_blocks_github_ghp_patterns.<locals>.<genexpr>^   ry   r   r   r   r   r   r$   s        r   *test_git_safety_blocks_github_ghp_patternsr}   [   s    ''(?@@@""HIIIIII3IIIIIIIIIIIIIIII3IIIII3IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIr   )labelcontent))bearer_tokenz6Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
openai_keyz2OPENAI_API_KEY=sk-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB)slack_tokenz1SLACK_TOKEN=xoxb-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCr~   strr   c                   | dz                       |           t          |           }f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}}d S )Nrw   c              3  4   K   | ]}|j         d  k    V  dS )zsecret_pattern:Nr   )r   r   r~   s     r   r   zNtest_git_safety_blocks_additional_cleartext_secret_patterns.<locals>.<genexpr>n   s3      GGqx4U444GGGGGGr   r   r   r   r   )r   r~   r   r%   r&   r'   r(   s    `     r   ;test_git_safety_blocks_additional_cleartext_secret_patternsr   a   s     ''000""HGGGGhGGGG3GGGGGGGGGGGGGGGG3GGGGG3GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGr   c                   | dz                       d           t          |           }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}}d S )Nz
id_rsa.txtz_-----BEGIN OPENSSH PRIVATE KEY-----
synthetic-not-a-real-key
-----END OPENSSH PRIVATE KEY-----
c              3  ,   K   | ]}|j         d k    V  dS )zsecret_pattern:private_keyNr   r   s     r   r   z6test_git_safety_blocks_private_keys.<locals>.<genexpr>x   s*      JJAqx77JJJJJJr   r   r   r   r   r$   s        r   #test_git_safety_blocks_private_keysr   q   s    ((	.  
 ""HJJJJJJ3JJJJJJJJJJJJJJJJ3JJJJJ3JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJr   c                   | dz                       d           | dz                       d           d t          |           D             }|j        }d} ||          }d}||k    }|st          j        d|fd	||f          d
t          j                    v st          j        |          rt          j        |          nd
t          j        |          t          j        |          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}x}x}}d S )Nrf   zaccount,balance
Demo,1
zexport.jsonz{"realistic":"blocked"}c                    g | ]	}|j         
S rj   r   r   s     r   rk   zItest_git_safety_blocks_csv_json_outside_allowed_paths.<locals>.<listcomp>~   s    555Aqx555r   =csv_json_only_allowed_in_examples_synthetic_or_tests_fixturesr,   rE   )zK%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.count
}(%(py4)s)
} == %(py9)srt   )r   r   r   r2   py9zassert %(py11)spy11)r   r   countr   r5   r   r   r    r!   r"   r#   )	r   rt   r&   r'   r:   @py_assert8@py_assert7@py_format10@py_format12s	            r   5test_git_safety_blocks_csv_json_outside_allowed_pathsr   {   sz   ++,GHHH))*CDDD558!4!4555G=^X^==XYY^]^^Y]^^^^^^^^^^^Y]^^^^^^^^^^^^^7^^^^^7^^^^^^=^^^^X^^^^Y^^^^]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^r   c                   dD ]3}| |z  }|                                  |dz                      d           4t          |           }d |D             }h d}||k    }|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  }t          t          j
        |                    d x}}d S )N)re   rh   exportsreportszpayload.txtznot allowed herec                2    h | ]}|j         d k    |j        S rm   r   rS   r   s     r   	<setcomp>zItest_git_safety_blocks_top_level_runtime_and_data_dirs.<locals>.<setcomp>   '    fff=e1e1eQV1e1e1er   >   data/payload.txtexports/payload.txtreports/payload.txtruntime/payload.txt)<=)z%(py1)s <= %(py3)sblocked_pathsr0   r1   assert %(py5)spy5)rI   r   r   r   r5   r!   r   r   r    r"   r#   )	r   dirnamefolderr%   r   @py_assert0r9   @py_format4r]   s	            r   6test_git_safety_blocks_top_level_runtime_and_data_dirsr      s<   < @ @G#	-	++,>????""HffXfffMdddudhuuuuuuuuuuudhuuuuuuduuuuuuuuuuuhuuuuuuhuuuuuuuuuuuuuuuuuuuuuuuuuuuuuur   c                   | j         dz  }|                    d           | dz                      |           t          |           }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}}d S )Nzoutside-sensitive.txtznot inspected
linked.txtc              3  B   K   | ]}|j         d k    o
|j        dk    V  dS )r   symlink_blockedNrX   r   s     r   r   zMtest_git_safety_blocks_symlinks_without_reading_the_target.<locals>.<genexpr>   s6      ZZAqv%G!(6G*GZZZZZZr   r   r   r   )rZ   r   
symlink_tor   r   r   r   r   r    r!   r"   r#   )r   outsider%   r&   r'   r(   s         r   :test_git_safety_blocks_symlinks_without_reading_the_targetr      s   o 77G'''((111""HZZQYZZZZ3ZZZZZZZZZZZZZZZZ3ZZZZZ3ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZr   c                h   | dz  dz  }|j                                          |                    d           t          |           }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}}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}}d S )	Nr   zcrypto_inventory.pdfs   %PDF-1.4 syntheticc              3  \   K   | ]'}t          |j                  d k    o
|j        dk    V  (dS )reports/crypto_inventory.pdfrm   Nr   rS   r   r   s     r   r   zBtest_git_safety_blocks_reports_and_pdfs_in_repo.<locals>.<genexpr>   sW          	AF55 	AH@@     r   r   r   r   c              3  \   K   | ]'}t          |j                  d k    o
|j        dk    V  (dS )r   zforbidden_file_type:.pdfNr   r   s     r   r   zBtest_git_safety_blocks_reports_and_pdfs_in_repo.<locals>.<genexpr>   sQ         	AF55`!(F`:`     r   rY   )r   reportr%   r&   r'   r(   s         r   /test_git_safety_blocks_reports_and_pdfs_in_repor      s   	!$::F
M
,---""H     3         	    	     	      	   	        	         
    3                                              r   c                   | dz  dz  }|j                                          |                    d           |j         dz                      d           t	          |           }d |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  }dd|iz  }t          t          j        |                    d x}}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}}	d S )Nbackupsz+finance-runtime-db-20260101T000000Z.sqlite3s   sqlite backup placeholderz2finance-runtime-db-20260101T000000Z.sqlite3.sha256@0000000000000000000000000000000000000000000000000000000000000000c                2    h | ]}|j         d k    |j        S r   r   r   s     r   r   z>test_git_safety_blocks_backup_files_in_repo.<locals>.<setcomp>   r   r   3backups/finance-runtime-db-20260101T000000Z.sqlite3)in)z%(py1)s in %(py3)sr   r   r   r   c              3  B   K   | ]}|j         d k    o
|j        dk    V  dS )r   zforbidden_file_type:.sqlite3NrX   r   s     r   r   z>test_git_safety_blocks_backup_files_in_repo.<locals>.<genexpr>   sP          	
GG 	7H66     r   r   r   r   )rZ   rI   r[   r   r   r   r5   r!   r   r   r    r"   r#   r   )r   backupr%   r   r   r9   r   r]   r&   r'   r(   s              r   +test_git_safety_blocks_backup_files_in_repor      sh   	!$QQF
M
3444]IIUUV^___""HffXfffM@Q@MQQQQQQQQQQ@MQQQQQ@QQQQQQQQQQQMQQQQQMQQQQQQQQQQQQQQQQQQQQQQQQQQQ     3         	    	     	      	   	        	           r   c                   | dz  }|dz                       d           |dz  dz                       d           |dz  dz                      d           |dz  dz  d	z                      d
           |dz                      d           |dz                      d           |dz                      d           |dz                      d           t          |           }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}}|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}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }d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  }	d#d$|	iz  }
t          t          j        |
                    d 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  }	d#d$|	iz  }
t          t          j        |
                    d 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  }	d#d$|	iz  }
t          t          j        |
                    d x}}d S )'NfrontenddistTrB   node_modulespkgz
index.htmlz<div>built</div>zindex.jsz	export {}z.env.developmentz VITE_OPENFIGI_KEY=must-not-existzpackage.jsonz{"private":true}zpackage-lock.jsonz{"lockfileVersion":3}ztsconfig.jsonz{"compilerOptions":{}}c                (    i | ]}|j         |j        S rj   rX   r   s     r   
<dictcomp>zQtest_git_safety_blocks_frontend_build_artifacts_and_env_files.<locals>.<dictcomp>   s    :::Aqvqx:::r   zfrontend/dist/index.htmlruntime_cache_file_blockedrE   )z%(py1)s == %(py4)s)r0   r   zassert %(py6)sr2   z"frontend/node_modules/pkg/index.jszfrontend/.env.developmentforbidden_secret_filenamezfrontend/package.json)not in)z%(py1)s not in %(py3)sreasons_by_pathr   r   r   zfrontend/package-lock.jsonzfrontend/tsconfig.json)rI   r   r   r   r5   r!   r"   r#   r   r   r    )r   r   r%   r   r   r'   r9   r(   r<   r   r]   s              r   =test_git_safety_blocks_frontend_build_artifacts_and_env_filesr      st   *$Hd+++&--d-;;;%112DEEE&3??LLL""../QRRR**+=>>>##//0GHHH++,DEEE""H:::::O56V:VV6:VVVVVVVVVVV6:VVVVVV6VVVV:VVVVVVVVVVVVVVVVVVVVVVVVVVVV?@`D``@D```````````@D``````@````D````````````````````````````67V;VV7;VVVVVVVVVVV7;VVVVVV7VVVV;VVVVVVVVVVVVVVVVVVVVVVVVVVVV"9"/9999999999"/99999"99999999999/99999/999999999999999999999999999'>'>>>>>>>>>>'>>>>>'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#:#?::::::::::#?:::::#:::::::::::?:::::?:::::::::::::::::::::::::::::r   )r   r   r   r	   )r   r   r~   r   r   r   r   r	   )!
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   pathlibr   r6   !jarvis_finance.quality.git_safetyr   r   r)   r>   rJ   rO   r^   rc   ru   rz   r}   markparametrizer   r   r   r   r   r   r   r   rj   r   r   <module>r      s   " " " " " "                      D D D D D D D DD D D D   % % % %% % % %j j j j$% % % %
> 
> 
> 
>J J J JJ J J J    H H H HK K K K_ _ _ _v v v v[ [ [ [   $    ; ; ; ; ; ;r   