Skip to content

Commit bf8eed6

Browse files
committed
fix(serialization): additional recursive paths
1 parent b99b400 commit bf8eed6

4 files changed

Lines changed: 111 additions & 14 deletions

File tree

‎src/Microsoft.OpenApi/Models/OpenApiHeader.cs‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
9090
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
9191
}
9292

93-
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
93+
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
9494
Action<IOpenApiWriter, IOpenApiSerializable> callback)
9595
{
9696
Utils.CheckArgumentNull(writer);
@@ -167,7 +167,12 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
167167
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);
168168

169169
// schema
170-
var targetSchema = Schema switch {
170+
if (Schema is OpenApiSchemaReference)
171+
{
172+
writer.CountInlineReference();
173+
}
174+
var targetSchema = Schema switch
175+
{
171176
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
172177
OpenApiSchema schema => schema,
173178
_ => null,

‎src/Microsoft.OpenApi/Models/OpenApiParameter.cs‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
107107
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
108108
}
109109

110-
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
110+
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
111111
Action<IOpenApiWriter, IOpenApiSerializable> callback)
112112
{
113113
Utils.CheckArgumentNull(writer);
@@ -202,7 +202,12 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction
202202
// uniqueItems
203203
// enum
204204
// multipleOf
205-
var targetSchema = Schema switch {
205+
if (Schema is OpenApiSchemaReference)
206+
{
207+
writer.CountInlineReference();
208+
}
209+
var targetSchema = Schema switch
210+
{
206211
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
207212
OpenApiSchema schema => schema,
208213
_ => null,

‎src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public override void SerializeAsV2(IOpenApiWriter writer)
6464
{
6565
if (writer.GetSettings().ShouldInlineReference(Reference))
6666
{
67+
writer.CountInlineReference();
6768
return GetFromTarget(target => target.ConvertToBodyParameter(writer));
6869
}
6970

@@ -74,6 +75,7 @@ public override void SerializeAsV2(IOpenApiWriter writer)
7475
{
7576
if (writer.GetSettings().ShouldInlineReference(Reference))
7677
{
78+
writer.CountInlineReference();
7779
return GetFromTarget(target => target.ConvertToFormDataParameters(writer));
7880
}
7981

‎test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterInlineReferenceTests.cs‎

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Globalization;
67
using System.IO;
78
using System.Text;
@@ -21,8 +22,6 @@ public class OpenApiWriterInlineReferenceTests
2122
[InlineData(OpenApiSpecVersion.OpenApi3_0, true)]
2223
[InlineData(OpenApiSpecVersion.OpenApi3_1, false)]
2324
[InlineData(OpenApiSpecVersion.OpenApi3_1, true)]
24-
[InlineData(OpenApiSpecVersion.OpenApi3_2, false)]
25-
[InlineData(OpenApiSpecVersion.OpenApi3_2, true)]
2625
public void SerializeWithRepeatedInlineReferencesStopsBeforeWriterLimit(
2726
OpenApiSpecVersion specVersion,
2827
bool useYaml)
@@ -45,7 +44,6 @@ public void SerializeWithRepeatedInlineReferencesStopsBeforeWriterLimit(
4544
[InlineData(OpenApiSpecVersion.OpenApi2_0)]
4645
[InlineData(OpenApiSpecVersion.OpenApi3_0)]
4746
[InlineData(OpenApiSpecVersion.OpenApi3_1)]
48-
[InlineData(OpenApiSpecVersion.OpenApi3_2)]
4947
public void SerializeWithInlineReferencesBelowLimitWorks(OpenApiSpecVersion specVersion)
5048
{
5149
var readResult = OpenApiDocument.Parse(CreateDocumentWithRepeatedReferences(4), "json");
@@ -87,6 +85,96 @@ public void ReusingSettingsWithNewWriterStartsANewInlineReferenceCount()
8785
Assert.DoesNotContain("$ref", secondOutput.ToString());
8886
}
8987

88+
[Fact]
89+
public void ConvertRequestBodyReferenceToV2ParameterUsesInlineReferenceCount()
90+
{
91+
var document = CreateDocumentWithRequestBodyComponent();
92+
var reference = new OpenApiRequestBodyReference("shared", document);
93+
using var output = new StringWriter(CultureInfo.InvariantCulture);
94+
var writer = new OpenApiJsonWriter(output, CreateWriterSettings(0));
95+
96+
Assert.Throws<OpenApiWriterException>(() => reference.ConvertToBodyParameter(writer));
97+
Assert.Throws<OpenApiWriterException>(() => reference.ConvertToFormDataParameters(writer));
98+
}
99+
100+
[Fact]
101+
public void SerializeV2HeaderSchemaReferenceUsesInlineReferenceCount()
102+
{
103+
var document = CreateDocumentWithSchemaComponent();
104+
var header = new OpenApiHeader
105+
{
106+
Schema = new OpenApiSchemaReference("shared", document)
107+
};
108+
using var output = new StringWriter(CultureInfo.InvariantCulture);
109+
var writer = new OpenApiJsonWriter(output, CreateWriterSettings(0));
110+
111+
Assert.Throws<OpenApiWriterException>(() => header.SerializeAsV2(writer));
112+
}
113+
114+
[Fact]
115+
public void SerializeV2ParameterSchemaReferenceUsesInlineReferenceCount()
116+
{
117+
var document = CreateDocumentWithSchemaComponent();
118+
var parameter = new OpenApiParameter
119+
{
120+
Name = "value",
121+
In = ParameterLocation.Query,
122+
Schema = new OpenApiSchemaReference("shared", document)
123+
};
124+
using var output = new StringWriter(CultureInfo.InvariantCulture);
125+
var writer = new OpenApiJsonWriter(output, CreateWriterSettings(0));
126+
127+
Assert.Throws<OpenApiWriterException>(() => parameter.SerializeAsV2(writer));
128+
}
129+
130+
private static OpenApiDocument CreateDocumentWithRequestBodyComponent()
131+
{
132+
var document = new OpenApiDocument
133+
{
134+
Components = new OpenApiComponents
135+
{
136+
RequestBodies = new Dictionary<string, IOpenApiRequestBody>
137+
{
138+
["shared"] = new OpenApiRequestBody
139+
{
140+
Content = new Dictionary<string, OpenApiMediaType>
141+
{
142+
["application/x-www-form-urlencoded"] = new OpenApiMediaType
143+
{
144+
Schema = new OpenApiSchema
145+
{
146+
Type = JsonSchemaType.Object,
147+
Properties = new Dictionary<string, IOpenApiSchema>
148+
{
149+
["value"] = new OpenApiSchema { Type = JsonSchemaType.String }
150+
}
151+
}
152+
}
153+
}
154+
}
155+
}
156+
}
157+
};
158+
document.Workspace.RegisterComponents(document);
159+
return document;
160+
}
161+
162+
private static OpenApiDocument CreateDocumentWithSchemaComponent()
163+
{
164+
var document = new OpenApiDocument
165+
{
166+
Components = new OpenApiComponents
167+
{
168+
Schemas = new Dictionary<string, IOpenApiSchema>
169+
{
170+
["shared"] = new OpenApiSchema { Type = JsonSchemaType.String }
171+
}
172+
}
173+
};
174+
document.Workspace.RegisterComponents(document);
175+
return document;
176+
}
177+
90178
private static string CreateDocumentWithRepeatedReferences(int levels)
91179
{
92180
var schemas = new StringBuilder();
@@ -147,23 +235,20 @@ private static string CreateDocumentWithRepeatedReferences(int levels)
147235
}
148236

149237
private static void Serialize(
150-
OpenApiDocument document,
238+
IOpenApiSerializable serializable,
151239
IOpenApiWriter writer,
152240
OpenApiSpecVersion specVersion)
153241
{
154242
switch (specVersion)
155243
{
156244
case OpenApiSpecVersion.OpenApi2_0:
157-
document.SerializeAsV2(writer);
245+
serializable.SerializeAsV2(writer);
158246
break;
159247
case OpenApiSpecVersion.OpenApi3_0:
160-
document.SerializeAsV3(writer);
248+
serializable.SerializeAsV3(writer);
161249
break;
162250
case OpenApiSpecVersion.OpenApi3_1:
163-
document.SerializeAsV31(writer);
164-
break;
165-
case OpenApiSpecVersion.OpenApi3_2:
166-
document.SerializeAsV32(writer);
251+
serializable.SerializeAsV31(writer);
167252
break;
168253
default:
169254
throw new ArgumentOutOfRangeException(nameof(specVersion), specVersion, null);

0 commit comments

Comments
 (0)