ComfyUI/tests-unit/comfy_api_test/remote_combo_options_test.py
bigcat88 fdf929031b
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Build package / Build Test (3.10) (push) Has been cancelled
Build package / Build Test (3.11) (push) Has been cancelled
Build package / Build Test (3.12) (push) Has been cancelled
Build package / Build Test (3.13) (push) Has been cancelled
Build package / Build Test (3.14) (push) Has been cancelled
feat: implement RemoteComboOptions for rich remote-populated combos
Signed-off-by: bigcat88 <bigcat88@icloud.com>
2026-04-16 15:22:20 +03:00

166 lines
4.6 KiB
Python

import pytest
from comfy_api.latest._io import (
Combo,
RemoteComboOptions,
RemoteItemSchema,
RemoteOptions,
)
def _schema(**overrides):
defaults = dict(value_field="id", label_field="name")
return RemoteItemSchema(**{**defaults, **overrides})
def _combo(**overrides):
defaults = dict(route="/proxy/foo", item_schema=_schema())
return RemoteComboOptions(**{**defaults, **overrides})
def test_item_schema_defaults_accepted():
d = _schema().as_dict()
assert d == {"value_field": "id", "label_field": "name", "preview_type": "image"}
def test_item_schema_full_config_accepted():
d = _schema(
preview_url_field="preview",
preview_type="audio",
description_field="desc",
search_fields=["first", "last", "profile.email"],
).as_dict()
assert d["preview_type"] == "audio"
assert d["search_fields"] == ["first", "last", "profile.email"]
@pytest.mark.parametrize(
"bad_fields",
[
["{first} {last}"],
["name", "{age}"],
["leading{"],
["trailing}"],
],
)
def test_item_schema_rejects_template_strings_in_search_fields(bad_fields):
with pytest.raises(ValueError, match="search_fields"):
_schema(search_fields=bad_fields)
@pytest.mark.parametrize("bad_preview_type", ["middle", "IMAGE", "", "gif"])
def test_item_schema_rejects_unknown_preview_type(bad_preview_type):
with pytest.raises(ValueError, match="preview_type"):
_schema(preview_type=bad_preview_type)
def test_combo_options_minimal_accepted():
d = _combo().as_dict()
assert d["route"] == "/proxy/foo"
assert d["refresh_button"] is True
assert "item_schema" in d
@pytest.mark.parametrize(
"route",
[
"/proxy/foo",
"http://localhost:9000/voices",
"https://api.example.com/v1/voices",
],
)
def test_combo_options_accepts_valid_routes(route):
_combo(route=route)
@pytest.mark.parametrize(
"route",
[
"",
"api.example.com/voices",
"voices",
"ftp-no-scheme",
],
)
def test_combo_options_rejects_invalid_routes(route):
with pytest.raises(ValueError, match="'route'"):
_combo(route=route)
@pytest.mark.parametrize(
"route",
[
"http://localhost:9000/voices",
"https://api.example.com/v1/voices",
],
)
def test_combo_options_use_comfy_api_rejects_absolute_route(route):
with pytest.raises(ValueError, match="use_comfy_api"):
_combo(route=route, use_comfy_api=True)
def test_combo_options_use_comfy_api_accepts_relative_route():
_combo(route="/proxy/foo", use_comfy_api=True)
def test_combo_options_page_size_with_response_key_rejected():
with pytest.raises(ValueError, match="response_key.*page_size"):
_combo(page_size=50, response_key="data.items")
@pytest.mark.parametrize("bad_page_size", [0, -1])
def test_combo_options_page_size_must_be_positive(bad_page_size):
with pytest.raises(ValueError, match="page_size"):
_combo(page_size=bad_page_size)
@pytest.mark.parametrize("bad_auto_select", ["middle", "FIRST", "", "firstlast"])
def test_combo_options_rejects_unknown_auto_select(bad_auto_select):
with pytest.raises(ValueError, match="auto_select"):
_combo(auto_select=bad_auto_select)
@pytest.mark.parametrize("bad_refresh", [1, 127])
def test_combo_options_refresh_in_forbidden_range_rejected(bad_refresh):
with pytest.raises(ValueError, match="refresh"):
_combo(refresh=bad_refresh)
@pytest.mark.parametrize("ok_refresh", [0, -1, 128])
def test_combo_options_refresh_valid_values_accepted(ok_refresh):
_combo(refresh=ok_refresh)
def test_combo_options_timeout_negative_rejected():
with pytest.raises(ValueError, match="timeout"):
_combo(timeout=-1)
def test_combo_options_max_retries_negative_rejected():
with pytest.raises(ValueError, match="max_retries"):
_combo(max_retries=-1)
def test_combo_options_as_dict_prunes_none_fields():
d = _combo().as_dict()
for pruned in ("page_size", "response_key", "refresh", "timeout", "max_retries", "auto_select"):
assert pruned not in d
def test_combo_input_accepts_remote_combo_alone():
Combo.Input("voice", remote_combo=_combo())
def test_combo_input_rejects_remote_plus_remote_combo():
with pytest.raises(ValueError, match="remote.*remote_combo"):
Combo.Input(
"voice",
remote=RemoteOptions(route="/r", refresh_button=True),
remote_combo=_combo(),
)
def test_combo_input_rejects_options_plus_remote_combo():
with pytest.raises(ValueError, match="options.*remote_combo"):
Combo.Input("voice", options=["a", "b"], remote_combo=_combo())