|
|
|
|
@ -122,159 +122,188 @@ public partial class McpServerResourceTests
|
|
|
|
|
public async Task UriTemplate_CreatedFromParameters_LotsOfTypesSupported()
|
|
|
|
|
{
|
|
|
|
|
const string Name = "Hello";
|
|
|
|
|
|
|
|
|
|
McpServerResource t;
|
|
|
|
|
ReadResourceResult? result;
|
|
|
|
|
IMcpServer server = new Mock<IMcpServer>().Object;
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create(() => "42", new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal("resource://mcp/Hello", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = "resource://mcp/Hello" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((IMcpServer server) => "42", new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal("resource://mcp/Hello", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = "resource://mcp/Hello" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((string arg1) => arg1, new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?arg1}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?arg1}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?arg1=wOrLd" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?arg1=wOrLd" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("wOrLd", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((string arg1, string? arg2 = null) => arg1 + arg2, new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?arg1,arg2}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?arg1,arg2}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?arg1=wo&arg2=rld" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?arg1=wo&arg2=rld" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("world", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((object a1, bool a2, char a3, byte a4, sbyte a5) => a1.ToString() + a2 + a3 + a4 + a5, new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=hi&a2=true&a3=s&a4=12&a5=34" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=hi&a2=true&a3=s&a4=12&a5=34" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("hiTrues1234", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((ushort a1, short a2, uint a3, int a4, ulong a5) => (a1 + a2 + a3 + a4 + (long)a5).ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=10&a2=20&a3=30&a4=40&a5=50" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=10&a2=20&a3=30&a4=40&a5=50" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("150", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((long a1, float a2, double a3, decimal a4, TimeSpan a5) => a5.ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=1&a2=2&a3=3&a4=4&a5=5" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=1&a2=2&a3=3&a4=4&a5=5" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("5.00:00:00", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((DateTime a1, DateTimeOffset a2, Uri a3, Guid a4, Version a5) => a4.ToString("N") + a5, new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1={DateTime.UtcNow:r}&a2={DateTimeOffset.UtcNow:r}&a3=http%3A%2F%2Ftest&a4=14e5f43d-0d41-47d6-8207-8249cf669e41&a5=1.2.3.4" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1={DateTime.UtcNow:r}&a2={DateTimeOffset.UtcNow:r}&a3=http%3A%2F%2Ftest&a4=14e5f43d-0d41-47d6-8207-8249cf669e41&a5=1.2.3.4" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("14e5f43d0d4147d682078249cf669e411.2.3.4", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((Half a2, Int128 a3, UInt128 a4, IntPtr a5) => (a3 + (Int128)a4 + a5).ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a2=1.0&a3=3&a4=4&a5=5" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a2=1.0&a3=3&a4=4&a5=5" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("12", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((UIntPtr a1, DateOnly a2, TimeOnly a3) => a1.ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=123&a2=0001-02-03&a3=01%3A02%3A03" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=123&a2=0001-02-03&a3=01%3A02%3A03" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("123", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((bool? a2, char? a3, byte? a4, sbyte? a5) => a2?.ToString() + a3 + a4 + a5, new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a2=true&a3=s&a4=12&a5=34" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a2=true&a3=s&a4=12&a5=34" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("Trues1234", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((ushort? a1, short? a2, uint? a3, int? a4, ulong? a5) => (a1 + a2 + a3 + a4 + (long?)a5).ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=10&a2=20&a3=30&a4=40&a5=50" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=10&a2=20&a3=30&a4=40&a5=50" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("150", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((long? a1, float? a2, double? a3, decimal? a4, TimeSpan? a5) => a5?.ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=1&a2=2&a3=3&a4=4&a5=5" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=1&a2=2&a3=3&a4=4&a5=5" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("5.00:00:00", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((DateTime? a1, DateTimeOffset? a2, Guid? a4) => a4?.ToString("N"), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a4}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a4}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1={DateTime.UtcNow:r}&a2={DateTimeOffset.UtcNow:r}&a4=14e5f43d-0d41-47d6-8207-8249cf669e41" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1={DateTime.UtcNow:r}&a2={DateTimeOffset.UtcNow:r}&a4=14e5f43d-0d41-47d6-8207-8249cf669e41" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("14e5f43d0d4147d682078249cf669e41", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((Half? a2, Int128? a3, UInt128? a4, IntPtr? a5) => (a3 + (Int128?)a4 + a5).ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a2,a3,a4,a5}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a2=1.0&a3=3&a4=4&a5=5" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a2=1.0&a3=3&a4=4&a5=5" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("12", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
t = McpServerResource.Create((UIntPtr? a1, DateOnly? a2, TimeOnly? a3) => a1?.ToString(), new() { Name = Name });
|
|
|
|
|
Assert.Equal($"resource://{Name}{{?a1,a2,a3}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal($"resource://mcp/Hello{{?a1,a2,a3}}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://{Name}?a1=123&a2=0001-02-03&a3=01%3A02%3A03" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(server) { Params = new() { Uri = $"resource://mcp/Hello?a1=123&a2=0001-02-03&a3=01%3A02%3A03" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("123", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory]
|
|
|
|
|
[InlineData("resource://Hello?arg1=42&arg2=84")]
|
|
|
|
|
[InlineData("resource://Hello?arg1=42&arg2=84&arg3=123")]
|
|
|
|
|
[InlineData("resource://Hello#fragment")]
|
|
|
|
|
[InlineData("resource://mcp/Hello?arg1=42&arg2=84")]
|
|
|
|
|
[InlineData("resource://mcp/Hello?arg1=42&arg2=84&arg3=123")]
|
|
|
|
|
[InlineData("resource://mcp/Hello#fragment")]
|
|
|
|
|
public async Task UriTemplate_NonMatchingUri_ReturnsNull(string uri)
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t = McpServerResource.Create((string arg1) => arg1, new() { Name = "Hello" });
|
|
|
|
|
Assert.Equal("resource://Hello{?arg1}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal("resource://mcp/Hello{?arg1}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Null(await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = uri } },
|
|
|
|
|
TestContext.Current.CancellationToken));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory]
|
|
|
|
|
[InlineData("resource://Hello?arg1=test")]
|
|
|
|
|
[InlineData("resource://Hello?arg2=test")]
|
|
|
|
|
[InlineData("resource://MyCoolResource", "resource://mycoolresource")]
|
|
|
|
|
[InlineData("resource://MyCoolResource{?arg1}", "resource://mycoolresource?arg1=42")]
|
|
|
|
|
public async Task UriTemplate_IsHostCaseInsensitive(string actualUri, string queriedUri)
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t = McpServerResource.Create(() => "resource", new() { UriTemplate = actualUri });
|
|
|
|
|
Assert.NotNull(await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = queriedUri } },
|
|
|
|
|
TestContext.Current.CancellationToken));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task ResourceCollection_UsesCaseInsensitiveHostLookup()
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t1 = McpServerResource.Create(() => "resource", new() { UriTemplate = "resource://MyCoolResource" });
|
|
|
|
|
McpServerResource t2 = McpServerResource.Create(() => "resource", new() { UriTemplate = "resource://MyCoolResource2" });
|
|
|
|
|
McpServerResourceCollection collection = new() { t1, t2 };
|
|
|
|
|
Assert.True(collection.TryGetPrimitive("resource://mycoolresource", out McpServerResource? result));
|
|
|
|
|
Assert.Same(t1, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public void MimeType_DefaultsToOctetStream()
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t = McpServerResource.Create(() => "resource", new() { Name = "My Cool Resource" });
|
|
|
|
|
Assert.Equal("application/octet-stream", t.ProtocolResourceTemplate.MimeType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Theory]
|
|
|
|
|
[InlineData("resource://mcp/Hello?arg1=test")]
|
|
|
|
|
[InlineData("resource://mcp/Hello?arg2=test")]
|
|
|
|
|
public async Task UriTemplate_MissingParameter_Throws(string uri)
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t = McpServerResource.Create((string arg1, int arg2) => arg1, new() { Name = "Hello" });
|
|
|
|
|
Assert.Equal("resource://Hello{?arg1,arg2}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal("resource://mcp/Hello{?arg1,arg2}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
await Assert.ThrowsAsync<ArgumentException>(async () => await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = uri } },
|
|
|
|
|
TestContext.Current.CancellationToken));
|
|
|
|
|
@ -284,30 +313,30 @@ public partial class McpServerResourceTests
|
|
|
|
|
public async Task UriTemplate_MissingOptionalParameter_Succeeds()
|
|
|
|
|
{
|
|
|
|
|
McpServerResource t = McpServerResource.Create((string? arg1 = null, int? arg2 = null) => arg1 + arg2, new() { Name = "Hello" });
|
|
|
|
|
Assert.Equal("resource://Hello{?arg1,arg2}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
Assert.Equal("resource://mcp/Hello{?arg1,arg2}", t.ProtocolResourceTemplate.UriTemplate);
|
|
|
|
|
|
|
|
|
|
ReadResourceResult? result;
|
|
|
|
|
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://Hello" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://mcp/Hello" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://Hello?arg1=first" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://mcp/Hello?arg1=first" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("first", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://Hello?arg2=42" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://mcp/Hello?arg2=42" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
|
|
|
|
|
result = await t.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://Hello?arg1=first&arg2=42" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://mcp/Hello?arg1=first&arg2=42" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("first42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
@ -325,7 +354,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
}, new() { Name = "Test" });
|
|
|
|
|
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
@ -376,11 +405,11 @@ public partial class McpServerResourceTests
|
|
|
|
|
Mock<IMcpServer> mockServer = new();
|
|
|
|
|
|
|
|
|
|
await Assert.ThrowsAnyAsync<ArgumentException>(async () => await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken));
|
|
|
|
|
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Services = services, Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Services = services, Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
@ -402,7 +431,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
}, new() { Services = services, Name = "Test" });
|
|
|
|
|
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(new Mock<IMcpServer>().Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal("42", ((TextResourceContents)result.Contents[0]).Text);
|
|
|
|
|
@ -436,7 +465,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
return new ReadResourceResult { Contents = new List<ResourceContents> { new TextResourceContents { Text = "hello" } } };
|
|
|
|
|
}, new() { Name = "Test" });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Single(result.Contents);
|
|
|
|
|
@ -453,7 +482,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
return new TextResourceContents { Text = "hello" };
|
|
|
|
|
}, new() { Name = "Test", SerializerOptions = JsonContext6.Default.Options });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Single(result.Contents);
|
|
|
|
|
@ -474,7 +503,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
];
|
|
|
|
|
}, new() { Name = "Test" });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal(2, result.Contents.Count);
|
|
|
|
|
@ -492,7 +521,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
return "42";
|
|
|
|
|
}, new() { Name = "Test" });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Single(result.Contents);
|
|
|
|
|
@ -509,7 +538,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
return new List<string> { "42", "43" };
|
|
|
|
|
}, new() { Name = "Test", SerializerOptions = JsonContext6.Default.Options });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal(2, result.Contents.Count);
|
|
|
|
|
@ -527,7 +556,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
return new DataContent(new byte[] { 0, 1, 2 }, "application/octet-stream");
|
|
|
|
|
}, new() { Name = "Test" });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Single(result.Contents);
|
|
|
|
|
@ -549,7 +578,7 @@ public partial class McpServerResourceTests
|
|
|
|
|
};
|
|
|
|
|
}, new() { Name = "Test", SerializerOptions = JsonContext6.Default.Options });
|
|
|
|
|
var result = await resource.ReadAsync(
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://Test" } },
|
|
|
|
|
new RequestContext<ReadResourceRequestParams>(mockServer.Object) { Params = new() { Uri = "resource://mcp/Test" } },
|
|
|
|
|
TestContext.Current.CancellationToken);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Equal(2, result.Contents.Count);
|
|
|
|
|
|