"""Unit tests for git mount resolution in tool instances.""" import os import tempfile from pathlib import Path import pytest from src.api.tool_instances import ( _checkout_branch, _expand_glob_source, _resolve_single_git_mount, ) from src.services.config_profile_resolver import ResolvedProfile class TestExpandGlobSource: """Unit tests for glob pattern expansion.""" def test_no_glob_single_file(self, tmp_path: Path) -> None: """Test non-glob path returns single file.""" test_file = tmp_path / "test.txt" test_file.write_text("content") result = _expand_glob_source(str(test_file), str(tmp_path)) assert len(result) == 1 assert result[0] == str(test_file) def test_no_glob_missing_file(self, tmp_path: Path) -> None: """Test non-glob missing file returns empty list.""" missing_file = tmp_path / "missing.txt" result = _expand_glob_source(str(missing_file), str(tmp_path)) assert len(result) == 0 def test_glob_pattern(self, tmp_path: Path) -> None: """Test glob pattern matches files.""" (tmp_path / "file1.txt").write_text("content1") (tmp_path / "file2.txt").write_text("content2") (tmp_path / "other.py").write_text("code") result = _expand_glob_source(str(tmp_path / "*.txt"), str(tmp_path)) assert len(result) == 2 assert all(f.endswith(".txt") for f in result) def test_glob_recursive(self, tmp_path: Path) -> None: """Test recursive glob pattern.""" subdir = tmp_path / "subdir" subdir.mkdir() (subdir / "nested.txt").write_text("content") result = _expand_glob_source(str(tmp_path / "**" / "*.txt"), str(tmp_path)) assert len(result) == 1 assert "nested.txt" in result[0] def test_glob_limit_enforced(self, tmp_path: Path) -> None: """Test that glob matches are limited to prevent abuse.""" # Create more than 100 files for i in range(105): (tmp_path / f"file{i}.txt").write_text("content") result = _expand_glob_source(str(tmp_path / "*.txt"), str(tmp_path)) assert len(result) == 100 # MAX_GLOB_MATCHES limit def test_glob_escapes_repo(self, tmp_path: Path) -> None: """Test that glob results outside repo are filtered.""" other_dir = tmp_path.parent / "other" other_dir.mkdir(exist_ok=True) (other_dir / "outside.txt").write_text("content") result = _expand_glob_source(str(tmp_path.parent / "*" / "*.txt"), str(tmp_path)) # Should only include files within tmp_path, not other_dir assert all(r.startswith(str(tmp_path)) for r in result) class TestCheckoutBranch: """Unit tests for branch checkout.""" def test_checkout_existing_branch(self, tmp_path: Path) -> None: """Test checking out an existing branch.""" # Initialize git repo os.system(f"cd {tmp_path} && git init && git config user.email 'test@test.com' && git config user.name 'Test'") (tmp_path / "file.txt").write_text("content") os.system(f"cd {tmp_path} && git add . && git commit -m 'initial'") os.system(f"cd {tmp_path} && git branch feature") _checkout_branch(str(tmp_path), "feature") # Verify we're on feature branch result = os.popen(f"cd {tmp_path} && git branch --show-current").read().strip() assert result == "feature" def test_checkout_nonexistent_branch(self, tmp_path: Path) -> None: """Test checking out a non-existent branch returns False.""" os.system(f"cd {tmp_path} && git init && git config user.email 'test@test.com' && git config user.name 'Test'") (tmp_path / "file.txt").write_text("content") os.system(f"cd {tmp_path} && git add . && git commit -m 'initial'") result = _checkout_branch(str(tmp_path), "nonexistent") assert result is False class TestResolveSingleGitMount: """Unit tests for resolving a single git mount.""" @pytest.mark.asyncio async def test_resolve_missing_remote_url(self, db_session) -> None: """Test that missing remote_url returns empty list.""" git_mount = { "source_path": ".", "target_path": "/app", } result = await _resolve_single_git_mount(db_session, git_mount) assert result == [] @pytest.mark.asyncio async def test_resolve_missing_target_path(self, db_session) -> None: """Test that missing target path returns empty list.""" git_mount = { "remote_url": "https://github.com/user/repo.git", "source_path": ".", } result = await _resolve_single_git_mount(db_session, git_mount) assert result == []