Files
Yiqun/gitea-shim/python/tests/test_gitea_github_shim.py

642 lines
23 KiB
Python

"""Unit tests for the Gitea GitHub shim."""
import unittest
from unittest.mock import Mock, MagicMock, patch
import os
from datetime import datetime
# Import the shim classes
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from gitea_github_shim import GiteaGitHubShim
from models.repository import Repository
from models.pull_request import PullRequest
from models.user import User
class TestGiteaGitHubShim(unittest.TestCase):
"""Test cases for GiteaGitHubShim class."""
def setUp(self):
"""Set up test fixtures."""
self.token = "test_token"
self.base_url = "https://gitea.example.com"
@patch('gitea_github_shim.Gitea')
def test_init_with_token_and_url(self, mock_gitea_class):
"""Test initialization with both token and URL."""
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
self.assertEqual(shim.token, self.token)
self.assertEqual(shim.base_url, self.base_url)
mock_gitea_class.assert_called_once_with(self.base_url, self.token)
@patch('gitea_github_shim.Gitea')
def test_init_with_token_only(self, mock_gitea_class):
"""Test initialization with only token (GitHub compatibility mode)."""
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
with patch.dict(os.environ, {'GITEA_URL': 'https://env.gitea.com'}):
shim = GiteaGitHubShim(self.token)
self.assertEqual(shim.token, self.token)
self.assertEqual(shim.base_url, 'https://env.gitea.com')
mock_gitea_class.assert_called_once_with('https://env.gitea.com', self.token)
@patch('gitea_github_shim.Gitea')
def test_get_repo(self, mock_gitea_class):
"""Test getting a repository."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
mock_repo = Mock()
mock_repo.name = "test-repo"
mock_repo.full_name = "owner/test-repo"
mock_repo.description = "Test repository"
mock_repo.private = False
mock_repo.fork = False
mock_repo.created_at = datetime.now()
mock_repo.updated_at = datetime.now()
mock_repo.size = 1024
mock_repo.stars_count = 10
mock_repo.watchers_count = 5
mock_repo.forks_count = 2
mock_repo.open_issues_count = 3
mock_repo.default_branch = "main"
mock_repo.archived = False
mock_repo.html_url = "https://gitea.example.com/owner/test-repo"
mock_repo.clone_url = "https://gitea.example.com/owner/test-repo.git"
mock_repo.ssh_url = "git@gitea.example.com:owner/test-repo.git"
mock_owner = Mock()
mock_owner.login = "owner"
mock_owner.id = 1
mock_owner.avatar_url = "https://gitea.example.com/avatars/1"
mock_repo.owner = mock_owner
mock_gitea.get_repo.return_value = mock_repo
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
repo = shim.get_repo("owner/test-repo")
# Assertions
self.assertIsInstance(repo, Repository)
self.assertEqual(repo.name, "test-repo")
self.assertEqual(repo.full_name, "owner/test-repo")
self.assertEqual(repo.default_branch, "main")
mock_gitea.get_repo.assert_called_once_with("owner", "test-repo")
@patch('gitea_github_shim.Gitea')
def test_get_user_authenticated(self, mock_gitea_class):
"""Test getting authenticated user."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
mock_user = Mock()
mock_user.login = "testuser"
mock_user.id = 1
mock_user.avatar_url = "https://gitea.example.com/avatars/1"
mock_user.html_url = "https://gitea.example.com/testuser"
mock_user.full_name = "Test User"
mock_user.location = "Earth"
mock_user.email = "test@example.com"
mock_user.created = datetime.now()
mock_gitea.get_user.return_value = mock_user
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
user = shim.get_user()
# Assertions
self.assertIsInstance(user, User)
self.assertEqual(user.login, "testuser")
self.assertEqual(user.email, "test@example.com")
mock_gitea.get_user.assert_called_once_with()
@patch('gitea_github_shim.Gitea')
def test_get_user_by_login(self, mock_gitea_class):
"""Test getting user by login name."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
mock_user = Mock()
mock_user.login = "otheruser"
mock_user.id = 2
mock_user.avatar_url = "https://gitea.example.com/avatars/2"
mock_user.html_url = "https://gitea.example.com/otheruser"
mock_user.full_name = "Other User"
mock_user.location = "Mars"
mock_user.email = "other@example.com"
mock_user.created = datetime.now()
mock_gitea.get_user.return_value = mock_user
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
user = shim.get_user("otheruser")
# Assertions
self.assertIsInstance(user, User)
self.assertEqual(user.login, "otheruser")
mock_gitea.get_user.assert_called_once_with("otheruser")
@patch('gitea_github_shim.Gitea')
def test_create_repo(self, mock_gitea_class):
"""Test creating a repository."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
mock_repo = Mock()
mock_repo.name = "new-repo"
mock_repo.full_name = "testuser/new-repo"
mock_repo.description = "New test repository"
mock_repo.private = True
mock_repo.fork = False
mock_repo.created_at = datetime.now()
mock_repo.updated_at = datetime.now()
mock_repo.size = 0
mock_repo.stars_count = 0
mock_repo.watchers_count = 0
mock_repo.forks_count = 0
mock_repo.open_issues_count = 0
mock_repo.default_branch = "main"
mock_repo.archived = False
mock_repo.html_url = "https://gitea.example.com/testuser/new-repo"
mock_repo.clone_url = "https://gitea.example.com/testuser/new-repo.git"
mock_repo.ssh_url = "git@gitea.example.com:testuser/new-repo.git"
mock_owner = Mock()
mock_owner.login = "testuser"
mock_owner.id = 1
mock_owner.avatar_url = "https://gitea.example.com/avatars/1"
mock_repo.owner = mock_owner
mock_gitea.create_repo.return_value = mock_repo
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
repo = shim.create_repo(
"new-repo",
description="New test repository",
private=True,
auto_init=True,
gitignore_template="Python",
license_template="MIT"
)
# Assertions
self.assertIsInstance(repo, Repository)
self.assertEqual(repo.name, "new-repo")
self.assertEqual(repo.description, "New test repository")
self.assertTrue(repo.private)
mock_gitea.create_repo.assert_called_once_with(
name="new-repo",
description="New test repository",
private=True,
auto_init=True,
gitignores="Python",
license="MIT",
readme=""
)
@patch('gitea_github_shim.Gitea')
def test_get_api_status(self, mock_gitea_class):
"""Test getting API status."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
mock_gitea.get_version.return_value = "1.17.0"
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
status = shim.get_api_status()
# Assertions
self.assertEqual(status['status'], 'good')
self.assertEqual(status['version'], '1.17.0')
self.assertEqual(status['api'], 'gitea')
@patch('gitea_github_shim.Gitea')
def test_get_rate_limit(self, mock_gitea_class):
"""Test getting rate limit (mock for Gitea)."""
# Set up mocks
mock_gitea = Mock()
mock_gitea_class.return_value = mock_gitea
# Test
shim = GiteaGitHubShim(self.token, base_url=self.base_url)
rate_limit = shim.get_rate_limit()
# Assertions
self.assertEqual(rate_limit['rate']['limit'], 999999)
self.assertEqual(rate_limit['rate']['remaining'], 999999)
self.assertEqual(rate_limit['rate']['reset'], 0)
class TestRepository(unittest.TestCase):
"""Test cases for Repository model."""
def setUp(self):
"""Set up test fixtures."""
self.mock_gitea = Mock()
self.mock_repo = Mock()
# Set up repository attributes
self.mock_repo.name = "test-repo"
self.mock_repo.full_name = "owner/test-repo"
self.mock_repo.description = "Test repository"
self.mock_repo.private = False
self.mock_repo.fork = False
self.mock_repo.created_at = datetime.now()
self.mock_repo.updated_at = datetime.now()
self.mock_repo.size = 1024
self.mock_repo.stars_count = 10
self.mock_repo.watchers_count = 5
self.mock_repo.forks_count = 2
self.mock_repo.open_issues_count = 3
self.mock_repo.default_branch = "main"
self.mock_repo.archived = False
self.mock_repo.html_url = "https://gitea.example.com/owner/test-repo"
self.mock_repo.clone_url = "https://gitea.example.com/owner/test-repo.git"
self.mock_repo.ssh_url = "git@gitea.example.com:owner/test-repo.git"
mock_owner = Mock()
mock_owner.login = "owner"
mock_owner.id = 1
mock_owner.avatar_url = "https://gitea.example.com/avatars/1"
self.mock_repo.owner = mock_owner
def test_repository_initialization(self):
"""Test Repository model initialization."""
repo = Repository(self.mock_repo, self.mock_gitea)
self.assertEqual(repo.name, "test-repo")
self.assertEqual(repo.full_name, "owner/test-repo")
self.assertEqual(repo.default_branch, "main")
self.assertEqual(repo.stargazers_count, 10)
self.assertEqual(repo.owner['login'], "owner")
def test_get_pull(self):
"""Test getting a pull request."""
# Set up mock PR
mock_pr = Mock()
mock_pr.number = 1
mock_pr.state = "open"
mock_pr.title = "Test PR"
mock_pr.body = "Test PR body"
mock_pr.created_at = datetime.now()
mock_pr.updated_at = datetime.now()
mock_pr.closed_at = None
mock_pr.merged_at = None
mock_pr.merge_commit_sha = None
mock_pr.html_url = "https://gitea.example.com/owner/test-repo/pulls/1"
mock_pr.diff_url = "https://gitea.example.com/owner/test-repo/pulls/1.diff"
mock_pr.patch_url = "https://gitea.example.com/owner/test-repo/pulls/1.patch"
mock_pr.mergeable = True
mock_pr.merged = False
mock_user = Mock()
mock_user.login = "contributor"
mock_user.id = 2
mock_user.avatar_url = "https://gitea.example.com/avatars/2"
mock_pr.user = mock_user
mock_pr.assignee = None
mock_pr.assignees = [] # Empty list of assignees
mock_pr.labels = [] # Empty list of labels
mock_base = Mock()
mock_base.ref = "main"
mock_base.sha = "abc123"
mock_base.repo = self.mock_repo
mock_pr.base = mock_base
mock_head = Mock()
mock_head.ref = "feature-branch"
mock_head.sha = "def456"
mock_head.repo = self.mock_repo
mock_pr.head = mock_head
mock_pr.milestone = None
self.mock_repo.get_pull.return_value = mock_pr
# Test
repo = Repository(self.mock_repo, self.mock_gitea)
pr = repo.get_pull(1)
# Assertions
self.assertIsInstance(pr, PullRequest)
self.assertEqual(pr.number, 1)
self.assertEqual(pr.title, "Test PR")
self.assertEqual(pr.state, "open")
self.mock_repo.get_pull.assert_called_once_with(1)
def test_create_pull(self):
"""Test creating a pull request."""
# Set up mock PR
mock_pr = Mock()
mock_pr.number = 2
mock_pr.state = "open"
mock_pr.title = "New feature"
mock_pr.body = "This adds a new feature"
mock_pr.created_at = datetime.now()
mock_pr.updated_at = datetime.now()
mock_pr.closed_at = None
mock_pr.merged_at = None
mock_pr.merge_commit_sha = None
mock_pr.html_url = "https://gitea.example.com/owner/test-repo/pulls/2"
mock_pr.diff_url = "https://gitea.example.com/owner/test-repo/pulls/2.diff"
mock_pr.patch_url = "https://gitea.example.com/owner/test-repo/pulls/2.patch"
mock_pr.mergeable = True
mock_pr.merged = False
mock_user = Mock()
mock_user.login = "contributor"
mock_user.id = 2
mock_user.avatar_url = "https://gitea.example.com/avatars/2"
mock_pr.user = mock_user
mock_pr.assignee = None
mock_pr.assignees = [] # Empty list of assignees
mock_pr.labels = [] # Empty list of labels
mock_base = Mock()
mock_base.ref = "main"
mock_base.sha = "abc123"
mock_base.repo = self.mock_repo
mock_pr.base = mock_base
mock_head = Mock()
mock_head.ref = "feature/new-feature"
mock_head.sha = "ghi789"
mock_head.repo = self.mock_repo
mock_pr.head = mock_head
mock_pr.milestone = None
self.mock_repo.create_pull_request.return_value = mock_pr
# Test
repo = Repository(self.mock_repo, self.mock_gitea)
pr = repo.create_pull(
title="New feature",
body="This adds a new feature",
head="feature/new-feature",
base="main"
)
# Assertions
self.assertIsInstance(pr, PullRequest)
self.assertEqual(pr.title, "New feature")
self.assertEqual(pr.base['ref'], "main")
self.assertEqual(pr.head['ref'], "feature/new-feature")
self.mock_repo.create_pull_request.assert_called_once_with(
title="New feature",
body="This adds a new feature",
head="feature/new-feature",
base="main"
)
class TestPullRequest(unittest.TestCase):
"""Test cases for PullRequest model."""
def setUp(self):
"""Set up test fixtures."""
self.mock_gitea = Mock()
self.mock_repo = Mock()
self.mock_pr = Mock()
# Set up PR attributes
self.mock_pr.number = 1
self.mock_pr.state = "open"
self.mock_pr.title = "Test PR"
self.mock_pr.body = "Test PR body"
self.mock_pr.created_at = datetime.now()
self.mock_pr.updated_at = datetime.now()
self.mock_pr.closed_at = None
self.mock_pr.merged_at = None
self.mock_pr.merge_commit_sha = None
self.mock_pr.html_url = "https://gitea.example.com/owner/test-repo/pulls/1"
self.mock_pr.diff_url = "https://gitea.example.com/owner/test-repo/pulls/1.diff"
self.mock_pr.patch_url = "https://gitea.example.com/owner/test-repo/pulls/1.patch"
self.mock_pr.mergeable = True
self.mock_pr.merged = False
mock_user = Mock()
mock_user.login = "contributor"
mock_user.id = 2
mock_user.avatar_url = "https://gitea.example.com/avatars/2"
self.mock_pr.user = mock_user
self.mock_pr.assignee = None
# Add missing attributes
self.mock_pr.assignees = [] # Empty list of assignees
self.mock_pr.labels = [] # Empty list of labels
mock_base = Mock()
mock_base.ref = "main"
mock_base.sha = "abc123"
mock_base.repo = Mock()
mock_base.repo.name = "test-repo"
mock_base.repo.full_name = "owner/test-repo"
mock_base.repo.owner = Mock()
mock_base.repo.owner.login = "owner"
mock_base.repo.owner.id = 1
mock_base.repo.owner.avatar_url = "https://gitea.example.com/avatars/1"
self.mock_pr.base = mock_base
mock_head = Mock()
mock_head.ref = "feature-branch"
mock_head.sha = "def456"
mock_head.repo = Mock()
mock_head.repo.name = "test-repo"
mock_head.repo.full_name = "contributor/test-repo"
mock_head.repo.owner = mock_user
self.mock_pr.head = mock_head
self.mock_pr.milestone = None
def test_pull_request_initialization(self):
"""Test PullRequest model initialization."""
pr = PullRequest(self.mock_pr, self.mock_repo, self.mock_gitea)
self.assertEqual(pr.number, 1)
self.assertEqual(pr.title, "Test PR")
self.assertEqual(pr.state, "open")
self.assertFalse(pr.merged)
self.assertEqual(pr.user['login'], "contributor")
self.assertEqual(pr.base['ref'], "main")
self.assertEqual(pr.head['ref'], "feature-branch")
def test_update_pull_request(self):
"""Test updating a pull request."""
# Set up mock for update
updated_pr = Mock()
updated_pr.number = 1
updated_pr.state = "open"
updated_pr.title = "Updated PR Title"
updated_pr.body = "Updated PR body"
updated_pr.created_at = self.mock_pr.created_at
updated_pr.updated_at = datetime.now()
updated_pr.closed_at = None
updated_pr.merged_at = None
updated_pr.merge_commit_sha = None
updated_pr.html_url = self.mock_pr.html_url
updated_pr.diff_url = self.mock_pr.diff_url
updated_pr.patch_url = self.mock_pr.patch_url
updated_pr.mergeable = True
updated_pr.merged = False
updated_pr.user = self.mock_pr.user
updated_pr.assignee = None
updated_pr.base = self.mock_pr.base
updated_pr.head = self.mock_pr.head
updated_pr.milestone = None
# Add missing attributes
updated_pr.assignees = [] # Empty list of assignees
updated_pr.labels = [] # Empty list of labels
self.mock_pr.update.return_value = updated_pr
# Test
pr = PullRequest(self.mock_pr, self.mock_repo, self.mock_gitea)
updated = pr.update(title="Updated PR Title", body="Updated PR body")
# Assertions
self.assertEqual(updated.title, "Updated PR Title")
self.assertEqual(updated.body, "Updated PR body")
self.mock_pr.update.assert_called_once_with(
title="Updated PR Title",
body="Updated PR body"
)
def test_merge_pull_request(self):
"""Test merging a pull request."""
# Set up mock for merge
merge_result = Mock()
merge_result.sha = "merged123"
self.mock_pr.merge.return_value = merge_result
# Test
pr = PullRequest(self.mock_pr, self.mock_repo, self.mock_gitea)
result = pr.merge(
commit_title="Merge PR #1",
commit_message="This merges the feature",
merge_method="squash"
)
# Assertions
self.assertEqual(result['sha'], "merged123")
self.assertTrue(result['merged'])
self.assertEqual(result['message'], "Pull Request successfully merged")
self.mock_pr.merge.assert_called_once_with(
style="squash",
title="Merge PR #1",
message="This merges the feature"
)
class TestUser(unittest.TestCase):
"""Test cases for User model."""
def setUp(self):
"""Set up test fixtures."""
self.mock_gitea = Mock()
self.mock_user = Mock()
# Set up user attributes
self.mock_user.login = "testuser"
self.mock_user.id = 1
self.mock_user.avatar_url = "https://gitea.example.com/avatars/1"
self.mock_user.html_url = "https://gitea.example.com/testuser"
self.mock_user.full_name = "Test User"
self.mock_user.location = "Earth"
self.mock_user.email = "test@example.com"
self.mock_user.created = datetime.now()
def test_user_initialization(self):
"""Test User model initialization."""
user = User(self.mock_user, self.mock_gitea)
self.assertEqual(user.login, "testuser")
self.assertEqual(user.name, "Test User")
self.assertEqual(user.email, "test@example.com")
self.assertEqual(user.location, "Earth")
self.assertEqual(user.type, "User")
def test_get_repos(self):
"""Test getting user repositories."""
# Set up mock repos
mock_repo1 = Mock()
mock_repo1.name = "repo1"
mock_repo1.full_name = "testuser/repo1"
mock_repo1.created_at = datetime.now()
mock_repo1.updated_at = datetime.now()
mock_repo2 = Mock()
mock_repo2.name = "repo2"
mock_repo2.full_name = "testuser/repo2"
mock_repo2.created_at = datetime.now()
mock_repo2.updated_at = datetime.now()
# Set other required attributes for Repository initialization
for repo in [mock_repo1, mock_repo2]:
repo.description = "Test repo"
repo.private = False
repo.fork = False
repo.size = 100
repo.stars_count = 1
repo.watchers_count = 1
repo.forks_count = 0
repo.open_issues_count = 0
repo.default_branch = "main"
repo.archived = False
repo.html_url = f"https://gitea.example.com/{repo.full_name}"
repo.clone_url = f"https://gitea.example.com/{repo.full_name}.git"
repo.ssh_url = f"git@gitea.example.com:{repo.full_name}.git"
repo.owner = self.mock_user
self.mock_user.get_repos.return_value = [mock_repo1, mock_repo2]
# Test
user = User(self.mock_user, self.mock_gitea)
repos = user.get_repos()
# Assertions
self.assertEqual(len(repos), 2)
self.assertEqual(repos[0].name, "repo1")
self.assertEqual(repos[1].name, "repo2")
self.mock_user.get_repos.assert_called_once()
def test_follow_user(self):
"""Test following another user."""
# Create another user to follow
other_user = Mock()
other_user.login = "otheruser"
# Test
user = User(self.mock_user, self.mock_gitea)
other = User(other_user, self.mock_gitea)
user.add_to_following(other)
# Assertions
self.mock_user.follow.assert_called_once_with("otheruser")
if __name__ == '__main__':
unittest.main()