Skip to content

Commit 8eecae6

Browse files
authored
Merge pull request #2235 from microsoft/andrueastman/validations
fix: fixes serialization of openApidocs with operation tags with settings to inline references
2 parents a457935 + f67fe64 commit 8eecae6

File tree

6 files changed

+75
-4
lines changed

6 files changed

+75
-4
lines changed

src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</PackageReference>
3434

3535
<PackageReference Include="SharpYaml" Version="2.1.1" />
36-
<PackageReference Include="System.Text.Json" Version="[8.0,)" />
36+
<PackageReference Include="System.Text.Json" Version="[8.0.5,)" />
3737
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-hh2w-p6rv-4g7w" />
3838
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-8g4q-xg66-9fp4" />
3939
</ItemGroup>

src/Microsoft.OpenApi/Microsoft.OpenApi.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
2424
</PropertyGroup>
2525
<ItemGroup>
26-
<PackageReference Include="System.Text.Json" Version="[8.0,)" />
26+
<PackageReference Include="System.Text.Json" Version="[8.0.5,)" />
2727
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-hh2w-p6rv-4g7w" />
2828
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-8g4q-xg66-9fp4" />
2929
</ItemGroup>

src/Microsoft.OpenApi/Models/References/BaseOpenApiReferenceHolder.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ protected BaseOpenApiReferenceHolder(string referenceId, OpenApiDocument hostDoc
6363
/// <inheritdoc/>
6464
public virtual void SerializeAsV3(IOpenApiWriter writer)
6565
{
66-
if (!writer.GetSettings().ShouldInlineReference(Reference))
66+
if (!writer.GetSettings().ShouldInlineReference(Reference)
67+
|| Reference.Type == ReferenceType.Tag) // tags are held as references need to drop in.
6768
{
6869
Reference.SerializeAsV3(writer);
6970
}

test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
using System.Globalization;
45
using Microsoft.Extensions.Logging;
6+
using Microsoft.OpenApi.Extensions;
57
using Microsoft.OpenApi.Models;
68
using Microsoft.OpenApi.Models.Interfaces;
79
using Microsoft.OpenApi.Models.References;
810
using Microsoft.OpenApi.Reader;
911
using Microsoft.OpenApi.Services;
1012
using Microsoft.OpenApi.Tests.UtilityFiles;
13+
using Microsoft.OpenApi.Writers;
1114
using Moq;
1215
using Xunit;
1316

@@ -235,7 +238,14 @@ public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly(
235238
using var stream = File.OpenRead(filePath);
236239
var settings = new OpenApiReaderSettings();
237240
settings.AddYamlReader();
238-
var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings)).Document;
241+
var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings)).Document;
242+
243+
// validated the tags are read as references
244+
var openApiOperationTags = doc.Paths["/items"].Operations[OperationType.Get].Tags?.ToArray();
245+
Assert.NotNull(openApiOperationTags);
246+
Assert.Single(openApiOperationTags);
247+
Assert.True(openApiOperationTags[0].UnresolvedReference);
248+
239249
var predicate = OpenApiFilterService.CreatePredicate(operationIds: operationIds);
240250
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate);
241251

@@ -255,6 +265,26 @@ public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly(
255265
Assert.Single(targetHeaders);
256266
Assert.NotNull(targetExamples);
257267
Assert.Single(targetExamples);
268+
// validated the tags of the trimmed document are read as references
269+
var trimmedOpenApiOperationTags = subsetOpenApiDocument.Paths["/items"].Operations[OperationType.Get].Tags?.ToArray();
270+
Assert.NotNull(trimmedOpenApiOperationTags);
271+
Assert.Single(trimmedOpenApiOperationTags);
272+
Assert.True(trimmedOpenApiOperationTags[0].UnresolvedReference);
273+
274+
// Finally try to write the trimmed document as v3 document
275+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
276+
var writer = new OpenApiJsonWriter(outputStringWriter)
277+
{
278+
Settings = new OpenApiWriterSettings()
279+
{
280+
InlineExternalReferences = true,
281+
InlineLocalReferences = true
282+
}
283+
};
284+
subsetOpenApiDocument.SerializeAsV3(writer);
285+
await writer.FlushAsync();
286+
var result = outputStringWriter.ToString();
287+
Assert.NotEmpty(result);
258288
}
259289

260290
[Theory]

test/Microsoft.OpenApi.Hidi.Tests/UtilityFiles/docWithReusableHeadersAndExamples.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ servers:
77
paths:
88
/items:
99
get:
10+
tags:
11+
- list.items
1012
operationId: getItems
1113
summary: Get a list of items
1214
responses:

test/Microsoft.OpenApi.Tests/Models/References/OpenApiTagReferenceTest.cs

+38
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public class OpenApiTagReferenceTest
4545
description: The user was not found.
4646
tags:
4747
- $ref: '#/tags/user'
48+
- users.user
4849
components:
4950
schemas:
5051
User:
@@ -60,11 +61,13 @@ public class OpenApiTagReferenceTest
6061
";
6162

6263
readonly OpenApiTagReference _openApiTagReference;
64+
readonly OpenApiTagReference _openApiTagReference2;
6365

6466
public OpenApiTagReferenceTest()
6567
{
6668
var result = OpenApiDocument.Parse(OpenApi, "yaml", SettingsFixture.ReaderSettings);
6769
_openApiTagReference = new("user", result.Document);
70+
_openApiTagReference2 = new("users.user", result.Document);
6871
}
6972

7073
[Fact]
@@ -73,6 +76,7 @@ public void TagReferenceResolutionWorks()
7376
// Assert
7477
Assert.Equal("user", _openApiTagReference.Name);
7578
Assert.Equal("Operations about users.", _openApiTagReference.Description);
79+
Assert.True(_openApiTagReference2.UnresolvedReference);// the target is null
7680
}
7781

7882
[Theory]
@@ -108,5 +112,39 @@ public async Task SerializeTagReferenceAsV31JsonWorks(bool produceTerseOutput)
108112
// Assert
109113
await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput);
110114
}
115+
116+
[Theory]
117+
[InlineData(true)]
118+
[InlineData(false)]
119+
public async Task SerializeTagAsV3JsonWorks(bool produceTerseOutput)
120+
{
121+
// Arrange
122+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
123+
var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput });
124+
125+
// Act
126+
_openApiTagReference2.SerializeAsV3(writer);
127+
await writer.FlushAsync();
128+
129+
// Assert
130+
Assert.Equal("\"users.user\"", outputStringWriter.ToString());
131+
}
132+
133+
[Theory]
134+
[InlineData(true)]
135+
[InlineData(false)]
136+
public async Task SerializeTagAsV31JsonWorks(bool produceTerseOutput)
137+
{
138+
// Arrange
139+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
140+
var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput });
141+
142+
// Act
143+
_openApiTagReference2.SerializeAsV31(writer);
144+
await writer.FlushAsync();
145+
146+
// Assert
147+
Assert.Equal("\"users.user\"", outputStringWriter.ToString());
148+
}
111149
}
112150
}

0 commit comments

Comments
 (0)