from __future__ import annotations import json import shutil from pathlib import Path from nexus_claude_api.cli import main from nexus_claude_api.config import ( Settings, load_local_config, load_user_config, write_user_config, ) from nexus_claude_api.shell import generate_claude_code_powershell def test_claude_code_command() -> None: settings = Settings.from_values( host="127.0.0.1", port=4141, api_key="test", require_api_key=False, ) command = generate_claude_code_powershell(settings) assert "ANTHROPIC_BASE_URL" in command assert "ANTHROPIC_AUTH_TOKEN='dummy'" in command assert "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY='1'" in command assert "claude-opus-4.6" in command assert command.endswith("claude --model claude-opus-4.6") def test_claude_code_command_uses_custom_model() -> None: settings = Settings.from_values( host="127.0.0.1", port=4141, api_key="test", model="claude-opus-4.6", require_api_key=False, ) command = generate_claude_code_powershell(settings) assert command.endswith("claude --model claude-opus-4.6") def test_missing_api_key_fails(monkeypatch) -> None: tmp_path = _workspace_tmp("missing-key") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) monkeypatch.delenv("NEXUS_API_KEY", raising=False) monkeypatch.delenv("AWS_BEARER_TOKEN_BEDROCK", raising=False) monkeypatch.chdir(tmp_path) try: exit_code = main(["start", "--dry-run"]) finally: monkeypatch.chdir(Path(__file__).parents[1]) shutil.rmtree(tmp_path, ignore_errors=True) assert exit_code == 2 def test_user_config_api_key(monkeypatch) -> None: tmp_path = _workspace_tmp("user-config") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) write_user_config({"api_key": "user-test-key"}) settings = Settings.from_values(require_api_key=False) assert settings.api_key == "user-test-key" assert load_user_config()["api_key"] == "user-test-key" shutil.rmtree(tmp_path, ignore_errors=True) def test_dev_local_config_api_key(monkeypatch) -> None: tmp_path = _workspace_tmp("dev-local-config") monkeypatch.chdir(tmp_path) (tmp_path / "nexus-claude-api.local.json").write_text( '{"api_key": "local-test-key"}', encoding="utf-8", ) try: settings = Settings.from_values(require_api_key=False, dev=True) assert settings.api_key == "local-test-key" assert load_local_config()["api_key"] == "local-test-key" finally: monkeypatch.chdir(Path(__file__).parents[1]) shutil.rmtree(tmp_path, ignore_errors=True) def test_default_mode_ignores_local_config(monkeypatch) -> None: tmp_path = _workspace_tmp("default-ignores-local") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) monkeypatch.delenv("NEXUS_API_KEY", raising=False) monkeypatch.delenv("AWS_BEARER_TOKEN_BEDROCK", raising=False) monkeypatch.chdir(tmp_path) (tmp_path / "nexus-claude-api.local.json").write_text( '{"api_key": "local-test-key"}', encoding="utf-8", ) try: settings = Settings.from_values(require_api_key=False) assert settings.api_key is None finally: monkeypatch.chdir(Path(__file__).parents[1]) shutil.rmtree(tmp_path, ignore_errors=True) def test_api_key_precedence_config_before_environment(monkeypatch) -> None: tmp_path = _workspace_tmp("config-precedence") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) monkeypatch.setenv("NEXUS_API_KEY", "env-key") write_user_config({"api_key": "config-key"}) settings = Settings.from_values(require_api_key=False) assert settings.api_key == "config-key" shutil.rmtree(tmp_path, ignore_errors=True) def test_api_key_argument_overrides_config(monkeypatch) -> None: tmp_path = _workspace_tmp("arg-precedence") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) write_user_config({"api_key": "config-key"}) settings = Settings.from_values(api_key="arg-key", require_api_key=False) assert settings.api_key == "arg-key" shutil.rmtree(tmp_path, ignore_errors=True) def test_config_set_writes_user_config(monkeypatch) -> None: tmp_path = _workspace_tmp("config-set") user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json" monkeypatch.setattr("nexus_claude_api.config.USER_CONFIG_FILE", user_config) exit_code = main(["config", "set", "--api-key", "written-key"]) assert exit_code == 0 assert json.loads(user_config.read_text(encoding="utf-8")) == { "api_key": "written-key" } shutil.rmtree(tmp_path, ignore_errors=True) def _workspace_tmp(name: str) -> Path: path = Path(__file__).parents[1] / ".test-tmp" / name shutil.rmtree(path, ignore_errors=True) path.mkdir(parents=True, exist_ok=True) return path