Files
headquarter/apps/api/tests/integration/test_git_control.py
miguel 1c94583307 fix: handle bare repos in branch creation and checkout
- Fall back to symbolic-ref when checkout --orphan fails on bare repos\n- Fall back to symbolic-ref when checkout fails on bare repos\n- Make get_current_branch handle bare repos with unborn branches\n- Add integration tests for bare repo branch operations\n\nQuality gates: pytest integration tests (12 passed)
2026-05-22 21:33:18 +02:00

165 lines
5.1 KiB
Python

"""Tests for git control utilities."""
import os
import tempfile
import pytest
from src.utils.git_control import (
GitStatus,
checkout_branch,
commit_changes,
create_branch,
delete_branch,
get_current_branch,
get_status,
)
@pytest.fixture
def temp_repo():
"""Create a temporary git repository."""
with tempfile.TemporaryDirectory() as tmpdir:
# Initialize git repo
os.system(f"cd {tmpdir} && git init && git config user.email 'test@test.com' && git config user.name 'Test User'")
# Create initial commit
with open(os.path.join(tmpdir, "README.md"), "w") as f:
f.write("# Test Repo\n")
os.system(f"cd {tmpdir} && git add README.md && git commit -m 'Initial commit'")
yield tmpdir
class TestGitStatus:
"""Tests for get_status function."""
def test_clean_repo(self, temp_repo):
"""Test status of a clean repository."""
status = get_status(temp_repo)
assert isinstance(status, GitStatus)
assert status.branch in ["main", "master"]
assert len(status.modified) == 0
assert len(status.added) == 0
assert len(status.deleted) == 0
assert len(status.untracked) == 0
def test_modified_file(self, temp_repo):
"""Test detecting modified files."""
# Modify a file
with open(os.path.join(temp_repo, "README.md"), "w") as f:
f.write("# Modified\n")
status = get_status(temp_repo)
assert "README.md" in status.modified
def test_untracked_file(self, temp_repo):
"""Test detecting untracked files."""
# Create new file
with open(os.path.join(temp_repo, "new.py"), "w") as f:
f.write("print('hello')\n")
status = get_status(temp_repo)
assert "new.py" in status.untracked
def test_get_current_branch_handles_unborn_main() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
os.system(f"git init -b main {tmpdir} >/dev/null 2>&1")
assert get_current_branch(tmpdir) == "main"
def test_create_branch_on_bare_repo_with_no_commits() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
os.system(f"git init --bare {tmpdir}/bare.git >/dev/null 2>&1")
create_branch(f"{tmpdir}/bare.git", "main")
assert get_current_branch(f"{tmpdir}/bare.git") == "main"
def test_checkout_branch_on_bare_repo_with_no_commits() -> None:
with tempfile.TemporaryDirectory() as tmpdir:
os.system(f"git init --bare {tmpdir}/bare.git >/dev/null 2>&1")
checkout_branch(f"{tmpdir}/bare.git", "main")
assert get_current_branch(f"{tmpdir}/bare.git") == "main"
class TestBranchOperations:
"""Tests for branch management functions."""
def test_create_branch(self, temp_repo):
"""Test creating a new branch."""
# Get the actual default branch name
default_branch = get_current_branch(temp_repo)
create_branch(temp_repo, "feature/test", default_branch)
# Check branch exists
branches = get_status(temp_repo)
# Branch should still be on default
assert branches.branch == default_branch
def test_checkout_branch(self, temp_repo):
"""Test checking out a branch."""
default_branch = get_current_branch(temp_repo)
create_branch(temp_repo, "feature/test", default_branch)
checkout_branch(temp_repo, "feature/test")
current = get_current_branch(temp_repo)
assert current == "feature/test"
def test_delete_branch(self, temp_repo):
"""Test deleting a branch."""
default_branch = get_current_branch(temp_repo)
create_branch(temp_repo, "feature/delete", default_branch)
delete_branch(temp_repo, "feature/delete")
# Should be back on default
current = get_current_branch(temp_repo)
assert current == default_branch
def test_get_current_branch(self, temp_repo):
"""Test getting current branch."""
branch = get_current_branch(temp_repo)
assert branch in ["main", "master"]
class TestCommit:
"""Tests for commit function."""
def test_commit_changes(self, temp_repo):
"""Test committing changes."""
# Modify file
with open(os.path.join(temp_repo, "README.md"), "w") as f:
f.write("# Updated\n")
# Commit
commit_changes(
temp_repo,
"Update README",
"Test User",
"test@test.com",
["README.md"]
)
# Check status is clean
status = get_status(temp_repo)
assert "README.md" not in status.modified
def test_commit_all_changes(self, temp_repo):
"""Test committing all changes."""
# Modify file
with open(os.path.join(temp_repo, "README.md"), "w") as f:
f.write("# All updated\n")
# Commit all
commit_changes(
temp_repo,
"Update all",
"Test User",
"test@test.com"
)
# Check status is clean
status = get_status(temp_repo)
assert len(status.modified) == 0