diff --git a/CHANGELOG.md b/CHANGELOG.md index eba65dc8d8..61d16f3e3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - PREVIEW: Moved the copy descriptions to dedicated folders. [#4310](https://github.com/microsoft/kiota/issues/4310) - PREVIEW: Renamed the config to workspace file. [#4310](https://github.com/microsoft/kiota/issues/4310) - Changed Csharp code generation to put braces on new lines (where it makes sense). [#4347](https://github.com/microsoft/kiota/issues/4347) +- Fixed a bug where some no-content status codes would be considered structured (301, 302, 303, 307) when described. [#4190](https://github.com/microsoft/kiota/issues/4190) ## [1.12.0] - 2024-03-06 diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index b9ae9bf50d..5a39f14fe6 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1083,7 +1083,7 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten }; } private const string RequestBodyPlainTextContentType = "text/plain"; - private static readonly HashSet noContentStatusCodes = new(StringComparer.OrdinalIgnoreCase) { "201", "202", "204", "205" }; + private static readonly HashSet noContentStatusCodes = new(StringComparer.OrdinalIgnoreCase) { "201", "202", "204", "205", "301", "302", "303", "304", "307" }; private static readonly HashSet errorStatusCodes = new(Enumerable.Range(400, 599).Select(static x => x.ToString(CultureInfo.InvariantCulture)) .Concat([CodeMethod.ErrorMappingClientRange, CodeMethod.ErrorMappingServerRange]), StringComparer.OrdinalIgnoreCase); private void AddErrorMappingsForExecutorMethod(OpenApiUrlTreeNode currentNode, OpenApiOperation operation, CodeMethod executorMethod) diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 99ea0c4769..479cc319e3 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -5334,8 +5334,14 @@ public void Considers204WithNoSchemaOver206WithNoSchema() Assert.NotNull(executor); Assert.Equal("void", executor.ReturnType.Name); } - [Fact] - public void DoesntGenerateVoidExecutorOnMixed204() + [InlineData(204)] + [InlineData(301)] + [InlineData(302)] + [InlineData(303)] + [InlineData(304)] + [InlineData(307)] + [Theory] + public void DoesntGenerateVoidExecutorOnMixedNoContent(int statusCode) { var myObjectSchema = new OpenApiSchema { @@ -5372,7 +5378,7 @@ public void DoesntGenerateVoidExecutorOnMixed204() } } }, - ["204"] = new OpenApiResponse(), + [statusCode.ToString()] = new OpenApiResponse(), } } } @@ -5400,6 +5406,77 @@ public void DoesntGenerateVoidExecutorOnMixed204() Assert.NotNull(executor); Assert.NotEqual("void", executor.ReturnType.Name); } + [InlineData(204)] + [InlineData(301)] + [InlineData(302)] + [InlineData(303)] + [InlineData(304)] + [InlineData(307)] + [Theory] + public void GeneratesVoidReturnTypeForNoContent(int statusCode) + { + var myObjectSchema = new OpenApiSchema + { + Type = "object", + Properties = new Dictionary { + { + "id", new OpenApiSchema { + Type = "string", + } + } + }, + Reference = new OpenApiReference + { + Id = "myobject", + Type = ReferenceType.Schema + }, + UnresolvedReference = false + }; + var document = new OpenApiDocument + { + Paths = new OpenApiPaths + { + ["answer"] = new OpenApiPathItem + { + Operations = { + [OperationType.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses + { + [statusCode.ToString()] = new OpenApiResponse { + Content = { + ["application/json"] = new OpenApiMediaType { + Schema = myObjectSchema + } + } + }, + } + } + } + } + }, + Components = new() + { + Schemas = new Dictionary { + { + "myobject", myObjectSchema + } + } + } + }; + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "TestClient", ClientNamespaceName = "TestSdk", ApiRootUrl = "https://localhost" }, _httpClient); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + var rbNS = codeModel.FindNamespaceByName("TestSdk.Answer"); + Assert.NotNull(rbNS); + var rbClass = rbNS.Classes.FirstOrDefault(x => x.IsOfKind(CodeClassKind.RequestBuilder)); + Assert.NotNull(rbClass); + Assert.Single(rbClass.Methods.Where(x => x.IsOfKind(CodeMethodKind.RequestExecutor))); + var executor = rbClass.Methods.FirstOrDefault(x => x.IsOfKind(CodeMethodKind.RequestExecutor)); + Assert.NotNull(executor); + Assert.Equal("void", executor.ReturnType.Name); + } [InlineData(new[] { "microsoft.graph.user", "microsoft.graph.termstore.term" }, "microsoft.graph")] [InlineData(new[] { "microsoft.graph.user", "odata.errors.error" }, "")] [InlineData(new string[] { }, "")]