From a05d6de848fe1f7174137bdc43ce696980cef310 Mon Sep 17 00:00:00 2001 From: Emond Papegaaij Date: Wed, 14 Jun 2023 21:51:01 +0200 Subject: [PATCH 1/2] Add testcases for allOf cases --- .../Kiota.Builder.Tests/KiotaBuilderTests.cs | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 1b4f362a23..a2e892280c 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -6969,4 +6969,116 @@ public async Task ComplexInheritanceStructures() Assert.NotNull(classificationPrimerClass); Assert.Single(classificationPrimerClass.Properties.Where(static x => x.Name.Equals("name", StringComparison.OrdinalIgnoreCase))); } + [Fact] + public async Task InheritanceWithAllOfInBaseType() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await using var fs = await GetDocumentStream(@"openapi: 3.0.1 +info: + title: OData Service for namespace microsoft.graph + description: This OData service is located at https://graph.microsoft.com/v1.0 + version: 1.0.1 +servers: + - url: https://graph.microsoft.com/v1.0 +paths: + /directoryObject: + get: + responses: + '200': + description: Example response + content: + application/json: + schema: + $ref: '#/components/schemas/microsoft.graph.directoryObject' +components: + schemas: + microsoft.graph.directoryObject: + allOf: + - title: 'directoryObject' + required: ['@odata.type'] + type: 'object' + properties: + '@odata.type': + type: 'string' + default: '#microsoft.graph.directoryObject' + discriminator: + propertyName: '@odata.type' + mapping: + '#microsoft.graph.user': '#/components/schemas/microsoft.graph.user' + '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group' + microsoft.graph.group: + allOf: + - '$ref': '#/components/schemas/microsoft.graph.directoryObject' + - title: 'group' + type: 'object' + properties: + groupprop: + type: 'string'"); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + Assert.NotNull(codeModel.FindChildByName("Group")); + } + [Fact] + public async Task InheritanceWithAllOfWith3Parts() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await using var fs = await GetDocumentStream(@"openapi: 3.0.1 +info: + title: OData Service for namespace microsoft.graph + description: This OData service is located at https://graph.microsoft.com/v1.0 + version: 1.0.1 +servers: + - url: https://graph.microsoft.com/v1.0 +paths: + /directoryObject: + get: + responses: + '200': + description: Example response + content: + application/json: + schema: + $ref: '#/components/schemas/microsoft.graph.directoryObject' +components: + schemas: + microsoft.graph.directoryObject: + title: 'directoryObject' + required: ['@odata.type'] + type: 'object' + properties: + '@odata.type': + type: 'string' + default: '#microsoft.graph.directoryObject' + discriminator: + propertyName: '@odata.type' + mapping: + '#microsoft.graph.user': '#/components/schemas/microsoft.graph.user' + '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group' + microsoft.graph.group: + allOf: + - '$ref': '#/components/schemas/microsoft.graph.directoryObject' + - title: 'group part 1' + type: 'object' + properties: + groupprop1: + type: 'string' + - title: 'group part 2' + type: 'object' + properties: + groupprop2: + type: 'string'"); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + var resultClass = codeModel.FindChildByName("Group"); + Assert.NotNull(resultClass); + Assert.Equal(2, resultClass.Properties.Count()); + Assert.Single(resultClass.Properties.Where(x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase))); + Assert.Single(resultClass.Properties.Where(x => x.Name.Equals("groupprop2", StringComparison.OrdinalIgnoreCase))); + } } From 76ea4a575e87e3fecc1d46992e11c3c22870b676 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 2 Oct 2023 14:21:59 -0400 Subject: [PATCH 2/2] - fixes a bug where nested all of would derail inheritance Signed-off-by: Vincent Biret --- .../Extensions/OpenApiSchemaExtensions.cs | 10 ++++++---- tests/Kiota.Builder.Tests/KiotaBuilderTests.cs | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index 527be4cdd3..25c9074324 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -32,7 +32,8 @@ public static IEnumerable GetSchemaNames(this OpenApiSchema schema) } internal static IEnumerable FlattenSchemaIfRequired(this IList schemas, Func> subsequentGetter) { - return schemas.Count == 1 && string.IsNullOrEmpty(schemas[0].Title) ? + if (schemas is null) return Enumerable.Empty(); + return schemas.Count == 1 ? schemas.FlattenEmptyEntries(subsequentGetter, 1) : schemas; } @@ -74,8 +75,9 @@ public static bool IsInclusiveUnion(this OpenApiSchema? schema) public static bool IsInherited(this OpenApiSchema? schema) { - var meaningfulSchemas = schema?.AllOf?.Where(IsSemanticallyMeaningful); - return meaningfulSchemas?.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) == 1 && meaningfulSchemas.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) == 1; + if (schema is null) return false; + var meaningfulSchemas = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf).Where(IsSemanticallyMeaningful).ToArray(); + return meaningfulSchemas.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) == 1 && meaningfulSchemas.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) == 1; } internal static OpenApiSchema? MergeIntersectionSchemaEntries(this OpenApiSchema? schema) @@ -99,7 +101,7 @@ public static bool IsExclusiveUnion(this OpenApiSchema? schema) { return schema?.OneOf?.Count(IsSemanticallyMeaningful) > 1; } - private static readonly HashSet oDataTypes = new() { + private static readonly HashSet oDataTypes = new(StringComparer.OrdinalIgnoreCase) { "number", "integer", }; diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index a2e892280c..b6b0eaac4f 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -6993,6 +6993,7 @@ public async Task InheritanceWithAllOfInBaseType() components: schemas: microsoft.graph.directoryObject: + type: object allOf: - title: 'directoryObject' required: ['@odata.type']