test_media.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """媒体落盘离线测试:注入假 downloader,断言图片落盘 + card.url 改写为 /data 路径。"""
  2. from __future__ import annotations
  3. from creation_knowledge import media
  4. from core.models import Card, Post
  5. PNG = b"\x89PNG\r\n\x1a\n" + b"fakepng"
  6. JPG = b"\xff\xd8\xff\xe0" + b"fakejpg"
  7. def _post():
  8. return Post(
  9. id="xhs_1", platform="xiaohongshu", url="u", content_id="1",
  10. image_urls=["http://cdn/a", "http://cdn/b"],
  11. cards=[Card(index=1, kind="image", url="http://cdn/a"),
  12. Card(index=2, kind="image", url="http://cdn/b")],
  13. )
  14. def test_media_target():
  15. t = media.media_target("data", "20260616-101010", "douyin", "dy_9")
  16. assert str(t.dir).endswith("data/20260616-101010/douyin/dy_9")
  17. assert t.public_base == "/data/20260616-101010/douyin/dy_9"
  18. def test_save_images_writes_and_rewrites(tmp_path):
  19. bodies = {"http://cdn/a": PNG, "http://cdn/b": JPG}
  20. calls = []
  21. def dl(url, platform):
  22. calls.append((url, platform))
  23. return bodies[url]
  24. post = _post()
  25. media.save_images(post, tmp_path, "/data/B/xiaohongshu/xhs_1", downloader=dl)
  26. assert (tmp_path / "image_1.png").read_bytes() == PNG # 文件头嗅探出 .png
  27. assert (tmp_path / "image_2.jpg").read_bytes() == JPG
  28. assert post.cards[0].url == "/data/B/xiaohongshu/xhs_1/image_1.png"
  29. assert post.cards[1].url == "/data/B/xiaohongshu/xhs_1/image_2.jpg"
  30. assert calls == [("http://cdn/a", "xiaohongshu"), ("http://cdn/b", "xiaohongshu")]
  31. def test_save_images_skips_failures(tmp_path):
  32. """单张下载失败只跳过,不抛、不改这张卡 url。"""
  33. def dl(url, platform):
  34. if url.endswith("b"):
  35. raise RuntimeError("boom")
  36. return JPG
  37. post = _post()
  38. media.save_images(post, tmp_path, "/data/B/xiaohongshu/xhs_1", downloader=dl)
  39. assert post.cards[0].url == "/data/B/xiaohongshu/xhs_1/image_1.jpg"
  40. assert post.cards[1].url == "http://cdn/b" # 失败的保持原样
  41. def test_save_images_ignores_local_and_segment(tmp_path):
  42. """已是本地路径 / 非 image 卡不处理。"""
  43. post = Post(id="x", platform="douyin", url="u", content_id="1",
  44. cards=[Card(index=1, kind="segment", url="/data/x/video.mp4", start=0, end=3),
  45. Card(index=2, kind="image", url="/data/x/image_2.jpg")])
  46. def dl(url, platform):
  47. raise AssertionError("不应被调用")
  48. media.save_images(post, tmp_path, "/data/x", downloader=dl)
  49. assert post.cards[0].url == "/data/x/video.mp4"
  50. assert post.cards[1].url == "/data/x/image_2.jpg"