elara / tests /test_api.py
adityagirishh's picture
reduced to 4 tasks
7b988a7
"""
test_api.py — Tests for the FastAPI server endpoints
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent / "app"))
sys.path.insert(0, str(Path(__file__).parent.parent))
import pytest
from fastapi.testclient import TestClient
from server import app
client = TestClient(app)
class TestHealthEndpoint:
def test_health_returns_ok(self):
resp = client.get("/health")
assert resp.status_code == 200
data = resp.json()
assert data["status"] == "ok"
assert data["project"] == "E.L.A.R.A."
class TestResetEndpoint:
def test_reset_default(self):
resp = client.post("/reset")
assert resp.status_code == 200
data = resp.json()
assert "observation" in data
obs = data["observation"]
assert obs["task_id"] == "easy"
assert obs["lead_id"] == "L-001"
def test_reset_with_task(self):
resp = client.post("/reset", json={"task_id": "medium"})
assert resp.status_code == 200
obs = resp.json()["observation"]
assert obs["task_id"] == "medium"
assert obs["lead_id"] == "L-004"
def test_reset_invalid_task(self):
resp = client.post("/reset", json={"task_id": "impossible"})
assert resp.status_code == 400
class TestStepEndpoint:
def test_step_after_reset(self):
client.post("/reset", json={"task_id": "easy"})
resp = client.post("/step", json={
"action": {
"action_type": "send_email",
"target_lead_id": "L-001",
"body": "Hi Arun, intro about E.L.A.R.A.",
"goal": "intro",
}
})
assert resp.status_code == 200
data = resp.json()
assert "observation" in data
assert "reward" in data
assert "done" in data
assert "info" in data
assert isinstance(data["reward"], float)
def test_step_before_reset_fails(self):
# Create a fresh app instance to avoid leftover state
from server import app as fresh_app
fresh_client = TestClient(fresh_app)
# This may or may not fail depending on whether env was reset elsewhere
# But we can test the step structure at least
client.post("/reset")
resp = client.post("/step", json={
"action": {
"action_type": "wait",
"target_lead_id": "L-001",
}
})
assert resp.status_code == 200
class TestStateEndpoint:
def test_state_after_reset(self):
client.post("/reset", json={"task_id": "easy"})
resp = client.get("/state")
assert resp.status_code == 200
data = resp.json()
assert "product" in data
assert "leads" in data
assert "task_id" in data
class TestTasksEndpoint:
def test_tasks_returns_all(self):
resp = client.get("/tasks")
assert resp.status_code == 200
data = resp.json()
assert "tasks" in data
assert len(data["tasks"]) == 4
task_ids = [t["task_id"] for t in data["tasks"]]
assert "easy" in task_ids
assert "medium" in task_ids
assert "hard" in task_ids
assert "consent" in task_ids
class TestGraderEndpoint:
def test_grader_after_episode(self):
client.post("/reset", json={"task_id": "easy"})
client.post("/step", json={
"action": {
"action_type": "send_email",
"target_lead_id": "L-001",
"body": "Hi Arun, E.L.A.R.A. cuts response time by 60%.",
"goal": "intro",
}
})
resp = client.post("/grader")
assert resp.status_code == 200
data = resp.json()
assert "score" in data
assert "pass" in data
assert "dimensions" in data
assert 0.0 <= data["score"] <= 1.0