60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
|
|
"""Story 变更触发章节物化:调用链与 Celery 派发的行为验证(无真实 DB)。"""
|
|||
|
|
|
|||
|
|
import asyncio
|
|||
|
|
import unittest
|
|||
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|||
|
|
|
|||
|
|
from app.features.story.service import StoryService
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ChapterStoryComposeFlowTest(unittest.TestCase):
|
|||
|
|
def test_append_version_marks_dirty_and_delays_recompose(self):
|
|||
|
|
async def run():
|
|||
|
|
db = MagicMock()
|
|||
|
|
db.flush = AsyncMock()
|
|||
|
|
db.commit = AsyncMock()
|
|||
|
|
db.add = MagicMock()
|
|||
|
|
story = MagicMock()
|
|||
|
|
story.id = "story-1"
|
|||
|
|
story.current_version_id = None
|
|||
|
|
story.title = "T"
|
|||
|
|
|
|||
|
|
version = MagicMock()
|
|||
|
|
version.id = "ver-new"
|
|||
|
|
|
|||
|
|
with (
|
|||
|
|
patch(
|
|||
|
|
"app.features.story.service.get_story_by_id",
|
|||
|
|
new_callable=AsyncMock,
|
|||
|
|
return_value=story,
|
|||
|
|
),
|
|||
|
|
patch(
|
|||
|
|
"app.features.story.service.count_story_versions",
|
|||
|
|
new_callable=AsyncMock,
|
|||
|
|
return_value=0,
|
|||
|
|
),
|
|||
|
|
patch(
|
|||
|
|
"app.features.story.service.create_story_version",
|
|||
|
|
new_callable=AsyncMock,
|
|||
|
|
return_value=version,
|
|||
|
|
),
|
|||
|
|
patch(
|
|||
|
|
"app.features.story.service._extract_and_store_image_intent",
|
|||
|
|
new_callable=AsyncMock,
|
|||
|
|
),
|
|||
|
|
patch(
|
|||
|
|
"app.features.memoir.repo.mark_chapters_dirty_for_story",
|
|||
|
|
new_callable=AsyncMock,
|
|||
|
|
) as m_mark,
|
|||
|
|
patch(
|
|||
|
|
"app.tasks.chapter_compose_tasks.recompose_chapters_for_story"
|
|||
|
|
) as m_task,
|
|||
|
|
):
|
|||
|
|
m_task.delay = MagicMock()
|
|||
|
|
svc = StoryService(db=db)
|
|||
|
|
await svc.append_version("story-1", "# 新正文")
|
|||
|
|
m_mark.assert_awaited_once_with(db, "story-1")
|
|||
|
|
m_task.delay.assert_called_once_with("story-1")
|
|||
|
|
|
|||
|
|
asyncio.run(run())
|