"""叩心枢测试共用 fixtures。""" from __future__ import annotations from collections.abc import AsyncGenerator from datetime import UTC, datetime, timedelta import pytest_asyncio from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.orm import sessionmaker from app.db.base import Base from app.models.big_cycle import BigCycle from app.models.chat import ChatMessage from app.models.drive import CuriosityQuestion from app.models.evolution import EvolutionCandidate from app.models.memory import Memory from app.models.personality_emotion import CharacterEmotionState from app.models.time_anniversary import TimeAnniversary # 用内存 SQLite 做测试数据库 _TEST_DATABASE_URL = "sqlite+aiosqlite://" @pytest_asyncio.fixture async def db_session() -> AsyncGenerator[AsyncSession, None]: engine = create_async_engine(_TEST_DATABASE_URL, echo=False) async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) async with async_session() as session: yield session await engine.dispose() @pytest_asyncio.fixture async def seed_old_message(db_session: AsyncSession) -> None: """插入一条 2 小时前的消息,供空闲超时条件触发。""" now = datetime.now(UTC) db_session.add( ChatMessage( character_id="char_test", session_id="sess_old", role="assistant", modality="text", content="旧消息", created_at=now - timedelta(hours=2), ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_recent_message(db_session: AsyncSession) -> None: """插入一条 1 分钟前的消息,供空闲超时条件不触发。""" now = datetime.now(UTC) db_session.add( ChatMessage( character_id="char_test", session_id="sess_recent", role="assistant", modality="text", content="新消息", created_at=now - timedelta(minutes=1), ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_anniversary(db_session: AsyncSession) -> None: """插入一条 2026-06-27 的生日纪念日。""" db_session.add( TimeAnniversary( character_id="char_test", name="测试生日", calendar="solar", date="2026-06-27", kind="birthday", subject_type="user", ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_emotion_state(db_session: AsyncSession) -> None: """插入一条初始情绪状态(neutral / 0.2)。""" db_session.add( CharacterEmotionState( character_id="char_test", mood="neutral", intensity=0.2, ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_curiosity(db_session: AsyncSession) -> None: """插入一条活跃的好奇心问题。""" db_session.add( CuriosityQuestion( character_id="char_test", cycle_id="cycle_test", question="你为什么总是沉默?", source="drive", ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_applied_evolution(db_session: AsyncSession) -> None: """插入一条已应用的演化候选。""" db_session.add( EvolutionCandidate( character_id="char_test", cycle_id="cycle_test", type="personality", title="语气更柔和", proposal="调整表达风格,减少命令式语气,增加温和感", level="L3", status="applied", ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_completed_big_cycle(db_session: AsyncSession) -> None: """插入一条已完成的大周天循环。""" now = datetime.now(UTC) db_session.add( BigCycle( character_id="char_test", trigger="session_turn", status="completed", summary="发现自己最近更倾向于回忆过去,在对话中表现出怀旧倾向", completed_at=now - timedelta(minutes=5), ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_new_memory(db_session: AsyncSession) -> None: """插入一条活跃的新记忆。""" db_session.add( Memory( character_id="char_test", type="experience", title="今天去了海边", content="用户提到今天去了海边,看日落。角色回忆起自己也曾喜欢在海边散步。", status="active", ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_many_messages(db_session: AsyncSession) -> None: """插入多条消息,供关系里程碑(消息数)条件触发。""" now = datetime.now(UTC) for i in range(5): db_session.add( ChatMessage( character_id="char_test", session_id=f"sess_rel_{i}", role="assistant" if i % 2 else "user", modality="text", content=f"第{i + 1}条消息", created_at=now - timedelta(minutes=10 - i), ) ) await db_session.commit() @pytest_asyncio.fixture async def seed_old_relationship(db_session: AsyncSession) -> None: """插入一条 60 天前的消息,供关系里程碑(天数)条件触发。""" now = datetime.now(UTC) db_session.add( ChatMessage( character_id="char_test", session_id="sess_old_rel", role="user", modality="text", content="你好", created_at=now - timedelta(days=60), ) ) await db_session.commit()