Replace the prior release tree with the current plugin, frontend, tests, and documentation. Document retired node IDs and the public Gitea update source.
76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
from io import BytesIO
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
from PIL import Image
|
|
|
|
|
|
PLUGIN_ROOT = Path(__file__).resolve().parents[1]
|
|
MODULE_PATH = PLUGIN_ROOT / "utils" / "o1key_image_thumbnail.py"
|
|
SPEC = importlib.util.spec_from_file_location("o1key_image_thumbnail_under_test", MODULE_PATH)
|
|
MODULE = importlib.util.module_from_spec(SPEC)
|
|
assert SPEC and SPEC.loader
|
|
SPEC.loader.exec_module(MODULE)
|
|
|
|
|
|
class _FolderPaths:
|
|
def __init__(self, roots):
|
|
self.roots = roots
|
|
|
|
def get_directory_by_type(self, folder_type):
|
|
return self.roots.get(folder_type)
|
|
|
|
|
|
class O1keyImageThumbnailTests(unittest.TestCase):
|
|
def test_thumbnail_is_bounded_and_source_is_untouched(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
source = Path(directory, "large.png")
|
|
Image.new("RGB", (1800, 900), (30, 80, 120)).save(source)
|
|
original = source.read_bytes()
|
|
|
|
encoded = MODULE.render_reference_thumbnail(str(source))
|
|
|
|
self.assertEqual(source.read_bytes(), original)
|
|
with Image.open(BytesIO(encoded)) as thumbnail:
|
|
self.assertEqual(thumbnail.format, "WEBP")
|
|
self.assertEqual(thumbnail.size, (256, 128))
|
|
|
|
def test_resolver_accepts_scoped_descriptor_and_rejects_traversal(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
input_root = Path(directory, "input")
|
|
nested = input_root / "legacy"
|
|
nested.mkdir(parents=True)
|
|
source = nested / "reference.png"
|
|
source.write_bytes(b"image")
|
|
folder_paths = _FolderPaths({"input": str(input_root)})
|
|
|
|
resolved = MODULE.resolve_thumbnail_source(
|
|
folder_paths,
|
|
"reference.png",
|
|
"legacy",
|
|
"input",
|
|
)
|
|
self.assertEqual(Path(resolved), source.resolve())
|
|
with self.assertRaisesRegex(ValueError, "子目录无效"):
|
|
MODULE.resolve_thumbnail_source(
|
|
folder_paths,
|
|
"reference.png",
|
|
"../outside",
|
|
"input",
|
|
)
|
|
with self.assertRaisesRegex(ValueError, "目录类型无效"):
|
|
MODULE.resolve_thumbnail_source(
|
|
folder_paths,
|
|
"reference.png",
|
|
"legacy",
|
|
"private",
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|