Skip to content

Commit 77b0c7b

Browse files
authored
chore: Adding some testing on toProto conversion. (#223)
Checking that optional parameters not being set doesn't lead to a NullPointerException. Signed-off-by: Emmanuel Hugonnet <[email protected]>
1 parent 81b4a6b commit 77b0c7b

File tree

4 files changed

+355
-34
lines changed

4 files changed

+355
-34
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,5 @@ nb-configuration.xml
4343
/.quarkus/cli/plugins/
4444
# TLS Certificates
4545
.certs/
46+
nbproject/
47+

spec-grpc/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@
5353
<artifactId>javax.annotation-api</artifactId>
5454
<scope>provided</scope>
5555
</dependency>
56+
<dependency>
57+
<groupId>org.junit.jupiter</groupId>
58+
<artifactId>junit-jupiter-api</artifactId>
59+
<scope>test</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.junit.jupiter</groupId>
63+
<artifactId>junit-jupiter-params</artifactId>
64+
<scope>test</scope>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.junit.jupiter</groupId>
68+
<artifactId>junit-jupiter-engine</artifactId>
69+
<scope>test</scope>
70+
</dependency>
5671
</dependencies>
5772

5873
<build>

spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.a2a.grpc.utils;
22

3+
34
import java.nio.charset.StandardCharsets;
45
import java.time.Instant;
56
import java.time.LocalDateTime;
@@ -61,6 +62,7 @@
6162
* Utility class to convert between GRPC and Spec objects.
6263
*/
6364
public class ProtoUtils {
65+
6466
public static class ToProto {
6567

6668
public static io.a2a.grpc.AgentCard agentCard(AgentCard agentCard) {
@@ -143,8 +145,12 @@ public static io.a2a.grpc.Task task(Task task) {
143145
public static io.a2a.grpc.Message message(Message message) {
144146
io.a2a.grpc.Message.Builder builder = io.a2a.grpc.Message.newBuilder();
145147
builder.setMessageId(message.getMessageId());
146-
builder.setContextId(message.getContextId());
147-
builder.setTaskId(message.getTaskId());
148+
if (message.getContextId() != null) {
149+
builder.setContextId(message.getContextId());
150+
}
151+
if (message.getTaskId() != null) {
152+
builder.setTaskId(message.getTaskId());
153+
}
148154
builder.setRole(role(message.getRole()));
149155
if (message.getParts() != null) {
150156
builder.addAllContent(message.getParts().stream().map(ToProto::part).collect(Collectors.toList()));
@@ -171,7 +177,7 @@ private static io.a2a.grpc.PushNotificationConfig pushNotificationConfig(PushNot
171177
if (config.authentication() != null) {
172178
builder.setAuthentication(authenticationInfo(config.authentication()));
173179
}
174-
if (config.id() != null) {
180+
if (config.id() != null) {
175181
builder.setId(config.id());
176182
}
177183
return builder.build();
@@ -182,8 +188,12 @@ public static io.a2a.grpc.TaskArtifactUpdateEvent taskArtifactUpdateEvent(TaskAr
182188
builder.setTaskId(event.getTaskId());
183189
builder.setContextId(event.getContextId());
184190
builder.setArtifact(artifact(event.getArtifact()));
185-
builder.setAppend(event.isAppend() == null ? false : event.isAppend());
186-
builder.setLastChunk(event.isLastChunk() == null ? false : event.isLastChunk());
191+
if (event.isAppend() != null) {
192+
builder.setAppend(event.isAppend());
193+
}
194+
if (event.isLastChunk() != null) {
195+
builder.setLastChunk(event.isLastChunk());
196+
}
187197
if (event.getMetadata() != null) {
188198
builder.setMetadata(struct(event.getMetadata()));
189199
}
@@ -258,8 +268,10 @@ private static io.a2a.grpc.Role role(Message.Role role) {
258268
return io.a2a.grpc.Role.ROLE_UNSPECIFIED;
259269
}
260270
return switch (role) {
261-
case USER -> io.a2a.grpc.Role.ROLE_USER;
262-
case AGENT -> io.a2a.grpc.Role.ROLE_AGENT;
271+
case USER ->
272+
io.a2a.grpc.Role.ROLE_USER;
273+
case AGENT ->
274+
io.a2a.grpc.Role.ROLE_AGENT;
263275
};
264276
}
265277

@@ -283,15 +295,24 @@ private static io.a2a.grpc.TaskState taskState(TaskState taskState) {
283295
return io.a2a.grpc.TaskState.TASK_STATE_UNSPECIFIED;
284296
}
285297
return switch (taskState) {
286-
case SUBMITTED -> io.a2a.grpc.TaskState.TASK_STATE_SUBMITTED;
287-
case WORKING -> io.a2a.grpc.TaskState.TASK_STATE_WORKING;
288-
case INPUT_REQUIRED -> io.a2a.grpc.TaskState.TASK_STATE_INPUT_REQUIRED;
289-
case AUTH_REQUIRED -> io.a2a.grpc.TaskState.TASK_STATE_AUTH_REQUIRED;
290-
case COMPLETED -> io.a2a.grpc.TaskState.TASK_STATE_COMPLETED;
291-
case CANCELED -> io.a2a.grpc.TaskState.TASK_STATE_CANCELLED;
292-
case FAILED -> io.a2a.grpc.TaskState.TASK_STATE_FAILED;
293-
case REJECTED -> io.a2a.grpc.TaskState.TASK_STATE_REJECTED;
294-
default -> io.a2a.grpc.TaskState.TASK_STATE_UNSPECIFIED;
298+
case SUBMITTED ->
299+
io.a2a.grpc.TaskState.TASK_STATE_SUBMITTED;
300+
case WORKING ->
301+
io.a2a.grpc.TaskState.TASK_STATE_WORKING;
302+
case INPUT_REQUIRED ->
303+
io.a2a.grpc.TaskState.TASK_STATE_INPUT_REQUIRED;
304+
case AUTH_REQUIRED ->
305+
io.a2a.grpc.TaskState.TASK_STATE_AUTH_REQUIRED;
306+
case COMPLETED ->
307+
io.a2a.grpc.TaskState.TASK_STATE_COMPLETED;
308+
case CANCELED ->
309+
io.a2a.grpc.TaskState.TASK_STATE_CANCELLED;
310+
case FAILED ->
311+
io.a2a.grpc.TaskState.TASK_STATE_FAILED;
312+
case REJECTED ->
313+
io.a2a.grpc.TaskState.TASK_STATE_REJECTED;
314+
default ->
315+
io.a2a.grpc.TaskState.TASK_STATE_UNSPECIFIED;
295316
};
296317
}
297318

@@ -596,7 +617,6 @@ public static io.a2a.grpc.SendMessageResponse taskOrMessage(EventKind eventKind)
596617
}
597618
}
598619

599-
600620
}
601621

602622
public static class FromProto {
@@ -734,8 +754,8 @@ public static Message message(io.a2a.grpc.Message message) {
734754
return new Message(
735755
role(message.getRole()),
736756
message.getContentList().stream().map(item -> part(item)).collect(Collectors.toList()),
737-
message.getMessageId(),
738-
message.getContextId(),
757+
message.getMessageId().isEmpty() ? null : message.getMessageId(),
758+
message.getContextId().isEmpty() ? null : message.getContextId(),
739759
message.getTaskId(),
740760
null, // referenceTaskIds is not in grpc message
741761
struct(message.getMetadata())
@@ -814,9 +834,12 @@ private static Message.Role role(io.a2a.grpc.Role role) {
814834
return null;
815835
}
816836
return switch (role) {
817-
case ROLE_USER -> Message.Role.USER;
818-
case ROLE_AGENT -> Message.Role.AGENT;
819-
default -> null;
837+
case ROLE_USER ->
838+
Message.Role.USER;
839+
case ROLE_AGENT ->
840+
Message.Role.AGENT;
841+
default ->
842+
null;
820843
};
821844
}
822845

@@ -825,16 +848,26 @@ private static TaskState taskState(io.a2a.grpc.TaskState taskState) {
825848
return null;
826849
}
827850
return switch (taskState) {
828-
case TASK_STATE_SUBMITTED -> TaskState.SUBMITTED;
829-
case TASK_STATE_WORKING -> TaskState.WORKING;
830-
case TASK_STATE_INPUT_REQUIRED -> TaskState.INPUT_REQUIRED;
831-
case TASK_STATE_AUTH_REQUIRED -> TaskState.AUTH_REQUIRED;
832-
case TASK_STATE_COMPLETED -> TaskState.COMPLETED;
833-
case TASK_STATE_CANCELLED -> TaskState.CANCELED;
834-
case TASK_STATE_FAILED -> TaskState.FAILED;
835-
case TASK_STATE_REJECTED -> TaskState.REJECTED;
836-
case TASK_STATE_UNSPECIFIED -> null;
837-
case UNRECOGNIZED -> null;
851+
case TASK_STATE_SUBMITTED ->
852+
TaskState.SUBMITTED;
853+
case TASK_STATE_WORKING ->
854+
TaskState.WORKING;
855+
case TASK_STATE_INPUT_REQUIRED ->
856+
TaskState.INPUT_REQUIRED;
857+
case TASK_STATE_AUTH_REQUIRED ->
858+
TaskState.AUTH_REQUIRED;
859+
case TASK_STATE_COMPLETED ->
860+
TaskState.COMPLETED;
861+
case TASK_STATE_CANCELLED ->
862+
TaskState.CANCELED;
863+
case TASK_STATE_FAILED ->
864+
TaskState.FAILED;
865+
case TASK_STATE_REJECTED ->
866+
TaskState.REJECTED;
867+
case TASK_STATE_UNSPECIFIED ->
868+
null;
869+
case UNRECOGNIZED ->
870+
null;
838871
};
839872
}
840873

@@ -867,5 +900,4 @@ private static Object value(Value value) {
867900
}
868901
}
869902

870-
871-
}
903+
}

0 commit comments

Comments
 (0)