Skip to content

Commit 54747f8

Browse files
fixed & improved tests for starlette and fastapi
1 parent 57420d5 commit 54747f8

File tree

1 file changed

+104
-8
lines changed

1 file changed

+104
-8
lines changed

tests/server/test_integration.py

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
from starlette.routing import Route
1010
from starlette.testclient import TestClient
1111

12-
from a2a.server.apps.starlette_app import A2AStarletteApplication
12+
from a2a.server.apps.jsonrpc import (
13+
A2AStarletteApplication,
14+
A2AFastAPIApplication,
15+
)
1316
from a2a.types import (
1417
AgentCapabilities,
1518
AgentCard,
@@ -116,13 +119,23 @@ def handler():
116119

117120

118121
@pytest.fixture
119-
def app(agent_card: AgentCard, handler: mock.AsyncMock):
122+
def starlette_app(agent_card: AgentCard, handler: mock.AsyncMock):
120123
return A2AStarletteApplication(agent_card, handler)
121124

122125

123126
@pytest.fixture
124-
def client(app: A2AStarletteApplication):
125-
"""Create a test client with the app."""
127+
def starlette_client(app: A2AStarletteApplication):
128+
"""Create a test client with the Starlette app."""
129+
return TestClient(app.build())
130+
131+
@pytest.fixture
132+
def fastapi_app(agent_card: AgentCard, handler: mock.AsyncMock):
133+
return A2AFastAPIApplication(agent_card, handler)
134+
135+
136+
@pytest.fixture
137+
def fastapi_client(app: A2AFastAPIApplication):
138+
"""Create a test client with the FastAPI app."""
126139
return TestClient(app.build())
127140

128141

@@ -139,7 +152,7 @@ def test_agent_card_endpoint(client: TestClient, agent_card: AgentCard):
139152
assert 'streaming' in data['capabilities']
140153

141154

142-
def test_authenticated_extended_agent_card_endpoint_not_supported(
155+
def test_authenticated_extended_agent_card_endpoint_not_supported_starlette(
143156
agent_card: AgentCard, handler: mock.AsyncMock
144157
):
145158
"""Test extended card endpoint returns 404 if not supported by main card."""
@@ -152,8 +165,21 @@ def test_authenticated_extended_agent_card_endpoint_not_supported(
152165
response = client.get('/agent/authenticatedExtendedCard')
153166
assert response.status_code == 404 # Starlette's default for no route
154167

168+
def test_authenticated_extended_agent_card_endpoint_not_supported_fastapi(
169+
agent_card: AgentCard, handler: mock.AsyncMock
170+
):
171+
"""Test extended card endpoint returns 404 if not supported by main card."""
172+
# Ensure supportsAuthenticatedExtendedCard is False or None
173+
agent_card.supportsAuthenticatedExtendedCard = False
174+
app_instance = A2AFastAPIApplication(agent_card, handler)
175+
# The route should not even be added if supportsAuthenticatedExtendedCard is false
176+
# So, building the app and trying to hit it should result in 404 from FastAPI itself
177+
client = TestClient(app_instance.build())
178+
response = client.get('/agent/authenticatedExtendedCard')
179+
assert response.status_code == 404 # FastAPI's default for no route
180+
155181

156-
def test_authenticated_extended_agent_card_endpoint_supported_with_specific_extended_card(
182+
def test_authenticated_extended_agent_card_endpoint_supported_with_specific_extended_card_starlette(
157183
agent_card: AgentCard,
158184
extended_agent_card_fixture: AgentCard,
159185
handler: mock.AsyncMock,
@@ -178,6 +204,30 @@ def test_authenticated_extended_agent_card_endpoint_supported_with_specific_exte
178204
'Extended skill not found in served card'
179205
)
180206

207+
def test_authenticated_extended_agent_card_endpoint_supported_with_specific_extended_card_fastapi(
208+
agent_card: AgentCard,
209+
extended_agent_card_fixture: AgentCard,
210+
handler: mock.AsyncMock,
211+
):
212+
"""Test extended card endpoint returns the specific extended card when provided."""
213+
agent_card.supportsAuthenticatedExtendedCard = (
214+
True # Main card must support it
215+
)
216+
app_instance = A2AFastAPIApplication(
217+
agent_card, handler, extended_agent_card=extended_agent_card_fixture
218+
)
219+
client = TestClient(app_instance.build())
220+
221+
response = client.get('/agent/authenticatedExtendedCard')
222+
assert response.status_code == 200
223+
data = response.json()
224+
# Verify it's the extended card's data
225+
assert data['name'] == extended_agent_card_fixture.name
226+
assert data['version'] == extended_agent_card_fixture.version
227+
assert len(data['skills']) == len(extended_agent_card_fixture.skills)
228+
assert any(skill['id'] == 'skill-extended' for skill in data['skills']), (
229+
'Extended skill not found in served card'
230+
)
181231

182232
def test_agent_card_custom_url(
183233
app: A2AStarletteApplication, agent_card: AgentCard
@@ -190,7 +240,7 @@ def test_agent_card_custom_url(
190240
assert data['name'] == agent_card.name
191241

192242

193-
def test_rpc_endpoint_custom_url(
243+
def test_starlette_rpc_endpoint_custom_url(
194244
app: A2AStarletteApplication, handler: mock.AsyncMock
195245
):
196246
"""Test the RPC endpoint with a custom URL."""
@@ -214,8 +264,31 @@ def test_rpc_endpoint_custom_url(
214264
data = response.json()
215265
assert data['result']['id'] == 'task1'
216266

267+
def test_fastapi_rpc_endpoint_custom_url(
268+
app: A2AFastAPIApplication, handler: mock.AsyncMock
269+
):
270+
"""Test the RPC endpoint with a custom URL."""
271+
# Provide a valid Task object as the return value
272+
task_status = TaskStatus(**MINIMAL_TASK_STATUS)
273+
task = Task(
274+
id='task1', contextId='ctx1', state='completed', status=task_status
275+
)
276+
handler.on_get_task.return_value = task
277+
client = TestClient(app.build(rpc_url='/api/rpc'))
278+
response = client.post(
279+
'/api/rpc',
280+
json={
281+
'jsonrpc': '2.0',
282+
'id': '123',
283+
'method': 'tasks/get',
284+
'params': {'id': 'task1'},
285+
},
286+
)
287+
assert response.status_code == 200
288+
data = response.json()
289+
assert data['result']['id'] == 'task1'
217290

218-
def test_build_with_extra_routes(
291+
def test_starlette_build_with_extra_routes(
219292
app: A2AStarletteApplication, agent_card: AgentCard
220293
):
221294
"""Test building the app with additional routes."""
@@ -238,6 +311,29 @@ def custom_handler(request):
238311
data = response.json()
239312
assert data['name'] == agent_card.name
240313

314+
def test_fastapi_build_with_extra_routes(
315+
app: A2AFastAPIApplication, agent_card: AgentCard
316+
):
317+
"""Test building the app with additional routes."""
318+
319+
def custom_handler(request):
320+
return JSONResponse({'message': 'Hello'})
321+
322+
extra_route = Route('/hello', custom_handler, methods=['GET'])
323+
test_app = app.build(routes=[extra_route])
324+
client = TestClient(test_app)
325+
326+
# Test the added route
327+
response = client.get('/hello')
328+
assert response.status_code == 200
329+
assert response.json() == {'message': 'Hello'}
330+
331+
# Ensure default routes still work
332+
response = client.get('/.well-known/agent.json')
333+
assert response.status_code == 200
334+
data = response.json()
335+
assert data['name'] == agent_card.name
336+
241337

242338
# === REQUEST METHODS TESTS ===
243339

0 commit comments

Comments
 (0)