chore: import upstream snapshot with attribution
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:08:55 +08:00
commit 7a0da7932b
2985 changed files with 1049377 additions and 0 deletions
@@ -0,0 +1,727 @@
"""
Comprehensive tests for the GitHub search engine.
Tests initialization, search functionality, and API configuration.
"""
import base64
import pytest
from unittest.mock import Mock, patch
class TestGitHubSearchEngineInit:
"""Tests for GitHub search engine initialization."""
def test_init_default_parameters(self):
"""Test initialization with default parameters."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
assert engine.max_results >= 10
# Default search type is repositories
assert engine.search_type == "repositories"
assert engine.api_key is None
def test_init_with_api_key(self):
"""Test initialization with GitHub API key."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(api_key="ghp_test_token_123")
assert engine.api_key == "ghp_test_token_123"
def test_init_with_search_type(self):
"""Test initialization with specific search type."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="code")
assert engine.search_type == "code"
def test_init_with_custom_max_results(self):
"""Test initialization with custom max results."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(max_results=50)
assert engine.max_results >= 50
class TestGitHubSearchExecution:
"""Tests for GitHub search execution."""
@pytest.fixture
def github_engine(self):
"""Create a GitHub engine instance."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
return GitHubSearchEngine(max_results=10)
def test_engine_initialization(self, github_engine):
"""Test that engine is properly initialized."""
assert github_engine is not None
assert github_engine.max_results >= 10
def test_engine_has_api_base(self, github_engine):
"""Test that engine has API base URL configured."""
assert hasattr(github_engine, "api_base")
assert "api.github.com" in github_engine.api_base
class TestGitHubAPIConfiguration:
"""Tests for GitHub API configuration."""
def test_api_key_in_headers(self):
"""Test that API key is included in headers when provided."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(api_key="ghp_my_token")
assert engine.api_key == "ghp_my_token"
# Check that Authorization header is set
assert "Authorization" in engine.headers
assert "ghp_my_token" in engine.headers["Authorization"]
def test_no_api_key_anonymous_access(self):
"""Test that engine works without API key (anonymous access)."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
assert engine.api_key is None
# Authorization header should not be present without API key
assert "Authorization" not in engine.headers
class TestGitHubSearchTypes:
"""Tests for different GitHub search types."""
def test_repository_search_type(self):
"""Test repository search type configuration."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="repositories")
assert engine.search_type == "repositories"
def test_code_search_type(self):
"""Test code search type configuration."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="code")
assert engine.search_type == "code"
def test_issues_search_type(self):
"""Test issues search type configuration."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="issues")
assert engine.search_type == "issues"
def test_users_search_type(self):
"""Test users search type configuration."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="users")
assert engine.search_type == "users"
class TestGitHubEngineType:
"""Tests for GitHub engine type identification."""
def test_engine_type_set(self):
"""Test that engine type is properly set."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
assert "github" in engine.engine_type.lower()
class TestGitHubHeaders:
"""Tests for GitHub request headers."""
def test_accept_header_set(self):
"""Test that Accept header is set for API compatibility."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
assert "Accept" in engine.headers
assert "application/vnd.github" in engine.headers["Accept"]
def test_user_agent_header_set(self):
"""Test that User-Agent header is set."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
assert "User-Agent" in engine.headers
class TestGitHubAdvancedInit:
"""Tests for advanced initialization options."""
def test_init_with_readme_option(self):
"""Test initialization with include_readme option."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(include_readme=False)
assert engine.include_readme is False
def test_init_with_issues_option(self):
"""Test initialization with include_issues option."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(include_issues=True)
assert engine.include_issues is True
def test_init_with_llm(self):
"""Test initialization with LLM."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
mock_llm = Mock()
engine = GitHubSearchEngine(llm=mock_llm)
assert engine.llm is mock_llm
class TestGitHubRateLimits:
"""Tests for rate limit handling."""
def test_handle_rate_limits_normal(self):
"""Test rate limit handling with normal remaining."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
mock_response = Mock()
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
# Should not raise or sleep
engine._handle_rate_limits(mock_response)
def test_handle_rate_limits_low_remaining(self):
"""Test rate limit handling with low remaining requests."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
mock_response = Mock()
mock_response.headers = {
"X-RateLimit-Remaining": "3",
"X-RateLimit-Reset": "0",
}
# Should log warning but not sleep
engine._handle_rate_limits(mock_response)
class TestGitHubOptimizeQuery:
"""Tests for query optimization."""
def test_optimize_query_without_llm(self):
"""Test query optimization returns original without LLM."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(llm=None)
# Patch the config getter to return None
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.llm_config.get_llm",
return_value=None,
):
result = engine._optimize_github_query("python web framework")
assert result == "python web framework"
def test_optimize_query_with_llm(self):
"""Test query optimization with LLM."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
mock_llm = Mock()
mock_llm.invoke.return_value = Mock(
content="python web framework stars:>100"
)
engine = GitHubSearchEngine(llm=mock_llm)
result = engine._optimize_github_query("python web framework")
assert "python" in result.lower()
mock_llm.invoke.assert_called_once()
def test_optimize_query_handles_error(self):
"""Test query optimization handles LLM errors gracefully."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
mock_llm = Mock()
mock_llm.invoke.side_effect = Exception("LLM error")
engine = GitHubSearchEngine(llm=mock_llm)
result = engine._optimize_github_query("test query")
# Should fall back to original query
assert result == "test query"
def test_optimize_query_handles_empty_response(self):
"""Test query optimization handles empty LLM response."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
mock_llm = Mock()
mock_llm.invoke.return_value = Mock(content="")
engine = GitHubSearchEngine(llm=mock_llm)
result = engine._optimize_github_query("test query")
# Should fall back to original query
assert result == "test query"
class TestGitHubSearchGithub:
"""Tests for _search_github method."""
def test_search_github_success(self):
"""Test successful GitHub search."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(llm=None)
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {
"total_count": 2,
"items": [
{"id": 1, "full_name": "owner/repo1"},
{"id": 2, "full_name": "owner/repo2"},
],
}
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.llm_config.get_llm",
return_value=None,
):
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._search_github("python")
assert len(result) == 2
assert result[0]["full_name"] == "owner/repo1"
def test_search_github_handles_error(self):
"""Test search handles API errors."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(llm=None)
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.llm_config.get_llm",
return_value=None,
):
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
side_effect=Exception("API error"),
):
result = engine._search_github("test query")
assert result == []
def test_search_github_handles_non_200_response(self):
"""Test search handles non-200 responses."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(llm=None)
mock_response = Mock()
mock_response.status_code = 403
mock_response.text = "Rate limit exceeded"
mock_response.headers = {
"X-RateLimit-Remaining": "0",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.llm_config.get_llm",
return_value=None,
):
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._search_github("test")
assert result == []
class TestGitHubGetReadmeContent:
"""Tests for _get_readme_content method."""
def test_get_readme_success(self):
"""Test successful README retrieval."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
readme_content = "# Test README\nThis is a test."
encoded_content = base64.b64encode(readme_content.encode()).decode()
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {
"content": encoded_content,
"encoding": "base64",
}
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._get_readme_content("owner/repo")
assert "Test README" in result
def test_get_readme_not_found(self):
"""Test README not found."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
mock_response = Mock()
mock_response.status_code = 404
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._get_readme_content("owner/repo")
assert result == ""
def test_get_readme_handles_error(self):
"""Test README retrieval handles errors."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
side_effect=Exception("Network error"),
):
result = engine._get_readme_content("owner/repo")
assert result == ""
class TestGitHubGetRecentIssues:
"""Tests for _get_recent_issues method."""
def test_get_issues_success(self):
"""Test successful issues retrieval."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
mock_issues = [
{"number": 1, "title": "Issue 1"},
{"number": 2, "title": "Issue 2"},
]
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = mock_issues
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._get_recent_issues("owner/repo", limit=5)
assert len(result) == 2
assert result[0]["title"] == "Issue 1"
def test_get_issues_not_found(self):
"""Test issues not found."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
mock_response = Mock()
mock_response.status_code = 404
mock_response.headers = {
"X-RateLimit-Remaining": "50",
"X-RateLimit-Reset": "0",
}
with patch(
"local_deep_research.web_search_engines.engines.search_engine_github.safe_get",
return_value=mock_response,
):
result = engine._get_recent_issues("owner/repo")
assert result == []
class TestGitHubFormatPreviews:
"""Tests for preview formatting methods."""
def test_format_repository_preview(self):
"""Test repository preview formatting."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
repo = {
"id": 123,
"full_name": "owner/repo",
"html_url": "https://github.com/owner/repo",
"description": "Test description",
"stargazers_count": 100,
"forks_count": 10,
"language": "Python",
"owner": {"login": "owner"},
}
preview = engine._format_repository_preview(repo)
assert preview["title"] == "owner/repo"
assert preview["stars"] == 100
assert preview["language"] == "Python"
assert preview["search_type"] == "repository"
def test_format_code_preview(self):
"""Test code preview formatting."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
code = {
"sha": "abc123",
"name": "test.py",
"path": "src/test.py",
"html_url": "https://github.com/owner/repo/blob/main/test.py",
"repository": {
"full_name": "owner/repo",
"html_url": "https://github.com/owner/repo",
},
}
preview = engine._format_code_preview(code)
assert "test.py" in preview["title"]
assert preview["path"] == "src/test.py"
assert preview["search_type"] == "code"
def test_format_issue_preview(self):
"""Test issue preview formatting."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
issue = {
"number": 42,
"title": "Bug report",
"html_url": "https://github.com/owner/repo/issues/42",
"body": "This is a bug description",
"state": "open",
"user": {"login": "reporter"},
"comments": 5,
}
preview = engine._format_issue_preview(issue)
assert preview["title"] == "Bug report"
assert preview["state"] == "open"
assert preview["search_type"] == "issue"
def test_format_user_preview(self):
"""Test user preview formatting."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine()
user = {
"id": 1,
"login": "testuser",
"html_url": "https://github.com/testuser",
"bio": "Test bio",
"followers": 100,
"public_repos": 50,
}
preview = engine._format_user_preview(user)
assert preview["title"] == "testuser"
assert preview["followers"] == 100
assert preview["search_type"] == "user"
class TestGitHubGetPreviews:
"""Tests for _get_previews method."""
def test_get_previews_repository(self):
"""Test getting repository previews."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="repositories", llm=None)
mock_results = [
{
"id": 123,
"full_name": "owner/repo",
"html_url": "https://github.com/owner/repo",
"description": "Test repo",
"stargazers_count": 100,
"forks_count": 10,
"owner": {"login": "owner"},
}
]
with patch.object(engine, "_search_github", return_value=mock_results):
previews = engine._get_previews("python")
assert len(previews) == 1
assert previews[0]["search_type"] == "repository"
def test_get_previews_code(self):
"""Test getting code previews."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="code", llm=None)
mock_results = [
{
"sha": "abc123",
"name": "test.py",
"path": "src/test.py",
"html_url": "https://github.com/owner/repo/blob/main/test.py",
"repository": {"full_name": "owner/repo"},
}
]
with patch.object(engine, "_search_github", return_value=mock_results):
previews = engine._get_previews("function")
assert len(previews) == 1
assert previews[0]["search_type"] == "code"
def test_get_previews_no_results(self):
"""Test getting previews with no results."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(llm=None)
with patch.object(engine, "_search_github", return_value=[]):
previews = engine._get_previews("nonexistent")
assert previews == []
def test_get_previews_contribution_query(self):
"""Test getting previews for contribution-focused queries."""
from local_deep_research.web_search_engines.engines.search_engine_github import (
GitHubSearchEngine,
)
engine = GitHubSearchEngine(search_type="issues", llm=None)
mock_results = [
{
"id": 123,
"full_name": "owner/repo",
"html_url": "https://github.com/owner/repo",
"description": "Good for beginners",
"stargazers_count": 500,
"forks_count": 50,
"owner": {"login": "owner"},
}
]
with patch.object(engine, "_search_github", return_value=mock_results):
previews = engine._get_previews(
"beginner python projects to contribute"
)
# Should have adjusted search type
assert len(previews) == 1