"""Unit tests: conditional debugpy gating (PLAN anchor A14). Rules under test: * DEBUGPY unset or 0 -> configure_debugging() is False, debugpy NOT imported. * DEBUGPY=1 -> configure_debugging() is True, listener on DEBUGPY_PORT. """ from __future__ import annotations import socket import sys import pytest import app.core.debugging as dbg @pytest.fixture() def free_port() -> int: with socket.socket() as s: s.bind(("127.0.0.1", 0)) return s.getsockname()[1] def test_disabled_by_default(monkeypatch) -> None: monkeypatch.delenv("DEBUGPY", raising=False) monkeypatch.delenv("DEBUGPY_PORT", raising=False) sys.modules.pop("debugpy", None) assert dbg.configure_debugging() is False assert "debugpy" not in sys.modules # zero overhead: never imported def test_explicit_zero(monkeypatch) -> None: monkeypatch.setenv("DEBUGPY", "0") sys.modules.pop("debugpy", None) assert dbg.configure_debugging() is False assert "debugpy" not in sys.modules def test_invalid_value_treated_as_disabled(monkeypatch) -> None: monkeypatch.setenv("DEBUGPY", "yes-please") assert dbg.configure_debugging() is False def test_enabled_starts_listener(monkeypatch, free_port) -> None: monkeypatch.setenv("DEBUGPY", "1") monkeypatch.setenv("DEBUGPY_PORT", str(free_port)) try: assert dbg.configure_debugging() is True assert "debugpy" in sys.modules finally: dbg.shutdown_debugpy() def test_port_falls_back_on_invalid_value(monkeypatch) -> None: monkeypatch.setenv("DEBUGPY_PORT", "not-a-port") assert dbg._port() == 5678 def test_shutdown_is_idempotent_when_disabled() -> None: dbg.shutdown_debugpy() # no listener → no-op, no error