133 lines
5.0 KiB
Python
133 lines
5.0 KiB
Python
import unittest
|
|
from unittest.mock import Mock, patch
|
|
|
|
from api.services.memoir_images.prompting import MemoirImagePromptService
|
|
from api.services.memoir_images.settings import MemoirImageSettings
|
|
|
|
|
|
class MemoirImagePromptingTest(unittest.TestCase):
|
|
def test_prompt_service_uses_english_fallback_without_llm(self):
|
|
settings = MemoirImageSettings(
|
|
enabled=True,
|
|
max_per_chapter=2,
|
|
provider="liblib",
|
|
default_style="watercolor",
|
|
default_size="1024x1024",
|
|
poll_interval_seconds=3,
|
|
max_attempts=20,
|
|
liblib_template_uuid="tpl-uuid",
|
|
)
|
|
service = MemoirImagePromptService(llm=None, settings=settings)
|
|
|
|
result = service.build_prompt(
|
|
chapter_title="童年的夏天",
|
|
chapter_category="childhood",
|
|
description="奶奶坐在院子里的藤椅上",
|
|
context_excerpt="梧桐树下很安静,夏天总有蝉鸣。",
|
|
)
|
|
|
|
self.assertEqual(result["style"], "watercolor")
|
|
self.assertEqual(result["size"], "1024x1024")
|
|
self.assertIn("childhood memory", result["prompt"])
|
|
self.assertIn("watercolor", result["prompt"])
|
|
self.assertNotIn("奶奶坐在院子里的藤椅上", result["prompt"])
|
|
self.assertIn("childhood", result["prompt_context"])
|
|
|
|
def test_prompt_service_parses_structured_llm_response(self):
|
|
settings = MemoirImageSettings(
|
|
enabled=True,
|
|
max_per_chapter=2,
|
|
provider="liblib",
|
|
default_style="watercolor",
|
|
default_size="1024x1024",
|
|
poll_interval_seconds=3,
|
|
max_attempts=20,
|
|
liblib_template_uuid="tpl-uuid",
|
|
)
|
|
llm = Mock()
|
|
llm.invoke.return_value.content = (
|
|
'{"prompt":"A grandmother in a quiet courtyard, summer cicadas, soft watercolor",'
|
|
'"style":"watercolor","size":"1024x1024"}'
|
|
)
|
|
service = MemoirImagePromptService(llm=llm, settings=settings)
|
|
|
|
result = service.build_prompt(
|
|
chapter_title="童年的夏天",
|
|
chapter_category="childhood",
|
|
description="奶奶坐在院子里的藤椅上",
|
|
context_excerpt="梧桐树下很安静,夏天总有蝉鸣。",
|
|
)
|
|
|
|
self.assertEqual(result["prompt"], "A grandmother in a quiet courtyard, summer cicadas, soft watercolor")
|
|
self.assertEqual(result["style"], "watercolor")
|
|
self.assertEqual(result["size"], "1024x1024")
|
|
|
|
def test_prompt_service_parses_markdown_wrapped_json_response(self):
|
|
settings = MemoirImageSettings(
|
|
enabled=True,
|
|
max_per_chapter=2,
|
|
provider="liblib",
|
|
default_style="watercolor",
|
|
default_size="1024x1024",
|
|
poll_interval_seconds=3,
|
|
max_attempts=20,
|
|
liblib_template_uuid="tpl-uuid",
|
|
)
|
|
llm = Mock()
|
|
llm.invoke.return_value.content = """```json
|
|
{
|
|
"prompt": "A middle-aged teacher stands on the empty stage, realistic, cinematic lighting",
|
|
"style": "realistic",
|
|
"size": "1280x720"
|
|
}
|
|
```"""
|
|
service = MemoirImagePromptService(llm=llm, settings=settings)
|
|
|
|
result = service.build_prompt(
|
|
chapter_title="二十出头 · 在小镇讲台上种下第一粒种子",
|
|
chapter_category="career_early",
|
|
description="空荡荡的教室讲台前,一个年轻老师站着",
|
|
context_excerpt="第一次站上讲台,心里紧张又兴奋。",
|
|
)
|
|
|
|
self.assertEqual(
|
|
result["prompt"],
|
|
"A middle-aged teacher stands on the empty stage, realistic, cinematic lighting",
|
|
)
|
|
self.assertEqual(result["style"], "realistic")
|
|
self.assertEqual(result["size"], "1280x720")
|
|
|
|
@patch("api.services.memoir_images.prompting.logger")
|
|
def test_prompt_service_logs_warning_and_falls_back_when_llm_response_is_invalid(
|
|
self, logger_mock
|
|
):
|
|
settings = MemoirImageSettings(
|
|
enabled=True,
|
|
max_per_chapter=2,
|
|
provider="liblib",
|
|
default_style="watercolor",
|
|
default_size="1024x1024",
|
|
poll_interval_seconds=3,
|
|
max_attempts=20,
|
|
liblib_template_uuid="tpl-uuid",
|
|
)
|
|
llm = Mock()
|
|
llm.invoke.return_value.content = "not-json"
|
|
service = MemoirImagePromptService(llm=llm, settings=settings)
|
|
|
|
result = service.build_prompt(
|
|
chapter_title="童年的夏天",
|
|
chapter_category="childhood",
|
|
description="奶奶坐在院子里的藤椅上",
|
|
context_excerpt="梧桐树下很安静,夏天总有蝉鸣。",
|
|
)
|
|
|
|
self.assertIn("childhood memory", result["prompt"])
|
|
self.assertNotIn("奶奶坐在院子里的藤椅上", result["prompt"])
|
|
logger_mock.warning.assert_called_once_with(
|
|
"图片 prompt 生成回退到默认模板: chapter_category=%s, title=%s, error=%s",
|
|
"childhood",
|
|
"童年的夏天",
|
|
unittest.mock.ANY,
|
|
)
|