"""测试 per-character goals API。""" from collections.abc import AsyncGenerator import pytest from httpx import ASGITransport, AsyncClient from sqlalchemy.ext.asyncio import AsyncSession from app.db.session import AsyncSessionLocal from app.main import app @pytest.fixture async def db_session() -> AsyncGenerator[AsyncSession, None]: async with AsyncSessionLocal() as session: yield session @pytest.fixture async def client() -> AsyncGenerator[AsyncClient, None]: transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as http_client: yield http_client @pytest.mark.asyncio async def test_list_goals_by_character(client: AsyncClient, db_session: AsyncSession) -> None: """GET /api/v1/goals?character_id=char_test 返回该人物的目标。""" from app.models.governance import Goal goal = Goal( id="goal_api_test", title="API测试目标", level="task", character_id="char_test", status="active", ) db_session.add(goal) await db_session.commit() resp = await client.get("/api/v1/goals?character_id=char_test") assert resp.status_code == 200 data = resp.json() assert any(g["id"] == "goal_api_test" for g in data) @pytest.mark.asyncio async def test_list_goals_filters_status(client: AsyncClient, db_session: AsyncSession) -> None: """GET /api/v1/goals?character_id=char_test&status=active 只返回 active。""" from app.models.governance import Goal db_session.add_all( [ Goal(id="goal_a1", title="a1", level="task", character_id="char_test", status="active"), Goal( id="goal_c1", title="c1", level="task", character_id="char_test", status="completed" ), ] ) await db_session.commit() resp = await client.get("/api/v1/goals?character_id=char_test&status=active") assert resp.status_code == 200 data = resp.json() assert len(data) == 1 assert data[0]["id"] == "goal_a1"