"""Tests for sonarqube_mcp.settings."""
from __future__ import annotations
import logging
import pytest
from sonarqube_mcp.settings import (
DEFAULT_REQUEST_TIMEOUT_SEC,
DEFAULT_SONARQUBE_URL,
SonarQubeSettings,
_float_env,
load_settings,
)
class TestFloatEnv:
"""Tests for _float_env helper."""
def test_returns_default_when_unset(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("MY_FLOAT", raising=False)
assert _float_env("MY_FLOAT", 42.0) == 42.0
def test_returns_default_when_empty(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("MY_FLOAT", "")
assert _float_env("MY_FLOAT", 42.0) == 42.0
def test_parses_valid_float(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("MY_FLOAT", "3.14")
assert _float_env("MY_FLOAT", 0.0) == pytest.approx(3.14)
def test_warns_on_invalid_value(
self, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
) -> None:
monkeypatch.setenv("MY_FLOAT", "not_a_number")
with caplog.at_level(logging.WARNING, logger="sonarqube_mcp.settings"):
result = _float_env("MY_FLOAT", 99.0)
assert result == 99.0
assert "Invalid value" in caplog.text
assert "not_a_number" in caplog.text
class TestLoadSettings:
"""Tests for load_settings."""
def test_defaults(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("SONARQUBE_URL", raising=False)
monkeypatch.delenv("SONARQUBE_TOKEN", raising=False)
monkeypatch.delenv("SONARQUBE_REQUEST_TIMEOUT_SEC", raising=False)
s = load_settings()
assert s.sonarqube_url == DEFAULT_SONARQUBE_URL
assert s.sonarqube_token == ""
assert s.request_timeout_sec == DEFAULT_REQUEST_TIMEOUT_SEC
def test_custom_values(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("SONARQUBE_URL", "http://custom:9000/")
monkeypatch.setenv("SONARQUBE_TOKEN", "my_token")
monkeypatch.setenv("SONARQUBE_REQUEST_TIMEOUT_SEC", "10")
s = load_settings()
assert s.sonarqube_url == "http://custom:9000" # trailing slash stripped
assert s.sonarqube_token == "my_token"
assert s.request_timeout_sec == 10.0
def test_warns_when_token_missing(
self, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
) -> None:
monkeypatch.delenv("SONARQUBE_TOKEN", raising=False)
monkeypatch.delenv("SONARQUBE_URL", raising=False)
monkeypatch.delenv("SONARQUBE_REQUEST_TIMEOUT_SEC", raising=False)
with caplog.at_level(logging.WARNING, logger="sonarqube_mcp.settings"):
load_settings()
assert "SONARQUBE_TOKEN is not set" in caplog.text
def test_frozen(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("SONARQUBE_TOKEN", "tok")
s = load_settings()
with pytest.raises(AttributeError):
s.sonarqube_url = "http://other" # type: ignore[misc]