M2b:删除旧 chat 体系——线性会话/叩心/情绪/纪念日模型与页面退役(迁移 003 双向验证),runs 去会话外键,测试全量修剪
This commit is contained in:
1 parent
5f36e3785c
commit
ad9c9e942a
22 files changed
+424
-427
No files matched your search
@@ -5,10 +5,8 @@ from collections.abc import AsyncGenerator
|
||||
import pytest
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
|
||||
from app.ai_provider.types.chat import ChatChunk
|
||||
from app.api.v1.deps import require_admin
|
||||
from app.application.agent.runtime import AgentTurnResult
|
||||
from app.application.chat.send_message import drain_pending_streams
|
||||
from app.main import app
|
||||
|
||||
|
||||
@@ -16,11 +14,6 @@ from app.main import app
|
||||
async def client(
|
||||
monkeypatch: pytest.MonkeyPatch, auth_headers: dict[str, str]
|
||||
) -> AsyncGenerator[AsyncClient, None]:
|
||||
async def fake_run_agent_turn(*, on_chunk, **_kwargs: object):
|
||||
await on_chunk(ChatChunk(delta_content="你好,我是测试模型回复。"))
|
||||
return AgentTurnResult(content="你好,我是测试模型回复。", reasoning="")
|
||||
|
||||
monkeypatch.setattr("app.application.chat.send_message.run_agent_turn", fake_run_agent_turn)
|
||||
transport = ASGITransport(app=app)
|
||||
async with AsyncClient(
|
||||
transport=transport,
|
||||
@@ -41,136 +34,6 @@ async def test_health_and_defaults(client: AsyncClient) -> None:
|
||||
assert personality.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_chat_run_and_memory_crud(client: AsyncClient) -> None:
|
||||
created = await client.post("/api/v1/chat/sessions", json={"title": "测试"})
|
||||
assert created.status_code == 200
|
||||
session_id = created.json()["session_id"]
|
||||
|
||||
sent = await client.post(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages",
|
||||
json={"content": "你好", "modality": "text"},
|
||||
)
|
||||
assert sent.status_code == 200
|
||||
run_id = sent.json()["run_id"]
|
||||
await drain_pending_streams()
|
||||
run = await client.get(f"/api/v1/runs/{run_id}")
|
||||
assert run.status_code == 200
|
||||
assert run.json()["status"] == "completed"
|
||||
|
||||
memory = await client.post(
|
||||
"/api/v1/memory",
|
||||
json={"type": "user", "title": "偏好", "content": "用户喜欢简洁回答。"},
|
||||
)
|
||||
assert memory.status_code == 200
|
||||
memory_id = memory.json()["id"]
|
||||
listed = await client.get("/api/v1/memory")
|
||||
assert listed.status_code == 200
|
||||
assert listed.json()["total"] == 1
|
||||
updated = await client.patch(f"/api/v1/memory/{memory_id}", json={"importance": 0.9})
|
||||
assert updated.status_code == 200
|
||||
deleted = await client.delete(f"/api/v1/memory/{memory_id}")
|
||||
assert deleted.status_code == 200
|
||||
assert deleted.json()["status"] == "deleted"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_chat_session_and_messages_query_api(client: AsyncClient) -> None:
|
||||
created = await client.post("/api/v1/chat/sessions", json={"title": "查询测试"})
|
||||
assert created.status_code == 200
|
||||
created_body = created.json()
|
||||
session_id = created_body["session_id"]
|
||||
|
||||
listed = await client.get("/api/v1/chat/sessions")
|
||||
assert listed.status_code == 200
|
||||
listed_body = listed.json()
|
||||
assert listed_body["total"] >= 1
|
||||
assert any(item["session_id"] == session_id for item in listed_body["items"])
|
||||
|
||||
fetched = await client.get(f"/api/v1/chat/sessions/{session_id}")
|
||||
assert fetched.status_code == 200
|
||||
fetched_body = fetched.json()
|
||||
assert fetched_body["session_id"] == session_id
|
||||
assert fetched_body["title"] == "查询测试"
|
||||
assert fetched_body["status"] == "active"
|
||||
|
||||
sent = await client.post(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages",
|
||||
json={"content": "查询消息", "modality": "text"},
|
||||
)
|
||||
assert sent.status_code == 200
|
||||
# 流式化后 send_message 立即返回,assistant_message_id 此刻为空,需等待后台任务定稿。
|
||||
await drain_pending_streams()
|
||||
|
||||
messages = await client.get(f"/api/v1/chat/sessions/{session_id}/messages")
|
||||
assert messages.status_code == 200
|
||||
messages_body = messages.json()
|
||||
assert messages_body["total"] == 2
|
||||
assert [item["role"] for item in messages_body["items"]] == ["user", "assistant"]
|
||||
assert messages_body["items"][0]["content"] == "查询消息"
|
||||
assert messages_body["items"][1]["message_id"].startswith("message_")
|
||||
|
||||
missing = await client.get("/api/v1/chat/sessions/session_missing")
|
||||
assert missing.status_code == 404
|
||||
assert missing.json()["error"]["code"] == "not_found"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_chat_session_update_and_delete(client: AsyncClient) -> None:
|
||||
created = await client.post("/api/v1/chat/sessions", json={"title": "待删除"})
|
||||
assert created.status_code == 200
|
||||
session_id = created.json()["session_id"]
|
||||
|
||||
# 发两条消息制造关联数据(覆盖 messages 软删路径)
|
||||
sent = await client.post(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages",
|
||||
json={"content": "占位消息", "modality": "text"},
|
||||
)
|
||||
assert sent.status_code == 200
|
||||
await drain_pending_streams()
|
||||
messages_before = await client.get(f"/api/v1/chat/sessions/{session_id}/messages")
|
||||
assert messages_before.status_code == 200
|
||||
assert messages_before.json()["total"] == 2
|
||||
|
||||
# PATCH 重命名
|
||||
renamed = await client.patch(f"/api/v1/chat/sessions/{session_id}", json={"title": "重命名后"})
|
||||
assert renamed.status_code == 200
|
||||
assert renamed.json()["title"] == "重命名后"
|
||||
assert renamed.json()["status"] == "active"
|
||||
|
||||
# PATCH 归档
|
||||
archived = await client.patch(
|
||||
f"/api/v1/chat/sessions/{session_id}", json={"status": "archived"}
|
||||
)
|
||||
assert archived.status_code == 200
|
||||
assert archived.json()["status"] == "archived"
|
||||
|
||||
# PATCH 禁止直接置 deleted
|
||||
bad = await client.patch(f"/api/v1/chat/sessions/{session_id}", json={"status": "deleted"})
|
||||
assert bad.status_code == 400
|
||||
|
||||
# DELETE 软删除 → 204
|
||||
deleted = await client.delete(f"/api/v1/chat/sessions/{session_id}")
|
||||
assert deleted.status_code == 204
|
||||
|
||||
# 删除后 GET 该会话 404
|
||||
gone = await client.get(f"/api/v1/chat/sessions/{session_id}")
|
||||
assert gone.status_code == 404
|
||||
|
||||
# 列表不再包含
|
||||
listed = await client.get("/api/v1/chat/sessions")
|
||||
assert listed.status_code == 200
|
||||
assert not any(item["session_id"] == session_id for item in listed.json()["items"])
|
||||
|
||||
# 消息也被软删:总条数为 0
|
||||
messages_after = await client.get(f"/api/v1/chat/sessions/{session_id}/messages")
|
||||
assert messages_after.status_code == 404 # 会话已 deleted,查询应拒绝
|
||||
|
||||
# 重复删除仍返回 404
|
||||
repeat = await client.delete(f"/api/v1/chat/sessions/{session_id}")
|
||||
assert repeat.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_personality_propose_approve_reject_and_rollback(client: AsyncClient) -> None:
|
||||
# 初始当前人格为 v1
|
||||
@@ -252,42 +115,6 @@ async def test_personality_propose_approve_reject_and_rollback(client: AsyncClie
|
||||
app.dependency_overrides.pop(require_admin, None)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_message_version_selection(client: AsyncClient) -> None:
|
||||
"""选择/激活消息版本——覆盖 services/chat.select_message_version 路径。"""
|
||||
created = await client.post("/api/v1/chat/sessions", json={"title": "版本测试"})
|
||||
assert created.status_code == 200
|
||||
session_id = created.json()["session_id"]
|
||||
|
||||
sent = await client.post(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages",
|
||||
json={"content": "原始内容", "modality": "text"},
|
||||
)
|
||||
assert sent.status_code == 200
|
||||
await drain_pending_streams()
|
||||
|
||||
messages = await client.get(f"/api/v1/chat/sessions/{session_id}/messages")
|
||||
assert messages.status_code == 200
|
||||
items = messages.json()["items"]
|
||||
assert len(items) == 2
|
||||
assistant_msg = next(m for m in items if m["role"] == "assistant")
|
||||
msg_id = assistant_msg["message_id"]
|
||||
|
||||
# 选择不存在的版本索引 → 400
|
||||
bad = await client.patch(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages/{msg_id}/version",
|
||||
json={"version_idx": 99},
|
||||
)
|
||||
assert bad.status_code == 400
|
||||
|
||||
# 选择索引 0(当前版本)
|
||||
ok = await client.patch(
|
||||
f"/api/v1/chat/sessions/{session_id}/messages/{msg_id}/version",
|
||||
json={"version_idx": 0},
|
||||
)
|
||||
assert ok.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_skills_crud(client: AsyncClient) -> None:
|
||||
"""Skill 能力包 CRUD——覆盖 services/skills 路径。"""
|
||||
|
||||
Reference in new issue
Block a user