"""Unit tests for constants helpers (defensive config / auth headers).""" import constants def test_service_headers_empty_when_no_key(monkeypatch): monkeypatch.setattr(constants, "API_SHARED_KEY", "") assert constants.service_headers() == {} def test_service_headers_with_key(monkeypatch): monkeypatch.setattr(constants, "API_SHARED_KEY", "s3cr3t") assert constants.service_headers() == {"X-Conjurer-Api-Key": "s3cr3t"} def test_load_json_missing_returns_fallback(tmp_path): missing = tmp_path / "nope.json" assert constants._load_json(str(missing), {"fallback": 1}) == {"fallback": 1} def test_load_json_valid(tmp_path): good = tmp_path / "ok.json" good.write_text('{"a": 2}', encoding="utf-8") assert constants._load_json(str(good), {}) == {"a": 2} def test_load_json_corrupt_returns_fallback(tmp_path): bad = tmp_path / "bad.json" bad.write_text("{ not valid json", encoding="utf-8") assert constants._load_json(str(bad), []) == [] def test_conan_defaults_present(): # Feature toggles default to "off" so the bridge stays dormant. assert constants.CONAN_JOIN_CHANNEL_ID == 0 assert constants.CONAN_RCON_HOST == "" def test_ai_configs_expose_gpt_and_claude_backends(): cfgs = constants.AI_CONFIGS assert cfgs["gpt"]["provider"] == "openai" assert cfgs["claude"]["provider"] == "anthropic" # Claude carries a max_tokens (Anthropic requires it) and omits temperature # (Opus 4.8 / Sonnet 5 reject sampling params). assert "max_tokens" in cfgs["claude"] assert "temperature" not in cfgs["claude"] def test_default_ai_config_is_a_known_config(): # The single startup switch must always resolve to a real, selectable config. assert constants.DEFAULT_AI_CONFIG in constants.AI_CONFIGS