test_content_collage.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from PIL import Image
  2. import pytest
  3. from agent.tools.builtin.content import collage
  4. from agent.tools.builtin.content.platforms import aigc_channel, x, youtube
  5. @pytest.mark.asyncio
  6. async def test_collage_filters_failed_images_and_keeps_matching_labels(monkeypatch):
  7. image = Image.new("RGB", (4, 4), "white")
  8. captured = {}
  9. async def fake_load(urls):
  10. return [(urls[0], image), (urls[1], None)]
  11. def fake_grid(*, images, labels):
  12. captured["images"] = images
  13. captured["labels"] = labels
  14. return image
  15. async def fake_upload(image_bytes, filename):
  16. captured["filename"] = filename
  17. return "https://cdn.example/collage.png"
  18. monkeypatch.setattr(collage, "load_images", fake_load)
  19. monkeypatch.setattr(collage, "build_image_grid", fake_grid)
  20. monkeypatch.setattr(collage, "_upload_bytes", fake_upload)
  21. result = await collage.render_image_collage(
  22. ["one", "two"], labels=["first", "second"], filename_prefix="test"
  23. )
  24. assert result == {"type": "url", "url": "https://cdn.example/collage.png"}
  25. assert captured["images"] == [image]
  26. assert captured["labels"] == ["first"]
  27. assert captured["filename"].startswith("test_")
  28. @pytest.mark.asyncio
  29. async def test_collage_falls_back_to_base64_when_upload_fails(monkeypatch):
  30. image = Image.new("RGB", (2, 2), "white")
  31. async def fake_load(urls):
  32. return [(urls[0], image)]
  33. async def failed_upload(image_bytes, filename):
  34. raise RuntimeError("offline")
  35. monkeypatch.setattr(collage, "load_images", fake_load)
  36. monkeypatch.setattr(collage, "build_image_grid", lambda **kwargs: image)
  37. monkeypatch.setattr(collage, "_upload_bytes", failed_upload)
  38. result = await collage.render_image_collage(["one"])
  39. assert result["type"] == "base64"
  40. assert result["media_type"] == "image/png"
  41. assert result["data"]
  42. @pytest.mark.asyncio
  43. @pytest.mark.parametrize(
  44. ("adapter", "args", "expected_prefix"),
  45. [
  46. (aigc_channel._build_images_collage, (["u"],), "collage_detail"),
  47. (x._build_images_collage, (["u"],), "x_detail_collage"),
  48. ],
  49. )
  50. async def test_detail_adapters_delegate_to_shared_collage(
  51. monkeypatch, adapter, args, expected_prefix
  52. ):
  53. module = __import__(adapter.__module__, fromlist=["render_image_collage"])
  54. captured = {}
  55. async def fake_render(urls, **kwargs):
  56. captured.update(kwargs)
  57. return {"type": "url", "url": "ok"}
  58. monkeypatch.setattr(module, "render_image_collage", fake_render)
  59. assert await adapter(*args) == {"type": "url", "url": "ok"}
  60. assert captured["filename_prefix"] == expected_prefix
  61. @pytest.mark.asyncio
  62. async def test_search_adapters_keep_platform_selection_rules(monkeypatch):
  63. calls = []
  64. async def fake_render(urls, **kwargs):
  65. calls.append((urls, kwargs))
  66. return {"type": "url", "url": "ok"}
  67. monkeypatch.setattr(x, "render_image_collage", fake_render)
  68. monkeypatch.setattr(youtube, "render_image_collage", fake_render)
  69. await x._build_tweet_collage(
  70. [{"image_url_list": [{"image_url": "x.jpg"}], "channel_account_name": "a"}]
  71. )
  72. await youtube._build_video_collage(
  73. [{"thumbnails": [{"url": "yt.jpg"}], "title": "video"}]
  74. )
  75. assert calls[0][0] == ["x.jpg"]
  76. assert calls[0][1]["labels"] == ["@a"]
  77. assert calls[0][1]["filename_prefix"] == "x_collage"
  78. assert calls[1][0] == ["yt.jpg"]
  79. assert calls[1][1]["labels"] == ["video"]
  80. assert calls[1][1]["filename_prefix"] == "youtube_collage"