// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using A2A; namespace Microsoft.Agents.AI.A2A.UnitTests; /// /// Unit tests for the class. /// public sealed class A2ACardResolverExtensionsTests : IDisposable { private readonly HttpClient _httpClient; private readonly HttpMessageHandlerStub _handler; private readonly A2ACardResolver _resolver; public A2ACardResolverExtensionsTests() { this._handler = new HttpMessageHandlerStub(); this._httpClient = new HttpClient(this._handler, false); this._resolver = new A2ACardResolver(new Uri("http://test-host"), httpClient: this._httpClient); } [Fact] public async Task GetAIAgentAsync_WithValidAgentCard_ReturnsAIAgentAsync() { // Arrange this._handler.ResponsesToReturn.Enqueue(new AgentCard { Name = "Test Agent", Description = "A test agent for unit testing", Url = "http://test-endpoint/agent" }); // Act var agent = await this._resolver.GetAIAgentAsync(); // Assert Assert.NotNull(agent); Assert.IsType(agent); Assert.Equal("Test Agent", agent.Name); Assert.Equal("A test agent for unit testing", agent.Description); // Verify that there was only one request made to retrieve the agent card Assert.Single(this._handler.CapturedUris); Assert.StartsWith("http://test-host/", this._handler.CapturedUris[0].ToString()); } [Fact] public async Task RunIAgentAsync_WithUrlFromAgentCard_SendsRequestToTheUrlAsync() { // Arrange this._handler.ResponsesToReturn.Enqueue(new AgentCard { Url = "http://test-endpoint/agent" }); this._handler.ResponsesToReturn.Enqueue(new AgentMessage { Role = MessageRole.Agent, Parts = [new TextPart { Text = "Response" }], }); var agent = await this._resolver.GetAIAgentAsync(this._httpClient); // Act await agent.RunAsync("Test input"); // Assert Assert.Equal(2, this._handler.CapturedUris.Count); // One for getting the card, one for sending the message to the agent Assert.Equal(new Uri("http://test-endpoint/agent"), this._handler.CapturedUris[1]); } public void Dispose() { this._handler.Dispose(); this._httpClient.Dispose(); } internal sealed class HttpMessageHandlerStub : HttpMessageHandler { public Queue ResponsesToReturn { get; } = new(); public List CapturedUris { get; } = []; protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { this.CapturedUris.Add(request.RequestUri!); var response = this.ResponsesToReturn.Dequeue(); if (response is AgentCard agentCard) { var json = JsonSerializer.Serialize(agentCard); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(json, Encoding.UTF8, "application/json") }; } else if (response is AgentMessage message) { var jsonRpcResponse = JsonRpcResponse.CreateJsonRpcResponse("response-id", message); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonSerializer.Serialize(jsonRpcResponse), Encoding.UTF8, "application/json") }; } // Return empty agent card if none specified var emptyCard = new AgentCard(); var emptyJson = JsonSerializer.Serialize(emptyCard); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(emptyJson, Encoding.UTF8, "application/json") }; } } }