Add focused API contract tests for chat idempotency, cursor pagination, and node routing behavior using isolated local fixtures and mocked upstream inference. Made-with: Cursor
78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
|
|
def _create_chat(client, agent_id: str, node_id: str, ref: str) -> str:
|
|
r = client.post(
|
|
"/api/chats",
|
|
json={
|
|
"agent_id": agent_id,
|
|
"node_id": node_id,
|
|
"source": "web",
|
|
"external_chat_ref": ref,
|
|
},
|
|
)
|
|
assert r.status_code == 200, r.text
|
|
return r.json()["chat"]["chat_id"]
|
|
|
|
|
|
def test_list_chats_cursor_paginates_without_duplicates(sofiia_client, sofiia_module, monkeypatch):
|
|
async def _fake_infer(base_url, agent_id, text, **kwargs):
|
|
return {"response": f"ok:{agent_id}:{text}", "backend": "fake", "model": "fake-model"}
|
|
|
|
monkeypatch.setattr(sofiia_module, "infer", _fake_infer)
|
|
|
|
chat_ids = []
|
|
for idx in range(5):
|
|
cid = _create_chat(sofiia_client, "sofiia", "NODA2", f"pag-chats-{idx}")
|
|
chat_ids.append(cid)
|
|
r = sofiia_client.post(
|
|
f"/api/chats/{cid}/send",
|
|
json={"text": f"touch-{idx}", "idempotency_key": f"touch-{idx}"},
|
|
)
|
|
assert r.status_code == 200, r.text
|
|
|
|
p1 = sofiia_client.get("/api/chats?nodes=NODA2&limit=2")
|
|
assert p1.status_code == 200, p1.text
|
|
j1 = p1.json()
|
|
assert j1["count"] == 2
|
|
assert j1["has_more"] is True
|
|
assert j1["next_cursor"]
|
|
|
|
p2 = sofiia_client.get(f"/api/chats?nodes=NODA2&limit=2&cursor={j1['next_cursor']}")
|
|
assert p2.status_code == 200, p2.text
|
|
j2 = p2.json()
|
|
assert j2["count"] >= 1
|
|
ids1 = {x["chat_id"] for x in j1["items"]}
|
|
ids2 = {x["chat_id"] for x in j2["items"]}
|
|
assert ids1.isdisjoint(ids2)
|
|
|
|
|
|
def test_list_messages_cursor_paginates_without_duplicates(sofiia_client, sofiia_module, monkeypatch):
|
|
async def _fake_infer(base_url, agent_id, text, **kwargs):
|
|
return {"response": f"ok:{agent_id}:{text}", "backend": "fake", "model": "fake-model"}
|
|
|
|
monkeypatch.setattr(sofiia_module, "infer", _fake_infer)
|
|
cid = _create_chat(sofiia_client, "sofiia", "NODA2", "pag-messages")
|
|
for idx in range(4):
|
|
r = sofiia_client.post(
|
|
f"/api/chats/{cid}/send",
|
|
json={"text": f"msg-{idx}", "idempotency_key": f"msg-{idx}"},
|
|
)
|
|
assert r.status_code == 200, r.text
|
|
|
|
p1 = sofiia_client.get(f"/api/chats/{cid}/messages?limit=2")
|
|
assert p1.status_code == 200, p1.text
|
|
j1 = p1.json()
|
|
assert j1["count"] == 2
|
|
assert j1["has_more"] is True
|
|
assert j1["next_cursor"]
|
|
|
|
p2 = sofiia_client.get(f"/api/chats/{cid}/messages?limit=2&cursor={j1['next_cursor']}")
|
|
assert p2.status_code == 200, p2.text
|
|
j2 = p2.json()
|
|
assert j2["count"] >= 1
|
|
ids1 = {x["message_id"] for x in j1["items"]}
|
|
ids2 = {x["message_id"] for x in j2["items"]}
|
|
assert ids1.isdisjoint(ids2)
|
|
|