def test_scan_no_baseline(self, mock_subprocess_obj): repo = mock_tracked_repo() repo.baseline_file = None # We don't really care about any **actual** git results, because mocked. mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git show', mocked_output=b'will be mocked', ), )) secrets = repo.scan() assert isinstance(secrets, SecretsCollection) assert len(secrets.data) == 0 # `git clone` unnecessary, because already cloned. However, should still work. mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git clone', mocked_output=b"fatal: destination path 'asdf' already exists", should_throw_exception=True, ), )) secrets = repo.scan() assert isinstance(secrets, SecretsCollection) # Baseline supplied, but unable to find baseline file. Should still work. repo.baseline_file = 'asdf' mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git show', mocked_output=b"fatal: Path 'asdf' does not exist", should_throw_exception=True, ), )) secrets = repo.scan() assert isinstance(secrets, SecretsCollection)
def test_scan_with_baseline(self, mock_subprocess_obj, mock_load_from_string, mock_apply): repo = mock_tracked_repo() # Setup secrets secretA = PotentialSecret('type', 'filenameA', 1, 'blah') secretB = PotentialSecret('type', 'filenameA', 2, 'curry') original_secrets = SecretsCollection() original_secrets.data['filenameA'] = { secretA: secretA, secretB: secretB, } baseline_secrets = SecretsCollection() baseline_secrets.data['filenameA'] = { secretA: secretA, } # Easier than mocking load_from_diff. mock_apply.side_effect = lambda orig, base: \ get_secrets_not_in_baseline(original_secrets, baseline_secrets) mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git show', mocked_output=b'will be mocked', ), )) secrets = repo.scan() assert len(secrets.data) == 1 assert secrets.data['filenameA'][secretB] == secretB
def test_no_files_in_git_repo(self, mock_subprocess_obj): mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git ls-files will_be_mocked', should_throw_exception=True, mocked_output='', ), )) results = self.get_results(rootdir='will_be_mocked') assert not results
def test_quit_if_baseline_is_changed_but_not_staged(self, mock_log): with mock.patch('detect_secrets.pre_commit_hook.subprocess.check_output') as \ mock_subprocess_obj: mock_subprocess_obj.side_effect = mock_subprocess((SubprocessMock( expected_input='git diff --name-only', mocked_output=b'baseline.file', ), )) assert_commit_blocked( '--baseline baseline.file test_data/files/file_with_secrets.py' ) assert mock_log.message == ( 'Your baseline file (baseline.file) is unstaged.\n' '`git add baseline.file` to fix this.\n')
def test_main_add_repo_local(self, mock_subprocess_obj): mock_subprocess_obj.side_effect = mock_subprocess(( # mock out `clone_and_pull_repo` SubprocessMock( expected_input='git clone', mocked_output=b"fatal: destination path 'asdf' already exists", ), SubprocessMock( expected_input='git rev-parse --abbrev-ref', mocked_output=b'master', ), SubprocessMock( expected_input='git fetch -q origin', mocked_output=b'', ), # mock out `update` SubprocessMock( expected_input='git rev-parse HEAD', mocked_output=b'new-sha-hash', ))) m = mock.mock_open() with mock.patch( 'detect_secrets_server.repos.base_tracked_repo.codecs.open', m): assert main([ '--add-repo', '/file/to/local/repo', '--local', '--baseline', '.baseline', ]) == 0 m().write.assert_called_once_with( json.dumps( { 'sha': 'new-sha-hash', 'repo': '/file/to/local/repo', 'plugins': { 'base64_limit': 4.5, 'hex_limit': 3, 'private_key_detector': True, }, 'cron': '', 'baseline_file': '.baseline', }, indent=2))
def test_main_scan_repo_scan_success_no_results_found( self, mock_file, mock_scan, mock_log, mock_subprocess_obj): mock_file.return_value = { 'sha': 'does_not_matter', 'repo': 'repo_name', 'plugins': { 'base64_limit': 3, }, 'cron': '* * * * *', 'baseline_file': '.secrets.baseline', } mock_scan.return_value = SecretsCollection() mock_subprocess_obj.side_effect = mock_subprocess( (SubprocessMock(expected_input='git rev-parse HEAD', mocked_output=b'new_sha'), )) m = mock.mock_open() with mock.patch( 'detect_secrets_server.repos.base_tracked_repo.codecs.open', m): assert main([ '--scan-repo', 'will-be-mocked', '--output-hook', 'examples/standalone_hook.py', ]) == 0 mock_log().info.assert_called_with( 'SCAN COMPLETE - STATUS: clean for %s', 'repo_name', ) m().write.assert_called_once_with( json.dumps( { 'sha': 'new_sha', 'repo': 'repo_name', 'plugins': { 'base64_limit': 3, 'hex_limit': None, 'private_key_detector': False, }, 'cron': '* * * * *', 'baseline_file': '.secrets.baseline', }, indent=2))
def test_main_add_repo_s3(self, mock_subprocess_obj, mock_s3_obj): mock_subprocess_obj.side_effect = mock_subprocess(( # mock out `_get_repo_name` SubprocessMock( expected_input='git remote get-url origin', mocked_output=b'[email protected]:yelp/detect-secrets', ), # mock out `update` SubprocessMock( expected_input='git rev-parse HEAD', mocked_output=b'new-sha-hash', ))) mock_s3_config = { 's3_creds_file': 'filename', 'bucket_name': 'bucketman', 'prefix': 'mister', } final_output = mock.mock_open() s3_config = mock.mock_open(read_data=json.dumps(mock_s3_config)) with mock.patch('detect_secrets_server.repos.base_tracked_repo.codecs.open', final_output),\ mock.patch('detect_secrets_server.__main__.codecs.open', s3_config),\ mock.patch( 'detect_secrets_server.repos.s3_tracked_repo.S3TrackedRepo._initialize_s3_client' ): assert main([ '--add-repo', '[email protected]:yelp/detect-secrets.git', '--s3-config-file', 'will-be-mocked', ]) == 0 mock_s3_obj.list_objects_v2.assert_called_once_with( Bucket='bucketman', Prefix='mister/%s.json' % hashlib.sha512('yelp/detect-secrets'.encode('utf-8')).hexdigest(), ) assert mock_s3_obj.upload_file.call_count == 1
def mock_tracked_repo(**kwargs): repo_name = kwargs.get( 'repo_name') or b'[email protected]:pre-commit/pre-commit-hooks' # Need to mock out, because __init__ runs `git remote get-url origin` with mock.patch( 'detect_secrets_server.repos.local_tracked_repo.subprocess.check_output', autospec=True) as m: m.side_effect = mock_subprocess((SubprocessMock( expected_input='git remote get-url origin', mocked_output=repo_name, ), )) output = _mock_tracked_repo(cls=LocalTrackedRepo, **kwargs) if 'git_dir' in kwargs: m.assert_called_with([ 'git', '--git-dir', kwargs.get('git_dir'), 'remote', 'get-url', 'origin' ], stderr=subprocess.STDOUT) return output