SummarizerApp / tests /test_api.py
ming
Add comprehensive unit tests for all production-ready features
0497d92
raw
history blame
3.65 kB
"""
Integration tests for API endpoints.
"""
import pytest
from unittest.mock import patch
from starlette.testclient import TestClient
from app.main import app
from tests.test_services import StubAsyncClient, StubAsyncResponse
client = TestClient(app)
@pytest.mark.integration
def test_summarize_endpoint_success(sample_text, mock_ollama_response):
"""Test successful summarization via API endpoint."""
stub_response = StubAsyncResponse(json_data=mock_ollama_response)
with patch('httpx.AsyncClient', return_value=StubAsyncClient(post_result=stub_response)):
resp = client.post(
"/api/v1/summarize/",
json={"text": sample_text, "max_tokens": 128}
)
assert resp.status_code == 200
data = resp.json()
assert data["summary"] == mock_ollama_response["response"]
assert data["model"]
@pytest.mark.integration
def test_summarize_endpoint_validation_error():
"""Test validation error for empty text."""
resp = client.post(
"/api/v1/summarize/",
json={"text": ""}
)
assert resp.status_code == 422
# Tests for Better Error Handling
@pytest.mark.integration
def test_summarize_endpoint_timeout_error():
"""Test that timeout errors return 504 Gateway Timeout instead of 502."""
import httpx
with patch('httpx.AsyncClient', return_value=StubAsyncClient(post_exc=httpx.TimeoutException("Timeout"))):
resp = client.post(
"/api/v1/summarize/",
json={"text": "Test text that will timeout"}
)
assert resp.status_code == 504 # Gateway Timeout
data = resp.json()
assert "timeout" in data["detail"].lower()
assert "text may be too long" in data["detail"].lower()
@pytest.mark.integration
def test_summarize_endpoint_http_error():
"""Test that HTTP errors return 502 Bad Gateway."""
import httpx
http_error = httpx.HTTPStatusError("Bad Request", request=MagicMock(), response=MagicMock())
with patch('httpx.AsyncClient', return_value=StubAsyncClient(post_exc=http_error)):
resp = client.post(
"/api/v1/summarize/",
json={"text": "Test text"}
)
assert resp.status_code == 502 # Bad Gateway
data = resp.json()
assert "Summarization failed" in data["detail"]
@pytest.mark.integration
def test_summarize_endpoint_unexpected_error():
"""Test that unexpected errors return 500 Internal Server Error."""
with patch('httpx.AsyncClient', return_value=StubAsyncClient(post_exc=Exception("Unexpected error"))):
resp = client.post(
"/api/v1/summarize/",
json={"text": "Test text"}
)
assert resp.status_code == 500 # Internal Server Error
data = resp.json()
assert "Internal server error" in data["detail"]
@pytest.mark.integration
def test_summarize_endpoint_large_text_handling():
"""Test that large text requests are handled with appropriate timeout."""
large_text = "A" * 5000 # Large text that should trigger dynamic timeout
with patch('httpx.AsyncClient') as mock_client:
mock_client.return_value = StubAsyncClient(post_result=StubAsyncResponse())
resp = client.post(
"/api/v1/summarize/",
json={"text": large_text, "max_tokens": 256}
)
# Verify the client was called with extended timeout
mock_client.assert_called_once()
call_args = mock_client.call_args
expected_timeout = 120 + (5000 - 1000) // 1000 * 10 # 160 seconds
assert call_args[1]['timeout'] == expected_timeout