2
0

test_wrapper.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import json
  2. from typing import Iterator
  3. import httpx
  4. import pytest
  5. from opencode_ai import OpenCodeClient
  6. from opencode_ai.api.default import config_get
  7. from opencode_ai.client import Client
  8. class _State:
  9. def __init__(self):
  10. self.calls = 0
  11. def test_imports_and_methods_available() -> None:
  12. w = OpenCodeClient()
  13. assert hasattr(w, "list_sessions")
  14. assert hasattr(w, "get_config")
  15. assert hasattr(w, "list_agents")
  16. assert hasattr(w, "list_projects")
  17. assert hasattr(w, "current_project")
  18. assert hasattr(w, "file_status")
  19. assert hasattr(w, "get_path")
  20. assert hasattr(w, "subscribe_events")
  21. def test_get_path_with_mock_transport() -> None:
  22. # Arrange a mock transport for GET /path
  23. def handler(request: httpx.Request) -> httpx.Response:
  24. assert request.url.path == "/path"
  25. return httpx.Response(
  26. 200,
  27. json={
  28. "state": "ok",
  29. "config": "/tmp/config",
  30. "worktree": "/repo",
  31. "directory": "/repo/project",
  32. },
  33. )
  34. transport = httpx.MockTransport(handler)
  35. w = OpenCodeClient(base_url="http://test")
  36. client = httpx.Client(base_url="http://test", transport=transport)
  37. w.client.set_httpx_client(client)
  38. # Act
  39. result = w.get_path()
  40. # Assert
  41. assert result is not None
  42. assert result.directory == "/repo/project"
  43. def test_retry_on_request_error_then_success() -> None:
  44. state = _State()
  45. def handler(request: httpx.Request) -> httpx.Response:
  46. if state.calls == 0:
  47. state.calls += 1
  48. raise httpx.ConnectError("boom", request=request)
  49. return httpx.Response(
  50. 200,
  51. json={
  52. "state": "ok",
  53. "config": "/tmp/config",
  54. "worktree": "/repo",
  55. "directory": "/repo/project",
  56. },
  57. )
  58. transport = httpx.MockTransport(handler)
  59. w = OpenCodeClient(base_url="http://test", retries=1, backoff_factor=0)
  60. client = httpx.Client(base_url="http://test", transport=transport)
  61. w.client.set_httpx_client(client)
  62. result = w.get_path()
  63. assert result is not None
  64. assert result.directory == "/repo/project"
  65. def test_generated_config_get_via_mock() -> None:
  66. def handler(request: httpx.Request) -> httpx.Response:
  67. assert request.url.path == "/config"
  68. return httpx.Response(200, json={})
  69. transport = httpx.MockTransport(handler)
  70. c = Client(base_url="http://test")
  71. c.set_httpx_client(httpx.Client(base_url="http://test", transport=transport))
  72. assert config_get.sync(client=c) is not None
  73. def test_sse_streaming_parses_events() -> None:
  74. # Prepare a simple SSE payload with one event
  75. payload = b'data: {"type":"server.connected"}\n\n'
  76. def handler(request: httpx.Request) -> httpx.Response:
  77. assert request.url.path == "/event"
  78. return httpx.Response(
  79. 200,
  80. headers={"Content-Type": "text/event-stream"},
  81. content=payload,
  82. )
  83. transport = httpx.MockTransport(handler)
  84. w = OpenCodeClient(base_url="http://test")
  85. client = httpx.Client(base_url="http://test", transport=transport)
  86. w.client.set_httpx_client(client)
  87. it = w.subscribe_events()
  88. first = next(it)
  89. assert isinstance(first, dict)
  90. assert first.get("type") == "server.connected"