Skip to content

Commit

Permalink
OpenAPI/Swagger updates (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
PureKrome authored Mar 20, 2020
1 parent 4cd6acd commit ae7b7ce
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 32 deletions.
13 changes: 11 additions & 2 deletions Homely.AspNetCore.Mvc.Helpers.sln
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Homely.AspNetCore.Mvc.Helpers", "src\Homely.AspNetCore.Mvc.Helpers\Homely.AspNetCore.Mvc.Helpers.csproj", "{04B7F2CF-CE32-413B-B9AA-01AA6EC4F340}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestWebApplication", "tests\TestWebApplication\TestWebApplication.csproj", "{56778678-D218-4D40-BDBF-6F862803F3F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Homely.AspNetCore.Mvc.Helpers.Tests", "tests\Homely.AspNetCore.Mvc.Helpers.Tests\Homely.AspNetCore.Mvc.Helpers.Tests.csproj", "{22381896-5D30-4B69-8D95-95A2D546E85B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6F6F0A84-3C6C-4FB2-A08E-E40BA03A05B4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BD11E9E6-8173-498B-A7EA-D16D78155A90}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -31,6 +35,11 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{04B7F2CF-CE32-413B-B9AA-01AA6EC4F340} = {6F6F0A84-3C6C-4FB2-A08E-E40BA03A05B4}
{56778678-D218-4D40-BDBF-6F862803F3F0} = {BD11E9E6-8173-498B-A7EA-D16D78155A90}
{22381896-5D30-4B69-8D95-95A2D546E85B} = {BD11E9E6-8173-498B-A7EA-D16D78155A90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CAE1AB89-D2DD-4A8E-8738-947BA3F1D089}
EndGlobalSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace Homely.AspNetCore.Mvc.Helpers.Extensions
public static class IApplicationBuilderExtensions
{
public static IApplicationBuilder UseCustomSwagger(this IApplicationBuilder application,
string routePrefix = "swagger",
string title = "My API",
string version = "v1")
string version = "v1",
string routePrefix = "swagger")
{
if (string.IsNullOrWhiteSpace(routePrefix))
{
Expand All @@ -25,12 +25,11 @@ public static IApplicationBuilder UseCustomSwagger(this IApplicationBuilder appl
throw new ArgumentException(nameof(title));
}

application.UseSwagger(c => c.RouteTemplate = routePrefix + "/{documentName}/swagger.json");

application.UseSwagger();
application.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"/{routePrefix}/{version}/swagger.json", title);
c.RoutePrefix = routePrefix;
});

return application;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;

namespace Homely.AspNetCore.Mvc.Helpers.Extensions
{
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddCustomSwagger(this IServiceCollection services,
string title = "My API",
string version = "v1")
string version = "v1",
Func<ApiDescription, string> operationIdSelector = null)
{
if (string.IsNullOrWhiteSpace(title))
{
throw new System.ArgumentException(nameof(title));
throw new ArgumentException(nameof(title));
}

if (string.IsNullOrWhiteSpace(version))
{
throw new System.ArgumentException(nameof(version));
throw new ArgumentException(nameof(version));
}

services.AddSwaggerGen(c =>
services.AddSwaggerGen(setupAction =>
{
c.SwaggerDoc(version,
new OpenApiInfo
{
Title = title,
Version = version
});
// Do we wish to override the current operationId with some custom logic?
if (operationIdSelector != null)
{
setupAction.CustomOperationIds(operationIdSelector);
}

var info = new OpenApiInfo
{
Title = title,
Version = version
};

setupAction.SwaggerDoc(version, info);

});

return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.1.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Shouldly;
using System.Threading.Tasks;
using Xunit;

namespace Homely.AspNetCore.Mvc.Helpers.Tests.SwaggerTests
{
public class CustomSwaggerTests : TestSetup
{
[Fact]
public async Task GivenASwaggerUiRequest_Get_ReturnsAnHttp200()
{
// Arrange.

// Act.
var response = await Client.GetAsync("/swagger/index.html");

// Assert.
response.IsSuccessStatusCode.ShouldBeTrue();
}

[Fact]
public async Task GivenASwaggerRequest_Get_ReturnsAnHttp200()
{
// Arrange.

// Act.
var response = await Client.GetAsync("/swagger/v2/swagger.json");

// Assert.
response.IsSuccessStatusCode.ShouldBeTrue();
response.Content.Headers.ContentType.MediaType.ShouldBe("application/json");
response.Content.Headers.ContentType.CharSet.ShouldBe("utf-8");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@
using Shouldly;
using System.Net;
using System.Threading.Tasks;
using TestWebApplication.Models;
using Xunit;

namespace Homely.AspNetCore.Mvc.Helpers.Tests.TestControllerTests
{
public class ModelBindingTests : TestSetup
{
[Fact]
public async Task GivenAValidModelBind_Get_ReturnsAnHttp200()
{
// Arrange & Act.
var response = await Client.GetAsync($"/test/modelbinding/{ColourType.GreenAndPink}");

// Assert.
response.StatusCode.ShouldBe(HttpStatusCode.OK);
}

[Fact]
public async Task GivenABadModelBind_Get_ReturnsAnHttp400()
{
Expand Down
4 changes: 1 addition & 3 deletions tests/Homely.AspNetCore.Mvc.Helpers.Tests/TestStartup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TestWebApplication;
using TestWebApplication.Repositories;
Expand All @@ -8,8 +7,7 @@ namespace Homely.AspNetCore.Mvc.Helpers.Tests
{
public class TestStartup : Startup
{
public TestStartup(IConfiguration configuration,
IHostingEnvironment hostingEnvironment) : base(configuration, hostingEnvironment)
public TestStartup(IHostingEnvironment hostingEnvironment) : base(hostingEnvironment)
{
}

Expand Down
3 changes: 2 additions & 1 deletion tests/TestWebApplication/Controllers/TestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public TestController(IFakeVehicleRepository fakeVehicleRepository)
}

// GET: /test/1 | 200 OK.
[HttpGet("{id:int}", Name ="GetId")]
[HttpGet("{id:int}", Name = "GetId")]
public IActionResult Get(int id)
{
var model = _fakeVehicleRepository.Get(id);
Expand All @@ -38,6 +38,7 @@ public IActionResult Get(int id)
}

// GET: /test/notFound | 404 Not Found.
[HttpHead("notfound")]
[HttpGet("notfound")]
public IActionResult GetNotFound()
{
Expand Down
29 changes: 21 additions & 8 deletions tests/TestWebApplication/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Reflection;
using TestWebApplication.Repositories;

namespace TestWebApplication
{
public class Startup
{
private readonly IConfiguration _configuration;
private const string SwaggerVersion = "v2";
private const string SwaggerTitle = "Test API";

private readonly IHostingEnvironment _hostingEnvironment;

public Startup(IConfiguration configuration,
IHostingEnvironment hostingEnvironment)
public Startup(IHostingEnvironment hostingEnvironment)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
}

Expand All @@ -35,16 +37,19 @@ public void ConfigureServices(IServiceCollection services)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

services.AddProblemDetails(options => options.IncludeExceptionDetails = _ => _hostingEnvironment.IsDevelopment())
.AddCustomSwagger("Test API");

.AddCustomSwagger(SwaggerTitle,
SwaggerVersion,
CustomOperationIdSelector);

ConfigureRepositories(services);
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{

app.UseProblemDetails()
.UseCustomSwagger(title: "Test API")
.UseCustomSwagger(SwaggerTitle, SwaggerVersion)
.UseMvc();
}

Expand All @@ -60,5 +65,13 @@ public virtual void ConfigureRepositories(IServiceCollection services)
// Inject our repo.
services.AddSingleton<IFakeVehicleRepository>(stubbedFakeVehicleRepository);
}

// Format: <Microservice>_<HTTP Method>_<MethodName>
// E.g. : TestMicroservice__Head_GetListingsAsync
private string CustomOperationIdSelector(ApiDescription apiDescription)
{
var methodName = apiDescription.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : Guid.NewGuid().ToString();
return $"TestMicroservice_{apiDescription.HttpMethod}_{methodName}_{Guid.NewGuid().ToString()}";
}
}
}
2 changes: 1 addition & 1 deletion tests/TestWebApplication/TestWebApplication.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="4.2.0" />
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="4.4.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

Expand Down

0 comments on commit ae7b7ce

Please sign in to comment.