"""Reading event API tests.""" import pytest from httpx import ASGITransport, AsyncClient from sqlalchemy import select from app.db.database import get_db from app.db.models import MemoryItem from app.main import app pytestmark = pytest.mark.asyncio async def _create_profile(client: AsyncClient) -> str: response = await client.post( "/api/profiles", json={"name": "小明", "gender": "male"}, ) assert response.status_code == 201 return response.json()["id"] async def test_create_reading_event_updates_stats_and_memory( db_session, test_user, auth_token, test_story, ): async def override_get_db(): yield db_session app.dependency_overrides[get_db] = override_get_db transport = ASGITransport(app=app) try: async with AsyncClient(transport=transport, base_url="http://test") as client: client.cookies.set("access_token", auth_token) profile_id = await _create_profile(client) response = await client.post( "/api/reading-events", json={ "child_profile_id": profile_id, "story_id": test_story.id, "event_type": "completed", "reading_time": 120, }, ) assert response.status_code == 201 data = response.json() assert data["child_profile_id"] == profile_id assert data["story_id"] == test_story.id assert data["event_type"] == "completed" response = await client.get(f"/api/profiles/{profile_id}") assert response.status_code == 200 profile = response.json() assert profile["stories_count"] == 1 assert profile["total_reading_time"] == 120 result = await db_session.execute( select(MemoryItem).where(MemoryItem.child_profile_id == profile_id) ) items = result.scalars().all() assert len(items) == 1 assert items[0].type == "recent_story" assert items[0].value["story_id"] == test_story.id response = await client.post( "/api/reading-events", json={ "child_profile_id": profile_id, "story_id": test_story.id, "event_type": "skipped", "reading_time": 0, }, ) assert response.status_code == 201 result = await db_session.execute( select(MemoryItem).where(MemoryItem.child_profile_id == profile_id) ) assert len(result.scalars().all()) == 1 response = await client.post( "/api/reading-events", json={ "child_profile_id": profile_id, "story_id": test_story.id, "event_type": "completed", "reading_time": 0, }, ) assert response.status_code == 201 response = await client.get(f"/api/profiles/{profile_id}") assert response.status_code == 200 profile = response.json() assert profile["stories_count"] == 1 assert profile["total_reading_time"] == 120 finally: app.dependency_overrides.clear() async def test_reading_event_validation_errors( db_session, test_user, auth_token, ): async def override_get_db(): yield db_session app.dependency_overrides[get_db] = override_get_db transport = ASGITransport(app=app) try: async with AsyncClient(transport=transport, base_url="http://test") as client: client.cookies.set("access_token", auth_token) response = await client.post( "/api/reading-events", json={ "child_profile_id": "not-exist", "event_type": "started", "reading_time": 0, }, ) assert response.status_code == 404 profile_id = await _create_profile(client) response = await client.post( "/api/reading-events", json={ "child_profile_id": profile_id, "story_id": 999999, "event_type": "completed", "reading_time": 0, }, ) assert response.status_code == 404 finally: app.dependency_overrides.clear()