From d7cbf6426b6dfc6c5673e8d2c3bd416f17dc6d5c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 11:52:30 +0000 Subject: [PATCH 01/10] Initial plan From 855a4a8a7a3bb2d62b9ed76e62a3fa6193932259 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 12:03:37 +0000 Subject: [PATCH 02/10] Add Summary support to OpenApiResponse with serialization/deserialization Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> --- .../Models/OpenApiResponse.cs | 18 +++- .../Reader/V3/OpenApiResponseDeserializer.cs | 12 ++- .../Reader/V31/OpenApiResponseDeserializer.cs | 12 ++- .../Reader/V32/OpenApiResponseDeserializer.cs | 6 ++ .../V3Tests/OpenApiResponseTests.cs | 24 +++++ .../OpenApiResponse/responseWithSummary.yaml | 16 +++ .../responseWithSummaryExtension.yaml | 16 +++ .../Models/OpenApiResponseTests.cs | 102 ++++++++++++++++++ 8 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummary.yaml create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummaryExtension.yaml diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index e15ea5742..6b1c851cf 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -10,8 +10,11 @@ namespace Microsoft.OpenApi /// /// Response object. /// - public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse + public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse, IOpenApiSummarizedElement { + /// + public string? Summary { get; set; } + /// public string? Description { get; set; } @@ -38,6 +41,7 @@ public OpenApiResponse() { } internal OpenApiResponse(IOpenApiResponse response) { Utils.CheckArgumentNull(response); + Summary = (response as IOpenApiSummarizedElement)?.Summary ?? Summary; Description = response.Description ?? Description; Headers = response.Headers != null ? new Dictionary(response.Headers) : null; Content = response.Content != null ? new Dictionary(response.Content) : null; @@ -76,6 +80,12 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteStartObject(); + // summary - only for v3.2+ + if (version >= OpenApiSpecVersion.OpenApi3_2) + { + writer.WriteProperty(OpenApiConstants.Summary, Summary); + } + // description writer.WriteRequiredProperty(OpenApiConstants.Description, Description); @@ -88,6 +98,12 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version // links writer.WriteOptionalMap(OpenApiConstants.Links, Links, callback); + // summary as extension for v3.1 and earlier + if (version < OpenApiSpecVersion.OpenApi3_2 && !string.IsNullOrEmpty(Summary)) + { + writer.WriteProperty(OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.Summary, Summary); + } + // extension writer.WriteExtensions(Extensions, version); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs index a2f4318ba..d251a1992 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs @@ -34,7 +34,17 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _responsePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + { + if (p.Equals("x-oai-summary", StringComparison.OrdinalIgnoreCase)) + { + o.Summary = n.GetScalarValue(); + } + else + { + o.AddExtension(p, LoadExtension(p,n)); + } + }} }; public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs index d25603126..d00b3eb80 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs @@ -39,7 +39,17 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _responsePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + { + if (p.Equals("x-oai-summary", StringComparison.OrdinalIgnoreCase)) + { + o.Summary = n.GetScalarValue(); + } + else + { + o.AddExtension(p, LoadExtension(p,n)); + } + }} }; public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs index eec9a03d1..a6020991b 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs @@ -10,6 +10,12 @@ internal static partial class OpenApiV32Deserializer { private static readonly FixedFieldMap _responseFixedFields = new() { + { + "summary", (o, n, _) => + { + o.Summary = n.GetScalarValue(); + } + }, { "description", (o, n, _) => { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs index 0f98b40ce..47d017b4b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs @@ -24,5 +24,29 @@ public async Task ResponseWithReferencedHeaderShouldReferenceComponent() Assert.Equal(expected.Description, actual.Description); } + + [Fact] + public async Task ResponseWithSummaryV32ShouldDeserializeCorrectly() + { + var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "responseWithSummary.yaml"), SettingsFixture.ReaderSettings); + + var response = result.Document.Components.Responses["SuccessResponse"] as OpenApiResponse; + + Assert.NotNull(response); + Assert.Equal("Successful response", response.Summary); + Assert.Equal("A successful response with summary", response.Description); + } + + [Fact] + public async Task ResponseWithSummaryExtensionV31ShouldDeserializeCorrectly() + { + var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "responseWithSummaryExtension.yaml"), SettingsFixture.ReaderSettings); + + var response = result.Document.Components.Responses["SuccessResponse"] as OpenApiResponse; + + Assert.NotNull(response); + Assert.Equal("Successful response", response.Summary); + Assert.Equal("A successful response with summary extension", response.Description); + } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummary.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummary.yaml new file mode 100644 index 000000000..0de4941fe --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummary.yaml @@ -0,0 +1,16 @@ +openapi: 3.2.0 +info: + title: Test API + version: 1.0.0 +components: + responses: + SuccessResponse: + summary: Successful response + description: A successful response with summary + content: + application/json: + schema: + type: object + properties: + message: + type: string \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummaryExtension.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummaryExtension.yaml new file mode 100644 index 000000000..2b3660cec --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiResponse/responseWithSummaryExtension.yaml @@ -0,0 +1,16 @@ +openapi: 3.1.0 +info: + title: Test API + version: 1.0.0 +components: + responses: + SuccessResponse: + description: A successful response with summary extension + x-oai-summary: Successful response + content: + application/json: + schema: + type: object + properties: + message: + type: string \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index 15c392466..9dc2093f6 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -166,6 +166,22 @@ public class OpenApiResponseTests } }; + private static OpenApiResponse ResponseWithSummary => new OpenApiResponse + { + Summary = "Successful response", + Description = "A detailed description of a successful response", + Content = new Dictionary + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema() + { + Type = JsonSchemaType.Object + } + } + } + }; + [Theory] [InlineData(OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Json)] [InlineData(OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Json)] @@ -399,5 +415,91 @@ public async Task SerializeReferencedResponseAsV2JsonWithoutReferenceWorksAsync( // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); } + + [Fact] + public async Task SerializeResponseWithSummaryAsV32Works() + { + // Arrange + var expected = @"{ + ""summary"": ""Successful response"", + ""description"": ""A detailed description of a successful response"", + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""object"" + } + } + } +}"; + + // Act + var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + Assert.Equal(expected, actual); + } + + [Fact] + public async Task SerializeResponseWithSummaryAsV31Works() + { + // Arrange + var expected = @"{ + ""description"": ""A detailed description of a successful response"", + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""object"" + } + } + }, + ""x-oai-summary"": ""Successful response"" +}"; + + // Act + var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + Assert.Equal(expected, actual); + } + + [Fact] + public async Task SerializeResponseWithSummaryAsV3Works() + { + // Arrange + var expected = @"{ + ""description"": ""A detailed description of a successful response"", + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""object"" + } + } + }, + ""x-oai-summary"": ""Successful response"" +}"; + + // Act + var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + Assert.Equal(expected, actual); + } + + [Fact] + public void ResponseWithSummaryShouldImplementIOpenApiSummarizedElement() + { + // Arrange + var response = new OpenApiResponse { Summary = "Test summary" }; + + // Act & Assert + Assert.IsAssignableFrom(response); + Assert.Equal("Test summary", response.Summary); + } } } From 48d714c7ea009632ec9cda793767fac8faab3d83 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 12:10:38 +0000 Subject: [PATCH 03/10] Complete implementation with reference support and test fixes Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> --- .../Models/References/OpenApiResponseReference.cs | 9 ++++++++- .../ReferenceService/TryLoadReferenceV2Tests.cs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index f76ddea15..ebb2b7d4b 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi /// /// Response Object Reference. /// - public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse + public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse, IOpenApiSummarizedElement { /// /// Constructor initializing the reference object. @@ -32,6 +32,13 @@ private OpenApiResponseReference(OpenApiResponseReference openApiResponseReferen } + /// + public string? Summary + { + get => (Target as IOpenApiSummarizedElement)?.Summary; + set { if (Target is IOpenApiSummarizedElement summarizedTarget) summarizedTarget.Summary = value; } + } + /// public string? Description { diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs index b20f72e9a..cb9571f42 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs @@ -67,6 +67,7 @@ public async Task LoadResponseReference() Assert.Equivalent( new OpenApiResponse { + Summary = null, Description = "Entity not found.", Content = new Dictionary() { From 8f5c5cb3bc88652f6ae68c0baacb839bf1aa582a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:07:31 +0000 Subject: [PATCH 04/10] Update IOpenApiResponse to derive from IOpenApiSummarizedElement Co-authored-by: baywet <7905502+baywet@users.noreply.github.com> --- src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs | 2 +- src/Microsoft.OpenApi/Models/OpenApiResponse.cs | 4 ++-- .../Models/References/OpenApiResponseReference.cs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs index dfddd7838..e8b8357fe 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs @@ -6,7 +6,7 @@ namespace Microsoft.OpenApi; /// Defines the base properties for the response object. /// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. /// -public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable +public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable, IOpenApiSummarizedElement { /// /// Maps a header name to its definition. diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index 6b1c851cf..68ff27fc5 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -10,7 +10,7 @@ namespace Microsoft.OpenApi /// /// Response object. /// - public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse, IOpenApiSummarizedElement + public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse { /// public string? Summary { get; set; } @@ -41,7 +41,7 @@ public OpenApiResponse() { } internal OpenApiResponse(IOpenApiResponse response) { Utils.CheckArgumentNull(response); - Summary = (response as IOpenApiSummarizedElement)?.Summary ?? Summary; + Summary = response.Summary ?? Summary; Description = response.Description ?? Description; Headers = response.Headers != null ? new Dictionary(response.Headers) : null; Content = response.Content != null ? new Dictionary(response.Content) : null; diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index ebb2b7d4b..8e15d84f4 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi /// /// Response Object Reference. /// - public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse, IOpenApiSummarizedElement + public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse { /// /// Constructor initializing the reference object. @@ -35,8 +35,8 @@ private OpenApiResponseReference(OpenApiResponseReference openApiResponseReferen /// public string? Summary { - get => (Target as IOpenApiSummarizedElement)?.Summary; - set { if (Target is IOpenApiSummarizedElement summarizedTarget) summarizedTarget.Summary = value; } + get => Target?.Summary; + set { if (Target != null) Target.Summary = value; } } /// From ce0d61ec72503318274860ec3dc20f4eec700abd Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 11:51:58 -0400 Subject: [PATCH 05/10] Apply suggestions from code review --- .../Models/References/OpenApiResponseReference.cs | 4 ++-- .../Models/OpenApiResponseTests.cs | 12 +++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 8e15d84f4..34d05cd4a 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -35,8 +35,8 @@ private OpenApiResponseReference(OpenApiResponseReference openApiResponseReferen /// public string? Summary { - get => Target?.Summary; - set { if (Target != null) Target.Summary = value; } + get => string.IsNullOrEmpty(Reference.Summary) ? Target?.Summary : Reference.Summary; + set => Reference.Summary = value; } /// diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index 9dc2093f6..2fefddf1c 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -436,9 +436,7 @@ public async Task SerializeResponseWithSummaryAsV32Works() var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); // Assert - actual = actual.MakeLineBreaksEnvironmentNeutral(); - expected = expected.MakeLineBreaksEnvironmentNeutral(); - Assert.Equal(expected, actual); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } [Fact] @@ -461,9 +459,7 @@ public async Task SerializeResponseWithSummaryAsV31Works() var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); // Assert - actual = actual.MakeLineBreaksEnvironmentNeutral(); - expected = expected.MakeLineBreaksEnvironmentNeutral(); - Assert.Equal(expected, actual); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } [Fact] @@ -486,9 +482,7 @@ public async Task SerializeResponseWithSummaryAsV3Works() var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); // Assert - actual = actual.MakeLineBreaksEnvironmentNeutral(); - expected = expected.MakeLineBreaksEnvironmentNeutral(); - Assert.Equal(expected, actual); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } [Fact] From 454c30fc1119eb049cd2d1a45bb3706ebb62d1d8 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 11:52:19 -0400 Subject: [PATCH 06/10] Apply suggestion from @baywet --- .../Models/References/OpenApiResponseReference.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 34d05cd4a..988a331ad 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi /// /// Response Object Reference. /// - public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse + public class OpenApiResponseReference : BaseOpenApiReferenceHolder, IOpenApiResponse { /// /// Constructor initializing the reference object. From 367d4a664491ca789b9cd0b69f7d9e75fd54799a Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 11:55:06 -0400 Subject: [PATCH 07/10] chore: copy reference implementation Signed-off-by: Vincent Biret --- .../Models/References/OpenApiResponseReference.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 988a331ad..3133e7054 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -70,9 +70,9 @@ public IOpenApiResponse CreateShallowCopy() return new OpenApiResponseReference(this); } /// - protected override OpenApiReferenceWithDescription CopyReference(OpenApiReferenceWithDescription sourceReference) + protected override OpenApiReferenceWithDescriptionAndSummary CopyReference(OpenApiReferenceWithDescriptionAndSummary sourceReference) { - return new OpenApiReferenceWithDescription(sourceReference); + return new OpenApiReferenceWithDescriptionAndSummary(sourceReference); } } } From 8a17339e3054659479edc7e73c2e2fa7dfee403a Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 11:56:44 -0400 Subject: [PATCH 08/10] chore: adds missing using Signed-off-by: Vincent Biret --- test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index 2fefddf1c..c0c0f3d49 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Text.Json.Nodes; using System.Threading.Tasks; using VerifyXunit; using Xunit; @@ -436,7 +437,7 @@ public async Task SerializeResponseWithSummaryAsV32Works() var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); // Assert - Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } [Fact] From 945624690ed01f85cbb4afc67dcc38aeaf2ee059 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 11:57:21 -0400 Subject: [PATCH 09/10] chore: linting Signed-off-by: Vincent Biret --- test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index c0c0f3d49..cb9182577 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -483,7 +483,7 @@ public async Task SerializeResponseWithSummaryAsV3Works() var actual = await ResponseWithSummary.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); // Assert - Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(expected), JsonNode.Parse(actual))); } [Fact] @@ -493,7 +493,7 @@ public void ResponseWithSummaryShouldImplementIOpenApiSummarizedElement() var response = new OpenApiResponse { Summary = "Test summary" }; // Act & Assert - Assert.IsAssignableFrom(response); + Assert.IsType(response, exactMatch: false); Assert.Equal("Test summary", response.Summary); } } From 9b5bb0155efc620a754c18c9d66e47bf14f42982 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 29 Sep 2025 12:01:40 -0400 Subject: [PATCH 10/10] chore: updates public API export Signed-off-by: Vincent Biret --- .../PublicApi/PublicApi.approved.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index a00be2a9b..5ad03ed5f 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -209,7 +209,7 @@ namespace Microsoft.OpenApi Microsoft.OpenApi.IOpenApiParameter? ConvertToBodyParameter(Microsoft.OpenApi.IOpenApiWriter writer); System.Collections.Generic.IEnumerable? ConvertToFormDataParameters(Microsoft.OpenApi.IOpenApiWriter writer); } - public interface IOpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public interface IOpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IOpenApiSummarizedElement, Microsoft.OpenApi.IShallowCopyable { System.Collections.Generic.IDictionary? Content { get; } System.Collections.Generic.IDictionary? Headers { get; } @@ -1112,7 +1112,7 @@ namespace Microsoft.OpenApi public Microsoft.OpenApi.IOpenApiRequestBody CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IOpenApiSummarizedElement, Microsoft.OpenApi.IShallowCopyable { public OpenApiResponse() { } public System.Collections.Generic.IDictionary? Content { get; set; } @@ -1120,13 +1120,14 @@ namespace Microsoft.OpenApi public System.Collections.Generic.IDictionary? Extensions { get; set; } public System.Collections.Generic.IDictionary? Headers { get; set; } public System.Collections.Generic.IDictionary? Links { get; set; } + public string? Summary { get; set; } public Microsoft.OpenApi.IOpenApiResponse CreateShallowCopy() { } public virtual void SerializeAsV2(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV32(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiResponseReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiResponseReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IOpenApiSummarizedElement, Microsoft.OpenApi.IShallowCopyable { public OpenApiResponseReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public System.Collections.Generic.IDictionary? Content { get; } @@ -1134,7 +1135,8 @@ namespace Microsoft.OpenApi public System.Collections.Generic.IDictionary? Extensions { get; } public System.Collections.Generic.IDictionary? Headers { get; } public System.Collections.Generic.IDictionary? Links { get; } - protected override Microsoft.OpenApi.OpenApiReferenceWithDescription CopyReference(Microsoft.OpenApi.OpenApiReferenceWithDescription sourceReference) { } + public string? Summary { get; set; } + protected override Microsoft.OpenApi.OpenApiReferenceWithDescriptionAndSummary CopyReference(Microsoft.OpenApi.OpenApiReferenceWithDescriptionAndSummary sourceReference) { } public override Microsoft.OpenApi.IOpenApiResponse CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.IOpenApiResponse source) { } public Microsoft.OpenApi.IOpenApiResponse CreateShallowCopy() { } }