- FastAPI backend with SQLModel, Alembic migrations, AgentScope agents - Next.js 15 frontend with React 19, Tailwind, Zustand, React Flow - Multi-provider AI system (DashScope, Kling, MiniMax, Volcengine, OpenAI, etc.) - All HTTP clients migrated from sync requests to async httpx - Admin-managed API keys via environment variables - SSRF vulnerability fixed in ensure_url()
185 lines
6.1 KiB
Python
185 lines
6.1 KiB
Python
"""
|
|
Tests for the models API grouped format
|
|
"""
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from src.main import app
|
|
from src.services.provider.registry import ModelRegistry, ModelType, ServiceConfig, ServiceFactory
|
|
|
|
|
|
class MockImageService:
|
|
"""Mock image service for testing"""
|
|
def __init__(self, **kwargs):
|
|
self.config = kwargs
|
|
|
|
|
|
class MockVideoService:
|
|
"""Mock video service for testing"""
|
|
def __init__(self, **kwargs):
|
|
self.config = kwargs
|
|
|
|
|
|
@pytest.fixture
|
|
def setup_test_models():
|
|
"""Setup test models in registry"""
|
|
# Register test image models
|
|
image_config_1 = ServiceConfig(
|
|
id="dashscope/qwen-image",
|
|
module="test",
|
|
class_name="MockImageService",
|
|
name="Qwen Image",
|
|
type="image",
|
|
provider="dashscope",
|
|
model_key="qwen-image",
|
|
enabled=True,
|
|
is_default=True,
|
|
capabilities={"supportsLora": True, "supportsRefImage": True},
|
|
resolutions={"1K": {"16:9": "1280*720", "1:1": "1024*1024"}}
|
|
)
|
|
factory_1 = ServiceFactory(image_config_1, MockImageService)
|
|
ModelRegistry.register_factory("dashscope/qwen-image", factory_1, ModelType.IMAGE, is_default=True)
|
|
|
|
image_config_2 = ServiceConfig(
|
|
id="modelscope/qwen-image",
|
|
module="test",
|
|
class_name="MockImageService",
|
|
name="ModelScope Qwen Image",
|
|
type="image",
|
|
provider="modelscope",
|
|
model_key="qwen-image",
|
|
enabled=True,
|
|
is_default=False
|
|
)
|
|
factory_2 = ServiceFactory(image_config_2, MockImageService)
|
|
ModelRegistry.register_factory("modelscope/qwen-image", factory_2, ModelType.IMAGE)
|
|
|
|
# Register test video model
|
|
video_config = ServiceConfig(
|
|
id="dashscope/wan2.6-video",
|
|
module="test",
|
|
class_name="MockVideoService",
|
|
name="Wan 2.6 Video",
|
|
type="video",
|
|
provider="dashscope",
|
|
model_key="wan2.6-video",
|
|
enabled=True,
|
|
is_default=True
|
|
)
|
|
factory_3 = ServiceFactory(video_config, MockVideoService)
|
|
ModelRegistry.register_factory("dashscope/wan2.6-video", factory_3, ModelType.VIDEO, is_default=True)
|
|
|
|
yield
|
|
|
|
# Cleanup (registry is a singleton, so we need to clean up)
|
|
# Note: In real tests, you might want to reset the registry
|
|
|
|
|
|
def test_models_api_returns_grouped_format(setup_test_models):
|
|
"""Test that /config/models returns grouped HashMap format"""
|
|
client = TestClient(app)
|
|
response = client.get("/api/v1/config/models")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
# Check response structure
|
|
assert "code" in data
|
|
assert "data" in data
|
|
assert data["code"] == "0000" # API uses "0000" for success
|
|
|
|
# Check grouped structure
|
|
grouped_data = data["data"]
|
|
assert "image" in grouped_data
|
|
assert "video" in grouped_data
|
|
assert "audio" in grouped_data
|
|
assert "llm" in grouped_data
|
|
|
|
# Check that image and video are dicts (HashMaps)
|
|
assert isinstance(grouped_data["image"], dict)
|
|
assert isinstance(grouped_data["video"], dict)
|
|
|
|
|
|
def test_models_api_image_models_structure(setup_test_models):
|
|
"""Test that image models have correct structure"""
|
|
client = TestClient(app)
|
|
response = client.get("/api/v1/config/models")
|
|
|
|
data = response.json()
|
|
image_models = data["data"]["image"]
|
|
|
|
# Check that we have the expected models
|
|
assert "dashscope/qwen-image" in image_models
|
|
assert "modelscope/qwen-image" in image_models
|
|
|
|
# Check dashscope/qwen-image structure
|
|
qwen_model = image_models["dashscope/qwen-image"]
|
|
assert qwen_model["id"] == "dashscope/qwen-image"
|
|
assert qwen_model["name"] == "Qwen Image"
|
|
assert qwen_model["type"] == "image"
|
|
assert qwen_model["provider"] == "dashscope"
|
|
assert qwen_model["model_key"] == "qwen-image"
|
|
assert qwen_model["is_default"] is True
|
|
assert qwen_model["enabled"] is True
|
|
|
|
# Check capabilities
|
|
assert "capabilities" in qwen_model
|
|
assert qwen_model["capabilities"]["supportsLora"] is True
|
|
assert qwen_model["capabilities"]["supportsRefImage"] is True
|
|
|
|
# Check resolutions
|
|
assert "resolutions" in qwen_model
|
|
assert "1K" in qwen_model["resolutions"]
|
|
|
|
|
|
def test_models_api_video_models_structure(setup_test_models):
|
|
"""Test that video models have correct structure"""
|
|
client = TestClient(app)
|
|
response = client.get("/api/v1/config/models")
|
|
|
|
data = response.json()
|
|
video_models = data["data"]["video"]
|
|
|
|
# Check that we have the expected model
|
|
assert "dashscope/wan2.6-video" in video_models
|
|
|
|
# Check structure
|
|
wan_model = video_models["dashscope/wan2.6-video"]
|
|
assert wan_model["id"] == "dashscope/wan2.6-video"
|
|
assert wan_model["name"] == "Wan 2.6 Video"
|
|
assert wan_model["type"] == "video"
|
|
assert wan_model["provider"] == "dashscope"
|
|
assert wan_model["model_key"] == "wan2.6-video"
|
|
assert wan_model["is_default"] is True
|
|
|
|
|
|
def test_models_api_hashmap_key_matches_id(setup_test_models):
|
|
"""Test that HashMap keys match the id field of each model"""
|
|
client = TestClient(app)
|
|
response = client.get("/api/v1/config/models")
|
|
|
|
data = response.json()
|
|
grouped_data = data["data"]
|
|
|
|
# Check all model types
|
|
for model_type in ["image", "video", "audio", "llm"]:
|
|
models = grouped_data[model_type]
|
|
for model_id, model_config in models.items():
|
|
# HashMap key should match the id field
|
|
assert model_id == model_config["id"], \
|
|
f"HashMap key '{model_id}' does not match id field '{model_config['id']}'"
|
|
|
|
|
|
def test_models_api_default_flag(setup_test_models):
|
|
"""Test that is_default flag is correctly set"""
|
|
client = TestClient(app)
|
|
response = client.get("/api/v1/config/models")
|
|
|
|
data = response.json()
|
|
image_models = data["data"]["image"]
|
|
|
|
# dashscope/qwen-image should be default
|
|
assert image_models["dashscope/qwen-image"]["is_default"] is True
|
|
|
|
# modelscope/qwen-image should not be default
|
|
assert image_models["modelscope/qwen-image"]["is_default"] is False
|