"""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()