From 090a84bc9271e2a1bee67f9f22755dd84e4c18c7 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Wed, 31 Jul 2019 13:51:54 +0200 Subject: [PATCH] Server Modularization (#940) --- CHANGELOG.md | 7 +- CONTRIBUTION.md | 2 +- README.md | 2 +- .../Execution/IQueryRequestBuilder.cs | 2 +- .../Execution/QueryRequestBuilder.cs | 10 +- .../Batching/BatchQueryExecutionResult.cs | 1 + .../Execution/JsonQueryResultSerializer.cs | 13 +- .../Middleware/ParseQueryMiddleware.cs | 57 +- .../Middleware/ValidateQueryMiddleware.cs | 1 - src/Core/Language/Utf8/GraphQLRequest.cs | 8 +- .../Utf8/Utf8GraphQLRequestParser.Request.cs | 2 + .../Language/Utf8/Utf8GraphQLRequestParser.cs | 35 +- src/Core/Types/InternalsVisibleTo.cs | 1 + .../Contracts/IInterfaceTypeDescriptor.cs | 6 +- .../Contracts/IInterfaceTypeDescriptor~1.cs | 17 +- .../Contracts/IObjectTypeDescriptor.cs | 6 +- .../Definitions/ITypeConfigration.cs | 2 +- .../Descriptors/InterfaceTypeDescriptor.cs | 8 +- .../Descriptors/InterfaceTypeDescriptor~1.cs | 16 +- .../Descriptors/ObjectFieldDescriptor.cs | 8 +- .../Types/Descriptors/ObjectTypeDescriptor.cs | 20 +- .../Descriptors/ObjectTypeDescriptor~1.cs | 16 +- src/Core/Types/Types/EnumType.cs | 4 +- .../AspNetClassic.Abstractions.csproj | 10 +- .../AspNetClassic.Authorization.csproj | 2 +- .../AspNetClassic.GraphiQL.csproj | 2 +- .../AspNetClassic.HttpGet.csproj | 36 + .../HttpGetApplicationBuilderExtensions.cs | 52 ++ .../AspNetClassic.HttpGetSchema.csproj | 39 + ...tpGetSchemaApplicationBuilderExtensions.cs | 46 + .../AspNetClassic.HttpPost.csproj | 39 + .../HttpPostApplicationBuilderExtensions.cs | 69 ++ .../AspNetClassic.Playground.csproj | 2 +- .../ApplicationBuilderTests.cs | 408 ++++++++ .../AspNetClassic.Tests.csproj | 8 +- .../AspNetClassic.Tests/GetMiddlewareTests.cs | 33 + .../Helpers/ClientQueryRequest.cs | 7 +- .../Helpers/ClientQueryResult.cs | 5 +- .../Helpers/ServiceCollectionExtensions.cs | 29 + .../Helpers/TestServerExtensions.cs | 15 +- .../Helpers/TestServerFactory.cs | 18 +- .../HttpGetMiddlewareOptionsTests.cs | 35 + .../HttpGetSchemaMiddlewareOptionsTests.cs | 35 + .../HttpPostMiddlewareOptionsTests.cs | 102 ++ .../PostMiddlewareTests.cs | 713 ++++++++++++++ .../QueryMiddlewareOptionsTests.cs | 75 ++ .../QueryMiddlewareTests.cs | 417 --------- src/Server/AspNetClassic.Tests/Schema/Foo.cs | 14 - .../Schema/FooInputType.cs | 13 - .../AspNetClassic.Tests/Schema/Query.cs | 81 -- .../AspNetClassic.Tests/Schema/QueryType.cs | 27 - .../AspNetClassic.Tests/Schema/TestEnum.cs | 8 - .../AspNetClassic.Tests/Schema/TestService.cs | 7 - .../AspNetClassic.Tests/ServerTestBase.cs | 46 + .../ServiceCollectionExtensionsTests.cs | 872 ++++++++++++++++++ ...eGraphQLHttpGetSchema_BuilderServices.snap | 124 +++ ...LHttpGetSchema_BuilderServicesOptions.snap | 124 +++ ...sts.UseGraphQLHttpGet_BuilderServices.snap | 9 + ...GraphQLHttpGet_BuilderServicesOptions.snap | 9 + ...ts.UseGraphQLHttpPost_BuilderServices.snap | 9 + ...raphQLHttpPost_BuilderServicesOptions.snap | 9 + .../GetMiddlewareTests.HttpGet_QueryOnly.snap | 9 + .../__snapshots__/HttpGet_BasicTest.json | 8 - .../__snapshots__/HttpPost_BasicTest.json | 8 - .../__snapshots__/HttpPost_Casing.json | 8 - .../HttpPost_CustomProperties.json | 6 - .../__snapshots__/HttpPost_EnumArgument.json | 6 - .../HttpPost_GraphQLRequest.json | 6 - .../HttpPost_NestedEnumArgument.json | 6 - .../HttpPost_WithHttpContext.json | 8 - .../HttpPost_WithObjectVariables.json | 10 - .../HttpPost_WithScalarVariables.json | 10 - .../HttpPost_WithScopedService.json | 6 - .../PostMiddlewareTests.HttpPost_Batch.snap | 20 + ..._Response_Casing_Alignes_With_Request.snap | 9 + ...lewareTests.HttpPost_Json_CachedQuery.snap | 9 + ...wareTests.HttpPost_Json_CachedQuery_2.snap | 9 + ...ts.HttpPost_Json_CachedQuery_NotFound.snap | 12 + ...reTests.HttpPost_Json_Object_Variable.snap | 10 + ...tMiddlewareTests.HttpPost_Json_OnRoot.snap | 9 + ...ddlewareTests.HttpPost_Json_OnSubPath.snap | 9 + ...ts.HttpPost_Json_QueryAndEnumVariable.snap | 9 + ...HttpPost_Json_QueryAndOperationName_a.snap | 9 + ...HttpPost_Json_QueryAndOperationName_b.snap | 9 + ....HttpPost_Json_QueryAndStringVariable.snap | 9 + ...ddlewareTests.HttpPost_Json_QueryOnly.snap | 9 + ...reTests.HttpPost_Json_Unused_Variable.snap | 15 + ...pPost_Json_Variable_NonNull_Violation.snap | 18 + ...pPost_Json_Variables_In_Object_Fields.snap | 10 + ...dlewareTests.HttpPost_Operation_Batch.snap | 20 + ...Post_Operation_Batch_Invalid_Argument.snap | 10 + ...iddlewareTests.HttpPost_Path__Slash__.snap | 9 + ...reTests.HttpPost_Path__Slash___Slash_.snap | 9 + ...__Slash_graphql_Slash___Slash_graphql.snap | 9 + ..._graphql_Slash___Slash_graphql_Slash_.snap | 9 + ...ql_Slash_foo__Slash_graphql_Slash_foo.snap | 9 + ...h_foo__Slash_graphql_Slash_foo_Slash_.snap | 9 + ...st_Path__Slash_graphql__Slash_graphql.snap | 9 + ...__Slash_graphql__Slash_graphql_Slash_.snap | 9 + ...iddlewareTests.HttpPost_Plain_GraphQL.snap | 9 + ...ueryMiddlewareTests.HttpGet_BasicTest.snap | 8 - ...eryMiddlewareTests.HttpPost_BasicTest.snap | 8 - .../QueryMiddlewareTests.HttpPost_Casing.snap | 8 - ...lewareTests.HttpPost_CustomProperties.snap | 6 - ...MiddlewareTests.HttpPost_EnumArgument.snap | 6 - ...ddlewareTests.HttpPost_GraphQLRequest.snap | 6 - ...wareTests.HttpPost_NestedEnumArgument.snap | 6 - ...dlewareTests.HttpPost_WithHttpContext.snap | 8 - ...areTests.HttpPost_WithObjectVariables.snap | 10 - ...areTests.HttpPost_WithScalarVariables.snap | 10 - ...ewareTests.HttpPost_WithScopedService.snap | 6 - ...onsTests.AddGraphQL_ServicesConfigure.snap | 54 ++ ...s.AddGraphQL_ServicesConfigureBuilder.snap | 54 ++ ...nsionsTests.AddGraphQL_ServicesSchema.snap | 54 ++ ...ests.AddGraphQL_ServicesSchemaBuilder.snap | 54 ++ ...ddGraphQL_ServicesSchemaConfigOptions.snap | 54 ++ ...ts.AddGraphQL_ServicesSchemaConfigure.snap | 54 ++ ...raphQL_ServicesSchemaConfigureBuilder.snap | 54 ++ ...dGraphQL_ServicesSchemaFactoryBuilder.snap | 54 ++ ...dGraphQL_ServicesSchemaFactoryOptions.snap | 54 ++ ...ests.AddGraphQL_ServicesSchemaOptions.snap | 54 ++ ...AddGraphQL_ServicesSchemaSdlConfigure.snap | 54 ++ ...GraphQL_ServicesSchemaSdlConfigureBld.snap | 54 ++ .../AspNetClassic.Voyager.csproj | 2 +- src/Server/AspNetClassic/AspNetClassic.csproj | 12 +- .../ApplicationBuilderExtensions.cs | 49 +- .../AspNetCore.Abstractions.csproj | 3 +- .../Extensions/HttpContextExtensions.cs | 16 +- .../Extensions/SerializerExtensions.cs | 46 + .../HttpMethods.cs | 2 +- .../IParserOptionsAccessor.cs | 19 + .../IPathOptionAccessor.cs | 19 + .../QueryMiddlewareBase.cs | 54 +- .../AspNetCore.Authorization.csproj | 2 +- .../AspNetCore.GraphiQL.csproj | 2 +- .../AspNetCore.HttpGet.csproj | 35 + .../HttpGetApplicationBuilderExtensions.cs | 32 + .../HttpGetMiddleware.cs} | 58 +- .../HttpGetMiddlewareOptions.cs | 39 + .../IHttpGetMiddlewareOptions.cs | 18 + .../AspNetCore.HttpGetSchema.csproj | 35 + ...tpGetSchemaApplicationBuilderExtensions.cs | 39 + .../HttpGetSchemaMiddleware.cs} | 25 +- .../HttpGetSchemaMiddlewareOptions.cs | 39 + .../IHttpGetSchemaMiddlewareOptions.cs | 19 + .../AspNetCore.HttpPost.csproj | 35 + .../HttpPostApplicationBuilderExtensions.cs | 39 + .../HttpPostMiddleware.cs} | 162 ++-- .../HttpPostMiddlewareOptions.cs | 74 ++ .../IHttpPostMiddlewareOptions.cs | 20 + .../AspNetCore.Playground.csproj | 2 +- .../LargeMessageTests.cs | 2 +- .../WebSocketProtocolTests.cs | 6 +- .../AspNetCore.Subscriptions.csproj | 6 +- .../Messages/DataStartMessageHandler.cs | 1 - .../SubscriptionMiddleware.cs | 2 +- .../SubscriptionMiddlewareOptions.cs | 2 +- .../TestServerExtensions.cs | 10 +- .../ApplicationBuilderTests.cs | 303 ++++++ .../AspNetCore.Tests/AspNetCore.Tests.csproj | 1 + .../HttpGetMiddlewareOptionsTests.cs | 35 + .../HttpGetSchemaMiddlewareOptionsTests.cs | 35 + .../HttpPostMiddlewareOptionsTests.cs | 102 ++ .../AspNetCore.Tests/PostMiddlewareTests.cs | 105 ++- .../ServiceCollectionExtensionsTests.cs | 3 +- ...Tests.UseGraphQLHttpGetSchema_Builder.snap | 124 +++ ...seGraphQLHttpGetSchema_BuilderOptions.snap | 124 +++ ...uilderTests.UseGraphQLHttpGet_Builder.snap | 9 + ...ests.UseGraphQLHttpGet_BuilderOptions.snap | 9 + ...ilderTests.UseGraphQLHttpPost_Builder.snap | 9 + ...sts.UseGraphQLHttpPost_BuilderOptions.snap | 9 + ...wareTests.HttpPost_Json_CachedQuery_2.snap | 9 + ...ts.HttpPost_Json_CachedQuery_NotFound.snap | 12 + .../AspNetCore.Voyager.csproj | 2 +- src/Server/AspNetCore/AspNetCore.csproj | 5 +- .../ApplicationBuilderExtensions.cs | 75 +- src/Server/AspNetCore/InternalsVisibleTo.cs | 4 - src/Server/Server.sln | 36 + src/Server/Server/ContentType.cs | 51 +- tools/Build.Core.sln | 52 +- tools/Build.sln | 84 ++ 181 files changed, 5832 insertions(+), 1192 deletions(-) create mode 100644 src/Server/AspNetClassic.HttpGet/AspNetClassic.HttpGet.csproj create mode 100644 src/Server/AspNetClassic.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs create mode 100644 src/Server/AspNetClassic.HttpGetSchema/AspNetClassic.HttpGetSchema.csproj create mode 100644 src/Server/AspNetClassic.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs create mode 100644 src/Server/AspNetClassic.HttpPost/AspNetClassic.HttpPost.csproj create mode 100644 src/Server/AspNetClassic.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs create mode 100644 src/Server/AspNetClassic.Tests/ApplicationBuilderTests.cs create mode 100644 src/Server/AspNetClassic.Tests/GetMiddlewareTests.cs create mode 100644 src/Server/AspNetClassic.Tests/Helpers/ServiceCollectionExtensions.cs create mode 100644 src/Server/AspNetClassic.Tests/HttpGetMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetClassic.Tests/HttpGetSchemaMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetClassic.Tests/HttpPostMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetClassic.Tests/PostMiddlewareTests.cs create mode 100644 src/Server/AspNetClassic.Tests/QueryMiddlewareOptionsTests.cs delete mode 100644 src/Server/AspNetClassic.Tests/QueryMiddlewareTests.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/Foo.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/FooInputType.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/Query.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/QueryType.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/TestEnum.cs delete mode 100644 src/Server/AspNetClassic.Tests/Schema/TestService.cs create mode 100644 src/Server/AspNetClassic.Tests/ServerTestBase.cs create mode 100644 src/Server/AspNetClassic.Tests/ServiceCollectionExtensionsTests.cs create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServices.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServicesOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServices.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServicesOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServices.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServicesOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/GetMiddlewareTests.HttpGet_QueryOnly.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpGet_BasicTest.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_BasicTest.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_Casing.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_CustomProperties.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_EnumArgument.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_GraphQLRequest.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_NestedEnumArgument.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithHttpContext.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithObjectVariables.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScalarVariables.json delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScopedService.json create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Batch.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Ensure_Response_Casing_Alignes_With_Request.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Object_Variable.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnRoot.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnSubPath.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndEnumVariable.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_a.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_b.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndStringVariable.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryOnly.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Unused_Variable.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variable_NonNull_Violation.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variables_In_Object_Fields.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch_Invalid_Argument.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash__.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash___Slash_.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql_Slash_.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo_Slash_.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql_Slash_.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Plain_GraphQL.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpGet_BasicTest.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_BasicTest.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_Casing.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_CustomProperties.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_EnumArgument.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_GraphQLRequest.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_NestedEnumArgument.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithHttpContext.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithObjectVariables.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScalarVariables.snap delete mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScopedService.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigure.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigureBuilder.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchema.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaBuilder.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigure.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigureBuilder.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryBuilder.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaOptions.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigure.snap create mode 100644 src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigureBld.snap create mode 100644 src/Server/AspNetCore.Abstractions/Extensions/SerializerExtensions.cs rename src/Server/{AspNetCore => AspNetCore.Abstractions}/HttpMethods.cs (84%) create mode 100644 src/Server/AspNetCore.Abstractions/IParserOptionsAccessor.cs create mode 100644 src/Server/AspNetCore.Abstractions/IPathOptionAccessor.cs create mode 100644 src/Server/AspNetCore.HttpGet/AspNetCore.HttpGet.csproj create mode 100644 src/Server/AspNetCore.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs rename src/Server/{AspNetCore/GetQueryMiddleware.cs => AspNetCore.HttpGet/HttpGetMiddleware.cs} (64%) create mode 100644 src/Server/AspNetCore.HttpGet/HttpGetMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.HttpGet/IHttpGetMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.HttpGetSchema/AspNetCore.HttpGetSchema.csproj create mode 100644 src/Server/AspNetCore.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs rename src/Server/{AspNetCore/SchemaMiddleware.cs => AspNetCore.HttpGetSchema/HttpGetSchemaMiddleware.cs} (76%) create mode 100644 src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.HttpGetSchema/IHttpGetSchemaMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.HttpPost/AspNetCore.HttpPost.csproj create mode 100644 src/Server/AspNetCore.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs rename src/Server/{AspNetCore/PostQueryMiddleware.cs => AspNetCore.HttpPost/HttpPostMiddleware.cs} (74%) create mode 100644 src/Server/AspNetCore.HttpPost/HttpPostMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.HttpPost/IHttpPostMiddlewareOptions.cs create mode 100644 src/Server/AspNetCore.Tests/ApplicationBuilderTests.cs create mode 100644 src/Server/AspNetCore.Tests/HttpGetMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetCore.Tests/HttpGetSchemaMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetCore.Tests/HttpPostMiddlewareOptionsTests.cs create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_Builder.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderOptions.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_Builder.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderOptions.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_Builder.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderOptions.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap create mode 100644 src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap delete mode 100644 src/Server/AspNetCore/InternalsVisibleTo.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba46e37fb7..ebdc658c266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added UTF-8 request parser. [#869](https://github.com/ChilliCream/hotchocolate/pull/869) - Added new syntax visitor API. - Added Redis subscription provider [#902](https://github.com/ChilliCream/hotchocolate/pull/902) +- Added support for batching over HTTP [#933](https://github.com/ChilliCream/hotchocolate/pull/933) ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved parser performance. [#806](https://github.com/ChilliCream/hotchocolate/pull/806) - Roles collection on authorization directive is now interpreted as OR. - The type conversion API is now better integreated with dependency injection. +- The server is now more modularized and the various server middlewares can be added separably. ### Fixed @@ -31,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Respect UseXmlDocumentation with Schema.Create [#897](https://github.com/ChilliCream/hotchocolate/pull/897) - Variables now work in lists and input objects [#896](https://github.com/ChilliCream/hotchocolate/pull/896) - Fixed url scalar now correctly detects url strings. +- Support directives declared stitched schemas [#936](https://github.com/ChilliCream/hotchocolate/pull/936) ## [9.0.4] - 2019-06-16 @@ -156,7 +159,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- The authoization directive is now more aligned how the authorize attribute in ASP.net works. +- The authoization directive is now more aligned how the authorize attribute in ASP .Net works. ### Fixed @@ -304,7 +307,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Separate package providing a _GraphiQL_ middleware. The middleware can serve all of _GraphiQL_ without needing to refer to CDNs making it useful even in closed networks. Moreover, we have configured _GraphiQL_ to work with the _GraphQL-ws_ protocol which is supported by _Hot Chocolate_. - Initial Support for _GraphQL_ subscriptions. We currently support the _GraphQL-ws_ protocol over web sockets. There will be a lot of additional work in version _0.7.0_ that will harden it. -- Authorization package for ASP.net core which supports policy-base authorization on fields. +- Authorization package for ASP .Net core which supports policy-base authorization on fields. - Diagnostic source which can be used to track field execution times and other events. - Implementing a directive middleware has now become much easier with this release. We have built the authorize-directive with these new APIs. diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md index 546eb51eada..ba246d6c2f9 100644 --- a/CONTRIBUTION.md +++ b/CONTRIBUTION.md @@ -11,7 +11,7 @@ - `StringExtensions.cs` - `ServiceCollectionExtensions.cs` - Write for every type a separate extension file. -- Use the origin namespace of the type; use `HotChocolate` when extending an external type like `Microsoft.Ectensions.DependencyInjection.IServiceCollection` or `HotChocolate.AspNetCore` when extending a ASP.net core specific type like `Microsoft.AspNetCore.Builder.IApplicationBuilder`. +- Use the origin namespace of the type; use `HotChocolate` when extending an external type like `Microsoft.Ectensions.DependencyInjection.IServiceCollection` or `HotChocolate.AspNetCore` when extending a ASP .Net core specific type like `Microsoft.AspNetCore.Builder.IApplicationBuilder`. Example: ```csharp using Microsoft.Extensions.DependencyInjection; diff --git a/README.md b/README.md index 900cfd80616..1e35e7a8ba2 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ This runs a query fetching the one field defined. The graphql function will firs Console.WriteLine(executor.Execute("{ foo }").ToJson()); ``` -In order to set up a GraphQL HTTP endpoint, Hot Chocolate comes with an ASP.net core middleware. +In order to set up a GraphQL HTTP endpoint, Hot Chocolate comes with an ASP .Net core middleware. Create a new project with the web template that comes with your dotnet CLI. diff --git a/src/Core/Abstractions/Execution/IQueryRequestBuilder.cs b/src/Core/Abstractions/Execution/IQueryRequestBuilder.cs index 913f233d2b9..0447f1f8d16 100644 --- a/src/Core/Abstractions/Execution/IQueryRequestBuilder.cs +++ b/src/Core/Abstractions/Execution/IQueryRequestBuilder.cs @@ -13,7 +13,7 @@ IQueryRequestBuilder SetQuery( IQueryRequestBuilder SetQueryName( string queryName); IQueryRequestBuilder SetQueryHash( - string queryHash); + string queryHash); IQueryRequestBuilder SetOperation( string operationName); IQueryRequestBuilder SetVariableValues( diff --git a/src/Core/Abstractions/Execution/QueryRequestBuilder.cs b/src/Core/Abstractions/Execution/QueryRequestBuilder.cs index 7b0cc91ff1c..a4050eddfb3 100644 --- a/src/Core/Abstractions/Execution/QueryRequestBuilder.cs +++ b/src/Core/Abstractions/Execution/QueryRequestBuilder.cs @@ -1,3 +1,4 @@ +using System.Runtime.Serialization; using System.Linq; using System; using System.Collections.Generic; @@ -267,13 +268,18 @@ public static QueryRequestBuilder From(GraphQLRequest request) { var builder = QueryRequestBuilder.New(); - builder.SetQuery(request.Query) + builder .SetQueryName(request.QueryName) - .SetQueryName(request.QueryName) // TODO : we should have a hash here + .SetQueryHash(request.QueryHash) .SetOperation(request.OperationName) .SetVariableValues(request.Variables) .SetProperties(request.Extensions); + if (request.Query != null) + { + builder.SetQuery(request.Query); + } + return builder; } } diff --git a/src/Core/Core/Execution/Batching/BatchQueryExecutionResult.cs b/src/Core/Core/Execution/Batching/BatchQueryExecutionResult.cs index bddb5db069d..3d8533c492c 100644 --- a/src/Core/Core/Execution/Batching/BatchQueryExecutionResult.cs +++ b/src/Core/Core/Execution/Batching/BatchQueryExecutionResult.cs @@ -96,6 +96,7 @@ public async Task ReadAsync( .SetVariableValues(variableValues) .AddExportedVariables(_exportedVariables) .SetQueryName(null) // TODO ... should we create a name here? + .SetQueryHash(null) .Create(); var result = diff --git a/src/Core/Core/Execution/JsonQueryResultSerializer.cs b/src/Core/Core/Execution/JsonQueryResultSerializer.cs index ca48d3e006a..77125d46c83 100644 --- a/src/Core/Core/Execution/JsonQueryResultSerializer.cs +++ b/src/Core/Core/Execution/JsonQueryResultSerializer.cs @@ -15,7 +15,13 @@ public sealed class JsonQueryResultSerializer public Task SerializeAsync( IReadOnlyQueryResult result, - Stream stream) + Stream stream) => + SerializeAsync(result, stream, CancellationToken.None); + + public Task SerializeAsync( + IReadOnlyQueryResult result, + Stream stream, + CancellationToken cancellationToken) { if (result is null) { @@ -32,10 +38,5 @@ public Task SerializeAsync( byte[] buffer = _encoding.GetBytes(json); return stream.WriteAsync(buffer, 0, buffer.Length); } - - public Task SerializeAsync(IReadOnlyQueryResult result, Stream stream, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } } } diff --git a/src/Core/Core/Execution/Middleware/ParseQueryMiddleware.cs b/src/Core/Core/Execution/Middleware/ParseQueryMiddleware.cs index 0ccc649cc87..5be5d780842 100644 --- a/src/Core/Core/Execution/Middleware/ParseQueryMiddleware.cs +++ b/src/Core/Core/Execution/Middleware/ParseQueryMiddleware.cs @@ -52,26 +52,46 @@ public async Task InvokeAsync(IQueryContext context) try { bool documentRetrievedFromCache = true; + string queryKey = context.Request.QueryName; + ICachedQuery cachedQuery = null; - string queryKey = context.Request.QueryHash - ?? context.Request.QueryName; + if (queryKey is null || context.Request.Query != null) + { + queryKey = context.Request.QueryHash is null + ? _documentHashProvider.ComputeHash( + context.Request.Query.ToSource()) + : context.Request.QueryHash; + } - if (queryKey is null) + if (context.Request.Query is null + && !_queryCache.TryGet(queryKey, out cachedQuery)) { - queryKey = _documentHashProvider.ComputeHash( - context.Request.Query.ToSource()); + // TODO : check for query storage here? + // TODO : RESOURCES + context.Result = QueryResult.CreateError( + ErrorBuilder.New() + .SetMessage("persistedQueryNotFound") + .SetCode("CACHED_QUERY_NOT_FOUND") + .Build()); + return; } + if (cachedQuery is null) + { + cachedQuery = _queryCache.GetOrCreate( + queryKey, + () => + { + documentRetrievedFromCache = false; + DocumentNode document = + ParseDocument(context.Request.Query); + return new CachedQuery(queryKey, document); + }); + } + + // update context context.QueryKey = queryKey; - context.CachedQuery = _queryCache.GetOrCreate( - queryKey, - () => - { - documentRetrievedFromCache = false; - DocumentNode document = - ParseDocument(context.Request.Query); - return new CachedQuery(queryKey, document); - }); + context.CachedQuery = cachedQuery; context.Document = context.CachedQuery.Document; context.ContextData[ContextDataKeys.DocumentCached] = documentRetrievedFromCache; @@ -80,9 +100,9 @@ public async Task InvokeAsync(IQueryContext context) { _diagnosticEvents.EndParsing(activity, context); } - } - await _next(context).ConfigureAwait(false); + await _next(context).ConfigureAwait(false); + } } private DocumentNode ParseDocument(IQuery query) @@ -104,8 +124,9 @@ private DocumentNode ParseDocument(IQuery query) private static bool IsContextIncomplete(IQueryContext context) { - return context.Request == null - || context.Request.Query == null; + return context.Request is null + || (context.Request.Query is null + && context.Request.QueryName is null); } } } diff --git a/src/Core/Core/Execution/Middleware/ValidateQueryMiddleware.cs b/src/Core/Core/Execution/Middleware/ValidateQueryMiddleware.cs index 8a4c152f586..51195ae70a0 100644 --- a/src/Core/Core/Execution/Middleware/ValidateQueryMiddleware.cs +++ b/src/Core/Core/Execution/Middleware/ValidateQueryMiddleware.cs @@ -34,7 +34,6 @@ public ValidateQueryMiddleware( public async Task InvokeAsync(IQueryContext context) { - if (context.Document == null) { context.Result = QueryResult.CreateError(new Error diff --git a/src/Core/Language/Utf8/GraphQLRequest.cs b/src/Core/Language/Utf8/GraphQLRequest.cs index 9eb54178a8f..b0e769c2be1 100644 --- a/src/Core/Language/Utf8/GraphQLRequest.cs +++ b/src/Core/Language/Utf8/GraphQLRequest.cs @@ -6,18 +6,19 @@ namespace HotChocolate.Language public class GraphQLRequest { public GraphQLRequest(DocumentNode query) - : this(query, null, null, null, null) + : this(query, null, null, null, null, null) { } public GraphQLRequest(DocumentNode query, string queryName) - : this(query, queryName, null, null, null) + : this(query, queryName, null, null, null, null) { } public GraphQLRequest( DocumentNode query, string queryName, + string queryHash, string operationName, IReadOnlyDictionary variables, IReadOnlyDictionary extensions) @@ -29,6 +30,7 @@ public GraphQLRequest( OperationName = operationName; QueryName = queryName; + QueryHash = queryHash; Query = query; Variables = variables; Extensions = extensions; @@ -38,6 +40,8 @@ public GraphQLRequest( public string QueryName { get; } + public string QueryHash { get; } + public string OperationName { get; } public IReadOnlyDictionary Variables { get; } diff --git a/src/Core/Language/Utf8/Utf8GraphQLRequestParser.Request.cs b/src/Core/Language/Utf8/Utf8GraphQLRequestParser.Request.cs index 105de6ed2fa..e67c48fa86c 100644 --- a/src/Core/Language/Utf8/Utf8GraphQLRequestParser.Request.cs +++ b/src/Core/Language/Utf8/Utf8GraphQLRequestParser.Request.cs @@ -11,6 +11,8 @@ private ref struct Request public string NamedQuery { get; set; } + public string QueryHash { get; set; } + public ReadOnlySpan Query { get; set; } public bool IsQueryNull { get; set; } diff --git a/src/Core/Language/Utf8/Utf8GraphQLRequestParser.cs b/src/Core/Language/Utf8/Utf8GraphQLRequestParser.cs index 6128450ef79..fee45e63cca 100644 --- a/src/Core/Language/Utf8/Utf8GraphQLRequestParser.cs +++ b/src/Core/Language/Utf8/Utf8GraphQLRequestParser.cs @@ -136,30 +136,43 @@ private GraphQLRequest ParseRequest() "property have to have a value."); } - DocumentNode document; + DocumentNode document = null; - if (_useCache) + if (!request.IsQueryNull) { - if (request.NamedQuery is null) + if (_useCache) { - request.NamedQuery = - _hashProvider.ComputeHash(request.Query); - } + if (request.NamedQuery is null) + { + request.NamedQuery = + request.QueryHash = + _hashProvider.ComputeHash(request.Query); + } - if (!_cache.TryGetDocument(request.NamedQuery, out document)) + if (!_cache.TryGetDocument( + request.NamedQuery, + out document)) + { + document = ParseQuery(in request); + + if (request.QueryHash is null) + { + request.QueryHash = + _hashProvider.ComputeHash(request.Query); + } + } + } + else { document = ParseQuery(in request); } } - else - { - document = ParseQuery(in request); - } return new GraphQLRequest ( document, request.NamedQuery, + request.QueryHash, request.OperationName, request.Variables, request.Extensions diff --git a/src/Core/Types/InternalsVisibleTo.cs b/src/Core/Types/InternalsVisibleTo.cs index b52d6fb447b..4e86caed8b0 100644 --- a/src/Core/Types/InternalsVisibleTo.cs +++ b/src/Core/Types/InternalsVisibleTo.cs @@ -2,3 +2,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("HotChocolate.AspNetCore.Tests")] +[assembly: InternalsVisibleTo("HotChocolate.AspNetClassic.Tests")] diff --git a/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor.cs index 12f6b51c351..6f97c6956f0 100644 --- a/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor.cs @@ -10,14 +10,14 @@ public interface IInterfaceTypeDescriptor { // /// Associates the specified - /// + /// /// with the . /// /// /// The of a parsed schema. /// IInterfaceTypeDescriptor SyntaxNode( - InterfaceTypeDefinitionNode interfaceTypeDefinitionNode); + InterfaceTypeDefinitionNode interfaceTypeDefinition); /// /// Defines the name of the . @@ -41,7 +41,7 @@ IInterfaceTypeDescriptor ResolveAbstractType( IInterfaceFieldDescriptor Field(NameString name); - IInterfaceTypeDescriptor Directive(T directive) + IInterfaceTypeDescriptor Directive(T directiveInstance) where T : class; IInterfaceTypeDescriptor Directive() diff --git a/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor~1.cs b/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor~1.cs index aadb318d53a..ff8bbfe948b 100644 --- a/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor~1.cs +++ b/src/Core/Types/Types/Descriptors/Contracts/IInterfaceTypeDescriptor~1.cs @@ -10,31 +10,32 @@ public interface IInterfaceTypeDescriptor , IFluent { // - /// Associates the specified + /// Associates the specified + /// /// with the . /// - /// + /// /// The of a parsed schema. /// IInterfaceTypeDescriptor SyntaxNode( - InterfaceTypeDefinitionNode syntaxNode); + InterfaceTypeDefinitionNode syntaxinterfaceTypeDefinitionode); /// /// Defines the name of the . /// - /// The interface type name. + /// The interface type name. /// - /// is null or + /// is null or /// . /// - IInterfaceTypeDescriptor Name(NameString name); + IInterfaceTypeDescriptor Name(NameString value); /// /// Adds explanatory text to the /// that can be accessd via introspection. /// - /// The interface type description. - IInterfaceTypeDescriptor Description(string description); + /// The interface type description. + IInterfaceTypeDescriptor Description(string value); /// /// Defines the field binding behavior. diff --git a/src/Core/Types/Types/Descriptors/Contracts/IObjectTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/Contracts/IObjectTypeDescriptor.cs index d68241f20a5..9a103b05d0d 100644 --- a/src/Core/Types/Types/Descriptors/Contracts/IObjectTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/Contracts/IObjectTypeDescriptor.cs @@ -10,14 +10,14 @@ public interface IObjectTypeDescriptor , IFluent { /// - /// Associates the specified + /// Associates the specified /// with the . /// - /// + /// /// The of a parsed schema. /// IObjectTypeDescriptor SyntaxNode( - ObjectTypeDefinitionNode objectTypeDefinitionNode); + ObjectTypeDefinitionNode objectTypeDefinition); /// /// Defines the name of the . diff --git a/src/Core/Types/Types/Descriptors/Definitions/ITypeConfigration.cs b/src/Core/Types/Types/Descriptors/Definitions/ITypeConfigration.cs index 53531c8f928..e516e44e99e 100644 --- a/src/Core/Types/Types/Descriptors/Definitions/ITypeConfigration.cs +++ b/src/Core/Types/Types/Descriptors/Definitions/ITypeConfigration.cs @@ -20,6 +20,6 @@ public interface ILazyTypeConfiguration /// /// Executes this configuration. /// - void Configure(ICompletionContext completionContext); + void Configure(ICompletionContext context); } } diff --git a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs index a5e434762d6..e629213a6bb 100644 --- a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs @@ -65,9 +65,9 @@ protected virtual void OnCompleteFields( } public IInterfaceTypeDescriptor SyntaxNode( - InterfaceTypeDefinitionNode interfaceTypeDefinitionNode) + InterfaceTypeDefinitionNode interfaceTypeDefinition) { - Definition.SyntaxNode = interfaceTypeDefinitionNode; + Definition.SyntaxNode = interfaceTypeDefinition; return this; } @@ -100,10 +100,10 @@ public IInterfaceTypeDescriptor ResolveAbstractType( return this; } - public IInterfaceTypeDescriptor Directive(T directive) + public IInterfaceTypeDescriptor Directive(T directiveInstance) where T : class { - Definition.AddDirective(directive); + Definition.AddDirective(directiveInstance); return this; } diff --git a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor~1.cs b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor~1.cs index 6d6d5f2eda1..66b451958d1 100644 --- a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor~1.cs +++ b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor~1.cs @@ -39,9 +39,9 @@ protected override void OnCompleteFields( } public new IInterfaceTypeDescriptor SyntaxNode( - InterfaceTypeDefinitionNode interfaceTypeDefinitionNode) + InterfaceTypeDefinitionNode interfaceTypeDefinition) { - base.SyntaxNode(interfaceTypeDefinitionNode); + base.SyntaxNode(interfaceTypeDefinition); return this; } @@ -58,9 +58,9 @@ protected override void OnCompleteFields( } public IInterfaceTypeDescriptor BindFields( - BindingBehavior bindingBehavior) + BindingBehavior behavior) { - Definition.Fields.BindingBehavior = bindingBehavior; + Definition.Fields.BindingBehavior = behavior; return this; } @@ -87,17 +87,17 @@ public IInterfaceFieldDescriptor Field( } public new IInterfaceTypeDescriptor ResolveAbstractType( - ResolveAbstractType resolveAbstractType) + ResolveAbstractType typeResolver) { - base.ResolveAbstractType(resolveAbstractType); + base.ResolveAbstractType(typeResolver); return this; } public new IInterfaceTypeDescriptor Directive( - TDirective directive) + TDirective directiveInstance) where TDirective : class { - base.Directive(directive); + base.Directive(directiveInstance); return this; } diff --git a/src/Core/Types/Types/Descriptors/ObjectFieldDescriptor.cs b/src/Core/Types/Types/Descriptors/ObjectFieldDescriptor.cs index 749d603b001..bad9723e63d 100644 --- a/src/Core/Types/Types/Descriptors/ObjectFieldDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/ObjectFieldDescriptor.cs @@ -142,10 +142,10 @@ public IObjectFieldDescriptor DeprecationReason(string reason) => } public new IObjectFieldDescriptor Argument( - NameString name, + NameString argumentName, Action argumentDescriptor) { - base.Argument(name, argumentDescriptor); + base.Argument(argumentName, argumentDescriptor); return this; } @@ -206,10 +206,10 @@ public IObjectFieldDescriptor Use(FieldMiddleware middleware) return this; } - public new IObjectFieldDescriptor Directive(T directive) + public new IObjectFieldDescriptor Directive(T directiveInstance) where T : class { - base.Directive(directive); + base.Directive(directiveInstance); return this; } diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs index 679befd6037..0f7b258c54e 100644 --- a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs @@ -137,9 +137,9 @@ private static bool IsResolverRelevant( } public IObjectTypeDescriptor SyntaxNode( - ObjectTypeDefinitionNode objectTypeDefinitionNode) + ObjectTypeDefinitionNode objectTypeDefinition) { - Definition.SyntaxNode = objectTypeDefinitionNode; + Definition.SyntaxNode = objectTypeDefinition; return this; } @@ -169,29 +169,29 @@ public IObjectTypeDescriptor Interface() } public IObjectTypeDescriptor Interface( - TInterface interfaceType) + TInterface type) where TInterface : InterfaceType { - if (interfaceType == null) + if (type == null) { - throw new ArgumentNullException(nameof(interfaceType)); + throw new ArgumentNullException(nameof(type)); } Definition.Interfaces.Add(new SchemaTypeReference( - interfaceType)); + type)); return this; } public IObjectTypeDescriptor Interface( - NamedTypeNode namedTypeNode) + NamedTypeNode namedType) { - if (namedTypeNode == null) + if (namedType == null) { - throw new ArgumentNullException(nameof(namedTypeNode)); + throw new ArgumentNullException(nameof(namedType)); } Definition.Interfaces.Add(new SyntaxTypeReference( - namedTypeNode, TypeContext.Output)); + namedType, TypeContext.Output)); return this; } diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs index b7689b3abbd..78546e5f325 100644 --- a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs +++ b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs @@ -37,23 +37,23 @@ protected override void OnCompleteFields( base.OnCompleteFields(fields, handledMembers); } - public new IObjectTypeDescriptor Name(NameString name) + public new IObjectTypeDescriptor Name(NameString value) { - base.Name(name); + base.Name(value); return this; } public new IObjectTypeDescriptor Description( - string description) + string value) { - base.Description(description); + base.Description(value); return this; } public IObjectTypeDescriptor BindFields( - BindingBehavior bindingBehavior) + BindingBehavior behavior) { - Definition.Fields.BindingBehavior = bindingBehavior; + Definition.Fields.BindingBehavior = behavior; return this; } @@ -114,10 +114,10 @@ public IObjectFieldDescriptor Field( } public new IObjectTypeDescriptor Directive( - TDirective directive) + TDirective directiveInstance) where TDirective : class { - base.Directive(directive); + base.Directive(directiveInstance); return this; } diff --git a/src/Core/Types/Types/EnumType.cs b/src/Core/Types/Types/EnumType.cs index 42fb655d92c..b84d9e5d305 100644 --- a/src/Core/Types/Types/EnumType.cs +++ b/src/Core/Types/Types/EnumType.cs @@ -150,9 +150,9 @@ public object Serialize(object value) TypeResourceHelper.Scalar_Cannot_Serialize(Name)); } - public object Deserialize(object value) + public object Deserialize(object serialized) { - if (TryDeserialize(value, out object v)) + if (TryDeserialize(serialized, out object v)) { return v; } diff --git a/src/Server/AspNetClassic.Abstractions/AspNetClassic.Abstractions.csproj b/src/Server/AspNetClassic.Abstractions/AspNetClassic.Abstractions.csproj index b6370398d3b..e60f727f6f7 100644 --- a/src/Server/AspNetClassic.Abstractions/AspNetClassic.Abstractions.csproj +++ b/src/Server/AspNetClassic.Abstractions/AspNetClassic.Abstractions.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic.Abstractions HotChocolate.AspNetClassic HotChocolate.AspNetClassic.Abstractions - Contains the Hot Chocolate GraphQL middleware abstractions for ASP.net framework. + Contains the Hot Chocolate GraphQL middleware abstractions for ASP .Net framework. @@ -34,11 +34,9 @@ - + diff --git a/src/Server/AspNetClassic.Authorization/AspNetClassic.Authorization.csproj b/src/Server/AspNetClassic.Authorization/AspNetClassic.Authorization.csproj index 51bbb9cf395..6eb4bb61a1b 100644 --- a/src/Server/AspNetClassic.Authorization/AspNetClassic.Authorization.csproj +++ b/src/Server/AspNetClassic.Authorization/AspNetClassic.Authorization.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic.Authorization HotChocolate.AspNetClassic.Authorization HotChocolate.AspNetClassic.Authorization - Contains authorization extensions for the Hot Chocolate ASP.net classic GraphQL middleware. + Contains authorization extensions for the Hot Chocolate ASP .Net classic GraphQL middleware. diff --git a/src/Server/AspNetClassic.GraphiQL/AspNetClassic.GraphiQL.csproj b/src/Server/AspNetClassic.GraphiQL/AspNetClassic.GraphiQL.csproj index c8631f05952..1e723194607 100644 --- a/src/Server/AspNetClassic.GraphiQL/AspNetClassic.GraphiQL.csproj +++ b/src/Server/AspNetClassic.GraphiQL/AspNetClassic.GraphiQL.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic.GraphiQL HotChocolate.AspNetClassic.GraphiQL HotChocolate.AspNetClassic.GraphiQL - Contains a GraphiQL middleware for ASP.net classic that can be used with the Hot Chocolate GraphQL server. + Contains a GraphiQL middleware for ASP .Net classic that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetClassic.HttpGet/AspNetClassic.HttpGet.csproj b/src/Server/AspNetClassic.HttpGet/AspNetClassic.HttpGet.csproj new file mode 100644 index 00000000000..d82163481e2 --- /dev/null +++ b/src/Server/AspNetClassic.HttpGet/AspNetClassic.HttpGet.csproj @@ -0,0 +1,36 @@ + + + + net461 + HotChocolate.AspNetClassic.HttpGet + HotChocolate.AspNetClassic.HttpGet + HotChocolate.AspNetClassic.HttpGet + Contains the Hot Chocolate GraphQL HTTP GET middleware for ASP .Net classic. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG;ASPNETCLASSIC + + + + pdbonly + true + TRACE;ASPNETCLASSIC + + + + + + + + + + + + diff --git a/src/Server/AspNetClassic.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs b/src/Server/AspNetClassic.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..40a2f362148 --- /dev/null +++ b/src/Server/AspNetClassic.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs @@ -0,0 +1,52 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Owin; +using IApplicationBuilder = Owin.IAppBuilder; +using HotChocolate.Execution; + +namespace HotChocolate.AspNetClassic +{ + public static class HttpGetApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpGet( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider) => + UseGraphQLHttpGet( + applicationBuilder, + serviceProvider, + new HttpGetMiddlewareOptions()); + + public static IApplicationBuilder UseGraphQLHttpGet( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider, + IHttpGetMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (serviceProvider == null) + { + throw new ArgumentNullException(nameof(serviceProvider)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + IQueryExecutor executor = serviceProvider + .GetRequiredService(); + + IQueryResultSerializer serializer = serviceProvider + .GetRequiredService(); + + OwinContextAccessor contextAccessor = + serviceProvider.GetService(); + + return applicationBuilder.Use( + options, contextAccessor, executor, serializer); + } + } +} diff --git a/src/Server/AspNetClassic.HttpGetSchema/AspNetClassic.HttpGetSchema.csproj b/src/Server/AspNetClassic.HttpGetSchema/AspNetClassic.HttpGetSchema.csproj new file mode 100644 index 00000000000..cc9b2a26ce4 --- /dev/null +++ b/src/Server/AspNetClassic.HttpGetSchema/AspNetClassic.HttpGetSchema.csproj @@ -0,0 +1,39 @@ + + + + net461 + HotChocolate.AspNetClassic.HttpGetSchema + HotChocolate.AspNetClassic.HttpGetSchema + HotChocolate.AspNetClassic.HttpGetSchema + Contains the Hot Chocolate GraphQL HTTP GET schema middleware for ASP .Net classic. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG;ASPNETCLASSIC + + + + pdbonly + true + TRACE;ASPNETCLASSIC + + + + + + + + + + + + + + + diff --git a/src/Server/AspNetClassic.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs b/src/Server/AspNetClassic.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..4d5d1128dc6 --- /dev/null +++ b/src/Server/AspNetClassic.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs @@ -0,0 +1,46 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Owin; +using IApplicationBuilder = Owin.IAppBuilder; +using HotChocolate.Execution; + +namespace HotChocolate.AspNetClassic +{ + public static class HttpGetSchemaApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpGetSchema( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider) => + UseGraphQLHttpGetSchema( + applicationBuilder, + serviceProvider, + new HttpGetSchemaMiddlewareOptions()); + + public static IApplicationBuilder UseGraphQLHttpGetSchema( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider, + IHttpGetSchemaMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (serviceProvider == null) + { + throw new ArgumentNullException(nameof(serviceProvider)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + IQueryExecutor executor = serviceProvider + .GetRequiredService(); + + return applicationBuilder.Use( + options, executor); + } + } +} diff --git a/src/Server/AspNetClassic.HttpPost/AspNetClassic.HttpPost.csproj b/src/Server/AspNetClassic.HttpPost/AspNetClassic.HttpPost.csproj new file mode 100644 index 00000000000..be9099b2603 --- /dev/null +++ b/src/Server/AspNetClassic.HttpPost/AspNetClassic.HttpPost.csproj @@ -0,0 +1,39 @@ + + + + net461 + HotChocolate.AspNetClassic.HttpPost + HotChocolate.AspNetClassic.HttpPost + HotChocolate.AspNetClassic.HttpPost + Contains the Hot Chocolate GraphQL HTTP POST middleware for ASP .Net classic. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG;ASPNETCLASSIC + + + + pdbonly + true + TRACE;ASPNETCLASSIC + + + + + + + + + + + + + + + diff --git a/src/Server/AspNetClassic.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs b/src/Server/AspNetClassic.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..9ca18e1d16e --- /dev/null +++ b/src/Server/AspNetClassic.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs @@ -0,0 +1,69 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Owin; +using IApplicationBuilder = Owin.IAppBuilder; +using HotChocolate.Execution; +using HotChocolate.Execution.Batching; +using HotChocolate.Language; + +namespace HotChocolate.AspNetClassic +{ + public static class HttpPostApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpPost( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider) => + UseGraphQLHttpPost( + applicationBuilder, + serviceProvider, + new HttpPostMiddlewareOptions()); + + public static IApplicationBuilder UseGraphQLHttpPost( + this IApplicationBuilder applicationBuilder, + IServiceProvider serviceProvider, + IHttpPostMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (serviceProvider == null) + { + throw new ArgumentNullException(nameof(serviceProvider)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + IQueryExecutor executor = serviceProvider + .GetRequiredService(); + + IBatchQueryExecutor batchQueryExecutor = serviceProvider + .GetRequiredService(); + + IQueryResultSerializer resultSerializer = serviceProvider + .GetRequiredService(); + + IResponseStreamSerializer streamSerializer = serviceProvider + .GetRequiredService(); + + IDocumentCache documentCache = serviceProvider + .GetRequiredService(); + + IDocumentHashProvider documentHashProvider = serviceProvider + .GetRequiredService(); + + OwinContextAccessor contextAccessor = + serviceProvider.GetService(); + + return applicationBuilder.Use( + options, contextAccessor, + executor, batchQueryExecutor, + resultSerializer, streamSerializer, + documentCache, documentHashProvider); + } + } +} diff --git a/src/Server/AspNetClassic.Playground/AspNetClassic.Playground.csproj b/src/Server/AspNetClassic.Playground/AspNetClassic.Playground.csproj index 08a02fa0cc5..e6cc62cff17 100644 --- a/src/Server/AspNetClassic.Playground/AspNetClassic.Playground.csproj +++ b/src/Server/AspNetClassic.Playground/AspNetClassic.Playground.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic.Playground HotChocolate.AspNetClassic.Playground HotChocolate.AspNetClassic.Playground - Contains a GraphQL Playground for ASP.net classic that can be used with the Hot Chocolate GraphQL server. + Contains a GraphQL Playground for ASP .Net classic that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetClassic.Tests/ApplicationBuilderTests.cs b/src/Server/AspNetClassic.Tests/ApplicationBuilderTests.cs new file mode 100644 index 00000000000..0b65d58d00e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/ApplicationBuilderTests.cs @@ -0,0 +1,408 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using HotChocolate.Utilities; +using HotChocolate.StarWars; +using Moq; +using Owin; +using Snapshooter.Xunit; +using Xunit; +using Microsoft.Owin.Testing; +using Microsoft.Owin; + +namespace HotChocolate.AspNetClassic +{ + public class ApplicationBuilderTests + : ServerTestBase + { + public ApplicationBuilderTests(TestServerFactory serverFactory) + : base(serverFactory) + { + } + + [Fact] + public void UseGraphQLHttpGet_BuilderServices_BuilderIsNull() + { + // arrange + IServiceProvider service = new EmptyServiceProvider(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(null, service); + + // assert + Assert.Throws(action); + } + + + [Fact] + public void UseGraphQLHttpGet_BuilderServices_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGet_BuilderServices() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpGet(sp)); + + // act + HttpResponseMessage message = + await server.SendGetRequestAsync("{ hero { name } }"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGet_BuilderServicesOptions_BuilderIsNull() + { + // arrange + IServiceProvider services = new EmptyServiceProvider(); + var options = new HttpGetMiddlewareOptions(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(null, services, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGet_BuilderServicesOptions_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + var options = new HttpGetMiddlewareOptions(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(builder, null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGet_BuilderServicesOptions_OptionsIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + IServiceProvider services = new EmptyServiceProvider(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(builder, services, null); + + // assert + Assert.Throws(action); + } + + + + [Fact] + public async Task UseGraphQLHttpGet_BuilderServicesOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpGet( + sp, + new HttpGetMiddlewareOptions + { + Path = new PathString("/foo") + })); + + // act + HttpResponseMessage message = + await server.SendGetRequestAsync( + "{ hero { name } }", "foo"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderServices_BuilderIsNull() + { + // arrange + IServiceProvider services = new EmptyServiceProvider(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(null, services); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderServices_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpPost_BuilderServices() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpPost(sp)); + + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderServicesOptions_BuilderIsNull() + { + // arrange + IServiceProvider services = new EmptyServiceProvider(); + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(null, services, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderServicesOptions_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(builder, null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderServicesOptions_OptionsIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + IServiceProvider services = new EmptyServiceProvider(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(builder, services, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpPost_BuilderServicesOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpPost( + sp, + new HttpPostMiddlewareOptions + { + Path = new PathString("/foo") + })); + + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, "foo"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderServices_BuilderIsNull() + { + // arrange + IServiceProvider services = new EmptyServiceProvider(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(null, services); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderServices_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGetSchema_BuilderServices() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpGetSchema(sp)); + + HttpClient client = server.HttpClient; + + string uri = TestServerExtensions.CreateUrl(null); + + // act + HttpResponseMessage message = await client.GetAsync(uri); + + // assert + string s = await message.Content.ReadAsStringAsync(); + s.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderServicesOptions_BuilderIsNull() + { + // arrange + IServiceProvider services = new EmptyServiceProvider(); + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(null, services, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderServicesOptions_ServicesIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(builder, null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderServicesOptions_OptionsIsNull() + { + // arrange + IAppBuilder builder = Mock.Of(); + IServiceProvider services = new EmptyServiceProvider(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(builder, services, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGetSchema_BuilderServicesOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQLHttpGetSchema( + sp, + new HttpGetSchemaMiddlewareOptions + { + Path = new PathString("/foo") + })); + + HttpClient client = server.HttpClient; + + string uri = TestServerExtensions.CreateUrl("foo"); + + // act + HttpResponseMessage message = await client.GetAsync(uri); + + // assert + string s = await message.Content.ReadAsStringAsync(); + s.MatchSnapshot(); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/AspNetClassic.Tests.csproj b/src/Server/AspNetClassic.Tests/AspNetClassic.Tests.csproj index fc30088d297..ce5fe1759b1 100644 --- a/src/Server/AspNetClassic.Tests/AspNetClassic.Tests.csproj +++ b/src/Server/AspNetClassic.Tests/AspNetClassic.Tests.csproj @@ -31,14 +31,10 @@ + + - - - Always - - - diff --git a/src/Server/AspNetClassic.Tests/GetMiddlewareTests.cs b/src/Server/AspNetClassic.Tests/GetMiddlewareTests.cs new file mode 100644 index 00000000000..405f7b06fb1 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/GetMiddlewareTests.cs @@ -0,0 +1,33 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Owin.Testing; +using Snapshooter.Xunit; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class GetMiddlewareTests + : ServerTestBase + { + public GetMiddlewareTests(TestServerFactory serverFactory) + : base(serverFactory) + { + } + + [Fact] + public async Task HttpGet_QueryOnly() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = "{ hero { name } }"; + + // act + HttpResponseMessage message = + await server.SendGetRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/Helpers/ClientQueryRequest.cs b/src/Server/AspNetClassic.Tests/Helpers/ClientQueryRequest.cs index f7ba29e101c..ade569d682a 100644 --- a/src/Server/AspNetClassic.Tests/Helpers/ClientQueryRequest.cs +++ b/src/Server/AspNetClassic.Tests/Helpers/ClientQueryRequest.cs @@ -1,9 +1,10 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace HotChocolate.AspNetClassic { - internal class ClientQueryRequest + public class ClientQueryRequest { [JsonProperty("operationName")] public string OperationName { get; set; } @@ -15,6 +16,6 @@ internal class ClientQueryRequest public string Query { get; set; } [JsonProperty("variables")] - public JObject Variables { get; set; } + public Dictionary Variables { get; set; } } } diff --git a/src/Server/AspNetClassic.Tests/Helpers/ClientQueryResult.cs b/src/Server/AspNetClassic.Tests/Helpers/ClientQueryResult.cs index 29658a79c9e..9b60b3b1b3c 100644 --- a/src/Server/AspNetClassic.Tests/Helpers/ClientQueryResult.cs +++ b/src/Server/AspNetClassic.Tests/Helpers/ClientQueryResult.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using HotChocolate.Execution; namespace HotChocolate.AspNetClassic @@ -6,6 +6,7 @@ namespace HotChocolate.AspNetClassic public class ClientQueryResult { public Dictionary Data { get; set; } - public List Errors { get; set; } + public List> Errors { get; set; } + public Dictionary Extensions { get; set; } } } diff --git a/src/Server/AspNetClassic.Tests/Helpers/ServiceCollectionExtensions.cs b/src/Server/AspNetClassic.Tests/Helpers/ServiceCollectionExtensions.cs new file mode 100644 index 00000000000..754dc591860 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/Helpers/ServiceCollectionExtensions.cs @@ -0,0 +1,29 @@ +using HotChocolate.Execution.Batching; +using HotChocolate.StarWars; +using HotChocolate.Subscriptions; +using Microsoft.Extensions.DependencyInjection; + +namespace HotChocolate.AspNetClassic +{ + public static class TestingServiceCollectionExtensions + { + public static IServiceCollection AddStarWars( + this IServiceCollection services) + { + // Add the custom services like repositories etc ... + services.AddStarWarsRepositories(); + + // Add in-memory event provider + services.AddInMemorySubscriptionProvider(); + + // Add GraphQL Services + services.AddGraphQL(sp => SchemaBuilder.New() + .AddServices(sp) + .AddStarWarsTypes() + .AddDirectiveType() + .Create()); + + return services; + } + } +} diff --git a/src/Server/AspNetClassic.Tests/Helpers/TestServerExtensions.cs b/src/Server/AspNetClassic.Tests/Helpers/TestServerExtensions.cs index d8827cff6a1..7b9b4f4bfd8 100644 --- a/src/Server/AspNetClassic.Tests/Helpers/TestServerExtensions.cs +++ b/src/Server/AspNetClassic.Tests/Helpers/TestServerExtensions.cs @@ -1,4 +1,4 @@ -using System.Net.Http; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Owin.Testing; @@ -8,7 +8,7 @@ namespace HotChocolate.AspNetClassic { public static class TestServerExtensions { - public static Task SendRequestAsync( + public static Task SendPostRequestAsync( this TestServer testServer, TObject requestBody, string path = null) @@ -16,7 +16,7 @@ public static Task SendRequestAsync( return SendPostRequestAsync( testServer, JsonConvert.SerializeObject(requestBody), - path); + path?.TrimStart('/')); } public static Task SendPostRequestAsync( @@ -27,7 +27,8 @@ public static Task SendPostRequestAsync( return SendPostRequestAsync( testServer, requestBody, - "application/json", path); + "application/json", + path?.TrimStart('/')); } public static Task SendPostRequestAsync( @@ -53,15 +54,13 @@ public static Task SendGetRequestAsync( .GetAsync($"{CreateUrl(path)}?query={normalizedQuery}"); } - private static string CreateUrl(string path) + public static string CreateUrl(string path) { string url = "http://localhost:5000"; - if (path != null) { - url += "/" + path; + url += "/" + path.TrimStart('/'); } - return url; } } diff --git a/src/Server/AspNetClassic.Tests/Helpers/TestServerFactory.cs b/src/Server/AspNetClassic.Tests/Helpers/TestServerFactory.cs index 1c9b5cbc3d1..2a7c85ab88f 100644 --- a/src/Server/AspNetClassic.Tests/Helpers/TestServerFactory.cs +++ b/src/Server/AspNetClassic.Tests/Helpers/TestServerFactory.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Web.Http; using HotChocolate.AspNetClassic.Helpers; -using HotChocolate.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Owin.Testing; +using Owin; namespace HotChocolate.AspNetClassic { @@ -14,33 +14,23 @@ public class TestServerFactory public readonly List _instances = new List(); public TestServer Create( - Action configure, - QueryMiddlewareOptions options) - { - return Create(configure, null, options); - } - - public TestServer Create( - Action configure, Action configureServices, - QueryMiddlewareOptions options) + Action configureApplication) { var server = TestServer.Create(appBuilder => { var httpConfig = new HttpConfiguration(); var serviceCollection = new ServiceCollection(); - configureServices?.Invoke(serviceCollection); serviceCollection.AddOwinContextAccessor(); - serviceCollection.AddScoped(); - serviceCollection.AddGraphQL(configure); + configureServices?.Invoke(serviceCollection); IServiceProvider serviceProvider = serviceCollection .BuildServiceProvider(); httpConfig.DependencyResolver = new DefaultDependencyResolver(serviceProvider); - appBuilder.UseGraphQL(serviceProvider, options); + configureApplication(appBuilder, serviceProvider); }); _instances.Add(server); diff --git a/src/Server/AspNetClassic.Tests/HttpGetMiddlewareOptionsTests.cs b/src/Server/AspNetClassic.Tests/HttpGetMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..3219e6e85d4 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/HttpGetMiddlewareOptionsTests.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.Owin; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class HttpGetMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpGetMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpGetMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/HttpGetSchemaMiddlewareOptionsTests.cs b/src/Server/AspNetClassic.Tests/HttpGetSchemaMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..af2f28413e7 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/HttpGetSchemaMiddlewareOptionsTests.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.Owin; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class HttpGetSchemaMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/HttpPostMiddlewareOptionsTests.cs b/src/Server/AspNetClassic.Tests/HttpPostMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..43f7f54ac96 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/HttpPostMiddlewareOptionsTests.cs @@ -0,0 +1,102 @@ +using System; +using HotChocolate.Language; +using Microsoft.Owin; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class HttpPostMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + + [Fact] + public void SetMaxRequestSizeToZero() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = () => options.MaxRequestSize = 0; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetMaxRequestSize() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + options.MaxRequestSize = 4096 * 1000; + + // assert + Assert.Equal(4096 * 1000, options.MaxRequestSize); + } + + [Fact] + public void DefaultParserOptionsAreSet() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + ParserOptions parserOptions = options.ParserOptions; + + // assert + Assert.NotNull(parserOptions); + } + + [Fact] + public void CannotSetParserOptionsNull() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + Action action = () => options.ParserOptions = null; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetParserOptions() + { + // arrange + var options = new QueryMiddlewareOptions(); + var parserOptions = new ParserOptions(); + + // act + options.ParserOptions = parserOptions; + + // assert + Assert.Equal(parserOptions, options.ParserOptions); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/PostMiddlewareTests.cs b/src/Server/AspNetClassic.Tests/PostMiddlewareTests.cs new file mode 100644 index 00000000000..2392f3bdd87 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/PostMiddlewareTests.cs @@ -0,0 +1,713 @@ +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using HotChocolate.Language; +using Microsoft.Owin.Testing; +using Snapshooter; +using Snapshooter.Xunit; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class PostMiddlewareTests + : ServerTestBase + { + public PostMiddlewareTests(TestServerFactory serverFactory) + : base(serverFactory) + { + } + + [Fact] + public async Task HttpPost_Json_QueryOnly() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_QueryAndEnumVariable() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query h($episode: Episode) { + hero(episode: $episode) { + name + } + } + ", + Variables = new Dictionary + { + { "episode", "EMPIRE" } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_QueryAndStringVariable() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query h($id: String!) { + human(id: $id) { + name + } + } + ", + Variables = new Dictionary + { + { "id", "1000" } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_OnRoot() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_OnSubPath() + { + // arrange + TestServer server = CreateStarWarsServer("/foo"); + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, "foo"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_OnSubPath_PostOnInvalidPath() + { + // arrange + TestServer server = CreateStarWarsServer("/foo"); + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, "bar"); + + // assert + Assert.Equal(HttpStatusCode.NotFound, message.StatusCode); + } + + [Fact] + public async Task HttpPost_Ensure_Response_Casing_Alignes_With_Request() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + { + Hero: hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_Object_Variable() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + mutation CreateReviewForEpisode( + $ep: Episode! + $review: ReviewInput!) { + createReview(episode: $ep, review: $review) { + stars + commentary + } + } + ", + Variables = new Dictionary + { + { "ep", "EMPIRE" }, + { "review", + new Dictionary + { + { "stars", 5 }, + { "commentary", "This is a great movie!" }, + } + } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_Variable_NonNull_Violation() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + mutation CreateReviewForEpisode( + $ep: Episode! + $review: ReviewInput!) { + createReview(episode: $ep, review: $review) { + stars + commentary + } + } + ", + Variables = new Dictionary + { + { "review", + new Dictionary + { + { "stars", 5 }, + { "commentary", "This is a great movie!" }, + } + } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_Variables_In_Object_Fields() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + mutation CreateReviewForEpisode( + $ep: Episode! + $stars: Int! + $commentary: String!) { + createReview(episode: $ep, review: { + stars: $stars + commentary: $commentary + } ) { + stars + commentary + } + } + ", + Variables = new Dictionary + { + { "ep", "EMPIRE" }, + { "stars", 5 }, + { "commentary", "This is a great movie!" } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_Unused_Variable() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + mutation CreateReviewForEpisode( + $ep: Episode! + $stars: Int! + $commentary: String! + $foo: Float) { + createReview(episode: $ep, review: { + stars: $stars + commentary: $commentary + } ) { + stars + commentary + } + } + ", + Variables = new Dictionary + { + { "ep", "EMPIRE" }, + { "stars", 5 }, + { "commentary", "This is a great movie!" } + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [InlineData("a")] + [InlineData("b")] + [Theory] + public async Task HttpPost_Json_QueryAndOperationName( + string operationName) + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + a: hero { + name + } + } + + query b { + b: hero { + name + } + } + ", + OperationName = operationName + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(new SnapshotNameExtension(operationName)); + } + + [Fact] + public async Task HttpPost_Json_CachedQuery() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + ".Replace("\n", string.Empty).Replace("\r", string.Empty), + }; + + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // act + request = new ClientQueryRequest + { + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + message = await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_CachedQuery_2() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + ".Replace("\n", string.Empty).Replace("\r", string.Empty), + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // act + request = new ClientQueryRequest + { + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + message = await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_CachedQuery_NotFound() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + ".Replace("\n", string.Empty).Replace("\r", string.Empty), + NamedQuery = "abc" + }; + + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // act + request = new ClientQueryRequest + { + NamedQuery = "abc" + }; + + message = await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Plain_GraphQL() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = + @" + { + hero { + name + } + } + "; + var contentType = "application/graphql"; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, contentType, null); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_UnknownContentType() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = + @" + { + hero { + name + } + } + "; + var contentType = "application/foo"; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, contentType, null); + + // assert + Assert.Equal(HttpStatusCode.BadRequest, message.StatusCode); + } + + [InlineData("/", null, HttpStatusCode.OK)] + [InlineData("/", "/", HttpStatusCode.OK)] + [InlineData("/graphql", "/graphql/", HttpStatusCode.OK)] + [InlineData("/graphql", "/graphql", HttpStatusCode.OK)] + [InlineData("/graphql/", "/graphql", HttpStatusCode.OK)] + [InlineData("/graphql/", "/graphql/", HttpStatusCode.OK)] + [InlineData("/graphql", "/graphql/foo", HttpStatusCode.NotFound)] + [InlineData("/graphql/foo", "/graphql/foo/", HttpStatusCode.OK)] + [InlineData("/graphql/foo", "/graphql/foo", HttpStatusCode.OK)] + [Theory] + public async Task HttpPost_Path( + string path, + string requestPath, + HttpStatusCode httpStatus) + { + // arrange + TestServer server = CreateStarWarsServer(path); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, requestPath); + + // assert + Assert.Equal(httpStatus, message.StatusCode); + + if (message.StatusCode == HttpStatusCode.OK) + { + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(new SnapshotNameExtension( + path?.Replace("/", "_Slash_"), + requestPath?.Replace("/", "_Slash_"))); + } + } + + [Fact] + public async Task HttpPost_Batch() + { + // arrange + TestServer server = CreateStarWarsServer(); + var batch = new List + { + new ClientQueryRequest + { + Query = + @" + query getHero { + hero(episode: EMPIRE) { + id @export + } + }" + }, + new ClientQueryRequest + { + Query = + @" + query getHuman { + human(id: $id) { + name + } + }" + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(batch); + + // assert + List result = + await DeserializeBatchAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Operation_Batch() + { + // arrange + TestServer server = CreateStarWarsServer(); + var batch = new List + { + new ClientQueryRequest + { + Query = + @" + query getHero { + hero(episode: EMPIRE) { + id @export + } + } + + query getHuman { + human(id: $id) { + name + } + }" + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync( + batch, + "?batchOperations=[getHero, getHuman]"); + + // assert + List result = + await DeserializeBatchAsync(message); + result.MatchSnapshot(); + } + + + [InlineData("?batchOperations=getHero")] + [InlineData("?batchOperations=[getHero")] + [Theory] + public async Task HttpPost_Operation_Batch_Invalid_Argument(string path) + { + // arrange + TestServer server = CreateStarWarsServer(); + var batch = new List + { + new ClientQueryRequest + { + Query = + @" + query getHero { + hero(episode: EMPIRE) { + id @export + } + } + + query getHuman { + human(id: $id) { + name + } + }" + } + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync( + batch, + path); + + // assert + Assert.Equal(HttpStatusCode.OK, message.StatusCode); + byte[] json = await message.Content.ReadAsByteArrayAsync(); + Utf8GraphQLRequestParser.ParseJson(json).MatchSnapshot(); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/QueryMiddlewareOptionsTests.cs b/src/Server/AspNetClassic.Tests/QueryMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..9d25dc86524 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/QueryMiddlewareOptionsTests.cs @@ -0,0 +1,75 @@ +using System; +using HotChocolate.Language; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class QueryMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetEmptySubscriptionPathString() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + Action action = () => options.SubscriptionPath = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void DefaultParserOptionsAreSet() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + ParserOptions parserOptions = options.ParserOptions; + + // assert + Assert.NotNull(parserOptions); + } + + [Fact] + public void CannotSetParserOptionsNull() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + Action action = () => options.ParserOptions = null; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetParserOptions() + { + // arrange + var options = new QueryMiddlewareOptions(); + var parserOptions = new ParserOptions(); + + // act + options.ParserOptions = parserOptions; + + // assert + Assert.Equal(parserOptions, options.ParserOptions); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/QueryMiddlewareTests.cs b/src/Server/AspNetClassic.Tests/QueryMiddlewareTests.cs deleted file mode 100644 index 9f1dab8ed6b..00000000000 --- a/src/Server/AspNetClassic.Tests/QueryMiddlewareTests.cs +++ /dev/null @@ -1,417 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using HotChocolate.Types; -using Microsoft.Owin; -using Microsoft.Owin.Testing; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Snapshooter.Xunit; -using Xunit; - -namespace HotChocolate.AspNetClassic -{ - public class QueryMiddlewareTests - : IClassFixture - { - public QueryMiddlewareTests(TestServerFactory testServerFactory) - { - TestServerFactory = testServerFactory; - } - - private TestServerFactory TestServerFactory { get; set; } - - [Fact] - public async Task HttpPost_BasicTest() - { - // arrange - TestServer server = CreateTestServer("/foo"); - var request = new ClientQueryRequest { Query = "{ basic { a } }" }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request, "foo") - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_Casing() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest { Query = "{ A:basic { B:a } }" }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_EnumArgument() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = "query a($a: TestEnum) { withEnum(test: $a) }", - Variables = JObject.FromObject(new Dictionary - { - { "a", "A"} - }) - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_NestedEnumArgument() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = "query a($a: BarInput) { withNestedEnum(bar: $a) }", - Variables = JObject.FromObject(new Dictionary - { - { "a", new Dictionary - { - { "a", "B" } - } - } - }) - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpGet_BasicTest() - { - // arrange - TestServer server = CreateTestServer(); - var query = "{ basic { a } }"; - - // act - HttpResponseMessage message = await server - .SendGetRequestAsync(query) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpGet_ForwardToNextMiddleware() - { - // arrange - TestServer server = CreateTestServer(); - - // act - HttpResponseMessage message = await server.HttpClient - .GetAsync($"http://localhost:5000/1234"); - - // assert - Assert.Equal(HttpStatusCode.NotFound, message.StatusCode); - } - - [Fact] - public async Task HttpPost_WithScalarVariables() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = @" - query test($a: String!) { - withScalarArgument(a: $a) { - a - b - c - } - }", - Variables = JObject.FromObject(new Dictionary - { - { "a", "1234567890"} - }) - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_WithObjectVariables() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = @" - query test($a: FooInput!) { - withObjectArgument(b: $a) { - a - b - c - } - }", - Variables = JObject.FromObject(new Dictionary - { - { "a", new Dictionary { - {"a", "44"}, - {"b", "55"}, - {"c", 66} - } } - }) - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_WithScopedService() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = @" - { - sayHello - }" - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_WithHttpContext() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = @" - { - requestPath - requestPath2 - requestPath3 - }" - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_CustomProperties() - { - // arrange - TestServer server = CreateTestServer(); - var request = new ClientQueryRequest - { - Query = @" - { - customProperty - }" - }; - - // act - HttpResponseMessage message = await server - .SendRequestAsync(request) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_GraphQLRequest() - { - // arrange - TestServer server = CreateTestServer(); - var request = @" - { - customProperty - }"; - var contentType = "application/graphql"; - - // act - HttpResponseMessage message = await server - .SendPostRequestAsync(request, contentType, null) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.OK, message.StatusCode); - - string json = await message.Content.ReadAsStringAsync() - .ConfigureAwait(false); - ClientQueryResult result = JsonConvert - .DeserializeObject(json); - - Assert.Null(result.Errors); - result.MatchSnapshot(); - } - - [Fact] - public async Task HttpPost_UnknownContentType() - { - // arrange - TestServer server = CreateTestServer(); - var request = @" - { - customProperty - }"; - var contentType = "application/foo"; - - // act - HttpResponseMessage message = await server - .SendPostRequestAsync(request, contentType, null) - .ConfigureAwait(false); - - // assert - Assert.Equal(HttpStatusCode.BadRequest, message.StatusCode); - } - - private TestServer CreateTestServer(string path = null) - { - return TestServerFactory.Create( - c => - { - c.RegisterQueryType(); - c.RegisterType>(); - }, - services => services.AddQueryRequestInterceptor( - (context, request, ct) => - { - request.AddProperty("foo", "bar"); - return Task.CompletedTask; - }), - new QueryMiddlewareOptions - { - Path = new PathString(path ?? "/") - }); - } - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/Foo.cs b/src/Server/AspNetClassic.Tests/Schema/Foo.cs deleted file mode 100644 index 38141d11571..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/Foo.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace HotChocolate.AspNetClassic -{ - public class Foo - { - public string A { get; set; } - public string B { get; set; } - public int C { get; set; } - } - - public class Bar - { - public TestEnum A { get; set; } - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/FooInputType.cs b/src/Server/AspNetClassic.Tests/Schema/FooInputType.cs deleted file mode 100644 index 957ad799324..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/FooInputType.cs +++ /dev/null @@ -1,13 +0,0 @@ -using HotChocolate.Types; - -namespace HotChocolate.AspNetClassic -{ - public class FooInputType - : InputObjectType - { - protected override void Configure(IInputObjectTypeDescriptor descriptor) - { - descriptor.Name("FooInput"); - } - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/Query.cs b/src/Server/AspNetClassic.Tests/Schema/Query.cs deleted file mode 100644 index 0e31c569ff4..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/Query.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using HotChocolate.Resolvers; -using Microsoft.Owin; - -namespace HotChocolate.AspNetClassic -{ - public class Query - { - private readonly TestService _service; - private readonly IOwinContextAccessor _contextAccessor; - - public Query(TestService testService, IOwinContextAccessor contextAccessor) - { - _service = testService - ?? throw new ArgumentNullException(nameof(testService)); - _contextAccessor = contextAccessor - ?? throw new ArgumentNullException(nameof(contextAccessor)); - } - - public string SayHello() - { - return _service.GetGreetings(); - } - - public string GetRequestPath() - { - return _contextAccessor.OwinContext.Request.Path.Value; - } - - public string GetRequestPath2(IResolverContext context) - { - return context.Service() - .OwinContext.Request.Path.Value; - } - - public string GetRequestPath3([Service]IOwinContextAccessor context) - { - return context.OwinContext.Request.Path.Value; - } - - public Foo GetBasic() - { - return new Foo - { - A = "1", - B = "2", - C = 3 - }; - } - - public Foo GetWithScalarArgument(string a) - { - return new Foo - { - A = a, - B = "2", - C = 3 - }; - } - - public Foo GetWithObjectArgument(Foo b) - { - return new Foo - { - A = b.A, - B = "2", - C = b.C - }; - } - - public bool GetWithEnum(TestEnum test) - { - return true; - } - - public TestEnum GetWithNestedEnum(Bar bar) - { - return bar.A; - } - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/QueryType.cs b/src/Server/AspNetClassic.Tests/Schema/QueryType.cs deleted file mode 100644 index fb08d5a98df..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/QueryType.cs +++ /dev/null @@ -1,27 +0,0 @@ -using HotChocolate.Types; - -namespace HotChocolate.AspNetClassic -{ - public class QueryType - : ObjectType - { - protected override void Configure(IObjectTypeDescriptor descriptor) - { - descriptor.Field(t => t.GetBasic()) - .Type>(); - descriptor.Field(t => t.GetWithScalarArgument(default)) - .Type>() - .Argument("a", a => a.Type>()); - descriptor.Field(t => t.GetWithObjectArgument(default)) - .Type>() - .Argument("b", a => - a.Type>() - .DefaultValue(new Foo { A = "hello world", C = 0 })); - descriptor.Field(t => t.GetWithEnum(default)) - .Type>() - .Argument("test", a => a.Type>()); - descriptor.Field("customProperty") - .Resolver(ctx => ctx.CustomProperty("foo")); - } - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/TestEnum.cs b/src/Server/AspNetClassic.Tests/Schema/TestEnum.cs deleted file mode 100644 index 0448fea391c..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/TestEnum.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace HotChocolate.AspNetClassic -{ - public enum TestEnum - { - A, - B - } -} diff --git a/src/Server/AspNetClassic.Tests/Schema/TestService.cs b/src/Server/AspNetClassic.Tests/Schema/TestService.cs deleted file mode 100644 index e936221c4b5..00000000000 --- a/src/Server/AspNetClassic.Tests/Schema/TestService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace HotChocolate.AspNetClassic -{ - public class TestService - { - public string GetGreetings() => "Hello World"; - } -} diff --git a/src/Server/AspNetClassic.Tests/ServerTestBase.cs b/src/Server/AspNetClassic.Tests/ServerTestBase.cs new file mode 100644 index 00000000000..05ae7368f33 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/ServerTestBase.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Owin; +using Microsoft.Owin.Testing; +using Newtonsoft.Json; +using Xunit; + + +namespace HotChocolate.AspNetClassic +{ + public class ServerTestBase + : IClassFixture + { + public ServerTestBase(TestServerFactory serverFactory) + { + ServerFactory = serverFactory; + } + + protected TestServerFactory ServerFactory { get; set; } + + protected TestServer CreateStarWarsServer(string path = null) + { + return ServerFactory.Create( + services => services.AddStarWars(), + (app, sp) => app.UseGraphQL(sp, new PathString(path))); + } + + protected async Task DeserializeAsync( + HttpResponseMessage message) + { + Assert.Equal(HttpStatusCode.OK, message.StatusCode); + string json = await message.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(json); + } + + protected async Task> DeserializeBatchAsync( + HttpResponseMessage message) + { + Assert.Equal(HttpStatusCode.OK, message.StatusCode); + string json = await message.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject>(json); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/ServiceCollectionExtensionsTests.cs b/src/Server/AspNetClassic.Tests/ServiceCollectionExtensionsTests.cs new file mode 100644 index 00000000000..74f2b459cc0 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,872 @@ +using System.Threading.Tasks; +using System; +using System.Linq; +using HotChocolate.Configuration; +using HotChocolate.Execution; +using HotChocolate.Execution.Configuration; +using HotChocolate.Utilities; +using Microsoft.Extensions.DependencyInjection; +using Snapshooter.Xunit; +using Xunit; + +namespace HotChocolate.AspNetClassic +{ + public class ServiceCollectionExtensionsTests + { + [Fact] + public void AddGraphQL_ServicesSchemaBuilder() + { + // arrange + var services = new ServiceCollection(); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + SchemaBuilder.New() + .AddDocumentFromString("type Query { a: String }") + .Use(next => context => Task.CompletedTask)); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchema_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, schema); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchema_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), default(Schema)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchema() + { + // arrange + var services = new ServiceCollection(); + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigure_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + schema, + new Func( + c => c)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigure_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Schema), + new Func( + c => c)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigure_ConfigureNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + schema, + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigure() + { + // arrange + var services = new ServiceCollection(); + var schema = Schema.Create(c => c.Options.StrictValidation = false); + var cfg = new Func( + c => c.UseDefaultPipeline()); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema, + cfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactory_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, new Func(s => schema)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactory_SchemaFactoryNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryBuilder_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + new Func(s => schema), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryBuilder_SchemaFactoryNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Func), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryBuilder_BuilderNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + new Func(s => schema), + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryBuilder() + { + // arrange + var services = new ServiceCollection(); + var schema = Schema.Create(c => c.Options.StrictValidation = false); + var cfg = new Func( + c => c.UseDefaultPipeline()); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + sp => schema, + cfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesConfigure_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + new Action(c => { })); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesConfigure_ConfigureNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Action)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesConfigure() + { + // arrange + var services = new ServiceCollection(); + var schemaCfg = new Action( + c => c.Options.StrictValidation = false); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schemaCfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesConfigureBuilder_ServiceNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesConfigureBuilder_ConfigureNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Action), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesConfigureBuilder_BuilderNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + new Action(c => { }), + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesConfigureBuilder() + { + // arrange + var services = new ServiceCollection(); + var schemaCfg = new Action( + c => c.Options.StrictValidation = false); + var cfg = new Func( + c => c.UseDefaultPipeline()); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schemaCfg, + cfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigure_ServiceNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + "type Query { a: String }", + new Action(c => { })); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigure_SchemaSdlNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(string), + new Action(c => { })); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigure_SchemaSdlEmpty() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + string.Empty, + new Action(c => { })); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigure_ConfigureNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + "type Query { a: String }", + default(Action)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigure() + { + // arrange + var services = new ServiceCollection(); + string schema = "type Query { a: String }"; + var schemaCfg = new Action( + c => c.Options.StrictValidation = false); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema, + schemaCfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld_ServiceNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + "type Query { a: String }", + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld_SchemaSdlNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(string), + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld_SchemaSdlEmpty() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + string.Empty, + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld_ConfigureNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + "type Query { a: String }", + default(Action), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld_BuilderNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + "type Query { a: String }", + new Action(c => { }), + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaSdlConfigureBld() + { + // arrange + var services = new ServiceCollection(); + string schema = "type Query { a: String }"; + var schemaCfg = new Action( + c => c.Options.StrictValidation = false); + var cfg = new Func( + c => c.UseDefaultPipeline()); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema, + schemaCfg, + cfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaOptions_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + schema, + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaOptions_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Schema), + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaOptions_OptionsNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + schema, + default(IQueryExecutionOptionsAccessor)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaOptions() + { + // arrange + var services = new ServiceCollection(); + var schema = Schema.Create(c => c.Options.StrictValidation = false); + var options = new QueryExecutionOptions(); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema, + options); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryOptions_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + sp => schema, + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryOptions_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Func), + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryOptions_OptionsNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + sp => schema, + default(IQueryExecutionOptionsAccessor)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaFactoryOptions() + { + // arrange + var services = new ServiceCollection(); + var schema = Schema.Create(c => c.Options.StrictValidation = false); + var options = new QueryExecutionOptions(); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + sp => schema, + options); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigOptions_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + new Action(c => { }), + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigOptions_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(Action), + new QueryExecutionOptions()); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigOptions_OptionsNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + new Action(c => { }), + default(IQueryExecutionOptionsAccessor)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigOptions() + { + // arrange + var services = new ServiceCollection(); + var options = new QueryExecutionOptions(); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + c => c.Options.StrictValidation = false, + options); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + + [Obsolete("Use different overload.", true)] + [Fact] + public void AddGraphQL_ServicesQueryExecutor_ServiceNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + schema.MakeExecutable()); + + // assert + Assert.Throws(action); + } + + [Obsolete("Use different overload.", true)] + [Fact] + public void AddGraphQL_ServicesQueryExecutor_ExecutorNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + default(IQueryExecutor)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigureBuilder_ServiceNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + null, + "type Query { a: String }", + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigureBuilder_SchemaNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + null, + new Action(c => { }), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigureBuilder_ConfigureNull() + { + // arrange + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + "type Query { a: String }", + default(Action), + new Func( + b => b)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigureBuilder_BuilderNull() + { + // arrange + var schema = Schema.Create(c => c.Options.StrictValidation = false); + + // act + Action action = () => ServiceCollectionExtensions.AddGraphQL( + new ServiceCollection(), + "type Query { a: String }", + new Action(c => { }), + default(Func)); + + // assert + Assert.Throws(action); + } + + [Fact] + public void AddGraphQL_ServicesSchemaConfigureBuilder() + { + // arrange + var services = new ServiceCollection(); + var schema = "type Query { a: String }"; + var schemaCfg = new Action( + c => c.Options.StrictValidation = false); + var cfg = new Func( + c => c.UseDefaultPipeline()); + + // act + ServiceCollectionExtensions.AddGraphQL( + services, + schema, + schemaCfg, + cfg); + + // assert + services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) + .OrderBy(t => t, StringComparer.Ordinal) + .ToArray() + .MatchSnapshot(); + } + } +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServices.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServices.snap new file mode 100644 index 00000000000..30578f35d4f --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServices.snap @@ -0,0 +1,124 @@ +schema { + query: Query + mutation: Mutation + subscription: Subscription +} + +interface Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String +} + +"A connection to a list of items." +type CharacterConnection { + "A list of edges." + edges: [CharacterEdge!] + "A flattened list of the nodes." + nodes: [Character] + "Information to aid in pagination." + pageInfo: PageInfo! + totalCount: Int! +} + +"An edge in a connection." +type CharacterEdge { + "A cursor for use in pagination." + cursor: String! + "The item at the end of the edge." + node: Character +} + +type Droid implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String + primaryFunction: String +} + +type Human implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + homePlanet: String + id: ID! + name: String +} + +type Mutation { + createReview(episode: Episode! review: ReviewInput!): Review! +} + +"Information about pagination in a connection." +type PageInfo { + "When paginating forwards, the cursor to continue." + endCursor: String + "Indicates whether more edges exist following the set defined by the clients arguments." + hasNextPage: Boolean! + "Indicates whether more edges exist prior the set defined by the clients arguments." + hasPreviousPage: Boolean! + "When paginating backwards, the cursor to continue." + startCursor: String +} + +type Query { + character(characterIds: [String]): [Character!]! + droid(id: String): Droid + hero(episode: Episode! = NEWHOPE): Character + human(id: String): Human + search(text: String): [SearchResult] +} + +type Review { + commentary: String + stars: Int! +} + +type Starship { + id: String + length: Float! + name: String +} + +type Subscription { + onReview(episode: Episode!): Review! +} + +union SearchResult = Starship | Human | Droid + +input ReviewInput { + commentary: String + stars: Int! +} + +enum Episode { + NEWHOPE + EMPIRE + JEDI +} + +enum Unit { + FOOT + METERS +} + +"The `Boolean` scalar type represents `true` or `false`." +scalar Boolean + +"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http:\/\/en.wikipedia.org\/wiki\/IEEE_floating_point)." +scalar Float + +"The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." +scalar ID + +"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." +scalar Int + +scalar PaginationAmount + +"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." +scalar String diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServicesOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServicesOptions.snap new file mode 100644 index 00000000000..30578f35d4f --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderServicesOptions.snap @@ -0,0 +1,124 @@ +schema { + query: Query + mutation: Mutation + subscription: Subscription +} + +interface Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String +} + +"A connection to a list of items." +type CharacterConnection { + "A list of edges." + edges: [CharacterEdge!] + "A flattened list of the nodes." + nodes: [Character] + "Information to aid in pagination." + pageInfo: PageInfo! + totalCount: Int! +} + +"An edge in a connection." +type CharacterEdge { + "A cursor for use in pagination." + cursor: String! + "The item at the end of the edge." + node: Character +} + +type Droid implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String + primaryFunction: String +} + +type Human implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + homePlanet: String + id: ID! + name: String +} + +type Mutation { + createReview(episode: Episode! review: ReviewInput!): Review! +} + +"Information about pagination in a connection." +type PageInfo { + "When paginating forwards, the cursor to continue." + endCursor: String + "Indicates whether more edges exist following the set defined by the clients arguments." + hasNextPage: Boolean! + "Indicates whether more edges exist prior the set defined by the clients arguments." + hasPreviousPage: Boolean! + "When paginating backwards, the cursor to continue." + startCursor: String +} + +type Query { + character(characterIds: [String]): [Character!]! + droid(id: String): Droid + hero(episode: Episode! = NEWHOPE): Character + human(id: String): Human + search(text: String): [SearchResult] +} + +type Review { + commentary: String + stars: Int! +} + +type Starship { + id: String + length: Float! + name: String +} + +type Subscription { + onReview(episode: Episode!): Review! +} + +union SearchResult = Starship | Human | Droid + +input ReviewInput { + commentary: String + stars: Int! +} + +enum Episode { + NEWHOPE + EMPIRE + JEDI +} + +enum Unit { + FOOT + METERS +} + +"The `Boolean` scalar type represents `true` or `false`." +scalar Boolean + +"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http:\/\/en.wikipedia.org\/wiki\/IEEE_floating_point)." +scalar Float + +"The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." +scalar ID + +"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." +scalar Int + +scalar PaginationAmount + +"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." +scalar String diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServices.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServices.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServices.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServicesOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServicesOptions.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderServicesOptions.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServices.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServices.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServices.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServicesOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServicesOptions.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderServicesOptions.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/GetMiddlewareTests.HttpGet_QueryOnly.snap b/src/Server/AspNetClassic.Tests/__snapshots__/GetMiddlewareTests.HttpGet_QueryOnly.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/GetMiddlewareTests.HttpGet_QueryOnly.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpGet_BasicTest.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpGet_BasicTest.json deleted file mode 100644 index 92606e8ffee..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpGet_BasicTest.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "basic": { - "a": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_BasicTest.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_BasicTest.json deleted file mode 100644 index 92606e8ffee..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_BasicTest.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "basic": { - "a": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_Casing.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_Casing.json deleted file mode 100644 index c988a89a226..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_Casing.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "A": { - "B": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_CustomProperties.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_CustomProperties.json deleted file mode 100644 index 354a140f2db..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_CustomProperties.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "customProperty": "bar" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_EnumArgument.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_EnumArgument.json deleted file mode 100644 index 3213085c02a..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_EnumArgument.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "withEnum": true - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_GraphQLRequest.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_GraphQLRequest.json deleted file mode 100644 index 354a140f2db..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_GraphQLRequest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "customProperty": "bar" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_NestedEnumArgument.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_NestedEnumArgument.json deleted file mode 100644 index 0389bfc11b6..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_NestedEnumArgument.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "withNestedEnum": "B" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithHttpContext.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithHttpContext.json deleted file mode 100644 index aef137eb67b..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithHttpContext.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "requestPath": "/", - "requestPath2": "/", - "requestPath3": "/" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithObjectVariables.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithObjectVariables.json deleted file mode 100644 index e4fbbd784a7..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithObjectVariables.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Data": { - "withObjectArgument": { - "a": "44", - "b": "2", - "c": 66 - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScalarVariables.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScalarVariables.json deleted file mode 100644 index 306021aed76..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScalarVariables.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Data": { - "withScalarArgument": { - "a": "1234567890", - "b": "2", - "c": 3 - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScopedService.json b/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScopedService.json deleted file mode 100644 index 03183d5faf4..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/HttpPost_WithScopedService.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "sayHello": "Hello World" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Batch.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Batch.snap new file mode 100644 index 00000000000..0a9961091a5 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Batch.snap @@ -0,0 +1,20 @@ +[ + { + "Data": { + "hero": { + "id": "1000" + } + }, + "Errors": null, + "Extensions": null + }, + { + "Data": { + "human": { + "name": "Luke Skywalker" + } + }, + "Errors": null, + "Extensions": null + } +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Ensure_Response_Casing_Alignes_With_Request.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Ensure_Response_Casing_Alignes_With_Request.snap new file mode 100644 index 00000000000..1a5cc31e91e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Ensure_Response_Casing_Alignes_With_Request.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "Hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap new file mode 100644 index 00000000000..2567876533c --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap @@ -0,0 +1,12 @@ +{ + "Data": null, + "Errors": [ + { + "message": "persistedQueryNotFound", + "extensions": { + "code": "CACHED_QUERY_NOT_FOUND" + } + } + ], + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Object_Variable.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Object_Variable.snap new file mode 100644 index 00000000000..baf4b38cbe7 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Object_Variable.snap @@ -0,0 +1,10 @@ +{ + "Data": { + "createReview": { + "stars": 5, + "commentary": "This is a great movie!" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnRoot.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnRoot.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnRoot.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnSubPath.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnSubPath.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_OnSubPath.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndEnumVariable.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndEnumVariable.snap new file mode 100644 index 00000000000..8fb414072f0 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndEnumVariable.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "Luke Skywalker" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_a.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_a.snap new file mode 100644 index 00000000000..69d97c5974a --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_a.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "a": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_b.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_b.snap new file mode 100644 index 00000000000..457de11526b --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndOperationName_b.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "b": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndStringVariable.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndStringVariable.snap new file mode 100644 index 00000000000..bbe643cd0b4 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryAndStringVariable.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "human": { + "name": "Luke Skywalker" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryOnly.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryOnly.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_QueryOnly.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Unused_Variable.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Unused_Variable.snap new file mode 100644 index 00000000000..bd0f20ffbc5 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Unused_Variable.snap @@ -0,0 +1,15 @@ +{ + "Data": null, + "Errors": [ + { + "message": "The following variables were not used: foo.", + "locations": [ + { + "line": 2, + "column": 21 + } + ] + } + ], + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variable_NonNull_Violation.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variable_NonNull_Violation.snap new file mode 100644 index 00000000000..3f7014f8364 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variable_NonNull_Violation.snap @@ -0,0 +1,18 @@ +{ + "Data": null, + "Errors": [ + { + "message": "Variable `ep` of type `Episode!` must not be null.", + "locations": [ + { + "line": 3, + "column": 25 + } + ], + "extensions": { + "variableName": "ep" + } + } + ], + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variables_In_Object_Fields.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variables_In_Object_Fields.snap new file mode 100644 index 00000000000..baf4b38cbe7 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_Variables_In_Object_Fields.snap @@ -0,0 +1,10 @@ +{ + "Data": { + "createReview": { + "stars": 5, + "commentary": "This is a great movie!" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch.snap new file mode 100644 index 00000000000..0a9961091a5 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch.snap @@ -0,0 +1,20 @@ +[ + { + "Data": { + "hero": { + "id": "1000" + } + }, + "Errors": null, + "Extensions": null + }, + { + "Data": { + "human": { + "name": "Luke Skywalker" + } + }, + "Errors": null, + "Extensions": null + } +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch_Invalid_Argument.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch_Invalid_Argument.snap new file mode 100644 index 00000000000..a8a268e6424 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Operation_Batch_Invalid_Argument.snap @@ -0,0 +1,10 @@ +{ + "errors": [ + { + "message": "Invalid GraphQL Request.", + "extensions": { + "code": "INVALID_REQUEST" + } + } + ] +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash__.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash__.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash__.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash___Slash_.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash___Slash_.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash___Slash_.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql_Slash_.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql_Slash_.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash___Slash_graphql_Slash_.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo_Slash_.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo_Slash_.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql_Slash_foo__Slash_graphql_Slash_foo_Slash_.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql_Slash_.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql_Slash_.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Path__Slash_graphql__Slash_graphql_Slash_.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Plain_GraphQL.snap b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Plain_GraphQL.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Plain_GraphQL.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpGet_BasicTest.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpGet_BasicTest.snap deleted file mode 100644 index 92606e8ffee..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpGet_BasicTest.snap +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "basic": { - "a": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_BasicTest.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_BasicTest.snap deleted file mode 100644 index 92606e8ffee..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_BasicTest.snap +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "basic": { - "a": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_Casing.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_Casing.snap deleted file mode 100644 index c988a89a226..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_Casing.snap +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "A": { - "B": "1" - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_CustomProperties.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_CustomProperties.snap deleted file mode 100644 index 354a140f2db..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_CustomProperties.snap +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "customProperty": "bar" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_EnumArgument.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_EnumArgument.snap deleted file mode 100644 index 3213085c02a..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_EnumArgument.snap +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "withEnum": true - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_GraphQLRequest.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_GraphQLRequest.snap deleted file mode 100644 index 354a140f2db..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_GraphQLRequest.snap +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "customProperty": "bar" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_NestedEnumArgument.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_NestedEnumArgument.snap deleted file mode 100644 index 0389bfc11b6..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_NestedEnumArgument.snap +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "withNestedEnum": "B" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithHttpContext.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithHttpContext.snap deleted file mode 100644 index aef137eb67b..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithHttpContext.snap +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Data": { - "requestPath": "/", - "requestPath2": "/", - "requestPath3": "/" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithObjectVariables.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithObjectVariables.snap deleted file mode 100644 index e4fbbd784a7..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithObjectVariables.snap +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Data": { - "withObjectArgument": { - "a": "44", - "b": "2", - "c": 66 - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScalarVariables.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScalarVariables.snap deleted file mode 100644 index 306021aed76..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScalarVariables.snap +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Data": { - "withScalarArgument": { - "a": "1234567890", - "b": "2", - "c": 3 - } - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScopedService.snap b/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScopedService.snap deleted file mode 100644 index 03183d5faf4..00000000000 --- a/src/Server/AspNetClassic.Tests/__snapshots__/QueryMiddlewareTests.HttpPost_WithScopedService.snap +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Data": { - "sayHello": "Hello World" - }, - "Errors": null -} diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigure.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigure.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigure.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigureBuilder.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigureBuilder.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesConfigureBuilder.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchema.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchema.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchema.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaBuilder.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaBuilder.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaBuilder.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigOptions.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigOptions.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigure.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigure.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigure.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigureBuilder.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigureBuilder.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaConfigureBuilder.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryBuilder.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryBuilder.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryBuilder.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryOptions.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaFactoryOptions.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaOptions.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaOptions.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaOptions.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigure.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigure.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigure.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigureBld.snap b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigureBld.snap new file mode 100644 index 00000000000..100e457665e --- /dev/null +++ b/src/Server/AspNetClassic.Tests/__snapshots__/ServiceCollectionExtensionsTests.AddGraphQL_ServicesSchemaSdlConfigureBld.snap @@ -0,0 +1,54 @@ +[ + "HotChocolate.Execution.Batching.IBatchQueryExecutor", + "HotChocolate.Execution.Configuration.IErrorHandlerOptionsAccessor", + "HotChocolate.Execution.Configuration.IInstrumentationOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryCacheSizeOptionsAccessor", + "HotChocolate.Execution.Configuration.IQueryExecutionOptionsAccessor", + "HotChocolate.Execution.Configuration.IRequestTimeoutOptionsAccessor", + "HotChocolate.Execution.Configuration.IValidateQueryOptionsAccessor", + "HotChocolate.Execution.IExecutionStrategyResolver", + "HotChocolate.Execution.IQueryExecutor", + "HotChocolate.Execution.IQueryParser", + "HotChocolate.Execution.IQueryResultSerializer", + "HotChocolate.Execution.IResponseStreamSerializer", + "HotChocolate.Execution.Instrumentation.QueryExecutionDiagnostics", + "HotChocolate.IErrorHandler", + "HotChocolate.ISchema", + "HotChocolate.Language.IDocumentCache", + "HotChocolate.Language.IDocumentHashProvider", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Runtime.Cache", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidationRule", + "HotChocolate.Validation.IQueryValidator", + "System.Diagnostics.DiagnosticListener", + "System.Diagnostics.DiagnosticSource" +] diff --git a/src/Server/AspNetClassic.Voyager/AspNetClassic.Voyager.csproj b/src/Server/AspNetClassic.Voyager/AspNetClassic.Voyager.csproj index e450d19a538..38bfaebbc84 100644 --- a/src/Server/AspNetClassic.Voyager/AspNetClassic.Voyager.csproj +++ b/src/Server/AspNetClassic.Voyager/AspNetClassic.Voyager.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic.Voyager HotChocolate.AspNetClassic.Voyager HotChocolate.AspNetClassic.Voyager - Contains a GraphQL Voyager for ASP.net classic that can be used with the Hot Chocolate GraphQL server. + Contains a GraphQL Voyager for ASP .Net classic that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetClassic/AspNetClassic.csproj b/src/Server/AspNetClassic/AspNetClassic.csproj index ba32de12757..b8fa2d95dba 100644 --- a/src/Server/AspNetClassic/AspNetClassic.csproj +++ b/src/Server/AspNetClassic/AspNetClassic.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetClassic HotChocolate.AspNetClassic HotChocolate.AspNetClassic - Contains the Hot Chocolate GraphQL middleware for ASP.net classic. + Contains the Hot Chocolate GraphQL middleware for ASP .Net classic. @@ -31,15 +31,13 @@ + + + - + diff --git a/src/Server/AspNetClassic/Extensions/ApplicationBuilderExtensions.cs b/src/Server/AspNetClassic/Extensions/ApplicationBuilderExtensions.cs index 6f969c70720..936e44b130a 100644 --- a/src/Server/AspNetClassic/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Server/AspNetClassic/Extensions/ApplicationBuilderExtensions.cs @@ -1,11 +1,6 @@ using System; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Owin; -using Owin; using IApplicationBuilder = Owin.IAppBuilder; -using HotChocolate.Execution; -using HotChocolate.Execution.Batching; -using HotChocolate.Language; namespace HotChocolate.AspNetClassic { @@ -53,34 +48,24 @@ public static IApplicationBuilder UseGraphQL( throw new ArgumentNullException(nameof(options)); } - IQueryExecutor executor = serviceProvider - .GetRequiredService(); - - IBatchQueryExecutor batchExecutor = serviceProvider - .GetRequiredService(); - - IQueryResultSerializer serializer = serviceProvider - .GetService() - ?? new JsonQueryResultSerializer(); - - IDocumentCache cache = serviceProvider - .GetRequiredService(); - - IDocumentHashProvider hashProvider = serviceProvider - .GetRequiredService(); - - OwinContextAccessor contextAccessor = - serviceProvider.GetService(); - return applicationBuilder - .Use( - executor, batchExecutor, serializer, - cache, hashProvider, contextAccessor, - options) - .Use( - executor, serializer, contextAccessor, - options) - .Use(executor, options); + .UseGraphQLHttpPost(serviceProvider, + new HttpPostMiddlewareOptions + { + Path = options.Path, + ParserOptions = options.ParserOptions, + MaxRequestSize = options.MaxRequestSize + }) + .UseGraphQLHttpGet(serviceProvider, + new HttpGetMiddlewareOptions + { + Path = options.Path + }) + .UseGraphQLHttpGetSchema(serviceProvider, + new HttpGetSchemaMiddlewareOptions + { + Path = options.Path.Add(new PathString("/schema")) + }); } } } diff --git a/src/Server/AspNetCore.Abstractions/AspNetCore.Abstractions.csproj b/src/Server/AspNetCore.Abstractions/AspNetCore.Abstractions.csproj index 720f01b3d8e..c24bdf1c876 100644 --- a/src/Server/AspNetCore.Abstractions/AspNetCore.Abstractions.csproj +++ b/src/Server/AspNetCore.Abstractions/AspNetCore.Abstractions.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.Abstractions HotChocolate.AspNetCore HotChocolate.AspNetCore.Abstractions - Contains the Hot Chocolate GraphQL middleware abstractions for ASP.net core. + Contains the Hot Chocolate GraphQL middleware abstractions for ASP .Net core. @@ -26,6 +26,7 @@ + diff --git a/src/Server/AspNetCore.Abstractions/Extensions/HttpContextExtensions.cs b/src/Server/AspNetCore.Abstractions/Extensions/HttpContextExtensions.cs index 13a7bcf5b0d..6fbb3f500c1 100644 --- a/src/Server/AspNetCore.Abstractions/Extensions/HttpContextExtensions.cs +++ b/src/Server/AspNetCore.Abstractions/Extensions/HttpContextExtensions.cs @@ -19,7 +19,7 @@ namespace HotChocolate.AspNetClassic namespace HotChocolate.AspNetCore #endif { - internal static class HttpContextExtensions + public static class HttpContextExtensions { #if ASPNETCLASSIC public static IServiceProvider CreateRequestServices( @@ -84,19 +84,5 @@ public static bool IsValidPath( || context.Request.Path.Equals(path2, StringComparison.OrdinalIgnoreCase); } - - public static bool IsValidPath( - this HttpContext context, - params PathString[] paths) - { - for (int i = 0; i < paths.Length; i++) - { - if(!IsValidPath(context, paths[i])) - { - return false; - } - } - return true; - } } } diff --git a/src/Server/AspNetCore.Abstractions/Extensions/SerializerExtensions.cs b/src/Server/AspNetCore.Abstractions/Extensions/SerializerExtensions.cs new file mode 100644 index 00000000000..90e58f70d42 --- /dev/null +++ b/src/Server/AspNetCore.Abstractions/Extensions/SerializerExtensions.cs @@ -0,0 +1,46 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using HotChocolate.Execution; + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +#else +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public static class SerializerExtensions + { + public static Task SerializeAsync( + this IQueryResultSerializer serializer, + IExecutionResult result, + Stream outputStream, + CancellationToken cancellationToken) + { + if (result is IReadOnlyQueryResult queryResult) + { + return serializer.SerializeAsync( + queryResult, + outputStream, + cancellationToken); + } + else + { + return serializer.SerializeAsync( + QueryResult.CreateError( + ErrorBuilder.New() + .SetMessage("Result type not supported.") + .SetCode("RESULT_TYPE_NOT_SUPPORTED") + .Build()), + outputStream, + cancellationToken); + } + } + } +} diff --git a/src/Server/AspNetCore/HttpMethods.cs b/src/Server/AspNetCore.Abstractions/HttpMethods.cs similarity index 84% rename from src/Server/AspNetCore/HttpMethods.cs rename to src/Server/AspNetCore.Abstractions/HttpMethods.cs index dcc5b71f4d2..0e38cfef23a 100644 --- a/src/Server/AspNetCore/HttpMethods.cs +++ b/src/Server/AspNetCore.Abstractions/HttpMethods.cs @@ -4,7 +4,7 @@ namespace HotChocolate.AspNetClassic namespace HotChocolate.AspNetCore #endif { - internal static class HttpMethods + public static class HttpMethods { public const string Post = "POST"; public const string Get = "GET"; diff --git a/src/Server/AspNetCore.Abstractions/IParserOptionsAccessor.cs b/src/Server/AspNetCore.Abstractions/IParserOptionsAccessor.cs new file mode 100644 index 00000000000..70cfc73e7ec --- /dev/null +++ b/src/Server/AspNetCore.Abstractions/IParserOptionsAccessor.cs @@ -0,0 +1,19 @@ +using HotChocolate.Language; + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HotChocolate.AspNetClassic.Interceptors; +#else +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public interface IParserOptionsAccessor + { + ParserOptions ParserOptions { get; } + } +} diff --git a/src/Server/AspNetCore.Abstractions/IPathOptionAccessor.cs b/src/Server/AspNetCore.Abstractions/IPathOptionAccessor.cs new file mode 100644 index 00000000000..637abdd0ff4 --- /dev/null +++ b/src/Server/AspNetCore.Abstractions/IPathOptionAccessor.cs @@ -0,0 +1,19 @@ + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HotChocolate.AspNetClassic.Interceptors; +#else +using Microsoft.AspNetCore.Http; +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public interface IPathOptionAccessor + { + PathString Path { get; } + } +} diff --git a/src/Server/AspNetCore.Abstractions/QueryMiddlewareBase.cs b/src/Server/AspNetCore.Abstractions/QueryMiddlewareBase.cs index 7fd8cfc858f..9bae1e15bee 100644 --- a/src/Server/AspNetCore.Abstractions/QueryMiddlewareBase.cs +++ b/src/Server/AspNetCore.Abstractions/QueryMiddlewareBase.cs @@ -31,7 +31,6 @@ public abstract class QueryMiddlewareBase private const int _badRequest = 400; private const int _ok = 200; - private readonly IQueryResultSerializer _resultSerializer; private readonly Func _isPathValid; private IQueryRequestInterceptor _interceptor; @@ -57,21 +56,21 @@ public abstract class QueryMiddlewareBase /// protected QueryMiddlewareBase( RequestDelegate next, - IQueryResultSerializer resultSerializer, + IPathOptionAccessor options, OwinContextAccessor owinContextAccessor, - QueryMiddlewareOptions options, IServiceProvider services) : base(next) { - _resultSerializer = resultSerializer - ?? throw new ArgumentNullException(nameof(resultSerializer)); + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + _accessor = owinContextAccessor; - Options = options - ?? throw new ArgumentNullException(nameof(options)); _services = services ?? throw new ArgumentNullException(nameof(services)); - if (Options.Path.Value.Length > 1) + if (options.Path.Value.Length > 1) { var path1 = new PathString(options.Path.Value.TrimEnd('/')); PathString path2 = path1.Add(new PathString("/")); @@ -85,16 +84,16 @@ protected QueryMiddlewareBase( #else protected QueryMiddlewareBase( RequestDelegate next, - IQueryResultSerializer resultSerializer, - QueryMiddlewareOptions options) + IPathOptionAccessor options) { - Next = next; - _resultSerializer = resultSerializer - ?? throw new ArgumentNullException(nameof(resultSerializer)); - Options = options ?? + if (options == null) + { throw new ArgumentNullException(nameof(options)); + } + + Next = next; - if (Options.Path.Value.Length > 1) + if (options.Path.Value.Length > 1) { var path1 = new PathString(options.Path.Value.TrimEnd('/')); PathString path2 = path1.Add(new PathString("/")); @@ -109,11 +108,6 @@ protected QueryMiddlewareBase( protected RequestDelegate Next { get; } #endif - /// - /// Gets the GraphQL middleware options. - /// - protected QueryMiddlewareOptions Options { get; } - #if ASPNETCLASSIC /// public override async Task Invoke(HttpContext context) @@ -220,26 +214,6 @@ await _interceptor.OnCreateAsync( return builder.Create(); } - protected Task WriteResponseAsync( - HttpResponse response, - IExecutionResult executionResult) - { - SetResponseHeaders(response); - return WriteBatchResponseAsync(response, executionResult); - } - - protected async Task WriteBatchResponseAsync( - HttpResponse response, - IExecutionResult executionResult) - { - if (executionResult is IReadOnlyQueryResult queryResult) - { - await _resultSerializer.SerializeAsync( - queryResult, response.Body) - .ConfigureAwait(false); - } - } - protected static void SetResponseHeaders( HttpResponse response) { diff --git a/src/Server/AspNetCore.Authorization/AspNetCore.Authorization.csproj b/src/Server/AspNetCore.Authorization/AspNetCore.Authorization.csproj index 6f75e3375cf..433620321ec 100644 --- a/src/Server/AspNetCore.Authorization/AspNetCore.Authorization.csproj +++ b/src/Server/AspNetCore.Authorization/AspNetCore.Authorization.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.Authorization HotChocolate.AspNetCore.Authorization HotChocolate.AspNetCore.Authorization - Contains authorization extensions for the Hot Chocolate ASP.net classic GraphQL middleware. + Contains authorization extensions for the Hot Chocolate ASP .Net classic GraphQL middleware. diff --git a/src/Server/AspNetCore.GraphiQL/AspNetCore.GraphiQL.csproj b/src/Server/AspNetCore.GraphiQL/AspNetCore.GraphiQL.csproj index 083e87aac92..adad910b34a 100644 --- a/src/Server/AspNetCore.GraphiQL/AspNetCore.GraphiQL.csproj +++ b/src/Server/AspNetCore.GraphiQL/AspNetCore.GraphiQL.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.GraphiQL HotChocolate.AspNetCore.GraphiQL HotChocolate.AspNetCore.GraphiQL - Contains a GraphiQL middleware for ASP.net core that can be used with the Hot Chocolate GraphQL server. + Contains a GraphiQL middleware for ASP .Net core that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetCore.HttpGet/AspNetCore.HttpGet.csproj b/src/Server/AspNetCore.HttpGet/AspNetCore.HttpGet.csproj new file mode 100644 index 00000000000..a9cfce288d1 --- /dev/null +++ b/src/Server/AspNetCore.HttpGet/AspNetCore.HttpGet.csproj @@ -0,0 +1,35 @@ + + + + netstandard2.0 + HotChocolate.AspNetCore.HttpGet + HotChocolate.AspNetCore.HttpGet + HotChocolate.AspNetCore.HttpGet + Contains the Hot Chocolate GraphQL HTTP GET middleware for ASP .Net core. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG + + + + pdbonly + true + TRACE + + + + + + + + + + + diff --git a/src/Server/AspNetCore.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs b/src/Server/AspNetCore.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..d6c9bde4563 --- /dev/null +++ b/src/Server/AspNetCore.HttpGet/Extensions/HttpGetApplicationBuilderExtensions.cs @@ -0,0 +1,32 @@ +using System; +using Microsoft.AspNetCore.Builder; + +namespace HotChocolate.AspNetCore +{ + public static class HttpGetApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpGet( + this IApplicationBuilder applicationBuilder) => + UseGraphQLHttpGet( + applicationBuilder, + new HttpGetMiddlewareOptions()); + + public static IApplicationBuilder UseGraphQLHttpGet( + this IApplicationBuilder applicationBuilder, + IHttpGetMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return applicationBuilder + .UseMiddleware(options); + } + } +} diff --git a/src/Server/AspNetCore/GetQueryMiddleware.cs b/src/Server/AspNetCore.HttpGet/HttpGetMiddleware.cs similarity index 64% rename from src/Server/AspNetCore/GetQueryMiddleware.cs rename to src/Server/AspNetCore.HttpGet/HttpGetMiddleware.cs index a0356e0f49a..ece4621c561 100644 --- a/src/Server/AspNetCore/GetQueryMiddleware.cs +++ b/src/Server/AspNetCore.HttpGet/HttpGetMiddleware.cs @@ -19,7 +19,7 @@ namespace HotChocolate.AspNetClassic namespace HotChocolate.AspNetCore #endif { - public class GetQueryMiddleware + public class HttpGetMiddleware : QueryMiddlewareBase { private const string _namedQueryIdentifier = "namedQuery"; @@ -28,33 +28,37 @@ public class GetQueryMiddleware private const string _variablesIdentifier = "variables"; private readonly IQueryExecutor _queryExecutor; + private readonly IQueryResultSerializer _resultSerializer; #if ASPNETCLASSIC - public GetQueryMiddleware( + public HttpGetMiddleware( RequestDelegate next, - IQueryExecutor queryExecutor, - IQueryResultSerializer resultSerializer, + IHttpGetMiddlewareOptions options, OwinContextAccessor owinContextAccessor, - QueryMiddlewareOptions options) + IQueryExecutor queryExecutor, + IQueryResultSerializer resultSerializer) : base(next, - resultSerializer, - owinContextAccessor, options, + owinContextAccessor, queryExecutor.Schema.Services) { _queryExecutor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); + _resultSerializer = resultSerializer + ?? throw new ArgumentNullException(nameof(resultSerializer)); } #else - public GetQueryMiddleware( + public HttpGetMiddleware( RequestDelegate next, + IHttpGetMiddlewareOptions options, IQueryExecutor queryExecutor, - IQueryResultSerializer resultSerializer, - QueryMiddlewareOptions options) - : base(next, resultSerializer, options) + IQueryResultSerializer resultSerializer) + : base(next, options) { _queryExecutor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); + _resultSerializer = resultSerializer + ?? throw new ArgumentNullException(nameof(resultSerializer)); } #endif @@ -72,17 +76,18 @@ protected override async Task ExecuteRequestAsync( HttpContext context, IServiceProvider services) { + var builder = QueryRequestBuilder.New(); + #if ASPNETCLASSIC IReadableStringCollection requestQuery = context.Request.Query; #else IQueryCollection requestQuery = context.Request.Query; #endif - IQueryRequestBuilder builder = - QueryRequestBuilder.New() - .SetQuery(requestQuery[_queryIdentifier]) - .SetQueryName(requestQuery[_namedQueryIdentifier]) - .SetOperation(requestQuery[_operationNameIdentifier]); + builder + .SetQuery(requestQuery[_queryIdentifier]) + .SetQueryName(requestQuery[_namedQueryIdentifier]) + .SetOperation(requestQuery[_operationNameIdentifier]); string variables = requestQuery[_variablesIdentifier]; if (variables != null @@ -101,18 +106,27 @@ await BuildRequestAsync( .ConfigureAwait(false); IExecutionResult result = await _queryExecutor - .ExecuteAsync(request, context.GetCancellationToken()) - .ConfigureAwait(false); + .ExecuteAsync(request, context.GetCancellationToken()) + .ConfigureAwait(false); + + SetResponseHeaders(context.Response); - await WriteResponseAsync(context.Response, result) + await _resultSerializer.SerializeAsync( + result, + context.Response.Body, + context.GetCancellationToken()) .ConfigureAwait(false); } private static bool HasQueryParameter(HttpContext context) { - return context.Request.QueryString.HasValue && - context.Request.Query.ToDictionary(i => i.Key, i => i.Value) - .ContainsKey(_queryIdentifier); +#if ASPNETCLASSIC + return context.Request.Query[_queryIdentifier] != null + || context.Request.Query[_namedQueryIdentifier] != null; +#else + return context.Request.Query[_queryIdentifier].Count != 0 + || context.Request.Query[_namedQueryIdentifier].Count != 0; +#endif } } } diff --git a/src/Server/AspNetCore.HttpGet/HttpGetMiddlewareOptions.cs b/src/Server/AspNetCore.HttpGet/HttpGetMiddlewareOptions.cs new file mode 100644 index 00000000000..decd59466e1 --- /dev/null +++ b/src/Server/AspNetCore.HttpGet/HttpGetMiddlewareOptions.cs @@ -0,0 +1,39 @@ +using System; +using HotChocolate.Language; + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +using Microsoft.AspNetCore.Http; +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public class HttpGetMiddlewareOptions + : IHttpGetMiddlewareOptions + { + private PathString _path = new PathString("/"); + + public PathString Path + { + get => _path; + set + { + if (!value.HasValue) + { + // TODO : resources + throw new ArgumentException( + "The path cannot be empty."); + } + + _path = value; + } + } + } +} diff --git a/src/Server/AspNetCore.HttpGet/IHttpGetMiddlewareOptions.cs b/src/Server/AspNetCore.HttpGet/IHttpGetMiddlewareOptions.cs new file mode 100644 index 00000000000..09155a6f052 --- /dev/null +++ b/src/Server/AspNetCore.HttpGet/IHttpGetMiddlewareOptions.cs @@ -0,0 +1,18 @@ +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public interface IHttpGetMiddlewareOptions + : IPathOptionAccessor + { + } +} diff --git a/src/Server/AspNetCore.HttpGetSchema/AspNetCore.HttpGetSchema.csproj b/src/Server/AspNetCore.HttpGetSchema/AspNetCore.HttpGetSchema.csproj new file mode 100644 index 00000000000..b7b042ad094 --- /dev/null +++ b/src/Server/AspNetCore.HttpGetSchema/AspNetCore.HttpGetSchema.csproj @@ -0,0 +1,35 @@ + + + + netstandard2.0 + HotChocolate.AspNetCore.HttpGetSchema + HotChocolate.AspNetCore.HttpGetSchema + HotChocolate.AspNetCore.HttpGetSchema + Contains the Hot Chocolate GraphQL HTTP GET schema middleware for ASP .Net core. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG + + + + pdbonly + true + TRACE + + + + + + + + + + + diff --git a/src/Server/AspNetCore.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs b/src/Server/AspNetCore.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..aa91989f831 --- /dev/null +++ b/src/Server/AspNetCore.HttpGetSchema/Extensions/HttpGetSchemaApplicationBuilderExtensions.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.AspNetCore.Builder; + +namespace HotChocolate.AspNetCore +{ + public static class HttpGetSchemaApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpGetSchema( + this IApplicationBuilder applicationBuilder) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + return UseGraphQLHttpGetSchema( + applicationBuilder, + new HttpGetSchemaMiddlewareOptions()); + } + + public static IApplicationBuilder UseGraphQLHttpGetSchema( + this IApplicationBuilder applicationBuilder, + IHttpGetSchemaMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return applicationBuilder + .UseMiddleware(options); + } + } +} diff --git a/src/Server/AspNetCore/SchemaMiddleware.cs b/src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddleware.cs similarity index 76% rename from src/Server/AspNetCore/SchemaMiddleware.cs rename to src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddleware.cs index b346e2927ab..b04ac5aa50a 100644 --- a/src/Server/AspNetCore/SchemaMiddleware.cs +++ b/src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddleware.cs @@ -1,7 +1,8 @@ -using System; +using System; using System.IO; using System.Threading.Tasks; using HotChocolate.Execution; +using HotChocolate.Server; #if ASPNETCLASSIC using Microsoft.Owin; @@ -18,7 +19,7 @@ namespace HotChocolate.AspNetClassic namespace HotChocolate.AspNetCore #endif { - internal sealed class SchemaMiddleware + internal sealed class HttpGetSchemaMiddleware #if ASPNETCLASSIC : RequestDelegate #endif @@ -26,12 +27,12 @@ internal sealed class SchemaMiddleware private readonly PathString _path; private readonly IQueryExecutor _queryExecutor; - public SchemaMiddleware( - RequestDelegate next, - IQueryExecutor queryExecutor, - QueryMiddlewareOptions options) + public HttpGetSchemaMiddleware( + RequestDelegate next, + IHttpGetSchemaMiddlewareOptions options, + IQueryExecutor queryExecutor) #if ASPNETCLASSIC - : base(next) + : base(next) #endif { #if !ASPNETCLASSIC @@ -44,7 +45,7 @@ public SchemaMiddleware( _queryExecutor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); - _path = options.Path.Add(new PathString("/schema")); + _path = options.Path; } #if !ASPNETCLASSIC @@ -57,10 +58,12 @@ public override async Task Invoke(HttpContext context) public async Task InvokeAsync(HttpContext context) #endif { - if (context.Request.Method.Equals(HttpMethods.Get, - StringComparison.Ordinal) && context.IsValidPath(_path)) + if (context.Request.Method.Equals( + HttpMethods.Get, + StringComparison.Ordinal) + && context.IsValidPath(_path)) { - context.Response.ContentType = "application/graphql"; + context.Response.ContentType = ContentType.GraphQL; context.Response.Headers.Add( "Content-Disposition", new[] { "attachment; filename=\"schema.graphql\"" }); diff --git a/src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddlewareOptions.cs b/src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddlewareOptions.cs new file mode 100644 index 00000000000..9b30d93527c --- /dev/null +++ b/src/Server/AspNetCore.HttpGetSchema/HttpGetSchemaMiddlewareOptions.cs @@ -0,0 +1,39 @@ +using System; + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using HttpResponse = Microsoft.Owin.IOwinResponse; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +using Microsoft.AspNetCore.Http; +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public class HttpGetSchemaMiddlewareOptions + : IHttpGetSchemaMiddlewareOptions + { + private PathString _path = new PathString("/"); + + public PathString Path + { + get => _path; + set + { + if (!value.HasValue) + { + // TODO : resources + throw new ArgumentException( + "The path cannot be empty."); + } + + _path = value; + } + } + } +} diff --git a/src/Server/AspNetCore.HttpGetSchema/IHttpGetSchemaMiddlewareOptions.cs b/src/Server/AspNetCore.HttpGetSchema/IHttpGetSchemaMiddlewareOptions.cs new file mode 100644 index 00000000000..72de6757f9d --- /dev/null +++ b/src/Server/AspNetCore.HttpGetSchema/IHttpGetSchemaMiddlewareOptions.cs @@ -0,0 +1,19 @@ +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using HttpResponse = Microsoft.Owin.IOwinResponse; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public interface IHttpGetSchemaMiddlewareOptions + : IPathOptionAccessor + { + } +} diff --git a/src/Server/AspNetCore.HttpPost/AspNetCore.HttpPost.csproj b/src/Server/AspNetCore.HttpPost/AspNetCore.HttpPost.csproj new file mode 100644 index 00000000000..24e0fd6cf1e --- /dev/null +++ b/src/Server/AspNetCore.HttpPost/AspNetCore.HttpPost.csproj @@ -0,0 +1,35 @@ + + + + netstandard2.0 + HotChocolate.AspNetCore.HttpPost + HotChocolate.AspNetCore.HttpPost + HotChocolate.AspNetCore.HttpPost + Contains the Hot Chocolate GraphQL HTTP POST middleware for ASP .Net core. + + + + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + portable + true + TRACE;DEBUG + + + + pdbonly + true + TRACE + + + + + + + + + + + diff --git a/src/Server/AspNetCore.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs b/src/Server/AspNetCore.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs new file mode 100644 index 00000000000..12a9748c220 --- /dev/null +++ b/src/Server/AspNetCore.HttpPost/Extensions/HttpPostApplicationBuilderExtensions.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.AspNetCore.Builder; + +namespace HotChocolate.AspNetCore +{ + public static class HttpPostApplicationBuilderExtensions + { + public static IApplicationBuilder UseGraphQLHttpPost( + this IApplicationBuilder applicationBuilder) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + return UseGraphQLHttpPost( + applicationBuilder, + new HttpPostMiddlewareOptions()); + } + + public static IApplicationBuilder UseGraphQLHttpPost( + this IApplicationBuilder applicationBuilder, + IHttpPostMiddlewareOptions options) + { + if (applicationBuilder == null) + { + throw new ArgumentNullException(nameof(applicationBuilder)); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return applicationBuilder + .UseMiddleware(options); + } + } +} diff --git a/src/Server/AspNetCore/PostQueryMiddleware.cs b/src/Server/AspNetCore.HttpPost/HttpPostMiddleware.cs similarity index 74% rename from src/Server/AspNetCore/PostQueryMiddleware.cs rename to src/Server/AspNetCore.HttpPost/HttpPostMiddleware.cs index 19dc5882765..33a0dc0ee90 100644 --- a/src/Server/AspNetCore/PostQueryMiddleware.cs +++ b/src/Server/AspNetCore.HttpPost/HttpPostMiddleware.cs @@ -6,12 +6,9 @@ using HotChocolate.Language; using HotChocolate.Server; using HotChocolate.Execution.Batching; -using System.Threading; -using System.Linq; using System.Text; #if ASPNETCLASSIC -using Microsoft.Owin; using HttpContext = Microsoft.Owin.IOwinContext; using RequestDelegate = Microsoft.Owin.OwinMiddleware; #else @@ -24,37 +21,40 @@ namespace HotChocolate.AspNetClassic namespace HotChocolate.AspNetCore #endif { - public class PostQueryMiddleware + public class HttpPostMiddleware : QueryMiddlewareBase { private const string _batchOperations = "batchOperations"; - private const byte _leftBracket = (byte)'['; - private const byte _rightBracket = (byte)']'; - private const byte _comma = (byte)','; private readonly RequestHelper _requestHelper; private readonly IQueryExecutor _queryExecutor; private readonly IBatchQueryExecutor _batchExecutor; + private readonly IQueryResultSerializer _resultSerializer; + private readonly IResponseStreamSerializer _streamSerializer; #if ASPNETCLASSIC - public PostQueryMiddleware( + public HttpPostMiddleware( RequestDelegate next, + IHttpPostMiddlewareOptions options, + OwinContextAccessor owinContextAccessor, IQueryExecutor queryExecutor, - IBatchQueryExecutor batchExecutor, + IBatchQueryExecutor batchQueryExecutor, IQueryResultSerializer resultSerializer, + IResponseStreamSerializer streamSerializer, IDocumentCache documentCache, - IDocumentHashProvider documentHashProvider, - OwinContextAccessor owinContextAccessor, - QueryMiddlewareOptions options) + IDocumentHashProvider documentHashProvider) : base(next, - resultSerializer, - owinContextAccessor, options, + owinContextAccessor, queryExecutor.Schema.Services) { _queryExecutor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); - _batchExecutor = batchExecutor - ?? throw new ArgumentNullException(nameof(batchExecutor)); + _batchExecutor = batchQueryExecutor + ?? throw new ArgumentNullException(nameof(batchQueryExecutor)); + _resultSerializer = resultSerializer + ?? throw new ArgumentNullException(nameof(resultSerializer)); + _streamSerializer = streamSerializer + ?? throw new ArgumentNullException(nameof(streamSerializer)); _requestHelper = new RequestHelper( documentCache, @@ -63,20 +63,25 @@ public PostQueryMiddleware( options.ParserOptions); } #else - public PostQueryMiddleware( + public HttpPostMiddleware( RequestDelegate next, + IHttpPostMiddlewareOptions options, IQueryExecutor queryExecutor, - IBatchQueryExecutor batchExecutor, + IBatchQueryExecutor batchQueryExecutor, IQueryResultSerializer resultSerializer, + IResponseStreamSerializer streamSerializer, IDocumentCache documentCache, - IDocumentHashProvider documentHashProvider, - QueryMiddlewareOptions options) - : base(next, resultSerializer, options) + IDocumentHashProvider documentHashProvider) + : base(next, options) { _queryExecutor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); - _batchExecutor = batchExecutor - ?? throw new ArgumentNullException(nameof(batchExecutor)); + _batchExecutor = batchQueryExecutor + ?? throw new ArgumentNullException(nameof(batchQueryExecutor)); + _resultSerializer = resultSerializer + ?? throw new ArgumentNullException(nameof(resultSerializer)); + _streamSerializer = streamSerializer + ?? throw new ArgumentNullException(nameof(streamSerializer)); _requestHelper = new RequestHelper( documentCache, @@ -126,7 +131,8 @@ await ExecuteOperationBatchAsync( .SetMessage("Invalid GraphQL Request.") .SetCode("INVALID_REQUEST") .Build()); - await WriteResponseAsync(context.Response, result) + await _resultSerializer.SerializeAsync( + result, context.Response.Body) .ConfigureAwait(false); } } @@ -153,7 +159,10 @@ await BuildRequestAsync( .ExecuteAsync(queryRequest, context.GetCancellationToken()) .ConfigureAwait(false); - await WriteResponseAsync(context.Response, result) + await _resultSerializer.SerializeAsync( + result, + context.Response.Body, + context.GetCancellationToken()) .ConfigureAwait(false); } @@ -169,11 +178,14 @@ await BuildBatchRequestAsync( context, services, request, operationNames) .ConfigureAwait(false); - IResponseStream stream = await _batchExecutor + IResponseStream responseStream = await _batchExecutor .ExecuteAsync(requestBatch, context.GetCancellationToken()) .ConfigureAwait(false); - await WriteBatchResultAsync(context, stream) + await _streamSerializer.SerializeAsync( + responseStream, + context.Response.Body, + context.GetCancellationToken()) .ConfigureAwait(false); } @@ -186,61 +198,14 @@ private async Task ExecuteQueryBatchAsync( await BuildBatchRequestAsync(context, services, batch) .ConfigureAwait(false); - IResponseStream stream = await _batchExecutor + IResponseStream responseStream = await _batchExecutor .ExecuteAsync(requestBatch, context.GetCancellationToken()) .ConfigureAwait(false); - await WriteBatchResultAsync(context, stream) - .ConfigureAwait(false); - } - - private async Task WriteBatchResultAsync( - HttpContext context, - IResponseStream stream) - { - // TODO : we might want different stream result types ... we might want to put that im a serializer that can be injected. - SetResponseHeaders(context.Response); - - context.Response.Body.WriteByte(_leftBracket); - - await WriteNextResultAsync(context, stream, false) - .ConfigureAwait(false); - - while (!stream.IsCompleted) - { - await WriteNextResultAsync(context, stream, true) - .ConfigureAwait(false); - } - - context.Response.Body.WriteByte(_rightBracket); - } - - private async Task WriteNextResultAsync( - HttpContext context, - IResponseStream stream, - bool delimiter) - { - CancellationToken requestAborted = context.GetCancellationToken(); - - IReadOnlyQueryResult result = - await stream.ReadAsync(requestAborted) - .ConfigureAwait(false); - - if (result == null) - { - return; - } - - if (delimiter) - { - context.Response.Body.WriteByte(_comma); - } - - await WriteBatchResponseAsync(context.Response, result) - .ConfigureAwait(false); - - await context.Response.Body.FlushAsync( - requestAborted) + await _streamSerializer.SerializeAsync( + responseStream, + context.Response.Body, + context.GetCancellationToken()) .ConfigureAwait(false); } @@ -296,15 +261,15 @@ protected async Task> ReadRequestAsync( { IReadOnlyList batch = null; - switch (context.Request.ContentType.Split(';')[0]) + switch (ParseContentType(context.Request.ContentType)) { - case ContentType.Json: + case AllowedContentType.Json: batch = await _requestHelper .ReadJsonRequestAsync(stream) .ConfigureAwait(false); break; - case ContentType.GraphQL: + case AllowedContentType.GraphQL: batch = await _requestHelper .ReadGraphQLQueryAsync(stream) .ConfigureAwait(false); @@ -318,6 +283,32 @@ protected async Task> ReadRequestAsync( } } + private static AllowedContentType ParseContentType(string s) + { + ReadOnlySpan span = s.AsSpan(); + + for(int i = 0; i < span.Length; i++) + { + if(span[i] == ';') + { + span = span.Slice(0, i); + break; + } + } + + if(span.SequenceEqual(ContentType.GraphQLSpan())) + { + return AllowedContentType.GraphQL; + } + + if (span.SequenceEqual(ContentType.JsonSpan())) + { + return AllowedContentType.Json; + } + + return AllowedContentType.None; + } + private static bool TryParseOperations( string operationNameString, out IReadOnlyList operationNames) @@ -348,5 +339,12 @@ private static bool TryParseOperations( operationNames = names; return true; } + + private enum AllowedContentType + { + None, + GraphQL, + Json + } } } diff --git a/src/Server/AspNetCore.HttpPost/HttpPostMiddlewareOptions.cs b/src/Server/AspNetCore.HttpPost/HttpPostMiddlewareOptions.cs new file mode 100644 index 00000000000..b5a67bef726 --- /dev/null +++ b/src/Server/AspNetCore.HttpPost/HttpPostMiddlewareOptions.cs @@ -0,0 +1,74 @@ +using System; +using HotChocolate.Language; + +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +using Microsoft.AspNetCore.Http; +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public class HttpPostMiddlewareOptions + : IHttpPostMiddlewareOptions + { + private const int _minMaxRequestSize = 1024; + private PathString _path = new PathString("/"); + private ParserOptions _parserOptions = new ParserOptions(); + private int _maxRequestSize = 20 * 1000 * 1000; + + public PathString Path + { + get => _path; + set + { + if (!value.HasValue) + { + // TODO : resources + throw new ArgumentException( + "The path cannot be empty."); + } + + _path = value; + } + } + + public ParserOptions ParserOptions + { + get => _parserOptions; + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + _parserOptions = value; + } + } + + public int MaxRequestSize + { + get => _maxRequestSize; + set + { + if (value < _minMaxRequestSize) + { + // TODO : resources + throw new ArgumentException( + "The minimum max request size is 1024 byte.", + nameof(value)); + } + + _maxRequestSize = value; + } + } + } + + +} diff --git a/src/Server/AspNetCore.HttpPost/IHttpPostMiddlewareOptions.cs b/src/Server/AspNetCore.HttpPost/IHttpPostMiddlewareOptions.cs new file mode 100644 index 00000000000..0cd0eb64f40 --- /dev/null +++ b/src/Server/AspNetCore.HttpPost/IHttpPostMiddlewareOptions.cs @@ -0,0 +1,20 @@ +#if ASPNETCLASSIC +using Microsoft.Owin; +using HttpContext = Microsoft.Owin.IOwinContext; +using RequestDelegate = Microsoft.Owin.OwinMiddleware; +#else +#endif + +#if ASPNETCLASSIC +namespace HotChocolate.AspNetClassic +#else +namespace HotChocolate.AspNetCore +#endif +{ + public interface IHttpPostMiddlewareOptions + : IPathOptionAccessor + , IParserOptionsAccessor + { + int MaxRequestSize { get; } + } +} diff --git a/src/Server/AspNetCore.Playground/AspNetCore.Playground.csproj b/src/Server/AspNetCore.Playground/AspNetCore.Playground.csproj index 676d566207a..4a351862a38 100644 --- a/src/Server/AspNetCore.Playground/AspNetCore.Playground.csproj +++ b/src/Server/AspNetCore.Playground/AspNetCore.Playground.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.Playground HotChocolate.AspNetCore.Playground HotChocolate.AspNetCore.Playground - Contains a GraphQL Playground for ASP.net core that can be used with the Hot Chocolate GraphQL server. + Contains a GraphQL Playground for ASP .Net core that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetCore.Subscriptions.Tests/LargeMessageTests.cs b/src/Server/AspNetCore.Subscriptions.Tests/LargeMessageTests.cs index c1e138df2f5..40de93928dd 100644 --- a/src/Server/AspNetCore.Subscriptions.Tests/LargeMessageTests.cs +++ b/src/Server/AspNetCore.Subscriptions.Tests/LargeMessageTests.cs @@ -44,7 +44,7 @@ await webSocket.SendSubscriptionStartAsync( // assert await webSocket.SendEmptyMessageAsync(); - await testServer.SendRequestAsync(new ClientQueryRequest + await testServer.SendPostRequestAsync(new ClientQueryRequest { Query = @" mutation { diff --git a/src/Server/AspNetCore.Subscriptions.Tests/WebSocketProtocolTests.cs b/src/Server/AspNetCore.Subscriptions.Tests/WebSocketProtocolTests.cs index 56800d421f7..89ecd5aa757 100644 --- a/src/Server/AspNetCore.Subscriptions.Tests/WebSocketProtocolTests.cs +++ b/src/Server/AspNetCore.Subscriptions.Tests/WebSocketProtocolTests.cs @@ -135,7 +135,7 @@ public Task Send_Start_ReceiveDataOnMutation() await webSocket.SendSubscriptionStartAsync(subscriptionId, request); // assert - await testServer.SendRequestAsync(new ClientQueryRequest + await testServer.SendPostRequestAsync(new ClientQueryRequest { Query = @" mutation { @@ -181,7 +181,7 @@ public Task Send_Start_Stop() await webSocket.SendSubscriptionStartAsync(subscriptionId, request); - await testServer.SendRequestAsync(new ClientQueryRequest + await testServer.SendPostRequestAsync(new ClientQueryRequest { Query = @" mutation { @@ -204,7 +204,7 @@ await WaitForMessage( // act await webSocket.SendSubscriptionStopAsync(subscriptionId); - await testServer.SendRequestAsync(new ClientQueryRequest + await testServer.SendPostRequestAsync(new ClientQueryRequest { Query = @" mutation { diff --git a/src/Server/AspNetCore.Subscriptions/AspNetCore.Subscriptions.csproj b/src/Server/AspNetCore.Subscriptions/AspNetCore.Subscriptions.csproj index 8cece31d96e..4272d037858 100644 --- a/src/Server/AspNetCore.Subscriptions/AspNetCore.Subscriptions.csproj +++ b/src/Server/AspNetCore.Subscriptions/AspNetCore.Subscriptions.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.Subscriptions HotChocolate.AspNetCore.Subscriptions HotChocolate.AspNetCore.Subscriptions - Contains the Hot Chocolate GraphQL subscription middleware for ASP.net core. + Contains the Hot Chocolate GraphQL subscription middleware for ASP .Net core. @@ -25,14 +25,12 @@ - - - + diff --git a/src/Server/AspNetCore.Subscriptions/Messages/DataStartMessageHandler.cs b/src/Server/AspNetCore.Subscriptions/Messages/DataStartMessageHandler.cs index 5e709f9324e..793aa1d35a3 100644 --- a/src/Server/AspNetCore.Subscriptions/Messages/DataStartMessageHandler.cs +++ b/src/Server/AspNetCore.Subscriptions/Messages/DataStartMessageHandler.cs @@ -30,7 +30,6 @@ protected override async Task HandleAsync( QueryRequestBuilder.New() .SetQuery(message.Payload.Query) .SetQueryName(message.Payload.QueryName) - .SetQueryHash(message.Payload.QueryName) .SetOperation(message.Payload.OperationName) .SetVariableValues(message.Payload.Variables) .SetProperties(message.Payload.Extensions) diff --git a/src/Server/AspNetCore.Subscriptions/SubscriptionMiddleware.cs b/src/Server/AspNetCore.Subscriptions/SubscriptionMiddleware.cs index dacf941d66b..838d124129d 100644 --- a/src/Server/AspNetCore.Subscriptions/SubscriptionMiddleware.cs +++ b/src/Server/AspNetCore.Subscriptions/SubscriptionMiddleware.cs @@ -28,7 +28,7 @@ public SubscriptionMiddleware( public async Task InvokeAsync(HttpContext context) { if (context.WebSockets.IsWebSocketRequest - && IsValidPath(context, _options.SubscriptionPath)) + && IsValidPath(context, _options.Path)) { await WebSocketSession .New(context, _messagePipeline) diff --git a/src/Server/AspNetCore.Subscriptions/SubscriptionMiddlewareOptions.cs b/src/Server/AspNetCore.Subscriptions/SubscriptionMiddlewareOptions.cs index b3b40065885..d4ac6bad089 100644 --- a/src/Server/AspNetCore.Subscriptions/SubscriptionMiddlewareOptions.cs +++ b/src/Server/AspNetCore.Subscriptions/SubscriptionMiddlewareOptions.cs @@ -10,7 +10,7 @@ public class SubscriptionMiddlewareOptions public ParserOptions ParserOptions { get; set; } = new ParserOptions(); - public PathString SubscriptionPath + public PathString Path { get => _subscriptionPath; set diff --git a/src/Server/AspNetCore.Tests.Utilities/TestServerExtensions.cs b/src/Server/AspNetCore.Tests.Utilities/TestServerExtensions.cs index db589004471..79b75772ea3 100644 --- a/src/Server/AspNetCore.Tests.Utilities/TestServerExtensions.cs +++ b/src/Server/AspNetCore.Tests.Utilities/TestServerExtensions.cs @@ -1,4 +1,4 @@ -using System.Net.Http; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.TestHost; @@ -8,13 +8,13 @@ namespace HotChocolate.AspNetCore.Tests.Utilities { public static class TestServerExtensions { - public static Task SendRequestAsync( + public static Task SendPostRequestAsync( this TestServer testServer, TObject requestBody, string path = null) { return SendPostRequestAsync( testServer, JsonConvert.SerializeObject(requestBody), - path?.TrimStart('/')); + path); } public static Task SendPostRequestAsync( @@ -46,12 +46,12 @@ public static Task SendGetRequestAsync( .GetAsync($"{CreateUrl(path)}?query={normalizedQuery}"); } - private static string CreateUrl(string path) + public static string CreateUrl(string path) { string url = "http://localhost:5000"; if (path != null) { - url += "/" + path; + url += "/" + path.TrimStart('/'); } return url; } diff --git a/src/Server/AspNetCore.Tests/ApplicationBuilderTests.cs b/src/Server/AspNetCore.Tests/ApplicationBuilderTests.cs new file mode 100644 index 00000000000..89ca8f5f4fa --- /dev/null +++ b/src/Server/AspNetCore.Tests/ApplicationBuilderTests.cs @@ -0,0 +1,303 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using HotChocolate.AspNetCore.Tests.Utilities; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.TestHost; +using Moq; +using Snapshooter.Xunit; +using Xunit; + +namespace HotChocolate.AspNetCore +{ + public class ApplicationBuilderTests + : ServerTestBase + { + public ApplicationBuilderTests(TestServerFactory serverFactory) + : base(serverFactory) + { + } + + [Fact] + public void UseGraphQLHttpGet_Builder_BuilderIsNull() + { + // arrange + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGet_Builder() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpGet()); + + HttpClient client = server.CreateClient(); + + // act + HttpResponseMessage message = + await server.SendGetRequestAsync("{ hero { name } }"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGet_BuilderOptions_BuilderIsNull() + { + // arrange + var options = new HttpGetMiddlewareOptions(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGet_BuilderOptions_OptionsIsNull() + { + // arrange + IApplicationBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpGetApplicationBuilderExtensions + .UseGraphQLHttpGet(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGet_BuilderOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpGet( + new HttpGetMiddlewareOptions + { + Path = "/foo" + })); + + HttpClient client = server.CreateClient(); + + // act + HttpResponseMessage message = + await server.SendGetRequestAsync( + "{ hero { name } }", "foo"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpPost_Builder_BuilderIsNull() + { + // arrange + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpPost_Builder() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpPost()); + + HttpClient client = server.CreateClient(); + + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderOptions_BuilderIsNull() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpPost_BuilderOptions_OptionsIsNull() + { + // arrange + IApplicationBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpPostApplicationBuilderExtensions + .UseGraphQLHttpPost(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpPost_BuilderOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpPost( + new HttpPostMiddlewareOptions + { + Path = "/foo" + })); + + HttpClient client = server.CreateClient(); + + var request = new ClientQueryRequest + { + Query = + @" + { + hero { + name + } + } + " + }; + + // act + HttpResponseMessage message = + await server.SendPostRequestAsync(request, "foo"); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGetSchema_Builder_BuilderIsNull() + { + // arrange + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGetSchema_Builder() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpGetSchema()); + + HttpClient client = server.CreateClient(); + + string uri = TestServerExtensions.CreateUrl(null); + + // act + HttpResponseMessage message = await client.GetAsync(uri); + + // assert + string s = await message.Content.ReadAsStringAsync(); + s.MatchSnapshot(); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderOptions_BuilderIsNull() + { + // arrange + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(null, options); + + // assert + Assert.Throws(action); + } + + [Fact] + public void UseGraphQLHttpGetSchema_BuilderOptions_OptionsIsNull() + { + // arrange + IApplicationBuilder builder = Mock.Of(); + + // act + Action action = + () => HttpGetSchemaApplicationBuilderExtensions + .UseGraphQLHttpGetSchema(builder, null); + + // assert + Assert.Throws(action); + } + + [Fact] + public async Task UseGraphQLHttpGetSchema_BuilderOptions() + { + // arrange + TestServer server = ServerFactory.Create( + services => services.AddStarWars(), + app => app.UseGraphQLHttpGetSchema( + new HttpGetSchemaMiddlewareOptions + { + Path = "/foo" + })); + + HttpClient client = server.CreateClient(); + + string uri = TestServerExtensions.CreateUrl("foo"); + + // act + HttpResponseMessage message = await client.GetAsync(uri); + + // assert + string s = await message.Content.ReadAsStringAsync(); + s.MatchSnapshot(); + } + } +} diff --git a/src/Server/AspNetCore.Tests/AspNetCore.Tests.csproj b/src/Server/AspNetCore.Tests/AspNetCore.Tests.csproj index 561274c9dac..51fdb6f3d01 100644 --- a/src/Server/AspNetCore.Tests/AspNetCore.Tests.csproj +++ b/src/Server/AspNetCore.Tests/AspNetCore.Tests.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Server/AspNetCore.Tests/HttpGetMiddlewareOptionsTests.cs b/src/Server/AspNetCore.Tests/HttpGetMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..473b6845082 --- /dev/null +++ b/src/Server/AspNetCore.Tests/HttpGetMiddlewareOptionsTests.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.AspNetCore.Http; +using Xunit; + +namespace HotChocolate.AspNetCore +{ + public class HttpGetMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpGetMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpGetMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + } +} diff --git a/src/Server/AspNetCore.Tests/HttpGetSchemaMiddlewareOptionsTests.cs b/src/Server/AspNetCore.Tests/HttpGetSchemaMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..ca8ae463a93 --- /dev/null +++ b/src/Server/AspNetCore.Tests/HttpGetSchemaMiddlewareOptionsTests.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.AspNetCore.Http; +using Xunit; + +namespace HotChocolate.AspNetCore +{ + public class HttpGetSchemaMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpGetSchemaMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + } +} diff --git a/src/Server/AspNetCore.Tests/HttpPostMiddlewareOptionsTests.cs b/src/Server/AspNetCore.Tests/HttpPostMiddlewareOptionsTests.cs new file mode 100644 index 00000000000..8c89b5dab6f --- /dev/null +++ b/src/Server/AspNetCore.Tests/HttpPostMiddlewareOptionsTests.cs @@ -0,0 +1,102 @@ +using System; +using HotChocolate.Language; +using Microsoft.AspNetCore.Http; +using Xunit; + +namespace HotChocolate.AspNetCore +{ + public class HttpPostMiddlewareOptionsTests + { + [Fact] + public void SetEmptyPathString() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = () => options.Path = default; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetPath() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + options.Path = new PathString("/foo"); + + // assert + Assert.Equal(new PathString("/foo"), options.Path); + } + + [Fact] + public void SetMaxRequestSizeToZero() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + Action action = () => options.MaxRequestSize = 0; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetMaxRequestSize() + { + // arrange + var options = new HttpPostMiddlewareOptions(); + + // act + options.MaxRequestSize = 4096 * 1000; + + // assert + Assert.Equal(4096 * 1000, options.MaxRequestSize); + } + + [Fact] + public void DefaultParserOptionsAreSet() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + ParserOptions parserOptions = options.ParserOptions; + + // assert + Assert.NotNull(parserOptions); + } + + [Fact] + public void CannotSetParserOptionsNull() + { + // arrange + var options = new QueryMiddlewareOptions(); + + // act + Action action = () => options.ParserOptions = null; + + // assert + Assert.Throws(action); + } + + [Fact] + public void SetParserOptions() + { + // arrange + var options = new QueryMiddlewareOptions(); + var parserOptions = new ParserOptions(); + + // act + options.ParserOptions = parserOptions; + + // assert + Assert.Equal(parserOptions, options.ParserOptions); + } + } +} diff --git a/src/Server/AspNetCore.Tests/PostMiddlewareTests.cs b/src/Server/AspNetCore.Tests/PostMiddlewareTests.cs index 0dd3c3ec7ff..62024c99b9d 100644 --- a/src/Server/AspNetCore.Tests/PostMiddlewareTests.cs +++ b/src/Server/AspNetCore.Tests/PostMiddlewareTests.cs @@ -38,7 +38,7 @@ public async Task HttpPost_Json_QueryOnly() // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -68,7 +68,7 @@ query h($episode: Episode) { // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -98,7 +98,7 @@ query h($id: String!) { // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -124,7 +124,7 @@ public async Task HttpPost_Json_OnRoot() // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -150,7 +150,7 @@ public async Task HttpPost_Json_OnSubPath() // act HttpResponseMessage message = - await server.SendRequestAsync(request, "foo"); + await server.SendPostRequestAsync(request, "foo"); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -176,7 +176,7 @@ public async Task HttpPost_Json_OnSubPath_PostOnInvalidPath() // act HttpResponseMessage message = - await server.SendRequestAsync(request, "bar"); + await server.SendPostRequestAsync(request, "bar"); // assert Assert.Equal(HttpStatusCode.NotFound, message.StatusCode); @@ -201,7 +201,7 @@ public async Task HttpPost_Ensure_Response_Casing_Alignes_With_Request() // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -241,7 +241,7 @@ mutation CreateReviewForEpisode( // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -280,7 +280,7 @@ mutation CreateReviewForEpisode( // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -319,7 +319,7 @@ mutation CreateReviewForEpisode( // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -359,7 +359,7 @@ mutation CreateReviewForEpisode( // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -395,7 +395,7 @@ query b { // act HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -416,12 +416,79 @@ query a { name } } - ", + ".Replace("\n", string.Empty).Replace("\r", string.Empty), + }; + + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // act + request = new ClientQueryRequest + { + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + message = await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_CachedQuery_2() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + ".Replace("\n", string.Empty).Replace("\r", string.Empty), + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + HttpResponseMessage message = + await server.SendPostRequestAsync(request); + + // act + request = new ClientQueryRequest + { + NamedQuery = "W5vrrAIypCbniaIYeroNnw==" + }; + + message = await server.SendPostRequestAsync(request); + + // assert + ClientQueryResult result = await DeserializeAsync(message); + result.MatchSnapshot(); + } + + [Fact] + public async Task HttpPost_Json_CachedQuery_NotFound() + { + // arrange + TestServer server = CreateStarWarsServer(); + var request = new ClientQueryRequest + { + Query = + @" + query a { + hero { + name + } + } + ".Replace("\n", string.Empty).Replace("\r", string.Empty), NamedQuery = "abc" }; HttpResponseMessage message = - await server.SendRequestAsync(request); + await server.SendPostRequestAsync(request); // act request = new ClientQueryRequest @@ -429,7 +496,7 @@ query a { NamedQuery = "abc" }; - message = await server.SendRequestAsync(request); + message = await server.SendPostRequestAsync(request); // assert ClientQueryResult result = await DeserializeAsync(message); @@ -514,7 +581,7 @@ query a { // act HttpResponseMessage message = - await server.SendRequestAsync(request, requestPath); + await server.SendPostRequestAsync(request, requestPath); // assert Assert.Equal(httpStatus, message.StatusCode); @@ -559,7 +626,7 @@ query getHuman { // act HttpResponseMessage message = - await server.SendRequestAsync(batch); + await server.SendPostRequestAsync(batch); // assert List result = @@ -594,7 +661,7 @@ query getHuman { // act HttpResponseMessage message = - await server.SendRequestAsync( + await server.SendPostRequestAsync( batch, "?batchOperations=[getHero, getHuman]"); @@ -634,7 +701,7 @@ query getHuman { // act HttpResponseMessage message = - await server.SendRequestAsync( + await server.SendPostRequestAsync( batch, path); diff --git a/src/Server/AspNetCore.Tests/ServiceCollectionExtensionsTests.cs b/src/Server/AspNetCore.Tests/ServiceCollectionExtensionsTests.cs index 25318803a59..ff6fb8b361d 100644 --- a/src/Server/AspNetCore.Tests/ServiceCollectionExtensionsTests.cs +++ b/src/Server/AspNetCore.Tests/ServiceCollectionExtensionsTests.cs @@ -24,8 +24,7 @@ public void AddGraphQL_ServicesSchemaBuilder() services, SchemaBuilder.New() .AddDocumentFromString("type Query { a: String }") - .Use(next => context => Task.CompletedTask) - .Create()); + .Use(next => context => Task.CompletedTask)); // assert services.Select(t => ReflectionUtils.GetTypeName(t.ServiceType)) diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_Builder.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_Builder.snap new file mode 100644 index 00000000000..30578f35d4f --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_Builder.snap @@ -0,0 +1,124 @@ +schema { + query: Query + mutation: Mutation + subscription: Subscription +} + +interface Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String +} + +"A connection to a list of items." +type CharacterConnection { + "A list of edges." + edges: [CharacterEdge!] + "A flattened list of the nodes." + nodes: [Character] + "Information to aid in pagination." + pageInfo: PageInfo! + totalCount: Int! +} + +"An edge in a connection." +type CharacterEdge { + "A cursor for use in pagination." + cursor: String! + "The item at the end of the edge." + node: Character +} + +type Droid implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String + primaryFunction: String +} + +type Human implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + homePlanet: String + id: ID! + name: String +} + +type Mutation { + createReview(episode: Episode! review: ReviewInput!): Review! +} + +"Information about pagination in a connection." +type PageInfo { + "When paginating forwards, the cursor to continue." + endCursor: String + "Indicates whether more edges exist following the set defined by the clients arguments." + hasNextPage: Boolean! + "Indicates whether more edges exist prior the set defined by the clients arguments." + hasPreviousPage: Boolean! + "When paginating backwards, the cursor to continue." + startCursor: String +} + +type Query { + character(characterIds: [String]): [Character!]! + droid(id: String): Droid + hero(episode: Episode! = NEWHOPE): Character + human(id: String): Human + search(text: String): [SearchResult] +} + +type Review { + commentary: String + stars: Int! +} + +type Starship { + id: String + length: Float! + name: String +} + +type Subscription { + onReview(episode: Episode!): Review! +} + +union SearchResult = Starship | Human | Droid + +input ReviewInput { + commentary: String + stars: Int! +} + +enum Episode { + NEWHOPE + EMPIRE + JEDI +} + +enum Unit { + FOOT + METERS +} + +"The `Boolean` scalar type represents `true` or `false`." +scalar Boolean + +"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http:\/\/en.wikipedia.org\/wiki\/IEEE_floating_point)." +scalar Float + +"The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." +scalar ID + +"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." +scalar Int + +scalar PaginationAmount + +"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." +scalar String diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderOptions.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderOptions.snap new file mode 100644 index 00000000000..30578f35d4f --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGetSchema_BuilderOptions.snap @@ -0,0 +1,124 @@ +schema { + query: Query + mutation: Mutation + subscription: Subscription +} + +interface Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String +} + +"A connection to a list of items." +type CharacterConnection { + "A list of edges." + edges: [CharacterEdge!] + "A flattened list of the nodes." + nodes: [Character] + "Information to aid in pagination." + pageInfo: PageInfo! + totalCount: Int! +} + +"An edge in a connection." +type CharacterEdge { + "A cursor for use in pagination." + cursor: String! + "The item at the end of the edge." + node: Character +} + +type Droid implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + id: ID! + name: String + primaryFunction: String +} + +type Human implements Character { + appearsIn: [Episode] + friends(after: String before: String first: PaginationAmount last: PaginationAmount): CharacterConnection + height(unit: Unit): Float + homePlanet: String + id: ID! + name: String +} + +type Mutation { + createReview(episode: Episode! review: ReviewInput!): Review! +} + +"Information about pagination in a connection." +type PageInfo { + "When paginating forwards, the cursor to continue." + endCursor: String + "Indicates whether more edges exist following the set defined by the clients arguments." + hasNextPage: Boolean! + "Indicates whether more edges exist prior the set defined by the clients arguments." + hasPreviousPage: Boolean! + "When paginating backwards, the cursor to continue." + startCursor: String +} + +type Query { + character(characterIds: [String]): [Character!]! + droid(id: String): Droid + hero(episode: Episode! = NEWHOPE): Character + human(id: String): Human + search(text: String): [SearchResult] +} + +type Review { + commentary: String + stars: Int! +} + +type Starship { + id: String + length: Float! + name: String +} + +type Subscription { + onReview(episode: Episode!): Review! +} + +union SearchResult = Starship | Human | Droid + +input ReviewInput { + commentary: String + stars: Int! +} + +enum Episode { + NEWHOPE + EMPIRE + JEDI +} + +enum Unit { + FOOT + METERS +} + +"The `Boolean` scalar type represents `true` or `false`." +scalar Boolean + +"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http:\/\/en.wikipedia.org\/wiki\/IEEE_floating_point)." +scalar Float + +"The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." +scalar ID + +"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." +scalar Int + +scalar PaginationAmount + +"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." +scalar String diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_Builder.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_Builder.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_Builder.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderOptions.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderOptions.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpGet_BuilderOptions.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_Builder.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_Builder.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_Builder.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderOptions.snap b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderOptions.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/ApplicationBuilderTests.UseGraphQLHttpPost_BuilderOptions.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap b/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap new file mode 100644 index 00000000000..182b6fb2b77 --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_2.snap @@ -0,0 +1,9 @@ +{ + "Data": { + "hero": { + "name": "R2-D2" + } + }, + "Errors": null, + "Extensions": null +} diff --git a/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap b/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap new file mode 100644 index 00000000000..2567876533c --- /dev/null +++ b/src/Server/AspNetCore.Tests/__snapshots__/PostMiddlewareTests.HttpPost_Json_CachedQuery_NotFound.snap @@ -0,0 +1,12 @@ +{ + "Data": null, + "Errors": [ + { + "message": "persistedQueryNotFound", + "extensions": { + "code": "CACHED_QUERY_NOT_FOUND" + } + } + ], + "Extensions": null +} diff --git a/src/Server/AspNetCore.Voyager/AspNetCore.Voyager.csproj b/src/Server/AspNetCore.Voyager/AspNetCore.Voyager.csproj index 7bc6afcc383..c60f9cf280e 100644 --- a/src/Server/AspNetCore.Voyager/AspNetCore.Voyager.csproj +++ b/src/Server/AspNetCore.Voyager/AspNetCore.Voyager.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore.Voyager HotChocolate.AspNetCore.Voyager HotChocolate.AspNetCore.Voyager - Contains a GraphQL Voyager for ASP.net core that can be used with the Hot Chocolate GraphQL server. + Contains a GraphQL Voyager for ASP .Net core that can be used with the Hot Chocolate GraphQL server. diff --git a/src/Server/AspNetCore/AspNetCore.csproj b/src/Server/AspNetCore/AspNetCore.csproj index 8088f7b66e7..60bdeca54ee 100644 --- a/src/Server/AspNetCore/AspNetCore.csproj +++ b/src/Server/AspNetCore/AspNetCore.csproj @@ -5,7 +5,7 @@ HotChocolate.AspNetCore HotChocolate.AspNetCore HotChocolate.AspNetCore - Contains the Hot Chocolate GraphQL middleware for ASP.net core. + Contains the Hot Chocolate GraphQL middleware for ASP .Net core. @@ -33,6 +33,9 @@ + + + diff --git a/src/Server/AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/Server/AspNetCore/Extensions/ApplicationBuilderExtensions.cs index e3b6863177e..58cd4822c9d 100644 --- a/src/Server/AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Server/AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -42,68 +42,25 @@ public static IApplicationBuilder UseGraphQL( } return applicationBuilder - .UseGraphQLHttpGet(options) - .UseGraphQLHttpPost(options) - .UseGraphQLSubscriptions(new SubscriptionMiddlewareOptions + .UseGraphQLHttpPost(new HttpPostMiddlewareOptions { + Path = options.Path, ParserOptions = options.ParserOptions, - SubscriptionPath = options.SubscriptionPath + MaxRequestSize = options.MaxRequestSize }) - .UseGraphQLHttpGetSchema(options); - } - - public static IApplicationBuilder UseGraphQLHttpGet( - this IApplicationBuilder applicationBuilder, - QueryMiddlewareOptions options) - { - if (applicationBuilder == null) - { - throw new ArgumentNullException(nameof(applicationBuilder)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - return applicationBuilder - .UseMiddleware(options); - } - - public static IApplicationBuilder UseGraphQLHttpPost( - this IApplicationBuilder applicationBuilder, - QueryMiddlewareOptions options) - { - if (applicationBuilder == null) - { - throw new ArgumentNullException(nameof(applicationBuilder)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - return applicationBuilder - .UseMiddleware(options); - } - - public static IApplicationBuilder UseGraphQLHttpGetSchema( - this IApplicationBuilder applicationBuilder, - QueryMiddlewareOptions options) - { - if (applicationBuilder == null) - { - throw new ArgumentNullException(nameof(applicationBuilder)); - } - - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - return applicationBuilder - .UseMiddleware(options); + .UseGraphQLHttpGet(new HttpGetMiddlewareOptions + { + Path = options.Path + }) + .UseGraphQLHttpGetSchema(new HttpGetSchemaMiddlewareOptions + { + Path = options.Path.Add(new PathString("/schema")) + }) + .UseGraphQLSubscriptions(new SubscriptionMiddlewareOptions + { + ParserOptions = options.ParserOptions, + Path = options.SubscriptionPath + }); } } } diff --git a/src/Server/AspNetCore/InternalsVisibleTo.cs b/src/Server/AspNetCore/InternalsVisibleTo.cs deleted file mode 100644 index 1f5546d37b1..00000000000 --- a/src/Server/AspNetCore/InternalsVisibleTo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("HotChocolate.AspNetClassic.Tests")] -[assembly: InternalsVisibleTo("HotChocolate.AspNetCore.Tests")] diff --git a/src/Server/Server.sln b/src/Server/Server.sln index 569d6945a70..89e655f51c9 100644 --- a/src/Server/Server.sln +++ b/src/Server/Server.sln @@ -65,6 +65,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StarWars", "..\Core\StarWar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.Abstractions", "AspNetClassic.Abstractions\AspNetClassic.Abstractions.csproj", "{B930D413-E013-4DE6-B1AB-C88BE946E615}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpGet", "AspNetClassic.HttpGet\AspNetClassic.HttpGet.csproj", "{24990C47-B073-40D5-AE1C-A9740EE35845}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpGetSchema", "AspNetClassic.HttpGetSchema\AspNetClassic.HttpGetSchema.csproj", "{05815423-DF06-4959-B5B1-63962F883836}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpPost", "AspNetClassic.HttpPost\AspNetClassic.HttpPost.csproj", "{4B7871E6-63CA-4472-AB88-B1DD6BD99A3B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpGet", "AspNetCore.HttpGet\AspNetCore.HttpGet.csproj", "{AF1587CB-958E-4758-9B80-4DE357EF146A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpGetSchema", "AspNetCore.HttpGetSchema\AspNetCore.HttpGetSchema.csproj", "{155D7C34-3B27-4C35-8436-E5136E7326AF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpPost", "AspNetCore.HttpPost\AspNetCore.HttpPost.csproj", "{D072B67B-348C-4AB1-893F-FBD456FDFE2C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -191,6 +203,30 @@ Global {B930D413-E013-4DE6-B1AB-C88BE946E615}.Debug|Any CPU.Build.0 = Debug|Any CPU {B930D413-E013-4DE6-B1AB-C88BE946E615}.Release|Any CPU.ActiveCfg = Release|Any CPU {B930D413-E013-4DE6-B1AB-C88BE946E615}.Release|Any CPU.Build.0 = Release|Any CPU + {24990C47-B073-40D5-AE1C-A9740EE35845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24990C47-B073-40D5-AE1C-A9740EE35845}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24990C47-B073-40D5-AE1C-A9740EE35845}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24990C47-B073-40D5-AE1C-A9740EE35845}.Release|Any CPU.Build.0 = Release|Any CPU + {05815423-DF06-4959-B5B1-63962F883836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05815423-DF06-4959-B5B1-63962F883836}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05815423-DF06-4959-B5B1-63962F883836}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05815423-DF06-4959-B5B1-63962F883836}.Release|Any CPU.Build.0 = Release|Any CPU + {4B7871E6-63CA-4472-AB88-B1DD6BD99A3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B7871E6-63CA-4472-AB88-B1DD6BD99A3B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B7871E6-63CA-4472-AB88-B1DD6BD99A3B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B7871E6-63CA-4472-AB88-B1DD6BD99A3B}.Release|Any CPU.Build.0 = Release|Any CPU + {AF1587CB-958E-4758-9B80-4DE357EF146A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF1587CB-958E-4758-9B80-4DE357EF146A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF1587CB-958E-4758-9B80-4DE357EF146A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF1587CB-958E-4758-9B80-4DE357EF146A}.Release|Any CPU.Build.0 = Release|Any CPU + {155D7C34-3B27-4C35-8436-E5136E7326AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {155D7C34-3B27-4C35-8436-E5136E7326AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {155D7C34-3B27-4C35-8436-E5136E7326AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {155D7C34-3B27-4C35-8436-E5136E7326AF}.Release|Any CPU.Build.0 = Release|Any CPU + {D072B67B-348C-4AB1-893F-FBD456FDFE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D072B67B-348C-4AB1-893F-FBD456FDFE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D072B67B-348C-4AB1-893F-FBD456FDFE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D072B67B-348C-4AB1-893F-FBD456FDFE2C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Server/Server/ContentType.cs b/src/Server/Server/ContentType.cs index 755db57bbf4..a175253c44e 100644 --- a/src/Server/Server/ContentType.cs +++ b/src/Server/Server/ContentType.cs @@ -1,9 +1,58 @@ -namespace HotChocolate.Server +using System; + +namespace HotChocolate.Server { public static class ContentType { + private static readonly char[] _graphQLChars = new char[] + { + 'a', + 'p', + 'p', + 'l', + 'i', + 'c', + 'a', + 't', + 'i', + 'o', + 'n', + '/', + 'g', + 'r', + 'a', + 'p', + 'h', + 'q', + 'l' + }; + + private static readonly char[] _jsonChars = new char[] + { + 'a', + 'p', + 'p', + 'l', + 'i', + 'c', + 'a', + 't', + 'i', + 'o', + 'n', + '/', + 'j', + 's', + 'o', + 'n' + }; + public const string GraphQL = "application/graphql"; public const string Json = "application/json"; + + public static ReadOnlySpan GraphQLSpan() => _graphQLChars; + + public static ReadOnlySpan JsonSpan() => _jsonChars; } } diff --git a/tools/Build.Core.sln b/tools/Build.Core.sln index d7cdb46bba2..ffffdcfcad5 100644 --- a/tools/Build.Core.sln +++ b/tools/Build.Core.sln @@ -61,15 +61,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "..\src\Server\Ser EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.Subscriptions", "..\src\Server\AspNetCore.Subscriptions\AspNetCore.Subscriptions.csproj", "{03013EE5-2C7A-4235-851C-539B27BE8CD5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Subscriptions.Tests", "..\src\Server\AspNetCore.Subscriptions.Tests\AspNetCore.Subscriptions.Tests.csproj", "{A69D70D4-ABF5-4D64-B0BB-32973035AD83}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.Subscriptions.Tests", "..\src\Server\AspNetCore.Subscriptions.Tests\AspNetCore.Subscriptions.Tests.csproj", "{A69D70D4-ABF5-4D64-B0BB-32973035AD83}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Abstractions", "..\src\Server\AspNetCore.Abstractions\AspNetCore.Abstractions.csproj", "{778CBCDD-C1E4-4651-9D1C-FCF1F8EC671D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.Abstractions", "..\src\Server\AspNetCore.Abstractions\AspNetCore.Abstractions.csproj", "{778CBCDD-C1E4-4651-9D1C-FCF1F8EC671D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Tests.Utilities", "..\src\Server\AspNetCore.Tests.Utilities\AspNetCore.Tests.Utilities.csproj", "{8B5D52A2-CCB0-4E6C-95DA-FB9CEAD717BF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.Tests.Utilities", "..\src\Server\AspNetCore.Tests.Utilities\AspNetCore.Tests.Utilities.csproj", "{8B5D52A2-CCB0-4E6C-95DA-FB9CEAD717BF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StarWars", "..\src\Core\StarWars\StarWars.csproj", "{720A44F6-5633-49D1-AEF2-16F1635B83A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StarWars", "..\src\Core\StarWars\StarWars.csproj", "{720A44F6-5633-49D1-AEF2-16F1635B83A4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subscriptions.Redis", "..\src\Core\Subscriptions.Redis\Subscriptions.Redis.csproj", "{E6554113-C3B0-4BE9-AE4B-CB7F3F082C9C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Subscriptions.Redis", "..\src\Core\Subscriptions.Redis\Subscriptions.Redis.csproj", "{E6554113-C3B0-4BE9-AE4B-CB7F3F082C9C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.HttpGetSchema", "..\src\Server\AspNetCore.HttpGetSchema\AspNetCore.HttpGetSchema.csproj", "{DC74E89D-E498-46AB-ACE0-3445831F937E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.HttpGet", "..\src\Server\AspNetCore.HttpGet\AspNetCore.HttpGet.csproj", "{4C9626D1-19C8-4611-B5C7-380BAB3B686C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.HttpPost", "..\src\Server\AspNetCore.HttpPost\AspNetCore.HttpPost.csproj", "{CBD7536C-543D-4E10-8FB5-196895FC761B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -489,6 +495,42 @@ Global {E6554113-C3B0-4BE9-AE4B-CB7F3F082C9C}.Release|x64.Build.0 = Release|Any CPU {E6554113-C3B0-4BE9-AE4B-CB7F3F082C9C}.Release|x86.ActiveCfg = Release|Any CPU {E6554113-C3B0-4BE9-AE4B-CB7F3F082C9C}.Release|x86.Build.0 = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|x64.Build.0 = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Debug|x86.Build.0 = Debug|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|Any CPU.Build.0 = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|x64.ActiveCfg = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|x64.Build.0 = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|x86.ActiveCfg = Release|Any CPU + {DC74E89D-E498-46AB-ACE0-3445831F937E}.Release|x86.Build.0 = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|x64.Build.0 = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Debug|x86.Build.0 = Debug|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|Any CPU.Build.0 = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|x64.ActiveCfg = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|x64.Build.0 = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|x86.ActiveCfg = Release|Any CPU + {4C9626D1-19C8-4611-B5C7-380BAB3B686C}.Release|x86.Build.0 = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|x64.Build.0 = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|x86.ActiveCfg = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Debug|x86.Build.0 = Debug|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|Any CPU.Build.0 = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|x64.ActiveCfg = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|x64.Build.0 = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|x86.ActiveCfg = Release|Any CPU + {CBD7536C-543D-4E10-8FB5-196895FC761B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tools/Build.sln b/tools/Build.sln index b43baeedaa8..32ca4be0e39 100644 --- a/tools/Build.sln +++ b/tools/Build.sln @@ -89,6 +89,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.Abstractions" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subscriptions.Redis", "..\src\Core\Subscriptions.Redis\Subscriptions.Redis.csproj", "{48D7658F-ECD5-4D13-88F2-2E394E8BFF9D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpGetSchema", "..\src\Server\AspNetCore.HttpGetSchema\AspNetCore.HttpGetSchema.csproj", "{C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpGet", "..\src\Server\AspNetClassic.HttpGet\AspNetClassic.HttpGet.csproj", "{19548E97-1C1F-4C15-A87E-7B428A719060}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpGetSchema", "..\src\Server\AspNetClassic.HttpGetSchema\AspNetClassic.HttpGetSchema.csproj", "{6D7179B8-8F09-47D3-82C4-98E0769DC26B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetClassic.HttpPost", "..\src\Server\AspNetClassic.HttpPost\AspNetClassic.HttpPost.csproj", "{4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpGet", "..\src\Server\AspNetCore.HttpGet\AspNetCore.HttpGet.csproj", "{594F453D-1AF3-4E7A-B554-09B3E9546437}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.HttpPost", "..\src\Server\AspNetCore.HttpPost\AspNetCore.HttpPost.csproj", "{DBADC16A-413E-4AD7-9AF5-75295752EA1C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -615,6 +627,78 @@ Global {48D7658F-ECD5-4D13-88F2-2E394E8BFF9D}.Release|x64.Build.0 = Release|Any CPU {48D7658F-ECD5-4D13-88F2-2E394E8BFF9D}.Release|x86.ActiveCfg = Release|Any CPU {48D7658F-ECD5-4D13-88F2-2E394E8BFF9D}.Release|x86.Build.0 = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|x64.ActiveCfg = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|x64.Build.0 = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|x86.ActiveCfg = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Debug|x86.Build.0 = Debug|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|Any CPU.Build.0 = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|x64.ActiveCfg = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|x64.Build.0 = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|x86.ActiveCfg = Release|Any CPU + {C860EF23-7BA0-4DB5-89C7-F51398AC8B5A}.Release|x86.Build.0 = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|x64.ActiveCfg = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|x64.Build.0 = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|x86.ActiveCfg = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Debug|x86.Build.0 = Debug|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|Any CPU.Build.0 = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|x64.ActiveCfg = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|x64.Build.0 = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|x86.ActiveCfg = Release|Any CPU + {19548E97-1C1F-4C15-A87E-7B428A719060}.Release|x86.Build.0 = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|x64.ActiveCfg = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|x64.Build.0 = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|x86.ActiveCfg = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Debug|x86.Build.0 = Debug|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|Any CPU.Build.0 = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|x64.ActiveCfg = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|x64.Build.0 = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|x86.ActiveCfg = Release|Any CPU + {6D7179B8-8F09-47D3-82C4-98E0769DC26B}.Release|x86.Build.0 = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|x64.Build.0 = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Debug|x86.Build.0 = Debug|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|Any CPU.Build.0 = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|x64.ActiveCfg = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|x64.Build.0 = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|x86.ActiveCfg = Release|Any CPU + {4F2FD7D7-F1F7-4732-B7E1-390C056E1F1F}.Release|x86.Build.0 = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|Any CPU.Build.0 = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|x64.ActiveCfg = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|x64.Build.0 = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|x86.ActiveCfg = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Debug|x86.Build.0 = Debug|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|Any CPU.ActiveCfg = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|Any CPU.Build.0 = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|x64.ActiveCfg = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|x64.Build.0 = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|x86.ActiveCfg = Release|Any CPU + {594F453D-1AF3-4E7A-B554-09B3E9546437}.Release|x86.Build.0 = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|x64.Build.0 = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Debug|x86.Build.0 = Debug|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|Any CPU.Build.0 = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|x64.ActiveCfg = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|x64.Build.0 = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|x86.ActiveCfg = Release|Any CPU + {DBADC16A-413E-4AD7-9AF5-75295752EA1C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE