From 4ecd027f3ffffdbd224c5a99268a4483ff48ad4f Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 1 Sep 2022 20:12:38 +0300 Subject: [PATCH 1/3] Add child schema format to parent schema when serializing as V2 --- src/Microsoft.OpenApi/Models/OpenApiSchema.cs | 6 ++ .../Models/OpenApiSchemaTests.cs | 63 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 7482b6baf..95fe873ab 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -707,6 +707,12 @@ internal void WriteAsSchemaProperties( // oneOf (Not Supported in V2) - Write the first schema only as an allOf. writer.WriteOptionalCollection(OpenApiConstants.AllOf, OneOf?.Take(1), (w, s) => s.SerializeAsV2(w)); } + if (OneOf?.Count > 0) + { + // Take the format and set it at the root + var oneOfFormat = OneOf.Select(x => x.Format.ToString()).FirstOrDefault(); + this.Format = oneOfFormat; + } } // properties diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index ae13944e6..26e8df5f8 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -422,5 +422,68 @@ public async Task SerializeSchemaWRequiredPropertiesAsV2JsonWorksAsync(bool prod // Assert await Verifier.Verify(actual).UseParameters(produceTerseOutput); } + + [Fact] + public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChildrenSchema() + { + // Arrange + var schema = new OpenApiSchema() + { + OneOf = new List + { + new OpenApiSchema + { + Type = "number", + Format = "decimal" + }, + new OpenApiSchema { Type = "string" }, + } + }; + + var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); + var openApiJsonWriter = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = false }); + + // Act + // Serialize as V2 + schema.SerializeAsV2(openApiJsonWriter); + openApiJsonWriter.Flush(); + + var v2Schema = outputStringWriter.GetStringBuilder().ToString();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); + + // Serialize as V3 + //schema.SerializeAsV3(openApiJsonWriter); + //openApiJsonWriter.Flush(); + + //var v3Schema = outputStringWriter.GetStringBuilder().ToString();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n", ""); + + var expectedV2Schema = @"{ +""allOf"": [ +{ + ""format"": ""decimal"", + ""type"": ""number"" +}], +""format"": ""decimal"" +}".Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); + + + var expectedV3Schema = @"{ +""allOf"": [ +{ + ""format"": ""decimal"", + ""type"": ""number"" +}]} +{""oneOf"": [ +{ + ""type"": ""number"", + ""format"": ""decimal"" +}, +{""type"" : ""string""} + +]}}";//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n", ""); + + // Assert + Assert.Equal(expectedV2Schema, v2Schema); // Assert that v2 schema has the root schema Format defined + //Assert.Equal(expectedV3Schema, v3Schema); + } } } From 00fe8db93bce4e449af3b505dfeaf8d2cd0d05ee Mon Sep 17 00:00:00 2001 From: Irvine Date: Thu, 1 Sep 2022 21:21:40 +0300 Subject: [PATCH 2/3] Retrieve Format property --- src/Microsoft.OpenApi/Models/OpenApiSchema.cs | 14 ++++++-------- .../Models/OpenApiSchemaTests.cs | 17 +++++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 95fe873ab..c3b36c4f2 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -630,6 +630,10 @@ internal void WriteAsSchemaProperties( } // format + Format ??= AllOf?.FirstOrDefault(x => x.Format != null)?.Format ?? + AnyOf?.FirstOrDefault(x => x.Format != null)?.Format ?? + OneOf?.FirstOrDefault(x => x.Format != null)?.Format; + writer.WriteProperty(OpenApiConstants.Format, Format); // title @@ -695,7 +699,7 @@ internal void WriteAsSchemaProperties( // allOf writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV2(w)); - // If there isn't already an AllOf, and the schema contains a oneOf or anyOf write an allOf with the first + // If there isn't already an allOf, and the schema contains a oneOf or anyOf write an allOf with the first // schema in the list as an attempt to guess at a graceful downgrade situation. if (AllOf == null || AllOf.Count == 0) { @@ -707,12 +711,6 @@ internal void WriteAsSchemaProperties( // oneOf (Not Supported in V2) - Write the first schema only as an allOf. writer.WriteOptionalCollection(OpenApiConstants.AllOf, OneOf?.Take(1), (w, s) => s.SerializeAsV2(w)); } - if (OneOf?.Count > 0) - { - // Take the format and set it at the root - var oneOfFormat = OneOf.Select(x => x.Format.ToString()).FirstOrDefault(); - this.Format = oneOfFormat; - } } // properties diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index 26e8df5f8..a2e991e75 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -448,7 +448,7 @@ public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChild schema.SerializeAsV2(openApiJsonWriter); openApiJsonWriter.Flush(); - var v2Schema = outputStringWriter.GetStringBuilder().ToString();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); + var v2Schema = outputStringWriter.GetStringBuilder().ToString().MakeLineBreaksEnvironmentNeutral();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); // Serialize as V3 //schema.SerializeAsV3(openApiJsonWriter); @@ -457,13 +457,14 @@ public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChild //var v3Schema = outputStringWriter.GetStringBuilder().ToString();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n", ""); var expectedV2Schema = @"{ -""allOf"": [ -{ - ""format"": ""decimal"", - ""type"": ""number"" -}], -""format"": ""decimal"" -}".Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); + ""format"": ""decimal"", + ""allOf"": [ + { + ""format"": ""decimal"", + ""type"": ""number"" + } + ] +}".MakeLineBreaksEnvironmentNeutral(); var expectedV3Schema = @"{ From 0818fb742bca9c330dcd066b37aed8c0288b7ac7 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 1 Sep 2022 23:27:34 +0300 Subject: [PATCH 3/3] Clean up code --- src/Microsoft.OpenApi/Models/OpenApiSchema.cs | 6 ++-- .../Models/OpenApiSchemaTests.cs | 29 ++----------------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index c3b36c4f2..8734c19a2 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -630,9 +630,9 @@ internal void WriteAsSchemaProperties( } // format - Format ??= AllOf?.FirstOrDefault(x => x.Format != null)?.Format ?? - AnyOf?.FirstOrDefault(x => x.Format != null)?.Format ?? - OneOf?.FirstOrDefault(x => x.Format != null)?.Format; + Format ??= AllOf?.FirstOrDefault(static x => x.Format != null)?.Format ?? + AnyOf?.FirstOrDefault(static x => x.Format != null)?.Format ?? + OneOf?.FirstOrDefault(static x => x.Format != null)?.Format; writer.WriteProperty(OpenApiConstants.Format, Format); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index a2e991e75..429129c1e 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -424,7 +424,7 @@ public async Task SerializeSchemaWRequiredPropertiesAsV2JsonWorksAsync(bool prod } [Fact] - public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChildrenSchema() + public void SerializeAsV2ShouldSetFormatPropertyInParentSchemaIfPresentInChildrenSchema() { // Arrange var schema = new OpenApiSchema() @@ -448,13 +448,7 @@ public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChild schema.SerializeAsV2(openApiJsonWriter); openApiJsonWriter.Flush(); - var v2Schema = outputStringWriter.GetStringBuilder().ToString().MakeLineBreaksEnvironmentNeutral();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n",""); - - // Serialize as V3 - //schema.SerializeAsV3(openApiJsonWriter); - //openApiJsonWriter.Flush(); - - //var v3Schema = outputStringWriter.GetStringBuilder().ToString();//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n", ""); + var v2Schema = outputStringWriter.GetStringBuilder().ToString().MakeLineBreaksEnvironmentNeutral(); var expectedV2Schema = @"{ ""format"": ""decimal"", @@ -466,25 +460,8 @@ public void SerializeSchemaPrimitiveTypeShouldRemoveFormatInRootIfPresentInChild ] }".MakeLineBreaksEnvironmentNeutral(); - - var expectedV3Schema = @"{ -""allOf"": [ -{ - ""format"": ""decimal"", - ""type"": ""number"" -}]} -{""oneOf"": [ -{ - ""type"": ""number"", - ""format"": ""decimal"" -}, -{""type"" : ""string""} - -]}}";//.Replace(Environment.NewLine, "").Replace(" ", "").Replace("\n", ""); - // Assert - Assert.Equal(expectedV2Schema, v2Schema); // Assert that v2 schema has the root schema Format defined - //Assert.Equal(expectedV3Schema, v3Schema); + Assert.Equal(expectedV2Schema, v2Schema); } } }