2026-10-12 19:15:46 +08:00
|
|
|
# `client` fixture from conftest (per-test Registry on tmp data_dir; default
|
|
|
|
|
# tenant runtime pre-warmed by the app lifespan inside the TestClient loop).
|
|
|
|
|
|
|
|
|
|
import json
|
2026-10-12 16:25:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_session_creates_new(client):
|
|
|
|
|
r = client.post("/api/chat/session", json={})
|
|
|
|
|
assert r.status_code == 200
|
|
|
|
|
d = r.json()
|
|
|
|
|
assert "session_id" in d and d["is_new"] is True and d["ended"] is False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_session_resume_active(client):
|
|
|
|
|
sid = client.post("/api/chat/session", json={}).json()["session_id"]
|
|
|
|
|
r = client.post("/api/chat/session", json={"session_id": sid})
|
|
|
|
|
assert r.json()["is_new"] is False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_history_new_session_empty(client):
|
|
|
|
|
sid = client.post("/api/chat/session", json={}).json()["session_id"]
|
|
|
|
|
r = client.get(f"/api/chat/{sid}/messages")
|
|
|
|
|
assert r.status_code == 200 and r.json() == []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_history_404_unknown_sid(client):
|
|
|
|
|
assert client.get("/api/chat/nope/messages").status_code == 404
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_history_rejects_non_app_session(client):
|
|
|
|
|
# widget-source conversations are not readable via this public endpoint
|
2026-10-12 19:15:46 +08:00
|
|
|
# (narrow the read surface to app only). 经真实 WS 路由造 widget 会话:
|
|
|
|
|
# 租户 engine 的常驻连接绑定 TestClient 的事件循环,测试线程不得另起
|
|
|
|
|
# asyncio.run 直开其 session_factory(跨循环复用会死锁)。
|
|
|
|
|
with client.websocket_connect("/ws/chat") as ws:
|
|
|
|
|
ws.send_text(json.dumps({"source": "widget"}))
|
|
|
|
|
sid = ws.receive_json()["session_id"]
|
2026-10-12 16:25:32 +08:00
|
|
|
assert client.get(f"/api/chat/{sid}/messages").status_code == 404
|