7f26ecc19a
load_image_generation_settings now re-raises pydantic ValidationError as a sanitized ImageGenError carrying only field locations and error types, so a mis-indented config.yaml can never echo a literal API key into agent-visible errors. Also widen save_registry's expected_revision annotation to int | None to match the http_api caller (value remains ignored). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
"""Tests for image_gen.config."""
|
|
|
|
import os
|
|
|
|
import pytest
|
|
|
|
from EvoScientist.image_gen.adapters.base import ImageGenError
|
|
from EvoScientist.image_gen.config import (
|
|
ImageGenerationSettings,
|
|
ImageModelEntry,
|
|
is_image_generation_model,
|
|
load_image_generation_settings,
|
|
)
|
|
|
|
|
|
def _write_config(tmp_path, body: str):
|
|
path = tmp_path / "config.yaml"
|
|
path.write_text(body, encoding="utf-8")
|
|
return path
|
|
|
|
|
|
def test_load_full_section(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("TEST_IMG_KEY", "sk-secret-123")
|
|
path = _write_config(
|
|
tmp_path,
|
|
"""
|
|
image_generation:
|
|
default_model: gpt-image-2
|
|
timeout_seconds: 90
|
|
models:
|
|
- id: gpt-image-2
|
|
name: GPT Image 2
|
|
provider: openai
|
|
api_key: ${TEST_IMG_KEY}
|
|
base_url: https://api.openai.com
|
|
default_size: "1024x1024"
|
|
- id: imagen-4.0-generate-001
|
|
provider: gemini
|
|
api_key: ${TEST_IMG_KEY}
|
|
supports_edit: false
|
|
""",
|
|
)
|
|
settings = load_image_generation_settings(config_path=path)
|
|
assert settings.default_model == "gpt-image-2"
|
|
assert settings.timeout_seconds == 90
|
|
assert len(settings.models) == 2
|
|
openai_entry = settings.models[0]
|
|
assert openai_entry.resolved_api_key() == "sk-secret-123"
|
|
assert openai_entry.resolved_base_url() == "https://api.openai.com"
|
|
assert openai_entry.display_name() == "GPT Image 2"
|
|
gemini_entry = settings.models[1]
|
|
assert gemini_entry.provider == "gemini"
|
|
assert gemini_entry.supports_edit is False
|
|
assert gemini_entry.display_name() == "imagen-4.0-generate-001"
|
|
|
|
|
|
def test_missing_file_returns_empty_settings(tmp_path):
|
|
settings = load_image_generation_settings(config_path=tmp_path / "nope.yaml")
|
|
assert settings == ImageGenerationSettings()
|
|
|
|
|
|
def test_missing_section_returns_empty_settings(tmp_path):
|
|
path = _write_config(tmp_path, "webui_port: 4716\n")
|
|
settings = load_image_generation_settings(config_path=path)
|
|
assert settings.models == []
|
|
|
|
|
|
def test_unresolved_env_ref_yields_empty(tmp_path, monkeypatch):
|
|
monkeypatch.delenv("NOPE_NOT_SET", raising=False)
|
|
path = _write_config(
|
|
tmp_path,
|
|
"""
|
|
image_generation:
|
|
models:
|
|
- id: gpt-image-2
|
|
provider: openai
|
|
api_key: ${NOPE_NOT_SET}
|
|
""",
|
|
)
|
|
settings = load_image_generation_settings(config_path=path)
|
|
assert settings.models[0].resolved_api_key() == ""
|
|
|
|
|
|
def test_plain_value_passthrough(tmp_path):
|
|
path = _write_config(
|
|
tmp_path,
|
|
"""
|
|
image_generation:
|
|
models:
|
|
- id: gpt-image-2
|
|
provider: openai
|
|
api_key: sk-literal
|
|
""",
|
|
)
|
|
settings = load_image_generation_settings(config_path=path)
|
|
assert settings.models[0].resolved_api_key() == "sk-literal"
|
|
|
|
|
|
def test_validation_error_never_echoes_config_values(tmp_path):
|
|
"""A malformed section must raise a sanitized error: field locations and
|
|
error types only, never the offending input values (key-leak red line)."""
|
|
path = _write_config(
|
|
tmp_path,
|
|
"""
|
|
image_generation:
|
|
models:
|
|
- id: gpt-image-2
|
|
provider: sk-secret-value-123
|
|
api_key: sk-secret-value-123
|
|
""",
|
|
)
|
|
with pytest.raises(ImageGenError) as excinfo:
|
|
load_image_generation_settings(config_path=path)
|
|
message = str(excinfo.value)
|
|
assert "sk-secret-value-123" not in message
|
|
assert "provider" in message
|
|
|
|
|
|
def test_is_image_generation_model():
|
|
assert is_image_generation_model("gpt-image-2") is True
|
|
assert is_image_generation_model("dall-e-3") is True
|
|
assert is_image_generation_model("openai/gpt-image-1") is True
|
|
assert is_image_generation_model("imagen-4.0-generate-001") is True
|
|
assert is_image_generation_model("doubao-seedream-4-0") is True
|
|
assert is_image_generation_model("wanx2.1-t2i-turbo") is True
|
|
assert is_image_generation_model("glm-5.2") is False
|
|
assert is_image_generation_model("gpt-4o") is False
|
|
assert is_image_generation_model(None) is False
|
|
assert is_image_generation_model("") is False
|
|
|
|
|
|
def test_evoscientist_config_ignores_section(tmp_path, monkeypatch):
|
|
"""The platform config loader filters unknown keys, so the image section
|
|
never leaks through EvoScientistConfig / its API surface."""
|
|
from EvoScientist.config import settings as config_settings
|
|
|
|
path = _write_config(
|
|
tmp_path,
|
|
"image_generation:\n models:\n - id: gpt-image-2\n api_key: sk-x\n",
|
|
)
|
|
monkeypatch.setattr(config_settings, "get_config_path", lambda: path)
|
|
cfg = config_settings.load_config()
|
|
assert not hasattr(cfg, "image_generation")
|