Files
gokayfem-ComfyUI-fal-API/tests/test_server_routes.py
Gokay Aydogan eac683ddcc feat: v2.3.0 — durable job inbox, provenance, in-canvas cost UI
- Durable Job Inbox: every async submit is journaled to the shared
  sqlite store and survives ComfyUI restarts; the Fal Job Inbox node
  lists pending/collected jobs and outputs the newest pending
  request_id/endpoint for one-wire recovery via Result by Request ID.
- Provenance: Fal Save Media from URL writes a <file>.fal.json sidecar
  and embeds a fal_provenance PNG text chunk (preserving existing text
  chunks and ICC profiles), returning the request_id as a second output;
  new Fal Provenance from File node reads saved files back into
  endpoint_id + request_id for free re-materialization.
- First web extension (web/ + /fal_api server routes): per-node cost
  pills rendered above every priced fal node (live estimates on
  free-typed endpoint fields), a fal sidebar tab with session spend,
  account balance and a job list with copy/cancel, and in-canvas
  endpoint search with price labels. All features degrade silently on
  older frontends; routes are exception-guarded and cached.

Review fixes: PNG provenance embed preserves source text chunks and ICC
profile; jobs route limit clamped.

15 new tests (91 total).
2026-07-02 15:17:25 +03:00

51 lines
1.4 KiB
Python

"""Unit tests for the /fal_api server routes' pure functions."""
from __future__ import annotations
import importlib
import pytest
from conftest import PKG, _load_package
@pytest.fixture(scope="session")
def routes():
_load_package()
return importlib.import_module(f"{PKG}.nodes.server_routes")
def test_import_without_comfy_server_is_safe(routes):
# loaded via conftest without ComfyUI's `server` module present
assert routes is not None
def test_pricing_map_covers_registry(routes):
pricing_map = routes._pricing_map()
assert len(pricing_map) > 100
sample = next(iter(pricing_map.values()))
assert "label" in sample
for key in pricing_map:
assert key.startswith("FalAPI_")
def test_search_models(routes):
results = routes._search_models(q="kling", category="", max_price=None, limit=10)
assert results
assert all("kling" in r["endpoint_id"].lower() or "kling" in r["title"].lower() for r in results)
def test_search_models_price_filter(routes):
unfiltered = routes._search_models(q="", category="", max_price=None, limit=100)
cheap = routes._search_models(q="", category="", max_price=0.02, limit=100)
assert len(cheap) < len(unfiltered)
def test_session_shape(routes):
payload = routes._session()
assert set(payload) >= {"total_usd", "calls"}
def test_jobs_degrades_gracefully(routes):
payload = routes._jobs(limit=5)
assert "jobs" in payload and "counts" in payload