Update Swashbuckle and improve generated OpenAPI files (#6066)

* Improve generated OpenAPI files

* Nullable

* Fmt

* Correct powershell command

* Fix name

* Add some tests

* Fmt

* Switch to using json naming policy
This commit is contained in:
Daniel García
2025-08-18 18:40:50 +02:00
committed by GitHub
parent 03327cb082
commit 6971f0a976
20 changed files with 420 additions and 54 deletions

View File

@@ -0,0 +1,60 @@
using Bit.Core.Utilities;
using Bit.SharedWeb.Swagger;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SharedWeb.Test;
public class EncryptedStringSchemaFilterTest
{
private class TestClass
{
[EncryptedString]
public string SecretKey { get; set; }
public string Username { get; set; }
[EncryptedString]
public int Wrong { get; set; }
}
[Fact]
public void AnnotatedStringSetsFormat()
{
var schema = new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema> { { "secretKey", new() } }
};
var context = new SchemaFilterContext(typeof(TestClass), null, null, null);
var filter = new EncryptedStringSchemaFilter();
filter.Apply(schema, context);
Assert.Equal("x-enc-string", schema.Properties["secretKey"].Format);
}
[Fact]
public void NonAnnotatedStringIsIgnored()
{
var schema = new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema> { { "username", new() } }
};
var context = new SchemaFilterContext(typeof(TestClass), null, null, null);
var filter = new EncryptedStringSchemaFilter();
filter.Apply(schema, context);
Assert.Null(schema.Properties["username"].Format);
}
[Fact]
public void AnnotatedWrongTypeIsIgnored()
{
var schema = new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema> { { "wrong", new() } }
};
var context = new SchemaFilterContext(typeof(TestClass), null, null, null);
var filter = new EncryptedStringSchemaFilter();
filter.Apply(schema, context);
Assert.Null(schema.Properties["wrong"].Format);
}
}

View File

@@ -0,0 +1,41 @@
using Bit.SharedWeb.Swagger;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SharedWeb.Test;
public class EnumSchemaFilterTest
{
private enum TestEnum
{
First,
Second,
Third
}
[Fact]
public void SetsEnumVarNamesExtension()
{
var schema = new OpenApiSchema();
var context = new SchemaFilterContext(typeof(TestEnum), null, null, null);
var filter = new EnumSchemaFilter();
filter.Apply(schema, context);
Assert.True(schema.Extensions.ContainsKey("x-enum-varnames"));
var extensions = schema.Extensions["x-enum-varnames"] as OpenApiArray;
Assert.NotNull(extensions);
Assert.Equal(["First", "Second", "Third"], extensions.Select(x => ((OpenApiString)x).Value));
}
[Fact]
public void DoesNotSetExtensionForNonEnum()
{
var schema = new OpenApiSchema();
var context = new SchemaFilterContext(typeof(string), null, null, null);
var filter = new EnumSchemaFilter();
filter.Apply(schema, context);
Assert.False(schema.Extensions.ContainsKey("x-enum-varnames"));
}
}

View File

@@ -0,0 +1,23 @@
using Bit.SharedWeb.Swagger;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SharedWeb.Test;
public class GitCommitDocumentFilterTest
{
[Fact]
public void AddsGitCommitExtensionIfAvailable()
{
var doc = new OpenApiDocument();
var context = new DocumentFilterContext(null, null, null);
var filter = new GitCommitDocumentFilter();
filter.Apply(doc, context);
Assert.True(doc.Extensions.ContainsKey("x-git-commit"));
var ext = doc.Extensions["x-git-commit"] as Microsoft.OpenApi.Any.OpenApiString;
Assert.NotNull(ext);
Assert.False(string.IsNullOrEmpty(ext.Value));
}
}

View File

@@ -0,0 +1 @@
global using Xunit;

View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
<RootNamespace>SharedWeb.Test</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
<PackageReference Include="xunit.runner.visualstudio"
Version="$(XUnitRunnerVisualStudioVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SharedWeb\SharedWeb.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,33 @@
using Bit.SharedWeb.Swagger;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SharedWeb.Test;
public class SourceFileLineOperationFilterTest
{
private class DummyController
{
public void DummyMethod() { }
}
[Fact]
public void AddsSourceFileAndLineExtensionsIfAvailable()
{
var methodInfo = typeof(DummyController).GetMethod(nameof(DummyController.DummyMethod));
var operation = new OpenApiOperation();
var context = new OperationFilterContext(null, null, null, methodInfo);
var filter = new SourceFileLineOperationFilter();
filter.Apply(operation, context);
Assert.True(operation.Extensions.ContainsKey("x-source-file"));
Assert.True(operation.Extensions.ContainsKey("x-source-line"));
var fileExt = operation.Extensions["x-source-file"] as Microsoft.OpenApi.Any.OpenApiString;
var lineExt = operation.Extensions["x-source-line"] as Microsoft.OpenApi.Any.OpenApiInteger;
Assert.NotNull(fileExt);
Assert.NotNull(lineExt);
Assert.Equal(11, lineExt.Value);
Assert.StartsWith("test/SharedWeb.Test/", fileExt.Value);
}
}