From cfcec61cba172424e8d965fbbce324fa60d911b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Sobczyk?= Date: Wed, 5 Aug 2026 12:16:32 -0700 Subject: [PATCH] test(a2a): align ResponseConverter tests with unlabelled DataPart fallback A DataPart carrying no `adk_type` metadata is no longer inferred to be a function call. PartConverter serializes it into an inline `text/plain` JSON blob instead, so two tests that still asserted the old inferred behaviour failed at head with `NoSuchElementException` on an empty `functionCall()`. Update both to assert what the converter actually produces: no function call, and an inline JSON blob that still carries the original payload. A small `inlineJson` helper holds the blob-shape assertions and explains why the fallback happens. PiperOrigin-RevId: 959800614 --- .../a2a/converters/ResponseConverterTest.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/a2a/src/test/java/com/google/adk/a2a/converters/ResponseConverterTest.java b/a2a/src/test/java/com/google/adk/a2a/converters/ResponseConverterTest.java index 5f0f07dec..899af5c34 100644 --- a/a2a/src/test/java/com/google/adk/a2a/converters/ResponseConverterTest.java +++ b/a2a/src/test/java/com/google/adk/a2a/converters/ResponseConverterTest.java @@ -17,6 +17,7 @@ package com.google.adk.a2a.converters; import static com.google.common.truth.Truth.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.joining; import static org.junit.Assert.assertThrows; @@ -274,7 +275,7 @@ public void taskToEvent_withInputRequired_parsesLongRunningToolIds() { } @Test - public void taskToEvent_withDataPartWithoutMetadata_doesNotThrow() { + public void taskToEvent_withDataPartWithoutMetadata_fallsBackToInlineJson() { DataPart dataPart = new DataPart( ImmutableMap.of("name", "myTool", "id", "call_123", "args", ImmutableMap.of())); @@ -296,12 +297,14 @@ public void taskToEvent_withDataPartWithoutMetadata_doesNotThrow() { assertThat(event.longRunningToolIds().get()).isEmpty(); List parts = event.content().get().parts().get(); assertThat(parts).hasSize(2); - assertThat(parts.get(0).functionCall().get().id()).hasValue("call_123"); - assertThat(parts.get(1).functionCall().get().id()).hasValue("msg_123"); + assertThat(parts.get(0).functionCall()).isEmpty(); + assertThat(inlineJson(parts.get(0))).contains("call_123"); + assertThat(parts.get(1).functionCall()).isEmpty(); + assertThat(inlineJson(parts.get(1))).contains("msg_123"); } @Test - public void artifactToEvent_withDataPartWithoutMetadata_doesNotThrow() { + public void artifactToEvent_withDataPartWithoutMetadata_fallsBackToInlineJson() { DataPart dataPart = new DataPart( ImmutableMap.of("name", "myTool", "id", "call_123", "args", ImmutableMap.of())); @@ -313,7 +316,21 @@ public void artifactToEvent_withDataPartWithoutMetadata_doesNotThrow() { assertThat(event.longRunningToolIds().get()).isEmpty(); List parts = event.content().get().parts().get(); assertThat(parts).hasSize(1); - assertThat(parts.get(0).functionCall().get().id()).hasValue("call_123"); + assertThat(parts.get(0).functionCall()).isEmpty(); + assertThat(inlineJson(parts.get(0))).contains("call_123"); + } + + /** + * {@return the wrapped JSON payload of a part that {@link PartConverter} carried through as + * generic data} + * + *

A DataPart with no {@code adk_type} metadata is not converted into a function call, even + * when its data is shaped like one; it is serialized into an inline JSON blob instead. + */ + private static String inlineJson(com.google.genai.types.Part part) { + assertThat(part.inlineData()).isPresent(); + assertThat(part.inlineData().get().mimeType()).hasValue("text/plain"); + return new String(part.inlineData().get().data().get(), UTF_8); } @Test