csharp-sdk/tests/ModelContextProtocol.Tests/McpEndpointExtensionsTests.cs
Mackinnon Buck 38b4a26998
Restructure IMcpEndpoint, IMcpClient, and IMcpServer (#723)
* Remove `McpEndpoint` & `IMcpClient`

* Revise naming, add abstract classes

* Fix missing renames

* Move extension methods to instance methods

* Add back old API, but obsoleted

* Add back obsoleted factory classes

* Move deprecation attributes

* `SseClientTransport` -> `HttpClientTransport`

* Update src/ModelContextProtocol.Core/Server/AugmentedServiceProvider.cs

Co-authored-by: Stephen Halter <halter73@gmail.com>

* PR feedback

* PR feedback

* Add back dispose lock

* Fix docs projects

* PR feedback

* Undo `docs/*.md` changes

---------

Co-authored-by: Stephen Halter <halter73@gmail.com>
2025-09-16 10:22:10 -07:00

118 lines
No EOL
5 KiB
C#

using ModelContextProtocol.Protocol;
using Moq;
using System.Text.Json;
namespace ModelContextProtocol.Tests;
#pragma warning disable CS0618 // Type or member is obsolete
public class McpEndpointExtensionsTests
{
[Fact]
public async Task SendRequestAsync_Generic_Throws_When_Not_McpSession()
{
var endpoint = new Mock<IMcpEndpoint>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await McpEndpointExtensions.SendRequestAsync<string, int>(
endpoint, "method", "param", cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.SendRequestAsync' instead", ex.Message);
}
[Fact]
public async Task SendNotificationAsync_Parameterless_Throws_When_Not_McpSession()
{
var endpoint = new Mock<IMcpEndpoint>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await McpEndpointExtensions.SendNotificationAsync(
endpoint, "notify", cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.SendNotificationAsync' instead", ex.Message);
}
[Fact]
public async Task SendNotificationAsync_Generic_Throws_When_Not_McpSession()
{
var endpoint = new Mock<IMcpEndpoint>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await McpEndpointExtensions.SendNotificationAsync(
endpoint, "notify", "payload", cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.SendNotificationAsync' instead", ex.Message);
}
[Fact]
public async Task NotifyProgressAsync_Throws_When_Not_McpSession()
{
var endpoint = new Mock<IMcpEndpoint>(MockBehavior.Strict).Object;
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await McpEndpointExtensions.NotifyProgressAsync(
endpoint, new ProgressToken("t1"), new ProgressNotificationValue { Progress = 0.5f }, cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Prefer using 'McpServer.NotifyProgressAsync' instead", ex.Message);
}
[Fact]
public async Task SendRequestAsync_Generic_Forwards_To_McpSession_SendRequestAsync()
{
var mockSession = new Mock<McpSession> { CallBase = true };
mockSession
.Setup(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new JsonRpcResponse
{
Result = JsonSerializer.SerializeToNode(42, McpJsonUtilities.DefaultOptions),
});
IMcpEndpoint endpoint = mockSession.Object;
var result = await endpoint.SendRequestAsync<string, int>("method", "param", cancellationToken: TestContext.Current.CancellationToken);
Assert.Equal(42, result);
mockSession.Verify(s => s.SendRequestAsync(It.IsAny<JsonRpcRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task SendNotificationAsync_Parameterless_Forwards_To_McpSession_SendMessageAsync()
{
var mockSession = new Mock<McpSession> { CallBase = true };
mockSession
.Setup(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
IMcpEndpoint endpoint = mockSession.Object;
await endpoint.SendNotificationAsync("notify", cancellationToken: TestContext.Current.CancellationToken);
mockSession.Verify(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task SendNotificationAsync_Generic_Forwards_To_McpSession_SendMessageAsync()
{
var mockSession = new Mock<McpSession> { CallBase = true };
mockSession
.Setup(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
IMcpEndpoint endpoint = mockSession.Object;
await endpoint.SendNotificationAsync("notify", "payload", cancellationToken: TestContext.Current.CancellationToken);
mockSession.Verify(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task NotifyProgressAsync_Forwards_To_McpSession_SendMessageAsync()
{
var mockSession = new Mock<McpSession> { CallBase = true };
mockSession
.Setup(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()))
.Returns(Task.CompletedTask);
IMcpEndpoint endpoint = mockSession.Object;
await endpoint.NotifyProgressAsync(new ProgressToken("progress-token"), new ProgressNotificationValue { Progress = 1 }, cancellationToken: TestContext.Current.CancellationToken);
mockSession.Verify(s => s.SendMessageAsync(It.IsAny<JsonRpcMessage>(), It.IsAny<CancellationToken>()), Times.Once);
}
}