Files
nexus-claude-api/tests/test_cli.py

194 lines
6.5 KiB
Python

from __future__ import annotations
import json
import shutil
from pathlib import Path
from nexus_claude_api import __version__
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_version_prints_package_version(capsys) -> None:
try:
main(["--version"])
except SystemExit as exc:
assert exc.code == 0
output = capsys.readouterr()
assert output.out.strip() == f"nexus-claude-api {__version__}"
def test_invalid_user_config_returns_clean_error(monkeypatch, capsys) -> None:
tmp_path = _workspace_tmp("invalid-user-config")
user_config = tmp_path / ".config" / "nexus-claude-api" / "config.json"
user_config.parent.mkdir(parents=True, exist_ok=True)
user_config.write_text("{not json", encoding="utf-8")
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)
output = capsys.readouterr()
assert exit_code == 2
assert "Invalid configuration: Invalid JSON" in output.err
assert "Traceback" not in output.err
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