From 34b0f77734f467b71b6bf46c9d3834f6815913f8 Mon Sep 17 00:00:00 2001 From: Mark Pitman Date: Fri, 26 Apr 2019 16:56:46 -0700 Subject: [PATCH] Serialize explode value properly on parameters with style "form" When a parameter has the style set to "form" and explode set to false, the v3 serializer will not write out the value for explode. Swagger UI then defaults the explode value to true, since it is not specified and that is the correct default value when the style is set to "form". The OpenAPI spec for this is right around here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields-10 --- .../Models/OpenApiParameter.cs | 2 +- .../Models/OpenApiParameterTests.cs | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index 0333c6e11..a34116723 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -177,7 +177,7 @@ public void SerializeAsV3WithoutReference(IOpenApiWriter writer) writer.WriteProperty(OpenApiConstants.Style, Style?.GetDisplayName()); // explode - writer.WriteProperty(OpenApiConstants.Explode, Explode, false); + writer.WriteProperty(OpenApiConstants.Explode, Explode, Style.HasValue && Style.Value == ParameterStyle.Form); // allowReserved writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false); diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs index 8d92b139e..9833b5859 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.IO; using FluentAssertions; +using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Writers; @@ -58,6 +59,50 @@ public class OpenApiParameterTests } }; + public static OpenApiParameter ParameterWithFormStyleAndExplodeFalse = new OpenApiParameter + { + Name = "name1", + In = ParameterLocation.Query, + Description = "description1", + Style = ParameterStyle.Form, + Explode = false, + Schema = new OpenApiSchema + { + Type = "array", + Items = new OpenApiSchema + { + Enum = new List + { + new OpenApiString("value1"), + new OpenApiString("value2") + } + } + } + + }; + + public static OpenApiParameter ParameterWithFormStyleAndExplodeTrue = new OpenApiParameter + { + Name = "name1", + In = ParameterLocation.Query, + Description = "description1", + Style = ParameterStyle.Form, + Explode = true, + Schema = new OpenApiSchema + { + Type = "array", + Items = new OpenApiSchema + { + Enum = new List + { + new OpenApiString("value1"), + new OpenApiString("value2") + } + } + } + + }; + public static OpenApiParameter AdvancedHeaderParameterWithSchemaReference = new OpenApiParameter { Name = "name1", @@ -309,5 +354,74 @@ public void SerializeParameterWithSchemaTypeObjectAsV2JsonWorks() expected = expected.MakeLineBreaksEnvironmentNeutral(); actual.Should().Be(expected); } + + [Fact] + public void SerializeParameterWithFormStyleAndExplodeFalseWorks() + { + // Arrange + var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); + var writer = new OpenApiJsonWriter(outputStringWriter); + var expected = + @"{ + ""name"": ""name1"", + ""in"": ""query"", + ""description"": ""description1"", + ""style"": ""form"", + ""explode"": false, + ""schema"": { + ""type"": ""array"", + ""items"": { + ""enum"": [ + ""value1"", + ""value2"" + ] + } + } +}"; + + // Act + ParameterWithFormStyleAndExplodeFalse.SerializeAsV3WithoutReference(writer); + writer.Flush(); + var actual = outputStringWriter.GetStringBuilder().ToString(); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + actual.Should().Be(expected); + } + + [Fact] + public void SerializeParameterWithFormStyleAndExplodeTrueWorks() + { + // Arrange + var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); + var writer = new OpenApiJsonWriter(outputStringWriter); + var expected = + @"{ + ""name"": ""name1"", + ""in"": ""query"", + ""description"": ""description1"", + ""style"": ""form"", + ""schema"": { + ""type"": ""array"", + ""items"": { + ""enum"": [ + ""value1"", + ""value2"" + ] + } + } +}"; + + // Act + ParameterWithFormStyleAndExplodeTrue.SerializeAsV3WithoutReference(writer); + writer.Flush(); + var actual = outputStringWriter.GetStringBuilder().ToString(); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + actual.Should().Be(expected); + } } } \ No newline at end of file