CodeReviewAgent / tests /test_repository_service.py
c1r3x's picture
Review Agent: first commit
88d205f
raw
history blame
8.04 kB
#!/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("[email protected]: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("[email protected]:user/repo.git"),
"https://github.com/user/repo.git"
)
self.assertEqual(
normalize_github_url("[email protected]: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("[email protected]: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"))
@patch('git.Repo.clone_from')
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
)
@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 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)
@patch('shutil.rmtree')
@patch('os.path.exists')
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()
@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 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()