161 lines
No EOL
6 KiB
Python
161 lines
No EOL
6 KiB
Python
from fastapi.testclient import TestClient
|
|
from unittest.mock import patch, Mock
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Import the FastAPI app
|
|
from main import app
|
|
from app.models.fact_check_models import (
|
|
FactCheckResponse,
|
|
UnverifiedFactCheckResponse,
|
|
VerdictEnum,
|
|
ConfidenceEnum,
|
|
Source
|
|
)
|
|
|
|
# Create test client
|
|
client = TestClient(app)
|
|
|
|
def test_check_facts_missing_query():
|
|
"""Test the endpoint with a missing query."""
|
|
response = client.post("/check-facts", json={})
|
|
assert response.status_code == 422 # Validation error
|
|
|
|
def test_check_facts_short_query():
|
|
"""Test the endpoint with a query that's too short."""
|
|
response = client.post("/check-facts", json={"query": "ab"})
|
|
assert response.status_code == 422 # Query too short
|
|
|
|
def test_check_facts_valid_query_no_sources():
|
|
"""Test the endpoint with a valid query but no sources found."""
|
|
test_query = "Does drinking water cure all diseases?"
|
|
|
|
# Mock the search_websites function
|
|
with patch('app.api.scrap_websites.search_websites') as mock_search:
|
|
mock_search.return_value = {
|
|
"status": "no_results",
|
|
"urls_found": 0,
|
|
"verification_result": {
|
|
"no_sources_found": True,
|
|
"reason": "No relevant fact-checking sources found"
|
|
}
|
|
}
|
|
|
|
response = client.post("/check-facts", json={"query": test_query})
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["claim"] == test_query
|
|
assert data["verdict"] == VerdictEnum.UNVERIFIED
|
|
assert data["confidence"] == ConfidenceEnum.LOW
|
|
assert data["sources"] == []
|
|
assert "No fact-checking sources" in data["evidence"]
|
|
|
|
def test_check_facts_valid_query_with_sources():
|
|
"""Test the endpoint with a valid query and sources found."""
|
|
test_query = "Did NASA find aliens on Mars?"
|
|
mock_fact_check_response = {
|
|
"claims": [
|
|
{
|
|
"text": test_query,
|
|
"claimReview": [
|
|
{
|
|
"publisher": {
|
|
"name": "Fact Check Organization",
|
|
"site": "https://factcheck.org"
|
|
},
|
|
"textualRating": "False",
|
|
"title": "NASA Mars Claim",
|
|
"url": "https://factcheck.org/mars-claim"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
|
|
# Mock both the Google Fact Check API call and search_websites
|
|
with patch('httpx.AsyncClient.get') as mock_get:
|
|
mock_get.return_value.status_code = 200
|
|
mock_get.return_value.json.return_value = mock_fact_check_response
|
|
|
|
response = client.post("/check-facts", json={"query": test_query})
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["claim"] == test_query
|
|
assert data["verdict"] in [v.value for v in VerdictEnum]
|
|
assert data["confidence"] in [c.value for c in ConfidenceEnum]
|
|
assert len(data["sources"]) >= 1
|
|
assert all(isinstance(source, dict) for source in data["sources"])
|
|
assert all("url" in source and "name" in source for source in data["sources"])
|
|
|
|
def test_check_facts_api_error():
|
|
"""Test the endpoint's handling of API errors."""
|
|
test_query = "Test query for API error"
|
|
|
|
# Mock API error scenario
|
|
with patch('httpx.AsyncClient.get') as mock_get:
|
|
mock_get.side_effect = Exception("API Error")
|
|
|
|
response = client.post("/check-facts", json={"query": test_query})
|
|
|
|
assert response.status_code == 200 # We return 200 with UnverifiedFactCheckResponse
|
|
data = response.json()
|
|
assert data["verdict"] == VerdictEnum.UNVERIFIED
|
|
assert data["confidence"] == ConfidenceEnum.LOW
|
|
assert data["sources"] == []
|
|
assert "error" in data["evidence"].lower()
|
|
|
|
def test_check_facts_missing_api_keys():
|
|
"""Test the endpoint's handling of missing API keys."""
|
|
test_query = "Test query without API keys"
|
|
|
|
# Mock missing API keys
|
|
with patch('app.api.fact_check.GOOGLE_API_KEY', None):
|
|
response = client.post("/check-facts", json={"query": test_query})
|
|
|
|
assert response.status_code == 200 # We return 200 with UnverifiedFactCheckResponse
|
|
data = response.json()
|
|
assert data["verdict"] == VerdictEnum.UNVERIFIED
|
|
assert "configuration" in data["evidence"].lower()
|
|
assert data["sources"] == []
|
|
|
|
def test_check_facts_rate_limit():
|
|
"""Test the endpoint's handling of rate limiting."""
|
|
test_query = "Test query for rate limit"
|
|
|
|
# Mock rate limit response
|
|
with patch('httpx.AsyncClient.get') as mock_get:
|
|
mock_get.return_value.status_code = 429
|
|
|
|
response = client.post("/check-facts", json={"query": test_query})
|
|
|
|
assert response.status_code == 200 # We return 200 with UnverifiedFactCheckResponse
|
|
data = response.json()
|
|
assert data["verdict"] == VerdictEnum.UNVERIFIED
|
|
assert data["confidence"] == ConfidenceEnum.LOW
|
|
assert data["sources"] == []
|
|
|
|
def test_check_facts_empty_query():
|
|
"""Test the endpoint with an empty query."""
|
|
response = client.post("/check-facts", json={"query": ""})
|
|
assert response.status_code == 422 # Validation error
|
|
|
|
def test_check_facts_long_query():
|
|
"""Test the endpoint with a query that exceeds maximum length."""
|
|
long_query = "a" * 501 # Create a string longer than max_length (500)
|
|
response = client.post("/check-facts", json={"query": long_query})
|
|
assert response.status_code == 422 # Validation error
|
|
|
|
def test_check_facts_malformed_json():
|
|
"""Test the endpoint with malformed JSON."""
|
|
response = client.post(
|
|
"/check-facts",
|
|
data="this is not json",
|
|
headers={"Content-Type": "application/json"}
|
|
)
|
|
assert response.status_code == 422 # JSON validation error
|
|
|
|
if __name__ == "__main__":
|
|
import pytest
|
|
pytest.main([__file__, "-v"]) |