"""Integration tests for recall REST API endpoints."""
from datetime import datetime, timezone
import pytest
from navi.llm.base import Message
from tests.conftest_factory import FakeRecord
class TestRecallEndpoints:
@pytest.mark.anyio
async def test_get_recall(self, client, make_session, mock_deps):
session = await make_session("secretary", [Message(role="user", content="hi")])
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue(FakeRecord(
id="r1", session_id=session.id, call_type="once",
trigger_at=datetime(2026, 5, 20, 14, 0, 0, tzinfo=timezone.utc), interval_seconds=None,
internal_comment="test", additional_context_message="ctx",
status="pending", created_at=datetime(2026, 5, 15, 10, 0, 0, tzinfo=timezone.utc),
updated_at=datetime(2026, 5, 15, 10, 0, 0, tzinfo=timezone.utc),
))
response = client.get(f"/sessions/{session.id}/recall")
assert response.status_code == 200
data = response.json()
assert data["id"] == "r1"
assert data["call_type"] == "once"
@pytest.mark.anyio
async def test_get_recall_not_found(self, client, make_session, mock_deps):
session = await make_session("secretary")
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue(None)
response = client.get(f"/sessions/{session.id}/recall")
assert response.status_code == 200
assert response.json() == {"recall": None}
@pytest.mark.anyio
async def test_cancel_recall(self, client, make_session, mock_deps):
session = await make_session("secretary")
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue("UPDATE 1")
response = client.delete(f"/sessions/{session.id}/recall")
assert response.status_code == 200
data = response.json()
assert data["ok"] is True
@pytest.mark.anyio
async def test_skip_recall(self, client, make_session, mock_deps):
session = await make_session("secretary")
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue("UPDATE 1")
response = client.post(f"/sessions/{session.id}/recall/skip")
assert response.status_code == 200
data = response.json()
assert data["ok"] is True
@pytest.mark.anyio
async def test_admin_list_recalls(self, client, mock_deps):
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue([FakeRecord(
id="r1", session_id="s1", call_type="once",
trigger_at=datetime(2026, 5, 20, 14, 0, 0, tzinfo=timezone.utc), interval_seconds=None,
internal_comment="test", additional_context_message="ctx",
status="pending", created_at=datetime(2026, 5, 15, 10, 0, 0, tzinfo=timezone.utc),
updated_at=datetime(2026, 5, 15, 10, 0, 0, tzinfo=timezone.utc),
)])
response = client.get("/admin/recalls")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
assert data["items"][0]["id"] == "r1"
@pytest.mark.anyio
async def test_list_sessions_has_recall_flag(self, client, make_session, mock_deps):
session = await make_session("secretary", [Message(role="user", content="hi")])
scheduler = mock_deps["scheduler"]
scheduler._pool._conn.enqueue([{"session_id": session.id}])
response = client.get("/sessions")
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
found = next((s for s in data if s["session_id"] == session.id), None)
assert found is not None
assert found["has_pending_recall"] is True