"""灵核情绪状态数据访问测试(设计 §11.4)。""" import pytest from app.db.session import AsyncSessionLocal from app.models.personality_emotion import CharacterEmotionState from app.repositories import personality_emotion as emotion_repo from app.services.characters import get_active_character_model def _state(character_id: str, **overrides) -> CharacterEmotionState: base = { "character_id": character_id, "mood": "touched", "intensity": 0.7, "baseline_mood": "neutral", "baseline_intensity": 0.2, "last_trigger_event_id": "evt_abc", } base.update(overrides) return CharacterEmotionState(**base) @pytest.mark.asyncio async def test_get_state_returns_none_when_absent() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) assert await emotion_repo.get_state(session, character.id) is None @pytest.mark.asyncio async def test_upsert_state_inserts_new() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cid = character.id created = await emotion_repo.upsert_state(session, _state(cid)) await session.commit() assert created.mood == "touched" assert created.intensity == 0.7 async with AsyncSessionLocal() as session: fetched = await emotion_repo.get_state(session, cid) assert fetched is not None assert fetched.mood == "touched" assert fetched.last_trigger_event_id == "evt_abc" @pytest.mark.asyncio async def test_upsert_state_updates_existing() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cid = character.id await emotion_repo.upsert_state(session, _state(cid, mood="touched", intensity=0.7)) await emotion_repo.upsert_state( session, _state( cid, mood="concerned", intensity=0.5, last_trigger_event_id="evt_def", ), ) await session.commit() async with AsyncSessionLocal() as session: fetched = await emotion_repo.get_state(session, cid) assert fetched is not None assert fetched.mood == "concerned" assert fetched.intensity == 0.5 assert fetched.last_trigger_event_id == "evt_def" @pytest.mark.asyncio async def test_upsert_state_single_row_per_character() -> None: """单行 per character:重复 upsert 不产生重复行。""" async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cid = character.id await emotion_repo.upsert_state(session, _state(cid)) await emotion_repo.upsert_state(session, _state(cid)) await emotion_repo.upsert_state(session, _state(cid)) await session.commit() async with AsyncSessionLocal() as session: from sqlalchemy import func, select count = int( ( await session.execute( select(func.count()) .select_from(CharacterEmotionState) .where(CharacterEmotionState.character_id == cid) ) ).scalar_one() ) assert count == 1