From 3c2f1f7271cc8c4bc2dd74255814925c32f5bd5f Mon Sep 17 00:00:00 2001 From: Ilya Siamionau Date: Thu, 18 Jul 2024 10:33:28 +0200 Subject: [PATCH] CM-38309 - Cover optional System Git Executable with more tests --- cycode/cli/utils/git_proxy.py | 27 +++++++++++++++++- tests/cli/commands/test_main_command.py | 37 +++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/cycode/cli/utils/git_proxy.py b/cycode/cli/utils/git_proxy.py index 4143c657..5d535657 100644 --- a/cycode/cli/utils/git_proxy.py +++ b/cycode/cli/utils/git_proxy.py @@ -73,4 +73,29 @@ def get_git_proxy(git_module: Optional[types.ModuleType]) -> _AbstractGitProxy: return _GitProxy() if git_module else _DummyGitProxy() -git_proxy = get_git_proxy(git) +class GitProxyManager(_AbstractGitProxy): + """We are using this manager for easy unit testing and mocking of the git module.""" + + def __init__(self) -> None: + self._git_proxy = get_git_proxy(git) + + def _set_dummy_git_proxy(self) -> None: + self._git_proxy = _DummyGitProxy() + + def _set_git_proxy(self) -> None: + self._git_proxy = _GitProxy() + + def get_repo(self, path: Optional['PathLike'] = None, *args, **kwargs) -> 'Repo': + return self._git_proxy.get_repo(path, *args, **kwargs) + + def get_null_tree(self) -> object: + return self._git_proxy.get_null_tree() + + def get_invalid_git_repository_error(self) -> Type[BaseException]: + return self._git_proxy.get_invalid_git_repository_error() + + def get_git_command_error(self) -> Type[BaseException]: + return self._git_proxy.get_git_command_error() + + +git_proxy = GitProxyManager() diff --git a/tests/cli/commands/test_main_command.py b/tests/cli/commands/test_main_command.py index d74a2c40..32a55972 100644 --- a/tests/cli/commands/test_main_command.py +++ b/tests/cli/commands/test_main_command.py @@ -7,6 +7,7 @@ from click.testing import CliRunner from cycode.cli.commands.main_cli import main_cli +from cycode.cli.utils.git_proxy import git_proxy from tests.conftest import CLI_ENV_VARS, TEST_FILES_PATH, ZIP_CONTENT_PATH from tests.cyclient.mocked_responses.scan_client import mock_scan_responses from tests.cyclient.test_scan_client import get_zipped_file_scan_response, get_zipped_file_scan_url @@ -47,3 +48,39 @@ def test_passing_output_option(output: str, scan_client: 'ScanClient', api_token assert 'scan_id' in output else: assert 'Scan ID' in result.output + + +@responses.activate +def test_optional_git_with_path_scan(scan_client: 'ScanClient', api_token_response: responses.Response) -> None: + mock_scan_responses(responses, 'secret', scan_client, uuid4(), ZIP_CONTENT_PATH) + responses.add(get_zipped_file_scan_response(get_zipped_file_scan_url('secret', scan_client), ZIP_CONTENT_PATH)) + responses.add(api_token_response) + + # fake env without Git executable + git_proxy._set_dummy_git_proxy() + + args = ['--output', 'json', 'scan', 'path', str(_PATH_TO_SCAN)] + result = CliRunner().invoke(main_cli, args, env=CLI_ENV_VARS) + + # do NOT expect error about not found Git executable + assert 'GIT_PYTHON_GIT_EXECUTABLE' not in result.output + + # reset the git proxy + git_proxy._set_git_proxy() + + +@responses.activate +def test_required_git_with_path_repository(scan_client: 'ScanClient', api_token_response: responses.Response) -> None: + responses.add(api_token_response) + + # fake env without Git executable + git_proxy._set_dummy_git_proxy() + + args = ['--output', 'json', 'scan', 'repository', str(_PATH_TO_SCAN)] + result = CliRunner().invoke(main_cli, args, env=CLI_ENV_VARS) + + # expect error about not found Git executable + assert 'GIT_PYTHON_GIT_EXECUTABLE' in result.output + + # reset the git proxy + git_proxy._set_git_proxy()