"""内驱力审核服务测试(次生目标 approve/defer/reject)。""" import pytest from app.core.errors import AppError from app.db.session import AsyncSessionLocal from app.models.big_cycle import BigCycle from app.models.drive import CuriosityQuestion, ExploratorySubgoal from app.services import drive as drive_service from app.services.characters import get_active_character_model async def _seed_subgoal(session, character_id: str, status: str = "candidate") -> str: cycle = BigCycle( character_id=character_id, trigger="test", status="completed", memory_count_at_trigger=20, ) session.add(cycle) await session.flush() curios = CuriosityQuestion( character_id=character_id, cycle_id=cycle.id, question="q", source="memory_gap", expected_value=0.5, urgency=0.5, risk_level="L2", ) session.add(curios) await session.flush() sub = ExploratorySubgoal( character_id=character_id, cycle_id=cycle.id, curiosity_question_id=curios.id, title="询问项目目标", description="主动询问", expected_information_gain=0.6, interruption_cost=0.3, risk_level="L2", status=status, ) session.add(sub) await session.flush() return sub.id @pytest.mark.asyncio async def test_approve_candidate_subgoal() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) sid = await _seed_subgoal(session, character.id) await session.commit() resp = await drive_service.approve_subgoal(sid) assert resp.status == "approved" assert resp.reviewed_by == "user" @pytest.mark.asyncio async def test_defer_candidate_subgoal() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) sid = await _seed_subgoal(session, character.id) await session.commit() resp = await drive_service.defer_subgoal(sid) assert resp.status == "deferred" @pytest.mark.asyncio async def test_reject_candidate_subgoal() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) sid = await _seed_subgoal(session, character.id) await session.commit() resp = await drive_service.reject_subgoal(sid) assert resp.status == "rejected" @pytest.mark.asyncio async def test_review_non_candidate_conflicts() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) sid = await _seed_subgoal(session, character.id, status="approved") await session.commit() with pytest.raises(AppError): await drive_service.approve_subgoal(sid) @pytest.mark.asyncio async def test_approve_not_found() -> None: with pytest.raises(AppError): await drive_service.approve_subgoal("subgoal_missing")