diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index c9e5441a9..0ebe9eab9 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -650,7 +650,7 @@ internal void WriteAsItemsProperties(IOpenApiWriter writer) /// The open api writer. /// The list of required properties in parent schema. /// The property name that will be serialized. - internal void SerializeAsV2( + internal virtual void SerializeAsV2( IOpenApiWriter writer, ISet parentRequiredProperties, string propertyName) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs index 011e0b930..3e2c5b53c 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs @@ -227,6 +227,22 @@ public override void SerializeAsV3(IOpenApiWriter writer) writer.GetSettings().LoopDetector.PopLoop(); } + /// + internal override void SerializeAsV2( + IOpenApiWriter writer, + ISet parentRequiredProperties, + string propertyName) + { + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + } + else + { + base.SerializeAsV2(writer, parentRequiredProperties, propertyName); + } + } + /// public override void SerializeAsV2(IOpenApiWriter writer) { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs index aee5aab7e..384e23298 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs @@ -11,6 +11,8 @@ using System.Text.Json.Nodes; using System.Collections.Generic; using FluentAssertions.Equivalency; +using Microsoft.OpenApi.Models.References; +using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Readers.Tests.V2Tests { @@ -95,5 +97,56 @@ public void ParseSchemaWithEnumShouldSucceed() .Excluding((IMemberInfo memberInfo) => memberInfo.Path.EndsWith("Parent"))); } + [Fact] + public void PropertiesReferenceShouldWork() + { + var workingDocument = new OpenApiDocument() + { + Components = new OpenApiComponents(), + }; + const string referenceId = "targetSchema"; + var targetSchema = new OpenApiSchema() + { + Type = JsonSchemaType.Object, + Properties = new Dictionary + { + ["prop1"] = new OpenApiSchema() + { + Type = JsonSchemaType.String + } + } + }; + workingDocument.Components.Schemas.Add(referenceId, targetSchema); + workingDocument.Workspace.RegisterComponents(workingDocument); + var referenceSchema = new OpenApiSchema() + { + Type = JsonSchemaType.Object, + Properties = new Dictionary + { + ["propA"] = new OpenApiSchemaReference(referenceId, workingDocument), + } + }; + + using var textWriter = new StringWriter(); + var writer = new OpenApiJsonWriter(textWriter); + referenceSchema.SerializeAsV2(writer); + + var json = textWriter.ToString(); + var expected = JsonNode.Parse( + """ + { + "type": "object", + "properties": + { + "propA": + { + "$ref": "#/definitions/targetSchema" + } + } + } + """ + ); + Assert.True(JsonNode.DeepEquals(JsonNode.Parse(json), expected)); + } } }