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"])