File size: 6,262 Bytes
da1a902 133255a 0dff311 0602b26 133255a 0d0f0f9 0602b26 f987504 7c98fe6 728f32a f987504 d29db6e db883b3 d29db6e 0602b26 684eaa9 db883b3 0602b26 db883b3 0602b26 684eaa9 db883b3 0602b26 ecc6b8a da1a902 db883b3 ecc6b8a 0602b26 cd03cec 0602b26 f987504 7c98fe6 da1a902 f987504 7c98fe6 f987504 7c98fe6 da1a902 f987504 da1a902 7c98fe6 f987504 da1a902 7c98fe6 f987504 7c98fe6 f987504 7c98fe6 728f32a 7c98fe6 da1a902 7c98fe6 da1a902 728f32a 7c98fe6 728f32a 7c98fe6 728f32a da1a902 7c98fe6 728f32a da1a902 7c98fe6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | from unittest.mock import MagicMock, patch
import pytest
from fastapi import HTTPException, Request
from free_claude_code.api.dependencies import (
get_services,
get_settings,
require_proxy_auth,
resolve_provider,
)
from free_claude_code.api.ports import ApiServices
from free_claude_code.application.errors import ApplicationUnavailableError
from free_claude_code.application.ports import RequestRuntimeLease
from free_claude_code.config.settings import Settings
from tests.api.support import create_test_app
def _request(*, headers: dict[str, str], token: str) -> tuple[Request, Settings]:
request = Request(
{
"type": "http",
"method": "GET",
"path": "/",
"headers": [
(key.lower().encode(), value.encode()) for key, value in headers.items()
],
}
)
settings = Settings.model_construct(anthropic_auth_token=token)
return request, settings
def _lease(*, provider=None, error: Exception | None = None):
lease = MagicMock(spec=RequestRuntimeLease)
lease.is_provider_cached.return_value = False
if error is None:
lease.resolve_provider.return_value = provider or MagicMock()
else:
lease.resolve_provider.side_effect = error
return lease
def test_get_services_reads_the_single_app_state_boundary() -> None:
app = create_test_app()
request = Request({"type": "http", "app": app})
services = get_services(request)
assert services is app.state.services
assert isinstance(services, ApiServices)
def test_get_settings_reads_current_request_runtime_settings() -> None:
app = create_test_app(
Settings.model_construct(
model="deepseek/test-model",
anthropic_auth_token="",
)
)
assert get_settings(app.state.services).model == "deepseek/test-model"
def test_resolve_provider_uses_retained_lease_and_logs_first_initialization() -> None:
provider = MagicMock()
lease = _lease(provider=provider)
with patch("free_claude_code.api.dependencies.logger.info") as log_info:
result = resolve_provider("nvidia_nim", lease=lease)
assert result is provider
lease.resolve_provider.assert_called_once_with("nvidia_nim")
log_info.assert_called_once_with("Provider initialized: {}", "nvidia_nim")
def test_resolve_provider_skips_initialization_log_for_cached_provider() -> None:
lease = _lease()
lease.is_provider_cached.return_value = True
with patch("free_claude_code.api.dependencies.logger.info") as log_info:
resolve_provider("nvidia_nim", lease=lease)
log_info.assert_not_called()
def test_resolve_provider_missing_key_preserves_readiness_error() -> None:
lease = _lease(
error=ApplicationUnavailableError(
"OPENROUTER_API_KEY is required. Get one at https://openrouter.ai"
)
)
with pytest.raises(ApplicationUnavailableError) as exc_info:
resolve_provider("open_router", lease=lease)
assert exc_info.value.status_code == 503
assert "OPENROUTER_API_KEY" in exc_info.value.message
assert "openrouter.ai" in exc_info.value.message
def test_resolve_provider_unrelated_error_is_not_reclassified() -> None:
lease = _lease(error=ValueError("unrelated config"))
with pytest.raises(ValueError, match="unrelated config"):
resolve_provider("nvidia_nim", lease=lease)
def test_require_proxy_auth_allows_when_no_token_configured():
request, settings = _request(headers={}, token="")
require_proxy_auth(request, settings)
def test_require_proxy_auth_rejects_missing_authorization():
request, settings = _request(headers={}, token="secret")
with pytest.raises(HTTPException) as exc_info:
require_proxy_auth(request, settings)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Missing proxy authentication token"
@pytest.mark.parametrize("header_name", ["x-api-key", "anthropic-auth-token"])
def test_require_proxy_auth_rejects_legacy_header_only(header_name: str):
request, settings = _request(headers={header_name: "secret"}, token="secret")
with pytest.raises(HTTPException) as exc_info:
require_proxy_auth(request, settings)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Missing proxy authentication token"
def test_require_proxy_auth_accepts_exact_bearer_token():
request, settings = _request(
headers={"authorization": "bEaReR secret"},
token="secret",
)
require_proxy_auth(request, settings)
def test_require_proxy_auth_accepts_colons_in_configured_token():
request, settings = _request(
headers={"authorization": "Bearer secret:with:colons"},
token="secret:with:colons",
)
require_proxy_auth(request, settings)
def test_require_proxy_auth_accepts_valid_bearer_with_conflicting_legacy_headers():
request, settings = _request(
headers={
"authorization": "Bearer secret",
"x-api-key": "wrong",
"anthropic-auth-token": "also-wrong",
},
token="secret",
)
require_proxy_auth(request, settings)
@pytest.mark.parametrize(
"authorization",
[
"secret",
"Basic secret",
"Bearer",
"Bearer wrong",
"Bearer secret:claude-sonnet",
],
)
def test_require_proxy_auth_rejects_malformed_or_invalid_authorization(
authorization: str,
):
request, settings = _request(
headers={"authorization": authorization},
token="secret",
)
with pytest.raises(HTTPException) as exc_info:
require_proxy_auth(request, settings)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Invalid proxy authentication token"
def test_require_proxy_auth_rejects_invalid_bearer_when_legacy_header_matches():
request, settings = _request(
headers={"authorization": "Bearer wrong", "x-api-key": "secret"},
token="secret",
)
with pytest.raises(HTTPException) as exc_info:
require_proxy_auth(request, settings)
assert exc_info.value.status_code == 401
assert exc_info.value.detail == "Invalid proxy authentication token"
|