"""Tests for local Git operations.""" import subprocess import tempfile from pathlib import Path from typing import Any import pytest from app.git.operations import LocalGitOperations @pytest.fixture def local_git() -> LocalGitOperations: return LocalGitOperations() @pytest.fixture def temp_repo() -> Any: with tempfile.TemporaryDirectory() as tmpdir: repo_path = Path(tmpdir) / "repo" repo_path.mkdir() subprocess.run( ["git", "init", "--initial-branch=main"], cwd=repo_path, capture_output=True, text=True, check=True, ) subprocess.run( ["git", "config", "user.email", "test@example.com"], cwd=repo_path, capture_output=True, text=True, check=True, ) subprocess.run( ["git", "config", "user.name", "Test User"], cwd=repo_path, capture_output=True, text=True, check=True, ) yield repo_path def test_clone_raises_not_implemented_error(local_git: LocalGitOperations) -> None: with pytest.raises(NotImplementedError): local_git.clone("https://example.com/repo.git", Path("/tmp/dest"), "cred-id") def test_fetch_raises_not_implemented_error(local_git: LocalGitOperations, temp_repo: Path) -> None: with pytest.raises(NotImplementedError): local_git.fetch(temp_repo, "cred-id") def test_push_raises_not_implemented_error(local_git: LocalGitOperations, temp_repo: Path) -> None: with pytest.raises(NotImplementedError): local_git.push(temp_repo, "cred-id") def test_get_status_on_non_git_directory_raises(local_git: LocalGitOperations) -> None: with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises(RuntimeError, match="Not a git repository"): local_git.get_status(Path(tmpdir)) def test_get_status_clean_repo(local_git: LocalGitOperations, temp_repo: Path) -> None: status = local_git.get_status(temp_repo) assert status["branch"] == "main" assert status["clean"] is True assert status["untracked"] == [] assert status["modified"] == [] assert status["staged"] == [] assert status["deleted"] == [] def test_get_status_untracked_file(local_git: LocalGitOperations, temp_repo: Path) -> None: (temp_repo / "newfile.txt").write_text("hello") status = local_git.get_status(temp_repo) assert "newfile.txt" in status["untracked"] assert status["clean"] is False def test_get_status_staged_file(local_git: LocalGitOperations, temp_repo: Path) -> None: file_path = temp_repo / "newfile.txt" file_path.write_text("hello") subprocess.run( ["git", "add", "newfile.txt"], cwd=temp_repo, capture_output=True, text=True, check=True, ) status = local_git.get_status(temp_repo) assert "newfile.txt" in status["staged"] assert status["clean"] is False def test_get_status_modified_file(local_git: LocalGitOperations, temp_repo: Path) -> None: file_path = temp_repo / "newfile.txt" file_path.write_text("hello") subprocess.run( ["git", "add", "newfile.txt"], cwd=temp_repo, capture_output=True, text=True, check=True, ) file_path.write_text("world") status = local_git.get_status(temp_repo) assert "newfile.txt" in status["modified"] assert status["clean"] is False def test_get_status_deleted_file(local_git: LocalGitOperations, temp_repo: Path) -> None: file_path = temp_repo / "newfile.txt" file_path.write_text("hello") subprocess.run( ["git", "add", "newfile.txt"], cwd=temp_repo, capture_output=True, text=True, check=True, ) subprocess.run( ["git", "commit", "-m", "add file"], cwd=temp_repo, capture_output=True, text=True, check=True, ) file_path.unlink() status = local_git.get_status(temp_repo) assert "newfile.txt" in status["deleted"] assert status["clean"] is False def test_get_status_branch_name(local_git: LocalGitOperations, temp_repo: Path) -> None: subprocess.run( ["git", "checkout", "-b", "feature-branch"], cwd=temp_repo, capture_output=True, text=True, check=True, ) status = local_git.get_status(temp_repo) assert status["branch"] == "feature-branch"