diff --git a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs index 69e15f9a4..ed7a5f4d3 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs @@ -58,7 +58,7 @@ public void SerializeAsV32(IOpenApiWriter writer) if (DefaultMapping != null) { writer.WritePropertyName("defaultMapping"); - DefaultMapping.SerializeAsV32(writer); + WriteMappingReference(writer, DefaultMapping); } // extensions @@ -79,7 +79,7 @@ public void SerializeAsV31(IOpenApiWriter writer) if (DefaultMapping != null) { writer.WritePropertyName("x-oas-default-mapping"); - DefaultMapping.SerializeAsV31(writer); + WriteMappingReference(writer, DefaultMapping); } // extensions @@ -108,13 +108,16 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteProperty(OpenApiConstants.PropertyName, PropertyName); // mapping - writer.WriteOptionalMap(OpenApiConstants.Mapping, Mapping, (w, s) => + writer.WriteOptionalMap(OpenApiConstants.Mapping, Mapping, WriteMappingReference); + } + + private static void WriteMappingReference(IOpenApiWriter writer, OpenApiSchemaReference schemaReference) + { + var reference = schemaReference.Reference.ReferenceV3; + if (!string.IsNullOrEmpty(reference)) { - if (!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null) - { - w.WriteValue(s.Reference.ReferenceV3); - } - }); + writer.WriteValue(reference!); + } } /// diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDiscriminatorTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiDiscriminatorTests.cs new file mode 100644 index 000000000..495a0729e --- /dev/null +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDiscriminatorTests.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System.Collections.Generic; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.OpenApi.Tests.Models +{ + [Collection("DefaultSettings")] + public class OpenApiDiscriminatorTests + { + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi3_2, "defaultMapping", "Pet", true)] + [InlineData(OpenApiSpecVersion.OpenApi3_2, "defaultMapping", "#/components/schemas/Pet", true)] + [InlineData(OpenApiSpecVersion.OpenApi3_2, "defaultMapping", "Pet", false)] + [InlineData(OpenApiSpecVersion.OpenApi3_1, "x-oas-default-mapping", "Pet", true)] + [InlineData(OpenApiSpecVersion.OpenApi3_1, "x-oas-default-mapping", "#/components/schemas/Pet", true)] + [InlineData(OpenApiSpecVersion.OpenApi3_1, "x-oas-default-mapping", "Pet", false)] + public async Task SerializeDefaultMappingAsReferenceString(OpenApiSpecVersion specVersion, string propertyName, string referenceId, bool useDocument) + { + // Arrange + var document = useDocument ? new OpenApiDocument() : null; + var discriminator = new OpenApiDiscriminator + { + PropertyName = "pet_type", + DefaultMapping = new OpenApiSchemaReference(referenceId, document) + }; + + // Act + var actual = JsonNode.Parse(await discriminator.SerializeAsJsonAsync(specVersion)); + + // Assert + Assert.NotNull(actual); + Assert.Equal("#/components/schemas/Pet", actual[propertyName]?.GetValue()); + } + + [Theory] + [InlineData(OpenApiSpecVersion.OpenApi3_0)] + [InlineData(OpenApiSpecVersion.OpenApi3_1)] + [InlineData(OpenApiSpecVersion.OpenApi3_2)] + public async Task SerializeMappingValuesAsReferenceStrings(OpenApiSpecVersion specVersion) + { + // Arrange + var document = new OpenApiDocument(); + var discriminator = new OpenApiDiscriminator + { + PropertyName = "pet_type", + Mapping = new Dictionary + { + ["simple"] = new OpenApiSchemaReference("Pet", document), + ["explicit"] = new OpenApiSchemaReference("#/components/schemas/Pet", document), + ["noDocument"] = new OpenApiSchemaReference("Pet") + } + }; + + // Act + var actual = JsonNode.Parse(await discriminator.SerializeAsJsonAsync(specVersion)); + + // Assert + Assert.NotNull(actual); + var mapping = Assert.IsAssignableFrom(actual["mapping"]); + AssertMappingValue(mapping, "simple"); + AssertMappingValue(mapping, "explicit"); + AssertMappingValue(mapping, "noDocument"); + } + + private static void AssertMappingValue(JsonObject mapping, string key) + { + var value = Assert.IsAssignableFrom(mapping[key]); + Assert.Equal("#/components/schemas/Pet", value.GetValue()); + } + } +}