Spaces:
Sleeping
Sleeping
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
""" | |
Unit tests for the Repository Service | |
""" | |
import unittest | |
from unittest.mock import patch, MagicMock | |
import os | |
import sys | |
import shutil | |
from pathlib import Path | |
# Add the project root directory to the Python 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""" | |
# Valid URLs | |
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")) | |
# Invalid URLs | |
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""" | |
# HTTPS URLs | |
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" | |
) | |
# SSH URLs | |
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" | |
) | |
# URLs with trailing slashes | |
self.assertEqual( | |
normalize_github_url("https://github.com/user/repo/"), | |
"https://github.com/user/repo.git" | |
) | |
# Invalid URLs should return None | |
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") | |
# Invalid URLs should return None | |
self.assertIsNone(extract_repo_name("https://github.com")) | |
self.assertIsNone(extract_repo_name("not a url")) | |
def test_clone_repository(self, mock_clone_from): | |
"""Test clone_repository function""" | |
# Mock the Git clone operation | |
mock_repo = MagicMock() | |
mock_clone_from.return_value = mock_repo | |
# Test with default branch | |
repo_path = clone_repository( | |
"https://github.com/user/repo", | |
output_dir=self.test_repo_dir | |
) | |
# Verify the result | |
expected_path = os.path.join(self.test_repo_dir, "repo") | |
self.assertEqual(repo_path, expected_path) | |
mock_clone_from.assert_called_once() | |
# Test with specific branch | |
mock_clone_from.reset_mock() | |
repo_path = clone_repository( | |
"https://github.com/user/repo", | |
branch="dev", | |
output_dir=self.test_repo_dir | |
) | |
# Verify the result | |
self.assertEqual(repo_path, expected_path) | |
mock_clone_from.assert_called_once() | |
# Test with invalid URL | |
with self.assertRaises(ValueError): | |
clone_repository( | |
"not a url", | |
output_dir=self.test_repo_dir | |
) | |
def test_get_repository_info(self, mock_walk, mock_getsize, mock_repo): | |
"""Test get_repository_info function""" | |
# Mock the Git repository | |
mock_repo_instance = MagicMock() | |
mock_repo.return_value = mock_repo_instance | |
# Mock the active branch | |
mock_branch = MagicMock() | |
mock_branch.name = "main" | |
mock_repo_instance.active_branch = mock_branch | |
# Mock the head commit | |
mock_commit = MagicMock() | |
mock_commit.hexsha = "abc123" | |
mock_repo_instance.head.commit = mock_commit | |
# Mock the remote URL | |
mock_remote = MagicMock() | |
mock_remote.url = "https://github.com/user/repo.git" | |
mock_repo_instance.remotes.origin = mock_remote | |
# Mock the repository size | |
mock_getsize.return_value = 1024 | |
# Mock the file count | |
mock_walk.return_value = [ | |
("/test/repo", ["dir1"], ["file1.py", "file2.py"]), | |
("/test/repo/dir1", [], ["file3.py"]) | |
] | |
# Test the function | |
repo_info = get_repository_info("/test/repo") | |
# Verify the result | |
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) | |
def test_cleanup_repository(self, mock_exists, mock_rmtree): | |
"""Test cleanup_repository function""" | |
# Mock the path exists check | |
mock_exists.return_value = True | |
# Test the function | |
cleanup_repository("/test/repo") | |
# Verify the result | |
mock_exists.assert_called_once_with("/test/repo") | |
mock_rmtree.assert_called_once_with("/test/repo") | |
# Test with non-existent path | |
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() | |
def test_cleanup_all_repositories(self, mock_rmtree, mock_isdir, mock_listdir): | |
"""Test cleanup_all_repositories function""" | |
# Mock the directory listing | |
mock_listdir.return_value = ["repo1", "repo2", "file.txt"] | |
# Mock the isdir check | |
mock_isdir.side_effect = lambda path: path.endswith("repo1") or path.endswith("repo2") | |
# Test the function | |
cleanup_all_repositories(self.test_repo_dir) | |
# Verify the result | |
mock_listdir.assert_called_once_with(self.test_repo_dir) | |
self.assertEqual(mock_isdir.call_count, 3) # Called for each item in the directory | |
self.assertEqual(mock_rmtree.call_count, 2) # Called for each directory | |
if __name__ == "__main__": | |
unittest.main() |