Skip to content

Commit 92db49b

Browse files
authored
Merge pull request #2401 from microsoft/fix/sub-schema-reference
fix: sub-schema references are invalid
2 parents 22195f4 + 75d1d2b commit 92db49b

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,14 @@ public string? ReferenceV3
8484
{
8585
return Id;
8686
}
87-
if (!string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
88-
!string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
87+
if (!string.IsNullOrEmpty(Id) && Id is not null &&
88+
(Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
89+
Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ||
90+
#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER || NET5_0_OR_GREATER
91+
Id.Contains("#/components", StringComparison.OrdinalIgnoreCase)))
92+
#else
93+
Id.Contains("#/components")))
94+
#endif
8995
{
9096
return Id;
9197
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"name": {
5+
"type": [
6+
"string",
7+
"null"
8+
],
9+
"format": null,
10+
"x-schema-id": null
11+
},
12+
"parent": {
13+
"type": [
14+
"object",
15+
"null"
16+
],
17+
"properties": {
18+
"name": {
19+
"type": [
20+
"string",
21+
"null"
22+
],
23+
"format": null,
24+
"x-schema-id": null
25+
},
26+
"parent": {
27+
"$ref": "#/properties/parent",
28+
"x-schema-id": "Category"
29+
},
30+
"tags": {
31+
"type": [
32+
"array",
33+
"null"
34+
],
35+
"items": {
36+
"type": "object",
37+
"properties": {
38+
"name": {
39+
"type": [
40+
"string",
41+
"null"
42+
],
43+
"format": null,
44+
"x-schema-id": null
45+
}
46+
},
47+
"required": [
48+
"name"
49+
],
50+
"x-schema-id": "Tag"
51+
}
52+
}
53+
},
54+
"required": [
55+
"name"
56+
],
57+
"x-schema-id": "Category"
58+
},
59+
"tags": {
60+
"$ref": "#/properties/parent/properties/tags"
61+
}
62+
},
63+
"required": [
64+
"name"
65+
],
66+
"x-schema-id": "Category"
67+
}

test/Microsoft.OpenApi.Readers.Tests/V31Tests/RelativeReferenceTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ public async Task ShouldResolveRelativeSubReferenceUsingParsingContext()
312312
parsingContext.StartObject("schemas");
313313
parsingContext.StartObject("Foo");
314314
var document = new OpenApiDocument();
315-
315+
316316
// Act
317317
var fooComponentSchema = parsingContext.ParseFragment<OpenApiSchema>(schemaJsonNode, OpenApiSpecVersion.OpenApi3_1, document);
318318
document.AddComponent("Foo", fooComponentSchema);
@@ -412,5 +412,28 @@ public async Task ShouldResolveRecursiveRelativeSubReference()
412412
Assert.Equal(JsonSchemaType.Array | JsonSchemaType.Null, fooSchemaTagsProperty.Type);
413413
Assert.Equal(JsonSchemaType.Object, fooSchemaTagsProperty.Items.Type);
414414
}
415+
[Fact]
416+
public async Task ShouldResolveReferencesInSchemasFromSystemTextJson()
417+
{
418+
var filePath = Path.Combine(SampleFolderPath, "STJSchema.json");
419+
using var fs = File.OpenRead(filePath);
420+
var jsonNode = await JsonNode.ParseAsync(fs);
421+
422+
var parsingContext = new ParsingContext(new OpenApiDiagnostic());
423+
var document = new OpenApiDocument();
424+
var schema = parsingContext.ParseFragment<OpenApiSchema>(jsonNode, OpenApiSpecVersion.OpenApi3_1, document);
425+
Assert.NotNull(schema);
426+
427+
document.AddComponent("Foo", schema);
428+
var tagsProperty = Assert.IsType<OpenApiSchemaReference>(schema.Properties["tags"]);
429+
// this is the reference that is generated by STJ schema generator which does not have OAI in context.
430+
Assert.Equal("#/properties/parent/properties/tags", tagsProperty.Reference.ReferenceV3);
431+
// this is the reference that needs to be used in the document for components resolution.
432+
var absoluteReferenceId = $"#/components/schemas/Foo{tagsProperty.Reference.ReferenceV3.Replace("#", string.Empty)}";
433+
schema.Properties["tags"] = new OpenApiSchemaReference(absoluteReferenceId, document);
434+
var updatedTagsProperty = Assert.IsType<OpenApiSchemaReference>(schema.Properties["tags"]);
435+
Assert.Equal(absoluteReferenceId, updatedTagsProperty.Reference.ReferenceV3);
436+
Assert.Equal(JsonSchemaType.Array | JsonSchemaType.Null, updatedTagsProperty.Type);
437+
}
415438
}
416439
}

0 commit comments

Comments
 (0)