test: cover auth-on-request and close() in OpenCodeClient

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
tao.chen
2026-07-23 17:40:58 +08:00
co-authored by Claude Fable 5
parent c86de1d31b
commit b6c0273ee0
+39 -7
View File
@@ -2,6 +2,7 @@
import json
from io import BytesIO
from unittest.mock import MagicMock
import pytest
import tornado.httpclient
@@ -38,7 +39,9 @@ def base_config() -> OpenCodeConfig:
)
def _make_client(config: OpenCodeConfig, responses: list[tuple[int, object]]) -> tuple[OpenCodeClient, MockHTTPClient]:
def _make_client(
config: OpenCodeConfig, responses: list[tuple[int, object]]
) -> tuple[OpenCodeClient, MockHTTPClient]:
mock = MockHTTPClient()
mock.responses = responses
return OpenCodeClient(config, http_client=mock), mock
@@ -68,22 +71,30 @@ async def test_create_session_posts_title(base_config: OpenCodeConfig) -> None:
@pytest.mark.asyncio
async def test_auth_in_fetch_kwargs_when_password_set(base_config: OpenCodeConfig) -> None:
async def test_auth_set_on_request_when_password_present(
base_config: OpenCodeConfig,
) -> None:
"""Bug fix: auth must live on the HTTPRequest, not as fetch kwargs
(tornado rejects fetch(request, **kwargs) for request-construction kwargs)."""
config = base_config._replace(password="secret")
client, mock = _make_client(config, [(200, {"status": "ok"})])
await client.health()
call = mock.calls[0]
assert call["kwargs"].get("auth_username") == "opencode"
assert call["kwargs"].get("auth_password") == "secret"
# No kwargs forwarded to fetch.
assert call["kwargs"] == {}
# Auth is on the HTTPRequest.
assert call["request"].auth_username == "opencode"
assert call["request"].auth_password == "secret"
@pytest.mark.asyncio
async def test_auth_not_in_fetch_kwargs_when_password_empty(base_config: OpenCodeConfig) -> None:
async def test_auth_absent_when_no_password(base_config: OpenCodeConfig) -> None:
client, mock = _make_client(base_config, [(200, {"status": "ok"})])
await client.health()
call = mock.calls[0]
assert "auth_username" not in call["kwargs"]
assert "auth_password" not in call["kwargs"]
assert call["kwargs"] == {}
assert call["request"].auth_username is None
assert call["request"].auth_password is None
@pytest.mark.asyncio
@@ -149,3 +160,24 @@ async def test_non_2xx_response_raises_with_body(base_config: OpenCodeConfig) ->
with pytest.raises(OpenCodeError) as exc_info:
await client.health()
assert "boom" in str(exc_info.value)
def test_close_is_idempotent() -> None:
"""close() can be called multiple times safely."""
client = OpenCodeClient(OpenCodeConfig(
url="http://x", user="u", password="", request_timeout_seconds=10
))
client.close()
client.close() # must not raise
assert client._http_client is None
def test_close_does_not_close_injected_client() -> None:
"""close() must not call .close() on a client it didn't create."""
injected = MagicMock()
client = OpenCodeClient(OpenCodeConfig(
url="http://x", user="u", password="", request_timeout_seconds=10
), http_client=injected)
client.close()
injected.close.assert_not_called()
assert client._http_client is None