Files
ComfyUI-Lora-Manager/tests/utils/test_example_images_file_manager.py
2026-04-27 14:05:21 +08:00

221 lines
7.9 KiB
Python

from __future__ import annotations
import json
import os
import subprocess
from typing import Any, Dict
import pytest
from py.services.settings_manager import get_settings_manager
from py.utils.example_images_file_manager import ExampleImagesFileManager
class JsonRequest:
def __init__(self, payload: Dict[str, Any], query: Dict[str, str] | None = None) -> None:
self._payload = payload
self.query = query or {}
async def json(self) -> Dict[str, Any]:
return self._payload
@pytest.fixture(autouse=True)
def restore_settings() -> None:
manager = get_settings_manager()
original = manager.settings.copy()
try:
yield
finally:
manager.settings.clear()
manager.settings.update(original)
async def test_open_folder_requires_existing_model_directory(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "a" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
(model_folder / "image.png").write_text("data", encoding="utf-8")
popen_calls: list[list[str]] = []
startfile_calls: list[str] = []
class DummyPopen:
def __init__(self, cmd, *_args, **_kwargs):
popen_calls.append(cmd)
def dummy_startfile(path):
startfile_calls.append(path)
monkeypatch.setattr("subprocess.Popen", DummyPopen)
monkeypatch.setattr("os.startfile", dummy_startfile, raising=False)
request = JsonRequest({"model_hash": model_hash})
response = await ExampleImagesFileManager.open_folder(request)
body = json.loads(response.text)
assert body["success"] is True
# On Windows, os.startfile is used; on other platforms, subprocess.Popen
if os.name == 'nt':
assert startfile_calls
assert model_hash in startfile_calls[0]
else:
assert popen_calls
assert model_hash in popen_calls[0][-1]
async def test_open_folder_returns_clipboard_mode_with_mapped_local_path(
monkeypatch: pytest.MonkeyPatch, tmp_path
) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
settings_manager.settings["example_images_open_mode"] = "clipboard"
settings_manager.settings["example_images_local_root"] = "/Volumes/ComfyUI/examples"
model_hash = "d" * 64
model_folder = tmp_path / "library-a" / model_hash
model_folder.mkdir(parents=True)
(model_folder / "image.png").write_text("data", encoding="utf-8")
popen_calls: list[list[str]] = []
class DummyPopen:
def __init__(self, cmd, *_args, **_kwargs):
popen_calls.append(cmd)
monkeypatch.setattr("subprocess.Popen", DummyPopen)
monkeypatch.setattr("py.utils.example_images_file_manager.get_model_folder", lambda _hash: str(model_folder))
request = JsonRequest({"model_hash": model_hash})
response = await ExampleImagesFileManager.open_folder(request)
body = json.loads(response.text)
assert response.status == 200
assert body == {
"success": True,
"mode": "clipboard",
"path": f"/Volumes/ComfyUI/examples/library-a/{model_hash}",
"relative_path": f"library-a/{model_hash}",
}
assert popen_calls == []
async def test_open_folder_returns_uri_mode_with_rendered_template(
monkeypatch: pytest.MonkeyPatch, tmp_path
) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
settings_manager.settings["example_images_open_mode"] = "uri_template"
settings_manager.settings["example_images_local_root"] = "/Volumes/ComfyUI/examples"
settings_manager.settings["example_images_open_uri_template"] = (
"shortcuts://run-shortcut?name=OpenFinder&input=text&text={{encoded_local_path}}"
)
model_hash = "e" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
(model_folder / "image.png").write_text("data", encoding="utf-8")
popen_calls: list[list[str]] = []
class DummyPopen:
def __init__(self, cmd, *_args, **_kwargs):
popen_calls.append(cmd)
monkeypatch.setattr("subprocess.Popen", DummyPopen)
request = JsonRequest({"model_hash": model_hash})
response = await ExampleImagesFileManager.open_folder(request)
body = json.loads(response.text)
assert response.status == 200
assert body["success"] is True
assert body["mode"] == "uri"
assert body["path"] == f"/Volumes/ComfyUI/examples/{model_hash}"
assert body["relative_path"] == model_hash
assert body["uri"] == (
"shortcuts://run-shortcut?name=OpenFinder&input=text&text="
f"%2FVolumes%2FComfyUI%2Fexamples%2F{model_hash}"
)
assert popen_calls == []
async def test_open_folder_rejects_missing_uri_template(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
settings_manager.settings["example_images_open_mode"] = "uri_template"
model_hash = "f" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
(model_folder / "image.png").write_text("data", encoding="utf-8")
response = await ExampleImagesFileManager.open_folder(JsonRequest({"model_hash": model_hash}))
body = json.loads(response.text)
assert response.status == 400
assert body["success"] is False
assert body["error"] == "No example image open URI template configured."
async def test_open_folder_rejects_invalid_paths(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
def fake_get_model_folder(_hash):
return str(tmp_path.parent / "outside")
monkeypatch.setattr("py.utils.example_images_file_manager.get_model_folder", fake_get_model_folder)
request = JsonRequest({"model_hash": "a" * 64})
response = await ExampleImagesFileManager.open_folder(request)
body = json.loads(response.text)
assert response.status == 400
assert body["success"] is False
async def test_get_files_lists_supported_media(tmp_path) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "b" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
(model_folder / "image.png").write_text("data", encoding="utf-8")
(model_folder / "video.webm").write_text("data", encoding="utf-8")
(model_folder / "notes.txt").write_text("skip", encoding="utf-8")
request = JsonRequest({}, {"model_hash": model_hash})
response = await ExampleImagesFileManager.get_files(request)
body = json.loads(response.text)
assert response.status == 200
names = {entry["name"] for entry in body["files"]}
assert names == {"image.png", "video.webm"}
async def test_has_images_reports_presence(tmp_path) -> None:
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "c" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
(model_folder / "image.png").write_text("data", encoding="utf-8")
request = JsonRequest({}, {"model_hash": model_hash})
response = await ExampleImagesFileManager.has_images(request)
body = json.loads(response.text)
assert body["has_images"] is True
empty_request = JsonRequest({}, {"model_hash": "missing"})
empty_response = await ExampleImagesFileManager.has_images(empty_request)
empty_body = json.loads(empty_response.text)
assert empty_body["has_images"] is False
async def test_has_images_requires_model_hash() -> None:
response = await ExampleImagesFileManager.has_images(JsonRequest({}, {}))
body = json.loads(response.text)
assert response.status == 400
assert body["success"] is False