Skip to content

Commit

Permalink
Merge pull request #3801 from Spaeda/main
Browse files Browse the repository at this point in the history
Get Parameter's PathItems from first child if doesn't exist
  • Loading branch information
baywet authored Dec 7, 2023
2 parents 686fc2d + 6daa2e0 commit bdf094f
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed parsing of `DateOnly` values generated in request executors [#3679](https://github.com/microsoft/kiota/issues/3679)
- Fixes generation of default values names for go constructor functions [#3436](https://github.com/microsoft/kiota/issues/3436)
- [Java] Removed the usage of reflection in `ApiClientBuilder` [`kiota-java#923`](https://github.com/microsoft/kiota-java/issues/923)
- Fixed a bug where path parameter type was not correctly detected during generation. [#3791](https://github.com/microsoft/kiota/issues/3791)

## [1.8.2] - 2023-11-08

Expand Down
23 changes: 21 additions & 2 deletions src/Kiota.Builder/KiotaBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -1080,9 +1081,10 @@ private CodeParameter GetIndexerParameterType(OpenApiUrlTreeNode currentNode, Op
var parameterName = string.Join(OpenAPIUrlTreeNodePathSeparator, currentNode.Path.Split(OpenAPIUrlTreeNodePathSeparator, StringSplitOptions.RemoveEmptyEntries)
.Skip(parentNode.Path.Count(static x => x == OpenAPIUrlTreeNodePathSeparator)))
.Trim(OpenAPIUrlTreeNodePathSeparator, ForwardSlash, '{', '}');
var parameter = currentNode.PathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem) ? pathItem.Parameters
var pathItems = GetPathItems(currentNode);
var parameter = pathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem) ? pathItem.Parameters
.Select(static x => new { Parameter = x, IsPathParameter = true })
.Union(currentNode.PathItems[Constants.DefaultOpenApiLabel].Operations.SelectMany(static x => x.Value.Parameters).Select(static x => new { Parameter = x, IsPathParameter = false }))
.Union(pathItems[Constants.DefaultOpenApiLabel].Operations.SelectMany(static x => x.Value.Parameters).Select(static x => new { Parameter = x, IsPathParameter = false }))
.OrderBy(static x => x.IsPathParameter)
.Select(static x => x.Parameter)
.FirstOrDefault(x => x.Name.Equals(parameterName, StringComparison.OrdinalIgnoreCase) && x.In == ParameterLocation.Path) :
Expand All @@ -1105,6 +1107,23 @@ private CodeParameter GetIndexerParameterType(OpenApiUrlTreeNode currentNode, Op
};
return result;
}
private static IDictionary<string, OpenApiPathItem> GetPathItems(OpenApiUrlTreeNode currentNode, bool validateIsParameterNode = true)
{
if ((!validateIsParameterNode || currentNode.IsParameter) && currentNode.PathItems.Any())
{
return currentNode.PathItems;
}

if (currentNode.Children.Any())
{
return currentNode.Children
.SelectMany(static x => GetPathItems(x.Value, false))
.DistinctBy(static x => x.Key, StringComparer.Ordinal)
.ToDictionary(static x => x.Key, static x => x.Value, StringComparer.Ordinal);
}

return ImmutableDictionary<string, OpenApiPathItem>.Empty;
}
private CodeIndexer[] CreateIndexer(string childIdentifier, string childType, CodeParameter parameter, OpenApiUrlTreeNode currentNode, OpenApiUrlTreeNode parentNode)
{
logger.LogTrace("Creating indexer {Name}", childIdentifier);
Expand Down
109 changes: 91 additions & 18 deletions tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6204,6 +6204,40 @@ public async Task IndexerTypeIsAccurateAndBackwardCompatibleIndexersAreAdded()
application/json:
schema:
$ref: '#/components/schemas/microsoft.graph.post'
/authors/{author-id}/posts:
get:
parameters:
- name: author-id
in: path
required: true
description: The id of the author's posts to retrieve
schema:
type: string
format: uuid
responses:
200:
description: Success!
content:
application/json:
schema:
$ref: '#/components/schemas/microsoft.graph.post'
/actors/{actor-id}/foo/baz:
get:
parameters:
- name: actor-id
in: path
required: true
description: The id of the actor
schema:
type: string
format: uuid
responses:
200:
description: Success!
content:
application/json:
schema:
$ref: '#/components/schemas/microsoft.graph.post'
components:
schemas:
microsoft.graph.post:
Expand All @@ -6218,24 +6252,63 @@ public async Task IndexerTypeIsAccurateAndBackwardCompatibleIndexersAreAdded()
var document = await builder.CreateOpenApiDocumentAsync(fs);
var node = builder.CreateUriSpace(document!);
var codeModel = builder.CreateSourceModel(node);
var collectionRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.me.posts");
Assert.NotNull(collectionRequestBuilderNamespace);
var collectionRequestBuilder = collectionRequestBuilderNamespace.FindChildByName<CodeClass>("postsRequestBuilder");
var collectionIndexer = collectionRequestBuilder.Indexer;
Assert.NotNull(collectionIndexer);
Assert.Equal("integer", collectionIndexer.IndexParameter.Type.Name);
Assert.Equal("The id of the pet to retrieve", collectionIndexer.IndexParameter.Documentation.Description, StringComparer.OrdinalIgnoreCase);
Assert.False(collectionIndexer.IndexParameter.Type.IsNullable);
Assert.False(collectionIndexer.Deprecation.IsDeprecated);
var collectionStringIndexer = collectionRequestBuilder.FindChildByName<CodeIndexer>($"{collectionIndexer.Name}-string");
Assert.NotNull(collectionStringIndexer);
Assert.Equal("string", collectionStringIndexer.IndexParameter.Type.Name);
Assert.True(collectionStringIndexer.IndexParameter.Type.IsNullable);
Assert.True(collectionStringIndexer.Deprecation.IsDeprecated);
var itemRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.me.posts.item");
Assert.NotNull(itemRequestBuilderNamespace);
var itemRequestBuilder = itemRequestBuilderNamespace.FindChildByName<CodeClass>("postItemRequestBuilder");
Assert.Equal(collectionIndexer.ReturnType.Name, itemRequestBuilder.Name);

var postsCollectionRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.me.posts");
Assert.NotNull(postsCollectionRequestBuilderNamespace);
var postsCollectionRequestBuilder = postsCollectionRequestBuilderNamespace.FindChildByName<CodeClass>("postsRequestBuilder");
var postsCollectionIndexer = postsCollectionRequestBuilder.Indexer;
Assert.NotNull(postsCollectionIndexer);
Assert.Equal("integer", postsCollectionIndexer.IndexParameter.Type.Name);
Assert.Equal("The id of the pet to retrieve", postsCollectionIndexer.IndexParameter.Documentation.Description, StringComparer.OrdinalIgnoreCase);
Assert.False(postsCollectionIndexer.IndexParameter.Type.IsNullable);
Assert.False(postsCollectionIndexer.Deprecation.IsDeprecated);
var postsCollectionStringIndexer = postsCollectionRequestBuilder.FindChildByName<CodeIndexer>($"{postsCollectionIndexer.Name}-string");
Assert.NotNull(postsCollectionStringIndexer);
Assert.Equal("string", postsCollectionStringIndexer.IndexParameter.Type.Name);
Assert.True(postsCollectionStringIndexer.IndexParameter.Type.IsNullable);
Assert.True(postsCollectionStringIndexer.Deprecation.IsDeprecated);
var postsItemRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.me.posts.item");
Assert.NotNull(postsItemRequestBuilderNamespace);
var postsItemRequestBuilder = postsItemRequestBuilderNamespace.FindChildByName<CodeClass>("postItemRequestBuilder");
Assert.Equal(postsCollectionIndexer.ReturnType.Name, postsItemRequestBuilder.Name);

var authorsCollectionRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.authors");
Assert.NotNull(authorsCollectionRequestBuilderNamespace);
var authorsCollectionRequestBuilder = authorsCollectionRequestBuilderNamespace.FindChildByName<CodeClass>("authorsRequestBuilder");
var authorsCollectionIndexer = authorsCollectionRequestBuilder.Indexer;
Assert.NotNull(authorsCollectionIndexer);
Assert.Equal("Guid", authorsCollectionIndexer.IndexParameter.Type.Name);
Assert.Equal("The id of the author's posts to retrieve", authorsCollectionIndexer.IndexParameter.Documentation.Description, StringComparer.OrdinalIgnoreCase);
Assert.False(authorsCollectionIndexer.IndexParameter.Type.IsNullable);
Assert.False(authorsCollectionIndexer.Deprecation.IsDeprecated);
var authorsCllectionStringIndexer = authorsCollectionRequestBuilder.FindChildByName<CodeIndexer>($"{authorsCollectionIndexer.Name}-string");
Assert.NotNull(authorsCllectionStringIndexer);
Assert.Equal("string", authorsCllectionStringIndexer.IndexParameter.Type.Name);
Assert.True(authorsCllectionStringIndexer.IndexParameter.Type.IsNullable);
Assert.True(authorsCllectionStringIndexer.Deprecation.IsDeprecated);
var authorsItemRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.authors.item");
Assert.NotNull(authorsItemRequestBuilderNamespace);
var authorsItemRequestBuilder = authorsItemRequestBuilderNamespace.FindChildByName<CodeClass>("authorItemRequestBuilder");
Assert.Equal(authorsCollectionIndexer.ReturnType.Name, authorsItemRequestBuilder.Name);

var actorsCollectionRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.actors");
Assert.NotNull(actorsCollectionRequestBuilderNamespace);
var actorsCollectionRequestBuilder = actorsCollectionRequestBuilderNamespace.FindChildByName<CodeClass>("actorsRequestBuilder");
var actorsCollectionIndexer = actorsCollectionRequestBuilder.Indexer;
Assert.NotNull(actorsCollectionIndexer);
Assert.Equal("Guid", actorsCollectionIndexer.IndexParameter.Type.Name);
Assert.Equal("The id of the actor", actorsCollectionIndexer.IndexParameter.Documentation.Description, StringComparer.OrdinalIgnoreCase);
Assert.False(actorsCollectionIndexer.IndexParameter.Type.IsNullable);
Assert.False(actorsCollectionIndexer.Deprecation.IsDeprecated);
var actorsCllectionStringIndexer = actorsCollectionRequestBuilder.FindChildByName<CodeIndexer>($"{actorsCollectionIndexer.Name}-string");
Assert.NotNull(actorsCllectionStringIndexer);
Assert.Equal("string", actorsCllectionStringIndexer.IndexParameter.Type.Name);
Assert.True(actorsCllectionStringIndexer.IndexParameter.Type.IsNullable);
Assert.True(actorsCllectionStringIndexer.Deprecation.IsDeprecated);
var actorsItemRequestBuilderNamespace = codeModel.FindNamespaceByName("ApiSdk.actors.item");
Assert.NotNull(actorsItemRequestBuilderNamespace);
var actorsItemRequestBuilder = actorsItemRequestBuilderNamespace.FindChildByName<CodeClass>("actorItemRequestBuilder");
Assert.Equal(actorsCollectionIndexer.ReturnType.Name, actorsItemRequestBuilder.Name);
}
[Fact]
public async Task MapsBooleanEnumToBooleanType()
Expand Down

0 comments on commit bdf094f

Please sign in to comment.