Files
webber/webber-api/tests/test_e2e.py
T
jpmschweitzerandClaude Opus 4.5 c839e263f9
Build and Push API / release (push) Successful in 3s
Build and Push API / build (push) Has been cancelled
test: add integration and E2E test infrastructure
- Add pytest markers (integration, e2e, slow) with skip logic
- Add command line options (--run-integration, --run-e2e)
- Create sample_project and sample_project_with_bug fixtures
- Add test_integration.py with 10 LLM tests
- Add test_e2e.py with 12 API server tests
- Update COVERAGE.md to reflect ~65% complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 19:33:21 +01:00

226 lines
6.8 KiB
Python

"""
End-to-end tests for the API.
These tests require the API server to be running and are skipped by default.
Run with: pytest tests/test_e2e.py -v --run-e2e
Start the server first: ./wakeup.sh
"""
import pytest
from tests.conftest import assert_contains_any
# All tests in this module require --run-e2e
pytestmark = [pytest.mark.e2e, pytest.mark.slow]
class TestHealthEndpoint:
"""E2E tests for health endpoint."""
@pytest.mark.anyio
async def test_health_check(self, live_client):
"""Test that health endpoint responds."""
response = await live_client.get("/health")
assert response.status_code == 200
data = response.json()
assert data.get("status") == "healthy"
class TestAgentEndpoints:
"""E2E tests for agent endpoints."""
@pytest.mark.anyio
async def test_list_agents(self, live_client):
"""Test listing agents via live API."""
response = await live_client.get("/agents/")
assert response.status_code == 200
data = response.json()
assert "agents" in data
assert len(data["agents"]) >= 1
# Verify explore agent exists
names = [a["name"] for a in data["agents"]]
assert "explore" in names
@pytest.mark.anyio
async def test_get_agent_info(self, live_client):
"""Test getting agent info via live API."""
response = await live_client.get("/agents/explore")
assert response.status_code == 200
data = response.json()
assert data["name"] == "explore"
assert "description" in data
@pytest.mark.anyio
async def test_run_agent(self, live_client, sample_project):
"""Test running agent via live API."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "explore",
"prompt": "List all files in this directory",
"working_dir": str(sample_project),
},
timeout=60.0, # LLM calls can be slow
)
assert response.status_code == 200
data = response.json()
assert data.get("success") is True
assert "response" in data
assert len(data["response"]) > 0
class TestStreamingEndpoint:
"""E2E tests for streaming endpoint."""
@pytest.mark.anyio
async def test_stream_agent(self, live_client, sample_project):
"""Test streaming agent responses via live API."""
async with live_client.stream(
"POST",
"/agents/stream",
json={
"agent_type": "explore",
"prompt": "List all Python files",
"working_dir": str(sample_project),
},
timeout=60.0,
) as response:
assert response.status_code == 200
assert response.headers.get("content-type") == "text/event-stream; charset=utf-8"
# Collect chunks
chunks = []
async for line in response.aiter_lines():
if line.startswith("data: "):
chunks.append(line)
# Should receive some data
assert len(chunks) >= 1
@pytest.mark.anyio
async def test_stream_invalid_agent(self, live_client):
"""Test streaming with invalid agent type."""
response = await live_client.post(
"/agents/stream",
json={
"agent_type": "nonexistent",
"prompt": "test",
"working_dir": ".",
},
)
assert response.status_code == 400
class TestErrorHandling:
"""E2E tests for error handling."""
@pytest.mark.anyio
async def test_invalid_agent_type(self, live_client):
"""Test error response for invalid agent."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "nonexistent",
"prompt": "test",
"working_dir": ".",
},
)
assert response.status_code == 400
data = response.json()
assert "detail" in data
@pytest.mark.anyio
async def test_missing_required_fields(self, live_client):
"""Test validation error for missing fields."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "explore",
# Missing prompt
},
)
assert response.status_code == 422
@pytest.mark.anyio
async def test_agent_not_found(self, live_client):
"""Test 404 for unknown agent info."""
response = await live_client.get("/agents/unknown_agent")
assert response.status_code == 404
class TestRealWorldScenarios:
"""E2E tests for real-world usage scenarios."""
@pytest.mark.anyio
async def test_explore_codebase(self, live_client, sample_project):
"""Test exploring a real codebase."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "explore",
"prompt": "What functions are defined in the src directory?",
"working_dir": str(sample_project),
},
timeout=60.0,
)
assert response.status_code == 200
data = response.json()
assert data.get("success") is True
# Should mention some functions
assert_contains_any(
data.get("response", ""),
["greet", "add", "divide", "factorial", "function"]
)
@pytest.mark.anyio
async def test_find_bugs(self, live_client, sample_project_with_bug):
"""Test finding bugs in code."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "explore",
"prompt": "Review buggy.py and identify any potential bugs or issues.",
"working_dir": str(sample_project_with_bug),
},
timeout=60.0,
)
assert response.status_code == 200
data = response.json()
assert data.get("success") is True
# Should identify issues
assert_contains_any(
data.get("response", ""),
["zero", "division", "bug", "error", "issue", "check"]
)
@pytest.mark.anyio
async def test_read_and_summarize(self, live_client, sample_project):
"""Test reading and summarizing a file."""
response = await live_client.post(
"/agents/run",
json={
"agent_type": "explore",
"prompt": "Read README.md and give me a one-sentence summary.",
"working_dir": str(sample_project),
},
timeout=60.0,
)
assert response.status_code == 200
data = response.json()
assert data.get("success") is True
assert len(data.get("response", "")) > 10