dotb_ai-platform/tests/test_openai_compatible_adapter.py

80 lines
2.9 KiB
Python

import json
import httpx
import pytest
from ai_platform.infrastructure.openai_compatible_scoring import OpenAICompatibleScoringGateway
from ai_platform.lead_scoring.application.scoring_execution_repository import AIProviderFailure
def _completion(content: str) -> httpx.Response:
return httpx.Response(200, json={"choices": [{"message": {"content": content}}]})
@pytest.mark.asyncio
async def test_compatible_adapter_accepts_json_fence_without_request_vkey():
requests: list[httpx.Request] = []
def handler(request: httpx.Request) -> httpx.Response:
requests.append(request)
assert "authorization" not in request.headers
assert json.loads(request.content)["model"] == "gemini-3.5-flash-lite"
return _completion('```json\n{"items":[]}\n```')
http = httpx.AsyncClient(transport=httpx.MockTransport(handler))
provider = OpenAICompatibleScoringGateway("http://127.0.0.1:8317", None, http)
try:
evidence = await provider.extract_evidence(
model="gemini-3.5-flash-lite", snapshot={}, vkey="", timeout=7
)
finally:
await http.aclose()
assert evidence == []
assert len(requests) == 1
@pytest.mark.parametrize(
("response", "error_code"),
[
(
_completion('{"score":80,"score":1,"confidence":0.8,"reasoning":"a"}'),
"openai_invalid_response",
),
(_completion('{"score":"80","confidence":0.8,"reasoning":"a"}'), "openai_invalid_score"),
(httpx.Response(429, text="sensitive upstream error"), "openai_http_error"),
],
)
@pytest.mark.asyncio
async def test_compatible_adapter_rejects_unsafe_outputs(response: httpx.Response, error_code: str):
http = httpx.AsyncClient(transport=httpx.MockTransport(lambda _: response))
provider = OpenAICompatibleScoringGateway("https://proxy.example", "test-key", http)
try:
with pytest.raises(AIProviderFailure) as error:
await provider.score(
model="ignored", system_prompt="system", user_prompt="user", vkey="", timeout=7
)
finally:
await http.aclose()
assert error.value.error_code == error_code
assert "sensitive upstream error" not in str(error.value)
@pytest.mark.asyncio
async def test_compatible_adapter_does_not_return_echoed_key():
secret = "test/secret"
http = httpx.AsyncClient(
transport=httpx.MockTransport(
lambda _: _completion(json.dumps({"score": 80, "confidence": 0.8, "reasoning": secret}))
)
)
provider = OpenAICompatibleScoringGateway("https://proxy.example", secret, http)
try:
with pytest.raises(AIProviderFailure) as error:
await provider.score(
model="ignored", system_prompt="system", user_prompt="user", vkey="", timeout=7
)
finally:
await http.aclose()
assert error.value.error_code == "openai_invalid_response"
assert secret not in str(error.value)