Skip to content

Commit 4362730

Browse files
committed
Fix deserializing of const null
1 parent f143034 commit 4362730

5 files changed

Lines changed: 146 additions & 0 deletions

File tree

src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public static Dictionary<string, HashSet<T>> CreateArrayMap<T>(this JsonNode? no
157157

158158
public static string? GetScalarValue(this JsonNode? node)
159159
{
160+
if (node.IsJsonNullSentinel())
161+
{
162+
return null;
163+
}
164+
160165
var scalarNode = node is JsonValue value ? value : throw new OpenApiException("Expected scalar value.");
161166

162167
return Convert.ToString(scalarNode.GetValue<object>(), CultureInfo.InvariantCulture);

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,55 @@ public async Task ParseSchemaWithConstWorks()
632632
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), schemaString.MakeLineBreaksEnvironmentNeutral());
633633
}
634634

635+
[Fact]
636+
public async Task ParseSchemaWithConstNullWorks()
637+
{
638+
var expected = @"{
639+
""$schema"": ""https://json-schema.org/draft/2020-12/schema"",
640+
""required"": [
641+
""status""
642+
],
643+
""type"": ""object"",
644+
""properties"": {
645+
""status"": {
646+
""const"": null,
647+
""type"": ""string""
648+
},
649+
""user"": {
650+
""required"": [
651+
""role""
652+
],
653+
""type"": ""object"",
654+
""properties"": {
655+
""role"": {
656+
""const"": null,
657+
""type"": ""string""
658+
}
659+
}
660+
}
661+
}
662+
}";
663+
664+
var path = Path.Combine(SampleFolderPath, "schemaWithConstNull.json");
665+
666+
// Act
667+
var schema = await OpenApiModelFactory.LoadAsync<OpenApiSchema>(path, OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings);
668+
669+
var statusSchema = Assert.IsType<OpenApiSchema>(schema.Properties["status"]);
670+
Assert.Null(statusSchema.Const);
671+
Assert.True(statusSchema.WasConstExplicitlySet);
672+
673+
var userRoleSchema = Assert.IsType<OpenApiSchema>(schema.Properties["user"].Properties["role"]);
674+
Assert.Null(userRoleSchema.Const);
675+
Assert.True(userRoleSchema.WasConstExplicitlySet);
676+
677+
// serialization
678+
var writer = new StringWriter();
679+
schema.SerializeAsV31(new OpenApiJsonWriter(writer));
680+
var schemaString = writer.ToString();
681+
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), schemaString.MakeLineBreaksEnvironmentNeutral());
682+
}
683+
635684
[Fact]
636685
public void ParseSchemaWithUnrecognizedKeywordsWorks()
637686
{
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"type": "object",
4+
"properties": {
5+
"status": {
6+
"type": "string",
7+
"const": null
8+
},
9+
"user": {
10+
"type": "object",
11+
"properties": {
12+
"role": {
13+
"type": "string",
14+
"const": null
15+
}
16+
},
17+
"required": [ "role" ]
18+
}
19+
},
20+
"required": [ "status" ]
21+
}

test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSchemaTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,55 @@ public async Task ParseSchemaWithConstWorks()
534534
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), schemaString.MakeLineBreaksEnvironmentNeutral());
535535
}
536536

537+
[Fact]
538+
public async Task ParseSchemaWithConstNullWorks()
539+
{
540+
var expected = @"{
541+
""$schema"": ""https://json-schema.org/draft/2020-12/schema"",
542+
""required"": [
543+
""status""
544+
],
545+
""type"": ""object"",
546+
""properties"": {
547+
""status"": {
548+
""const"": null,
549+
""type"": ""string""
550+
},
551+
""user"": {
552+
""required"": [
553+
""role""
554+
],
555+
""type"": ""object"",
556+
""properties"": {
557+
""role"": {
558+
""const"": null,
559+
""type"": ""string""
560+
}
561+
}
562+
}
563+
}
564+
}";
565+
566+
var path = Path.Combine(SampleFolderPath, "schemaWithConstNull.json");
567+
568+
// Act
569+
var schema = await OpenApiModelFactory.LoadAsync<OpenApiSchema>(path, OpenApiSpecVersion.OpenApi3_2, new(), SettingsFixture.ReaderSettings);
570+
571+
var statusSchema = Assert.IsType<OpenApiSchema>(schema.Properties["status"]);
572+
Assert.Null(statusSchema.Const);
573+
Assert.True(statusSchema.WasConstExplicitlySet);
574+
575+
var userRoleSchema = Assert.IsType<OpenApiSchema>(schema.Properties["user"].Properties["role"]);
576+
Assert.Null(userRoleSchema.Const);
577+
Assert.True(userRoleSchema.WasConstExplicitlySet);
578+
579+
// serialization
580+
var writer = new StringWriter();
581+
schema.SerializeAsV32(new OpenApiJsonWriter(writer));
582+
var schemaString = writer.ToString();
583+
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), schemaString.MakeLineBreaksEnvironmentNeutral());
584+
}
585+
537586
[Fact]
538587
public void ParseSchemaWithUnrecognizedKeywordsWorks()
539588
{
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"type": "object",
4+
"properties": {
5+
"status": {
6+
"type": "string",
7+
"const": null
8+
},
9+
"user": {
10+
"type": "object",
11+
"properties": {
12+
"role": {
13+
"type": "string",
14+
"const": null
15+
}
16+
},
17+
"required": [ "role" ]
18+
}
19+
},
20+
"required": [ "status" ]
21+
}
22+

0 commit comments

Comments
 (0)