# #region Test.Api.Settings [C:3] [TYPE Module] [SEMANTICS test,settings,routes]
# @BRIEF Tests for settings API routes — get, update, storage, environments, logging, connections, policies, schedules.
# @RELATION BINDS_TO -> [SettingsRouter]

import os

os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-tests")
os.environ.setdefault("DEV_MODE", "true")

import sys
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

_src = str(Path(__file__).resolve().parent.parent.parent / "src")
if _src not in sys.path:
    sys.path.insert(0, _src)


def _make_env(id_val="env-1", name="Test Env", url="https://example.com"):
    env = MagicMock()
    env.id = id_val
    env.name = name
    env.url = url
    env.password = "real-password"
    return env


def _make_client(overrides: dict | None = None) -> TestClient:
    from src.api.routes.settings import router
    from src.core.database import get_db
    from src.dependencies import get_config_manager, get_current_user
    from src.schemas.auth import User, RoleSchema

    app = FastAPI()
    app.include_router(router, prefix="/api/settings")

    mock_user = User(
        id="admin-1", username="admin", email="admin@x.com",
        auth_source="LOCAL",
        created_at=__import__("datetime").datetime.now(),
        roles=[RoleSchema(id="r1", name="Admin", description="", permissions=[])],
    )

    app.dependency_overrides[get_db] = lambda: MagicMock()
    app.dependency_overrides[get_current_user] = lambda: mock_user
    app.dependency_overrides[get_config_manager] = lambda: MagicMock()
    if overrides:
        for dep, fn in overrides.items():
            app.dependency_overrides[dep] = fn
    return TestClient(app)


# ── get_settings ──

def _make_real_config(environments=None):
    """Build a real AppConfig with default settings for mock testing."""
    from src.core.config_models import (
        AppConfig, GlobalSettings, StorageConfig, LoggingConfig, CleanReleaseConfig,
    )
    gs = GlobalSettings(
        storage=StorageConfig(
            root_path="/tmp/storage",
            backup_path="/tmp/backup",
            repo_path="/tmp/repo",
            backup_structure_pattern="{env_id}/{backup_id}",
            repo_structure_pattern="{env_id}/{repo_id}",
            filename_pattern="{name}_{timestamp}",
        ),
        logging=LoggingConfig(
            level="INFO",
            task_log_level="DEBUG",
            file_path="/tmp/log.log",
            enable_belief_state=True,
        ),
        clean_release=CleanReleaseConfig(
            active_policy_id="",
            active_registry_id="",
        ),
        default_environment_id="",
        migration_sync_cron="0 0 * * *",
        app_timezone="UTC",
    )
    return AppConfig(settings=gs, environments=environments or [])


class TestGetSettings:
    """GET /settings"""

    def test_success(self):
        mock_config = MagicMock()
        mock_config.get_config.return_value = _make_real_config()

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings")
        assert resp.status_code == 200

    def test_password_masked(self):
        from src.core.config_models import Environment
        env = Environment(
            id="env-1", name="Test Env", url="https://example.com",
            username="admin", password="real-password", stage="DEV",
        )
        real_config = _make_real_config(environments=[env])

        mock_config = MagicMock()
        mock_config.get_config.return_value = real_config

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings")
        assert resp.status_code == 200
        data = resp.json()
        masked_env = data["environments"][0]
        assert masked_env["password"] == "********"


class TestGetFeatures:
    """GET /api/settings/features"""

    def test_success(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings.features.model_dump.return_value = {"translate": True, "migration": False}
        mock_config.get_config.return_value = mock_cfg

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings/features")
        assert resp.status_code == 200
        assert resp.json()["translate"] is True


# ── get_allowed_languages ──

class TestGetAllowedLanguages:
    """GET /settings/allowed-languages"""

    def test_success(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings.allowed_languages = ["en", "ru"]
        mock_config.get_config.return_value = mock_cfg

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings/allowed-languages")
        assert resp.status_code == 200
        assert resp.json() == ["en", "ru"]


# ── update_global_settings ──

class TestUpdateGlobalSettings:
    """PATCH /settings/global"""

    def test_success(self):
        mock_config = MagicMock()

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.patch("/api/settings/global", json={"app_name": "Test", "log_level": "INFO"})
        assert resp.status_code == 200


# ── get_storage_settings ──

class TestGetStorageSettings:
    """GET /settings/storage"""

    def test_success(self):
        from src.core.config_models import StorageConfig
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings.storage = StorageConfig(
            root_path="/tmp/storage",
            backup_path="/tmp/backup",
            repo_path="/tmp/repo",
            backup_structure_pattern="{env_id}/{backup_id}",
            repo_structure_pattern="{env_id}/{repo_id}",
            filename_pattern="{name}_{timestamp}",
        )
        mock_config.get_config.return_value = mock_cfg

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings/storage")
        assert resp.status_code == 200


# ── update_storage_settings ──

class TestUpdateStorageSettings:
    """PUT /settings/storage"""

    def test_success(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings = MagicMock()
        mock_cfg.settings.storage = MagicMock()
        mock_config.get_config.return_value = mock_cfg
        mock_config.validate_path.return_value = (True, "")

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.put("/api/settings/storage", json={
            "root_path": "/data/storage",
            "max_file_size_mb": 100,
            "allowed_extensions": [".txt"],
            "backup_retention_days": 30,
        })
        assert resp.status_code == 200

    def test_invalid_path(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings = MagicMock()
        mock_config.get_config.return_value = mock_cfg
        mock_config.validate_path.return_value = (False, "Path is invalid")

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.put("/api/settings/storage", json={
            "root_path": "/invalid",
            "max_file_size_mb": 100,
            "allowed_extensions": [],
            "backup_retention_days": 30,
        })
        assert resp.status_code == 400


# ── get_environments ──

class TestGetEnvironments:
    """GET /settings/environments"""

    def test_success(self):
        from src.core.config_models import Environment
        mock_config = MagicMock()
        real_env = Environment(
            id="env-1", name="Test Env", url="https://example.com",
            username="admin", password="secret", stage="DEV",
        )
        mock_config.get_environments.return_value = [real_env]

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings/environments")
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) == 1
        assert data[0]["id"] == "env-1"


# ── add_environment ──

class TestAddEnvironment:
    """POST /settings/environments"""

    ENV_PAYLOAD = {
        "id": "env-new",
        "name": "New Env",
        "url": "https://superset.example.com",
        "username": "admin",
        "password": "secret",
        "stage": "DEV",
    }

    def test_success(self):
        mock_config = MagicMock()

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock()
            mock_client.get_dashboards_page = AsyncMock(return_value=(0, []))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.post("/api/settings/environments", json=self.ENV_PAYLOAD)
        assert resp.status_code == 200
        mock_config.add_environment.assert_called_once()

    def test_connection_failure(self):
        mock_config = MagicMock()

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock(side_effect=RuntimeError("Connection refused"))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.post("/api/settings/environments", json=self.ENV_PAYLOAD)
        assert resp.status_code == 400


# ── update_environment ──

class TestUpdateEnvironment:
    """PUT /settings/environments/{id}"""

    ENV_PAYLOAD = {
        "id": "env-1",
        "name": "Updated Env",
        "url": "https://superset.example.com",
        "username": "admin",
        "password": "new-password",
        "stage": "DEV",
    }

    def test_success(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = [_make_env("env-1")]
        mock_config.update_environment.return_value = True

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock()
            mock_client.get_dashboards_page = AsyncMock(return_value=(0, []))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.put("/api/settings/environments/env-1", json=self.ENV_PAYLOAD)
        assert resp.status_code == 200

    def test_success_masked_password(self):
        """When password is '********', use the existing password for validation."""
        mock_config = MagicMock()
        old_env = _make_env("env-1")
        old_env.password = "existing-real-pwd"
        mock_config.get_environments.return_value = [old_env]
        mock_config.update_environment.return_value = True

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock()
            mock_client.get_dashboards_page = AsyncMock(return_value=(0, []))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.put("/api/settings/environments/env-1", json={
                "id": "env-1", "name": "Updated", "url": "https://x.com",
                "username": "admin", "password": "********", "stage": "DEV",
            })
        assert resp.status_code == 200

    def test_connection_failure(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = [_make_env("env-1")]

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock(side_effect=RuntimeError("fail"))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.put("/api/settings/environments/env-1", json=self.ENV_PAYLOAD)
        assert resp.status_code == 400

    def test_not_found(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = [_make_env("env-1")]
        mock_config.update_environment.return_value = False

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock()
            mock_client.get_dashboards_page = AsyncMock(return_value=(0, []))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.put("/api/settings/environments/env-999", json=self.ENV_PAYLOAD)
        assert resp.status_code == 404


# ── delete_environment ──

class TestDeleteEnvironment:
    """DELETE /settings/environments/{id}"""

    def test_success(self):
        mock_config = MagicMock()

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.delete("/api/settings/environments/env-1")
        assert resp.status_code == 200
        data = resp.json()
        assert "deleted" in data["message"]
        mock_config.delete_environment.assert_called_once_with("env-1")


# ── test_environment_connection ──

class TestTestEnvironmentConnection:
    """POST /settings/environments/{id}/test"""

    def test_success(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = [_make_env("env-1")]

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock()
            mock_client.get_dashboards_page = AsyncMock(return_value=(0, []))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.post("/api/settings/environments/env-1/test")
        assert resp.status_code == 200
        assert resp.json()["status"] == "success"

    def test_not_found(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = []

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.post("/api/settings/environments/env-unknown/test")
        assert resp.status_code == 404

    def test_connection_error(self):
        mock_config = MagicMock()
        mock_config.get_environments.return_value = [_make_env("env-1")]

        with patch("src.api.routes.settings.AsyncSupersetClient") as mock_client_cls:
            mock_client = MagicMock()
            mock_client.authenticate = AsyncMock(side_effect=RuntimeError("Connection failed"))
            mock_client_cls.return_value = mock_client

            from src.dependencies import get_config_manager
            client = _make_client({get_config_manager: lambda: mock_config})
            resp = client.post("/api/settings/environments/env-1/test")
        assert resp.status_code == 200
        assert resp.json()["status"] == "error"


# ── get_logging_config ──

class TestGetLoggingConfig:
    """GET /settings/logging"""

    def test_success(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_logging = MagicMock()
        mock_logging.level = "INFO"
        mock_logging.task_log_level = "DEBUG"
        mock_logging.enable_belief_state = True
        mock_cfg.settings.logging = mock_logging
        mock_config.get_config.return_value = mock_cfg

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.get("/api/settings/logging")
        assert resp.status_code == 200
        data = resp.json()
        assert data["level"] == "INFO"
        assert data["task_log_level"] == "DEBUG"
        assert data["enable_belief_state"] is True


# ── update_logging_config ──

class TestUpdateLoggingConfig:
    """PATCH /settings/logging"""

    def test_success(self):
        mock_config = MagicMock()
        mock_cfg = MagicMock()
        mock_cfg.settings = MagicMock()
        mock_config.get_config.return_value = mock_cfg

        from src.dependencies import get_config_manager
        client = _make_client({get_config_manager: lambda: mock_config})
        resp = client.patch("/api/settings/logging", json={
            "level": "WARNING", "task_log_level": "INFO", "enable_belief_state": False,
        })
        assert resp.status_code == 200
        data = resp.json()
        assert data["level"] == "WARNING"
        assert data["task_log_level"] == "INFO"


# ── get_validation_policies ──

class TestGetValidationPolicies:
    """GET /settings/automation/policies"""

    def test_success(self):
        from datetime import time, datetime, timezone
        from src.models.llm import ValidationPolicy

        mock_db = MagicMock()
        mock_db.query.return_value.all.return_value = [
            ValidationPolicy(
                id="p1",
                name="Test Policy",
                environment_id="env-1",
                is_active=True,
                notify_owners=True,
                alert_condition="FAIL_ONLY",
                dashboard_ids=["d1"],
                schedule_days=[1, 3, 5],
                window_start=time(9, 0),
                window_end=time(18, 0),
                created_at=datetime.now(timezone.utc),
                updated_at=datetime.now(timezone.utc),
            )
        ]

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.get("/api/settings/automation/policies")
        assert resp.status_code == 200


# ── create_validation_policy ──

class TestCreateValidationPolicy:
    """POST /settings/automation/policies"""

    def test_success(self):
        from datetime import datetime, timezone

        mock_db = MagicMock()
        now = datetime.now(timezone.utc)

        # Simulate that db.refresh populates auto-generated fields (id, created_at, updated_at)
        def _refresh(obj):
            obj.id = getattr(obj, "id", None) or "new-id"
            if getattr(obj, "created_at", None) is None:
                obj.created_at = now
            if getattr(obj, "updated_at", None) is None:
                obj.updated_at = now

        mock_db.refresh.side_effect = _refresh

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.post("/api/settings/automation/policies", json={
            "name": "Test Policy", "environment_id": "env-1", "dashboard_ids": [],
            "schedule_days": [1, 3, 5], "window_start": "09:00", "window_end": "18:00",
        })
        assert resp.status_code == 200
        mock_db.add.assert_called_once()
        mock_db.commit.assert_called_once()


# ── update_validation_policy ──

class TestUpdateValidationPolicy:
    """PATCH /settings/automation/policies/{id}"""

    def test_success(self):
        from datetime import time, datetime, timezone
        from src.models.llm import ValidationPolicy

        mock_db = MagicMock()
        mock_policy = ValidationPolicy(
            id="p1", name="Test", environment_id="env-1",
            is_active=True, notify_owners=True, alert_condition="FAIL_ONLY",
            dashboard_ids=[], schedule_days=[1],
            window_start=time(9, 0), window_end=time(18, 0),
            created_at=datetime.now(timezone.utc),
            updated_at=datetime.now(timezone.utc),
        )
        mock_db.query.return_value.filter.return_value.first.return_value = mock_policy

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.patch("/api/settings/automation/policies/p1", json={"name": "Updated"})
        assert resp.status_code == 200
        mock_db.commit.assert_called_once()

    def test_not_found(self):
        mock_db = MagicMock()
        mock_db.query.return_value.filter.return_value.first.return_value = None

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.patch("/api/settings/automation/policies/unknown", json={"name": "X"})
        assert resp.status_code == 404


# ── delete_validation_policy ──

class TestDeleteValidationPolicy:
    """DELETE /settings/automation/policies/{id}"""

    def test_success(self):
        mock_db = MagicMock()
        mock_policy = MagicMock()
        mock_db.query.return_value.filter.return_value.first.return_value = mock_policy

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.delete("/api/settings/automation/policies/p1")
        assert resp.status_code == 200
        mock_db.delete.assert_called_once()
        mock_db.commit.assert_called_once()

    def test_not_found(self):
        mock_db = MagicMock()
        mock_db.query.return_value.filter.return_value.first.return_value = None

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.delete("/api/settings/automation/policies/unknown")
        assert resp.status_code == 404


# ── get_translation_schedules ──

class TestGetTranslationSchedules:
    """GET /settings/automation/translation-schedules"""

    def test_success(self):
        mock_db = MagicMock()
        mock_ts = MagicMock()
        mock_ts.id = "sched-1"
        mock_ts.job_id = "job-1"
        mock_ts.cron_expression = "0 * * * *"
        mock_ts.timezone = "UTC"
        mock_ts.is_active = True
        mock_ts.last_run_at = None
        mock_ts.next_run_at = None
        mock_ts.created_by = "admin"
        mock_ts.created_at = None
        mock_db.query.return_value.outerjoin.return_value.all.return_value = [(mock_ts, "Test Job")]

        from src.core.database import get_db
        client = _make_client({get_db: lambda: mock_db})
        resp = client.get("/api/settings/automation/translation-schedules")
        assert resp.status_code == 200
        data = resp.json()
        assert len(data) == 1
        assert data[0]["schedule_id"] == "sched-1"
        assert data[0]["job_name"] == "Test Job"


# ── list_connections ──

class TestListConnections:
    """GET /settings/connections"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.list_connections.return_value = [{"id": "conn-1", "name": "Test"}]

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.get("/api/settings/connections")
        assert resp.status_code == 200


# ── get_connection ──

class TestGetConnection:
    """GET /settings/connections/{connection_id}"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn = MagicMock()
        mock_conn.model_dump.return_value = {"id": "conn-1", "name": "Test", "password": "real-pwd"}
        mock_conn_svc.get_connection.return_value = mock_conn
        mock_conn_svc._count_job_references.return_value = 2

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.get("/api/settings/connections/conn-1")
        assert resp.status_code == 200
        data = resp.json()
        assert data["password"] == "********"
        assert data["used_by"] == 2

    def test_not_found(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.get_connection.return_value = None

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.get("/api/settings/connections/unknown")
        assert resp.status_code == 404


# ── create_connection ──

class TestCreateConnection:
    """POST /settings/connections"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.create_connection.return_value = {"id": "conn-new", "name": "New"}

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.post("/api/settings/connections", json={
            "name": "New", "host": "localhost", "port": 5432,
            "database": "db", "username": "u", "password": "p", "dialect": "postgresql",
        })
        assert resp.status_code == 201

    def test_value_error(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.create_connection.side_effect = ValueError("Invalid")

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.post("/api/settings/connections", json={"name": "Bad"})
        assert resp.status_code == 422


# ── update_connection ──

class TestUpdateConnection:
    """PUT /settings/connections/{connection_id}"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.update_connection.return_value = {"id": "conn-1", "name": "Updated"}

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.put("/api/settings/connections/conn-1", json={"name": "Updated"})
        assert resp.status_code == 200

    def test_value_error(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.update_connection.side_effect = ValueError("Invalid")

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.put("/api/settings/connections/conn-1", json={"name": ""})
        assert resp.status_code == 422


# ── delete_connection ──

class TestDeleteConnection:
    """DELETE /settings/connections/{connection_id}"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.delete_connection.return_value = {"success": True}

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.delete("/api/settings/connections/conn-1")
        assert resp.status_code == 200

    def test_in_use(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.delete_connection.return_value = {
            "success": False, "blocking_jobs": ["job-1"],
        }

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.delete("/api/settings/connections/conn-1")
        assert resp.status_code == 409


# ── test_connection_endpoint ──

class TestTestConnectionEndpoint:
    """POST /settings/connections/{connection_id}/test"""

    def test_success(self):
        mock_conn_svc = MagicMock()
        mock_conn_svc.test_connection = AsyncMock(return_value={"success": True})

        from src.api.routes.settings import _get_connection_service
        from src.dependencies import get_config_manager
        client = _make_client({
            get_config_manager: lambda: MagicMock(),
            _get_connection_service: lambda: mock_conn_svc,
        })
        resp = client.post("/api/settings/connections/conn-1/test")
        assert resp.status_code == 200
# #endregion Test.Api.Settings
