"""CER-P5-010 env validation tests.""" from __future__ import annotations import pytest from option_mcp_common.env_validation import ( MissingEnvError, fail_fast_if_missing, optional_env, require_env, summarize, ) def test_require_env_present(monkeypatch): monkeypatch.setenv("FOO_KEY", "value1") assert require_env("FOO_KEY") == "value1" def test_require_env_missing_raises(monkeypatch): monkeypatch.delenv("MISSING_REQ", raising=False) with pytest.raises(MissingEnvError): require_env("MISSING_REQ", "critical path") def test_require_env_empty_raises(monkeypatch): monkeypatch.setenv("EMPTY_REQ", "") with pytest.raises(MissingEnvError): require_env("EMPTY_REQ") def test_require_env_whitespace_only_raises(monkeypatch): monkeypatch.setenv("WS_REQ", " ") with pytest.raises(MissingEnvError): require_env("WS_REQ") def test_optional_env_default(monkeypatch): monkeypatch.delenv("OPT_A", raising=False) assert optional_env("OPT_A", default="fallback") == "fallback" def test_optional_env_set(monkeypatch): monkeypatch.setenv("OPT_B", "xx") assert optional_env("OPT_B", default="fallback") == "xx" def test_fail_fast_all_present(monkeypatch): monkeypatch.setenv("AA", "1") monkeypatch.setenv("BB", "2") fail_fast_if_missing(["AA", "BB"]) # no exit def test_fail_fast_missing_exits(monkeypatch): monkeypatch.setenv("HAVE_IT", "1") monkeypatch.delenv("MISSING_X", raising=False) with pytest.raises(SystemExit) as exc: fail_fast_if_missing(["HAVE_IT", "MISSING_X"]) assert exc.value.code == 2 def test_summarize_does_not_leak_secrets(monkeypatch, caplog): import logging monkeypatch.setenv("API_KEY_FOO", "super-secret-token-123456") monkeypatch.setenv("PORT", "9000") with caplog.at_level(logging.INFO, logger="option_mcp_common.env_validation"): summarize(["API_KEY_FOO", "PORT", "NOT_SET_XYZ"]) log_text = "\n".join(caplog.messages) assert "super-secret-token-123456" not in log_text assert "9000" in log_text assert "" in log_text