Files
2026-08-25 14:34:46 -04:00

120 lines
4.0 KiB
Python

from __future__ import annotations
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import patch
from urllib.error import HTTPError, URLError
from urllib.request import Request
from twitter.catbox_client import load_userhash, upload_file
class _FakeResponse:
def __init__(self, body: bytes) -> None:
self._body = body
def read(self) -> bytes:
return self._body
def __enter__(self) -> _FakeResponse:
return self
def __exit__(self, *_args: object) -> bool:
return False
class CatboxClientTests(unittest.TestCase):
def test_load_userhash_reads_toml(self) -> None:
with TemporaryDirectory() as raw:
vault = Path(raw)
(vault / "secrets").mkdir()
(vault / "secrets" / "credentials.toml").write_text(
'[catbox]\nuserhash = "test-hash"\n',
encoding="utf-8",
)
self.assertEqual(load_userhash(vault), "test-hash")
def test_load_userhash_rejects_empty(self) -> None:
with TemporaryDirectory() as raw:
vault = Path(raw)
(vault / "secrets").mkdir()
(vault / "secrets" / "credentials.toml").write_text(
"[catbox]\nuserhash = \"\"\n",
encoding="utf-8",
)
with self.assertRaisesRegex(RuntimeError, "userhash is empty"):
load_userhash(vault)
def test_upload_posts_form_without_subprocess(self) -> None:
with TemporaryDirectory() as raw:
src = Path(raw) / "still.png"
src.write_bytes(b"png")
captured: dict[str, object] = {}
def fake_urlopen(
request: Request,
timeout: int,
context: object,
) -> _FakeResponse:
captured["data"] = request.data
captured["timeout"] = timeout
return _FakeResponse(b"https://files.catbox.moe/abc.png")
with patch("twitter.catbox_client.urlopen", fake_urlopen):
url = upload_file(src, "test-hash")
self.assertEqual(url, "https://files.catbox.moe/abc.png")
body = captured["data"]
assert isinstance(body, bytes)
self.assertIn(b"test-hash", body)
self.assertIn(b"reqtype", body)
self.assertIn(b"png", body)
self.assertEqual(captured["timeout"], 180)
def test_error_message_omits_userhash(self) -> None:
with TemporaryDirectory() as raw:
src = Path(raw) / "still.png"
src.write_bytes(b"png")
def boom(
request: Request,
timeout: int,
context: object,
) -> _FakeResponse:
del request, timeout, context
raise URLError("refused")
with patch("twitter.catbox_client.urlopen", boom):
with self.assertRaises(RuntimeError) as ctx:
upload_file(src, "test-hash")
self.assertNotIn("test-hash", str(ctx.exception))
def test_http_error_omits_userhash(self) -> None:
with TemporaryDirectory() as raw:
src = Path(raw) / "still.png"
src.write_bytes(b"png")
def boom(
request: Request,
timeout: int,
context: object,
) -> _FakeResponse:
del timeout, context
raise HTTPError(
request.full_url,
500,
"server",
hdrs=None, # type: ignore[arg-type]
fp=None,
)
with patch("twitter.catbox_client.urlopen", boom):
with self.assertRaises(RuntimeError) as ctx:
upload_file(src, "test-hash")
self.assertNotIn("test-hash", str(ctx.exception))
self.assertIn("HTTP 500", str(ctx.exception))
if __name__ == "__main__":
unittest.main()