Fix resource subscription handling (#89)

* Fix resource subscription handling
Add resource subscription tests

* Fix typo

* Typo

* small fixes

* Fix concurrency issue with test

* Align with specification schemas
This commit is contained in:
Peder Holdgaard Pedersen 2025-03-17 17:54:29 +01:00 • committed by GitHub
commit 34a6f1c665
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3,6 +3,7 @@ using McpDotNet.Configuration;
using McpDotNet.Protocol.Messages;
using McpDotNet.Protocol.Transport;
using McpDotNet.Protocol.Types;
using System.Text.Json;
namespace McpDotNet.Tests;
@ -208,6 +209,67 @@ public class ClientIntegrationTests : IClassFixture<ClientIntegrationTestFixture
Assert.NotNull(result.Contents[0].Blob);
}
// Not supported by "everything" server version on npx
[Fact]
public async Task SubscribeResource_Stdio()
{
// arrange
var clientId = "test_server";
// act
int counter = 0;
await using var client = await _fixture.CreateClientAsync(clientId);
client.AddNotificationHandler(NotificationMethods.ResourceUpdatedNotification, (notification) =>
{
var notificationParams = JsonSerializer.Deserialize<ResourceUpdatedNotificationParams>(notification.Params!.ToString() ?? string.Empty);
++counter;
return Task.CompletedTask;
});
await client.SubscribeToResourceAsync("test://static/resource/1", CancellationToken.None);
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification
await Task.Delay(10000);
// assert
Assert.True(counter > 0);
}
// Not supported by "everything" server version on npx
[Fact]
public async Task UnsubscribeResource_Stdio()
{
// arrange
var clientId = "test_server";
// act
int counter = 0;
await using var client = await _fixture.CreateClientAsync(clientId);
client.AddNotificationHandler(NotificationMethods.ResourceUpdatedNotification, (notification) =>
{
var notificationParams = JsonSerializer.Deserialize<ResourceUpdatedNotificationParams>(notification.Params!.ToString() ?? string.Empty);
++counter;
return Task.CompletedTask;
});
await client.SubscribeToResourceAsync("test://static/resource/1", CancellationToken.None);
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification
await Task.Delay(10000);
// reset counter
int counterAfterSubscribe = counter;
// unsubscribe
await client.UnsubscribeFromResourceAsync("test://static/resource/1", CancellationToken.None);
counter = 0;
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we would've gotten at least one notification
await Task.Delay(10000);
// assert
Assert.True(counterAfterSubscribe > 0);
Assert.Equal(0, counter);
}
[Theory]
[MemberData(nameof(GetClients))]
public async Task GetCompletion_Stdio_ResourceReference(string clientId)