Skip to content

Commit

Permalink
Add more integration tests (#3151)
Browse files Browse the repository at this point in the history
Extend the integration test coverage to include more of the test projects.
  • Loading branch information
Saibamen authored Nov 26, 2024
1 parent 6dcf7a5 commit 69db0e3
Show file tree
Hide file tree
Showing 17 changed files with 376 additions and 49 deletions.
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<ItemGroup>
<PackageVersion Include="Autofac.Extensions.DependencyInjection" Version="4.2.2" />
<PackageVersion Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
Expand Down Expand Up @@ -29,7 +29,7 @@
<PackageVersion Include="NSwag.MSBuild" Version="14.1.0" />
<PackageVersion Include="ReportGenerator" Version="5.4.1" />
<PackageVersion Include="System.Text.Json" Version="4.6.0" />
<PackageVersion Include="Verify.Xunit" Version="28.2.1" />
<PackageVersion Include="Verify.Xunit" Version="28.3.2" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.core" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Reflection;
#if NET8_0_OR_GREATER
using System.Net.Http.Json;
#endif
Expand Down Expand Up @@ -41,6 +42,15 @@ public async Task SwaggerEndpoint_ReturnsValidSwaggerJson(
await AssertValidSwaggerJson(client, swaggerRequestUri);
}

[Fact]
public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_ForAutofaq()
{
var testSite = new TestSiteAutofaq(typeof(CliExampleWithFactory.Startup));
using var client = testSite.BuildClient();

await AssertValidSwaggerJson(client, "/swagger/v1/swagger_net8.0.json");
}

[Fact]
public async Task SwaggerEndpoint_ReturnsNotFound_IfUnknownSwaggerDocument()
{
Expand Down Expand Up @@ -113,23 +123,22 @@ public async Task SwaggerMiddleware_CanBeConfiguredMultipleTimes(
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<WebApi.Program>(swaggerRequestUri);
}

[Theory]
[InlineData("/swagger/v1/swagger.json")]
public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_For_Mvc(
[InlineData(typeof(MinimalApp.Program), "/swagger/v1/swagger.json")]
[InlineData(typeof(TopLevelSwaggerDoc.Program), "/swagger/v1.json")]
#if NET8_0_OR_GREATER
[InlineData(typeof(MvcWithNullable.Program), "/swagger/v1/swagger.json")]
[InlineData(typeof(WebApi.Program), "/swagger/v1/swagger.json")]
[InlineData(typeof(WebApi.Aot.Program), "/swagger/v1/swagger.json")]
#endif
public async Task SwaggerEndpoint_ReturnsValidSwaggerJson_Without_Startup(
Type entryPointType,
string swaggerRequestUri)
{
await SwaggerEndpointReturnsValidSwaggerJson<MvcWithNullable.Program>(swaggerRequestUri);
await SwaggerEndpointReturnsValidSwaggerJson(entryPointType, swaggerRequestUri);
}

#if NET8_0_OR_GREATER
[Fact]
public async Task TypesAreRenderedCorrectly()
{
Expand Down Expand Up @@ -161,22 +170,45 @@ public async Task TypesAreRenderedCorrectly()
() => Assert.True(properties.GetProperty("temperatureF").GetProperty("readOnly").GetBoolean()),
]);
}
#endif

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

using var client = GetHttpClientForTestApplication(entryPointType);
await AssertValidSwaggerJson(client, swaggerRequestUri);
}
#endif

internal static HttpClient GetHttpClientForTestApplication(Type entryPointType)
{
var applicationType = typeof(TestApplication<>).MakeGenericType(entryPointType);
var application = (IDisposable)Activator.CreateInstance(applicationType);
Assert.NotNull(application);

var createClientMethod = applicationType
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(m => m.Name == "CreateDefaultClient" && m.GetParameters().Length == 1);
if (createClientMethod == null)
{
throw new InvalidOperationException($"The method CreateDefaultClient was not found on TestApplication<{entryPointType.FullName}>.");
}

// Pass null for DelegatingHandler[]
var parameters = new object[] { null };

var clientObject = (IDisposable)createClientMethod.Invoke(application, parameters);
if (clientObject is not HttpClient client)
{
throw new InvalidOperationException($"The method CreateDefaultClient on TestApplication<{entryPointType.FullName}> did not return an HttpClient.");
}

return client;
}

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

Assert.True(swaggerResponse.IsSuccessStatusCode, await swaggerResponse.Content.ReadAsStringAsync());
Assert.True(swaggerResponse.IsSuccessStatusCode, $"IsSuccessStatusCode is false. Response: '{await swaggerResponse.Content.ReadAsStringAsync()}'");
using var contentStream = await swaggerResponse.Content.ReadAsStreamAsync();
new OpenApiStreamReader().Read(contentStream, out OpenApiDiagnostic diagnostic);
Assert.Empty(diagnostic.Errors);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"openapi": "3.0.1",
"info": {
"title": "CliExampleWithFactory",
"version": "1.0"
},
"servers": [
{
"url": "http://localhost:57556/"
}
],
"paths": {
"/products": {
"get": {
"tags": [
"Products"
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Product"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Product": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"description": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"openapi": "3.0.1",
"info": {
"title": "MinimalApp",
"version": "v1"
},
"paths": {
"/WeatherForecast": {
"get": {
"tags": [
"WeatherForecast"
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"WeatherForecast": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date-time"
},
"temperatureC": {
"type": "integer",
"format": "int32"
},
"temperatureF": {
"type": "integer",
"format": "int32",
"readOnly": true
},
"summary": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"openapi": "3.0.1",
"info": {
"title": "Test API",
"version": "1"
},
"paths": { },
"components": { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"openapi": "3.0.1",
"info": {
"title": "Native AoT API V1",
"description": "A sample API for testing Swashbuckle with native AoT",
"termsOfService": "http://tempuri.org/terms",
"version": "v1"
},
"paths": {
"/todos": {
"get": {
"tags": [
"WebApi.Aot"
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Todo"
}
}
}
}
}
}
}
},
"/todos/{id}": {
"get": {
"tags": [
"WebApi.Aot"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"components": {
"schemas": {
"Todo": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"title": {
"type": "string",
"nullable": true
},
"dueBy": {
"type": "string",
"format": "date",
"nullable": true
},
"isComplete": {
"type": "boolean"
}
},
"additionalProperties": false
}
}
}
}
Loading

0 comments on commit 69db0e3

Please sign in to comment.