Files
hunjing/backend/tests/api/test_world.py
T
2026-08-21 16:00:13 +08:00

105 lines
3.5 KiB
Python

"""世界模型 API 测试(河图枢运行时,api-spec §12)。"""
from collections.abc import AsyncGenerator
import pytest
from httpx import ASGITransport, AsyncClient
from app.main import app
@pytest.fixture
async def client(auth_headers: dict[str, str]) -> AsyncGenerator[AsyncClient, None]:
transport = ASGITransport(app=app)
async with AsyncClient(
transport=transport, base_url="http://test", headers=auth_headers
) as http_client:
yield http_client
@pytest.mark.asyncio
async def test_list_entities_empty(client: AsyncClient) -> None:
resp = await client.get("/api/v1/world/entities")
assert resp.status_code == 200
body = resp.json()
assert body["total"] == 0
assert body["items"] == []
@pytest.mark.asyncio
async def test_create_and_get_entity(client: AsyncClient) -> None:
created = await client.post(
"/api/v1/world/entities",
json={"name": "用户项目", "type": "project", "state_type": "fact", "confidence": 0.9},
)
assert created.status_code == 200
entity = created.json()
assert entity["id"].startswith("world_entity_")
assert entity["name"] == "用户项目"
assert entity["type"] == "project"
assert entity["state_type"] == "fact"
assert entity["character_id"].startswith("character_")
fetched = await client.get(f"/api/v1/world/entities/{entity['id']}")
assert fetched.status_code == 200
assert fetched.json()["id"] == entity["id"]
@pytest.mark.asyncio
async def test_get_entity_not_found(client: AsyncClient) -> None:
resp = await client.get("/api/v1/world/entities/world_entity_missing")
assert resp.status_code == 404
@pytest.mark.asyncio
async def test_list_entities_filter_by_type(client: AsyncClient) -> None:
await client.post("/api/v1/world/entities", json={"name": "概念A", "type": "concept"})
await client.post("/api/v1/world/entities", json={"name": "项目B", "type": "project"})
filtered = await client.get("/api/v1/world/entities?type=project")
assert filtered.status_code == 200
body = filtered.json()
assert body["total"] == 1
assert body["items"][0]["type"] == "project"
all_entities = await client.get("/api/v1/world/entities")
assert all_entities.json()["total"] == 2
@pytest.mark.asyncio
async def test_create_relation(client: AsyncClient) -> None:
user = (
await client.post("/api/v1/world/entities", json={"name": "用户", "type": "person"})
).json()["id"]
project = (
await client.post("/api/v1/world/entities", json={"name": "魂镜项目", "type": "project"})
).json()["id"]
created = await client.post(
"/api/v1/world/relations",
json={"subject_id": user, "predicate": "正在进行", "object_id": project},
)
assert created.status_code == 200
relation = created.json()
assert relation["id"].startswith("world_relation_")
assert relation["predicate"] == "正在进行"
assert relation["subject_id"] == user
assert relation["object_id"] == project
listed = await client.get("/api/v1/world/relations")
assert listed.json()["total"] == 1
@pytest.mark.asyncio
async def test_create_relation_rejects_missing_entity(client: AsyncClient) -> None:
project = (
await client.post("/api/v1/world/entities", json={"name": "项目", "type": "project"})
).json()["id"]
# 主体不存在
resp = await client.post(
"/api/v1/world/relations",
json={"subject_id": "world_entity_missing", "predicate": "依赖", "object_id": project},
)
assert resp.status_code == 404