test: cover auth-on-request and close() in OpenCodeClient
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c86de1d31b
commit
b6c0273ee0
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import tornado.httpclient
|
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 = MockHTTPClient()
|
||||||
mock.responses = responses
|
mock.responses = responses
|
||||||
return OpenCodeClient(config, http_client=mock), mock
|
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
|
@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")
|
config = base_config._replace(password="secret")
|
||||||
client, mock = _make_client(config, [(200, {"status": "ok"})])
|
client, mock = _make_client(config, [(200, {"status": "ok"})])
|
||||||
await client.health()
|
await client.health()
|
||||||
call = mock.calls[0]
|
call = mock.calls[0]
|
||||||
assert call["kwargs"].get("auth_username") == "opencode"
|
# No kwargs forwarded to fetch.
|
||||||
assert call["kwargs"].get("auth_password") == "secret"
|
assert call["kwargs"] == {}
|
||||||
|
# Auth is on the HTTPRequest.
|
||||||
|
assert call["request"].auth_username == "opencode"
|
||||||
|
assert call["request"].auth_password == "secret"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@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"})])
|
client, mock = _make_client(base_config, [(200, {"status": "ok"})])
|
||||||
await client.health()
|
await client.health()
|
||||||
call = mock.calls[0]
|
call = mock.calls[0]
|
||||||
assert "auth_username" not in call["kwargs"]
|
assert call["kwargs"] == {}
|
||||||
assert "auth_password" not in call["kwargs"]
|
assert call["request"].auth_username is None
|
||||||
|
assert call["request"].auth_password is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@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:
|
with pytest.raises(OpenCodeError) as exc_info:
|
||||||
await client.health()
|
await client.health()
|
||||||
assert "boom" in str(exc_info.value)
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user