feat: add week 3 audio and timeline enhancements

This commit is contained in:
2026-04-18 22:10:48 +08:00
parent 4d54c144a8
commit 70efaf3ccf
20 changed files with 606 additions and 56 deletions

View File

@@ -65,6 +65,23 @@ async def test_create_reading_event_updates_stats_and_memory(
assert len(items) == 1
assert items[0].type == "recent_story"
assert items[0].value["story_id"] == test_story.id
assert items[0].value["mode"] == test_story.mode
assert items[0].value["reading_time"] == 120
assert items[0].value["source"] == "reading_event"
timeline_response = await client.get(f"/api/profiles/{profile_id}/timeline")
assert timeline_response.status_code == 200
timeline_events = timeline_response.json()["events"]
reading_events = [
event for event in timeline_events if event["type"] == "reading_event"
]
memory_events = [event for event in timeline_events if event["type"] == "memory"]
assert reading_events
assert memory_events
assert reading_events[0]["metadata"]["story_id"] == test_story.id
assert reading_events[0]["metadata"]["reading_time"] == 120
assert memory_events[0]["metadata"]["memory_type"] == "recent_story"
assert memory_events[0]["metadata"]["story_id"] == test_story.id
response = await client.post(
"/api/reading-events",

View File

@@ -256,6 +256,53 @@ class TestAudio:
assert detail["generation_status"] == "partial_ready"
assert detail["last_error"] is None
status_response = auth_client.get(f"/api/audio/{test_story.id}/status")
assert status_response.status_code == 200
status_data = status_response.json()
assert status_data["audio_ready"] is True
assert status_data["cache_exists"] is True
assert status_data["cache_size_bytes"] == len(b"fake-audio-bytes")
assert status_data["cache_updated_at"] is not None
assert status_data["audio_status"] == "ready"
def test_audio_status_does_not_generate_audio(
self,
auth_client: TestClient,
test_story,
mock_tts_provider,
):
response = auth_client.get(f"/api/audio/{test_story.id}/status")
assert response.status_code == 200
data = response.json()
assert data["audio_ready"] is False
assert data["cache_exists"] is False
assert data["audio_status"] == "not_requested"
assert "audio" in data["retryable_assets"]
mock_tts_provider.assert_not_awaited()
def test_delete_audio_cache_makes_audio_retryable(
self,
auth_client: TestClient,
test_story,
mock_tts_provider,
):
response = auth_client.get(f"/api/audio/{test_story.id}")
assert response.status_code == 200
cached_audio_path = Path(settings.story_audio_cache_dir) / f"story-{test_story.id}.mp3"
assert cached_audio_path.is_file()
response = auth_client.delete(f"/api/audio/{test_story.id}/cache")
assert response.status_code == 200
data = response.json()
assert data["audio_ready"] is False
assert data["cache_exists"] is False
assert data["audio_status"] == "not_requested"
assert "audio" in data["retryable_assets"]
assert not cached_audio_path.exists()
def test_get_audio_regenerates_when_cache_file_is_missing(
self,
auth_client: TestClient,