7a0da7932b
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
251 lines
8.5 KiB
Python
251 lines
8.5 KiB
Python
"""
|
|
Search engine mock fixtures - Based on scottvr's patterns but updated for current codebase.
|
|
|
|
This module provides mock responses for various search engines.
|
|
"""
|
|
|
|
from typing import Any, Dict, List
|
|
from urllib.parse import urlparse
|
|
|
|
import pytest
|
|
|
|
|
|
class SearchEngineMocks:
|
|
"""Collection of search engine mock responses."""
|
|
|
|
@staticmethod
|
|
def wikipedia_response() -> Dict[str, Any]:
|
|
"""Mock Wikipedia API response."""
|
|
return {
|
|
"query": {
|
|
"search": [
|
|
{
|
|
"title": "Artificial intelligence",
|
|
"snippet": "Artificial intelligence (AI) is intelligence demonstrated by machines...",
|
|
"pageid": 12345,
|
|
},
|
|
{
|
|
"title": "Machine learning",
|
|
"snippet": "Machine learning (ML) is a subset of artificial intelligence (AI)...",
|
|
"pageid": 67890,
|
|
},
|
|
]
|
|
}
|
|
}
|
|
|
|
@staticmethod
|
|
def arxiv_response() -> str:
|
|
"""Mock arXiv XML response."""
|
|
return """<?xml version="1.0" encoding="UTF-8"?>
|
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
<entry>
|
|
<title>Test Paper Title</title>
|
|
<id>http://arxiv.org/abs/2301.12345</id>
|
|
<summary>This is a test paper abstract about machine learning.</summary>
|
|
<published>2023-01-15T00:00:00Z</published>
|
|
<author>
|
|
<name>Test Author</name>
|
|
</author>
|
|
</entry>
|
|
</feed>"""
|
|
|
|
@staticmethod
|
|
def pubmed_search_response() -> str:
|
|
"""Mock PubMed search response."""
|
|
return """<?xml version="1.0" encoding="UTF-8"?>
|
|
<eSearchResult>
|
|
<IdList>
|
|
<Id>12345678</Id>
|
|
<Id>87654321</Id>
|
|
</IdList>
|
|
</eSearchResult>"""
|
|
|
|
@staticmethod
|
|
def pubmed_article_response() -> str:
|
|
"""Mock PubMed article detail."""
|
|
return """<?xml version="1.0" encoding="UTF-8"?>
|
|
<PubmedArticleSet>
|
|
<PubmedArticle>
|
|
<MedlineCitation>
|
|
<PMID>12345678</PMID>
|
|
<Article>
|
|
<ArticleTitle>Test Medical Research Paper</ArticleTitle>
|
|
<Abstract>
|
|
<AbstractText>This is a test medical abstract about clinical trials.</AbstractText>
|
|
</Abstract>
|
|
<AuthorList>
|
|
<Author>
|
|
<LastName>Smith</LastName>
|
|
<ForeName>John</ForeName>
|
|
</Author>
|
|
</AuthorList>
|
|
</Article>
|
|
</MedlineCitation>
|
|
</PubmedArticle>
|
|
</PubmedArticleSet>"""
|
|
|
|
@staticmethod
|
|
def semantic_scholar_response() -> Dict[str, Any]:
|
|
"""Mock Semantic Scholar API response."""
|
|
return {
|
|
"data": [
|
|
{
|
|
"paperId": "abc123def456", # pragma: allowlist secret
|
|
"title": "Deep Learning: A Comprehensive Overview",
|
|
"abstract": "This paper provides a comprehensive overview of deep learning techniques...",
|
|
"year": 2023,
|
|
"authors": [
|
|
{"authorId": "123", "name": "John Doe"},
|
|
{"authorId": "456", "name": "Jane Smith"},
|
|
],
|
|
"url": "https://www.semanticscholar.org/paper/abc123def456",
|
|
"venue": "Journal of Machine Learning Research",
|
|
"citationCount": 42,
|
|
}
|
|
]
|
|
}
|
|
|
|
@staticmethod
|
|
def google_pse_response() -> Dict[str, Any]:
|
|
"""Mock Google Programmable Search Engine response."""
|
|
return {
|
|
"kind": "customsearch#search",
|
|
"items": [
|
|
{
|
|
"kind": "customsearch#result",
|
|
"title": "Understanding Artificial Intelligence",
|
|
"link": "https://example.com/ai-guide",
|
|
"snippet": "A comprehensive guide to understanding artificial intelligence and its applications...",
|
|
"displayLink": "example.com",
|
|
"pagemap": {
|
|
"metatags": [
|
|
{
|
|
"og:description": "Learn about AI, machine learning, and neural networks in this comprehensive guide."
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"kind": "customsearch#result",
|
|
"title": "Machine Learning Basics",
|
|
"link": "https://example.com/ml-basics",
|
|
"snippet": "Introduction to machine learning concepts and algorithms...",
|
|
"displayLink": "example.com",
|
|
},
|
|
],
|
|
}
|
|
|
|
@staticmethod
|
|
def ddg_response() -> List[Dict[str, Any]]:
|
|
"""Mock DuckDuckGo search response."""
|
|
return [
|
|
{
|
|
"title": "Artificial Intelligence - Wikipedia",
|
|
"link": "https://en.wikipedia.org/wiki/Artificial_intelligence",
|
|
"snippet": "Artificial intelligence (AI) is intelligence demonstrated by machines...",
|
|
},
|
|
{
|
|
"title": "What is AI? Artificial Intelligence Explained",
|
|
"link": "https://example.com/what-is-ai",
|
|
"snippet": "AI refers to the simulation of human intelligence in machines...",
|
|
},
|
|
]
|
|
|
|
@staticmethod
|
|
def error_responses() -> Dict[str, Any]:
|
|
"""Collection of error responses for testing error handling."""
|
|
return {
|
|
"http_500": {"status_code": 500, "error": "Internal Server Error"},
|
|
"http_404": {"status_code": 404, "error": "Not Found"},
|
|
"http_429": {
|
|
"status_code": 429,
|
|
"error": "Too Many Requests",
|
|
"retry_after": 60,
|
|
},
|
|
"http_403": {
|
|
"status_code": 403,
|
|
"error": "Forbidden",
|
|
"message": "Invalid API key",
|
|
},
|
|
"network_timeout": {"error": "Connection timeout after 30 seconds"},
|
|
"dns_failure": {"error": "Failed to resolve hostname"},
|
|
"ssl_error": {"error": "SSL certificate verification failed"},
|
|
}
|
|
|
|
|
|
def validate_wikipedia_url(url: str) -> bool:
|
|
"""
|
|
Safely validate that a URL belongs to Wikipedia.
|
|
|
|
This addresses the security issue mentioned in the PR review.
|
|
"""
|
|
try:
|
|
parsed = urlparse(url)
|
|
hostname = parsed.hostname
|
|
scheme = parsed.scheme
|
|
|
|
if not hostname or not scheme:
|
|
return False
|
|
|
|
# Only allow HTTPS URLs for security
|
|
if scheme not in ["http", "https"]:
|
|
return False
|
|
|
|
# Check for wikipedia.org domain and its subdomains
|
|
return (
|
|
hostname.endswith(".wikipedia.org") or hostname == "wikipedia.org"
|
|
)
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
@pytest.fixture
|
|
def search_engine_mocks():
|
|
"""Provide SearchEngineMocks instance as a fixture."""
|
|
return SearchEngineMocks()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_successful_api_response(mocker):
|
|
"""Create a mock successful API response."""
|
|
|
|
def _create_response(status_code=200, json_data=None, text_data=None):
|
|
mock_response = mocker.Mock()
|
|
mock_response.status_code = status_code
|
|
mock_response.ok = status_code < 400
|
|
|
|
if json_data is not None:
|
|
mock_response.json.return_value = json_data
|
|
mock_response.text = str(json_data)
|
|
elif text_data is not None:
|
|
mock_response.text = text_data
|
|
mock_response.json.side_effect = ValueError("Not JSON")
|
|
else:
|
|
mock_response.json.return_value = {}
|
|
mock_response.text = "{}"
|
|
|
|
return mock_response
|
|
|
|
return _create_response
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_error_api_response(mocker):
|
|
"""Create a mock error API response."""
|
|
|
|
def _create_error(error_type="http_500"):
|
|
errors = SearchEngineMocks.error_responses()
|
|
error_data = errors.get(error_type, errors["http_500"])
|
|
|
|
if "status_code" in error_data:
|
|
mock_response = mocker.Mock()
|
|
mock_response.status_code = error_data["status_code"]
|
|
mock_response.ok = False
|
|
mock_response.text = error_data.get("error", "Error")
|
|
mock_response.json.return_value = error_data
|
|
return mock_response
|
|
# Network-level error
|
|
raise ConnectionError(error_data.get("error", "Unknown error"))
|
|
|
|
return _create_error
|