Skip to content

Commit b5e86c9

Browse files
committed
Fix nullable enum support in OpenAPI schemas and update tests accordingly.
1 parent 26dfb8f commit b5e86c9

2 files changed

Lines changed: 174 additions & 4 deletions

File tree

src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ public static bool IsSemanticallyMeaningful(this IOpenApiSchema schema, bool ign
322322
return schema.HasAnyProperty() ||
323323
(!ignoreEnums && schema.Enum is { Count: > 0 }) ||
324324
(!ignoreArrays && schema.Items != null) ||
325-
(!ignoreType && schema.Type is not null &&
325+
(!ignoreType && schema.Type is not null and not JsonSchemaType.Null &&
326326
((ignoreNullableObjects && !schema.IsObjectType()) ||
327327
!ignoreNullableObjects)) ||
328328
!string.IsNullOrEmpty(schema.Format) ||

tests/Kiota.Builder.Tests/Writers/CSharp/YamlToCSharpTests.cs

Lines changed: 173 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void Dispose()
2323

2424
private readonly HttpClient _httpClient = new();
2525

26-
public const string NullableInOpenApi3 = """
26+
public const string NullableObjectInOpenApi3 = """
2727
{
2828
"openapi": "3.1.1",
2929
"info": {
@@ -116,7 +116,7 @@ public void Dispose()
116116
}
117117
""";
118118

119-
public const string NullableInOpenApi3_Models_Sample = """
119+
public const string NullableObjectInOpenApi3_Models_Sample = """
120120
// <auto-generated/>
121121
#pragma warning disable CS0618
122122
using Microsoft.Kiota.Abstractions.Extensions;
@@ -205,9 +205,179 @@ public virtual void Serialize(ISerializationWriter writer)
205205
206206
""";
207207

208+
public const string NullableEnumInOpenApi3 = """
209+
{
210+
"openapi": "3.1.1",
211+
"info": {
212+
"title": "WebApplication2 | v1",
213+
"version": "1.0.0"
214+
},
215+
"servers": [
216+
{
217+
"url": "http://localhost:5088/"
218+
}
219+
],
220+
"paths": {
221+
"/Sample": {
222+
"get": {
223+
"tags": [
224+
"Sample"
225+
],
226+
"operationId": "GetWeatherForecast",
227+
"responses": {
228+
"200": {
229+
"description": "OK",
230+
"content": {
231+
"text/plain": {
232+
"schema": {
233+
"$ref": "#/components/schemas/SampleEnum"
234+
}
235+
},
236+
"application/json": {
237+
"schema": {
238+
"$ref": "#/components/schemas/SampleEnum"
239+
}
240+
},
241+
"text/json": {
242+
"schema": {
243+
"$ref": "#/components/schemas/SampleEnum"
244+
}
245+
}
246+
}
247+
}
248+
}
249+
}
250+
}
251+
},
252+
"components": {
253+
"schemas": {
254+
"ESample": {
255+
"$comment": "Applied FixEnumsSchemaTransformer",
256+
"enum": [
257+
"A",
258+
"B"
259+
],
260+
"type": "integer",
261+
"x-ms-enum": {
262+
"name": "ESample",
263+
"modelAsString": false,
264+
"values": [
265+
{
266+
"name": "A",
267+
"value": 0,
268+
"description": ""
269+
},
270+
{
271+
"name": "B",
272+
"value": 1,
273+
"description": ""
274+
}
275+
]
276+
}
277+
},
278+
"SampleEnum": {
279+
"required": [
280+
"notNullable",
281+
"nullable"
282+
],
283+
"type": "object",
284+
"properties": {
285+
"notNullable": {
286+
"$ref": "#/components/schemas/ESample"
287+
},
288+
"nullable": {
289+
"oneOf": [
290+
{
291+
"type": "null"
292+
},
293+
{
294+
"$ref": "#/components/schemas/ESample"
295+
}
296+
]
297+
}
298+
}
299+
}
300+
}
301+
},
302+
"tags": [
303+
{
304+
"name": "Sample"
305+
}
306+
]
307+
}
308+
""";
309+
310+
public const string NullableEnumInOpenApi3_Models_SampleEnum = """
311+
// <auto-generated/>
312+
#pragma warning disable CS0618
313+
using Microsoft.Kiota.Abstractions.Extensions;
314+
using Microsoft.Kiota.Abstractions.Serialization;
315+
using System.Collections.Generic;
316+
using System.IO;
317+
using System;
318+
namespace ApiSdk.Models
319+
{
320+
[global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")]
321+
#pragma warning disable CS1591
322+
public partial class SampleEnum : IAdditionalDataHolder, IParsable
323+
#pragma warning restore CS1591
324+
{
325+
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
326+
public IDictionary<string, object> AdditionalData { get; set; }
327+
/// <summary>The notNullable property</summary>
328+
public global::ApiSdk.Models.ESample? NotNullable { get; set; }
329+
/// <summary>The nullable property</summary>
330+
public global::ApiSdk.Models.ESample? Nullable { get; set; }
331+
/// <summary>
332+
/// Instantiates a new <see cref="global::ApiSdk.Models.SampleEnum"/> and sets the default values.
333+
/// </summary>
334+
public SampleEnum()
335+
{
336+
AdditionalData = new Dictionary<string, object>();
337+
}
338+
/// <summary>
339+
/// Creates a new instance of the appropriate class based on discriminator value
340+
/// </summary>
341+
/// <returns>A <see cref="global::ApiSdk.Models.SampleEnum"/></returns>
342+
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
343+
public static global::ApiSdk.Models.SampleEnum CreateFromDiscriminatorValue(IParseNode parseNode)
344+
{
345+
if(ReferenceEquals(parseNode, null)) throw new ArgumentNullException(nameof(parseNode));
346+
return new global::ApiSdk.Models.SampleEnum();
347+
}
348+
/// <summary>
349+
/// The deserialization information for the current model
350+
/// </summary>
351+
/// <returns>A IDictionary&lt;string, Action&lt;IParseNode&gt;&gt;</returns>
352+
public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
353+
{
354+
return new Dictionary<string, Action<IParseNode>>
355+
{
356+
{ "notNullable", n => { NotNullable = n.GetEnumValue<global::ApiSdk.Models.ESample>(); } },
357+
{ "nullable", n => { Nullable = n.GetEnumValue<global::ApiSdk.Models.ESample>(); } },
358+
};
359+
}
360+
/// <summary>
361+
/// Serializes information the current object
362+
/// </summary>
363+
/// <param name="writer">Serialization writer to use to serialize this model</param>
364+
public virtual void Serialize(ISerializationWriter writer)
365+
{
366+
if(ReferenceEquals(writer, null)) throw new ArgumentNullException(nameof(writer));
367+
writer.WriteEnumValue<global::ApiSdk.Models.ESample>("notNullable", NotNullable);
368+
writer.WriteEnumValue<global::ApiSdk.Models.ESample>("nullable", Nullable);
369+
writer.WriteAdditionalData(AdditionalData);
370+
}
371+
}
372+
}
373+
#pragma warning restore CS0618
374+
375+
""";
376+
208377

209378
[Theory]
210-
[InlineData(NullableInOpenApi3, new[] {"Models/Sample.cs", NullableInOpenApi3_Models_Sample})]
379+
[InlineData(NullableObjectInOpenApi3, new[] {"Models/Sample.cs", NullableObjectInOpenApi3_Models_Sample})]
380+
[InlineData(NullableEnumInOpenApi3, new[] {"Models/SampleEnum.cs", NullableEnumInOpenApi3_Models_SampleEnum})]
211381
public async Task CreateOpenApiDocumentWithResultAsync_ReturnsDiagnostics(string input,
212382
string[] expectedData)
213383
{

0 commit comments

Comments
 (0)