1f784b552d
- Fix validation error handler to serialize ValueError objects safely
- Add GET /config-folders/{id} endpoint (was missing)
- Fix project overrides API to accept project_id in body instead of query param
- Add flag_modified for SQLAlchemy JSONB change detection
- Fix DELETE endpoint to return 204 status code
- Fix conftest.py to use single SQLite engine per test
- Install aiosqlite dependency
- Fix frontend ToolWorkshopPage tests button names
Config folders tests: 13/13 passing
Docker build tests: 10/10 passing
Readiness probe tests: 13/13 passing
257 lines
9.6 KiB
Python
257 lines
9.6 KiB
Python
import uuid
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestToolConfigsAPIExtended:
|
|
"""Integration tests for tool configs API with new fields."""
|
|
|
|
def test_create_tool_config_with_new_fields(self, authenticated_client: TestClient) -> None:
|
|
"""Test creating a tool config with all new fields."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "config-test-tool",
|
|
"display_name": "Config Test Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Create config with new fields
|
|
response = authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "ADVANCED_CONFIG",
|
|
"value": "test-value",
|
|
"config_type": "env",
|
|
"port_override": 9090,
|
|
"start_command": "python app.py",
|
|
"working_directory": "/app",
|
|
"environment_variables": {"DEBUG": "true", "LOG_LEVEL": "debug"},
|
|
"volumes": [
|
|
{"source": "data", "target": "/data", "type": "bind"}
|
|
],
|
|
},
|
|
)
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["key"] == "ADVANCED_CONFIG"
|
|
assert data["port_override"] == 9090
|
|
assert data["start_command"] == "python app.py"
|
|
assert data["working_directory"] == "/app"
|
|
assert data["environment_variables"] == {"DEBUG": "true", "LOG_LEVEL": "debug"}
|
|
assert data["volumes"] == [{"source": "data", "target": "/data", "type": "bind"}]
|
|
|
|
def test_create_tool_config_invalid_port(self, authenticated_client: TestClient) -> None:
|
|
"""Test that invalid port numbers are rejected."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "port-test-tool",
|
|
"display_name": "Port Test Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Try to create config with invalid port
|
|
response = authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "BAD_PORT",
|
|
"value": "test",
|
|
"config_type": "env",
|
|
"port_override": 99999,
|
|
},
|
|
)
|
|
assert response.status_code == 422
|
|
|
|
def test_create_tool_config_invalid_volume_structure(self, authenticated_client: TestClient) -> None:
|
|
"""Test that invalid volume structures are rejected."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "volume-test-tool",
|
|
"display_name": "Volume Test Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Try to create config with invalid volume
|
|
response = authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "BAD_VOLUME",
|
|
"value": "test",
|
|
"config_type": "env",
|
|
"volumes": [{"invalid": "structure"}],
|
|
},
|
|
)
|
|
assert response.status_code == 422
|
|
|
|
def test_update_tool_config_with_new_fields(self, authenticated_client: TestClient) -> None:
|
|
"""Test updating a tool config with new fields."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "update-config-tool",
|
|
"display_name": "Update Config Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Create config
|
|
create_response = authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "UPDATE_TEST",
|
|
"value": "original",
|
|
"config_type": "env",
|
|
},
|
|
)
|
|
config_id = create_response.json()["id"]
|
|
|
|
# Update with new fields
|
|
response = authenticated_client.put(
|
|
f"/tool-configs/{config_id}",
|
|
json={
|
|
"value": "updated",
|
|
"port_override": 3000,
|
|
"start_command": "npm start",
|
|
"working_directory": "/workspace",
|
|
"environment_variables": {"NODE_ENV": "production"},
|
|
"volumes": [{"source": "src", "target": "/app/src", "type": "bind"}],
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["value"] == "updated"
|
|
assert data["port_override"] == 3000
|
|
assert data["start_command"] == "npm start"
|
|
assert data["working_directory"] == "/workspace"
|
|
assert data["environment_variables"] == {"NODE_ENV": "production"}
|
|
|
|
def test_list_tool_configs_returns_new_fields(self, authenticated_client: TestClient) -> None:
|
|
"""Test that listing configs returns new fields."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "list-config-tool",
|
|
"display_name": "List Config Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Create config with new fields
|
|
authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "LIST_TEST",
|
|
"value": "test",
|
|
"config_type": "env",
|
|
"port_override": 5000,
|
|
"environment_variables": {"TEST": "true"},
|
|
},
|
|
)
|
|
|
|
# List configs
|
|
response = authenticated_client.get("/tool-configs")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert len(data) > 0
|
|
config = data[0]
|
|
assert "port_override" in config
|
|
assert "start_command" in config
|
|
assert "working_directory" in config
|
|
assert "environment_variables" in config
|
|
assert "volumes" in config
|
|
|
|
def test_get_tool_config_defaults(self, authenticated_client: TestClient) -> None:
|
|
"""Test getting tool config defaults."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "defaults-tool",
|
|
"display_name": "Defaults Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": ["REPO_PATH"],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Get defaults
|
|
response = authenticated_client.get(f"/tool-configs/defaults/{tool_id}")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["tool_type_id"] == tool_id
|
|
assert "suggested_configs" in data
|
|
|
|
def test_tool_config_backward_compatibility(self, authenticated_client: TestClient) -> None:
|
|
"""Test that old configs without new fields still work."""
|
|
# Create a tool type first
|
|
tool_response = authenticated_client.post(
|
|
"/tool-types",
|
|
json={
|
|
"name": "backward-compat-tool",
|
|
"display_name": "Backward Compat Tool",
|
|
"default_port": 8080,
|
|
"definition_type": "compose",
|
|
"compose_template": "version: '3.8'\nservices:\n app:\n image: nginx",
|
|
"required_variables": [],
|
|
},
|
|
)
|
|
tool_id = tool_response.json()["id"]
|
|
|
|
# Create config without new fields (simulating old client)
|
|
response = authenticated_client.post(
|
|
"/tool-configs",
|
|
json={
|
|
"tool_type_id": tool_id,
|
|
"key": "OLD_STYLE",
|
|
"value": "value",
|
|
"config_type": "env",
|
|
},
|
|
)
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["key"] == "OLD_STYLE"
|
|
# New fields should have default values
|
|
assert data["port_override"] is None
|
|
assert data["start_command"] is None
|
|
assert data["working_directory"] is None
|
|
assert data["environment_variables"] == {}
|
|
assert data["volumes"] == []
|