diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f008adb45..c717546586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bug where TypeScript deserialization would fail on Uppercase properties.[#4479](https://github.com/microsoft/kiota/issues/4479) - Changed URI template generation to reuse templates when required templates are absent across operations. - Updated reserved name providers for Java and Php so that "object" can be escaped. +- Fixes request builder disambiguation when child nodes had different prefixes for different paths with same parameters.[#4448](https://github.com/microsoft/kiota/issues/4448) - Do not generate CS8603 warnings when enabling backing store in CSharp generation. ## [1.13.0] - 2024-04-04 diff --git a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs index ba925d728b..c90136b87f 100644 --- a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs @@ -40,7 +40,7 @@ public static string GetNodeNamespaceFromPath(this OpenApiUrlTreeNode currentNod return currentNode.Path.GetNamespaceFromPath(prefix); } //{id}, name(idParam={id}), name(idParam='{id}'), name(idParam='{id}',idParam2='{id2}') - [GeneratedRegex(@"(?:\w+)?=?'?\{(?\w+)\}'?,?", RegexOptions.Singleline, 500)] + [GeneratedRegex(@"(?\w+)?(?=?)'?\{(?\w+)\}'?,?", RegexOptions.Singleline, 500)] private static partial Regex PathParametersRegex(); // microsoft.graph.getRoleScopeTagsByIds(ids=@ids) [GeneratedRegex(@"=@(\w+)", RegexOptions.Singleline, 500)] @@ -51,8 +51,10 @@ public static string GetNodeNamespaceFromPath(this OpenApiUrlTreeNode currentNod private const string RequestParametersSectionEndChar = ")"; private const string WithKeyword = "With"; private static readonly MatchEvaluator requestParametersMatchEvaluator = match => - WithKeyword + match.Groups["paramName"].Value.ToFirstCharacterUpperCase(); - private static string CleanupParametersFromPath(string pathSegment) + string.IsNullOrEmpty(match.Groups["equals"].Value) ? + match.Groups["prefix"].Value + WithKeyword + match.Groups["paramName"].Value.ToFirstCharacterUpperCase() : + WithKeyword + match.Groups["paramName"].Value.ToFirstCharacterUpperCase(); + internal static string CleanupParametersFromPath(string pathSegment) { if (string.IsNullOrEmpty(pathSegment)) return pathSegment; diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 5b7c2b6f0f..e067f7157e 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -705,7 +705,7 @@ private static void AddPathParametersToMethod(OpenApiUrlTreeNode currentNode, Co Optional = asOptional, Documentation = new() { - DescriptionTemplate = parameter.Description.CleanupDescription(), + DescriptionTemplate = !string.IsNullOrEmpty(parameter.Description) ? parameter.Description.CleanupDescription() : $"The path parameter: {codeName}", }, Kind = CodeParameterKind.Path, SerializationName = parameter.Name.Equals(codeName, StringComparison.OrdinalIgnoreCase) ? string.Empty : parameter.Name.SanitizeParameterNameForUrlTemplate(), diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs index dba74a113f..99fa6e6662 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs @@ -1072,6 +1072,23 @@ public void repro4085() Assert.Equal("\\path\\{differentThingId-id}", differentThingId.Path); Assert.Equal("{+baseurl}/path/{differentThingId%2Did}", differentThingId.GetUrlTemplate()); } + + [Theory] + [InlineData("{path}", "WithPath")] + [InlineData("archived{path}", "archivedWithPath")] + [InlineData("files{path}", "filesWithPath")] + [InlineData("name(idParam='{id}')", "nameWithId")] + [InlineData("name(idParam={id})", "nameWithId")] + [InlineData("name(idParamFoo={id})", "nameWithId")] // The current implementation only uses the placeholder i.e {id} for the naming to ignore `idParamFoo` + // and thus generates the same identifier as the previous case. This collision risk is unlikely and constrained to an odata service scenario + // which would be invalid for functions scenario(overloads with the same parameters)) + [InlineData("name(idParam='{id}',idParam2='{id2}')", "nameWithIdWithId2")] + public void CleanupParametersFromPathGeneratesDifferentResultsWithPrefixPresent(string segmentName, string expectedIdentifer) + { + var result = OpenApiUrlTreeNodeExtensions.CleanupParametersFromPath(segmentName); + Assert.Equal(expectedIdentifer, result); + } + private static OpenApiUrlTreeNode GetChildNodeByPath(OpenApiUrlTreeNode node, string path) { var pathSegments = path.Split('/');