from pathlib import Path from typing import Any from unittest.mock import MagicMock, patch import pytest from gitea.workspace import WorkspaceManager @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_configure_repo_user( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.full_name = "Agent Tester" mock_user.login = "agent-test" mock_user.email = "agent-test@example.com" mock_client.repos.get_authenticated_user.return_value = mock_user workspace = WorkspaceManager() repo_path = Path("/tmp/mock-repo") workspace._configure_repo_user(repo_path) assert mock_run.call_count >= 3 calls = [c[0][0] for c in mock_run.call_args_list] assert any("http.extraHeader" in call for call in calls) assert any("user.name" in call for call in calls) assert any("user.email" in call for call in calls) @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_clone_repo( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.full_name = "Agent Tester" mock_user.login = "agent-test" mock_user.email = "agent-test@example.com" mock_client.repos.get_authenticated_user.return_value = mock_user workspace = WorkspaceManager() with patch.object(workspace, "_configure_repo_user") as mock_configure: with patch.object(workspace, "get_repo_path") as mock_get_path: mock_repo_path = MagicMock(spec=Path) mock_repo_path.exists.return_value = False mock_get_path.return_value = mock_repo_path workspace.clone_repo("meeks/repo1") mock_run.assert_called_once() args = mock_run.call_args[0][0] assert "clone" in args assert any("http.extraHeader=Authorization: Basic" in arg for arg in args) mock_configure.assert_called_once_with(mock_repo_path) @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_fails_if_no_authenticated_user( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_client.repos.get_authenticated_user.return_value = None workspace = WorkspaceManager() with pytest.raises(RuntimeError, match="No authenticated user found."): workspace.clone_repo("meeks/repo1") with pytest.raises(RuntimeError, match="No authenticated user found."): workspace._configure_repo_user(Path("/tmp/mock-repo")) @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_fails_if_authenticated_user_has_no_login( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.login = "" mock_client.repos.get_authenticated_user.return_value = mock_user workspace = WorkspaceManager() with pytest.raises(RuntimeError, match="No authenticated user found."): workspace.clone_repo("meeks/repo1") with pytest.raises(RuntimeError, match="No authenticated user found."): workspace._configure_repo_user(Path("/tmp/mock-repo")) @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_sanitize_repo_no_changes( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: # Setup Gitea client mock mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.full_name = "Agent Tester" mock_user.login = "agent-test" mock_user.email = "agent-test@example.com" mock_client.repos.get_authenticated_user.return_value = mock_user # Mock subprocess.run for status check and others def mock_run_side_effect(args: list[str], **kwargs: Any) -> MagicMock: result = MagicMock() result.returncode = 0 if "status" in args: result.stdout = "" else: result.stdout = "some output" return result mock_run.side_effect = mock_run_side_effect workspace = WorkspaceManager() repo_path = Path("/tmp/mock-repo") workspace.sanitize_repo("meeks/repo1", repo_path) # Verify that stash was not called stash_calls = [call for call in mock_run.call_args_list if "stash" in call[0][0]] assert len(stash_calls) == 0 # Verify other expected git calls reset_calls = [call for call in mock_run.call_args_list if "reset" in call[0][0]] clean_calls = [call for call in mock_run.call_args_list if "clean" in call[0][0]] assert len(reset_calls) > 0 assert len(clean_calls) > 0 @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_sanitize_repo_with_changes( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: # Setup Gitea client mock mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.full_name = "Agent Tester" mock_user.login = "agent-test" mock_user.email = "agent-test@example.com" mock_client.repos.get_authenticated_user.return_value = mock_user # Mock subprocess.run to show modified files def mock_run_side_effect(args: list[str], **kwargs: Any) -> MagicMock: result = MagicMock() result.returncode = 0 if "status" in args: result.stdout = " M file.py\n?? untracked.py\n" else: result.stdout = "" return result mock_run.side_effect = mock_run_side_effect workspace = WorkspaceManager() repo_path = Path("/tmp/mock-repo") workspace.sanitize_repo("meeks/repo1", repo_path) # Verify stash push was called stash_calls = [call for call in mock_run.call_args_list if "stash" in call[0][0]] assert len(stash_calls) == 1 assert "push" in stash_calls[0][0][0] assert "-u" in stash_calls[0][0][0] @patch("gitea.workspace.subprocess.run") @patch("gitea.workspace.GiteaClient") def test_workspace_manager_sanitize_repo_fails( mock_client_class: MagicMock, mock_run: MagicMock ) -> None: # Setup Gitea client mock mock_client = MagicMock() mock_client_class.return_value = mock_client mock_client.repos = MagicMock() mock_user = MagicMock() mock_user.full_name = "Agent Tester" mock_user.login = "agent-test" mock_user.email = "agent-test@example.com" mock_client.repos.get_authenticated_user.return_value = mock_user # Mock remote set-url to fail import subprocess mock_run.side_effect = subprocess.CalledProcessError(1, "git remote set-url") workspace = WorkspaceManager() repo_path = Path("/tmp/mock-repo") with pytest.raises(RuntimeError, match="Failed to sanitize repository"): workspace.sanitize_repo("meeks/repo1", repo_path)