2026-01-23 23:36:08 +08:00
|
|
|
from dataclasses import dataclass
|
2026-03-19 23:52:17 +08:00
|
|
|
from types import SimpleNamespace
|
|
|
|
|
|
|
|
|
|
import pytest
|
2026-01-23 23:36:08 +08:00
|
|
|
|
|
|
|
|
from src.services.provider.transport import build_provider_url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class _DummyEndpoint:
|
|
|
|
|
base_url: str
|
|
|
|
|
api_format: str
|
|
|
|
|
custom_path: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_gemini_stream_adds_alt_sse_and_drops_key_query_param() -> None:
|
|
|
|
|
endpoint = _DummyEndpoint(
|
|
|
|
|
base_url="https://generativelanguage.googleapis.com",
|
2026-02-01 17:28:00 +08:00
|
|
|
api_format="gemini:chat",
|
2026-01-23 23:36:08 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
url = build_provider_url(
|
|
|
|
|
endpoint, # type: ignore[arg-type] - test stub
|
|
|
|
|
query_params={"key": "SECRET"},
|
|
|
|
|
path_params={"model": "gemini-1.5-pro"},
|
|
|
|
|
is_stream=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert url.startswith(
|
|
|
|
|
"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:streamGenerateContent"
|
|
|
|
|
)
|
|
|
|
|
assert "key=" not in url
|
|
|
|
|
assert "alt=sse" in url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_gemini_stream_does_not_override_existing_alt() -> None:
|
|
|
|
|
endpoint = _DummyEndpoint(
|
|
|
|
|
base_url="https://generativelanguage.googleapis.com",
|
2026-02-01 17:28:00 +08:00
|
|
|
api_format="gemini:chat",
|
2026-01-23 23:36:08 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
url = build_provider_url(
|
|
|
|
|
endpoint, # type: ignore[arg-type] - test stub
|
|
|
|
|
query_params={"alt": "json"},
|
|
|
|
|
path_params={"model": "gemini-1.5-pro"},
|
|
|
|
|
is_stream=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert "alt=json" in url
|
|
|
|
|
assert "alt=sse" not in url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_gemini_non_stream_does_not_add_alt() -> None:
|
|
|
|
|
endpoint = _DummyEndpoint(
|
|
|
|
|
base_url="https://generativelanguage.googleapis.com",
|
2026-02-01 17:28:00 +08:00
|
|
|
api_format="gemini:chat",
|
2026-01-23 23:36:08 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
url = build_provider_url(
|
|
|
|
|
endpoint, # type: ignore[arg-type] - test stub
|
|
|
|
|
path_params={"model": "gemini-1.5-pro"},
|
|
|
|
|
is_stream=False,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert url.endswith("/v1beta/models/gemini-1.5-pro:generateContent")
|
|
|
|
|
assert "alt=" not in url
|
2026-03-19 23:52:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_vertex_gemini_api_key_base_url_uses_vertex_transport_without_provider_type(
|
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
endpoint = _DummyEndpoint(
|
|
|
|
|
base_url="https://aiplatform.googleapis.com",
|
|
|
|
|
api_format="gemini:chat",
|
|
|
|
|
)
|
|
|
|
|
key = SimpleNamespace(auth_type="api_key", api_key="enc-key")
|
|
|
|
|
|
|
|
|
|
from src.core.crypto import crypto_service
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(crypto_service, "decrypt", lambda value: "test-key")
|
|
|
|
|
|
|
|
|
|
url = build_provider_url(
|
|
|
|
|
endpoint, # type: ignore[arg-type] - test stub
|
|
|
|
|
path_params={"model": "gemini-3.1-pro-preview"},
|
|
|
|
|
is_stream=False,
|
|
|
|
|
key=key, # type: ignore[arg-type] - test stub
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert (
|
|
|
|
|
url == "https://aiplatform.googleapis.com/v1/publishers/google/models/"
|
|
|
|
|
"gemini-3.1-pro-preview:generateContent?key=test-key"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_vertex_gemini_service_account_base_url_uses_vertex_transport_without_provider_type() -> (
|
|
|
|
|
None
|
|
|
|
|
):
|
|
|
|
|
endpoint = _DummyEndpoint(
|
|
|
|
|
base_url="https://aiplatform.googleapis.com",
|
|
|
|
|
api_format="gemini:chat",
|
|
|
|
|
)
|
|
|
|
|
key = SimpleNamespace(auth_type="service_account", auth_config={"project_id": "demo-project"})
|
|
|
|
|
|
|
|
|
|
url = build_provider_url(
|
|
|
|
|
endpoint, # type: ignore[arg-type] - test stub
|
|
|
|
|
path_params={"model": "gemini-3.1-pro-preview"},
|
|
|
|
|
is_stream=False,
|
|
|
|
|
key=key, # type: ignore[arg-type] - test stub
|
|
|
|
|
decrypted_auth_config={"project_id": "demo-project", "region": "global"},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert (
|
|
|
|
|
url == "https://aiplatform.googleapis.com/v1/projects/demo-project/locations/global/"
|
|
|
|
|
"publishers/google/models/gemini-3.1-pro-preview:generateContent"
|
|
|
|
|
)
|