test_oss.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """OSS 转存离线测试:纯 parser + upload_stream + to_oss 兜底(注入 http_post)。"""
  2. from __future__ import annotations
  3. import httpx
  4. import pytest
  5. from creation_knowledge.config import PgConfig, Settings
  6. from creation_knowledge.integrations.oss import (
  7. OssError, parse_oss_response, to_oss, upload_stream,
  8. )
  9. def _settings() -> Settings:
  10. return Settings(
  11. pg=PgConfig(host="h", port=5432, user="u", password="p", database="d"),
  12. crawler_base_url="x", crawler_key="", crawler_timeout=30,
  13. video_model="m", gemini_api_key="",
  14. openrouter_base_url="b", openrouter_api_key="k",
  15. llm_model="m", max_cards=12, frames_dir="f", douyin_ratio="540p", data_dir="",
  16. oss_upload_url="http://oss.test/upload_stream", oss_upload_timeout_seconds=60)
  17. class _Resp:
  18. def __init__(self, payload): self._p = payload
  19. def raise_for_status(self): return None
  20. def json(self): return self._p
  21. def test_parse_ok():
  22. assert parse_oss_response(
  23. {"status": 0, "oss_object": {"cdn_url": "https://res/x.mp4"}}) == "https://res/x.mp4"
  24. def test_parse_status_error():
  25. with pytest.raises(OssError):
  26. parse_oss_response({"status": 1, "msg": "fail"})
  27. def test_parse_missing_cdn():
  28. with pytest.raises(OssError):
  29. parse_oss_response({"status": 0, "oss_object": {}})
  30. def test_upload_stream_posts_and_returns_cdn():
  31. captured = {}
  32. def post(url, json=None, headers=None, timeout=None):
  33. captured["url"] = url
  34. captured["json"] = json
  35. return _Resp({"status": 0, "oss_object": {"cdn_url": "https://res/y.webp"}})
  36. cdn = upload_stream("http://src/y.webp", src_type="image",
  37. settings=_settings(), http_post=post)
  38. assert cdn == "https://res/y.webp"
  39. assert captured["url"] == "http://oss.test/upload_stream"
  40. assert captured["json"] == {"src_url": "http://src/y.webp", "src_type": "image"}
  41. def test_upload_stream_bad_src_type():
  42. with pytest.raises(OssError):
  43. upload_stream("http://src/a", src_type="audio", settings=_settings())
  44. def test_to_oss_fallback_on_http_error():
  45. def post(url, json=None, headers=None, timeout=None):
  46. raise httpx.ConnectError("boom")
  47. # 失败返回原 url,永不抛
  48. assert to_oss("http://src/z.mp4", "video",
  49. settings=_settings(), http_post=post) == "http://src/z.mp4"
  50. def test_to_oss_fallback_on_business_error():
  51. def post(url, json=None, headers=None, timeout=None):
  52. return _Resp({"status": 500, "msg": "boom"})
  53. assert to_oss("http://src/z.mp4", "video",
  54. settings=_settings(), http_post=post) == "http://src/z.mp4"
  55. def test_to_oss_success():
  56. def post(url, json=None, headers=None, timeout=None):
  57. return _Resp({"status": 0, "oss_object": {"cdn_url": "https://res/z.mp4"}})
  58. assert to_oss("http://src/z.mp4", "video",
  59. settings=_settings(), http_post=post) == "https://res/z.mp4"
  60. def test_to_oss_empty_url_passthrough():
  61. assert to_oss("", "image", settings=_settings()) == ""