Files
headquarter/apps/api/tests/tools/test_router.py
T
Fusion f33a563003 feat(FN-003): add tool manifest registry with FastAPI CRUD and built-in manifests
- Add ToolManifest Pydantic models with validators for ports, mounts, health checks, and traefik config

- Implement in-memory ToolRegistry with YAML loading and built-in manifest scanning

- Add FastAPI CRUD routes for listing, retrieving, and creating tool manifests

- Include built-in manifests for runfusion and code-server

- Harden web Dockerfile with unprivileged nginx and port 8080

- Add tool manifest specification documentation and architecture updates

Fusion-Task-Id: FN-003
2026-05-14 09:15:22 +02:00

94 lines
2.6 KiB
Python

"""Tests for the FastAPI tool manifest router."""
from __future__ import annotations
import pytest
from fastapi.testclient import TestClient
from app.main import app
from app.tools.registry import registry
client = TestClient(app)
@pytest.fixture(autouse=True)
def _reset_registry() -> None:
registry._manifests.clear()
registry.load_builtin_manifests()
# ---------------------------------------------------------------------------
# GET /api/v1/tools
# ---------------------------------------------------------------------------
def test_list_tools_includes_builtins() -> None:
response = client.get("/api/v1/tools")
assert response.status_code == 200
data = response.json()
ids = {item["id"] for item in data}
assert "runfusion" in ids
assert "code-server" in ids
# ---------------------------------------------------------------------------
# GET /api/v1/tools/{tool_id}
# ---------------------------------------------------------------------------
def test_get_tool_runfusion() -> None:
response = client.get("/api/v1/tools/runfusion")
assert response.status_code == 200
data = response.json()
assert data["id"] == "runfusion"
assert data["name"] == "RunFusion"
def test_get_tool_not_found() -> None:
response = client.get("/api/v1/tools/nonexistent")
assert response.status_code == 404
# ---------------------------------------------------------------------------
# POST /api/v1/tools
# ---------------------------------------------------------------------------
def test_create_tool_success() -> None:
payload = {
"id": "new-tool",
"name": "New Tool",
"image": "new-tool:latest",
"ports": [{"container_port": 3000, "primary": True}],
"traefik": {"enabled": False},
}
response = client.post("/api/v1/tools", json=payload)
assert response.status_code == 201
data = response.json()
assert data["id"] == "new-tool"
assert data["name"] == "New Tool"
def test_create_tool_duplicate() -> None:
payload = {
"id": "runfusion",
"name": "Duplicate",
"image": "dup:latest",
"ports": [{"container_port": 3000, "primary": True}],
"traefik": {"enabled": False},
}
response = client.post("/api/v1/tools", json=payload)
assert response.status_code == 409
def test_create_tool_invalid_id() -> None:
payload = {
"id": "Bad ID",
"name": "Bad Tool",
"image": "bad:latest",
"ports": [{"container_port": 3000, "primary": True}],
"traefik": {"enabled": False},
}
response = client.post("/api/v1/tools", json=payload)
assert response.status_code == 422