Initial upload with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-02 18:27:20 +00:00
parent 0ca8d48a34
commit d9a83825f6

140
tests/test_github_client.py Normal file
View File

@@ -0,0 +1,140 @@
"""Tests for the GitHub client."""
from unittest.mock import MagicMock, patch
from datetime import datetime
import pytest
from src.github_client import GitHubClient, RateLimitExceededError
class TestGitHubClient:
"""Tests for GitHubClient class."""
@pytest.fixture
def mock_ghapi(self):
"""Create a mock GhApi class."""
with patch("src.github_client.GhApi") as mock:
yield mock
@pytest.fixture
def client(self, mock_ghapi):
"""Create a GitHub client with mocked API."""
return GitHubClient(token=None, verbose=False)
def test_init_without_token(self, client):
"""Test initialization without token."""
assert client.token is None
assert client.verbose is False
assert client.timeout == 30
def test_init_with_token(self, mock_ghapi):
"""Test initialization with token."""
client = GitHubClient(token="test_token", verbose=True)
assert client.token == "test_token"
assert client.verbose is True
def test_search_repositories(self, client, mock_ghapi):
"""Test repository search."""
mock_api_instance = MagicMock()
mock_response = MagicMock()
mock_response.get.return_value = {"items": [{"full_name": "test/repo"}]}
mock_response.headers = {"X-RateLimit-Remaining": "60"}
mock_api_instance.search.repos.return_value = mock_response
mock_ghapi.return_value = mock_api_instance
result = client.search_repositories(
language="python",
stars_min=100,
per_page=5,
)
assert len(result) == 1
mock_api_instance.search.repos.assert_called_once()
def test_search_repositories_with_query(self, client, mock_ghapi):
"""Test repository search with custom query."""
mock_api_instance = MagicMock()
mock_response = MagicMock()
mock_response.get.return_value = {"items": []}
mock_response.headers = {"X-RateLimit-Remaining": "60"}
mock_api_instance.search.repos.return_value = mock_response
mock_ghapi.return_value = mock_api_instance
client.search_repositories(
query="machine learning",
language="python",
stars_min=50,
stars_max=500,
per_page=10,
)
mock_api_instance.search.repos.assert_called_once()
call_args = mock_api_instance.search.repos.call_args
assert "machine learning" in call_args[1]["q"]
assert "language:python" in call_args[1]["q"]
def test_get_file_tree(self, client, mock_ghapi):
"""Test getting file tree."""
mock_api_instance = MagicMock()
mock_response = MagicMock()
mock_response.truncated = False
mock_response.tree = [
{"path": "src/main.py", "type": "blob"},
{"path": "README.md", "type": "blob"},
]
mock_response.headers = {"X-RateLimit-Remaining": "60"}
mock_api_instance.git_trees.get.return_value = mock_response
mock_ghapi.return_value = mock_api_instance
result = client.get_file_tree("owner", "repo")
assert len(result) == 2
assert result[0]["path"] == "src/main.py"
def test_get_file_content(self, client, mock_ghapi):
"""Test getting file content."""
import base64
mock_api_instance = MagicMock()
mock_response = {
"encoding": "base64",
"content": base64.b64encode(b"print('hello')").decode(),
}
mock_api_instance.repos.get_content.return_value = mock_response
mock_ghapi.return_value = mock_api_instance
result = client.get_file_content("owner", "repo", "main.py")
assert result == "print('hello')"
def test_get_file_content_not_base64(self, client, mock_ghapi):
"""Test getting file content when not base64 encoded."""
mock_api_instance = MagicMock()
mock_response = {"encoding": "utf-8"}
mock_api_instance.repos.get_content.return_value = mock_response
mock_ghapi.return_value = mock_api_instance
result = client.get_file_content("owner", "repo", "main.py")
assert result is None
class TestRateLimitExceededError:
"""Tests for RateLimitExceededError class."""
def test_error_creation(self):
"""Test creating rate limit error."""
reset_time = datetime.now()
error = RateLimitExceededError(
reset_time=reset_time,
message="Custom message",
)
assert error.reset_time == reset_time
assert error.message == "Custom message"
def test_error_default_message(self):
"""Test error with default message."""
error = RateLimitExceededError(reset_time=None)
assert "rate limit" in error.message.lower()