resumate / tests /test_github.py
gperdrizet's picture
Added tests for Gradio and GitHub functions.
90e1657
raw
history blame
14 kB
"""
Unit tests for the github module.
"""
import unittest
from unittest.mock import patch, MagicMock
import requests
from functions import github
class TestExtractGitHubUsername(unittest.TestCase):
"""Test cases for the _extract_github_username function."""
def test_valid_github_urls(self):
"""Test extraction from valid GitHub URLs."""
test_cases = [
("https://github.com/octocat", "octocat"),
("https://github.com/octocat/", "octocat"),
("http://github.com/test-user", "test-user"),
("github.com/user_name", "user_name"),
("https://github.com/user123", "user123"),
("https://github.com/octocat/Hello-World", "octocat"),
]
for url, expected in test_cases:
with self.subTest(url=url):
result = github._extract_github_username(url)
self.assertEqual(result, expected)
def test_invalid_github_urls(self):
"""Test handling of invalid GitHub URLs."""
invalid_urls = [
"",
"https://gitlab.com/user",
"https://github.com/",
"[email protected]",
"https://github.com/user-with-very-long-name-that-exceeds-github-limit",
None
]
for url in invalid_urls:
with self.subTest(url=url):
result = github._extract_github_username(url)
self.assertIsNone(result)
def test_username_validation(self):
"""Test username format validation."""
# Valid usernames
valid_usernames = ["user", "user-name", "user_name", "user123", "a" * 39]
for username in valid_usernames:
with self.subTest(username=username):
result = github._extract_github_username(f"github.com/{username}")
self.assertEqual(result, username)
# Invalid usernames
invalid_usernames = ["", "a" * 40, "user@name", "user.name"]
for username in invalid_usernames:
with self.subTest(username=username):
result = github._extract_github_username(f"github.com/{username}")
self.assertIsNone(result)
class TestGetGitHubUserInfo(unittest.TestCase):
"""Test cases for the _get_github_user_info function."""
@patch('requests.get')
def test_successful_user_info(self, mock_get):
"""Test successful user info retrieval."""
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"login": "octocat",
"public_repos": 10,
"name": "The Octocat"
}
mock_get.return_value = mock_response
result = github._get_github_user_info("octocat")
self.assertEqual(result["status"], "success")
self.assertIn("data", result)
self.assertEqual(result["data"]["login"], "octocat")
@patch('requests.get')
def test_user_not_found(self, mock_get):
"""Test handling of non-existent user."""
mock_response = MagicMock()
mock_response.status_code = 404
mock_get.return_value = mock_response
result = github._get_github_user_info("nonexistentuser")
self.assertEqual(result["status"], "error")
self.assertIn("not found", result["message"])
@patch('requests.get')
def test_rate_limit_exceeded(self, mock_get):
"""Test handling of rate limit exceeded."""
mock_response = MagicMock()
mock_response.status_code = 403
mock_get.return_value = mock_response
result = github._get_github_user_info("octocat")
self.assertEqual(result["status"], "error")
self.assertIn("rate limit", result["message"])
@patch('requests.get')
def test_network_error(self, mock_get):
"""Test handling of network errors."""
mock_get.side_effect = requests.RequestException("Connection error")
result = github._get_github_user_info("octocat")
self.assertEqual(result["status"], "error")
self.assertIn("Network error", result["message"])
class TestGetUserRepositories(unittest.TestCase):
"""Test cases for the _get_user_repositories function."""
@patch('requests.get')
def test_successful_repository_retrieval(self, mock_get):
"""Test successful repository retrieval."""
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = [
{
"name": "Hello-World",
"description": "My first repository",
"language": "Python",
"stargazers_count": 5,
"forks_count": 2
}
]
mock_get.return_value = mock_response
result = github._get_user_repositories("octocat")
self.assertEqual(result["status"], "success")
self.assertIn("data", result)
self.assertEqual(len(result["data"]), 1)
self.assertEqual(result["data"][0]["name"], "Hello-World")
@patch('requests.get')
def test_empty_repository_list(self, mock_get):
"""Test handling of empty repository list."""
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = []
mock_get.return_value = mock_response
result = github._get_user_repositories("octocat")
self.assertEqual(result["status"], "success")
self.assertEqual(len(result["data"]), 0)
@patch('requests.get')
def test_api_error(self, mock_get):
"""Test handling of API errors."""
mock_response = MagicMock()
mock_response.status_code = 500
mock_get.return_value = mock_response
result = github._get_user_repositories("octocat")
self.assertEqual(result["status"], "error")
self.assertIn("GitHub API error", result["message"])
class TestProcessRepositoryData(unittest.TestCase):
"""Test cases for the _process_repository_data function."""
def test_basic_processing(self):
"""Test basic repository data processing."""
raw_repos = [
{
"name": "test-repo",
"description": "Test repository",
"language": "Python",
"stargazers_count": 10,
"forks_count": 5,
"updated_at": "2024-01-01T00:00:00Z",
"html_url": "https://github.com/user/test-repo",
"topics": ["python", "test"],
"fork": False
}
]
result = github._process_repository_data(raw_repos)
self.assertEqual(len(result), 1)
processed_repo = result[0]
self.assertEqual(processed_repo["name"], "test-repo")
self.assertEqual(processed_repo["description"], "Test repository")
self.assertEqual(processed_repo["language"], "Python")
self.assertEqual(processed_repo["stars"], 10)
self.assertEqual(processed_repo["forks"], 5)
self.assertFalse(processed_repo["is_fork"])
def test_fork_filtering(self):
"""Test filtering of unmodified forks."""
raw_repos = [
{
"name": "original-repo",
"fork": False,
"stargazers_count": 5
},
{
"name": "unmodified-fork",
"fork": True,
"stargazers_count": 0
},
{
"name": "modified-fork",
"fork": True,
"stargazers_count": 3
}
]
result = github._process_repository_data(raw_repos)
# Should include original repo and modified fork, exclude unmodified fork
self.assertEqual(len(result), 2)
repo_names = [repo["name"] for repo in result]
self.assertIn("original-repo", repo_names)
self.assertIn("modified-fork", repo_names)
self.assertNotIn("unmodified-fork", repo_names)
def test_missing_fields(self):
"""Test handling of missing fields in repository data."""
raw_repos = [
{
"name": "minimal-repo"
# Missing most optional fields
}
]
result = github._process_repository_data(raw_repos)
self.assertEqual(len(result), 1)
processed_repo = result[0]
self.assertEqual(processed_repo["name"], "minimal-repo")
self.assertEqual(processed_repo["description"], "")
self.assertEqual(processed_repo["language"], "")
self.assertEqual(processed_repo["stars"], 0)
self.assertEqual(processed_repo["forks"], 0)
class TestGetGitHubRepositories(unittest.TestCase):
"""Test cases for the get_github_repositories function."""
def test_empty_url(self):
"""Test handling of empty or None URL."""
test_cases = [None, "", " "]
for url in test_cases:
with self.subTest(url=url):
result = github.get_github_repositories(url)
self.assertEqual(result["status"], "error")
self.assertIn("No GitHub URL provided", result["message"])
@patch('functions.github._get_user_repositories')
@patch('functions.github._get_github_user_info')
@patch('functions.github._extract_github_username')
def test_successful_retrieval(self, mock_extract, mock_user_info, mock_repos):
"""Test successful repository retrieval."""
mock_extract.return_value = "octocat"
mock_user_info.return_value = {
"status": "success",
"data": {"public_repos": 10}
}
mock_repos.return_value = {
"status": "success",
"data": [{"name": "Hello-World", "fork": False, "stargazers_count": 5}]
}
result = github.get_github_repositories("https://github.com/octocat")
self.assertEqual(result["status"], "success")
self.assertIn("repositories", result)
self.assertIn("metadata", result)
self.assertEqual(result["metadata"]["username"], "octocat")
def test_invalid_url_format(self):
"""Test handling of invalid URL format."""
result = github.get_github_repositories("https://gitlab.com/user")
self.assertEqual(result["status"], "error")
self.assertIn("Invalid GitHub URL format", result["message"])
class TestFormatRepositoriesForLLM(unittest.TestCase):
"""Test cases for the format_repositories_for_llm function."""
def test_successful_formatting(self):
"""Test successful formatting of repository data."""
github_result = {
"status": "success",
"repositories": [
{
"name": "test-repo",
"description": "A test repository",
"language": "Python",
"stars": 10,
"forks": 5,
"updated_at": "2024-01-01T00:00:00Z",
"html_url": "https://github.com/user/test-repo",
"topics": ["python", "test"]
}
],
"metadata": {
"username": "testuser",
"profile_url": "https://github.com/testuser"
}
}
result = github.format_repositories_for_llm(github_result)
self.assertIn("=== GITHUB REPOSITORIES ===", result)
self.assertIn("testuser", result)
self.assertIn("test-repo", result)
self.assertIn("A test repository", result)
self.assertIn("Python", result)
self.assertIn("=== END GITHUB REPOSITORIES ===", result)
def test_error_status(self):
"""Test formatting when there's an error status."""
github_result = {
"status": "error",
"message": "User not found"
}
result = github.format_repositories_for_llm(github_result)
self.assertIn("could not be retrieved", result)
self.assertIn("User not found", result)
def test_no_repositories(self):
"""Test formatting when no repositories are found."""
github_result = {
"status": "success",
"repositories": [],
"metadata": {"username": "emptyuser"}
}
result = github.format_repositories_for_llm(github_result)
self.assertIn("No public repositories found", result)
self.assertIn("emptyuser", result)
def test_many_repositories_limit(self):
"""Test that formatting limits to 20 repositories."""
repositories = []
for i in range(25):
repositories.append({
"name": f"repo-{i}",
"description": f"Repository {i}",
"language": "Python",
"stars": i,
"forks": 0,
"updated_at": "2024-01-01T00:00:00Z",
"html_url": f"https://github.com/user/repo-{i}",
"topics": []
})
github_result = {
"status": "success",
"repositories": repositories,
"metadata": {"username": "manyrepos"}
}
result = github.format_repositories_for_llm(github_result)
# Should mention "and 5 more repositories"
self.assertIn("and 5 more repositories", result)
# Should contain the first 20 repos
self.assertIn("repo-0", result)
self.assertIn("repo-19", result)
# Should not contain repos beyond 20
self.assertNotIn("repo-20", result)
if __name__ == '__main__':
unittest.main()