import pytest from datetime import datetime, timedelta, timezone from unittest.mock import AsyncMock, patch from app.core.config import parse_env_bool, settings from app.models.terminal_session import TerminalSession, SESSION_STATUS_ACTIVE class TestParseEnvBool: def test_parse_env_bool(self): assert parse_env_bool("YES") is True assert parse_env_bool("yes") is True assert parse_env_bool("TRUE") is True assert parse_env_bool("1") is True assert parse_env_bool("NO") is False assert parse_env_bool("no") is False assert parse_env_bool("FALSE") is False assert parse_env_bool("0") is False assert parse_env_bool("invalid") is False assert parse_env_bool(None) is False assert parse_env_bool(None, default=True) is True class TestDebugModeApi: @pytest.mark.asyncio async def test_config_endpoint_reflects_debug_mode(self, client, monkeypatch): monkeypatch.setattr(settings, "debug_mode", False) resp = await client.get("/api/config") assert resp.status_code == 200 assert resp.json() == {"debug_mode": False} @pytest.mark.asyncio async def test_terminal_status_reports_disabled(self, client, auth_headers, monkeypatch): monkeypatch.setattr(settings, "debug_mode", False) with patch("app.services.terminal_service.terminal_service.check_ttyd_available", return_value=True): resp = await client.get("/api/terminal/status", headers=auth_headers) assert resp.status_code == 200 data = resp.json() assert data["available"] is True assert data["debug_mode"] is False @pytest.mark.asyncio async def test_terminal_connect_allowed_when_debug_disabled(self, client, db_session, monkeypatch): monkeypatch.setattr(settings, "debug_mode", False) now = datetime.now(timezone.utc) sess = TerminalSession( id="s" * 64, host_id="host-1", host_name="test-host", host_ip="127.0.0.1", user_id="user-1", username="testuser", token_hash="x" * 64, ttyd_port=7680, ttyd_pid=123, mode="embedded", status=SESSION_STATUS_ACTIVE, created_at=now, last_seen_at=now, expires_at=now + timedelta(minutes=10), ) db_session.add(sess) await db_session.commit() with patch("app.services.terminal_service.terminal_service.verify_token", return_value=True), \ patch("app.services.terminal_service.terminal_service.is_session_process_alive", new=AsyncMock(return_value=True)): resp = await client.get(f"/api/terminal/connect/{sess.id}?token=dummy") assert resp.status_code == 200 @pytest.mark.asyncio async def test_terminal_probe_forbidden_when_debug_disabled(self, client, db_session, monkeypatch): monkeypatch.setattr(settings, "debug_mode", False) now = datetime.now(timezone.utc) sess = TerminalSession( id="t" * 64, host_id="host-1", host_name="test-host", host_ip="127.0.0.1", user_id="user-1", username="testuser", token_hash="x" * 64, ttyd_port=7681, ttyd_pid=123, mode="embedded", status=SESSION_STATUS_ACTIVE, created_at=now, last_seen_at=now, expires_at=now + timedelta(minutes=10), ) db_session.add(sess) await db_session.commit() with patch("app.services.terminal_service.terminal_service.verify_token", return_value=True): resp = await client.get(f"/api/terminal/sessions/{sess.id}/probe?token=dummy") assert resp.status_code == 403 assert resp.json()["detail"] == "Debug mode disabled"