mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-04 04:40:38 +08:00
147 lines
6.1 KiB
Python
147 lines
6.1 KiB
Python
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from pr_agent.git_providers.gitlab_provider import GitLabProvider
|
|
from gitlab import Gitlab
|
|
from gitlab.v4.objects import Project, ProjectFile
|
|
from gitlab.exceptions import GitlabGetError
|
|
|
|
|
|
class TestGitLabProvider:
|
|
"""Test suite for GitLab provider functionality."""
|
|
|
|
@pytest.fixture
|
|
def mock_gitlab_client(self):
|
|
client = MagicMock()
|
|
return client
|
|
|
|
@pytest.fixture
|
|
def mock_project(self):
|
|
project = MagicMock()
|
|
return project
|
|
|
|
@pytest.fixture
|
|
def gitlab_provider(self, mock_gitlab_client, mock_project):
|
|
with patch('pr_agent.git_providers.gitlab_provider.gitlab.Gitlab', return_value=mock_gitlab_client), \
|
|
patch('pr_agent.git_providers.gitlab_provider.get_settings') as mock_settings:
|
|
|
|
mock_settings.return_value.get.side_effect = lambda key, default=None: {
|
|
"GITLAB.URL": "https://gitlab.com",
|
|
"GITLAB.PERSONAL_ACCESS_TOKEN": "fake_token"
|
|
}.get(key, default)
|
|
|
|
mock_gitlab_client.projects.get.return_value = mock_project
|
|
provider = GitLabProvider("https://gitlab.com/test/repo/-/merge_requests/1")
|
|
provider.gl = mock_gitlab_client
|
|
provider.id_project = "test/repo"
|
|
return provider
|
|
|
|
def test_get_pr_file_content_success(self, gitlab_provider, mock_project):
|
|
mock_file = MagicMock(ProjectFile)
|
|
mock_file.decode.return_value = "# Changelog\n\n## v1.0.0\n- Initial release"
|
|
mock_project.files.get.return_value = mock_file
|
|
|
|
content = gitlab_provider.get_pr_file_content("CHANGELOG.md", "main")
|
|
|
|
assert content == "# Changelog\n\n## v1.0.0\n- Initial release"
|
|
mock_project.files.get.assert_called_once_with("CHANGELOG.md", "main")
|
|
mock_file.decode.assert_called_once()
|
|
|
|
def test_get_pr_file_content_with_bytes(self, gitlab_provider, mock_project):
|
|
mock_file = MagicMock(ProjectFile)
|
|
mock_file.decode.return_value = b"# Changelog\n\n## v1.0.0\n- Initial release"
|
|
mock_project.files.get.return_value = mock_file
|
|
|
|
content = gitlab_provider.get_pr_file_content("CHANGELOG.md", "main")
|
|
|
|
assert content == "# Changelog\n\n## v1.0.0\n- Initial release"
|
|
mock_project.files.get.assert_called_once_with("CHANGELOG.md", "main")
|
|
|
|
def test_get_pr_file_content_file_not_found(self, gitlab_provider, mock_project):
|
|
mock_project.files.get.side_effect = GitlabGetError("404 Not Found")
|
|
|
|
content = gitlab_provider.get_pr_file_content("CHANGELOG.md", "main")
|
|
|
|
assert content == ""
|
|
mock_project.files.get.assert_called_once_with("CHANGELOG.md", "main")
|
|
|
|
def test_get_pr_file_content_other_exception(self, gitlab_provider, mock_project):
|
|
mock_project.files.get.side_effect = Exception("Network error")
|
|
|
|
content = gitlab_provider.get_pr_file_content("CHANGELOG.md", "main")
|
|
|
|
assert content == ""
|
|
|
|
def test_create_or_update_pr_file_create_new(self, gitlab_provider, mock_project):
|
|
mock_project.files.get.side_effect = GitlabGetError("404 Not Found")
|
|
mock_file = MagicMock()
|
|
mock_project.files.create.return_value = mock_file
|
|
|
|
new_content = "# Changelog\n\n## v1.1.0\n- New feature"
|
|
commit_message = "Add CHANGELOG.md"
|
|
|
|
gitlab_provider.create_or_update_pr_file(
|
|
"CHANGELOG.md", "feature-branch", new_content, commit_message
|
|
)
|
|
|
|
mock_project.files.get.assert_called_once_with("CHANGELOG.md", "feature-branch")
|
|
mock_project.files.create.assert_called_once_with({
|
|
'file_path': 'CHANGELOG.md',
|
|
'branch': 'feature-branch',
|
|
'content': new_content,
|
|
'commit_message': commit_message,
|
|
})
|
|
|
|
def test_create_or_update_pr_file_update_existing(self, gitlab_provider, mock_project):
|
|
mock_file = MagicMock(ProjectFile)
|
|
mock_file.decode.return_value = "# Old changelog content"
|
|
mock_project.files.get.return_value = mock_file
|
|
|
|
new_content = "# New changelog content"
|
|
commit_message = "Update CHANGELOG.md"
|
|
|
|
gitlab_provider.create_or_update_pr_file(
|
|
"CHANGELOG.md", "feature-branch", new_content, commit_message
|
|
)
|
|
|
|
mock_project.files.get.assert_called_once_with("CHANGELOG.md", "feature-branch")
|
|
mock_file.content = new_content
|
|
mock_file.save.assert_called_once_with(branch="feature-branch", commit_message=commit_message)
|
|
|
|
def test_create_or_update_pr_file_update_exception(self, gitlab_provider, mock_project):
|
|
mock_project.files.get.side_effect = Exception("Network error")
|
|
|
|
with pytest.raises(Exception):
|
|
gitlab_provider.create_or_update_pr_file(
|
|
"CHANGELOG.md", "feature-branch", "content", "message"
|
|
)
|
|
|
|
def test_has_create_or_update_pr_file_method(self, gitlab_provider):
|
|
assert hasattr(gitlab_provider, "create_or_update_pr_file")
|
|
assert callable(getattr(gitlab_provider, "create_or_update_pr_file"))
|
|
|
|
def test_method_signature_compatibility(self, gitlab_provider):
|
|
import inspect
|
|
|
|
sig = inspect.signature(gitlab_provider.create_or_update_pr_file)
|
|
params = list(sig.parameters.keys())
|
|
|
|
expected_params = ['file_path', 'branch', 'contents', 'message']
|
|
assert params == expected_params
|
|
|
|
@pytest.mark.parametrize("content,expected", [
|
|
("simple text", "simple text"),
|
|
(b"bytes content", "bytes content"),
|
|
("", ""),
|
|
(b"", ""),
|
|
("unicode: café", "unicode: café"),
|
|
(b"unicode: caf\xc3\xa9", "unicode: café"),
|
|
])
|
|
def test_content_encoding_handling(self, gitlab_provider, mock_project, content, expected):
|
|
mock_file = MagicMock(ProjectFile)
|
|
mock_file.decode.return_value = content
|
|
mock_project.files.get.return_value = mock_file
|
|
|
|
result = gitlab_provider.get_pr_file_content("test.md", "main")
|
|
|
|
assert result == expected |