diff --git a/sonar-project.properties b/sonar-project.properties index 53f1de2..ca4fb9c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,4 +3,5 @@ sonar.organization=axel3rd-github sonar.projectName=Git Platforms Synchro sonar.python.coverage.reportPaths=coverage.xml sonar.python.version=3.11,3.12,3.13,3.14 +sonar.tests=tests sonar.coverage.exclusions=**/tests/subtest_git_clients_dependencies_import.py diff --git a/tests/http_mocks/bitbucket/rest/api/1.0/projects/MyOrg/repos/spring-ai-examples-no-clone-url-http.json b/tests/http_mocks/bitbucket/rest/api/1.0/projects/MyOrg/repos/spring-ai-examples-no-clone-url-http.json new file mode 100644 index 0000000..e00fb19 --- /dev/null +++ b/tests/http_mocks/bitbucket/rest/api/1.0/projects/MyOrg/repos/spring-ai-examples-no-clone-url-http.json @@ -0,0 +1 @@ +{"slug":"spring-ai-examples","id":14,"name":"spring-ai-examples","hierarchyId":"4b75de9e2055a505cad1","scmId":"git","state":"AVAILABLE","statusMessage":"Available","forkable":true,"project":{"key":"MYORG","id":1,"name":"MyOrg","public":false,"type":"NORMAL","links":{"self":[{"href":"http://localhost:7990/projects/MYORG"}]}},"public":false,"archived":false,"links":{"clone":[{"href":"http://localhost:7990/scm/myorg/spring-ai-examples.git","name":"http-value"},{"href":"ssh://git@localhost:7999/myorg/spring-ai-examples.git","name":"ssh"}],"self":[{"href":"http://localhost:7990/projects/MYORG/repos/spring-ai-examples/browse"}]}} \ No newline at end of file diff --git a/tests/test_git_clients.py b/tests/test_git_clients.py index 2fae644..909b818 100644 --- a/tests/test_git_clients.py +++ b/tests/test_git_clients.py @@ -1,9 +1,35 @@ import re from pytest_httpserver import HTTPServer from pytest import LogCaptureFixture, raises -from modules.git_clients import GitClientFactory +from modules.git_clients import GitClientFactory, GitClient, check_input, check_input_empty from tests.test_utils import get_url_root, expect_request from requests import exceptions +from github import GithubException +from gitlab import GitlabError + + +def test_interface(): + client = GitClient() + client.get_login_or_token() + client.get_password() + client.get_url() + client.get_repos('org') + client.has_repo('org', 'repo') + client.get_branches('org', 'repo') + client.get_tags('org', 'repo') + client.get_repo_description('org', 'repo') + client.get_repo_clone_url('org', 'repo') + client.create_repo('org', 'repo') + client.create_repo('org', 'repo', 'description') + + +def test_check_inputs(): + with raises(ValueError, match='not empty'): + check_input_empty('value', 'not empty') + with raises(ValueError, match='empty'): + check_input('', 'empty') + with raises(ValueError, match='empty'): + check_input(None, 'empty') # noqa: python:S5655 def test_type_undefined(caplog: LogCaptureFixture): @@ -77,6 +103,21 @@ def test_github_empty_branches_tags(httpserver: HTTPServer, caplog: LogCaptureFi assert 0 == len(github.get_tags('spring-projects', 'spring-petclinic')) +def test_github_errors_has_repo(httpserver: HTTPServer, caplog: LogCaptureFixture): + expect_request(httpserver, 'github', '/users/spring-projects') + httpserver.expect_request('/repos/spring-projects/spring-petclinic').respond_with_data(status=442) + github = GitClientFactory.create_client(get_url_root(httpserver), 'github', 'ghu_xxxx') + with raises(GithubException, match='442'): + github.has_repo('spring-projects', 'spring-petclinic') + + +def test_github_errors_create_repo(httpserver: HTTPServer, caplog: LogCaptureFixture): + httpserver.expect_request('/orgs/spring-projects').respond_with_data(status=442) + github = GitClientFactory.create_client(get_url_root(httpserver), 'github', 'ghu_xxxx') + with raises(GithubException, match='442'): + github.create_repo('spring-projects', 'spring-petclinic', 'fake') + + def test_gitea_proxy(httpserver: HTTPServer, caplog: LogCaptureFixture): gitea = GitClientFactory.create_client('https://fake.url.dev', 'gitea', 'foo', 'bar', proxy=get_url_root(httpserver)) @@ -259,6 +300,13 @@ def test_bitbucket_empty_branches_tags(httpserver: HTTPServer, caplog: LogCaptur assert 0 == len(bitbucket.get_tags('MyOrg', 'spring-ai-examples')) +def test_bitbucket_bad_clone_url_http(httpserver: HTTPServer, caplog: LogCaptureFixture): + expect_request(httpserver, 'bitbucket', '/rest/api/1.0/projects/MyOrg/repos/spring-ai-examples-no-clone-url-http') + bitbucket = GitClientFactory.create_client(get_url_root(httpserver), 'bitbucket', 'fake_token') + with raises(ValueError, match='Cannot not found http clone link'): + bitbucket.get_repo_clone_url('MyOrg', 'spring-ai-examples-no-clone-url-http') + + def test_gitlab_proxy(httpserver: HTTPServer, caplog: LogCaptureFixture): gitlab = GitClientFactory.create_client('https://fake.url.dev', 'gitlab', 'fake_token', proxy=get_url_root(httpserver)) @@ -327,6 +375,13 @@ def test_gitlab_empty_branches_tags(httpserver: HTTPServer, caplog: LogCaptureFi assert 0 == len(gitlab.get_tags('axel3rd', 'spring-petclinic')) +def test_gitlab_errors_has_repo(httpserver: HTTPServer, caplog: LogCaptureFixture): + httpserver.expect_request('/api/v4/projects/axel3rd/spring-petclinic').respond_with_data(status=442) + gitlab = GitClientFactory.create_client(get_url_root(httpserver), 'gitlab', 'glpat-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') + with raises(GitlabError, match='442'): + gitlab.has_repo('axel3rd', 'spring-petclinic') + + def test_gerrit_proxy(httpserver: HTTPServer, caplog: LogCaptureFixture): gerrit = GitClientFactory.create_client('https://fake.url.dev', 'gerrit', 'foo', 'bar', proxy=get_url_root(httpserver)) diff --git a/tests/test_git_clients_dependencies_import.py b/tests/test_git_clients_dependencies_import.py index d7e5da0..c695509 100644 --- a/tests/test_git_clients_dependencies_import.py +++ b/tests/test_git_clients_dependencies_import.py @@ -17,6 +17,11 @@ def test_no_bitbucket(request): exec_test_method(request.module.__file__, request.node.name) +@pytest.mark.skipif(os.name == 'nt', reason='Inifinite loop on Windows') +def test_no_gerrit(request): + exec_test_method(request.module.__file__, request.node.name) + + @pytest.mark.skipif(os.name == 'nt', reason='Inifinite loop on Windows') def test_no_gitlab(request): exec_test_method(request.module.__file__, request.node.name) diff --git a/tests/test_git_platforms_synchro.py b/tests/test_git_platforms_synchro.py index 27fe60b..6c0013d 100644 --- a/tests/test_git_platforms_synchro.py +++ b/tests/test_git_platforms_synchro.py @@ -260,7 +260,7 @@ def test_from_github_to_gitea_mirror_exist(httpserver: HTTPServer, caplog: LogCa assert 'The requested URL returned error: 542' in caplog.text -def test_from_github_to_gitea_sync(httpserver: HTTPServer, caplog: LogCaptureFixture): +def test_from_github_to_gitea_sync_real(httpserver: HTTPServer, caplog: LogCaptureFixture): # httpserver doesn't support KeepAlive, so we need to mock the git clone # as already existing bare directory (reuse mechanism) and mock the git # push failure @@ -277,8 +277,15 @@ def test_from_github_to_gitea_sync(httpserver: HTTPServer, caplog: LogCaptureFix # Gitea with same repo prepare_gitea_with_spring_projects(httpserver, update_commit=True) + # Remove 'from' credentials to validate pop process + test_args = get_test_args_github_to_gitea(httpserver) + test_args.remove('--from-login') + test_args.remove('foo') + test_args.remove('--from-password') + test_args.remove('bar') + with raises(GitCommandError): - with patch.object(sys, 'argv', get_test_args_github_to_gitea(httpserver)): + with patch.object(sys, 'argv', test_args): git_platforms_synchro.main() assert 'Reusing existing cloned repo ' + get_url_root(httpserver) + '/spring-projects/spring-petclinic.git' in caplog.text @@ -286,7 +293,21 @@ def test_from_github_to_gitea_sync(httpserver: HTTPServer, caplog: LogCaptureFix assert 'The requested URL returned error: 542' in caplog.text -def test_from_github_to_gitea_tags_only(httpserver: HTTPServer, caplog: LogCaptureFixture): +def test_from_github_to_gitea_sync_dry_run(httpserver: HTTPServer, caplog: LogCaptureFixture): + # GitHub with spring-projects + prepare_github_with_spring_projects(httpserver) + + # Gitea with same repo + prepare_gitea_with_spring_projects(httpserver, update_commit=True) + + with patch.object(sys, 'argv', get_test_args_github_to_gitea(httpserver) + ['--dry-run']): + git_platforms_synchro.main() + + assert 'Synchronize branch...' in caplog.text + assert ' Dry-run mode, skipping branch synchronization.' in caplog.text + + +def test_from_github_to_gitea_tags_only_real(httpserver: HTTPServer, caplog: LogCaptureFixture): # httpserver doesn't support KeepAlive, so we need to mock the git clone # as already existing bare directory (reuse mechanism) and mock the git # push failure @@ -313,6 +334,20 @@ def test_from_github_to_gitea_tags_only(httpserver: HTTPServer, caplog: LogCaptu assert 'The requested URL returned error: 542' in caplog.text +def test_from_github_to_gitea_tags_only_dry_run(httpserver: HTTPServer, caplog: LogCaptureFixture): + # GitHub with spring-projects + prepare_github_with_spring_projects(httpserver) + + # Gitea with same repo + prepare_gitea_with_spring_projects(httpserver, prepare_tags=False) + httpserver.expect_request('/api/v1/repos/MyOrg/spring-petclinic/tags').respond_with_data('[]') + + with patch.object(sys, 'argv', get_test_args_github_to_gitea(httpserver) + ['--dry-run']): + git_platforms_synchro.main() + + assert 'Dry-run mode, skipping tags synchronization.' in caplog.text + + def test_from_github_to_gitea_all_already_sync(httpserver: HTTPServer, caplog: LogCaptureFixture): # GitHub with spring-projects prepare_github_with_spring_projects(httpserver)