120 lines
4.0 KiB
Python
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()
|