fix: resolve stale backend test imports and schema drift

- Delete 4 obsolete unit tests tied to removed git mount/clone models
- Update imports and assertions across unit/integration/service tests
- Fix Settings defaults (postgres host, JWT props, cookie_samesite)
- Add skip guards for PostgreSQL-dependent integration tests
- Fix GitService env assertions and HealthMonitor state-change tests
- Repair docker/container inspect assertions in test_docker_service
- Fix ToolTypeCreate default_port validator ordering bug
- Fix check_port_exposed substring false-positive for port 0
- Update test_tool_types_api_extended to use interface_type field

Quality gates: pytest 311 passed, 34 skipped; npm typecheck/lint/test 87 passed
This commit is contained in:
Developer
2026-06-12 20:23:17 +00:00
parent 79be4eb525
commit 81b9a66ef5
35 changed files with 268 additions and 625 deletions
@@ -9,14 +9,14 @@ import pytest_asyncio
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from src.models.git_repository import GitRepository
from src.models.notification import Notification
from src.models.project import Project
from src.models.tool_instance import ToolInstance
from src.models.tool_type import ToolType
from src.models.user import User
from src.services.event_bus import InstanceEventBus, InstanceEventPayload
from src.services.health_monitor import HealthSnapshot
from src.models.project.git_repository import GitRepository
from src.models.system.notification import Notification
from src.models.project.project import Project
from src.models.tool.tool_instance import ToolInstance
from src.models.tool.tool_type import ToolType
from src.models.user.user import User
from src.services.instance.event_bus import InstanceEventBus, InstanceEventPayload
from src.services.instance.health_monitor import HealthSnapshot
@pytest.fixture
@@ -78,6 +78,7 @@ async def test_instance(db_session: AsyncSession) -> ToolInstance:
project_id=project.id,
owner_id=user.id,
status="running",
container_id="container123",
compose_path="/tmp/test-compose.yml",
port=8080,
)
@@ -101,7 +102,7 @@ async def test_lifecycle_started_intermediate_skips_notification(
event_bus.subscribe("instance.started", subscriber)
from src.services.lifecycle_hooks import publish_lifecycle_event
from src.services.instance.lifecycle_hooks import publish_lifecycle_event
await publish_lifecycle_event(
event_bus=event_bus,
@@ -131,7 +132,7 @@ async def test_lifecycle_running_creates_notification(
test_instance: ToolInstance,
) -> None:
"""Successful terminal state (running) creates a notification."""
from src.services.lifecycle_hooks import publish_lifecycle_event
from src.services.instance.lifecycle_hooks import publish_lifecycle_event
await publish_lifecycle_event(
event_bus=event_bus,
@@ -162,10 +163,17 @@ async def test_health_monitor_error_creates_notification(
event_bus: InstanceEventBus,
test_instance: ToolInstance,
) -> None:
"""Simulating a health monitor crash creates an error notification."""
from src.services.health_monitor import HealthMonitor
"""Simulating a container exit creates an error notification."""
from src.services.instance.health_monitor import HealthMonitor
monitor = HealthMonitor(event_bus)
# Seed a different healthy prior state so the exit is treated as a change.
monitor._last_known_state[test_instance.id] = HealthSnapshot(
container_status="running",
container_healthy=None,
tunnel_healthy=True,
exit_code=None,
)
received: list[InstanceEventPayload] = []
@@ -175,7 +183,7 @@ async def test_health_monitor_error_creates_notification(
event_bus.subscribe("instance.error", subscriber)
with patch(
"src.services.health_monitor.get_container_status",
"src.services.instance.health_monitor.get_container_status",
return_value={"status": "exited", "exit_code": 137, "health": None},
):
await monitor._check_instance(db_session, test_instance)
@@ -211,10 +219,10 @@ async def test_notification_failure_does_not_block_event_pipeline(
event_bus.subscribe("instance.started", subscriber)
from src.services.lifecycle_hooks import publish_lifecycle_event
from src.services.instance.lifecycle_hooks import publish_lifecycle_event
with patch(
"src.services.lifecycle_hooks.notification_service.create_notification",
"src.services.instance.lifecycle_hooks.notification_service.create_notification",
side_effect=RuntimeError("DB is down"),
):
# Should not raise
@@ -309,7 +317,7 @@ async def test_notification_ownership_matches_instance_owner(
db_session.add(instance)
await db_session.commit()
from src.services.lifecycle_hooks import publish_lifecycle_event
from src.services.instance.lifecycle_hooks import publish_lifecycle_event
await publish_lifecycle_event(
event_bus=event_bus,
@@ -336,7 +344,7 @@ async def test_lifecycle_error_creates_error_notification(
test_instance: ToolInstance,
) -> None:
"""An instance.error lifecycle event creates a severity=error notification."""
from src.services.lifecycle_hooks import publish_lifecycle_event
from src.services.instance.lifecycle_hooks import publish_lifecycle_event
await publish_lifecycle_event(
event_bus=event_bus,
@@ -363,7 +371,7 @@ async def test_health_monitor_unhealthy_creates_warning_notification(
test_instance: ToolInstance,
) -> None:
"""Health monitor marking instance unhealthy creates severity=warning notification."""
from src.services.health_monitor import HealthMonitor
from src.services.instance.health_monitor import HealthMonitor
monitor = HealthMonitor(event_bus)
monitor._last_known_state[test_instance.id] = HealthSnapshot(
@@ -376,11 +384,11 @@ async def test_health_monitor_unhealthy_creates_warning_notification(
with (
patch(
"src.services.health_monitor.get_container_status",
"src.services.instance.health_monitor.get_container_status",
return_value={"status": "running", "exit_code": None, "health": "healthy"},
),
patch(
"src.services.health_monitor.check_tunnel_health",
"src.services.instance.health_monitor.check_tunnel_health",
return_value={"healthy": False, "tunnel_status": "error_response"},
),
):