From 329c3e8b118af7f3bc48b604f0a952f1435a43d5 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 1 Oct 2024 15:52:57 +0300 Subject: [PATCH 1/2] Fixes incorrect type mapping --- CHANGELOG.md | 1 + src/Kiota.Builder/KiotaBuilder.cs | 5 +- .../Kiota.Builder.Tests/KiotaBuilderTests.cs | 68 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a36d356c..b18d01bcdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated schema link in plugin manifest to the correct url. [#5441](https://github.com/microsoft/kiota/issues/5441) - Removed registration of default serialization and deserialization classes in client constructor. [#5478](https://github.com/microsoft/kiota/pull/5478) - Fixed incorrect type name generation in aliased scenario in TS due to broad searching of types in root namespaces. [#5404](https://github.com/microsoft/kiota/issues/5404) +- Fixed incorrect type mapping in request builders with subsequent paths with the same name. [#5462](https://github.com/microsoft/kiota/issues/5462) ## [1.18.0] - 2024-09-05 diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 4978a47ec5..66176e81c8 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -955,8 +955,11 @@ x.Parent is CodeIndexer || Parallel.ForEach(unmappedRequestBuilderTypes, parallelOptions, x => { + var parentClass = x.Parent?.Parent as CodeClass; var parentNS = x.Parent?.Parent?.Parent as CodeNamespace; - x.TypeDefinition = parentNS?.FindChildrenByName(x.Name).MinBy(shortestNamespaceOrder); + x.TypeDefinition = parentNS?.FindChildrenByName(x.Name) + .Except([parentClass]).OfType() // the property method should not reference itself as a return type. + .MinBy(shortestNamespaceOrder); // searching down first because most request builder properties on a request builder are just sub paths on the API if (x.TypeDefinition == null) { diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index a38146b19a..6b17ad738e 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -231,6 +231,74 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 Assert.NotNull(specializedNS.FindChildByName("StorageAccount", false)); } [Fact] + public async Task HandlesPathWithRepeatedSegment() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await File.WriteAllTextAsync(tempFilePath, @$"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://api.funtranslations.com +paths: + /media/response/response/{{id}}: + get: + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/MediaResponseModel' +components: + schemas: + MediaResponseModel: + type: object + properties: + name: + type: string + id: + type: string + format: uuid + mediaType: + type: string + url: + type: string"); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration + { + ClientClassName = "Graph", + OpenAPIFilePath = "https://api.apis.guru/v2/specs/funtranslations.com/starwars/2.3/swagger.json" + }, _httpClient); + await using var fs = new FileStream(tempFilePath, FileMode.Open); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + builder.SetApiRootUrl(); + var codeModel = builder.CreateSourceModel(node); + var rootNS = codeModel.FindNamespaceByName("ApiSdk"); + Assert.NotNull(rootNS); + var responseBuilderNs = codeModel.FindNamespaceByName("ApiSdk.media.response"); + Assert.NotNull(responseBuilderNs); + var responseRequestBuilder = responseBuilderNs.FindChildByName("ResponseRequestBuilder", false); + Assert.NotNull(responseRequestBuilder); + var navigationProperty = responseRequestBuilder.Properties.FirstOrDefault(prop => + prop.IsOfKind(CodePropertyKind.RequestBuilder) && + prop.Name.Equals("Response", StringComparison.OrdinalIgnoreCase)); + Assert.NotNull(navigationProperty); + var navigationPropertyType = navigationProperty.Type as CodeType; + Assert.NotNull(navigationPropertyType); + Assert.NotEqual(responseRequestBuilder, navigationPropertyType.TypeDefinition);// the request builder should not be the same as the class it is in. + var nestedResponseBuilderNs = codeModel.FindNamespaceByName("ApiSdk.media.response.response"); + var nestedResponseRequestBuilder = nestedResponseBuilderNs.FindChildByName("ResponseRequestBuilder", false); + Assert.Equal(nestedResponseRequestBuilder, navigationPropertyType.TypeDefinition);// the request builder should not be the same as the class it is in. + } + [Fact] public async Task HandlesPathWithItemInNameSegment() { var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); From 8580374a50720a3056004b69e5052ccddab7917e Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 1 Oct 2024 16:46:28 +0300 Subject: [PATCH 2/2] adds nullable checks. --- src/Kiota.Builder/KiotaBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 66176e81c8..d575562412 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -955,10 +955,10 @@ x.Parent is CodeIndexer || Parallel.ForEach(unmappedRequestBuilderTypes, parallelOptions, x => { - var parentClass = x.Parent?.Parent as CodeClass; var parentNS = x.Parent?.Parent?.Parent as CodeNamespace; + CodeClass[] exceptions = x.Parent?.Parent is CodeClass parentClass ? [parentClass] : []; x.TypeDefinition = parentNS?.FindChildrenByName(x.Name) - .Except([parentClass]).OfType() // the property method should not reference itself as a return type. + .Except(exceptions)// the property method should not reference itself as a return type. .MinBy(shortestNamespaceOrder); // searching down first because most request builder properties on a request builder are just sub paths on the API if (x.TypeDefinition == null)