Skip to content

Commit

Permalink
Add .NET 8 Minimal API test app
Browse files Browse the repository at this point in the history
Add WeatherForecast .NET 8 Minimal API test application.
Resolves domaindrivendev#2791.
  • Loading branch information
martincostello committed Apr 14, 2024
1 parent 7f64f9d commit 9819a4f
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 6 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Expand Up @@ -13,6 +13,7 @@
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.28" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.Routing" Version="2.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
Expand Down
15 changes: 15 additions & 0 deletions Swashbuckle.AspNetCore.sln
Expand Up @@ -107,6 +107,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\update-dotnet-sdk.yml = .github\workflows\update-dotnet-sdk.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApi", "test\WebSites\WebApi\WebApi.csproj", "{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -501,6 +503,18 @@ Global
{3D0126CB-5439-483C-B2D5-4B4BE111D15C}.Release|x64.Build.0 = Release|Any CPU
{3D0126CB-5439-483C-B2D5-4B4BE111D15C}.Release|x86.ActiveCfg = Release|Any CPU
{3D0126CB-5439-483C-B2D5-4B4BE111D15C}.Release|x86.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x64.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x64.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x86.ActiveCfg = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Debug|x86.Build.0 = Debug|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|Any CPU.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x64.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x64.Build.0 = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x86.ActiveCfg = Release|Any CPU
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -541,6 +555,7 @@ Global
{3D0126CB-5439-483C-B2D5-4B4BE111D15C} = {DB3F57FC-1472-4F03-B551-43394DA3C5EB}
{3BA087DA-788C-43D6-9D8B-1EF017014A4A} = {FA1B4021-0A97-4F68-B966-148191F6AAA8}
{A0EC16BE-C520-4FCF-BB54-2D79CD255F00} = {3BA087DA-788C-43D6-9D8B-1EF017014A4A}
{DE1D77F8-3916-4DEE-A57D-6DDC357F64C6} = {DB3F57FC-1472-4F03-B551-43394DA3C5EB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {36FC6A67-247D-4149-8EDD-79FFD1A75F51}
Expand Down
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
Expand Down Expand Up @@ -33,12 +34,7 @@ public class SwaggerIntegrationTests
var testSite = new TestSite(startupType);
var client = testSite.BuildClient();

var swaggerResponse = await client.GetAsync(swaggerRequestUri);

swaggerResponse.EnsureSuccessStatusCode();
var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();
new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);
Assert.Empty(diagnostic.Errors);
await AssertValidSwaggerJson(client, swaggerRequestUri);
}

[Fact]
Expand Down Expand Up @@ -112,5 +108,34 @@ public async Task SwaggerEndpoint_ReturnsCorrectPriceExample_ForDifferentCulture
var json = await JsonSerializer.DeserializeAsync<JsonElement>(contentStream);
Assert.Equal(expectedVersionValue, json.GetProperty(expectedVersionProperty).GetString());
}

#if NET8_0_OR_GREATER
[Theory]
[InlineData("/swagger/v1/swagger.json")]
public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi(
string swaggerRequestUri)
{
await SwaggerEndpointReturnsValidSwaggerJson<Program>(swaggerRequestUri);
}

private async Task SwaggerEndpointReturnsValidSwaggerJson<TEntryPoint>(string swaggerRequestUri)
where TEntryPoint : class
{
var application = new TestApplication<TEntryPoint>();
var client = application.CreateDefaultClient();

await AssertValidSwaggerJson(client, swaggerRequestUri);
}
#endif

private async Task AssertValidSwaggerJson(HttpClient client, string swaggerRequestUri)
{
using var swaggerResponse = await client.GetAsync(swaggerRequestUri);

swaggerResponse.EnsureSuccessStatusCode();
using var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();
new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);
Assert.Empty(diagnostic.Errors);
}
}
}
Expand Up @@ -21,7 +21,12 @@
<ProjectReference Include="..\WebSites\TestFirst\TestFirst.csproj" />
</ItemGroup>

<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
<ProjectReference Include="..\WebSites\WebApi\WebApi.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.OpenApi.Readers" />
Expand Down
19 changes: 19 additions & 0 deletions test/Swashbuckle.AspNetCore.IntegrationTests/TestApplication.cs
@@ -0,0 +1,19 @@
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;

namespace Swashbuckle.AspNetCore.IntegrationTests;

public class TestApplication<TEntryPoint> : WebApplicationFactory<TEntryPoint>
where TEntryPoint : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
var startupAssembly = typeof(TEntryPoint).Assembly;
var applicationName = startupAssembly.GetName().Name;

builder.UseEnvironment("Development")
.UseSolutionRelativeContentRoot(Path.Combine("test", "WebSites", applicationName));
}
}
46 changes: 46 additions & 0 deletions test/WebSites/WebApi/Program.cs
@@ -0,0 +1,46 @@
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new() { Title = "WebApi", Version = "v1" });
});

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

public partial class Program
{
// Expose the Program class for use with WebApplicationFactory<T>
}
41 changes: 41 additions & 0 deletions test/WebSites/WebApi/Properties/launchSettings.json
@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:21394",
"sslPort": 44373
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5205",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7175;http://localhost:5205",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
19 changes: 19 additions & 0 deletions test/WebSites/WebApi/WebApi.csproj
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>WebApi</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Swashbuckle.AspNetCore.SwaggerGen\Swashbuckle.AspNetCore.SwaggerGen.csproj" />
<ProjectReference Include="..\..\..\src\Swashbuckle.AspNetCore.SwaggerUI\Swashbuckle.AspNetCore.SwaggerUI.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions test/WebSites/WebApi/WebApi.http
@@ -0,0 +1,4 @@
@WebApi_HostAddress = http://localhost:5205

GET {{WebApi_HostAddress}}/weatherforecast/
Accept: application/json
8 changes: 8 additions & 0 deletions test/WebSites/WebApi/appsettings.Development.json
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions test/WebSites/WebApi/appsettings.json
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

0 comments on commit 9819a4f

Please sign in to comment.