From 1702a982373490d89287fdb57bea9e6d72ec69d9 Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Thu, 30 May 2024 21:32:48 +0100 Subject: [PATCH 1/8] Implemented snapshot testing with Verify --- Directory.Packages.props | 3 +- ...shbuckle.AspNetCore.SwaggerGen.Test.csproj | 1 + ...riptionsWithMatchingGroupName.verified.txt | 45 ++++ .../VarifyTests/VarifyTests.cs | 192 ++++++++++++++++++ 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index b2c9b4f9f0..713a38c156 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -27,8 +27,9 @@ + - + \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj index e47f4275ef..950eefb2fa 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj @@ -17,6 +17,7 @@ + diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt new file mode 100644 index 0000000000..73d6704137 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt @@ -0,0 +1,45 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Get: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + }, + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: 0F1036F23326E2BD7543491DEC0E03ABCA5BC97AF845BEE30C164155D616F306F6F6E21A77507DA6BE2A85DF1A17B1F07AE23E7608E37C971BAF1CBA2491E899 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs new file mode 100644 index 0000000000..d36478bb39 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs @@ -0,0 +1,192 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Routing; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.Swagger; +using Swashbuckle.AspNetCore.TestSupport; +using VerifyXunit; +using Xunit; + +namespace Swashbuckle.AspNetCore.SwaggerGen.Test +{ + public class VarifyTests + { + [Fact] + public Task GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), + + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), + }, + options: new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary + { + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } + } + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithRouteNameMetadata() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithEndpointNameMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor + { + EndpointMetadata = new List() { new EndpointNameMetadata("SomeEndpointName") }, + RouteValues = new Dictionary + { + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithProvidedOpenApiMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor + { + EndpointMetadata = new List() + { + new OpenApiOperation + { + OperationId = "OperationIdSetInMetadata", + Parameters = new List() + { + new OpenApiParameter + { + Name = "ParameterInMetadata" + } + } + } + }, + RouteValues = new Dictionary + { + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Theory] + [InlineData(nameof(FakeController.ActionWithAcceptFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithContentTypeFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithAuthorizationFromHeaderParameter))] + public void GetSwagger_GeneratesSwaggerDocument_ForActionsWithIllegalHeaderParameters(string action) + { + var illegalParameter = typeof(FakeController).GetMethod(action).GetParameters()[0]; + var fromHeaderAttribute = illegalParameter.GetCustomAttribute(); + + var subject = Subject( + new[] + { + ApiDescriptionFactory.Create( + c => action, + groupName: "v1", + httpMethod: "GET", + relativePath: "resource", + parameterDescriptions: new[] + { + new ApiParameterDescription + { + Name = fromHeaderAttribute?.Name ?? illegalParameter.Name, + Source = BindingSource.Header, + ModelMetadata = ModelMetadataFactory.CreateForParameter(illegalParameter) + }, + new ApiParameterDescription + { + Name = "param", + Source = BindingSource.Header + } + } + ) + } + ); + + var document = subject.GetSwagger("v1"); + + var operation = document.Paths["/resource"].Operations[OperationType.Get]; + var parameter = Assert.Single(operation.Parameters); + Assert.Equal("param", parameter.Name); + } + + private static SwaggerGenerator Subject( + IEnumerable apiDescriptions, + SwaggerGeneratorOptions options = null, + IEnumerable authenticationSchemes = null) + { + return new SwaggerGenerator( + options ?? DefaultOptions, + new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), + new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), + new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) + ); + } + + private static readonly SwaggerGeneratorOptions DefaultOptions = new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary + { + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } + } + }; + } +} From a6bd5f2b005fcb2bdf84bb00c7e87ee72e2aebba Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 15:39:07 +0100 Subject: [PATCH 2/8] Implemented snapshot testing with Verify --- .gitignore | 1 + ...shbuckle.AspNetCore.SwaggerGen.Test.csproj | 6 + ...riptionsWithMatchingGroupName.verified.txt | 45 ---- .../VarifyTests/VarifyTests.cs | 192 ------------------ 4 files changed, 7 insertions(+), 237 deletions(-) delete mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt delete mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs diff --git a/.gitignore b/.gitignore index 6709dcea82..c12adce325 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ test/WebSites/CliExample/wwwroot/api-docs/v1/*.json test/WebSites/CliExampleWithFactory/wwwroot/api-docs/v1/*.json test/WebSites/NswagClientExample/NSwagClient/ *ncrunch* +*.received.* diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj index 950eefb2fa..ea6ba3ada4 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj @@ -22,4 +22,10 @@ + + + SwaggerGeneratorVerifyTests.cs + + + diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt deleted file mode 100644 index 73d6704137..0000000000 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName.verified.txt +++ /dev/null @@ -1,45 +0,0 @@ -{ - Info: { - Title: Test API, - Version: V1 - }, - Paths: { - /resource: { - Operations: { - Get: { - Tags: [ - { - Name: Fake, - UnresolvedReference: false - } - ], - Responses: { - 200: { - Description: OK, - UnresolvedReference: false - } - }, - Deprecated: false - }, - Post: { - Tags: [ - { - Name: Fake, - UnresolvedReference: false - } - ], - Responses: { - 200: { - Description: OK, - UnresolvedReference: false - } - }, - Deprecated: false - } - }, - UnresolvedReference: false - } - }, - Components: {}, - HashCode: 0F1036F23326E2BD7543491DEC0E03ABCA5BC97AF845BEE30C164155D616F306F6F6E21A77507DA6BE2A85DF1A17B1F07AE23E7608E37C971BAF1CBA2491E899 -} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs deleted file mode 100644 index d36478bb39..0000000000 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VarifyTests/VarifyTests.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text.Json; -using System.Threading.Tasks; - -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Abstractions; -using Microsoft.AspNetCore.Mvc.ApiExplorer; -using Microsoft.AspNetCore.Mvc.ModelBinding; -using Microsoft.AspNetCore.Routing; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.Swagger; -using Swashbuckle.AspNetCore.TestSupport; -using VerifyXunit; -using Xunit; - -namespace Swashbuckle.AspNetCore.SwaggerGen.Test -{ - public class VarifyTests - { - [Fact] - public Task GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGroupName() - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"), - - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), - - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), - }, - options: new SwaggerGeneratorOptions - { - SwaggerDocs = new Dictionary - { - ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } - } - } - ); - - var document = subject.GetSwagger("v1"); - - return Verifier.Verify(document); - } - - [Fact] - public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithRouteNameMetadata() - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); - - var document = subject.GetSwagger("v1"); - - return Verifier.Verify(document); - } - - [Fact] - public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithEndpointNameMetadata() - { - var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); - var actionDescriptor = new ActionDescriptor - { - EndpointMetadata = new List() { new EndpointNameMetadata("SomeEndpointName") }, - RouteValues = new Dictionary - { - ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) - } - }; - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); - - var document = subject.GetSwagger("v1"); - - return Verifier.Verify(document); - } - - [Fact] - public Task GetSwagger_GeneratesSwaggerDocument_ForActionWithProvidedOpenApiMetadata() - { - var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); - var actionDescriptor = new ActionDescriptor - { - EndpointMetadata = new List() - { - new OpenApiOperation - { - OperationId = "OperationIdSetInMetadata", - Parameters = new List() - { - new OpenApiParameter - { - Name = "ParameterInMetadata" - } - } - } - }, - RouteValues = new Dictionary - { - ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) - } - }; - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); - - var document = subject.GetSwagger("v1"); - - return Verifier.Verify(document); - } - - [Theory] - [InlineData(nameof(FakeController.ActionWithAcceptFromHeaderParameter))] - [InlineData(nameof(FakeController.ActionWithContentTypeFromHeaderParameter))] - [InlineData(nameof(FakeController.ActionWithAuthorizationFromHeaderParameter))] - public void GetSwagger_GeneratesSwaggerDocument_ForActionsWithIllegalHeaderParameters(string action) - { - var illegalParameter = typeof(FakeController).GetMethod(action).GetParameters()[0]; - var fromHeaderAttribute = illegalParameter.GetCustomAttribute(); - - var subject = Subject( - new[] - { - ApiDescriptionFactory.Create( - c => action, - groupName: "v1", - httpMethod: "GET", - relativePath: "resource", - parameterDescriptions: new[] - { - new ApiParameterDescription - { - Name = fromHeaderAttribute?.Name ?? illegalParameter.Name, - Source = BindingSource.Header, - ModelMetadata = ModelMetadataFactory.CreateForParameter(illegalParameter) - }, - new ApiParameterDescription - { - Name = "param", - Source = BindingSource.Header - } - } - ) - } - ); - - var document = subject.GetSwagger("v1"); - - var operation = document.Paths["/resource"].Operations[OperationType.Get]; - var parameter = Assert.Single(operation.Parameters); - Assert.Equal("param", parameter.Name); - } - - private static SwaggerGenerator Subject( - IEnumerable apiDescriptions, - SwaggerGeneratorOptions options = null, - IEnumerable authenticationSchemes = null) - { - return new SwaggerGenerator( - options ?? DefaultOptions, - new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), - new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), - new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) - ); - } - - private static readonly SwaggerGeneratorOptions DefaultOptions = new SwaggerGeneratorOptions - { - SwaggerDocs = new Dictionary - { - ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } - } - }; - } -} From c36af914d238dac31324f1282b55fb8cf682790a Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 16:15:03 +0100 Subject: [PATCH 3/8] Implemented snapshot testing with Verify --- .editorconfig | 10 + .gitattributes | 3 + ...ctionWithEndpointNameMetadata.verified.txt | 31 +++ ...onWithProvidedOpenApiMetadata.verified.txt | 31 +++ ...ests.ActionWithRequiredMember.verified.txt | 52 ++++ ...eterWithBindRequiredAttribute.verified.txt | 52 ++++ ...arameterWithRequiredAttribute.verified.txt | 52 ++++ ...s.ActionWithRouteNameMetadata.verified.txt | 31 +++ ...WithAcceptFromHeaderParameter.verified.txt | 52 ++++ ...horizationFromHeaderParameter.verified.txt | 52 ++++ ...ontentTypeFromHeaderParameter.verified.txt | 52 ++++ ...riptionsWithMatchingGroupName.verified.txt | 45 ++++ .../SwaggerGeneratorVerifyTests.cs | 252 ++++++++++++++++++ 13 files changed, 715 insertions(+) create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt create mode 100644 test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs diff --git a/.editorconfig b/.editorconfig index fd54f541b9..92b978a85c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,3 +31,13 @@ trim_trailing_whitespace = true [*.cs] dotnet_sort_system_directives_first = true + +# Verify settings +[*.{received,verified}.{txt,xml,json}] +charset = "utf-8-bom" +end_of_line = lf +indent_size = unset +indent_style = unset +insert_final_newline = false +tab_width = unset +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index e3eb50d710..644430043e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,5 @@ # Set the default end-of-line to UNIX * text=auto eol=lf +*.verified.txt text eol=lf working-tree-encoding=UTF-8 +*.verified.xml text eol=lf working-tree-encoding=UTF-8 +*.verified.json text eol=lf working-tree-encoding=UTF-8 \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt new file mode 100644 index 0000000000..aaaed8c375 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithEndpointNameMetadata.verified.txt @@ -0,0 +1,31 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + OperationId: SomeEndpointName, + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: A0047BEEDFB7C084AF6BF3412F47917E1914849406956B23249FD5A555B9545157FBFF5C1EAFC073B55E59FDE9BDB1774670EFE402C7319D5EC6A6A43D94E439 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt new file mode 100644 index 0000000000..facec5635b --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithProvidedOpenApiMetadata.verified.txt @@ -0,0 +1,31 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + OperationId: OperationIdSetInMetadata, + Parameters: [ + { + UnresolvedReference: false, + Name: ParameterInMetadata, + Required: false, + Deprecated: false, + AllowEmptyValue: false, + Style: Simple, + Explode: false, + AllowReserved: false + } + ], + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: 76DE54DD44D94D07BC803E615ECB0F6D290C3B8803EFB5EADF02C6B180682B1C20BFDD4C9CD50F71D5AD7042B7B4570903F3AF1CC7970ABCA1CEE20FBF971FFD +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt new file mode 100644 index 0000000000..f8133b12f1 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredMember.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Query, + Required: true, + Deprecated: false, + AllowEmptyValue: false, + Style: Form, + Explode: true, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt new file mode 100644 index 0000000000..f8133b12f1 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithBindRequiredAttribute.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Query, + Required: true, + Deprecated: false, + AllowEmptyValue: false, + Style: Form, + Explode: true, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt new file mode 100644 index 0000000000..f8133b12f1 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRequiredParameter_action=ActionWithParameterWithRequiredAttribute.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Query, + Required: true, + Deprecated: false, + AllowEmptyValue: false, + Style: Form, + Explode: true, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: A2DDB9D84BC2303C2E8B82FEE969073D4DCAE3D40331C1ED8376E3F427E46C7CAE5AE2791BC5FE1FFFE026EBE90FC10DE8A0409D9F0B6EBC5DBE6CB294DD6A84 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt new file mode 100644 index 0000000000..9c7d1af46d --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionWithRouteNameMetadata.verified.txt @@ -0,0 +1,31 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + OperationId: SomeRouteName, + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: 8A51577C0837548151E3938DC7033AF6AFDE7FD4E5F6F2FE20CC8931B3D18A883C1FB3FE92120D0A44EC31DDE90DDEDE4A237B3138AD45A37278F8924958D5A7 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt new file mode 100644 index 0000000000..49c8aec81d --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAcceptFromHeaderParameter.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Get: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Header, + Required: false, + Deprecated: false, + AllowEmptyValue: false, + Style: Simple, + Explode: false, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt new file mode 100644 index 0000000000..49c8aec81d --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithAuthorizationFromHeaderParameter.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Get: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Header, + Required: false, + Deprecated: false, + AllowEmptyValue: false, + Style: Simple, + Explode: false, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt new file mode 100644 index 0000000000..49c8aec81d --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ActionsWithIllegalHeaderParameters_action=ActionWithContentTypeFromHeaderParameter.verified.txt @@ -0,0 +1,52 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Get: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Parameters: [ + { + UnresolvedReference: false, + Name: param, + In: Header, + Required: false, + Deprecated: false, + AllowEmptyValue: false, + Style: Simple, + Explode: false, + AllowReserved: false, + Schema: { + Type: string, + ReadOnly: false, + WriteOnly: false, + AdditionalPropertiesAllowed: true, + Nullable: false, + Deprecated: false, + UnresolvedReference: false + } + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: E126911C7FB97665966DB7EA833EA70FDF82A779304ECD9B963D5A50C6E0AE51A3180983631720BDCD1BCDA3CAA7E79F0F0042120949EA990884D6188CE77AF1 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt new file mode 100644 index 0000000000..73d6704137 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt @@ -0,0 +1,45 @@ +{ + Info: { + Title: Test API, + Version: V1 + }, + Paths: { + /resource: { + Operations: { + Get: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + }, + Post: { + Tags: [ + { + Name: Fake, + UnresolvedReference: false + } + ], + Responses: { + 200: { + Description: OK, + UnresolvedReference: false + } + }, + Deprecated: false + } + }, + UnresolvedReference: false + } + }, + Components: {}, + HashCode: 0F1036F23326E2BD7543491DEC0E03ABCA5BC97AF845BEE30C164155D616F306F6F6E21A77507DA6BE2A85DF1A17B1F07AE23E7608E37C971BAF1CBA2491E899 +} \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs new file mode 100644 index 0000000000..e13240e3a8 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Routing; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.Swagger; +using Swashbuckle.AspNetCore.TestSupport; +using VerifyTests; + +using VerifyXunit; +using Xunit; + +namespace Swashbuckle.AspNetCore.SwaggerGen.Test +{ + public class SwaggerGeneratorVerifyTests + { + [Fact] + public Task ApiDescriptionsWithMatchingGroupName() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), + + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), + }, + options: new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary + { + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } + } + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task ActionWithRouteNameMetadata() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task ActionWithEndpointNameMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor + { + EndpointMetadata = new List() { new EndpointNameMetadata("SomeEndpointName") }, + RouteValues = new Dictionary + { + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Fact] + public Task ActionWithProvidedOpenApiMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor + { + EndpointMetadata = new List() + { + new OpenApiOperation + { + OperationId = "OperationIdSetInMetadata", + Parameters = new List() + { + new OpenApiParameter + { + Name = "ParameterInMetadata" + } + } + } + }, + RouteValues = new Dictionary + { + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } + + [Theory] + [InlineData(nameof(FakeController.ActionWithAcceptFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithContentTypeFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithAuthorizationFromHeaderParameter))] + public Task ActionsWithIllegalHeaderParameters(string action) + { + var illegalParameter = typeof(FakeController).GetMethod(action).GetParameters()[0]; + var fromHeaderAttribute = illegalParameter.GetCustomAttribute(); + + var subject = Subject( + new[] + { + ApiDescriptionFactory.Create( + c => action, + groupName: "v1", + httpMethod: "GET", + relativePath: "resource", + parameterDescriptions: new[] + { + new ApiParameterDescription + { + Name = fromHeaderAttribute?.Name ?? illegalParameter.Name, + Source = BindingSource.Header, + ModelMetadata = ModelMetadataFactory.CreateForParameter(illegalParameter) + }, + new ApiParameterDescription + { + Name = "param", + Source = BindingSource.Header + } + } + ) + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document).UseParameters(action); + } + + [Theory] + [InlineData(nameof(FakeController.ActionWithParameterWithRequiredAttribute))] + [InlineData(nameof(FakeController.ActionWithParameterWithBindRequiredAttribute))] + public Task ActionWithRequiredParameter(string action) + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + methodInfo: typeof(FakeController).GetMethod(action), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: new [] + { + new ApiParameterDescription + { + Name = "param", + Source = BindingSource.Query + } + }) + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document).UseParameters(action); + } + +#if NET7_0_OR_GREATER + [Fact] + public Task ActionWithRequiredMember() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + methodInfo: typeof(FakeController).GetMethod(nameof(FakeController.ActionWithRequiredMember)), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: new [] + { + new ApiParameterDescription + { + Name = "param", + Source = BindingSource.Query, + ModelMetadata = ModelMetadataFactory.CreateForProperty(typeof(FakeController.TypeWithRequiredProperty), "RequiredProperty") + } + }) + } + ); + + var document = subject.GetSwagger("v1"); + + return Verifier.Verify(document); + } +#endif + + private static SwaggerGenerator Subject( + IEnumerable apiDescriptions, + SwaggerGeneratorOptions options = null, + IEnumerable authenticationSchemes = null) + { + return new SwaggerGenerator( + options ?? DefaultOptions, + new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), + new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), + new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) + ); + } + + private static readonly SwaggerGeneratorOptions DefaultOptions = new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary + { + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } + } + }; + } +} From d21056b636cfc211df0253b3e1f4b985af2fe453 Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 16:31:00 +0100 Subject: [PATCH 4/8] Cleanup --- .../SwaggerGeneratorVerifyTests.cs | 7 +------ .../Swashbuckle.AspNetCore.SwaggerGen.Test.csproj | 6 ------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs index e13240e3a8..a583bdbe32 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs @@ -1,10 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.Json; using System.Threading.Tasks; - using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; @@ -12,10 +10,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Routing; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.TestSupport; -using VerifyTests; - using VerifyXunit; using Xunit; diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj index ea6ba3ada4..950eefb2fa 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Swashbuckle.AspNetCore.SwaggerGen.Test.csproj @@ -22,10 +22,4 @@ - - - SwaggerGeneratorVerifyTests.cs - - - From e3542bcdef68de1fb9666e642c4cfedb1b4104e4 Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 17:09:00 +0100 Subject: [PATCH 5/8] Code review fixes --- .github/dependabot.yml | 1 + .../SwaggerGeneratorVerifyTests.cs | 367 +++++++++--------- 2 files changed, 184 insertions(+), 184 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b85290bd95..63b350d798 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -33,6 +33,7 @@ updates: xunit: patterns: - xunit* + - Verify.Xunit* schedule: interval: weekly day: wednesday diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs index a583bdbe32..891f3cd308 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.cs @@ -14,234 +14,233 @@ using VerifyXunit; using Xunit; -namespace Swashbuckle.AspNetCore.SwaggerGen.Test +namespace Swashbuckle.AspNetCore.SwaggerGen.Test; + +public class SwaggerGeneratorVerifyTests { - public class SwaggerGeneratorVerifyTests + [Fact] + public Task ApiDescriptionsWithMatchingGroupName() { - [Fact] - public Task ApiDescriptionsWithMatchingGroupName() - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "POST", relativePath: "resource"), - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), - }, - options: new SwaggerGeneratorOptions + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), + }, + options: new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary { - SwaggerDocs = new Dictionary - { - ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } - } + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } } - ); + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document); - } + return Verifier.Verify(document); + } - [Fact] - public Task ActionWithRouteNameMetadata() - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); + [Fact] + public Task ActionWithRouteNameMetadata() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithRouteNameMetadata), groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document); - } + return Verifier.Verify(document); + } - [Fact] - public Task ActionWithEndpointNameMetadata() + [Fact] + public Task ActionWithEndpointNameMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor { - var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); - var actionDescriptor = new ActionDescriptor + EndpointMetadata = new List() { new EndpointNameMetadata("SomeEndpointName") }, + RouteValues = new Dictionary { - EndpointMetadata = new List() { new EndpointNameMetadata("SomeEndpointName") }, - RouteValues = new Dictionary - { - ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) - } - }; - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document); - } + return Verifier.Verify(document); + } - [Fact] - public Task ActionWithProvidedOpenApiMetadata() + [Fact] + public Task ActionWithProvidedOpenApiMetadata() + { + var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); + var actionDescriptor = new ActionDescriptor { - var methodInfo = typeof(FakeController).GetMethod(nameof(FakeController.ActionWithParameter)); - var actionDescriptor = new ActionDescriptor + EndpointMetadata = new List() { - EndpointMetadata = new List() + new OpenApiOperation { - new OpenApiOperation + OperationId = "OperationIdSetInMetadata", + Parameters = new List() { - OperationId = "OperationIdSetInMetadata", - Parameters = new List() + new OpenApiParameter { - new OpenApiParameter - { - Name = "ParameterInMetadata" - } + Name = "ParameterInMetadata" } } - }, - RouteValues = new Dictionary - { - ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) } - }; - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), - } - ); + }, + RouteValues = new Dictionary + { + ["controller"] = methodInfo.DeclaringType.Name.Replace("Controller", string.Empty) + } + }; + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create(actionDescriptor, methodInfo, groupName: "v1", httpMethod: "POST", relativePath: "resource"), + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document); - } + return Verifier.Verify(document); + } - [Theory] - [InlineData(nameof(FakeController.ActionWithAcceptFromHeaderParameter))] - [InlineData(nameof(FakeController.ActionWithContentTypeFromHeaderParameter))] - [InlineData(nameof(FakeController.ActionWithAuthorizationFromHeaderParameter))] - public Task ActionsWithIllegalHeaderParameters(string action) - { - var illegalParameter = typeof(FakeController).GetMethod(action).GetParameters()[0]; - var fromHeaderAttribute = illegalParameter.GetCustomAttribute(); + [Theory] + [InlineData(nameof(FakeController.ActionWithAcceptFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithContentTypeFromHeaderParameter))] + [InlineData(nameof(FakeController.ActionWithAuthorizationFromHeaderParameter))] + public Task ActionsWithIllegalHeaderParameters(string action) + { + var illegalParameter = typeof(FakeController).GetMethod(action).GetParameters()[0]; + var fromHeaderAttribute = illegalParameter.GetCustomAttribute(); - var subject = Subject( - new[] - { - ApiDescriptionFactory.Create( - c => action, - groupName: "v1", - httpMethod: "GET", - relativePath: "resource", - parameterDescriptions: new[] + var subject = Subject( + new[] + { + ApiDescriptionFactory.Create( + c => action, + groupName: "v1", + httpMethod: "GET", + relativePath: "resource", + parameterDescriptions: new[] + { + new ApiParameterDescription + { + Name = fromHeaderAttribute?.Name ?? illegalParameter.Name, + Source = BindingSource.Header, + ModelMetadata = ModelMetadataFactory.CreateForParameter(illegalParameter) + }, + new ApiParameterDescription { - new ApiParameterDescription - { - Name = fromHeaderAttribute?.Name ?? illegalParameter.Name, - Source = BindingSource.Header, - ModelMetadata = ModelMetadataFactory.CreateForParameter(illegalParameter) - }, - new ApiParameterDescription - { - Name = "param", - Source = BindingSource.Header - } + Name = "param", + Source = BindingSource.Header } - ) - } - ); + } + ) + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document).UseParameters(action); - } + return Verifier.Verify(document).UseParameters(action); + } - [Theory] - [InlineData(nameof(FakeController.ActionWithParameterWithRequiredAttribute))] - [InlineData(nameof(FakeController.ActionWithParameterWithBindRequiredAttribute))] - public Task ActionWithRequiredParameter(string action) - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - methodInfo: typeof(FakeController).GetMethod(action), - groupName: "v1", - httpMethod: "POST", - relativePath: "resource", - parameterDescriptions: new [] + [Theory] + [InlineData(nameof(FakeController.ActionWithParameterWithRequiredAttribute))] + [InlineData(nameof(FakeController.ActionWithParameterWithBindRequiredAttribute))] + public Task ActionWithRequiredParameter(string action) + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + methodInfo: typeof(FakeController).GetMethod(action), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: new [] + { + new ApiParameterDescription { - new ApiParameterDescription - { - Name = "param", - Source = BindingSource.Query - } - }) - } - ); + Name = "param", + Source = BindingSource.Query + } + }) + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document).UseParameters(action); - } + return Verifier.Verify(document).UseParameters(action); + } #if NET7_0_OR_GREATER - [Fact] - public Task ActionWithRequiredMember() - { - var subject = Subject( - apiDescriptions: new[] - { - ApiDescriptionFactory.Create( - methodInfo: typeof(FakeController).GetMethod(nameof(FakeController.ActionWithRequiredMember)), - groupName: "v1", - httpMethod: "POST", - relativePath: "resource", - parameterDescriptions: new [] + [Fact] + public Task ActionWithRequiredMember() + { + var subject = Subject( + apiDescriptions: new[] + { + ApiDescriptionFactory.Create( + methodInfo: typeof(FakeController).GetMethod(nameof(FakeController.ActionWithRequiredMember)), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: new [] + { + new ApiParameterDescription { - new ApiParameterDescription - { - Name = "param", - Source = BindingSource.Query, - ModelMetadata = ModelMetadataFactory.CreateForProperty(typeof(FakeController.TypeWithRequiredProperty), "RequiredProperty") - } - }) - } - ); + Name = "param", + Source = BindingSource.Query, + ModelMetadata = ModelMetadataFactory.CreateForProperty(typeof(FakeController.TypeWithRequiredProperty), "RequiredProperty") + } + }) + } + ); - var document = subject.GetSwagger("v1"); + var document = subject.GetSwagger("v1"); - return Verifier.Verify(document); - } + return Verifier.Verify(document); + } #endif - private static SwaggerGenerator Subject( - IEnumerable apiDescriptions, - SwaggerGeneratorOptions options = null, - IEnumerable authenticationSchemes = null) - { - return new SwaggerGenerator( - options ?? DefaultOptions, - new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), - new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), - new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) - ); - } + private static SwaggerGenerator Subject( + IEnumerable apiDescriptions, + SwaggerGeneratorOptions options = null, + IEnumerable authenticationSchemes = null) + { + return new SwaggerGenerator( + options ?? DefaultOptions, + new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), + new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), + new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) + ); + } - private static readonly SwaggerGeneratorOptions DefaultOptions = new SwaggerGeneratorOptions + private static readonly SwaggerGeneratorOptions DefaultOptions = new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary { - SwaggerDocs = new Dictionary - { - ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } - } - }; - } + ["v1"] = new OpenApiInfo { Version = "V1", Title = "Test API" } + } + }; } From 055edb1d78d1bf27b1454f069ac73e98996926d7 Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 17:21:48 +0100 Subject: [PATCH 6/8] Testing verify failure --- ...rifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt index 73d6704137..8fad8e8135 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt @@ -30,8 +30,7 @@ ], Responses: { 200: { - Description: OK, - UnresolvedReference: false + Description: OK } }, Deprecated: false From 9f7f28a73ef27e9517a969c0bf5a9740f051879b Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 17:27:43 +0100 Subject: [PATCH 7/8] Fix verify test --- ...rifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt index 8fad8e8135..73d6704137 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.ApiDescriptionsWithMatchingGroupName.verified.txt @@ -30,7 +30,8 @@ ], Responses: { 200: { - Description: OK + Description: OK, + UnresolvedReference: false } }, Deprecated: false From 2f5962dd74d7ebacc0ab8e8f98a7df38b4f6cc72 Mon Sep 17 00:00:00 2001 From: Keah Peters Date: Fri, 31 May 2024 17:40:48 +0100 Subject: [PATCH 8/8] Update .github/dependabot.yml Co-authored-by: Martin Costello --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 63b350d798..5bdb1b2704 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -33,7 +33,7 @@ updates: xunit: patterns: - xunit* - - Verify.Xunit* + - Verify.Xunit schedule: interval: weekly day: wednesday