"""内驱力数据访问测试(好奇问题 + 次生目标)。""" import pytest from app.db.session import AsyncSessionLocal from app.models.big_cycle import BigCycle from app.models.drive import CuriosityQuestion, ExploratorySubgoal from app.repositories import drive as drive_repo from app.services.characters import get_active_character_model async def _seed_cycle(session, character_id: str) -> str: cycle = BigCycle( character_id=character_id, trigger="test", status="completed", memory_count_at_trigger=20, ) session.add(cycle) await session.flush() return cycle.id def _curiosity(character_id: str, cycle_id: str, **overrides) -> CuriosityQuestion: base = { "character_id": character_id, "cycle_id": cycle_id, "question": "q", "source": "memory_gap", "related_entities_json": "[]", "expected_value": 0.5, "urgency": 0.5, "risk_level": "L2", } base.update(overrides) return CuriosityQuestion(**base) def _subgoal( character_id: str, cycle_id: str, curiosity_id: str, **overrides ) -> ExploratorySubgoal: base = { "character_id": character_id, "cycle_id": cycle_id, "curiosity_question_id": curiosity_id, "title": "t", "description": "d", "expected_information_gain": 0.6, "interruption_cost": 0.3, "risk_level": "L2", "status": "candidate", } base.update(overrides) return ExploratorySubgoal(**base) @pytest.mark.asyncio async def test_curiosity_add_get_list() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cycle_id = await _seed_cycle(session, character.id) curios = _curiosity(character.id, cycle_id, question="为何频繁提到项目X") await drive_repo.add_curiosities(session, [curios]) await drive_repo.add_curiosities( session, [_curiosity(character.id, cycle_id, source="world_uncertainty")] ) await session.commit() cid = curios.id async with AsyncSessionLocal() as session: fetched = await drive_repo.get_curiosity(session, cid) all_items, total = await drive_repo.list_curiosities(session, character.id) gap, gap_total = await drive_repo.list_curiosities( session, character.id, source="memory_gap" ) assert fetched is not None assert fetched.question == "为何频繁提到项目X" assert total == 2 assert gap_total == 1 @pytest.mark.asyncio async def test_subgoal_add_get_list() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cycle_id = await _seed_cycle(session, character.id) curios = _curiosity(character.id, cycle_id) await drive_repo.add_curiosities(session, [curios]) await session.flush() curiosity_id = curios.id sub = _subgoal(character.id, cycle_id, curiosity_id, title="询问项目目标") await drive_repo.add_subgoals(session, [sub]) await drive_repo.add_subgoals( session, [_subgoal(character.id, cycle_id, curiosity_id, status="approved")] ) await session.commit() sid = sub.id async with AsyncSessionLocal() as session: fetched = await drive_repo.get_subgoal(session, sid) _, total = await drive_repo.list_subgoals(session, character.id) cand, cand_total = await drive_repo.list_subgoals(session, character.id, status="candidate") assert fetched is not None assert fetched.title == "询问项目目标" assert fetched.curiosity_question_id == curiosity_id assert total == 2 assert cand_total == 1