Skip to content

Commit 541cbaa

Browse files
fix(tests): pass mock Request to orchestrate() to satisfy slowapi @limiter.limit decorator
Fix tests to accommodate slowapi's requirements for Request object and improve error handling.
1 parent cc5990c commit 541cbaa

1 file changed

Lines changed: 33 additions & 15 deletions

File tree

tests/test_resilience.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ def raise_permission_error(self, *args, **kwargs):
2727

2828
monkeypatch.setattr(Path, "write_text", raise_permission_error)
2929
tracker = AgentTracker(state_dir=str(tmp_path))
30-
3130
record = tracker.register(
3231
role="orchestrator",
3332
model="test-model",
@@ -44,7 +43,6 @@ def test_sync_returns_structured_error_when_vendor_clone_unavailable(monkeypatch
4443
import orchestrator.ecc_tools_sync as sync_mod
4544

4645
monkeypatch.setattr(sync_mod, "_ensure_cloned", lambda: False)
47-
4846
result = sync_mod.sync_ecc_tools(force=False)
4947

5048
assert result["status"] == "error"
@@ -75,8 +73,28 @@ def _load_orchestrator_module():
7573
return mod
7674

7775

76+
def _make_mock_request():
77+
"""Return a minimal mock of starlette.requests.Request that satisfies
78+
slowapi's get_remote_address key_func (needs request.client.host).
79+
80+
fix(tests): slowapi @limiter.limit decorator requires a Request object in
81+
the function signature. Tests that call the handler directly must supply
82+
one; this helper avoids pulling in starlette's full Request machinery.
83+
"""
84+
class _Client:
85+
host = "127.0.0.1"
86+
87+
class _MockRequest:
88+
client = _Client()
89+
# slowapi also reads scope/headers in some paths; provide safe stubs.
90+
headers: dict = {}
91+
scope: dict = {"type": "http"}
92+
93+
return _MockRequest()
94+
95+
7896
def test_call_ultrathink_appends_ultrathink_path(monkeypatch):
79-
"""Bug fix: call_ultrathink must POST to <base>/ultrathink, not bare base URL.
97+
"""Bug fix: call_ultrathink must POST to /ultrathink, not bare base URL.
8098
8199
Before the fix: session.post(ULTRATHINK_ENDPOINT, ...)
82100
After the fix: session.post(ULTRATHINK_ENDPOINT.rstrip('/') + '/ultrathink', ...)
@@ -85,25 +103,19 @@ def test_call_ultrathink_appends_ultrathink_path(monkeypatch):
85103
import aiohttp
86104

87105
orch_mod = _load_orchestrator_module()
88-
89106
captured_urls = []
90107

91108
class _FakeResp:
92-
async def __aenter__(self):
93-
return self
94-
async def __aexit__(self, *a):
95-
pass
96-
async def json(self):
97-
return {"result": "ok"}
109+
async def __aenter__(self): return self
110+
async def __aexit__(self, *a): pass
111+
async def json(self): return {"result": "ok"}
98112

99113
class _FakeSession:
100114
def post(self, url, **kwargs):
101115
captured_urls.append(url)
102116
return _FakeResp()
103-
async def __aenter__(self):
104-
return self
105-
async def __aexit__(self, *a):
106-
pass
117+
async def __aenter__(self): return self
118+
async def __aexit__(self, *a): pass
107119

108120
monkeypatch.setattr(orch_mod, "ULTRATHINK_ENDPOINT", "http://localhost:8001")
109121
monkeypatch.setattr(aiohttp, "ClientSession", _FakeSession)
@@ -121,6 +133,10 @@ def test_orchestrate_returns_empty_string_when_all_backends_fail(monkeypatch):
121133
122134
Before the fix: Pydantic raises ValidationError because result:str got None.
123135
After the fix: status='success', result='' returned cleanly.
136+
137+
fix(tests): orchestrate() is decorated with @limiter.limit which requires a
138+
starlette Request as the second positional argument. Pass a mock Request so
139+
slowapi's async_wrapper can extract the client IP without IndexError.
124140
"""
125141
import asyncio
126142

@@ -148,7 +164,9 @@ async def setex(self, *a): pass
148164
privacy_critical=False,
149165
enable_critic=False,
150166
)
151-
resp = asyncio.run(orch_mod.orchestrate(req))
167+
# fix(tests): pass mock Request as second positional arg to satisfy slowapi
168+
mock_request = _make_mock_request()
169+
resp = asyncio.run(orch_mod.orchestrate(req, mock_request))
152170

153171
assert resp.result == "", f"Expected empty string, got: {resp.result!r}"
154172
assert resp.status == "success"

0 commit comments

Comments
 (0)