// 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;
}
}
}