From 34d69d915603c99b03d8549fe54925ca112e609f Mon Sep 17 00:00:00 2001 From: Markus Friesen Date: Thu, 6 Jul 2023 12:19:08 +0200 Subject: [PATCH] Swtich reference id type names and remove underscore for dictionary and list to comply OpenApi Spec --- .../Extensions/TypeExtensions.cs | 10 ++-- .../FakeFunctions.cs | 5 ++ .../FakeOtherGenericModel.cs | 9 ++++ .../DocumentHelperTests.cs | 48 ++++++++++++------- .../DictionaryObjectTypeVisitorTests.cs | 2 +- 5 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeOtherGenericModel.cs diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs index cf2a7b6f..e061583b 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs @@ -402,19 +402,19 @@ public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bo if (isDictionary) { - var name = type.Name.EndsWith("[]") ? "Dictionary_" + type.GetOpenApiSubTypeName(namingStrategy) : type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy); + var name = type.Name.EndsWith("[]") ? type.GetOpenApiSubTypeName(namingStrategy) + "Dictionary" : type.GetOpenApiSubTypeName(namingStrategy) + type.Name.Split('`').First(); return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } if (isList) { - var name = type.Name.EndsWith("[]") ? "List_" + type.GetOpenApiSubTypeName(namingStrategy) : type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy); + var name = type.Name.EndsWith("[]") ? type.GetOpenApiSubTypeName(namingStrategy) + "List" : type.GetOpenApiSubTypeName(namingStrategy) + type.Name.Split('`').First(); return namingStrategy.GetPropertyName(name, hasSpecifiedName: false); } if (type.IsGenericType) { - return namingStrategy.GetPropertyName(type.Name.Split('`').First(), false) + "_" + - string.Join("_", type.GenericTypeArguments.Select(a => namingStrategy.GetPropertyName(a.Name, false))); + return namingStrategy.GetPropertyName(type.Name.Split('`').First(), false) + + string.Concat( type.GenericTypeArguments.Select(a => namingStrategy.GetPropertyName(a.Name, false))); } return namingStrategy.GetPropertyName(type.Name, hasSpecifiedName: false); @@ -460,7 +460,7 @@ public static Type GetUnderlyingType(this Type type) } if (type.IsOpenApiArray()) - { + { underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0]; } diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeFunctions.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeFunctions.cs index 0fa131d1..fd540008 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeFunctions.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeFunctions.cs @@ -35,5 +35,10 @@ public static void GenericMethodOne() public static void GenericMethodTwo() { } + + [OpenApiRequestBody(contentType: "application/json", bodyType: typeof(FakeOtherGenericModel), Required = true, Description = "Fake list model")] + public static void GenericMethodThree() + { + } } } diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeOtherGenericModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeOtherGenericModel.cs new file mode 100644 index 00000000..137e2652 --- /dev/null +++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeOtherGenericModel.cs @@ -0,0 +1,9 @@ +namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes +{ + public class FakeOtherGenericModel + { + public string Name { get; set; } + public T1 FirstValue { get; set; } + public T2 SecondValue { get; set; } + } +} diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs index f89246db..e86a52d2 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/DocumentHelperTests.cs @@ -41,7 +41,7 @@ public void GetOpenApiSchemas_Result_Should_Contain_Schema_For_Function_Classes( var schemas = documentHelper.GetOpenApiSchemas(methods, namingStrategy, visitorCollection); schemas.Should().NotBeNull(); - schemas.Count.Should().Be(6); + schemas.Count.Should().Be(7); schemas.Should().ContainKey("FakeClassModel"); @@ -65,23 +65,35 @@ public void GetOpenApiSchemas_Result_Should_Contain_Schema_For_Function_Classes( schemas["FakeStringModel"].Properties.Count.Should().Be(2); schemas["FakeStringModel"].Type.Should().Be("object"); - schemas.Should().ContainKey("FakeGenericModel_FakeClassModel"); - - schemas["FakeGenericModel_FakeClassModel"].Properties.Count.Should().Be(2); - schemas["FakeGenericModel_FakeClassModel"].Type.Should().Be("object"); - schemas["FakeGenericModel_FakeClassModel"].Properties.Should().ContainKey("Name"); - schemas["FakeGenericModel_FakeClassModel"].Properties.Should().ContainKey("Value"); - schemas["FakeGenericModel_FakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Number"); - schemas["FakeGenericModel_FakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Text"); - - schemas.Should().ContainKey("FakeGenericModel_FakeOtherClassModel"); - - schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Count.Should().Be(2); - schemas["FakeGenericModel_FakeOtherClassModel"].Type.Should().Be("object"); - schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Should().ContainKey("Name"); - schemas["FakeGenericModel_FakeOtherClassModel"].Properties.Should().ContainKey("Value"); - schemas["FakeGenericModel_FakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("FirstName"); - schemas["FakeGenericModel_FakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("LastName"); + schemas.Should().ContainKey("FakeGenericModelFakeClassModel"); + + schemas["FakeGenericModelFakeClassModel"].Properties.Count.Should().Be(2); + schemas["FakeGenericModelFakeClassModel"].Type.Should().Be("object"); + schemas["FakeGenericModelFakeClassModel"].Properties.Should().ContainKey("Name"); + schemas["FakeGenericModelFakeClassModel"].Properties.Should().ContainKey("Value"); + schemas["FakeGenericModelFakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Number"); + schemas["FakeGenericModelFakeClassModel"].Properties["Value"].Properties.Should().ContainKey("Text"); + + schemas.Should().ContainKey("FakeGenericModelFakeOtherClassModel"); + + schemas["FakeGenericModelFakeOtherClassModel"].Properties.Count.Should().Be(2); + schemas["FakeGenericModelFakeOtherClassModel"].Type.Should().Be("object"); + schemas["FakeGenericModelFakeOtherClassModel"].Properties.Should().ContainKey("Name"); + schemas["FakeGenericModelFakeOtherClassModel"].Properties.Should().ContainKey("Value"); + schemas["FakeGenericModelFakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("FirstName"); + schemas["FakeGenericModelFakeOtherClassModel"].Properties["Value"].Properties.Should().ContainKey("LastName"); + + schemas.Should().ContainKey("FakeOtherGenericModelFakeClassModelFakeOtherClassModel"); + + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties.Count.Should().Be(3); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Type.Should().Be("object"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties.Should().ContainKey("Name"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties.Should().ContainKey("FirstValue"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties.Should().ContainKey("SecondValue"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties["FirstValue"].Properties.Should().ContainKey("Number"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties["FirstValue"].Properties.Should().ContainKey("Text"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties["SecondValue"].Properties.Should().ContainKey("FirstName"); + schemas["FakeOtherGenericModelFakeClassModelFakeOtherClassModel"].Properties["SecondValue"].Properties.Should().ContainKey("LastName"); } [TestMethod] diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs index 29615b4a..4aac43b2 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests/Visitors/DictionaryObjectTypeVisitorTests.cs @@ -91,7 +91,7 @@ public void Given_Type_When_IsPayloadVisitable_Invoked_Then_It_Should_Return_Res [DataRow(typeof(IReadOnlyDictionary), "object", null, "string", false, "string", 0)] [DataRow(typeof(KeyValuePair), "object", null, "string", false, "string", 0)] [DataRow(typeof(Dictionary), "object", null, "object", true, "fakeModel", 1)] - [DataRow(typeof(Dictionary), "object", null, "array", true, "list_string", 1)] // + [DataRow(typeof(Dictionary), "object", null, "array", true, "stringList", 1)] // [DataRow(typeof(IDictionary), "object", null, "object", true, "fakeModel", 1)] [DataRow(typeof(IReadOnlyDictionary), "object", null, "object", true, "fakeModel", 1)] [DataRow(typeof(KeyValuePair), "object", null, "object", true, "fakeModel", 1)]