// Copyright (c) Microsoft. All rights reserved. using System; using System.Text.Json; using Microsoft.Extensions.AI; namespace Microsoft.Agents.AI.A2A.UnitTests; /// /// Unit tests for the class. /// public sealed class A2AContinuationTokenTests { [Fact] public void Constructor_WithValidTaskId_InitializesTaskIdProperty() { // Arrange const string TaskId = "task-123"; // Act var token = new A2AContinuationToken(TaskId); // Assert Assert.Equal(TaskId, token.TaskId); } [Fact] public void ToBytes_WithValidToken_SerializesToJsonBytes() { // Arrange const string TaskId = "task-456"; var token = new A2AContinuationToken(TaskId); // Act var bytes = token.ToBytes(); // Assert Assert.NotEqual(0, bytes.Length); var jsonString = System.Text.Encoding.UTF8.GetString(bytes.ToArray()); using var jsonDoc = JsonDocument.Parse(jsonString); var root = jsonDoc.RootElement; Assert.True(root.TryGetProperty("taskId", out var taskIdElement)); Assert.Equal(TaskId, taskIdElement.GetString()); } [Fact] public void FromToken_WithA2AContinuationToken_ReturnsSameInstance() { // Arrange const string TaskId = "task-direct"; var originalToken = new A2AContinuationToken(TaskId); // Act var resultToken = A2AContinuationToken.FromToken(originalToken); // Assert Assert.Same(originalToken, resultToken); Assert.Equal(TaskId, resultToken.TaskId); } [Fact] public void FromToken_WithSerializedToken_DeserializesCorrectly() { // Arrange const string TaskId = "task-deserialized"; var originalToken = new A2AContinuationToken(TaskId); var serialized = originalToken.ToBytes(); // Create a mock token wrapper to pass to FromToken var mockToken = new MockResponseContinuationToken(serialized); // Act var resultToken = A2AContinuationToken.FromToken(mockToken); // Assert Assert.Equal(TaskId, resultToken.TaskId); Assert.IsType(resultToken); } [Fact] public void FromToken_RoundTrip_PreservesTaskId() { // Arrange const string TaskId = "task-roundtrip-123"; var originalToken = new A2AContinuationToken(TaskId); var serialized = originalToken.ToBytes(); var mockToken = new MockResponseContinuationToken(serialized); // Act var deserializedToken = A2AContinuationToken.FromToken(mockToken); var reserialized = deserializedToken.ToBytes(); var mockToken2 = new MockResponseContinuationToken(reserialized); var deserializedAgain = A2AContinuationToken.FromToken(mockToken2); // Assert Assert.Equal(TaskId, deserializedAgain.TaskId); } [Fact] public void FromToken_WithEmptyData_ThrowsArgumentException() { // Arrange var emptyToken = new MockResponseContinuationToken(ReadOnlyMemory.Empty); // Act & Assert Assert.Throws(() => A2AContinuationToken.FromToken(emptyToken)); } [Fact] public void FromToken_WithMissingTaskIdProperty_ThrowsException() { // Arrange var jsonWithoutTaskId = System.Text.Encoding.UTF8.GetBytes("{ \"someOtherProperty\": \"value\" }").AsMemory(); var mockToken = new MockResponseContinuationToken(jsonWithoutTaskId); // Act & Assert Assert.Throws(() => A2AContinuationToken.FromToken(mockToken)); } [Fact] public void FromToken_WithValidTaskId_ParsesTaskIdCorrectly() { // Arrange const string TaskId = "task-multi-prop"; var json = System.Text.Encoding.UTF8.GetBytes($"{{ \"taskId\": \"{TaskId}\" }}").AsMemory(); var mockToken = new MockResponseContinuationToken(json); // Act var resultToken = A2AContinuationToken.FromToken(mockToken); // Assert Assert.Equal(TaskId, resultToken.TaskId); } /// /// Mock implementation of ResponseContinuationToken for testing. /// private sealed class MockResponseContinuationToken : ResponseContinuationToken { private readonly ReadOnlyMemory _data; public MockResponseContinuationToken(ReadOnlyMemory data) { this._data = data; } public override ReadOnlyMemory ToBytes() { return this._data; } } }