Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b190ebc
Migrate test infrastructure from WebHostBuilder to
michaelstaib Mar 27, 2026
ce41600
fixes
michaelstaib Mar 28, 2026
89d02df
CreateSlimBuilder
michaelstaib Mar 28, 2026
58b1d20
Make sse test stable
michaelstaib Mar 28, 2026
075c50b
increase timeout
michaelstaib Mar 28, 2026
29a1d6f
retrigger CI
michaelstaib Mar 29, 2026
8729750
edits
michaelstaib Apr 8, 2026
2146d26
edits
michaelstaib Apr 16, 2026
11821de
Merge origin/main into mst/webhostbuilder-migration
michaelstaib Apr 16, 2026
567c8bd
Merge branch 'main' into mst/webhostbuilder-migration
glen-84 Oct 25, 2026
13977de
Use RunTest in the Transport.Sockets.Client tests
glen-84 Oct 25, 2026
9046625
Migrate the adapter test servers to WebApplication
glen-84 Oct 25, 2026
ed75572
Rename the StrawberryShake test server helper to StartApp
glen-84 Oct 25, 2026
4f55516
Migrate FileUploadTests to WebApplication
glen-84 Oct 25, 2026
4b18437
Migrate the Nitro CLI web hosts to WebApplication
glen-84 Oct 25, 2026
30a182f
Stop exempting the deprecated web host warnings
glen-84 Oct 25, 2026
7ff245c
Stop test apps before disposal and build them with the empty builder
glen-84 Oct 25, 2026
dd95cdc
Remove the unused stream handling from the CookieCrumble formatters
glen-84 Oct 25, 2026
acf407a
Merge branch 'main' into mst/webhostbuilder-migration
glen-84 Oct 25, 2026
b684493
Stop the Nitro login listener before disposing it
glen-84 Oct 25, 2026
16a1701
Merge branch 'main' into mst/webhostbuilder-migration
glen-84 Oct 25, 2026
10bb80f
Wait for the unsubscribe before asserting no further subscription events
glen-84 Oct 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ anthropics
Antiforgery
apphost
appsettings
ASPDEPR004
ASPDEPR008
aspnet
aspnetcore
Astromech
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<PropertyGroup Condition="'$(TreatWarningsAsErrors)' == ''">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsNotAsErrors>NU1901;NU1902;NU1903;NU1904;ASPDEPR004;ASPDEPR008</WarningsNotAsErrors>
<WarningsNotAsErrors>NU1901;NU1902;NU1903;NU1904</WarningsNotAsErrors>
</PropertyGroup>

<PropertyGroup Condition="'$(TreatWarningsAsErrors)' == 'false'">
Expand Down
265 changes: 121 additions & 144 deletions src/HotChocolate/Adapters/test/Adapters.Mcp.Tests/CoreIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Configurations;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
Expand All @@ -29,26 +29,24 @@ await storage.AddOrUpdateToolAsync(
new OperationToolDefinition(
Utf8GraphQLParser.Parse("query GetBooks { books { title } }")),
TestContext.Current.CancellationToken);
var builder = new WebHostBuilder()
.ConfigureServices(
services => services
.AddRouting()
.AddGraphQL("NamedSchema")
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp()
.AddMcpStorage(storage))
.Configure(
app => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapGraphQLMcp()));
var server = new TestServer(builder);
var mcpClient = await CreateMcpClientAsync(server.CreateClient());
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddRouting()
.AddGraphQL("NamedSchema")
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp()
.AddMcpStorage(storage);
await using var webApp = webAppBuilder.Build();
webApp.MapGraphQLMcp();
webApp.Start();
var mcpClient = await CreateMcpClientAsync(webApp.GetTestClient());

// act
var tools = await mcpClient.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken);
Expand All @@ -66,31 +64,26 @@ await storage.AddOrUpdateToolAsync(
new OperationToolDefinition(
Utf8GraphQLParser.Parse("query GetBooks { books { title } }")),
TestContext.Current.CancellationToken);
var builder = new WebHostBuilder()
.ConfigureServices(
services =>
{
services
.AddRouting()
.AddGraphQL("NamedSchema")
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp();
services
.AddOptions<McpSetup>("NamedSchema")
.PostConfigure(setup => setup.StorageFactory = _ => storage);
})
.Configure(
app => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapGraphQLMcp()));
using var server = new TestServer(builder);
var mcpClient = await CreateMcpClientAsync(server.CreateClient());
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddRouting()
.AddGraphQL("NamedSchema")
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp();
webAppBuilder.Services
.AddOptions<McpSetup>("NamedSchema")
.PostConfigure(setup => setup.StorageFactory = _ => storage);
await using var webApp = webAppBuilder.Build();
webApp.MapGraphQLMcp();
webApp.Start();
var mcpClient = await CreateMcpClientAsync(webApp.GetTestClient());

// act
var tools = await mcpClient.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken);
Expand All @@ -103,19 +96,16 @@ await storage.AddOrUpdateToolAsync(
public void MapGraphQLMcp_Should_Throw_When_AddMcpNotCalled()
{
// arrange
var builder = new WebHostBuilder()
.ConfigureServices(
services => services
.AddRouting()
.AddGraphQL()
.AddQueryType<TestSchema.Query>())
.Configure(
app => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapGraphQLMcp()));
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddRouting()
.AddGraphQL()
.AddQueryType<TestSchema.Query>();
var webApp = webAppBuilder.Build();

// act
var exception = Assert.Throws<InvalidOperationException>(() => new TestServer(builder));
var exception = Assert.Throws<InvalidOperationException>(() => webApp.MapGraphQLMcp());

// assert
Assert.Equal(
Expand All @@ -128,37 +118,28 @@ public void MapGraphQLMcp_Should_NotBuildSchema_When_Mapping()
{
// arrange
var schemaBuilt = false;
var schemaBuiltWhileMapping = false;
var builder = new WebHostBuilder()
.ConfigureServices(
services => services
.AddRouting()
.AddGraphQLServer()
.ConfigureSchemaServices(_ => schemaBuilt = true)
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp()
.AddMcpStorage(new TestMcpStorage()))
.Configure(
app => app
.UseRouting()
.UseEndpoints(
endpoints =>
{
endpoints.MapGraphQLMcp();
schemaBuiltWhileMapping = schemaBuilt;
}));
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddRouting()
.AddGraphQLServer()
.ConfigureSchemaServices(_ => schemaBuilt = true)
.AddAuthorization()
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>()
.AddMcp()
.AddMcpStorage(new TestMcpStorage());
var webApp = webAppBuilder.Build();

// act
_ = new TestServer(builder);
webApp.MapGraphQLMcp();

// assert
Assert.False(schemaBuiltWhileMapping);
Assert.False(schemaBuilt);
}

[Fact]
Expand All @@ -174,21 +155,19 @@ await File.ReadAllTextAsync(
TestContext.Current.CancellationToken))),
TestContext.Current.CancellationToken);
var typeModule = new TestTypeModule();
var builder = new WebHostBuilder()
.ConfigureServices(
services => services
.AddRouting()
.AddGraphQL()
.AddTypeModule(_ => typeModule)
.AddMcp()
.AddMcpStorage(storage))
.Configure(
app => app
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapGraphQLMcp()));
var server = new TestServer(builder);
var mcpClient1 = await CreateMcpClientAsync(server.CreateClient());
var mcpClient2 = await CreateMcpClientAsync(server.CreateClient());
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddRouting()
.AddGraphQL()
.AddTypeModule(_ => typeModule)
.AddMcp()
.AddMcpStorage(storage);
await using var webApp = webAppBuilder.Build();
webApp.MapGraphQLMcp();
webApp.Start();
var mcpClient1 = await CreateMcpClientAsync(webApp.GetTestClient());
var mcpClient2 = await CreateMcpClientAsync(webApp.GetTestClient());
var listChangedResetEvent1 = new ManualResetEventSlim(false);
var listChangedResetEvent2 = new ManualResetEventSlim(false);
mcpClient1.RegisterNotificationHandler(
Expand All @@ -213,7 +192,7 @@ await File.ReadAllTextAsync(

if (listChangedResetEvent1.Wait(TimeSpan.FromSeconds(5), TestContext.Current.CancellationToken))
{
var mcpClient3 = await CreateMcpClientAsync(server.CreateClient());
var mcpClient3 = await CreateMcpClientAsync(webApp.GetTestClient());
updatedTools = await mcpClient3.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken);
}

Expand Down Expand Up @@ -247,54 +226,52 @@ protected override Task<TestServer> CreateTestServerAsync(
Action<McpServerOptions>? configureMcpServerOptions = null,
Action<IMcpServerBuilder>? configureMcpServer = null)
{
var builder = new WebHostBuilder()
.ConfigureServices(
services =>
{
services
.AddLogging()
.AddRouting()
.AddAuthentication()
.AddJwtBearer(
o => o.TokenValidationParameters =
new TokenValidationParameters
{
ValidIssuer = TokenIssuer,
ValidAudience = TokenAudience,
IssuerSigningKey = TokenKey
});
var webAppBuilder = WebApplication.CreateSlimBuilder();
webAppBuilder.WebHost.UseTestServer();
webAppBuilder.Services
.AddLogging()
.AddRouting()
.AddAuthentication()
.AddJwtBearer(
o => o.TokenValidationParameters =
new TokenValidationParameters
{
ValidIssuer = TokenIssuer,
ValidAudience = TokenAudience,
IssuerSigningKey = TokenKey
});

var builder =
services
.AddGraphQLServer()
.ModifyCostOptions(o => o.DefaultListSize = 1)
.AddAuthorization()
.AddMcp(configureMcpServerOptions, configureMcpServer)
.AddMcpStorage(storage)
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>();
var graphqlBuilder =
webAppBuilder.Services
.AddGraphQLServer()
.ModifyCostOptions(o => o.DefaultListSize = 1)
.AddAuthorization()
.AddMcp(configureMcpServerOptions, configureMcpServer)
.AddMcpStorage(storage)
.AddQueryType<TestSchema.Query>()
.AddMutationType<TestSchema.Mutation>()
.AddInterfaceType<TestSchema.IPet>()
.AddUnionType<TestSchema.IPet>()
.AddObjectType<TestSchema.Cat>()
.AddObjectType<TestSchema.Dog>();

if (additionalTypes is not null)
{
builder.AddTypes(additionalTypes);
}
if (additionalTypes is not null)
{
graphqlBuilder.AddTypes(additionalTypes);
}

if (diagnosticEventListener is not null)
{
builder.AddDiagnosticEventListener(_ => diagnosticEventListener);
}
})
.Configure(
app => app
.UseRouting()
.UseAuthentication()
.UseEndpoints(endpoints => endpoints.MapGraphQLMcp()));
if (diagnosticEventListener is not null)
{
graphqlBuilder.AddDiagnosticEventListener(_ => diagnosticEventListener);
}

var app = webAppBuilder.Build();
app.UseRouting();
app.UseAuthentication();
app.MapGraphQLMcp();
app.Start();

return Task.FromResult(new TestServer(builder));
return Task.FromResult(app.GetTestServer());
}

private sealed class TestTypeModule : TypeModule
Expand Down
Loading
Loading