Fix dynamic memoir image limits
This commit is contained in:
@@ -149,3 +149,135 @@ class MemoirImageBootstrapTest(unittest.TestCase):
|
||||
self.assertEqual(len(assets), 1)
|
||||
self.assertEqual(assets[0]["status"], "failed")
|
||||
self.assertEqual(assets[0]["error"], "invalid image status: mystery")
|
||||
|
||||
def test_initialize_chapter_images_preserves_existing_completed_assets_beyond_effective_max(self):
|
||||
chapter = type(
|
||||
"ChapterStub",
|
||||
(),
|
||||
{
|
||||
"id": "chapter-1",
|
||||
"title": "童年的夏天",
|
||||
"category": "childhood",
|
||||
"content": (
|
||||
"{{IMAGE:南方小镇的青石板路}}\n"
|
||||
"{{IMAGE:奶奶坐在院子里的藤椅上}}\n"
|
||||
"{{IMAGE:门前的老槐树}}"
|
||||
),
|
||||
"images": [
|
||||
{
|
||||
"index": 0,
|
||||
"placeholder": "{{IMAGE:南方小镇的青石板路}}",
|
||||
"description": "南方小镇的青石板路",
|
||||
"status": "completed",
|
||||
"url": "https://cos.example.com/1.png",
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"placeholder": "{{IMAGE:奶奶坐在院子里的藤椅上}}",
|
||||
"description": "奶奶坐在院子里的藤椅上",
|
||||
"status": "completed",
|
||||
"url": "https://cos.example.com/2.png",
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"placeholder": "{{IMAGE:门前的老槐树}}",
|
||||
"description": "门前的老槐树",
|
||||
"status": "completed",
|
||||
"url": "https://cos.example.com/3.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
)()
|
||||
|
||||
with unittest.mock.patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"MEMOIR_IMAGE_ENABLED": "true",
|
||||
"MEMOIR_IMAGE_MAX_PER_CHAPTER": "2",
|
||||
"MEMOIR_IMAGE_CHARS_PER_EXTRA": "99999",
|
||||
"MEMOIR_IMAGE_MAX_CAP": "8",
|
||||
},
|
||||
clear=False,
|
||||
):
|
||||
assets = initialize_chapter_images(chapter)
|
||||
|
||||
self.assertEqual(len(assets), 3)
|
||||
self.assertEqual(
|
||||
[asset["placeholder"] for asset in assets],
|
||||
[
|
||||
"{{IMAGE:南方小镇的青石板路}}",
|
||||
"{{IMAGE:奶奶坐在院子里的藤椅上}}",
|
||||
"{{IMAGE:门前的老槐树}}",
|
||||
],
|
||||
)
|
||||
self.assertTrue(all(asset["status"] == "completed" for asset in assets))
|
||||
|
||||
def test_initialize_chapter_images_increases_limit_for_long_content(self):
|
||||
chapter = type(
|
||||
"ChapterStub",
|
||||
(),
|
||||
{
|
||||
"id": "chapter-1",
|
||||
"title": "童年的夏天",
|
||||
"category": "childhood",
|
||||
"content": (
|
||||
("很长的正文" * 800)
|
||||
+ "\n{{IMAGE:南方小镇的青石板路}}"
|
||||
+ "\n{{IMAGE:奶奶坐在院子里的藤椅上}}"
|
||||
+ "\n{{IMAGE:门前的老槐树}}"
|
||||
+ "\n{{IMAGE:夏夜的晒谷场}}"
|
||||
),
|
||||
"images": [],
|
||||
},
|
||||
)()
|
||||
|
||||
with unittest.mock.patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"MEMOIR_IMAGE_ENABLED": "true",
|
||||
"MEMOIR_IMAGE_MAX_PER_CHAPTER": "2",
|
||||
"MEMOIR_IMAGE_CHARS_PER_EXTRA": "1000",
|
||||
"MEMOIR_IMAGE_MAX_CAP": "8",
|
||||
},
|
||||
clear=False,
|
||||
):
|
||||
assets = initialize_chapter_images(chapter)
|
||||
|
||||
self.assertEqual(len(assets), 4)
|
||||
self.assertTrue(all(asset["status"] == "pending" for asset in assets))
|
||||
|
||||
def test_initialize_chapter_images_caps_dynamic_limit_at_max_images_cap(self):
|
||||
chapter = type(
|
||||
"ChapterStub",
|
||||
(),
|
||||
{
|
||||
"id": "chapter-1",
|
||||
"title": "童年的夏天",
|
||||
"category": "childhood",
|
||||
"content": (
|
||||
("很长的正文" * 1600)
|
||||
+ "\n{{IMAGE:图1}}"
|
||||
+ "\n{{IMAGE:图2}}"
|
||||
+ "\n{{IMAGE:图3}}"
|
||||
+ "\n{{IMAGE:图4}}"
|
||||
+ "\n{{IMAGE:图5}}"
|
||||
+ "\n{{IMAGE:图6}}"
|
||||
),
|
||||
"images": [],
|
||||
},
|
||||
)()
|
||||
|
||||
with unittest.mock.patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"MEMOIR_IMAGE_ENABLED": "true",
|
||||
"MEMOIR_IMAGE_MAX_PER_CHAPTER": "2",
|
||||
"MEMOIR_IMAGE_CHARS_PER_EXTRA": "1000",
|
||||
"MEMOIR_IMAGE_MAX_CAP": "4",
|
||||
},
|
||||
clear=False,
|
||||
):
|
||||
assets = initialize_chapter_images(chapter)
|
||||
|
||||
self.assertEqual(len(assets), 4)
|
||||
self.assertEqual([asset["description"] for asset in assets], ["图1", "图2", "图3", "图4"])
|
||||
|
||||
@@ -13,6 +13,8 @@ class MemoirImageSettingsTest(unittest.TestCase):
|
||||
os.environ,
|
||||
{
|
||||
"MEMOIR_IMAGE_MAX_PER_CHAPTER": "not-an-int",
|
||||
"MEMOIR_IMAGE_CHARS_PER_EXTRA": "bad-extra",
|
||||
"MEMOIR_IMAGE_MAX_CAP": "bad-cap",
|
||||
"MEMOIR_IMAGE_POLL_INTERVAL": "bad",
|
||||
"MEMOIR_IMAGE_MAX_ATTEMPTS": "oops",
|
||||
},
|
||||
@@ -22,6 +24,8 @@ class MemoirImageSettingsTest(unittest.TestCase):
|
||||
settings = MemoirImageSettings.from_env()
|
||||
|
||||
self.assertEqual(settings.max_per_chapter, 2)
|
||||
self.assertEqual(settings.chars_per_extra_image, 1500)
|
||||
self.assertEqual(settings.max_images_cap, 8)
|
||||
self.assertEqual(settings.poll_interval_seconds, 3)
|
||||
self.assertEqual(settings.max_attempts, 60)
|
||||
|
||||
@@ -31,3 +35,8 @@ class MemoirImageSettingsTest(unittest.TestCase):
|
||||
settings = MemoirImageSettings.from_env()
|
||||
|
||||
self.assertEqual(settings.liblib_template_uuid, DEFAULT_LIBLIB_TEMPLATE_UUID)
|
||||
|
||||
def test_effective_max_images_never_drops_below_base_max_per_chapter(self):
|
||||
settings = MemoirImageSettings(enabled=True, max_per_chapter=2, max_images_cap=1)
|
||||
|
||||
self.assertEqual(settings.effective_max_images(0), 2)
|
||||
|
||||
Reference in New Issue
Block a user