"""Tests for Git utilities."""
import pytest
from unittest.mock import patch, MagicMock
from src.git_utils import (
parse_git_remote_url,
get_project_path_from_working_dir,
validate_working_dir,
GitUtilsError,
)
class TestParseGitRemoteUrl:
"""Tests for git remote URL parsing."""
def test_parse_ssh_format_with_git_extension(self):
"""Test parsing SSH format URLs with .git extension."""
url = "git@gitlab.example.com:group/project.git"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_ssh_format_without_git_extension(self):
"""Test parsing SSH format URLs without .git extension."""
url = "git@gitlab.example.com:group/project"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_https_format_with_git_extension(self):
"""Test parsing HTTPS format URLs with .git extension."""
url = "https://gitlab.example.com/group/project.git"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_https_format_without_git_extension(self):
"""Test parsing HTTPS format URLs without .git extension."""
url = "https://gitlab.example.com/group/project"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_https_with_trailing_slash(self):
"""Test parsing HTTPS format URLs with trailing slash."""
url = "https://gitlab.example.com/group/project/"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_http_format(self):
"""Test parsing HTTP (non-secure) format URLs."""
url = "http://gitlab.example.com/group/project.git"
result = parse_git_remote_url(url)
assert result == "group/project"
def test_parse_nested_groups(self):
"""Test parsing URLs with nested groups."""
url = "git@gitlab.example.com:company/team/subteam/project.git"
result = parse_git_remote_url(url)
assert result == "company/team/subteam/project"
def test_parse_invalid_format(self):
"""Test that invalid URL format raises error."""
url = "invalid://example.com/group/project"
with pytest.raises(GitUtilsError, match="Unable to parse"):
parse_git_remote_url(url)
class TestValidateWorkingDir:
"""Tests for working directory validation."""
def test_validate_git_repo_exists(self):
"""Test validation succeeds when .git directory exists."""
with patch('src.git_utils.Path') as MockPath:
mock_git_dir = MagicMock()
mock_git_dir.exists.return_value = True
MockPath.return_value.__truediv__.return_value = mock_git_dir
# Should not raise
validate_working_dir("/some/path")
def test_validate_not_git_repo(self):
"""Test validation fails when .git directory doesn't exist."""
with patch('src.git_utils.Path') as MockPath:
mock_git_dir = MagicMock()
mock_git_dir.exists.return_value = False
MockPath.return_value.__truediv__.return_value = mock_git_dir
with pytest.raises(GitUtilsError, match="Not a git repository"):
validate_working_dir("/some/path")
class TestGetProjectPathFromWorkingDir:
"""Tests for project path extraction from working directory."""
def test_get_project_path_from_valid_repo(self):
"""Test extracting project path from a valid git repository."""
with patch('src.git_utils.get_git_remote_url') as mock_remote, \
patch('src.git_utils.parse_git_remote_url') as mock_parse:
mock_remote.return_value = "git@gitlab.example.com:group/project.git"
mock_parse.return_value = "group/project"
result = get_project_path_from_working_dir("/repo/path")
assert result == "group/project"
mock_remote.assert_called_once_with("/repo/path")
mock_parse.assert_called_once_with("git@gitlab.example.com:group/project.git")