25473ed684
- Create gitea/issues_client.py with IssuesClient class (9 methods) - Create gitea/prs_client.py with PullRequestsClient class (17 methods) - Create gitea/files_client.py with FilesClient class (4 methods) - Create gitea/notifications_client.py with NotificationsClient class (2 methods) - Create gitea/repos_client.py with ReposClient class (2 methods) - Create gitea/__init__.py to export all client classes - Remove delegation methods from GiteaClient (now ~70 lines) - Update all callers to use sub-clients (client.issues, client.prs, etc.) - Update test files to mock sub-client attributes GiteaClient is now a facade that provides access to focused sub-clients: - repos: Repository operations (ReposClient) - issues: Issue operations (IssuesClient) - prs: Pull request operations (PullRequestsClient) - files: File and git ref operations (FilesClient) - notifications: Notification operations (NotificationsClient) Refs: #godclass-refactor
212 lines
7.3 KiB
Python
212 lines
7.3 KiB
Python
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)
|