From 537754cb2e2c6eca835ff2a4fe832a496b0aa8fe Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 12:04:07 -0700 Subject: [PATCH 1/2] Omit null OpenAPI response descriptions (#3077) * Initial plan fix(openapi): omit null response descriptions Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> * test(models): update response serialization expectation Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> --- .../Models/OpenApiResponse.cs | 8 +++---- .../OpenApiResponseSerializationTests.cs | 22 +++++++++++++++++++ .../Models/OpenApiOperationTests.cs | 4 ---- .../Models/OpenApiResponseTests.cs | 4 +--- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index 6c1af10f1..1f8ad5dd7 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -61,7 +61,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, + private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { Utils.CheckArgumentNull(writer); @@ -69,7 +69,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteStartObject(); // description - writer.WriteRequiredProperty(OpenApiConstants.Description, Description); + writer.WriteProperty(OpenApiConstants.Description, Description); // headers writer.WriteOptionalMap(OpenApiConstants.Headers, Headers, callback); @@ -96,7 +96,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) writer.WriteStartObject(); // description - writer.WriteRequiredProperty(OpenApiConstants.Description, Description); + writer.WriteProperty(OpenApiConstants.Description, Description); var extensionsClone = Extensions is not null ? new Dictionary(Extensions) : null; @@ -153,7 +153,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) // so remove it from the cloned collection so we don't write it again. extensionsClone?.Remove(key); } - } + } } } diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs index 27246fa7e..95a5a6980 100644 --- a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs @@ -1,5 +1,7 @@ using System.IO; using System.Net.Http; +using System.Text.Json.Nodes; +using System.Threading.Tasks; using Moq; using Xunit; @@ -61,5 +63,25 @@ public void SerializeAsV3_DoesNotCallV31OrV2Serialization() _linkMock.Verify(l => l.SerializeAsV31(It.IsAny()), Times.Never); _linkMock.Verify(l => l.SerializeAsV2(It.IsAny()), Times.Never); } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi2_0)] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + [InlineData(OpenApiSpecVersion.OpenApi3_1)] + [InlineData(OpenApiSpecVersion.OpenApi3_2)] + public async Task SerializeResponseWithoutDescriptionAsJsonDoesNotWriteNullDescription(OpenApiSpecVersion specVersion) + { + // Arrange + var response = new OpenApiResponse(); + + // Act + var actual = await response.SerializeAsJsonAsync(specVersion, TestContext.Current.CancellationToken); + + // Assert + var node = JsonNode.Parse(actual); + Assert.NotNull(node); + var responseObject = Assert.IsType(node); + Assert.False(responseObject.ContainsKey(OpenApiConstants.Description)); + } } } diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs index 6fb63c719..a3edc36f7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs @@ -343,7 +343,6 @@ public async Task SerializeOperationWithBodyAsV3JsonWorks() "$ref": "#/components/responses/response1" }, "400": { - "description": null, "content": { "application/json": { "schema": { @@ -416,7 +415,6 @@ public async Task SerializeAdvancedOperationWithTagAndSecurityAsV3JsonWorks() "$ref": "#/components/responses/response1" }, "400": { - "description": null, "content": { "application/json": { "schema": { @@ -648,7 +646,6 @@ public async Task SerializeOperationWithBodyAsV2JsonWorks() "$ref": "#/responses/response1" }, "400": { - "description": null, "schema": { "type": "number", "maximum": 10, @@ -718,7 +715,6 @@ public async Task SerializeAdvancedOperationWithTagAndSecurityAsV2JsonWorks() "$ref": "#/responses/response1" }, "400": { - "description": null, "schema": { "type": "number", "maximum": 10, diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index 83e321975..74b1e2a77 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -176,9 +176,7 @@ public async Task SerializeBasicResponseWorks( string format) { // Arrange - var expected = format == OpenApiConstants.Json ? @"{ - ""description"": null -}" : @"description: null"; + var expected = @"{ }"; // Act var actual = await BasicResponse.SerializeAsync(version, format, TestContext.Current.CancellationToken); From 33daae2a2dac97fa449633631f6afb9b0260115a Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 11 Sep 2026 15:11:24 -0400 Subject: [PATCH 2/2] chore: fixes wrong merge Signed-off-by: Vincent Biret --- .../Mocks/OpenApiResponseSerializationTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs index 95a5a6980..7d3e2a86e 100644 --- a/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Mocks/OpenApiResponseSerializationTests.cs @@ -68,7 +68,6 @@ public void SerializeAsV3_DoesNotCallV31OrV2Serialization() [InlineData(OpenApiSpecVersion.OpenApi2_0)] [InlineData(OpenApiSpecVersion.OpenApi3_0)] [InlineData(OpenApiSpecVersion.OpenApi3_1)] - [InlineData(OpenApiSpecVersion.OpenApi3_2)] public async Task SerializeResponseWithoutDescriptionAsJsonDoesNotWriteNullDescription(OpenApiSpecVersion specVersion) { // Arrange