101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
"""演化候选数据访问测试。"""
|
|
|
|
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
|