Files
chatgpt-on-wechat/tests/test_feishu_markdown_images.py
2026-07-17 17:15:37 +08:00

152 lines
4.4 KiB
Python

import socket
import pytest
from channel.feishu import feishu_static_card
class FakeResponse:
def __init__(self, status_code=200, headers=None, chunks=None):
self.status_code = status_code
self.headers = headers or {}
self._chunks = chunks or []
self.closed = False
def iter_content(self, chunk_size=8192):
yield from self._chunks
def close(self):
self.closed = True
def json(self):
return getattr(self, "json_body", {})
def test_remote_markdown_images_are_uploaded_once_and_replaced_with_image_keys():
calls = []
def upload(url):
calls.append(url)
return "img_v2_chart"
markdown = (
"Before\n![chart](https://cdn.example.com/chart.png)\n"
"Again ![same](https://cdn.example.com/chart.png)"
)
result = feishu_static_card.resolve_markdown_images(markdown, upload)
assert result == (
"Before\n![chart](img_v2_chart)\nAgain ![same](img_v2_chart)"
)
assert calls == ["https://cdn.example.com/chart.png"]
def test_existing_feishu_image_keys_and_regular_links_are_untouched():
def unexpected(_url):
raise AssertionError("uploader should not be called")
markdown = "![ready](img_v2_existing) [docs](https://example.com/docs)"
assert feishu_static_card.resolve_markdown_images(markdown, unexpected) == markdown
def test_failed_remote_image_upload_degrades_to_readable_alt_text():
markdown = "Result: ![latency chart](https://cdn.example.com/chart.png)"
result = feishu_static_card.resolve_markdown_images(markdown, lambda _url: None)
assert result == "Result: [Image unavailable: latency chart]"
@pytest.mark.parametrize(
"url",
[
"http://127.0.0.1/image.png",
"http://169.254.169.254/latest/meta-data",
"http://[::1]/image.png",
],
)
def test_public_image_guard_rejects_non_public_literal_addresses(url):
with pytest.raises(ValueError, match="non-public"):
feishu_static_card.validate_public_image_url(url)
def test_image_download_revalidates_redirect_targets(monkeypatch):
monkeypatch.setattr(
socket,
"getaddrinfo",
lambda *args, **kwargs: [
(socket.AF_INET, socket.SOCK_STREAM, 6, "", ("93.184.216.34", 0))
],
)
redirect = FakeResponse(
status_code=302,
headers={"Location": "http://127.0.0.1/private.png"},
)
with pytest.raises(ValueError, match="non-public"):
feishu_static_card.download_public_image(
"https://example.com/image.png", get=lambda *args, **kwargs: redirect
)
assert redirect.closed is True
def test_image_download_enforces_content_type_and_size(monkeypatch):
monkeypatch.setattr(
socket,
"getaddrinfo",
lambda *args, **kwargs: [
(socket.AF_INET, socket.SOCK_STREAM, 6, "", ("93.184.216.34", 0))
],
)
not_image = FakeResponse(
headers={"Content-Type": "text/html"},
chunks=[b"not an image"],
)
too_large = FakeResponse(
headers={"Content-Type": "image/png", "Content-Length": "11"},
chunks=[b"01234567890"],
)
with pytest.raises(ValueError, match="not an image"):
feishu_static_card.download_public_image(
"https://example.com/image.png", get=lambda *args, **kwargs: not_image
)
with pytest.raises(ValueError, match="too large"):
feishu_static_card.download_public_image(
"https://example.com/image.png",
get=lambda *args, **kwargs: too_large,
max_bytes=10,
)
def test_public_image_is_uploaded_to_feishu_without_a_temp_file(monkeypatch):
monkeypatch.setattr(
feishu_static_card,
"download_public_image",
lambda _url: (b"png-bytes", "image/png"),
)
response = FakeResponse()
response.json_body = {
"code": 0,
"data": {"image_key": "img_v2_uploaded"},
}
calls = []
def post(url, **kwargs):
calls.append((url, kwargs))
return response
image_key = feishu_static_card.upload_public_image_to_feishu(
"https://example.com/image.png", "tenant-token", post=post
)
assert image_key == "img_v2_uploaded"
assert calls[0][1]["headers"] == {"Authorization": "Bearer tenant-token"}
filename, payload, content_type = calls[0][1]["files"]["image"]
assert filename == "markdown-image.png"
assert payload == b"png-bytes"
assert content_type == "image/png"