From 0a1f9f318ba8a1d531ffd6bb046f4edbe14a2efb Mon Sep 17 00:00:00 2001 From: Georg Dangl <10274404+GeorgDangl@users.noreply.github.com> Date: Tue, 19 May 2020 22:06:45 +0200 Subject: [PATCH 01/11] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3233790..8ffc458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to **LightQuery** are documented here. ## v1.8.1: -- The Angular library was updateds to be compatible with Angular v9.1 +- The Angular library was updated to be compatible with Angular v9.1 ## v1.8.0: - Add a `thenSort` parameter to specify a second sort option. This translates to something like `queryable.OrderBy(sort).ThenBy(thenSort)` From deec8d6000bb2e0efa8ab87b000ab4f3dac98dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berkay=20AKC=CC=A7AY?= Date: Wed, 27 May 2020 22:49:27 +0300 Subject: [PATCH 02/11] init Swashbuckle project and IOperationFilter issue-#6 --- LightQuery.sln | 7 ++ .../LightQuery.Swashbuckle.csproj | 16 ++++ .../LightQueryOperationFilter.cs | 84 +++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj create mode 100644 src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs diff --git a/LightQuery.sln b/LightQuery.sln index 4cb9520..f9801ba 100644 --- a/LightQuery.sln +++ b/LightQuery.sln @@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LightQuery.Shared.Tests", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = ".build", "build\.build.csproj", "{506E6C78-4821-4269-A19A-7B60900EFBC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightQuery.Swashbuckle", "src\LightQuery.Swashbuckle\LightQuery.Swashbuckle.csproj", "{6C16698D-EA61-49B0-B24F-60B4E238C897}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -101,6 +103,10 @@ Global {38C64E1E-28CD-46D9-A4B2-D2E59683F8C0}.Release|Any CPU.Build.0 = Release|Any CPU {506E6C78-4821-4269-A19A-7B60900EFBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {506E6C78-4821-4269-A19A-7B60900EFBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C16698D-EA61-49B0-B24F-60B4E238C897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C16698D-EA61-49B0-B24F-60B4E238C897}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C16698D-EA61-49B0-B24F-60B4E238C897}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C16698D-EA61-49B0-B24F-60B4E238C897}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -118,6 +124,7 @@ Global {8CCD27FA-22E5-41FA-A796-44290D427ED9} = {7F628AED-CB88-45FF-BF48-8EA02C691700} {B2D54A8A-30DD-489C-847D-9347E4F7D436} = {6526DECE-8511-41B3-B5A6-C8170D362611} {38C64E1E-28CD-46D9-A4B2-D2E59683F8C0} = {7F628AED-CB88-45FF-BF48-8EA02C691700} + {6C16698D-EA61-49B0-B24F-60B4E238C897} = {6526DECE-8511-41B3-B5A6-C8170D362611} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A225AC12-BAEB-44E1-8A7E-CE6E82AF1756} diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj new file mode 100644 index 0000000..81f6de0 --- /dev/null +++ b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.0 + + + + + + + + + + + + diff --git a/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs b/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs new file mode 100644 index 0000000..cdff9ca --- /dev/null +++ b/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs @@ -0,0 +1,84 @@ +using System.Linq; +using System.Reflection; +using LightQuery.EntityFrameworkCore; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace LightQuery.Swashbuckle +{ + /// + /// Generates operation filter for LightQuery's paramters + /// Swashbuckle + /// + /// OpenAPI Support + public class LightQueryOperationFilter : IOperationFilter + { + /* + * TODO : how can open api schema be parametric? + */ + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + //Check for [SwaggerParameter] add defined parameter to the parameter list + if (((ControllerActionDescriptor)context.ApiDescription.ActionDescriptor).MethodInfo.GetCustomAttributes().Any(a => a is AsyncLightQueryAttribute || a is LightQueryAttribute)) + { + // sort + operation.Parameters.Add(new OpenApiParameter() + { + Name = "sort", + In = ParameterLocation.Query, + Description = "sort", + Required = false, + Schema = new OpenApiSchema + { + Type = "string", + Example = new OpenApiString("CreatedAt desc") + } + }); + + // thenSort + operation.Parameters.Add(new OpenApiParameter() + { + Name = "thenSort", + In = ParameterLocation.Query, + Description = "then sort", + Required = false, + Schema = new OpenApiSchema + { + Type = "string", + Example = new OpenApiString("UpdatedAt desc") + } + }); + + // pageSize + operation.Parameters.Add(new OpenApiParameter() + { + Name = "pageSize", + In = ParameterLocation.Query, + Description = "page size", + Required = false, + Schema = new OpenApiSchema + { + Type = "integer", + Example = new OpenApiInteger(10) + } + }); + + // page + operation.Parameters.Add(new OpenApiParameter() + { + Name = "page", + In = ParameterLocation.Query, + Description = "page", + Required = false, + Schema = new OpenApiSchema + { + Type = "integer", + Example = new OpenApiInteger(1) + } + }); + } + } + } +} \ No newline at end of file From d1643f221ace831145bdc7d4c54d409cd745383d Mon Sep 17 00:00:00 2001 From: Georg Dangl Date: Wed, 27 May 2020 23:43:51 +0200 Subject: [PATCH 03/11] Add LightQuery.NSwag with tests +semver: minor --- CHANGELOG.md | 3 + LightQuery.sln | 11 +- README.md | 22 ++++ src/LightQuery.NSwag/LightQuery.NSwag.csproj | 33 +++++ src/LightQuery.NSwag/LightQuery.NSwag.snk | Bin 0 -> 596 bytes .../LightQueryOperationsProcessor.cs | 75 +++++++++++ .../NSwagGenerationTests.cs | 120 ++++++++++++++++++ .../LightQuery.IntegrationTestsServer.csproj | 1 + .../Startup.cs | 26 +++- 9 files changed, 287 insertions(+), 4 deletions(-) create mode 100644 src/LightQuery.NSwag/LightQuery.NSwag.csproj create mode 100644 src/LightQuery.NSwag/LightQuery.NSwag.snk create mode 100644 src/LightQuery.NSwag/LightQueryOperationsProcessor.cs create mode 100644 test/LightQuery.Client.Tests.Integration/NSwagGenerationTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ffc458..a722f97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to **LightQuery** are documented here. +## v1.9.0: +- Addition of the **LightQuery.Swashbuckle** (thanks to GitHub user @berkayakcay) and **LightQuery.NSwag** packages to support Swagger & OpenAPI generation + ## v1.8.1: - The Angular library was updated to be compatible with Angular v9.1 diff --git a/LightQuery.sln b/LightQuery.sln index 4cb9520..612e9a7 100644 --- a/LightQuery.sln +++ b/LightQuery.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2005 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LightQuery", "src\LightQuery\LightQuery.csproj", "{33650DEE-5957-45BA-AFE4-2AFEA731DA4D}" EndProject @@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LightQuery.Shared.Tests", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = ".build", "build\.build.csproj", "{506E6C78-4821-4269-A19A-7B60900EFBC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightQuery.NSwag", "src\LightQuery.NSwag\LightQuery.NSwag.csproj", "{9D88E0DE-D298-4143-B051-E022B20B102E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -101,6 +103,10 @@ Global {38C64E1E-28CD-46D9-A4B2-D2E59683F8C0}.Release|Any CPU.Build.0 = Release|Any CPU {506E6C78-4821-4269-A19A-7B60900EFBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {506E6C78-4821-4269-A19A-7B60900EFBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D88E0DE-D298-4143-B051-E022B20B102E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D88E0DE-D298-4143-B051-E022B20B102E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D88E0DE-D298-4143-B051-E022B20B102E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D88E0DE-D298-4143-B051-E022B20B102E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -118,6 +124,7 @@ Global {8CCD27FA-22E5-41FA-A796-44290D427ED9} = {7F628AED-CB88-45FF-BF48-8EA02C691700} {B2D54A8A-30DD-489C-847D-9347E4F7D436} = {6526DECE-8511-41B3-B5A6-C8170D362611} {38C64E1E-28CD-46D9-A4B2-D2E59683F8C0} = {7F628AED-CB88-45FF-BF48-8EA02C691700} + {9D88E0DE-D298-4143-B051-E022B20B102E} = {6526DECE-8511-41B3-B5A6-C8170D362611} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A225AC12-BAEB-44E1-8A7E-CE6E82AF1756} diff --git a/README.md b/README.md index b9cefaf..e6dc1c2 100644 --- a/README.md +++ b/README.md @@ -288,6 +288,28 @@ export class UsersDetailsService extends PaginationBaseService implements } ``` +## Swagger & OpenAPI Support + +The packages **LightQuery.NSwag** and **LightQuery.Swashbuckle** support the automatic generation +of correct Swagger & OpenAPI parameter descriptions for the sort and pagination parameters. + +### Example with NSwag + +Just add the `LightQuery.NSwag.LightQueryOperationsProcessor` to your document generation: + +```csharp +services.AddSwaggerDocument(nSwagConfig => +{ + nSwagConfig.DocumentName = "swagger20"; + nSwagConfig.OperationProcessors.Add(new LightQueryOperationsProcessor()); +}); +services.AddOpenApiDocument(nSwagConfig => +{ + nSwagConfig.DocumentName = "openapi30"; + nSwagConfig.OperationProcessors.Add(new LightQueryOperationsProcessor()); +}); +``` + ## Assembly Strong Naming & Usage in Signed Applications This module produces strong named assemblies when compiled. When consumers of this package require strongly named assemblies, for example when they diff --git a/src/LightQuery.NSwag/LightQuery.NSwag.csproj b/src/LightQuery.NSwag/LightQuery.NSwag.csproj new file mode 100644 index 0000000..59a79e2 --- /dev/null +++ b/src/LightQuery.NSwag/LightQuery.NSwag.csproj @@ -0,0 +1,33 @@ + + + + netcoreapp3.0;netstandard2.0;net461 + True + Georg Dangl + + Extensions to use LightQuery with NSwag + (c) $([System.DateTime]::Now.Year) Georg Dangl + MIT + https://github.com/GeorgDangl/LightQuery + https://github.com/GeorgDangl/LightQuery.git + git + Asp-Net-Core Querying Sorting Filtering + gd_icon_256.png + true + LightQuery.NSwag.snk + + + + + + + + + + + + + + + + diff --git a/src/LightQuery.NSwag/LightQuery.NSwag.snk b/src/LightQuery.NSwag/LightQuery.NSwag.snk new file mode 100644 index 0000000000000000000000000000000000000000..824c8e96d4ae8418fe9841283ce405a300c4ac7e GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096sL1F_GMCZcblWxtN3UZuM7NP(d3wzn; zWkE>0l$zUnsqvR{lun%!UY z#eOHMjW~@i4-a-bBuetcq+YdPZBIeN5Yjt}y8&wMzKmuyfW8R*B;FF6N@m!*xK+1@ zJ-)YIK;_2x+L>i-{2pPju9#Nfi+(}1^`BfA6&aOK3*N>v$!19B)Pl2wa=~L`rj${E zQxy5oa6p#NYpy9*a+pDyM9YFdRB@2W7)69)Cv(?DGd5FCl?nwx z6s9me{{b%mFicHE))m3+POez~J}>im82zx)T>`z~0_}0xAnDu##vS*mK0dNs!CBUu zA}B0!D=C#zG&?(f>9Oq{v^oRmFAYigS#FN4bs^ZfNyS-}gS@nvs1wrW%OLlF);dh@ zFtVCexb@6jmd2Hj#hyh&hQ64LIEBSwWnxyZId_9%hS9GlyUZWF*ObSKRe;#WDlChKWQM#3D+2gWsM^!=5tYf?8X0PPZvTli%kV6AeqxstBwnmF2*5sq(sD~ z%Ks$eLXaKNkKd#O7MipAHcLx56MdB?$DqCb9`-eI8Zvca2f$qwAQ+sqZO8#8c=>5D z7+r!0sJ%!p|C=~;V3nCP@wxmnNE2O7ndTfkHr$b2A#hq@K?Q=UUk2OWIk{wjc^G%p iQh~WS3;n805(79!UGfZ=i27q5PRn7*ZfKa7To9Q7T@@Sv literal 0 HcmV?d00001 diff --git a/src/LightQuery.NSwag/LightQueryOperationsProcessor.cs b/src/LightQuery.NSwag/LightQueryOperationsProcessor.cs new file mode 100644 index 0000000..091bdfe --- /dev/null +++ b/src/LightQuery.NSwag/LightQueryOperationsProcessor.cs @@ -0,0 +1,75 @@ +using LightQuery.EntityFrameworkCore; +using NSwag; +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; +using System.Linq; +using System.Reflection; + +namespace LightQuery.NSwag +{ + public class LightQueryOperationsProcessor : IOperationProcessor + { + public bool Process(OperationProcessorContext context) + { + if (context.MethodInfo.GetCustomAttributes() + .Any(a => a is LightQueryAttribute + || a is AsyncLightQueryAttribute)) + { + context.OperationDescription + .Operation + .Parameters + .Add(new OpenApiParameter + { + Name = "sort", + Kind = OpenApiParameterKind.Query, + Description = "sort", + Schema = new NJsonSchema.JsonSchema + { + Type = NJsonSchema.JsonObjectType.String + } + }); + context.OperationDescription + .Operation + .Parameters + .Add(new OpenApiParameter + { + Name = "thenSort", + Kind = OpenApiParameterKind.Query, + Description = "then sort", + Schema = new NJsonSchema.JsonSchema + { + Type = NJsonSchema.JsonObjectType.String + } + }); + context.OperationDescription + .Operation + .Parameters + .Add(new OpenApiParameter + { + Name = "pageSize", + Kind = OpenApiParameterKind.Query, + Description = "page size", + Schema = new NJsonSchema.JsonSchema + { + Type = NJsonSchema.JsonObjectType.Integer + } + }); + context.OperationDescription + .Operation + .Parameters + .Add(new OpenApiParameter + { + Name = "page", + Kind = OpenApiParameterKind.Query, + Description = "page", + Schema = new NJsonSchema.JsonSchema + { + Type = NJsonSchema.JsonObjectType.Integer + } + }); + } + + return true; + } + } +} diff --git a/test/LightQuery.Client.Tests.Integration/NSwagGenerationTests.cs b/test/LightQuery.Client.Tests.Integration/NSwagGenerationTests.cs new file mode 100644 index 0000000..20a8c13 --- /dev/null +++ b/test/LightQuery.Client.Tests.Integration/NSwagGenerationTests.cs @@ -0,0 +1,120 @@ +using LightQuery.IntegrationTestsServer; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace LightQuery.Client.Tests.Integration +{ + public class NSwagGenerationTests + { + private readonly HttpClient _client = IntegrationTestServer.GetTestServer().CreateClient(); + + [Fact] + public async Task CanGetSwaggerDocument() + { + var swaggerDocResponse = await _client.GetAsync("/nswag/swagger20.json"); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + Assert.True(swaggerDoc.Length > 0); + } + + [Fact] + public async Task CanGetOpenApiDocument() + { + var swaggerDocResponse = await _client.GetAsync("/nswag/openapi30.json"); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + Assert.True(swaggerDoc.Length > 0); + } + + [Fact] + public async Task GeneratesSortParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "sort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesSortParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "sort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesThenSortParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "thenSort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesThenSortParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "thenSort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "page" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "page" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageSizeParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "pageSize" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageSizeParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/nswag/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "pageSize" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + private async Task GetSwaggerDocAsync(string specUrl) + { + var swaggerDocResponse = await _client.GetAsync(specUrl); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + return JObject.Parse(swaggerDoc); + } + } +} diff --git a/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj b/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj index ef5e2c7..5c0b4d1 100644 --- a/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj +++ b/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj @@ -19,6 +19,7 @@ + diff --git a/test/LightQuery.IntegrationTestsServer/Startup.cs b/test/LightQuery.IntegrationTestsServer/Startup.cs index 872f055..f0a1520 100644 --- a/test/LightQuery.IntegrationTestsServer/Startup.cs +++ b/test/LightQuery.IntegrationTestsServer/Startup.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Builder; +using LightQuery.NSwag; +using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -11,7 +12,17 @@ public class Startup public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseInMemoryDatabase(_inMemoryDatabaseName)); - services.AddMvc(); + + services.AddSwaggerDocument(nSwagConfig => + { + nSwagConfig.DocumentName = "swagger20"; + nSwagConfig.OperationProcessors.Add(new LightQueryOperationsProcessor()); + }); + services.AddOpenApiDocument(nSwagConfig => + { + nSwagConfig.DocumentName = "openapi30"; + nSwagConfig.OperationProcessors.Add(new LightQueryOperationsProcessor()); + }); #if NETCORE3 services.AddMvc(mvcOptions => mvcOptions.EnableEndpointRouting = false); ; @@ -22,6 +33,17 @@ public void ConfigureServices(IServiceCollection services) public void Configure(IApplicationBuilder app) { + app.UseOpenApi(openApiConfig => + { + openApiConfig.DocumentName = "swagger20"; + openApiConfig.Path = "/nswag/swagger20.json"; + }); + app.UseOpenApi(openApiConfig => + { + openApiConfig.DocumentName = "openapi30"; + openApiConfig.Path = "/nswag/openapi30.json"; + }); + app.UseMvc(); } } From 45ea7dfc13bae10042b3ef557bc8b476cf561b57 Mon Sep 17 00:00:00 2001 From: Georg Dangl Date: Wed, 27 May 2020 23:51:54 +0200 Subject: [PATCH 04/11] Update build script The C# projects are enumerated explicitly in the Clean task to prevent the globbing from catching folders in the Angular libraries node_modules folder --- build/Build.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Build.cs b/build/Build.cs index bb408b1..95d7ee9 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -79,6 +79,7 @@ class Build : NukeBuild GlobDirectories(SourceDirectory / "LightQuery.Client", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(SourceDirectory / "LightQuery.EntityFrameworkCore", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(SourceDirectory / "LightQuery.Shared", "**/bin", "**/obj").ForEach(DeleteDirectory); + GlobDirectories(SourceDirectory / "LightQuery.NSwag", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(RootDirectory / "test", "**/bin", "**/obj").ForEach(DeleteDirectory); EnsureCleanDirectory(OutputDirectory); }); From 6e7d2e432365abdb8a803170582ecf48d1831876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berkay=20AKC=CC=A7AY?= Date: Fri, 29 May 2020 16:02:33 +0300 Subject: [PATCH 05/11] added LightQuery Swashbuckle LightQueryOperationFilter test and its obligations --- LightQuery.sln | 7 ++ .../LightQuery.Swashbuckle.csproj | 25 +++- .../LightQueryOperationFilter.cs | 6 +- .../SwashbuckleGenerationTests.cs | 117 ++++++++++++++++++ .../Controllers/AsyncLightQueryController.cs | 1 + .../AsyncPaginatedLightQueryController.cs | 1 + .../Controllers/LightQueryController.cs | 1 + .../PaginatedLightQueryController.cs | 1 + .../Controllers/ValuesController.cs | 1 + .../LightQuery.IntegrationTestsServer.csproj | 1 + .../Startup.cs | 35 ++++++ 11 files changed, 187 insertions(+), 9 deletions(-) create mode 100644 test/LightQuery.Client.Tests.Integration/SwashbuckleGenerationTests.cs diff --git a/LightQuery.sln b/LightQuery.sln index 612e9a7..49730d6 100644 --- a/LightQuery.sln +++ b/LightQuery.sln @@ -47,6 +47,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = ".build", "build\.build.cspr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightQuery.NSwag", "src\LightQuery.NSwag\LightQuery.NSwag.csproj", "{9D88E0DE-D298-4143-B051-E022B20B102E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightQuery.Swashbuckle", "src\LightQuery.Swashbuckle\LightQuery.Swashbuckle.csproj", "{CAF56EA7-A8E2-4AC7-A274-1D26C8E15401}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +109,10 @@ Global {9D88E0DE-D298-4143-B051-E022B20B102E}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D88E0DE-D298-4143-B051-E022B20B102E}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D88E0DE-D298-4143-B051-E022B20B102E}.Release|Any CPU.Build.0 = Release|Any CPU + {CAF56EA7-A8E2-4AC7-A274-1D26C8E15401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAF56EA7-A8E2-4AC7-A274-1D26C8E15401}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAF56EA7-A8E2-4AC7-A274-1D26C8E15401}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAF56EA7-A8E2-4AC7-A274-1D26C8E15401}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -125,6 +131,7 @@ Global {B2D54A8A-30DD-489C-847D-9347E4F7D436} = {6526DECE-8511-41B3-B5A6-C8170D362611} {38C64E1E-28CD-46D9-A4B2-D2E59683F8C0} = {7F628AED-CB88-45FF-BF48-8EA02C691700} {9D88E0DE-D298-4143-B051-E022B20B102E} = {6526DECE-8511-41B3-B5A6-C8170D362611} + {CAF56EA7-A8E2-4AC7-A274-1D26C8E15401} = {6526DECE-8511-41B3-B5A6-C8170D362611} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A225AC12-BAEB-44E1-8A7E-CE6E82AF1756} diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj index 81f6de0..7c5d312 100644 --- a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj +++ b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj @@ -1,16 +1,33 @@ - netcoreapp3.0 + netcoreapp3.0;netstandard2.0;net461 + True + Georg Dangl + + Extensions to use LightQuery with Swashbuckle + (c) $([System.DateTime]::Now.Year) Georg Dangl + MIT + https://github.com/GeorgDangl/LightQuery + https://github.com/GeorgDangl/LightQuery.git + git + Asp-Net-Core Querying Sorting Filtering + gd_icon_256.png + true + - + - - + + + + + + diff --git a/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs b/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs index cdff9ca..7d90b69 100644 --- a/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs +++ b/src/LightQuery.Swashbuckle/LightQueryOperationFilter.cs @@ -15,12 +15,8 @@ namespace LightQuery.Swashbuckle /// OpenAPI Support public class LightQueryOperationFilter : IOperationFilter { - /* - * TODO : how can open api schema be parametric? - */ public void Apply(OpenApiOperation operation, OperationFilterContext context) { - //Check for [SwaggerParameter] add defined parameter to the parameter list if (((ControllerActionDescriptor)context.ApiDescription.ActionDescriptor).MethodInfo.GetCustomAttributes().Any(a => a is AsyncLightQueryAttribute || a is LightQueryAttribute)) { // sort @@ -36,7 +32,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) Example = new OpenApiString("CreatedAt desc") } }); - + // thenSort operation.Parameters.Add(new OpenApiParameter() { diff --git a/test/LightQuery.Client.Tests.Integration/SwashbuckleGenerationTests.cs b/test/LightQuery.Client.Tests.Integration/SwashbuckleGenerationTests.cs new file mode 100644 index 0000000..868da8e --- /dev/null +++ b/test/LightQuery.Client.Tests.Integration/SwashbuckleGenerationTests.cs @@ -0,0 +1,117 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using LightQuery.IntegrationTestsServer; +using Newtonsoft.Json.Linq; +using Xunit; + +namespace LightQuery.Client.Tests.Integration +{ + public class SwashbuckleGenerationTests + { + private readonly HttpClient _client = IntegrationTestServer.GetTestServer().CreateClient(); + + [Fact] + public async Task CanGetSwaggerDocument() + { + var swaggerDocResponse = await _client.GetAsync("/swashbuckle/swagger20.json"); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + Assert.True(swaggerDoc.Length > 0); + } + + [Fact] + public async Task CanGetOpenApiDocument() + { + var swaggerDocResponse = await _client.GetAsync("/swashbuckle/openapi30.json"); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + Assert.True(swaggerDoc.Length > 0); + } + + [Fact] + public async Task GeneratesSortParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "sort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesSortParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "sort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesThenSortParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "thenSort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesThenSortParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "thenSort" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "page" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "page" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageSizeParameterInfo_Swagger() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/swagger20.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "pageSize" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + [Fact] + public async Task GeneratesPageSizeParameterInfo_OpenApi() + { + var swaggerDoc = await GetSwaggerDocAsync("/swashbuckle/openapi30.json"); + var sortParameter = swaggerDoc.Descendants() + .OfType() + .FirstOrDefault(d => d["name"]?.Value() == "pageSize" && d.Parent.Path.EndsWith(".parameters")); + Assert.NotNull(sortParameter); + } + + private async Task GetSwaggerDocAsync(string specUrl) + { + var swaggerDocResponse = await _client.GetAsync(specUrl); + var swaggerDoc = await swaggerDocResponse.Content.ReadAsStringAsync(); + return JObject.Parse(swaggerDoc); + } + } +} \ No newline at end of file diff --git a/test/LightQuery.IntegrationTestsServer/Controllers/AsyncLightQueryController.cs b/test/LightQuery.IntegrationTestsServer/Controllers/AsyncLightQueryController.cs index b79a884..c59ef2d 100644 --- a/test/LightQuery.IntegrationTestsServer/Controllers/AsyncLightQueryController.cs +++ b/test/LightQuery.IntegrationTestsServer/Controllers/AsyncLightQueryController.cs @@ -15,6 +15,7 @@ public AsyncLightQueryController(LightQueryContext context) private readonly LightQueryContext _context; + [HttpGet] [AsyncLightQuery] public IActionResult GetValues() { diff --git a/test/LightQuery.IntegrationTestsServer/Controllers/AsyncPaginatedLightQueryController.cs b/test/LightQuery.IntegrationTestsServer/Controllers/AsyncPaginatedLightQueryController.cs index d6519bd..d3be1dd 100644 --- a/test/LightQuery.IntegrationTestsServer/Controllers/AsyncPaginatedLightQueryController.cs +++ b/test/LightQuery.IntegrationTestsServer/Controllers/AsyncPaginatedLightQueryController.cs @@ -16,6 +16,7 @@ public AsyncPaginatedLightQueryController(LightQueryContext context) private readonly LightQueryContext _context; + [HttpGet] [AsyncLightQuery(forcePagination: true, defaultPageSize: 3)] public IActionResult GetValues(bool returnEmptyList = false) { diff --git a/test/LightQuery.IntegrationTestsServer/Controllers/LightQueryController.cs b/test/LightQuery.IntegrationTestsServer/Controllers/LightQueryController.cs index da89166..0ca5d06 100644 --- a/test/LightQuery.IntegrationTestsServer/Controllers/LightQueryController.cs +++ b/test/LightQuery.IntegrationTestsServer/Controllers/LightQueryController.cs @@ -14,6 +14,7 @@ public LightQueryController(LightQueryContext context) private readonly LightQueryContext _context; + [HttpGet] [LightQuery] public IActionResult GetValues() { diff --git a/test/LightQuery.IntegrationTestsServer/Controllers/PaginatedLightQueryController.cs b/test/LightQuery.IntegrationTestsServer/Controllers/PaginatedLightQueryController.cs index 4ec8201..2f00a59 100644 --- a/test/LightQuery.IntegrationTestsServer/Controllers/PaginatedLightQueryController.cs +++ b/test/LightQuery.IntegrationTestsServer/Controllers/PaginatedLightQueryController.cs @@ -15,6 +15,7 @@ public PaginatedLightQueryController(LightQueryContext context) private readonly LightQueryContext _context; + [HttpGet] [LightQuery(forcePagination: true, defaultPageSize: 3)] public IActionResult GetValues(bool returnEmptyList = false) { diff --git a/test/LightQuery.IntegrationTestsServer/Controllers/ValuesController.cs b/test/LightQuery.IntegrationTestsServer/Controllers/ValuesController.cs index 6613fdc..d5c6cf5 100644 --- a/test/LightQuery.IntegrationTestsServer/Controllers/ValuesController.cs +++ b/test/LightQuery.IntegrationTestsServer/Controllers/ValuesController.cs @@ -14,6 +14,7 @@ public ValuesController(LightQueryContext context) private readonly LightQueryContext _context; + [HttpGet] public IActionResult GetValues() { var users = _context.Users.OrderBy(u => Guid.NewGuid()); diff --git a/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj b/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj index 5c0b4d1..8319737 100644 --- a/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj +++ b/test/LightQuery.IntegrationTestsServer/LightQuery.IntegrationTestsServer.csproj @@ -20,6 +20,7 @@ + diff --git a/test/LightQuery.IntegrationTestsServer/Startup.cs b/test/LightQuery.IntegrationTestsServer/Startup.cs index f0a1520..becbb74 100644 --- a/test/LightQuery.IntegrationTestsServer/Startup.cs +++ b/test/LightQuery.IntegrationTestsServer/Startup.cs @@ -1,7 +1,9 @@ using LightQuery.NSwag; +using LightQuery.Swashbuckle; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; namespace LightQuery.IntegrationTestsServer { @@ -23,7 +25,25 @@ public void ConfigureServices(IServiceCollection services) nSwagConfig.DocumentName = "openapi30"; nSwagConfig.OperationProcessors.Add(new LightQueryOperationsProcessor()); }); + + services.AddSwaggerGen(options => + { + options.SwaggerDoc("swagger20", new OpenApiInfo() + { + Description = "swagger20" + }); + options.OperationFilter(); + }); + services.AddSwaggerGen(options => + { + options.SwaggerDoc("openapi30", new OpenApiInfo() + { + Description = "openapi30" + }); + options.OperationFilter(); + }); + #if NETCORE3 services.AddMvc(mvcOptions => mvcOptions.EnableEndpointRouting = false); ; #else @@ -43,6 +63,21 @@ public void Configure(IApplicationBuilder app) openApiConfig.DocumentName = "openapi30"; openApiConfig.Path = "/nswag/openapi30.json"; }); + + /* + * Change the path for swageer json endpoints + * https://github.com/domaindrivendev/Swashbuckle.AspNetCore#change-the-path-for-swagger-json-endpoints + */ + app.UseSwagger(options => + { + options.RouteTemplate = "swashbuckle/{documentName}.json"; + options.SerializeAsV2 = true; + }); + + app.UseSwagger(options => + { + options.RouteTemplate = "swashbuckle/{documentName}.json"; + }); app.UseMvc(); } From a6ed690bd6ed643117ec2728c7fbc22784af432f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berkay=20AKC=CC=A7AY?= Date: Fri, 29 May 2020 17:01:37 +0300 Subject: [PATCH 06/11] updated README.md for LightQuery.Swashbuckle --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6dc1c2..a69a0bb 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ e.g. sorting can be done by using `bankAccount.balance`. Take this example: { "name": "Bob", "bankAccount": null - }, + } ] ``` @@ -310,6 +310,32 @@ services.AddOpenApiDocument(nSwagConfig => }); ``` +### Example with Swashbuckle + +Just add the `LightQuery.Swashbuckle.LightQueryOperationFilter` to your document generation: + +```csharp +services.AddSwaggerGen(options => +{ + options.SwaggerDoc("swagger20", new OpenApiInfo() + { + Description = "swagger20" + }); + options.OperationFilter(); +}); + +services.AddSwaggerGen(options => +{ + options.SwaggerDoc("openapi30", new OpenApiInfo() + { + Description = "openapi30" + }); + options.OperationFilter(); +}); + + +``` + ## Assembly Strong Naming & Usage in Signed Applications This module produces strong named assemblies when compiled. When consumers of this package require strongly named assemblies, for example when they From c4aa2ecb97e3be29bb2be71123574907a786f247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berkay=20AKC=CC=A7AY?= Date: Fri, 29 May 2020 23:29:41 +0300 Subject: [PATCH 07/11] added to build LightQuery.Swashbuckle --- build/Build.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Build.cs b/build/Build.cs index 95d7ee9..4c35671 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -80,6 +80,7 @@ class Build : NukeBuild GlobDirectories(SourceDirectory / "LightQuery.EntityFrameworkCore", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(SourceDirectory / "LightQuery.Shared", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(SourceDirectory / "LightQuery.NSwag", "**/bin", "**/obj").ForEach(DeleteDirectory); + GlobDirectories(SourceDirectory / "LightQuery.Swashbuckle", "**/bin", "**/obj").ForEach(DeleteDirectory); GlobDirectories(RootDirectory / "test", "**/bin", "**/obj").ForEach(DeleteDirectory); EnsureCleanDirectory(OutputDirectory); }); From aa44da0ec6b2438b8966aed0f90eb20694df14c4 Mon Sep 17 00:00:00 2001 From: Georg Dangl Date: Sun, 31 May 2020 21:51:03 +0200 Subject: [PATCH 08/11] Add signing key for LightQuery.Swashbuckle --- .../LightQuery.Swashbuckle.csproj | 2 +- .../LightQuery.Swashbuckle.snk | Bin 0 -> 596 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.snk diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj index 7c5d312..64d721f 100644 --- a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj +++ b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj @@ -14,7 +14,7 @@ Asp-Net-Core Querying Sorting Filtering gd_icon_256.png true - + LightQuery.Swashbuckle.snk diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.snk b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.snk new file mode 100644 index 0000000000000000000000000000000000000000..50d791a9028030260ac1846902bb1010bc06c514 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098eN|td*E(73;c?ZrI@dBG2QI+#xuBznx z@>}i#kD>MF#Zb0((rHS)^i?S4%Y~h9XCPaf*in zq!T4B^bO!z)AE|-pT@k~rmmW{g~_b22Otp-5(Wd#dWuSFh^`YoNpK{Zi8cRuM(v|V zeIfitW~=k6e0~laBY=TirrA8(z=+0AdGVF@Dy`}@Gw!R=sKNoI`hzIsz@AGdvVoYb z_lWv8WR4{qJy6;wqllO;a3;E3ER^nn(8u7F{fNvbh>BxjOLcHFcpcn~_1a}z_R+o_SzT_S~1k~zSkSV4yXH-`|2@xd|Cy^neuPI7(0%ebL;hLKVO z8MqPkWe<#(#tVD);7KxFK*6Avl=p4lpDw4wHXUfFY1(BA#`K!=^SZ;C7*_4EDWaJM z5B&ZdRf+Yh8Mno`S^J3rm1DS}$hR3Pe?Go+G08jmzMv5yaATnY*js;(7%qyClbtK> zV9W^behj&5xTo+c$K@{@pU+S+Qlgp7L@KcdElR2<-biSOU*wFW6QETOy Date: Sun, 31 May 2020 21:51:18 +0200 Subject: [PATCH 09/11] Fix build error due to Swashbuckle trying to generate OpenApi document on build --- src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj index 64d721f..4d26674 100644 --- a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj +++ b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj @@ -15,6 +15,9 @@ gd_icon_256.png true LightQuery.Swashbuckle.snk + + false From d42bc805c6ec5b10f72bd55d8e4aecd31ee02c04 Mon Sep 17 00:00:00 2001 From: Georg Dangl Date: Sun, 31 May 2020 21:51:57 +0200 Subject: [PATCH 10/11] Add @berkayakcay as author --- src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj index 4d26674..3f534ff 100644 --- a/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj +++ b/src/LightQuery.Swashbuckle/LightQuery.Swashbuckle.csproj @@ -3,7 +3,7 @@ netcoreapp3.0;netstandard2.0;net461 True - Georg Dangl + Georg Dangl, Berkay AKÇAY Extensions to use LightQuery with Swashbuckle (c) $([System.DateTime]::Now.Year) Georg Dangl From 5ca1936b90f664944469e32c793c6c04b7d29086 Mon Sep 17 00:00:00 2001 From: Georg Dangl Date: Sun, 31 May 2020 22:10:02 +0200 Subject: [PATCH 11/11] Increased delay in test functions The functions were checking if previous requests are being cancelled when new ones are sent. In case the CI server has a case of the Mondays and is slow, it lead to a failure. The delay was increaed from 10 to 100ms, which should fix that. But it's more of a hack than a real solution. --- test/LightQuery.Client.Tests/PaginationBaseServiceTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/LightQuery.Client.Tests/PaginationBaseServiceTests.cs b/test/LightQuery.Client.Tests/PaginationBaseServiceTests.cs index e5019a9..e6bffb7 100644 --- a/test/LightQuery.Client.Tests/PaginationBaseServiceTests.cs +++ b/test/LightQuery.Client.Tests/PaginationBaseServiceTests.cs @@ -192,7 +192,7 @@ private class User private async Task<(HttpResponseMessage, bool)> GetResponseWithDelay(CancellationToken cancellationToken) { // Adding a short delay to simulate a long running operation, e.g. a web request - await Task.Delay(10); + await Task.Delay(100); var httpResponse = new HttpResponseMessage(System.Net.HttpStatusCode.OK); var memStream = new MemoryStream();