Skip to content

Commit 5e02bcb

Browse files
committed
More tests
1 parent c87dac2 commit 5e02bcb

1 file changed

Lines changed: 92 additions & 1 deletion

File tree

tests/integration/test_end_to_end.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@
2222
AgentCapabilities,
2323
AgentCard,
2424
AgentInterface,
25+
CancelTaskRequest,
26+
DeleteTaskPushNotificationConfigRequest,
27+
GetTaskPushNotificationConfigRequest,
2528
GetTaskRequest,
29+
ListTaskPushNotificationConfigsRequest,
2630
ListTasksRequest,
2731
Message,
2832
Part,
2933
Role,
3034
SendMessageConfiguration,
3135
SendMessageRequest,
36+
SubscribeToTaskRequest,
3237
TaskState,
3338
a2a_pb2_grpc,
3439
)
@@ -273,6 +278,22 @@ def transport_setups(request) -> ClientSetup:
273278
return request.getfixturevalue(request.param)
274279

275280

281+
@pytest.fixture(
282+
params=[
283+
pytest.param('jsonrpc_setup', id='JSON-RPC'),
284+
pytest.param('grpc_setup', id='gRPC'),
285+
]
286+
)
287+
def rpc_transport_setups(request) -> ClientSetup:
288+
"""Parametrized fixture for RPC transports only (excludes REST).
289+
290+
REST encodes some required fields in URL paths, so empty-field validation
291+
tests hit routing errors before reaching the handler. JSON-RPC and gRPC
292+
send the full request message, allowing server-side validation to work.
293+
"""
294+
return request.getfixturevalue(request.param)
295+
296+
276297
@pytest.mark.asyncio
277298
async def test_end_to_end_send_message_blocking(transport_setups):
278299
client = transport_setups.client
@@ -569,9 +590,15 @@ async def test_end_to_end_input_required(transport_setups):
569590
SendMessageRequest(message=Message()),
570591
{'message.message_id', 'message.role', 'message.parts'},
571592
),
593+
(
594+
SendMessageRequest(
595+
message=Message(message_id='m1', role=Role.ROLE_USER)
596+
),
597+
{'message.parts'},
598+
),
572599
],
573600
)
574-
async def test_end_to_end_validation_errors(
601+
async def test_end_to_end_send_message_validation_errors(
575602
transport_setups,
576603
empty_request: SendMessageRequest,
577604
expected_fields: set[str],
@@ -586,3 +613,67 @@ async def test_end_to_end_validation_errors(
586613
assert {e['field'] for e in errors} == expected_fields
587614

588615
await client.close()
616+
617+
618+
@pytest.mark.asyncio
619+
@pytest.mark.parametrize(
620+
'method, invalid_request, expected_fields',
621+
[
622+
(
623+
'get_task',
624+
GetTaskRequest(),
625+
{'id'},
626+
),
627+
(
628+
'cancel_task',
629+
CancelTaskRequest(),
630+
{'id'},
631+
),
632+
(
633+
'get_task_push_notification_config',
634+
GetTaskPushNotificationConfigRequest(),
635+
{'task_id', 'id'},
636+
),
637+
(
638+
'list_task_push_notification_configs',
639+
ListTaskPushNotificationConfigsRequest(),
640+
{'task_id'},
641+
),
642+
(
643+
'delete_task_push_notification_config',
644+
DeleteTaskPushNotificationConfigRequest(),
645+
{'task_id', 'id'},
646+
),
647+
],
648+
)
649+
async def test_end_to_end_unary_validation_errors(
650+
rpc_transport_setups,
651+
method: str,
652+
invalid_request,
653+
expected_fields: set[str],
654+
) -> None:
655+
client = rpc_transport_setups.client
656+
657+
with pytest.raises(InvalidParamsError) as exc_info:
658+
await getattr(client, method)(request=invalid_request)
659+
660+
errors = exc_info.value.data.get('errors', [])
661+
assert {e['field'] for e in errors} == expected_fields
662+
663+
await client.close()
664+
665+
666+
@pytest.mark.asyncio
667+
async def test_end_to_end_subscribe_validation_error(
668+
rpc_transport_setups,
669+
) -> None:
670+
client = rpc_transport_setups.client
671+
672+
with pytest.raises(InvalidParamsError) as exc_info:
673+
async for _ in client.subscribe(request=SubscribeToTaskRequest()):
674+
pass
675+
676+
errors = exc_info.value.data.get('errors', [])
677+
assert {e['field'] for e in errors} == {'id'}
678+
679+
await client.close()

0 commit comments

Comments
 (0)