|
|
|
|
|
|
|
""" |
|
Unit tests for the Repository Service |
|
""" |
|
|
|
import unittest |
|
from unittest.mock import patch, MagicMock |
|
import os |
|
import sys |
|
import shutil |
|
from pathlib import Path |
|
|
|
|
|
project_root = Path(__file__).resolve().parent.parent |
|
sys.path.insert(0, str(project_root)) |
|
|
|
from src.services.repository_service import ( |
|
validate_github_url, |
|
normalize_github_url, |
|
extract_repo_name, |
|
clone_repository, |
|
get_repository_info, |
|
cleanup_repository, |
|
cleanup_all_repositories |
|
) |
|
|
|
|
|
class TestRepositoryService(unittest.TestCase): |
|
"""Test cases for the repository service functions""" |
|
|
|
def setUp(self): |
|
"""Set up test fixtures""" |
|
self.test_repo_dir = "test_repos" |
|
os.makedirs(self.test_repo_dir, exist_ok=True) |
|
|
|
def tearDown(self): |
|
"""Tear down test fixtures""" |
|
if os.path.exists(self.test_repo_dir): |
|
shutil.rmtree(self.test_repo_dir) |
|
|
|
def test_validate_github_url(self): |
|
"""Test validate_github_url function""" |
|
|
|
self.assertTrue(validate_github_url("https://github.com/user/repo")) |
|
self.assertTrue(validate_github_url("https://github.com/user/repo.git")) |
|
self.assertTrue(validate_github_url("git@github.com:user/repo.git")) |
|
self.assertTrue(validate_github_url("https://github.com/user/repo-with-dash")) |
|
self.assertTrue(validate_github_url("https://github.com/user/repo_with_underscore")) |
|
|
|
|
|
self.assertFalse(validate_github_url("https://gitlab.com/user/repo")) |
|
self.assertFalse(validate_github_url("https://github.com")) |
|
self.assertFalse(validate_github_url("https://github.com/user")) |
|
self.assertFalse(validate_github_url("not a url")) |
|
|
|
def test_normalize_github_url(self): |
|
"""Test normalize_github_url function""" |
|
|
|
self.assertEqual( |
|
normalize_github_url("https://github.com/user/repo"), |
|
"https://github.com/user/repo.git" |
|
) |
|
self.assertEqual( |
|
normalize_github_url("https://github.com/user/repo.git"), |
|
"https://github.com/user/repo.git" |
|
) |
|
|
|
|
|
self.assertEqual( |
|
normalize_github_url("git@github.com:user/repo.git"), |
|
"https://github.com/user/repo.git" |
|
) |
|
self.assertEqual( |
|
normalize_github_url("git@github.com:user/repo"), |
|
"https://github.com/user/repo.git" |
|
) |
|
|
|
|
|
self.assertEqual( |
|
normalize_github_url("https://github.com/user/repo/"), |
|
"https://github.com/user/repo.git" |
|
) |
|
|
|
|
|
self.assertIsNone(normalize_github_url("https://gitlab.com/user/repo")) |
|
self.assertIsNone(normalize_github_url("not a url")) |
|
|
|
def test_extract_repo_name(self): |
|
"""Test extract_repo_name function""" |
|
self.assertEqual(extract_repo_name("https://github.com/user/repo"), "repo") |
|
self.assertEqual(extract_repo_name("https://github.com/user/repo.git"), "repo") |
|
self.assertEqual(extract_repo_name("git@github.com:user/repo.git"), "repo") |
|
self.assertEqual(extract_repo_name("https://github.com/user/repo-with-dash"), "repo-with-dash") |
|
|
|
|
|
self.assertIsNone(extract_repo_name("https://github.com")) |
|
self.assertIsNone(extract_repo_name("not a url")) |
|
|
|
@patch('git.Repo.clone_from') |
|
def test_clone_repository(self, mock_clone_from): |
|
"""Test clone_repository function""" |
|
|
|
mock_repo = MagicMock() |
|
mock_clone_from.return_value = mock_repo |
|
|
|
|
|
repo_path = clone_repository( |
|
"https://github.com/user/repo", |
|
output_dir=self.test_repo_dir |
|
) |
|
|
|
|
|
expected_path = os.path.join(self.test_repo_dir, "repo") |
|
self.assertEqual(repo_path, expected_path) |
|
mock_clone_from.assert_called_once() |
|
|
|
|
|
mock_clone_from.reset_mock() |
|
repo_path = clone_repository( |
|
"https://github.com/user/repo", |
|
branch="dev", |
|
output_dir=self.test_repo_dir |
|
) |
|
|
|
|
|
self.assertEqual(repo_path, expected_path) |
|
mock_clone_from.assert_called_once() |
|
|
|
|
|
with self.assertRaises(ValueError): |
|
clone_repository( |
|
"not a url", |
|
output_dir=self.test_repo_dir |
|
) |
|
|
|
@patch('git.Repo') |
|
@patch('os.path.getsize') |
|
@patch('os.walk') |
|
def test_get_repository_info(self, mock_walk, mock_getsize, mock_repo): |
|
"""Test get_repository_info function""" |
|
|
|
mock_repo_instance = MagicMock() |
|
mock_repo.return_value = mock_repo_instance |
|
|
|
|
|
mock_branch = MagicMock() |
|
mock_branch.name = "main" |
|
mock_repo_instance.active_branch = mock_branch |
|
|
|
|
|
mock_commit = MagicMock() |
|
mock_commit.hexsha = "abc123" |
|
mock_repo_instance.head.commit = mock_commit |
|
|
|
|
|
mock_remote = MagicMock() |
|
mock_remote.url = "https://github.com/user/repo.git" |
|
mock_repo_instance.remotes.origin = mock_remote |
|
|
|
|
|
mock_getsize.return_value = 1024 |
|
|
|
|
|
mock_walk.return_value = [ |
|
("/test/repo", ["dir1"], ["file1.py", "file2.py"]), |
|
("/test/repo/dir1", [], ["file3.py"]) |
|
] |
|
|
|
|
|
repo_info = get_repository_info("/test/repo") |
|
|
|
|
|
self.assertEqual(repo_info["branch"], "main") |
|
self.assertEqual(repo_info["commit"], "abc123") |
|
self.assertEqual(repo_info["remote_url"], "https://github.com/user/repo.git") |
|
self.assertEqual(repo_info["size"], 1024) |
|
self.assertEqual(repo_info["file_count"], 3) |
|
|
|
@patch('shutil.rmtree') |
|
@patch('os.path.exists') |
|
def test_cleanup_repository(self, mock_exists, mock_rmtree): |
|
"""Test cleanup_repository function""" |
|
|
|
mock_exists.return_value = True |
|
|
|
|
|
cleanup_repository("/test/repo") |
|
|
|
|
|
mock_exists.assert_called_once_with("/test/repo") |
|
mock_rmtree.assert_called_once_with("/test/repo") |
|
|
|
|
|
mock_exists.reset_mock() |
|
mock_rmtree.reset_mock() |
|
mock_exists.return_value = False |
|
|
|
cleanup_repository("/test/repo") |
|
|
|
mock_exists.assert_called_once_with("/test/repo") |
|
mock_rmtree.assert_not_called() |
|
|
|
@patch('os.listdir') |
|
@patch('os.path.isdir') |
|
@patch('shutil.rmtree') |
|
def test_cleanup_all_repositories(self, mock_rmtree, mock_isdir, mock_listdir): |
|
"""Test cleanup_all_repositories function""" |
|
|
|
mock_listdir.return_value = ["repo1", "repo2", "file.txt"] |
|
|
|
|
|
mock_isdir.side_effect = lambda path: path.endswith("repo1") or path.endswith("repo2") |
|
|
|
|
|
cleanup_all_repositories(self.test_repo_dir) |
|
|
|
|
|
mock_listdir.assert_called_once_with(self.test_repo_dir) |
|
self.assertEqual(mock_isdir.call_count, 3) |
|
self.assertEqual(mock_rmtree.call_count, 2) |
|
|
|
|
|
if __name__ == "__main__": |
|
unittest.main() |