"""演化候选数据访问测试。""" import pytest from app.db.session import AsyncSessionLocal from app.models.big_cycle import BigCycle from app.models.evolution import EvolutionCandidate from app.repositories import evolution as evolution_repo from app.repositories.json_utils import dumps 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 _make_candidate(character_id: str, cycle_id: str, **overrides) -> EvolutionCandidate: base = { "character_id": character_id, "cycle_id": cycle_id, "type": "personality", "source": "big_cycle", "level": "L4", "scope": "character_scope", "title": "t", "proposal": "p", "delta_json": dumps({}), "evidence_ids_json": "[]", "confidence": 0.5, "benefit_score": 0.5, "risk_score": 0.5, "drift_score": 0.0, "auto_apply_allowed": False, "status": "pending", } base.update(overrides) return EvolutionCandidate(**base) @pytest.mark.asyncio async def test_add_and_get_candidate() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cycle_id = await _seed_cycle(session, character.id) candidate = _make_candidate(character.id, cycle_id, title="身份调整") await evolution_repo.add_candidates(session, [candidate]) await session.commit() cid = candidate.id async with AsyncSessionLocal() as session: fetched = await evolution_repo.get_candidate(session, cid) assert fetched is not None assert fetched.title == "身份调整" assert fetched.status == "pending" assert fetched.source == "big_cycle" @pytest.mark.asyncio async def test_list_candidates_with_filters_and_paging() -> None: async with AsyncSessionLocal() as session: character = await get_active_character_model(session) cycle_id = await _seed_cycle(session, character.id) await evolution_repo.add_candidates( session, [ _make_candidate(character.id, cycle_id, type="personality", status="pending"), _make_candidate(character.id, cycle_id, type="procedural", status="applied"), _make_candidate(character.id, cycle_id, type="procedural", status="pending"), ], ) await session.commit() async with AsyncSessionLocal() as session: all_items, total = await evolution_repo.list_candidates(session, character.id) assert total == 3 assert len(all_items) == 3 pending, pending_total = await evolution_repo.list_candidates( session, character.id, status="pending" ) assert pending_total == 2 assert len(pending) == 2 procedural, proc_total = await evolution_repo.list_candidates( session, character.id, candidate_type="procedural" ) assert proc_total == 2 page1, _ = await evolution_repo.list_candidates(session, character.id, page=1, page_size=2) page2, _ = await evolution_repo.list_candidates(session, character.id, page=2, page_size=2) assert len(page1) == 2 assert len(page2) == 1