From 85194e4128bc77024f7094bfcccbd07dfec634a2 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 14 Oct 2024 14:53:42 -0400 Subject: [PATCH 01/41] fix: oas extensions parsing Signed-off-by: Vincent Biret --- .../Configuration/LanguagesInformation.cs | 34 +++++------ .../Extensions/OpenApiSettingsExtensions.cs | 2 +- src/Kiota.Builder/LanguageInformation.cs | 57 +++++++++++-------- ...OpenApiAiReasoningInstructionsExtension.cs | 9 +-- ...penApiAiRespondingInstructionsExtension.cs | 9 +-- .../OpenApiDescriptionForModelExtension.cs | 4 +- .../OpenApiKiotaExtension.cs | 8 +-- .../OpenApiLegalInfoUrlExtension.cs | 4 +- .../OpenApiExtensions/OpenApiLogoExtension.cs | 11 ++-- .../OpenApiPrivacyPolicyUrlExtension.cs | 4 +- .../OpenApiSimpleStringExtension.cs | 10 ++-- .../Validation/OpenApiSchemaComparer.cs | 8 +-- 12 files changed, 87 insertions(+), 73 deletions(-) diff --git a/src/Kiota.Builder/Configuration/LanguagesInformation.cs b/src/Kiota.Builder/Configuration/LanguagesInformation.cs index 5dcb41dc59..a80f718faf 100644 --- a/src/Kiota.Builder/Configuration/LanguagesInformation.cs +++ b/src/Kiota.Builder/Configuration/LanguagesInformation.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.OpenApi.Any; +using System.Text.Json.Nodes; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -9,23 +9,14 @@ namespace Kiota.Builder.Configuration; public class LanguagesInformation : Dictionary, IOpenApiSerializable, ICloneable { - public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV3(writer); - public void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV31(writer); + public void SerializeAsV3(IOpenApiWriter writer) => SerializeAsV31(writer); + public static LanguagesInformation Parse(JsonObject jsonNode) { - ArgumentNullException.ThrowIfNull(writer); - writer.WriteStartObject(); - foreach (var entry in this.OrderBy(static x => x.Key, StringComparer.OrdinalIgnoreCase)) - { - writer.WriteRequiredObject(entry.Key, entry.Value, (w, x) => x.SerializeAsV3(w)); - } - writer.WriteEndObject(); - } - public static LanguagesInformation Parse(IOpenApiAny source) - { - if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new LanguagesInformation(); - foreach (var property in rawObject) - extension.Add(property.Key, LanguageInformation.Parse(property.Value)); + foreach (var property in jsonNode.Where(static property => property.Value is JsonObject)) + extension.Add(property.Key, LanguageInformation.Parse(property.Value!)); + return extension; } @@ -36,4 +27,15 @@ public object Clone() result.Add(entry.Key, entry.Value);// records don't need to be cloned as they are immutable return result; } + + public void SerializeAsV31(IOpenApiWriter writer) + { + ArgumentNullException.ThrowIfNull(writer); + writer.WriteStartObject(); + foreach (var entry in this.OrderBy(static x => x.Key, StringComparer.OrdinalIgnoreCase)) + { + writer.WriteRequiredObject(entry.Key, entry.Value, (w, x) => x.SerializeAsV3(w)); + } + writer.WriteEndObject(); + } } diff --git a/src/Kiota.Builder/Extensions/OpenApiSettingsExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSettingsExtensions.cs index 118ac47698..6546b601cb 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSettingsExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSettingsExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using Kiota.Builder.OpenApiExtensions; -using Microsoft.OpenApi.Readers; +using Microsoft.OpenApi.Reader; namespace Kiota.Builder.Extensions; public static class OpenApiSettingsExtensions diff --git a/src/Kiota.Builder/LanguageInformation.cs b/src/Kiota.Builder/LanguageInformation.cs index c0b36309aa..9c3f44cf23 100644 --- a/src/Kiota.Builder/LanguageInformation.cs +++ b/src/Kiota.Builder/LanguageInformation.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.Json.Serialization; using Kiota.Builder.Extensions; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -26,8 +27,9 @@ public LanguageMaturityLevel MaturityLevel #pragma warning disable CA2227 public HashSet StructuredMimeTypes { get; set; } = new(StringComparer.OrdinalIgnoreCase); #pragma warning restore CA2227 - public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV3(writer); - public void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV31(writer); + public void SerializeAsV3(IOpenApiWriter writer) => SerializeAsV31(writer); + public void SerializeAsV31(IOpenApiWriter writer) { ArgumentNullException.ThrowIfNull(writer); writer.WriteStartObject(); @@ -39,32 +41,34 @@ public void SerializeAsV3(IOpenApiWriter writer) writer.WriteOptionalCollection(nameof(StructuredMimeTypes).ToFirstCharacterLowerCase(), StructuredMimeTypes, (w, x) => w.WriteValue(x)); writer.WriteEndObject(); } - public static LanguageInformation Parse(IOpenApiAny source) + public static LanguageInformation Parse(JsonNode source) { - if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); + ArgumentNullException.ThrowIfNull(source); + if (source.GetValueKind() is not JsonValueKind.Object || + source.AsObject() is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new LanguageInformation(); - if (rawObject.TryGetValue(nameof(Dependencies).ToFirstCharacterLowerCase(), out var dependencies) && dependencies is OpenApiArray arrayValue) + if (rawObject.TryGetPropertyValue(nameof(Dependencies).ToFirstCharacterLowerCase(), out var dependencies) && dependencies is JsonArray arrayValue) { - foreach (var entry in arrayValue) + foreach (var entry in arrayValue.OfType()) extension.Dependencies.Add(LanguageDependency.Parse(entry)); } - if (rawObject.TryGetValue(nameof(DependencyInstallCommand).ToFirstCharacterLowerCase(), out var installCommand) && installCommand is OpenApiString stringValue) + if (rawObject.TryGetPropertyValue(nameof(DependencyInstallCommand).ToFirstCharacterLowerCase(), out var installCommand) && installCommand is JsonValue stringValue) { - extension.DependencyInstallCommand = stringValue.Value; + extension.DependencyInstallCommand = stringValue.GetValue(); } // not parsing the maturity level on purpose, we don't want APIs to be able to change that - if (rawObject.TryGetValue(nameof(ClientClassName).ToFirstCharacterLowerCase(), out var clientClassName) && clientClassName is OpenApiString clientClassNameValue) + if (rawObject.TryGetPropertyValue(nameof(ClientClassName).ToFirstCharacterLowerCase(), out var clientClassName) && clientClassName is JsonValue clientClassNameValue) { - extension.ClientClassName = clientClassNameValue.Value; + extension.ClientClassName = clientClassNameValue.GetValue(); } - if (rawObject.TryGetValue(nameof(ClientNamespaceName).ToFirstCharacterLowerCase(), out var clientNamespaceName) && clientNamespaceName is OpenApiString clientNamespaceNameValue) + if (rawObject.TryGetPropertyValue(nameof(ClientNamespaceName).ToFirstCharacterLowerCase(), out var clientNamespaceName) && clientNamespaceName is JsonValue clientNamespaceNameValue) { - extension.ClientNamespaceName = clientNamespaceNameValue.Value; + extension.ClientNamespaceName = clientNamespaceNameValue.GetValue(); } - if (rawObject.TryGetValue(nameof(StructuredMimeTypes).ToFirstCharacterLowerCase(), out var structuredMimeTypes) && structuredMimeTypes is OpenApiArray structuredMimeTypesValue) + if (rawObject.TryGetPropertyValue(nameof(StructuredMimeTypes).ToFirstCharacterLowerCase(), out var structuredMimeTypes) && structuredMimeTypes is JsonArray structuredMimeTypesValue) { - foreach (var entry in structuredMimeTypesValue.OfType()) - extension.StructuredMimeTypes.Add(entry.Value); + foreach (var entry in structuredMimeTypesValue.OfType()) + extension.StructuredMimeTypes.Add(entry.GetValue()); } return extension; } @@ -79,8 +83,9 @@ public DependencyType? DependencyType get; set; } private const string TypePropertyName = "type"; - public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV3(writer); - public void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV2(IOpenApiWriter writer) => SerializeAsV31(writer); + public void SerializeAsV3(IOpenApiWriter writer) => SerializeAsV31(writer); + public void SerializeAsV31(IOpenApiWriter writer) { ArgumentNullException.ThrowIfNull(writer); writer.WriteStartObject(); @@ -92,19 +97,21 @@ public void SerializeAsV3(IOpenApiWriter writer) } writer.WriteEndObject(); } - public static LanguageDependency Parse(IOpenApiAny source) + public static LanguageDependency Parse(JsonNode source) { - if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); + ArgumentNullException.ThrowIfNull(source); + if (source.GetValueKind() is not JsonValueKind.Object || + source.AsObject() is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new LanguageDependency(); - if (rawObject.TryGetValue(nameof(Name).ToFirstCharacterLowerCase(), out var name) && name is OpenApiString stringValue) + if (rawObject.TryGetPropertyValue(nameof(Name).ToFirstCharacterLowerCase(), out var nameNode) && nameNode is JsonValue nameJsonValue && nameJsonValue.TryGetValue(out var nameValue)) { - extension.Name = stringValue.Value; + extension.Name = nameValue; } - if (rawObject.TryGetValue(nameof(Version).ToFirstCharacterLowerCase(), out var version) && version is OpenApiString versionValue) + if (rawObject.TryGetPropertyValue(nameof(Version).ToFirstCharacterLowerCase(), out var versionNode) && versionNode is JsonValue versionJsonValue && versionJsonValue.TryGetValue(out var versionValue)) { - extension.Version = versionValue.Value; + extension.Version = versionValue; } - if (rawObject.TryGetValue(TypePropertyName, out var typeValue) && typeValue is OpenApiString typeStringValue && Enum.TryParse(typeStringValue.Value, true, out var parsedTypeValue)) + if (rawObject.TryGetPropertyValue(TypePropertyName, out var typeNode) && typeNode is JsonValue typeJsonValue && typeJsonValue.TryGetValue(out var typeValue) && Enum.TryParse(typeValue, true, out var parsedTypeValue)) { extension.DependencyType = parsedTypeValue; } diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiAiReasoningInstructionsExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiAiReasoningInstructionsExtension.cs index f690e1df81..8cfd72a30e 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiAiReasoningInstructionsExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiAiReasoningInstructionsExtension.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -28,11 +29,11 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) writer.WriteEndArray(); } } - public static OpenApiAiReasoningInstructionsExtension Parse(IOpenApiAny source) + public static OpenApiAiReasoningInstructionsExtension Parse(JsonNode source) { - if (source is not OpenApiArray rawArray) throw new ArgumentOutOfRangeException(nameof(source)); + if (source is not JsonArray rawArray) throw new ArgumentOutOfRangeException(nameof(source)); var result = new OpenApiAiReasoningInstructionsExtension(); - result.ReasoningInstructions.AddRange(rawArray.OfType().Select(x => x.Value)); + result.ReasoningInstructions.AddRange(rawArray.OfType().Where(static x => x.GetValueKind() is JsonValueKind.String).Select(static x => x.GetValue())); return result; } } diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiAiRespondingInstructionsExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiAiRespondingInstructionsExtension.cs index b8137ec225..440f90f03b 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiAiRespondingInstructionsExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiAiRespondingInstructionsExtension.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -28,11 +29,11 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) writer.WriteEndArray(); } } - public static OpenApiAiRespondingInstructionsExtension Parse(IOpenApiAny source) + public static OpenApiAiRespondingInstructionsExtension Parse(JsonNode source) { - if (source is not OpenApiArray rawArray) throw new ArgumentOutOfRangeException(nameof(source)); + if (source is not JsonArray rawArray) throw new ArgumentOutOfRangeException(nameof(source)); var result = new OpenApiAiRespondingInstructionsExtension(); - result.RespondingInstructions.AddRange(rawArray.OfType().Select(x => x.Value)); + result.RespondingInstructions.AddRange(rawArray.OfType().Where(static x => x.GetValueKind() is JsonValueKind.String).Select(static x => x.GetValue())); return result; } } diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiDescriptionForModelExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiDescriptionForModelExtension.cs index ba198df7c9..0a174f9fa3 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiDescriptionForModelExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiDescriptionForModelExtension.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Any; +using System.Text.Json.Nodes; namespace Kiota.Builder.OpenApiExtensions; @@ -10,7 +10,7 @@ public string? Description get; set; } protected override string? ValueSelector => Description; - public static OpenApiDescriptionForModelExtension Parse(IOpenApiAny source) + public static OpenApiDescriptionForModelExtension Parse(JsonNode source) { return new OpenApiDescriptionForModelExtension { diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiKiotaExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiKiotaExtension.cs index 80a9149f2f..6c7d9398d8 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiKiotaExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiKiotaExtension.cs @@ -1,9 +1,9 @@ using System; using System.Linq; +using System.Text.Json.Nodes; using Kiota.Builder.Configuration; using Kiota.Builder.Extensions; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -30,11 +30,11 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) writer.WriteEndObject(); } } - public static OpenApiKiotaExtension Parse(IOpenApiAny source) + public static OpenApiKiotaExtension Parse(JsonNode source) { - if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); + if (source is not JsonObject jsonNode) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new OpenApiKiotaExtension(); - if (rawObject.TryGetValue(nameof(LanguagesInformation).ToFirstCharacterLowerCase(), out var languagesInfo) && languagesInfo is OpenApiObject objectValue) + if (jsonNode.TryGetPropertyValue(nameof(LanguagesInformation).ToFirstCharacterLowerCase(), out var languagesInfo) && languagesInfo is JsonObject objectValue) { extension.LanguagesInformation = LanguagesInformation.Parse(objectValue); } diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiLegalInfoUrlExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiLegalInfoUrlExtension.cs index 3f042fc70c..10a52bce1a 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiLegalInfoUrlExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiLegalInfoUrlExtension.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Any; +using System.Text.Json.Nodes; namespace Kiota.Builder.OpenApiExtensions; @@ -10,7 +10,7 @@ public string? Legal get; set; } protected override string? ValueSelector => Legal; - public static OpenApiLegalInfoUrlExtension Parse(IOpenApiAny source) + public static OpenApiLegalInfoUrlExtension Parse(JsonNode source) { return new OpenApiLegalInfoUrlExtension { diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiLogoExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiLogoExtension.cs index edd5a2daf5..6ddab21631 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiLogoExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiLogoExtension.cs @@ -1,7 +1,8 @@ using System; +using System.Text.Json; +using System.Text.Json.Nodes; using Kiota.Builder.Extensions; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -16,13 +17,13 @@ public string? Url { get; set; } - public static OpenApiLogoExtension Parse(IOpenApiAny source) + public static OpenApiLogoExtension Parse(JsonNode source) { - if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); + if (source is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new OpenApiLogoExtension(); - if (rawObject.TryGetValue(nameof(Url).ToFirstCharacterLowerCase(), out var url) && url is OpenApiString urlValue) + if (rawObject.TryGetPropertyValue(nameof(Url).ToFirstCharacterLowerCase(), out var url) && url is JsonValue urlValue && urlValue.GetValueKind() is JsonValueKind.String && urlValue.TryGetValue(out var urlStrValue)) { - extension.Url = urlValue.Value; + extension.Url = urlStrValue; } return extension; } diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiPrivacyPolicyUrlExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiPrivacyPolicyUrlExtension.cs index 4cbc47c72a..039b2f54fe 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiPrivacyPolicyUrlExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiPrivacyPolicyUrlExtension.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Any; +using System.Text.Json.Nodes; namespace Kiota.Builder.OpenApiExtensions; @@ -10,7 +10,7 @@ public string? Privacy get; set; } protected override string? ValueSelector => Privacy; - public static OpenApiPrivacyPolicyUrlExtension Parse(IOpenApiAny source) + public static OpenApiPrivacyPolicyUrlExtension Parse(JsonNode source) { return new OpenApiPrivacyPolicyUrlExtension { diff --git a/src/Kiota.Builder/OpenApiExtensions/OpenApiSimpleStringExtension.cs b/src/Kiota.Builder/OpenApiExtensions/OpenApiSimpleStringExtension.cs index 9978939205..53ba859256 100644 --- a/src/Kiota.Builder/OpenApiExtensions/OpenApiSimpleStringExtension.cs +++ b/src/Kiota.Builder/OpenApiExtensions/OpenApiSimpleStringExtension.cs @@ -1,6 +1,7 @@ using System; +using System.Text.Json; +using System.Text.Json.Nodes; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -20,9 +21,10 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) writer.WriteValue(ValueSelector); } } - public static string ParseString(IOpenApiAny source) + public static string ParseString(JsonNode source) { - if (source is not OpenApiString rawString) throw new ArgumentOutOfRangeException(nameof(source)); - return rawString.Value; + if (source is not JsonValue rawString || + rawString.GetValueKind() is not JsonValueKind.String) throw new ArgumentOutOfRangeException(nameof(source)); + return rawString.GetValue(); } } diff --git a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs index 5b145e9daa..4543d3acbb 100644 --- a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs +++ b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs @@ -143,17 +143,17 @@ public int GetHashCode([DisallowNull] OpenApiDiscriminator obj) return hash.ToHashCode(); } } -internal class OpenApiAnyComparer : IEqualityComparer +internal class OpenApiAnyComparer : IEqualityComparer { /// - public bool Equals(IOpenApiAny? x, IOpenApiAny? y) + public bool Equals(OpenApiAny? x, OpenApiAny? y) { if (x is null || y is null) return object.Equals(x, y); // TODO: Can we use the OpenAPI.NET implementation of Equals? - return x.AnyType == y.AnyType && string.Equals(x.ToString(), y.ToString(), StringComparison.OrdinalIgnoreCase); + return x.Node.GetValueKind() == y.Node.GetValueKind() && string.Equals(x.Node.ToString(), y.Node.ToString(), StringComparison.OrdinalIgnoreCase); } /// - public int GetHashCode([DisallowNull] IOpenApiAny obj) + public int GetHashCode([DisallowNull] OpenApiAny obj) { var hash = new HashCode(); if (obj == null) return hash.ToHashCode(); From d83bc2fbe274923175951da633d6b0de2cb646e6 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 14 Oct 2024 16:02:06 -0400 Subject: [PATCH 02/41] fix: multiple NRE Signed-off-by: Vincent Biret --- .../OpenApiDeprecationExtensionExtensions.cs | 6 +-- .../Extensions/OpenApiDocumentExtensions.cs | 2 +- .../Extensions/OpenApiOperationExtensions.cs | 3 +- src/Kiota.Builder/KiotaBuilder.cs | 51 +++++++++++-------- .../Validation/MultipleServerEntries.cs | 2 +- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs index 75a2b5921d..8d29cd92ba 100644 --- a/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs @@ -24,15 +24,15 @@ internal static DeprecationInformation GetDeprecationInformation(this OpenApiPar return deprecatedValue.ToDeprecationInformation(); else if (parameter.Schema != null && !parameter.Schema.IsReferencedSchema() && parameter.Schema.Deprecated) return parameter.Schema.GetDeprecationInformation(); - else if (parameter.Content.Values.Select(static x => x.Schema).Where(static x => x != null && !x.IsReferencedSchema() && x.Deprecated).Select(static x => x.GetDeprecationInformation()).FirstOrDefault(static x => x.IsDeprecated) is DeprecationInformation contentDeprecationInformation) + else if (parameter.Content.Values.Select(static x => x.Schema).Where(static x => x != null && !x.IsReferencedSchema() && x.Deprecated).Select(static x => x!.GetDeprecationInformation()).FirstOrDefault(static x => x.IsDeprecated) is DeprecationInformation contentDeprecationInformation) return contentDeprecationInformation; return new(null, null, null, null, parameter.Deprecated); } internal static DeprecationInformation GetDeprecationInformation(this OpenApiOperation operation) { - if (operation.Deprecated && operation.Extensions.TryGetValue(OpenApiDeprecationExtension.Name, out var deprecatedExtension) && deprecatedExtension is OpenApiDeprecationExtension deprecatedValue) + if (operation.Deprecated && operation.Extensions is not null && operation.Extensions.TryGetValue(OpenApiDeprecationExtension.Name, out var deprecatedExtension) && deprecatedExtension is OpenApiDeprecationExtension deprecatedValue) return deprecatedValue.ToDeprecationInformation(); - else if (operation.Responses.Values + else if (operation.Responses?.Values .SelectMany(static x => x.Content.Values) .Select(static x => x?.Schema) .OfType() diff --git a/src/Kiota.Builder/Extensions/OpenApiDocumentExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiDocumentExtensions.cs index dc46ca6807..a655a79f12 100644 --- a/src/Kiota.Builder/Extensions/OpenApiDocumentExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiDocumentExtensions.cs @@ -31,7 +31,7 @@ internal static void InitializeInheritanceIndex(this OpenApiDocument openApiDocu { ArgumentNullException.ThrowIfNull(openApiDocument); var candidateUrl = openApiDocument.Servers - .GroupBy(static x => x, new OpenApiServerComparer()) //group by protocol relative urls + ?.GroupBy(static x => x, new OpenApiServerComparer()) //group by protocol relative urls .FirstOrDefault() ?.OrderByDescending(static x => x.Url, StringComparer.OrdinalIgnoreCase) // prefer https over http ?.FirstOrDefault() diff --git a/src/Kiota.Builder/Extensions/OpenApiOperationExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiOperationExtensions.cs index 2ca1fd3009..23c7659f88 100644 --- a/src/Kiota.Builder/Extensions/OpenApiOperationExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiOperationExtensions.cs @@ -30,6 +30,7 @@ private static string vendorSpecificCleanup(string input) } internal static IEnumerable GetResponseSchemas(this OpenApiOperation operation, HashSet successCodesToUse, StructuredMimeTypesCollection structuredMimeTypes) { + if (operation.Responses is null) return []; // Return Schema that represents all the possible success responses! return operation.Responses.Where(r => successCodesToUse.Contains(r.Key)) .OrderBy(static x => x.Key, StringComparer.OrdinalIgnoreCase) @@ -67,7 +68,7 @@ internal static IEnumerable GetValidSchemas(this IDictionary (Key: c.Key.Split(';', StringSplitOptions.RemoveEmptyEntries)[0], c.Value)) .Where(c => structuredMimeTypes.Contains(c.Key) || structuredMimeTypes.Contains(vendorSpecificCleanup(c.Key))) .Select(static co => co.Value.Schema) - .Where(static s => s is not null); + .OfType(); } internal static OpenApiSchema? GetResponseSchema(this OpenApiResponse response, StructuredMimeTypesCollection structuredMimeTypes) { diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 193f336e99..a3fc731565 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -8,7 +8,10 @@ using System.Linq; using System.Net.Http; using System.Runtime.CompilerServices; +using System.Security.Cryptography; using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -224,7 +227,7 @@ private void UpdateConfigurationFromOpenApiDocument() } private LanguagesInformation? GetLanguagesInformationInternal() { - if (openApiDocument == null) + if (openApiDocument is null || openApiDocument.Extensions is null) return null; if (openApiDocument.Extensions.TryGetValue(OpenApiKiotaExtension.Name, out var ext) && ext is OpenApiKiotaExtension kiotaExt) return kiotaExt.LanguagesInformation; @@ -1011,7 +1014,7 @@ private CodeParameter GetIndexerParameter(OpenApiUrlTreeNode currentNode, OpenAp var pathItems = GetPathItems(currentNode); var parameter = pathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem) ? pathItem.Parameters .Select(static x => new { Parameter = x, IsPathParameter = true }) - .Union(pathItems[Constants.DefaultOpenApiLabel].Operations.SelectMany(static x => x.Value.Parameters).Select(static x => new { Parameter = x, IsPathParameter = false })) + .Union(pathItems[Constants.DefaultOpenApiLabel].Operations.SelectMany(static x => x.Value.Parameters ?? []).Select(static x => new { Parameter = x, IsPathParameter = false })) .OrderBy(static x => x.IsPathParameter) .Select(static x => x.Parameter) .FirstOrDefault(x => x.Name.Equals(parameterName, StringComparison.OrdinalIgnoreCase) && x.In == ParameterLocation.Path) : @@ -1112,9 +1115,10 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten !propertyName.Equals(childIdentifier, StringComparison.Ordinal)) prop.SerializationName = childIdentifier; if (kind == CodePropertyKind.Custom && - propertySchema?.Default is OpenApiString stringDefaultValue && - !string.IsNullOrEmpty(stringDefaultValue.Value)) - prop.DefaultValue = $"\"{stringDefaultValue.Value}\""; + propertySchema?.Default is JsonValue stringDefaultJsonValue && + stringDefaultJsonValue.TryGetValue(out var stringDefaultValue) && + !string.IsNullOrEmpty(stringDefaultValue)) + prop.DefaultValue = $"\"{stringDefaultValue}\""; if (existingType == null) { @@ -1185,6 +1189,7 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten .Concat([CodeMethod.ErrorMappingClientRange, CodeMethod.ErrorMappingServerRange]), StringComparer.OrdinalIgnoreCase); private void AddErrorMappingsForExecutorMethod(OpenApiUrlTreeNode currentNode, OpenApiOperation operation, CodeMethod executorMethod) { + if (operation.Responses is null) return; foreach (var response in operation.Responses.Where(x => errorStatusCodes.Contains(x.Key))) { if (response.Value.GetResponseSchema(config.StructuredMimeTypes) is { } schema) @@ -1281,11 +1286,11 @@ private void AddErrorMappingToExecutorMethod(OpenApiUrlTreeNode currentNode, Ope private static CodeType GetExecutorMethodDefaultReturnType(OpenApiOperation operation) { string returnType; - if (operation.Responses.Any(static x => x.Value.Content.ContainsKey(RequestBodyOctetStreamContentType) && redirectStatusCodes.Contains(x.Key))) + if (operation.Responses?.Any(static x => x.Value.Content.ContainsKey(RequestBodyOctetStreamContentType) && redirectStatusCodes.Contains(x.Key)) is true) returnType = "binary"; - else if (operation.Responses.Any(static x => noContentStatusCodes.Contains(x.Key))) + else if (operation.Responses?.Any(static x => noContentStatusCodes.Contains(x.Key)) is true) returnType = VoidType; - else if (operation.Responses.Any(static x => x.Value.Content.ContainsKey(RequestBodyPlainTextContentType))) + else if (operation.Responses?.Any(static x => x.Value.Content.ContainsKey(RequestBodyPlainTextContentType)) is true) returnType = "string"; else returnType = "binary"; @@ -1329,7 +1334,7 @@ private void CreateOperationMethods(OpenApiUrlTreeNode currentNode, OperationTyp Deprecation = deprecationInformation, }; - if (operation.Extensions.TryGetValue(OpenApiPagingExtension.Name, out var extension) && extension is OpenApiPagingExtension pagingExtension) + if (operation.Extensions is not null && operation.Extensions.TryGetValue(OpenApiPagingExtension.Name, out var extension) && extension is OpenApiPagingExtension pagingExtension) { executorMethod.PagingInformation = new PagingInformation { @@ -1388,19 +1393,20 @@ private void CreateOperationMethods(OpenApiUrlTreeNode currentNode, OperationTyp && currentNode.HasRequiredQueryParametersAcrossOperations())// no need to generate extra strings/templates as optional parameters will have no effect on resolved url. generatorMethod.UrlTemplateOverride = operationUrlTemplate; - var mediaTypes = schema switch + var mediaTypes = (schema, operation.Responses is null) switch { - null => operation.Responses + (_, true) => [], + (null, _) => operation.Responses! .Where(static x => !errorStatusCodes.Contains(x.Key)) .SelectMany(static x => x.Value.Content) .Select(static x => x.Key) //get the successful non structured media types first, with a default 1 priority .Union(config.StructuredMimeTypes.GetAcceptedTypes( - operation.Responses + operation.Responses! .Where(static x => errorStatusCodes.Contains(x.Key)) // get any structured error ones, with the priority from the configuration .SelectMany(static x => x.Value.Content) // we can safely ignore unstructured ones as they won't be used in error mappings anyway and the body won't be read .Select(static x => x.Key))) .Distinct(StringComparer.OrdinalIgnoreCase), - _ => config.StructuredMimeTypes.GetAcceptedTypes(operation.Responses.Values.SelectMany(static x => x.Content).Where(x => schemaReferenceComparer.Equals(schema, x.Value.Schema)).Select(static x => x.Key)), + (_, false) => config.StructuredMimeTypes.GetAcceptedTypes(operation.Responses!.Values.SelectMany(static x => x.Content).Where(x => schemaReferenceComparer.Equals(schema, x.Value.Schema)).Select(static x => x.Key)), }; generatorMethod.AddAcceptedResponsesTypes(mediaTypes); if (config.Language == GenerationLanguage.CLI) @@ -1447,8 +1453,9 @@ private static void SetPathAndQueryParameters(CodeMethod target, OpenApiUrlTreeN .Select(GetCodeParameterFromApiParameter) .Union(operation .Parameters - .Where(ParametersFilter) - .Select(GetCodeParameterFromApiParameter)) + ?.Where(ParametersFilter) + .Select(GetCodeParameterFromApiParameter) ?? + []) .ToArray(); target.AddPathQueryOrHeaderParameter(pathAndQueryParameters); } @@ -1510,14 +1517,15 @@ private static bool IsSupportedMultipartDefault(OpenApiSchema openApiSchema, private void AddRequestBuilderMethodParameters(OpenApiUrlTreeNode currentNode, OperationType operationType, OpenApiOperation operation, CodeClass requestConfigClass, CodeMethod method) { - if (operation.GetRequestSchema(config.StructuredMimeTypes) is OpenApiSchema requestBodySchema) + if (operation.RequestBody is not null && + operation.GetRequestSchema(config.StructuredMimeTypes) is OpenApiSchema requestBodySchema) { CodeTypeBase requestBodyType; if (operation.RequestBody.Content.IsMultipartFormDataSchema(config.StructuredMimeTypes) && operation.RequestBody.Content.IsMultipartTopMimeType(config.StructuredMimeTypes)) { var mediaType = operation.RequestBody.Content.First(x => x.Value.Schema == requestBodySchema).Value; - if (mediaType.Encoding.Any()) + if (mediaType.Encoding is not null && mediaType.Encoding.Any()) { requestBodyType = new CodeType { Name = "MultipartBody", IsExternal = true, }; foreach (var encodingEntry in mediaType.Encoding @@ -1940,9 +1948,10 @@ private static void SetEnumOptions(OpenApiSchema schema, CodeEnum target) OpenApiEnumValuesDescriptionExtension? extensionInformation = null; if (schema.Extensions.TryGetValue(OpenApiEnumValuesDescriptionExtension.Name, out var rawExtension) && rawExtension is OpenApiEnumValuesDescriptionExtension localExtInfo) extensionInformation = localExtInfo; - target.AddOption(schema.Enum.OfType() - .Where(static x => !x.Value.Equals("null", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(x.Value)) - .Select(static x => x.Value) + target.AddOption(schema.Enum.OfType() + .Where(static x => x.GetValueKind() is JsonValueKind.String) + .Select(static x => x.GetValue()) + .Where(static x => !string.IsNullOrEmpty(x)) .Distinct(StringComparer.OrdinalIgnoreCase) .Select((x) => { @@ -2215,7 +2224,7 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin private CodeType? GetCodeTypeForMapping(OpenApiUrlTreeNode currentNode, string referenceId, CodeNamespace currentNamespace, CodeClass? baseClass, OpenApiOperation? currentOperation) { var componentKey = referenceId?.Replace("#/components/schemas/", string.Empty, StringComparison.OrdinalIgnoreCase); - if (openApiDocument == null || !openApiDocument.Components.Schemas.TryGetValue(componentKey, out var discriminatorSchema)) + if (openApiDocument == null || string.IsNullOrEmpty(componentKey) || openApiDocument.Components?.Schemas is null || !openApiDocument.Components.Schemas.TryGetValue(componentKey, out var discriminatorSchema)) { logger.LogWarning("Discriminator {ComponentKey} not found in the OpenAPI document.", componentKey); return null; diff --git a/src/Kiota.Builder/Validation/MultipleServerEntries.cs b/src/Kiota.Builder/Validation/MultipleServerEntries.cs index 05ff96e5c5..98b3dd2167 100644 --- a/src/Kiota.Builder/Validation/MultipleServerEntries.cs +++ b/src/Kiota.Builder/Validation/MultipleServerEntries.cs @@ -8,7 +8,7 @@ public class MultipleServerEntries : ValidationRule { public MultipleServerEntries() : base(nameof(MultipleServerEntries), static (context, document) => { - if (document.Servers.GroupBy(static x => x.Url, StringComparer.OrdinalIgnoreCase).Count() > 1) + if (document.Servers?.GroupBy(static x => x.Url, StringComparer.OrdinalIgnoreCase).Count() > 1) context.CreateWarning(nameof(MultipleServerEntries), "Multiple servers entries were found in the OpenAPI description. Only the first one will be used. The root URL can be set manually with the request adapter."); }) From 99623e1a2a646c11d5ed9dbdf9ff52abd2fec3c0 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 14 Oct 2024 16:06:37 -0400 Subject: [PATCH 03/41] fix: additional NRE Signed-off-by: Vincent Biret --- .../Extensions/OpenApiSchemaExtensions.cs | 4 ++-- src/Kiota.Builder/Plugins/PluginsGenerationService.cs | 11 ++++++----- .../Validation/InconsistentTypeFormatPair.cs | 2 +- src/Kiota.Builder/Validation/NoContentWithBody.cs | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index c5ed4b24e9..31434963dd 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -53,7 +53,7 @@ public static bool IsReferencedSchema(this OpenApiSchema schema) public static bool IsArray(this OpenApiSchema? schema) { - return "array".Equals(schema?.Type, StringComparison.OrdinalIgnoreCase) && schema.Items != null && + return schema is not null && "array".Equals(schema.Type, StringComparison.OrdinalIgnoreCase) && schema.Items is not null && (schema.Items.IsComposedEnum() || schema.Items.IsEnum() || schema.Items.IsSemanticallyMeaningful() || @@ -62,7 +62,7 @@ public static bool IsArray(this OpenApiSchema? schema) public static bool IsObjectType(this OpenApiSchema? schema) { - return "object".Equals(schema?.Type, StringComparison.OrdinalIgnoreCase); + return schema is not null && "object".Equals(schema.Type, StringComparison.OrdinalIgnoreCase); } public static bool HasAnyProperty(this OpenApiSchema? schema) { diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index ef638601fa..a791b281d4 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -107,7 +107,7 @@ private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDoc if (openApiDocument.Paths is null) return openApiDocument; var contentItems = openApiDocument.Paths.Values.Where(static x => x?.Operations is not null) .SelectMany(static x => x.Operations.Values.Where(static x => x?.RequestBody?.Content is not null) - .SelectMany(static x => x.RequestBody.Content.Values)); + .SelectMany(static x => x.RequestBody!.Content.Values)); foreach (var contentItem in contentItems) { var schema = contentItem.Schema; @@ -351,9 +351,9 @@ private static (OpenApiRuntime[], Function[], ConversationStarter[]) GetRuntimes runtimes.Add(new OpenApiRuntime { // Configuration overrides document information - Auth = configAuth ?? GetAuth(operation.Security ?? document.SecurityRequirements), + Auth = configAuth ?? GetAuth(operation.Security ?? document.SecurityRequirements ?? []), Spec = new OpenApiRuntimeSpec { Url = openApiDocumentPath }, - RunForFunctions = [operation.OperationId] + RunForFunctions = [operation.OperationId!] }); var summary = operation.Summary.CleanupXMLString(); @@ -361,7 +361,7 @@ private static (OpenApiRuntime[], Function[], ConversationStarter[]) GetRuntimes functions.Add(new Function { - Name = operation.OperationId, + Name = operation.OperationId!, Description = !string.IsNullOrEmpty(description) ? description : summary, States = GetStatesFromOperation(operation), @@ -441,7 +441,8 @@ SecuritySchemeType.Http when securityScheme.Scheme.Equals("bearer", StringCompar private static State? GetStateFromExtension(OpenApiOperation openApiOperation, string extensionName, Func> instructionsExtractor) { - if (openApiOperation.Extensions.TryGetValue(extensionName, out var rExtRaw) && + if (openApiOperation.Extensions is not null && + openApiOperation.Extensions.TryGetValue(extensionName, out var rExtRaw) && rExtRaw is T rExt && instructionsExtractor(rExt).Exists(static x => !string.IsNullOrEmpty(x))) { diff --git a/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs b/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs index 636bf96689..437aac2b22 100644 --- a/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs +++ b/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs @@ -51,7 +51,7 @@ public class InconsistentTypeFormatPair : ValidationRule }; public InconsistentTypeFormatPair() : base(nameof(InconsistentTypeFormatPair), static (context, schema) => { - if (string.IsNullOrEmpty(schema?.Type) || string.IsNullOrEmpty(schema.Format) || KnownAndNotSupportedFormats.knownAndUnsupportedFormats.Contains(schema.Format) || escapedTypes.Contains(schema.Type)) + if (schema is null || string.IsNullOrEmpty(schema.Type) || string.IsNullOrEmpty(schema.Format) || KnownAndNotSupportedFormats.knownAndUnsupportedFormats.Contains(schema.Format) || escapedTypes.Contains(schema.Type)) return; if (!validPairs.TryGetValue(schema.Type, out var validFormats) || !validFormats.Contains(schema.Format)) context.CreateWarning(nameof(InconsistentTypeFormatPair), $"The format {schema.Format} is not supported by Kiota for the type {schema.Type} and the string type will be used."); diff --git a/src/Kiota.Builder/Validation/NoContentWithBody.cs b/src/Kiota.Builder/Validation/NoContentWithBody.cs index 539c4430e7..29b1c5b960 100644 --- a/src/Kiota.Builder/Validation/NoContentWithBody.cs +++ b/src/Kiota.Builder/Validation/NoContentWithBody.cs @@ -8,7 +8,7 @@ public class NoContentWithBody : ValidationRule { public NoContentWithBody() : base(nameof(NoContentWithBody), static (context, operation) => { - if (operation.Responses.TryGetValue("204", out var response) && (response?.Content?.Any() ?? false)) + if (operation.Responses is not null && operation.Responses.TryGetValue("204", out var response) && (response?.Content?.Any() ?? false)) context.CreateWarning(nameof(NoContentWithBody), "A 204 response with a body media type was found. The response body will be ignored."); }) { From 839202367fe4e6bbf01c9a9d5da47c833446fc4d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 04:41:16 -0500 Subject: [PATCH 04/41] chore: updates reference to oai.net preview --- src/Kiota.Builder/Kiota.Builder.csproj | 4 ++-- src/kiota/kiota.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index b23ec7bc4f..96e4b9cbf5 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -44,9 +44,9 @@ - + - + diff --git a/src/kiota/kiota.csproj b/src/kiota/kiota.csproj index 57ec4596cc..cffd93d309 100644 --- a/src/kiota/kiota.csproj +++ b/src/kiota/kiota.csproj @@ -47,7 +47,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 25e45112782cf04cff868bfda5dabbcf53ab4bef Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 06:50:37 -0500 Subject: [PATCH 05/41] fix: additional 3.1 NRT and type reference fixes --- src/Kiota.Builder/KiotaBuilder.cs | 5 ++-- .../Validation/InconsistentTypeFormatPair.cs | 26 +++++++++---------- .../Validation/MissingDiscriminator.cs | 2 +- src/Kiota.Builder/Validation/NoServerEntry.cs | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index a3fc731565..c8ad541d67 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -34,6 +34,7 @@ using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.ApiManifest; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.MicrosoftExtensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; @@ -2389,7 +2390,7 @@ internal static void AddSerializationMembers(CodeClass model, bool includeAdditi } private CodeClass? CreateOperationParameterClass(OpenApiUrlTreeNode node, OperationType operationType, OpenApiOperation operation, CodeClass parentClass) { - var parameters = node.PathItems[Constants.DefaultOpenApiLabel].Parameters.Union(operation.Parameters).Where(static p => p.In == ParameterLocation.Query).ToArray(); + var parameters = node.PathItems[Constants.DefaultOpenApiLabel].Parameters.Union(operation.Parameters ?? Enumerable.Empty()).Where(static p => p.In == ParameterLocation.Query).ToArray(); if (parameters.Length != 0) { var parameterClass = parentClass.AddInnerClass(new CodeClass @@ -2499,7 +2500,7 @@ private static CodeType GetQueryParameterType(OpenApiSchema schema) var paramType = GetPrimitiveType(schema) ?? new() { IsExternal = true, - Name = schema.Items?.Type ?? schema.Type, + Name = schema.Items is not null && schema.Items.Type.HasValue ? schema.Items.Type.ToIdentifier() : schema.Type.ToIdentifier(), }; paramType.CollectionKind = schema.IsArray() ? CodeTypeBase.CodeTypeCollectionKind.Array : default; diff --git a/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs b/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs index 437aac2b22..ecdd6edc2f 100644 --- a/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs +++ b/src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs @@ -7,9 +7,9 @@ namespace Kiota.Builder.Validation; public class InconsistentTypeFormatPair : ValidationRule { - private static readonly Dictionary> validPairs = new(StringComparer.OrdinalIgnoreCase) + private static readonly Dictionary> validPairs = new() { - ["string"] = new(StringComparer.OrdinalIgnoreCase) { + [JsonSchemaType.String] = new(StringComparer.OrdinalIgnoreCase) { "commonmark", "html", "date", @@ -21,7 +21,7 @@ public class InconsistentTypeFormatPair : ValidationRule "binary", "byte", }, - ["integer"] = new(StringComparer.OrdinalIgnoreCase) { + [JsonSchemaType.Integer] = new(StringComparer.OrdinalIgnoreCase) { "int32", "int64", "int8", @@ -29,7 +29,7 @@ public class InconsistentTypeFormatPair : ValidationRule "int16", "uint16", }, - ["number"] = new(StringComparer.OrdinalIgnoreCase) { + [JsonSchemaType.Number] = new(StringComparer.OrdinalIgnoreCase) { "float", "double", "decimal", @@ -41,19 +41,17 @@ public class InconsistentTypeFormatPair : ValidationRule "uint16", }, }; - private static readonly HashSet escapedTypes = new(StringComparer.OrdinalIgnoreCase) { - "array", - "boolean", - "const", - "enum", - "null", - "object", - }; + private static readonly HashSet escapedTypes = [ + JsonSchemaType.Array, + JsonSchemaType.Boolean, + JsonSchemaType.Null, + JsonSchemaType.Object, + ]; public InconsistentTypeFormatPair() : base(nameof(InconsistentTypeFormatPair), static (context, schema) => { - if (schema is null || string.IsNullOrEmpty(schema.Type) || string.IsNullOrEmpty(schema.Format) || KnownAndNotSupportedFormats.knownAndUnsupportedFormats.Contains(schema.Format) || escapedTypes.Contains(schema.Type)) + if (schema is null || !schema.Type.HasValue || string.IsNullOrEmpty(schema.Format) || KnownAndNotSupportedFormats.knownAndUnsupportedFormats.Contains(schema.Format) || escapedTypes.Contains(schema.Type.Value)) return; - if (!validPairs.TryGetValue(schema.Type, out var validFormats) || !validFormats.Contains(schema.Format)) + if (!validPairs.TryGetValue(schema.Type.Value, out var validFormats) || !validFormats.Contains(schema.Format)) context.CreateWarning(nameof(InconsistentTypeFormatPair), $"The format {schema.Format} is not supported by Kiota for the type {schema.Type} and the string type will be used."); }) { diff --git a/src/Kiota.Builder/Validation/MissingDiscriminator.cs b/src/Kiota.Builder/Validation/MissingDiscriminator.cs index c889f5cf5a..4fa5b52064 100644 --- a/src/Kiota.Builder/Validation/MissingDiscriminator.cs +++ b/src/Kiota.Builder/Validation/MissingDiscriminator.cs @@ -14,7 +14,7 @@ public MissingDiscriminator(GenerationConfiguration configuration) : base(nameof { var idx = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); document.InitializeInheritanceIndex(idx); - if (document.Components != null) + if (document.Components is { Schemas.Count: > 0 }) Parallel.ForEach(document.Components.Schemas, entry => { ValidateSchema(entry.Value, context, idx, entry.Key); diff --git a/src/Kiota.Builder/Validation/NoServerEntry.cs b/src/Kiota.Builder/Validation/NoServerEntry.cs index 17513ed4f7..8d51b1e9ef 100644 --- a/src/Kiota.Builder/Validation/NoServerEntry.cs +++ b/src/Kiota.Builder/Validation/NoServerEntry.cs @@ -8,7 +8,7 @@ public class NoServerEntry : ValidationRule { public NoServerEntry() : base(nameof(NoServerEntry), static (context, document) => { - if (!document.Servers.Any() || string.IsNullOrEmpty(document.Servers.First().Url?.TrimEnd('/'))) + if (document.Servers is not { Count: > 1 } || string.IsNullOrEmpty(document.Servers[0].Url?.TrimEnd('/'))) context.CreateWarning(nameof(NoServerEntry), "A servers entry (v3) or host + basePath + schemes properties (v2) was not present in the OpenAPI description. The root URL will need to be set manually with the request adapter."); }) From 99dcbfbf4eb6b2fc22af5dee3f54ae44e1d07510 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 07:03:56 -0500 Subject: [PATCH 06/41] fix: additional 3.1 NRT and type reference fixes --- src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs | 2 +- src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs | 2 ++ src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs index 4543d3acbb..aac8f6341f 100644 --- a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs +++ b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs @@ -68,7 +68,7 @@ private void GetHashCodeInternal([DisallowNull] OpenApiSchema obj, HashSet }; public UrlFormEncodedComplex() : base(nameof(UrlFormEncodedComplex), static (context, operation) => { + if (string.IsNullOrEmpty(operation.OperationId)) + return; if (operation.GetRequestSchema(validContentTypes) is OpenApiSchema requestSchema) ValidateSchema(requestSchema, context, operation.OperationId, "request body"); if (operation.GetResponseSchema(validContentTypes) is OpenApiSchema responseSchema) diff --git a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs index c54eb22904..95d66e80e8 100644 --- a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs +++ b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs @@ -24,7 +24,8 @@ public static void AddKiotaValidationRules(this ValidationRuleSet ruleSet, Gener } private static void AddRuleIfEnabled(this ValidationRuleSet ruleSet, GenerationConfiguration configuration, T instance) where T : ValidationRule { - if (!configuration.DisabledValidationRules.Contains(instance.GetType().Name)) - ruleSet.Add(instance); + var ruleType = instance.GetType(); + if (!configuration.DisabledValidationRules.Contains(ruleType.Name)) + ruleSet.Add(ruleType, instance); } } From 6422b453f84688dc2c0491716f3cb53495353fbd Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 07:07:17 -0500 Subject: [PATCH 07/41] fix: wrong value comparison Signed-off-by: Vincent Biret --- src/Kiota.Builder/Validation/NoServerEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Validation/NoServerEntry.cs b/src/Kiota.Builder/Validation/NoServerEntry.cs index 8d51b1e9ef..291ce7ecb0 100644 --- a/src/Kiota.Builder/Validation/NoServerEntry.cs +++ b/src/Kiota.Builder/Validation/NoServerEntry.cs @@ -8,7 +8,7 @@ public class NoServerEntry : ValidationRule { public NoServerEntry() : base(nameof(NoServerEntry), static (context, document) => { - if (document.Servers is not { Count: > 1 } || string.IsNullOrEmpty(document.Servers[0].Url?.TrimEnd('/'))) + if (document.Servers is not { Count: > 0 } || string.IsNullOrEmpty(document.Servers[0].Url?.TrimEnd('/'))) context.CreateWarning(nameof(NoServerEntry), "A servers entry (v3) or host + basePath + schemes properties (v2) was not present in the OpenAPI description. The root URL will need to be set manually with the request adapter."); }) From 4bff2273983a5259f1b96d5afb6eb079fdb09669 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 08:38:45 -0500 Subject: [PATCH 08/41] fix: additional type and NRT fixes Signed-off-by: Vincent Biret --- .../OpenApiUrlTreeNodeExtensions.cs | 16 ++-- src/Kiota.Builder/KiotaBuilder.cs | 86 +++++++++---------- .../OpenApiDocumentDownloadService.cs | 6 +- .../Plugins/PluginsGenerationService.cs | 4 +- src/Kiota.Builder/Validation/NoServerEntry.cs | 3 +- 5 files changed, 57 insertions(+), 58 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs index a49b82968a..98e4e8a6af 100644 --- a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs @@ -69,7 +69,7 @@ internal static string CleanupParametersFromPath(string pathSegment) private static IEnumerable GetParametersForPathItem(OpenApiPathItem pathItem, string nodeSegment) { return pathItem.Parameters - .Union(pathItem.Operations.SelectMany(static x => x.Value.Parameters)) + .Union(pathItem.Operations.SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty())) .Where(static x => x.In == ParameterLocation.Path) .Where(x => nodeSegment.Contains($"{{{x.Name}}}", StringComparison.OrdinalIgnoreCase)); } @@ -193,7 +193,7 @@ public static bool HasRequiredQueryParametersAcrossOperations(this OpenApiUrlTre if (!currentNode.PathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem)) return false; - var operationQueryParameters = pathItem.Operations.SelectMany(static x => x.Value.Parameters); + var operationQueryParameters = pathItem.Operations.SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty()); return operationQueryParameters.Union(pathItem.Parameters).Where(static x => x.In == ParameterLocation.Query) .Any(static x => x.Required); } @@ -207,9 +207,9 @@ public static string GetUrlTemplate(this OpenApiUrlTreeNode currentNode, Operati var pathItem = currentNode.PathItems[Constants.DefaultOpenApiLabel]; var operationQueryParameters = (operationType, pathItem.Operations.Any()) switch { - (OperationType ot, _) when pathItem.Operations.TryGetValue(ot, out var operation) => operation.Parameters, - (null, true) => pathItem.Operations.SelectMany(static x => x.Value.Parameters).Where(static x => x.In == ParameterLocation.Query), - _ => Enumerable.Empty(), + (OperationType ot, _) when pathItem.Operations.TryGetValue(ot, out var operation) && operation.Parameters is not null => operation.Parameters, + (null, true) => pathItem.Operations.SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty()).Where(static x => x.In == ParameterLocation.Query), + _ => [], }; var parameters = pathItem.Parameters .Union(operationQueryParameters) @@ -234,7 +234,7 @@ public static string GetUrlTemplate(this OpenApiUrlTreeNode currentNode, Operati } var pathReservedPathParametersIds = currentNode.PathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pItem) ? pItem.Parameters - .Union(pItem.Operations.SelectMany(static x => x.Value.Parameters)) + .Union(pItem.Operations.SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty())) .Where(static x => x.In == ParameterLocation.Path && x.Extensions.TryGetValue(OpenApiReservedParameterExtension.Name, out var ext) && ext is OpenApiReservedParameterExtension reserved && reserved.IsReserved.HasValue && reserved.IsReserved.Value) .Select(static x => x.Name) .ToHashSet(StringComparer.OrdinalIgnoreCase) : @@ -356,7 +356,7 @@ private static void ReplaceParameterInPathForAllChildNodes(OpenApiUrlTreeNode no if (node.PathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem)) { foreach (var pathParameter in pathItem.Parameters - .Union(pathItem.Operations.SelectMany(static x => x.Value.Parameters)) + .Union(pathItem.Operations.SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty())) .Where(x => x.In == ParameterLocation.Path && oldName.Equals(x.Name, StringComparison.Ordinal))) { pathParameter.Name = newParameterName; @@ -386,7 +386,7 @@ private static void CopyNodeIntoOtherNode(OpenApiUrlTreeNode source, OpenApiUrlT pathItem .Value .Operations - .SelectMany(static x => x.Value.Parameters) + .SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty()) .Where(x => x.In == ParameterLocation.Path && pathParameterNameToReplace.Equals(x.Name, StringComparison.Ordinal)) )) { diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index c8ad541d67..c04a01f47e 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1082,7 +1082,7 @@ private CodeIndexer[] CreateIndexer(string childIdentifier, string childType, Co result.Add(backCompatibleValue); } - return result.ToArray(); + return [.. result]; } private static readonly StructuralPropertiesReservedNameProvider structuralPropertiesReservedNameProvider = new(); @@ -1091,7 +1091,9 @@ private CodeIndexer[] CreateIndexer(string childIdentifier, string childType, Co var propertyName = childIdentifier.CleanupSymbolName(); if (structuralPropertiesReservedNameProvider.ReservedNames.Contains(propertyName)) propertyName += "Property"; - var resultType = existingType ?? GetPrimitiveType(propertySchema, childType); + var resultType = existingType ?? GetPrimitiveType(propertySchema); + if ((propertySchema?.Items?.IsEnum() ?? false) && resultType is CodeType codeType) + codeType.Name = childType; if (resultType == null) return null; var prop = new CodeProperty { @@ -1128,57 +1130,55 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten } return prop; } - private static readonly HashSet typeNamesToSkip = new(StringComparer.OrdinalIgnoreCase) { "object", "array" }; - private static CodeType? GetPrimitiveType(OpenApiSchema? typeSchema, string? childType = default) + private static readonly HashSet typeNamesToSkip = [JsonSchemaType.Object, JsonSchemaType.Array]; + private static CodeType? GetPrimitiveType(OpenApiSchema? typeSchema) { - var typeNames = new List { typeSchema?.Items?.Type, childType, typeSchema?.Type }; + var typeNames = new List { typeSchema?.Items?.Type, typeSchema?.Type }; if (typeSchema?.AnyOf?.Any() ?? false) typeNames.AddRange(typeSchema.AnyOf.Select(x => x.Type)); // double is sometimes an anyof string, number and enum if (typeSchema?.OneOf?.Any() ?? false) typeNames.AddRange(typeSchema.OneOf.Select(x => x.Type)); // double is sometimes an oneof string, number and enum // first value that's not null, and not "object" for primitive collections, the items type matters - var typeName = typeNames.Find(static x => !string.IsNullOrEmpty(x) && !typeNamesToSkip.Contains(x)); + var typeName = typeNames.Find(static x => x is not null && !typeNamesToSkip.Contains(x.Value)); var isExternal = false; - if (typeSchema?.Items?.IsEnum() ?? false) - typeName = childType; - else + var format = typeSchema?.Format ?? typeSchema?.Items?.Format; + var primitiveTypeName = (typeName, format?.ToLowerInvariant()) switch + { + (JsonSchemaType.String, "base64url") => "base64url", + (JsonSchemaType.String, "duration") => "TimeSpan", + (JsonSchemaType.String, "time") => "TimeOnly", + (JsonSchemaType.String, "date") => "DateOnly", + (JsonSchemaType.String, "date-time") => "DateTimeOffset", + (JsonSchemaType.String, "uuid") => "Guid", + (JsonSchemaType.String, _) => "string", // covers commonmark and html + (JsonSchemaType.Number, "double" or "float" or "decimal") => format.ToLowerInvariant(), + (JsonSchemaType.Number or JsonSchemaType.Integer, "int8") => "sbyte", + (JsonSchemaType.Number or JsonSchemaType.Integer, "uint8") => "byte", + (JsonSchemaType.Number or JsonSchemaType.Integer, "int64") => "int64", + (JsonSchemaType.Number, "int16") => "integer", + (JsonSchemaType.Number, "int32") => "integer", + (JsonSchemaType.Number, _) => "double", + (JsonSchemaType.Integer, _) => "integer", + (JsonSchemaType.Boolean, _) => "boolean", + (_, "byte") => "base64", + (_, "binary") => "binary", + //TODO handle the case where we have multiple entries + (_, _) => string.Empty, + }; + if (!string.IsNullOrEmpty(primitiveTypeName)) { - var format = typeSchema?.Format ?? typeSchema?.Items?.Format; - var primitiveTypeName = (typeName?.ToLowerInvariant(), format?.ToLowerInvariant()) switch - { - ("string", "base64url") => "base64url", - ("file", _) => "binary", - ("string", "duration") => "TimeSpan", - ("string", "time") => "TimeOnly", - ("string", "date") => "DateOnly", - ("string", "date-time") => "DateTimeOffset", - ("string", "uuid") => "Guid", - ("string", _) => "string", // covers commonmark and html - ("number", "double" or "float" or "decimal") => format.ToLowerInvariant(), - ("number" or "integer", "int8") => "sbyte", - ("number" or "integer", "uint8") => "byte", - ("number" or "integer", "int64") => "int64", - ("number", "int16") => "integer", - ("number", "int32") => "integer", - ("number", _) => "double", - ("integer", _) => "integer", - ("boolean", _) => "boolean", - (_, "byte") => "base64", - (_, "binary") => "binary", - (_, _) => string.Empty, - }; - if (!string.IsNullOrEmpty(primitiveTypeName)) + return new CodeType { - typeName = primitiveTypeName; - isExternal = true; - } + Name = primitiveTypeName, + IsExternal = true, + }; } - if (string.IsNullOrEmpty(typeName)) + if (typeName is null || typeName.ToIdentifier() is not string normalizedTypeName || string.IsNullOrEmpty(normalizedTypeName)) return null; return new CodeType { - Name = typeName, + Name = normalizedTypeName, IsExternal = isExternal, }; } @@ -1842,7 +1842,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope return CreateComposedModelDeclaration(currentNode, schema, operation, suffix, codeNamespace, isRequestBody, typeNameForInlineSchema); } - if (schema.IsObjectType() || schema.HasAnyProperty() || schema.IsEnum() || !string.IsNullOrEmpty(schema.AdditionalProperties?.Type)) + if (schema.IsObjectType() || schema.HasAnyProperty() || schema.IsEnum() || schema.AdditionalProperties?.Type is not null) { // no inheritance or union type, often empty definitions with only additional properties are used as property bags. return CreateModelDeclarationAndType(currentNode, schema, operation, codeNamespace, suffix, response: responseValue, typeNameForInlineSchema: typeNameForInlineSchema, isRequestBody); @@ -1855,8 +1855,8 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope return CreateCollectionModelDeclaration(currentNode, schema, operation, codeNamespace, typeNameForInlineSchema, isRequestBody); } - if (!string.IsNullOrEmpty(schema.Type) || !string.IsNullOrEmpty(schema.Format)) - return GetPrimitiveType(schema, string.Empty) ?? new CodeType { Name = UntypedNodeName, IsExternal = true }; + if (schema.Type is not null || !string.IsNullOrEmpty(schema.Format)) + return GetPrimitiveType(schema) ?? new CodeType { Name = UntypedNodeName, IsExternal = true }; if ((schema.AnyOf.Any() || schema.OneOf.Any() || schema.AllOf.Any()) && (schema.AnyOf.FirstOrDefault(static x => x.IsSemanticallyMeaningful(true)) ?? schema.OneOf.FirstOrDefault(static x => x.IsSemanticallyMeaningful(true)) ?? schema.AllOf.FirstOrDefault(static x => x.IsSemanticallyMeaningful(true))) is { } childSchema) // we have an empty node because of some local override for schema properties and need to unwrap it. return CreateModelDeclarations(currentNode, childSchema, operation, parentElement, suffixForInlineSchema, response, typeNameForInlineSchema, isRequestBody); @@ -1864,7 +1864,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope } private CodeTypeBase CreateCollectionModelDeclaration(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, OpenApiOperation? operation, CodeNamespace codeNamespace, string typeNameForInlineSchema, bool isRequestBody) { - CodeTypeBase? type = GetPrimitiveType(schema.Items, string.Empty); + CodeTypeBase? type = GetPrimitiveType(schema.Items); var isEnumOrComposedCollectionType = schema.Items.IsEnum() //the collection could be an enum type so override with strong type instead of string type. || schema.Items.IsComposedEnum() && string.IsNullOrEmpty(schema.Items.Format);//the collection could be a composed type with an enum type so override with strong type instead of string type. if ((string.IsNullOrEmpty(type?.Name) diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index ae586c86a3..9e76322596 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -16,7 +16,7 @@ using Kiota.Builder.WorkspaceManagement; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Readers; +using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Validations; namespace Kiota.Builder; @@ -135,8 +135,8 @@ ex is SecurityException || { // couldn't parse the URL, it's probably a local file } - var reader = new OpenApiStreamReader(settings); - var readResult = await reader.ReadAsync(input, cancellationToken).ConfigureAwait(false); + //TODO update to remove the unknown format when the overload is available + var readResult = await OpenApiDocument.LoadAsync(input, "unknown", settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false); stopwatch.Stop(); if (generating) foreach (var warning in readResult.OpenApiDiagnostic.Warnings) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index a791b281d4..19392e9dd7 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -144,9 +144,9 @@ private static OpenApiDocument InlineRequestBodyAllOf(OpenApiDocument openApiDoc foreach (var apiSchema in schema.AllOf) { if (apiSchema.Title is not null) newSchema.Title = apiSchema.Title; - if (!string.IsNullOrEmpty(apiSchema.Type)) + if (apiSchema.Type is not null) { - if (!string.IsNullOrEmpty(newSchema.Type) && newSchema.Type != apiSchema.Type) + if (newSchema.Type is not null && newSchema.Type.Value != apiSchema.Type.Value) { throw new InvalidOperationException( $"The schemas in allOf cannot have different types: '{newSchema.Type}' and '{apiSchema.Type}'."); diff --git a/src/Kiota.Builder/Validation/NoServerEntry.cs b/src/Kiota.Builder/Validation/NoServerEntry.cs index 291ce7ecb0..895744b4b5 100644 --- a/src/Kiota.Builder/Validation/NoServerEntry.cs +++ b/src/Kiota.Builder/Validation/NoServerEntry.cs @@ -1,5 +1,4 @@ -using System.Linq; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Validations; namespace Kiota.Builder.Validation; From 229a425b4da6291dc8c524670777b6ef724f2c48 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 13:13:41 -0500 Subject: [PATCH 09/41] fix: main project builds Signed-off-by: Vincent Biret --- .../Extensions/OpenApiSchemaExtensions.cs | 45 ++++++++++--------- .../Validation/OpenApiSchemaComparer.cs | 17 +++---- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index 31434963dd..187c3a49e1 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using Microsoft.OpenApi.Any; +using System.Text.Json; using Microsoft.OpenApi.Models; namespace Kiota.Builder.Extensions; @@ -53,7 +53,7 @@ public static bool IsReferencedSchema(this OpenApiSchema schema) public static bool IsArray(this OpenApiSchema? schema) { - return schema is not null && "array".Equals(schema.Type, StringComparison.OrdinalIgnoreCase) && schema.Items is not null && + return schema is { Type: JsonSchemaType.Array or (JsonSchemaType.Array | JsonSchemaType.Null) } && schema.Items is not null && (schema.Items.IsComposedEnum() || schema.Items.IsEnum() || schema.Items.IsSemanticallyMeaningful() || @@ -62,7 +62,7 @@ public static bool IsArray(this OpenApiSchema? schema) public static bool IsObjectType(this OpenApiSchema? schema) { - return schema is not null && "object".Equals(schema.Type, StringComparison.OrdinalIgnoreCase); + return schema is { Type: JsonSchemaType.Object or (JsonSchemaType.Object | JsonSchemaType.Null) }; } public static bool HasAnyProperty(this OpenApiSchema? schema) { @@ -128,45 +128,48 @@ public static bool IsExclusiveUnion(this OpenApiSchema? schema) return schema?.OneOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > 1; // so we don't consider one of object/nullable as a union type } - private static readonly HashSet oDataTypes = new(StringComparer.OrdinalIgnoreCase) { - "number", - "integer", - }; + private static readonly HashSet oDataTypes = [ + JsonSchemaType.Number, + JsonSchemaType.Integer, + ]; + private static readonly Func isODataType = static x => x.Type is not null && oDataTypes.Contains(x.Type.Value); + private static readonly Func isStringType = static x => x is { Type: JsonSchemaType.String or (JsonSchemaType.String | JsonSchemaType.Null) }; private static bool IsODataPrimitiveTypeBackwardCompatible(this OpenApiSchema schema) { return schema.IsExclusiveUnion() && schema.OneOf.Count == 3 && schema.OneOf.Count(static x => x.Enum?.Any() ?? false) == 1 && - schema.OneOf.Count(static x => oDataTypes.Contains(x.Type)) == 1 && - schema.OneOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase)) == 1 + schema.OneOf.Count(isODataType) == 1 && + schema.OneOf.Count(isStringType) == 1 || schema.IsInclusiveUnion() && schema.AnyOf.Count == 3 && schema.AnyOf.Count(static x => x.Enum?.Any() ?? false) == 1 && - schema.AnyOf.Count(static x => oDataTypes.Contains(x.Type)) == 1 && - schema.AnyOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase)) == 1; + schema.AnyOf.Count(isODataType) == 1 && + schema.AnyOf.Count(isStringType) == 1; } public static bool IsODataPrimitiveType(this OpenApiSchema schema) { return schema.IsExclusiveUnion() && schema.OneOf.Count == 3 && - schema.OneOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase) && (x.Enum?.Any() ?? false)) == 1 && - schema.OneOf.Count(static x => oDataTypes.Contains(x.Type)) == 1 && - schema.OneOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase)) == 2 + schema.OneOf.Count(static x => isStringType(x) && (x.Enum?.Any() ?? false)) == 1 && + schema.OneOf.Count(isODataType) == 1 && + schema.OneOf.Count(isStringType) == 2 || schema.IsInclusiveUnion() && schema.AnyOf.Count == 3 && - schema.AnyOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase) && (x.Enum?.Any() ?? false)) == 1 && - schema.AnyOf.Count(static x => oDataTypes.Contains(x.Type)) == 1 && - schema.AnyOf.Count(static x => "string".Equals(x.Type, StringComparison.OrdinalIgnoreCase)) == 2 + schema.AnyOf.Count(static x => isStringType(x) && (x.Enum?.Any() ?? false)) == 1 && + schema.AnyOf.Count(isODataType) == 1 && + schema.AnyOf.Count(isStringType) == 2 || schema.IsODataPrimitiveTypeBackwardCompatible(); } public static bool IsEnum(this OpenApiSchema schema) { if (schema is null) return false; - return schema.Enum.OfType().Any(static x => !string.IsNullOrEmpty(x.Value)) && - (string.IsNullOrEmpty(schema.Type) || "string".Equals(schema.Type, StringComparison.OrdinalIgnoreCase)); // number and boolean enums are not supported + return schema.Enum.Any(static x => x.GetValueKind() is JsonValueKind.String && + x.GetValue() is string value && + !string.IsNullOrEmpty(value)); // number and boolean enums are not supported } public static bool IsComposedEnum(this OpenApiSchema schema) { @@ -180,8 +183,8 @@ public static bool IsSemanticallyMeaningful(this OpenApiSchema schema, bool igno return schema.HasAnyProperty() || (!ignoreEnums && schema.Enum is { Count: > 0 }) || (!ignoreArrays && schema.Items != null) || - (!ignoreType && !string.IsNullOrEmpty(schema.Type) && - ((ignoreNullableObjects && !"object".Equals(schema.Type, StringComparison.OrdinalIgnoreCase)) || + (!ignoreType && schema.Type is not null && + ((ignoreNullableObjects && !schema.IsObjectType()) || !ignoreNullableObjects)) || !string.IsNullOrEmpty(schema.Format) || !string.IsNullOrEmpty(schema.Reference?.Id); diff --git a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs index aac8f6341f..1d7b2c1fcb 100644 --- a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs +++ b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Text.Json.Nodes; using Kiota.Builder.Extensions; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; @@ -11,16 +12,16 @@ namespace Kiota.Builder.Validation; internal class OpenApiSchemaComparer : IEqualityComparer { private readonly OpenApiDiscriminatorComparer discriminatorComparer; - private readonly OpenApiAnyComparer openApiAnyComparer; + private readonly JsonNodeComparer jsonNodeComparer; private readonly KeyValueComparer schemaMapComparer; public OpenApiSchemaComparer( OpenApiDiscriminatorComparer? discriminatorComparer = null, - OpenApiAnyComparer? openApiAnyComparer = null, + JsonNodeComparer? jsonNodeComparer = null, KeyValueComparer? schemaMapComparer = null) { this.discriminatorComparer = discriminatorComparer ?? new OpenApiDiscriminatorComparer(); - this.openApiAnyComparer = openApiAnyComparer ?? new OpenApiAnyComparer(); + this.jsonNodeComparer = jsonNodeComparer ?? new JsonNodeComparer(); this.schemaMapComparer = schemaMapComparer ?? new KeyValueComparer(StringComparer.Ordinal, this); } @@ -53,7 +54,7 @@ private void GetHashCodeInternal([DisallowNull] OpenApiSchema obj, HashSet +internal class JsonNodeComparer : IEqualityComparer { /// - public bool Equals(OpenApiAny? x, OpenApiAny? y) + public bool Equals(JsonNode? x, JsonNode? y) { if (x is null || y is null) return object.Equals(x, y); // TODO: Can we use the OpenAPI.NET implementation of Equals? - return x.Node.GetValueKind() == y.Node.GetValueKind() && string.Equals(x.Node.ToString(), y.Node.ToString(), StringComparison.OrdinalIgnoreCase); + return x.GetValueKind() == y.GetValueKind() && string.Equals(x.GetValue(), y.GetValue(), StringComparison.OrdinalIgnoreCase); } /// - public int GetHashCode([DisallowNull] OpenApiAny obj) + public int GetHashCode([DisallowNull] JsonNode obj) { var hash = new HashCode(); if (obj == null) return hash.ToHashCode(); From 193a7b9b970bf851c2ef3fb99e091e5f50215243 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 14:07:44 -0500 Subject: [PATCH 10/41] fix: all validation tests migrated to the new OAI.net object model Signed-off-by: Vincent Biret --- .../DivergentResponseSchemaTests.cs | 50 ++++------ .../Validation/GetWithBodyTests.cs | 48 ++++----- .../InconsistentTypeFormatPairTests.cs | 50 ++++------ .../KnownAndNotSupportedFormatsTests.cs | 51 ++++------ .../Validation/MissingDiscriminatorTests.cs | 74 +++++--------- .../Validation/MultipleServerEntriesTests.cs | 38 ++++--- .../Validation/NoContentWithBodyTests.cs | 51 ++++------ .../Validation/NoServerEntryTests.cs | 38 ++++--- .../Validation/UrlFormEncodedComplexTests.cs | 98 +++++++------------ .../ValidationRuleSetExtensionsTests.cs | 8 +- 10 files changed, 205 insertions(+), 301 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs index 6bdc1bd756..c50ae4e9e3 100644 --- a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs @@ -1,8 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -10,9 +11,8 @@ namespace Kiota.Builder.Tests.Validation; public class DivergentResponseSchemaTests { [Fact] - public void DoesntAddAWarningWhenBodyIsSingle() + public async Task DoesntAddAWarningWhenBodyIsSingle() { - var rule = new DivergentResponseSchema(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -28,18 +28,12 @@ public void DoesntAddAWarningWhenBodyIsSingle() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void AddsAWarningWhenBodyIsDivergent() + public async Task AddsAWarningWhenBodyIsDivergent() { - var rule = new DivergentResponseSchema(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -61,18 +55,12 @@ public void AddsAWarningWhenBodyIsDivergent() schema: type: string format: int64"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenUsing2XX() + public async Task DoesntAddAWarningWhenUsing2XX() { - var rule = new DivergentResponseSchema(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -94,12 +82,16 @@ public void DoesntAddAWarningWhenUsing2XX() schema: type: string format: int64"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new DivergentResponseSchema(new()); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(DivergentResponseSchema), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs index 99ba847d8c..e04999b87a 100644 --- a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs @@ -1,6 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Readers; using Microsoft.OpenApi.Validations; using Xunit; @@ -10,9 +13,8 @@ namespace Kiota.Builder.Tests.Validation; public class GetWithBodyTests { [Fact] - public void AddsAWarningWhenGetWithBody() + public async Task AddsAWarningWhenGetWithBody() { - var rule = new GetWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -29,18 +31,12 @@ public void AddsAWarningWhenGetWithBody() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenGetWithNoBody() + public async Task DoesntAddAWarningWhenGetWithNoBody() { - var rule = new GetWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -55,18 +51,12 @@ public void DoesntAddAWarningWhenGetWithNoBody() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenPostWithBody() + public async Task DoesntAddAWarningWhenPostWithBody() { - var rule = new GetWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -83,12 +73,16 @@ public void DoesntAddAWarningWhenPostWithBody() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new GetWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(GetWithBody), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs index 9b46823c30..34b965b2fe 100644 --- a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs @@ -1,17 +1,17 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; public class InconsistentTypeFormatPairTests { [Fact] - public void AddsAWarningWhenKnownInconsistentPair() + public async Task AddsAWarningWhenKnownInconsistentPair() { - var rule = new InconsistentTypeFormatPair(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -27,18 +27,12 @@ public void AddsAWarningWhenKnownInconsistentPair() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenSupportedPair() + public async Task DoesntAddAWarningWhenSupportedPair() { - var rule = new InconsistentTypeFormatPair(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -54,18 +48,12 @@ public void DoesntAddAWarningWhenSupportedPair() schema: type: string format: uuid"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntFailWhenKnownAlternative() + public async Task DoesntFailWhenKnownAlternative() { - var rule = new InconsistentTypeFormatPair(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -81,12 +69,16 @@ public void DoesntFailWhenKnownAlternative() schema: type: enum format: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new InconsistentTypeFormatPair(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs index 8df9463cf9..2a3dfbe407 100644 --- a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs @@ -1,8 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -10,9 +11,8 @@ namespace Kiota.Builder.Tests.Validation; public class KnownAndNotSupportedFormatsTests { [Fact] - public void AddsAWarningWhenKnownUnsupportedFormat() + public async Task AddsAWarningWhenKnownUnsupportedFormat() { - var rule = new KnownAndNotSupportedFormats(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -28,18 +28,12 @@ public void AddsAWarningWhenKnownUnsupportedFormat() schema: type: string format: email"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenSupportedFormat() + public async Task DoesntAddAWarningWhenSupportedFormat() { - var rule = new KnownAndNotSupportedFormats(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -55,18 +49,12 @@ public void DoesntAddAWarningWhenSupportedFormat() schema: type: string format: uuid"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntFailWhenNoFormat() + public async Task DoesntFailWhenNoFormat() { - var rule = new KnownAndNotSupportedFormats(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -81,13 +69,16 @@ public void DoesntFailWhenNoFormat() application/json: schema: type: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new KnownAndNotSupportedFormats(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } - } diff --git a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs index d112997287..58404f74d6 100644 --- a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs @@ -1,17 +1,17 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; public class MissingDiscriminatorTests { [Fact] - public void DoesntAddAWarningWhenBodyIsSimple() + public async Task DoesntAddAWarningWhenBodyIsSimple() { - var rule = new MissingDiscriminator(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -27,18 +27,12 @@ public void DoesntAddAWarningWhenBodyIsSimple() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void AddsWarningOnInlineSchemas() + public async Task AddsWarningOnInlineSchemas() { - var rule = new MissingDiscriminator(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -62,18 +56,12 @@ public void AddsWarningOnInlineSchemas() properties: type2: type: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void AddsWarningOnComponentSchemas() + public async Task AddsWarningOnComponentSchemas() { - var rule = new MissingDiscriminator(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -105,18 +93,12 @@ public void AddsWarningOnComponentSchemas() application/json: schema: $ref: '#/components/schemas/type3'"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() + public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() { - var rule = new MissingDiscriminator(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -150,18 +132,12 @@ public void DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() application/json: schema: $ref: '#/components/schemas/type3'"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntAddsWarningOnComponentSchemasScalars() + public async Task DoesntAddsWarningOnComponentSchemasScalars() { - var rule = new MissingDiscriminator(new()); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -185,12 +161,16 @@ public void DoesntAddsWarningOnComponentSchemasScalars() application/json: schema: $ref: '#/components/schemas/type1'"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MissingDiscriminator(new()); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs index 0bbd417140..a4e0934e8b 100644 --- a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs @@ -1,8 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -10,9 +11,8 @@ namespace Kiota.Builder.Tests.Validation; public class MultipleServerEntriesTests { [Fact] - public void AddsAWarningWhenMultipleServersPresent() + public async Task AddsAWarningWhenMultipleServersPresent() { - var rule = new MultipleServerEntries(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -28,18 +28,12 @@ public void AddsAWarningWhenMultipleServersPresent() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenSingleServerPresent() + public async Task DoesntAddAWarningWhenSingleServerPresent() { - var rule = new MultipleServerEntries(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -54,12 +48,16 @@ public void DoesntAddAWarningWhenSingleServerPresent() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MultipleServerEntries(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs index d0924580c3..900228a339 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs @@ -1,8 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -10,9 +11,8 @@ namespace Kiota.Builder.Tests.Validation; public class NoContentWithBodyTests { [Fact] - public void AddsAWarningWhen204WithBody() + public async Task AddsAWarningWhen204WithBody() { - var rule = new NoContentWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -25,18 +25,12 @@ public void AddsAWarningWhen204WithBody() '204': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhen204WithNoBody() + public async Task DoesntAddAWarningWhen204WithNoBody() { - var rule = new NoContentWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -49,18 +43,12 @@ public void DoesntAddAWarningWhen204WithNoBody() get: responses: '204':"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhen200WithBody() + public async Task DoesntAddAWarningWhen200WithBody() { - var rule = new NoContentWithBody(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -77,13 +65,16 @@ public void DoesntAddAWarningWhen200WithBody() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoContentWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } - } diff --git a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs index acae1bf4b3..beeea627c6 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs @@ -1,8 +1,9 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -10,9 +11,8 @@ namespace Kiota.Builder.Tests.Validation; public class NoServerEntryTests { [Fact] - public void AddsAWarningWhenNoServersPresent() + public async Task AddsAWarningWhenNoServersPresent() { - var rule = new NoServerEntry(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -25,18 +25,12 @@ public void AddsAWarningWhenNoServersPresent() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenServerPresent() + public async Task DoesntAddAWarningWhenServerPresent() { - var rule = new NoServerEntry(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -51,12 +45,16 @@ public void DoesntAddAWarningWhenServerPresent() '200': content: application/json:"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoServerEntry(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoServerEntry), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs index a45f0f9498..f74ecbcd80 100644 --- a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs @@ -1,17 +1,17 @@ using System.IO; using System.Text; +using System.Threading.Tasks; using Kiota.Builder.Validation; -using Microsoft.OpenApi.Readers; -using Microsoft.OpenApi.Validations; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Kiota.Builder.Tests.Validation; public class UrlFormEncodedComplexTests { [Fact] - public void AddsAWarningWhenUrlEncodedNotObjectRequestBody() + public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -33,18 +33,12 @@ public void AddsAWarningWhenUrlEncodedNotObjectRequestBody() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void AddsAWarningWhenUrlEncodedNotObjectResponse() + public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -60,18 +54,12 @@ public void AddsAWarningWhenUrlEncodedNotObjectResponse() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -98,18 +86,12 @@ public void AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() schema: type: string format: int32"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -130,18 +112,12 @@ public void AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() properties: prop: type: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Single(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenUrlEncoded() + public async Task DoesntAddAWarningWhenUrlEncoded() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -159,18 +135,12 @@ public void DoesntAddAWarningWhenUrlEncoded() properties: prop: type: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningOnArrayProperty() + public async Task DoesntAddAWarningOnArrayProperty() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -199,18 +169,12 @@ public void DoesntAddAWarningOnArrayProperty() properties: prop: type: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); } [Fact] - public void DoesntAddAWarningWhenNotUrlEncoded() + public async Task DoesntAddAWarningWhenNotUrlEncoded() { - var rule = new UrlFormEncodedComplex(); var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -226,12 +190,16 @@ public void DoesntAddAWarningWhenNotUrlEncoded() schema: type: enum format: string"; - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(documentTxt)); - var reader = new OpenApiStreamReader(new OpenApiReaderSettings - { - RuleSet = new(new ValidationRule[] { rule }), - }); - var doc = reader.Read(stream, out var diag); - Assert.Empty(diag.Warnings); + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new UrlFormEncodedComplex(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.OpenApiDiagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs b/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs index 7159d17db0..26800d8df4 100644 --- a/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs @@ -19,7 +19,7 @@ public void DisablesAllRules() var ruleSet = new ValidationRuleSet(); var configuration = new GenerationConfiguration { DisabledValidationRules = new() { "all" } }; ruleSet.AddKiotaValidationRules(configuration); - Assert.Empty(ruleSet); + Assert.Empty(ruleSet.Rules); } [Fact] public void DisablesNoRule() @@ -27,7 +27,7 @@ public void DisablesNoRule() var ruleSet = new ValidationRuleSet(); var configuration = new GenerationConfiguration { DisabledValidationRules = new() }; ruleSet.AddKiotaValidationRules(configuration); - Assert.NotEmpty(ruleSet); + Assert.NotEmpty(ruleSet.Rules); } [Fact] public void DisablesOneRule() @@ -35,7 +35,7 @@ public void DisablesOneRule() var ruleSet = new ValidationRuleSet(); var configuration = new GenerationConfiguration { DisabledValidationRules = new() { nameof(NoServerEntry) } }; ruleSet.AddKiotaValidationRules(configuration); - Assert.NotEmpty(ruleSet); - Assert.DoesNotContain(ruleSet, static x => x.GetType() == typeof(NoServerEntry)); + Assert.NotEmpty(ruleSet.Rules); + Assert.DoesNotContain(ruleSet.Rules, static x => x.GetType() == typeof(NoServerEntry)); } } From 294d80e9fd398ea66825e89bd26213bf2b5a64d1 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 14:32:36 -0500 Subject: [PATCH 11/41] fix: openapi extension migrated to new OAI.net model Signed-off-by: Vincent Biret --- ...piAiReasoningInstructionsExtensionTests.cs | 16 +++++-- ...iAiRespondingInstructionsExtensionTests.cs | 16 +++++-- ...penApiDescriptionForModelExtensionTests.cs | 4 +- .../OpenApiKiotaExtensionTests.cs | 48 ++++++++++--------- 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs index 5b34465903..1c511b92f2 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs @@ -1,12 +1,13 @@ using System; using System.IO; using System.Net.Http; +using System.Text; +using System.Text.Json.Nodes; using System.Threading.Tasks; using Kiota.Builder.Configuration; using Kiota.Builder.OpenApiExtensions; using Microsoft.Extensions.Logging; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Writers; using Moq; using Xunit; @@ -22,10 +23,15 @@ public void Dispose() [Fact] public void Parses() { - var oaiValue = new OpenApiArray { - new OpenApiString("This is a description"), - new OpenApiString("This is a description 2"), - }; + var oaiValueRepresentation = + """ + [ + "This is a description", + "This is a description 2", + ] + """; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(oaiValueRepresentation)); + var oaiValue = JsonNode.Parse(stream); var value = OpenApiAiReasoningInstructionsExtension.Parse(oaiValue); Assert.NotNull(value); Assert.Equal("This is a description", value.ReasoningInstructions[0]); diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs index d14f85a70e..158f280ea6 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs @@ -1,12 +1,13 @@ using System; using System.IO; using System.Net.Http; +using System.Text; +using System.Text.Json.Nodes; using System.Threading.Tasks; using Kiota.Builder.Configuration; using Kiota.Builder.OpenApiExtensions; using Microsoft.Extensions.Logging; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Writers; using Moq; using Xunit; @@ -22,10 +23,15 @@ public void Dispose() [Fact] public void Parses() { - var oaiValue = new OpenApiArray { - new OpenApiString("This is a description"), - new OpenApiString("This is a description 2"), - }; + var oaiValueRepresentation = + """ + [ + "This is a description", + "This is a description 2", + ] + """; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(oaiValueRepresentation)); + var oaiValue = JsonNode.Parse(stream); var value = OpenApiAiRespondingInstructionsExtension.Parse(oaiValue); Assert.NotNull(value); Assert.Equal("This is a description", value.RespondingInstructions[0]); diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiDescriptionForModelExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiDescriptionForModelExtensionTests.cs index bfcec098c2..c81192394a 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiDescriptionForModelExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiDescriptionForModelExtensionTests.cs @@ -6,7 +6,6 @@ using Kiota.Builder.OpenApiExtensions; using Microsoft.Extensions.Logging; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Writers; using Moq; using Xunit; @@ -22,8 +21,7 @@ public void Dispose() [Fact] public void Parses() { - var oaiValue = new OpenApiString("This is a description"); - var value = OpenApiDescriptionForModelExtension.Parse(oaiValue); + var value = OpenApiDescriptionForModelExtension.Parse("This is a description"); Assert.NotNull(value); Assert.Equal("This is a description", value.Description); } diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs index beb4c3fe4f..e7f9dba6f8 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs @@ -1,7 +1,8 @@ using System.IO; +using System.Text; +using System.Text.Json.Nodes; using Kiota.Builder.OpenApiExtensions; using Microsoft.OpenApi; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Writers; using Xunit; @@ -48,29 +49,32 @@ public void Serializes() [Fact] public void Parses() { - var oaiValue = new OpenApiObject + var oaiValueRepresentation = + """ { - { "languagesInformation", new OpenApiObject { - {"CSharp", new OpenApiObject { - {"dependencies", new OpenApiArray { - new OpenApiObject { - {"name", new OpenApiString("Microsoft.Graph.Core")}, - {"version", new OpenApiString("1.0.0") }, - {"type", new OpenApiString("bundle")} - } - }}, - {"dependencyInstallCommand", new OpenApiString("dotnet add package") }, - {"maturityLevel", new OpenApiString("Preview")}, - {"clientClassName", new OpenApiString("GraphServiceClient")}, - {"clientNamespaceName", new OpenApiString("Microsoft.Graph")}, - {"structuredMimeTypes", new OpenApiArray { - new OpenApiString("application/json"), - new OpenApiString("application/xml")} - }, - } + "languagesInformation": { + "CSharp": { + "dependencies": [ + { + "name": "Microsoft.Graph.Core", + "version": "1.0.0", + "type": "bundle" + } + ], + "dependencyInstallCommand": "dotnet add package", + "maturityLevel": "Preview", + "clientClassName": "GraphServiceClient", + "clientNamespaceName": "Microsoft.Graph", + "structuredMimeTypes": [ + "application/json", + "application/xml" + ] } - }} - }; + } + } + """; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(oaiValueRepresentation)); + var oaiValue = JsonNode.Parse(stream); var value = OpenApiKiotaExtension.Parse(oaiValue); Assert.NotNull(value); Assert.True(value.LanguagesInformation.TryGetValue("CSharp", out var CSEntry)); From 2d879383e5d38d01547d8c8aefee257fcbcdb99c Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 12 Nov 2024 14:45:35 -0500 Subject: [PATCH 12/41] fix: main tests build Signed-off-by: Vincent Biret --- .../ContentTypeMappingTests.cs | 24 +- .../OpenApiSchemaExtensionsTests.cs | 98 +-- .../OpenApiUrlTreeNodeExtensionsTests.cs | 98 +-- .../Kiota.Builder.Tests/KiotaBuilderTests.cs | 651 +++++++++--------- .../Plugins/PluginsGenerationServiceTests.cs | 71 +- 5 files changed, 469 insertions(+), 473 deletions(-) diff --git a/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs b/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs index 07cd3bd7c4..1c1c020583 100644 --- a/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs +++ b/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs @@ -83,11 +83,11 @@ public void GeneratesTheRightReturnTypeBasedOnContentAndStatus(string contentTyp { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -177,11 +177,11 @@ public void GeneratesTheRightParameterTypeBasedOnContentAndStatus(string content { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -269,11 +269,11 @@ public void GeneratesTheRightAcceptHeaderBasedOnContentAndStatus(string contentM ["200"] = new OpenApiResponse { Content = contentMediaTypes.Split(',').Select(x => new {Key = x.Trim(), value = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -297,11 +297,11 @@ public void GeneratesTheRightAcceptHeaderBasedOnContentAndStatus(string contentM Schemas = new Dictionary { { "myobject", new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -360,11 +360,11 @@ public void GeneratesTheRightContentTypeHeaderBasedOnContentAndStatus(string con { Content = contentMediaTypes.Split(',').Select(x => new {Key = x.Trim(), value = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -387,11 +387,11 @@ public void GeneratesTheRightContentTypeHeaderBasedOnContentAndStatus(string con Schemas = new Dictionary { { "myobject", new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs index d0c7a81f9f..02e3288755 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; - +using System.Text.Json.Nodes; using Kiota.Builder.Extensions; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; @@ -49,8 +49,8 @@ public void Defensive() Assert.Null(OpenApiSchemaExtensions.MergeIntersectionSchemaEntries(null)); Assert.False(new OpenApiSchema { Reference = null }.IsReferencedSchema()); - Assert.False(new OpenApiSchema { Type = null }.IsArray()); - Assert.False(new OpenApiSchema { Type = null }.IsObjectType()); + Assert.False(new OpenApiSchema { Type = JsonSchemaType.Null }.IsArray()); + Assert.False(new OpenApiSchema { Type = JsonSchemaType.Null }.IsObjectType()); Assert.False(new OpenApiSchema { AnyOf = null }.IsInclusiveUnion()); Assert.False(new OpenApiSchema { AllOf = null }.IsInherited()); Assert.False(new OpenApiSchema { AllOf = null }.IsIntersection()); @@ -486,7 +486,7 @@ public void IsInherited() { AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Reference = new() { Id = "microsoft.graph.entity" }, @@ -495,7 +495,7 @@ public void IsInherited() } }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema() } @@ -512,7 +512,7 @@ public void IsIntersection() { AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Reference = new() { Id = "microsoft.graph.entity" }, @@ -521,7 +521,7 @@ public void IsIntersection() } }, new() { - Type = "object", + Type = JsonSchemaType.Object, Reference = new() { Id = "microsoft.graph.user" }, @@ -538,13 +538,13 @@ public void IsIntersection() { AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["id"] = new OpenApiSchema() } }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema() } @@ -558,7 +558,7 @@ public void IsIntersection() { AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["id"] = new OpenApiSchema() } @@ -577,7 +577,7 @@ public void MergesIntersection() Deprecated = true, AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Reference = new() { Id = "microsoft.graph.entity" }, @@ -586,7 +586,7 @@ public void MergesIntersection() } }, new() { - Type = "object", + Type = JsonSchemaType.Object, Reference = new() { Id = "microsoft.graph.user" }, @@ -613,23 +613,23 @@ public void MergesIntersectionRecursively() Deprecated = true, AllOf = new List { new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["id"] = new OpenApiSchema() } }, new() { - Type = "object", + Type = JsonSchemaType.Object, AllOf = new List() { new () { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), ["lastName"] = new OpenApiSchema() } }, new () { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["lastName"] = new OpenApiSchema() } @@ -652,7 +652,7 @@ public void IsArrayFalseOnEmptyItems() { var schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema(), }; Assert.False(schema.IsArray()); @@ -662,7 +662,7 @@ public void IsArrayFalseOnNullItems() { var schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, }; Assert.False(schema.IsArray()); } @@ -671,27 +671,27 @@ public void IsEnumFailsOnEmptyMembers() { var schema = new OpenApiSchema { - Type = "string", - Enum = new List(), + Type = JsonSchemaType.String, + Enum = new List(), }; Assert.False(schema.IsEnum()); - schema.Enum.Add(new OpenApiString("")); + schema.Enum.Add(""); Assert.False(schema.IsEnum()); } private static readonly OpenApiSchema enumSchema = new OpenApiSchema { Title = "riskLevel", - Enum = new List + Enum = new List { - new OpenApiString("low"), - new OpenApiString("medium"), - new OpenApiString("high"), - new OpenApiString("hidden"), - new OpenApiString("none"), - new OpenApiString("unknownFutureValue") - }, - Type = "string" + "low", + "medium", + "high", + "hidden", + "none", + "unknownFutureValue" + }, + Type = JsonSchemaType.String }; [Fact] public void IsEnumIgnoresNullableUnions() @@ -703,7 +703,7 @@ public void IsEnumIgnoresNullableUnions() enumSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -720,7 +720,7 @@ public void IsEnumFailsOnNullableInheritance() enumSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -737,7 +737,7 @@ public void IsEnumIgnoresNullableExclusiveUnions() enumSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -746,7 +746,7 @@ public void IsEnumIgnoresNullableExclusiveUnions() } private static readonly OpenApiSchema numberSchema = new OpenApiSchema { - Type = "number", + Type = JsonSchemaType.Number, Format = "double", }; [Fact] @@ -760,7 +760,7 @@ public void IsEnumDoesNotMaskExclusiveUnions() numberSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -778,7 +778,7 @@ public void IsEnumDoesNotMaskUnions() numberSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -794,24 +794,24 @@ public void IsOdataPrimitive() { new () { - Type = "number", + Type = JsonSchemaType.Number, Format = "double", Nullable = true }, new () { - Type = "string", + Type = JsonSchemaType.String, Nullable = true }, new () { - Enum = new List() + Enum = new List { - new OpenApiString("INF"), - new OpenApiString("INF"), - new OpenApiString("NaN"), + "INF", + "INF", + "NaN", }, - Type = "string", + Type = JsonSchemaType.String, Nullable = true } } @@ -827,20 +827,20 @@ public void IsOdataPrimitiveBackwardCompatible() { new () { - Type = "number", + Type = JsonSchemaType.Number, Format = "double", }, new () { - Type = "string", + Type = JsonSchemaType.String, }, new () { - Enum = new List() + Enum = new List() { - new OpenApiString("INF"), - new OpenApiString("INF"), - new OpenApiString("NaN"), + "INF", + "INF", + "NaN", } } } diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs index 718248ee2f..0a073478b1 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs @@ -145,7 +145,7 @@ public void GetUrlTemplateSelectsDistinctQueryParameters() In = ParameterLocation.Path, Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -153,7 +153,7 @@ public void GetUrlTemplateSelectsDistinctQueryParameters() Name = "$select", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -168,7 +168,7 @@ public void GetUrlTemplateSelectsDistinctQueryParameters() In = ParameterLocation.Path, Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -176,7 +176,7 @@ public void GetUrlTemplateSelectsDistinctQueryParameters() Name = "$select", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -206,7 +206,7 @@ public void DifferentUrlTemplatesPerOperation() Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -219,7 +219,7 @@ public void DifferentUrlTemplatesPerOperation() Name = "$select", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -256,7 +256,7 @@ public void DifferentUrlTemplatesPerOperationWithRequiredParameter() Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -269,7 +269,7 @@ public void DifferentUrlTemplatesPerOperationWithRequiredParameter() Name = "$select", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -283,7 +283,7 @@ public void DifferentUrlTemplatesPerOperationWithRequiredParameter() Name = "$expand", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -300,7 +300,7 @@ public void DifferentUrlTemplatesPerOperationWithRequiredParameter() Name = "id", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, Required = true @@ -335,7 +335,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInPathItem() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -343,7 +343,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInPathItem() In = ParameterLocation.Query, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -351,7 +351,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInPathItem() In = ParameterLocation.Query, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -381,7 +381,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInOperation() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -389,7 +389,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInOperation() In = ParameterLocation.Query, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -397,7 +397,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInOperation() In = ParameterLocation.Query, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -423,7 +423,7 @@ public void GeneratesOnlyOptionalQueryParametersInPathItem() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -431,14 +431,14 @@ public void GeneratesOnlyOptionalQueryParametersInPathItem() In = ParameterLocation.Query, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { Name = "apikey", In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -468,21 +468,21 @@ public void GeneratesOnlyOptionalQueryParametersInOperation() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { Name = "filter", In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { Name = "apikey", In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -508,7 +508,7 @@ public void GeneratesOnlyRequiredQueryParametersInPathItem() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -516,7 +516,7 @@ public void GeneratesOnlyRequiredQueryParametersInPathItem() In = ParameterLocation.Query, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -524,7 +524,7 @@ public void GeneratesOnlyRequiredQueryParametersInPathItem() Required = true, In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -554,7 +554,7 @@ public void GeneratesOnlyRequiredQueryParametersInOperation() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -562,7 +562,7 @@ public void GeneratesOnlyRequiredQueryParametersInOperation() Required = true, In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter { @@ -570,7 +570,7 @@ public void GeneratesOnlyRequiredQueryParametersInOperation() Required = true, In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -599,7 +599,7 @@ public void GetUrlTemplateCleansInvalidParameters() In = ParameterLocation.Path, Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -607,7 +607,7 @@ public void GetUrlTemplateCleansInvalidParameters() Name = "$select", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -615,7 +615,7 @@ public void GetUrlTemplateCleansInvalidParameters() Name = "api-version", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -623,7 +623,7 @@ public void GetUrlTemplateCleansInvalidParameters() Name = "api~topic", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, }, @@ -631,7 +631,7 @@ public void GetUrlTemplateCleansInvalidParameters() Name = "api.encoding", In = ParameterLocation.Query, Schema = new () { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -669,7 +669,7 @@ public void GetsClassNameWithIndexerAndExtension() In = ParameterLocation.Path, Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -679,7 +679,7 @@ public void GetsClassNameWithIndexerAndExtension() Content = new Dictionary() { {"application/json", new() { Schema = new () { - Type = "string" + Type = JsonSchemaType.String } }} } @@ -711,7 +711,7 @@ public void GetsClassNameWithSegmentsToSkipForClassNames() In = ParameterLocation.Path, Required = true, Schema = new() { - Type = "string" + Type = JsonSchemaType.String }, Style = ParameterStyle.Simple, } @@ -728,7 +728,7 @@ public void GetsClassNameWithSegmentsToSkipForClassNames() { Schema = new () { - Type = "object", + Type = JsonSchemaType.Object, Title = "json", Reference = new OpenApiReference() { @@ -763,16 +763,16 @@ public void SinglePathParametersAreDeduplicated() { var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "displayName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -794,7 +794,7 @@ public void SinglePathParametersAreDeduplicated() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, }, @@ -823,7 +823,7 @@ public void SinglePathParametersAreDeduplicated() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, }, @@ -855,7 +855,7 @@ public void SinglePathParametersAreDeduplicated() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, }, @@ -912,11 +912,11 @@ public void SinglePathParametersAreDeduplicatedAndOrderIsRespected() { var ownerSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -928,11 +928,11 @@ public void SinglePathParametersAreDeduplicatedAndOrderIsRespected() }; var repoSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -1023,7 +1023,7 @@ public void repro4085() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -1044,7 +1044,7 @@ public void repro4085() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 606bbe5c62..d1dbc550d3 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Net.Http; using System.Text; +using System.Text.Json.Nodes; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -1354,10 +1355,10 @@ public void Single_path_with_get_collection() { Schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "int" + Type = JsonSchemaType.Integer } } } @@ -1399,19 +1400,19 @@ public void OData_doubles_as_one_of() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ OneOf = new List{ new OpenApiSchema{ - Type = "number" + Type = JsonSchemaType.Number }, new OpenApiSchema{ - Type = "string" + Type = JsonSchemaType.String }, new OpenApiSchema { - Enum = new List { new OpenApiString("-INF"), new OpenApiString("INF"), new OpenApiString("NaN") } + Enum = new List { "-INF", "INF", "NaN" } } }, Format = "double" @@ -1451,20 +1452,20 @@ public void OData_doubles_as_one_of_format_inside() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ OneOf = new List{ new OpenApiSchema{ - Type = "number", + Type = JsonSchemaType.Number, Format = "double" }, new OpenApiSchema{ - Type = "string" + Type = JsonSchemaType.String }, new OpenApiSchema { - Enum = new List { new OpenApiString("-INF"), new OpenApiString("INF"), new OpenApiString("NaN") } + Enum = new List { "-INF", "INF", "NaN" } } }, } @@ -1503,19 +1504,19 @@ public void OData_doubles_as_any_of() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ AnyOf = new List{ new OpenApiSchema{ - Type = "number" + Type = JsonSchemaType.Number }, new OpenApiSchema{ - Type = "string" + Type = JsonSchemaType.String }, new OpenApiSchema { - Enum = new List { new OpenApiString("-INF"), new OpenApiString("INF"), new OpenApiString("NaN") } + Enum = new List { "-INF", "INF", "NaN" } } }, Format = "double" @@ -1541,15 +1542,15 @@ public void MultiNestedArraysSupportedAsUntypedNodes() { var fooSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "sortBy", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -1609,16 +1610,16 @@ public void Object_Arrays_are_supported() { var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "displayName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -1644,17 +1645,17 @@ public void Object_Arrays_are_supported() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "value", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = userSchema } }, { "unknown", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { } } @@ -1711,7 +1712,7 @@ public void TextPlainEndpointsAreSupported() ["text/plain"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "number", + Type = JsonSchemaType.Number, Format = "int32", } } @@ -1740,22 +1741,22 @@ public void Supports_Path_Parameters() { var resourceActionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Title = "resourceAction", Properties = new Dictionary { { "allowedResourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, { "notAllowedResourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -1768,11 +1769,11 @@ public void Supports_Path_Parameters() }; var permissionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "resourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { AnyOf = new List { resourceActionSchema, @@ -1800,7 +1801,7 @@ public void Supports_Path_Parameters() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -1814,7 +1815,7 @@ public void Supports_Path_Parameters() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { AnyOf = new List { permissionSchema, @@ -1861,22 +1862,22 @@ public void Supports_Path_Query_And_Header_Parameters() { var resourceActionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Title = "resourceAction", Properties = new Dictionary { { "allowedResourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, { "notAllowedResourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -1889,11 +1890,11 @@ public void Supports_Path_Query_And_Header_Parameters() }; var permissionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "resourceActions", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { AnyOf = new List { resourceActionSchema, @@ -1921,7 +1922,7 @@ public void Supports_Path_Query_And_Header_Parameters() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter @@ -1930,7 +1931,7 @@ public void Supports_Path_Query_And_Header_Parameters() In = ParameterLocation.Query, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, }, new OpenApiParameter @@ -1940,7 +1941,7 @@ public void Supports_Path_Query_And_Header_Parameters() Description = "ETag", Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, }, new OpenApiParameter @@ -1950,7 +1951,7 @@ public void Supports_Path_Query_And_Header_Parameters() Description = "Consistency level", Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, } }, @@ -1964,7 +1965,7 @@ public void Supports_Path_Query_And_Header_Parameters() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { AnyOf = new List { permissionSchema, @@ -2031,7 +2032,7 @@ public void DeduplicatesConflictingParameterNamesForCLI() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, new OpenApiParameter @@ -2040,7 +2041,7 @@ public void DeduplicatesConflictingParameterNamesForCLI() In = ParameterLocation.Query, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, }, new OpenApiParameter @@ -2049,7 +2050,7 @@ public void DeduplicatesConflictingParameterNamesForCLI() In = ParameterLocation.Header, Required = false, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, }, }, @@ -2063,10 +2064,10 @@ public void DeduplicatesConflictingParameterNamesForCLI() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { { "foo", new() { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -2105,11 +2106,11 @@ public void Inline_Property_Inheritance_Is_Supported() { var resourceSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "info", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -2135,19 +2136,19 @@ public void Inline_Property_Inheritance_Is_Supported() ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "derivedResource", new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "info2", new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "title", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2203,7 +2204,7 @@ public void Inline_Property_Inheritance_Is_Supported2() { var resourceSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Reference = new OpenApiReference { Id = "resource" @@ -2213,7 +2214,7 @@ public void Inline_Property_Inheritance_Is_Supported2() var properties = new Dictionary { - { "info", new OpenApiSchema { Type = "string", } }, + { "info", new OpenApiSchema { Type = JsonSchemaType.String, } }, { "derivedResource", new OpenApiSchema { AllOf = new List { resourceSchema, } } }, }; @@ -2289,11 +2290,11 @@ public void MapsTime() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Format = "time" } } @@ -2331,11 +2332,11 @@ public void MapsDate() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Format = "date" } } @@ -2373,11 +2374,11 @@ public void MapsDuration() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Format = "duration" } } @@ -2415,11 +2416,11 @@ public void AddsErrorMapping() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2435,11 +2436,11 @@ public void AddsErrorMapping() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "errorId", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Extensions = new Dictionary { { OpenApiPrimaryErrorMessageExtension.Name, @@ -2463,11 +2464,11 @@ public void AddsErrorMapping() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "serviceErrorId", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Extensions = new Dictionary { { OpenApiPrimaryErrorMessageExtension.Name, @@ -2491,7 +2492,7 @@ public void AddsErrorMapping() { Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -2504,11 +2505,11 @@ public void AddsErrorMapping() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "authenticationRealm", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, Extensions = new Dictionary { { OpenApiPrimaryErrorMessageExtension.Name, @@ -2521,7 +2522,7 @@ public void AddsErrorMapping() }, { "authenticationCode", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2585,11 +2586,11 @@ public void IgnoresErrorCodesWithNoSchema() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2634,11 +2635,11 @@ public void DoesntAddSuffixesToErrorTypesWhenComponents() { var errorSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "errorId", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -2684,11 +2685,11 @@ public void DoesntAddSuffixesToErrorTypesWhenComponents() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2744,11 +2745,11 @@ public void UsesDefaultAs4XXAnd5XXWhenAbsent() { var errorSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "errorId", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -2794,11 +2795,11 @@ public void UsesDefaultAs4XXAnd5XXWhenAbsent() { Schema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "progress", new OpenApiSchema{ - Type = "string", + Type = JsonSchemaType.String, } } } @@ -2853,18 +2854,18 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels() { var weatherForecastSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalPropertiesAllowed = false, Properties = new Dictionary { { "date", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, Format = "date-time" } }, { "temperature", new OpenApiSchema { - Type = "integer", + Type = JsonSchemaType.Integer, Format = "int32" } } @@ -2938,18 +2939,18 @@ public void SquishesLonelyNullables() { var uploadSessionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalPropertiesAllowed = false, Properties = new Dictionary { { "date", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, Format = "date-time" } }, { "temperature", new OpenApiSchema { - Type = "integer", + Type = JsonSchemaType.Integer, Format = "int32" } } @@ -3022,18 +3023,18 @@ public void SquishesLonelyNullablesBothAnyOf() { var uploadSessionSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalPropertiesAllowed = false, Properties = new Dictionary { { "date", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, Format = "date-time" } }, { "temperature", new OpenApiSchema { - Type = "integer", + Type = JsonSchemaType.Integer, Format = "int32" } } @@ -3108,19 +3109,19 @@ public void SupportsArraysInComposedTypes() { var anyOfSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalPropertiesAllowed = false, Properties = new Dictionary { { "date", new OpenApiSchema { AnyOf = [ new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, }, new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, }, }, ] @@ -3191,18 +3192,18 @@ public void SupportsNullableAnyOf() { var anyOfSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalPropertiesAllowed = false, Properties = new Dictionary { { "date", new OpenApiSchema { AnyOf = [ new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, Nullable = true }, new OpenApiSchema { - Type = "number", + Type = JsonSchemaType.Number, Format = "int64", Nullable = true, } @@ -3275,17 +3276,17 @@ public void AddsDiscriminatorMappings() { var entitySchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.entity") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.entity" } } }, @@ -3310,16 +3311,16 @@ public void AddsDiscriminatorMappings() }; var directoryObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.directoryObject") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.directoryObject" } } }, @@ -3410,17 +3411,17 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() { var entitySchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.entity") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.entity" } } }, @@ -3448,16 +3449,16 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() }; var directoryObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.directoryObject") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.directoryObject" } } }, @@ -3473,16 +3474,16 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() }; var fileSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.file") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.file" } } }, @@ -3562,17 +3563,17 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() { var entitySchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.entity") + Type = JsonSchemaType.String, + Default = "microsoft.graph.entity" } } }, @@ -3592,16 +3593,16 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() }; var directoryObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.directoryObject") + Type = JsonSchemaType.String, + Default = "microsoft.graph.directoryObject" } } }, @@ -3617,7 +3618,7 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() }; var directoryObjectsResponse = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, OneOf = new List { entitySchema, directoryObjectSchema @@ -3705,17 +3706,17 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() { var entitySchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.entity") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.entity" } } }, @@ -3735,19 +3736,19 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() }; var directoryObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = new List { entitySchema, new OpenApiSchema { Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.directoryObject") + Type = JsonSchemaType.String, + Default = "microsoft.graph.directoryObject" } } }, @@ -3765,19 +3766,19 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() }; var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = new List { directoryObjectSchema, new OpenApiSchema { Properties = new Dictionary { { "firstName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.firstName") + Type = JsonSchemaType.String, + Default = "microsoft.graph.firstName" } } }, @@ -3883,17 +3884,17 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings { var entitySchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("#microsoft.graph.entity") + Type = JsonSchemaType.String, + Default = "#microsoft.graph.entity" } } }, @@ -3922,7 +3923,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings }; var directoryObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = [ entitySchema, new OpenApiSchema @@ -3930,12 +3931,12 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings Properties = new Dictionary { { "tenant", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.directoryObject") + Type = JsonSchemaType.String, + Default = "microsoft.graph.directoryObject" } } }, @@ -3953,7 +3954,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings }; var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = [ directoryObjectSchema, new OpenApiSchema @@ -3961,12 +3962,12 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings Properties = new Dictionary { { "firstName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "@odata.type", new OpenApiSchema { - Type = "string", - Default = new OpenApiString("microsoft.graph.firstName") + Type = JsonSchemaType.String, + Default = "microsoft.graph.firstName" } } }, @@ -4064,11 +4065,11 @@ public void UnionOfPrimitiveTypesWorks() { var simpleObjet = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4097,7 +4098,7 @@ public void UnionOfPrimitiveTypesWorks() OneOf = new List { simpleObjet, new OpenApiSchema { - Type = "number" + Type = JsonSchemaType.Number } } } @@ -4182,11 +4183,11 @@ public void UnionOfInlineSchemasWorks() { var simpleObjet = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4215,11 +4216,11 @@ public void UnionOfInlineSchemasWorks() OneOf = new List { simpleObjet, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -4265,11 +4266,11 @@ public void IntersectionOfPrimitiveTypesWorks() { var simpleObjet = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4298,7 +4299,7 @@ public void IntersectionOfPrimitiveTypesWorks() AnyOf = new List { simpleObjet, new OpenApiSchema { - Type = "number" + Type = JsonSchemaType.Number } } } @@ -4341,11 +4342,11 @@ public void IntersectionOfInlineSchemasWorks() { var simpleObjet = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4374,11 +4375,11 @@ public void IntersectionOfInlineSchemasWorks() AnyOf = new List { simpleObjet, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -4424,16 +4425,16 @@ public void InheritedTypeWithInlineSchemaWorks() { var baseObject = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "kind", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4455,16 +4456,16 @@ public void InheritedTypeWithInlineSchemaWorks() }; var derivedObject = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = [ baseObject, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "special", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -4488,16 +4489,16 @@ public void InheritedTypeWithInlineSchemaWorks() }; var secondLevelDerivedObject = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AllOf = [ derivedObject, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "moreSpecial", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -4568,38 +4569,37 @@ public void InheritedTypeWithInlineSchemaWorks() Assert.Equal("kind", derivedObjectClass.DiscriminatorInformation.DiscriminatorPropertyName); Assert.NotEmpty(derivedObjectClass.DiscriminatorInformation.DiscriminatorMappings); } - [InlineData("string", "", "string")]// https://spec.openapis.org/registry/format/ - [InlineData("string", "commonmark", "string")] - [InlineData("string", "html", "string")] - [InlineData("string", "date-time", "DateTimeOffset")] - [InlineData("string", "duration", "TimeSpan")] - [InlineData("string", "date", "DateOnly")] - [InlineData("string", "time", "TimeOnly")] - [InlineData("string", "base64url", "base64url")] - [InlineData("string", "uuid", "Guid")] + [InlineData(JsonSchemaType.String, "", "string")]// https://spec.openapis.org/registry/format/ + [InlineData(JsonSchemaType.String, "commonmark", "string")] + [InlineData(JsonSchemaType.String, "html", "string")] + [InlineData(JsonSchemaType.String, "date-time", "DateTimeOffset")] + [InlineData(JsonSchemaType.String, "duration", "TimeSpan")] + [InlineData(JsonSchemaType.String, "date", "DateOnly")] + [InlineData(JsonSchemaType.String, "time", "TimeOnly")] + [InlineData(JsonSchemaType.String, "base64url", "base64url")] + [InlineData(JsonSchemaType.String, "uuid", "Guid")] // floating points can only be declared as numbers - [InlineData("number", "double", "double")] - [InlineData("number", "float", "float")] - [InlineData("number", "decimal", "decimal")] + [InlineData(JsonSchemaType.Number, "double", "double")] + [InlineData(JsonSchemaType.Number, "float", "float")] + [InlineData(JsonSchemaType.Number, "decimal", "decimal")] // integers can only be declared as numbers or integers - [InlineData("number", "int32", "integer")] - [InlineData("integer", "int32", "integer")] - [InlineData("number", "int64", "int64")] - [InlineData("integer", "int64", "int64")] - [InlineData("number", "int8", "sbyte")] - [InlineData("integer", "int8", "sbyte")] - [InlineData("number", "int16", "integer")] - [InlineData("integer", "int16", "integer")] - [InlineData("number", "uint8", "byte")] - [InlineData("integer", "uint8", "byte")] - [InlineData("number", "", "double")] - [InlineData("integer", "", "integer")] - [InlineData("boolean", "", "boolean")] - [InlineData("", "byte", "base64")] - [InlineData("", "binary", "binary")] - [InlineData("file", null, "binary")] + [InlineData(JsonSchemaType.Number, "int32", "integer")] + [InlineData(JsonSchemaType.Integer, "int32", "integer")] + [InlineData(JsonSchemaType.Number, "int64", "int64")] + [InlineData(JsonSchemaType.Integer, "int64", "int64")] + [InlineData(JsonSchemaType.Number, "int8", "sbyte")] + [InlineData(JsonSchemaType.Integer, "int8", "sbyte")] + [InlineData(JsonSchemaType.Number, "int16", "integer")] + [InlineData(JsonSchemaType.Integer, "int16", "integer")] + [InlineData(JsonSchemaType.Number, "uint8", "byte")] + [InlineData(JsonSchemaType.Integer, "uint8", "byte")] + [InlineData(JsonSchemaType.Number, "", "double")] + [InlineData(JsonSchemaType.Integer, "", "integer")] + [InlineData(JsonSchemaType.Boolean, "", "boolean")] + [InlineData(JsonSchemaType.String, "byte", "base64")] + [InlineData(JsonSchemaType.String, "binary", "binary")] [Theory] - public void MapsPrimitiveFormats(string type, string format, string expected) + public void MapsPrimitiveFormats(JsonSchemaType type, string format, string expected) { var document = new OpenApiDocument { @@ -4639,35 +4639,34 @@ public void MapsPrimitiveFormats(string type, string format, string expected) Assert.Equal(expected, method.ReturnType.Name); Assert.True(method.ReturnType.AllTypes.First().IsExternal); } - [InlineData("string", "", "string")]// https://spec.openapis.org/registry/format/ - [InlineData("string", "commonmark", "string")] - [InlineData("string", "html", "string")] - [InlineData("string", "date-time", "DateTimeOffset")] - [InlineData("string", "duration", "TimeSpan")] - [InlineData("string", "date", "DateOnly")] - [InlineData("string", "time", "TimeOnly")] - [InlineData("string", "base64url", "base64url")] + [InlineData(JsonSchemaType.String, "", "string")]// https://spec.openapis.org/registry/format/ + [InlineData(JsonSchemaType.String, "commonmark", "string")] + [InlineData(JsonSchemaType.String, "html", "string")] + [InlineData(JsonSchemaType.String, "date-time", "DateTimeOffset")] + [InlineData(JsonSchemaType.String, "duration", "TimeSpan")] + [InlineData(JsonSchemaType.String, "date", "DateOnly")] + [InlineData(JsonSchemaType.String, "time", "TimeOnly")] + [InlineData(JsonSchemaType.String, "base64url", "base64url")] // floating points can only be declared as numbers - [InlineData("number", "double", "double")] - [InlineData("number", "float", "float")] - [InlineData("number", "decimal", "decimal")] + [InlineData(JsonSchemaType.Number, "double", "double")] + [InlineData(JsonSchemaType.Number, "float", "float")] + [InlineData(JsonSchemaType.Number, "decimal", "decimal")] // integers can only be declared as numbers or integers - [InlineData("number", "int32", "integer")] - [InlineData("integer", "int32", "integer")] - [InlineData("number", "int64", "int64")] - [InlineData("integer", "int64", "int64")] - [InlineData("number", "int8", "sbyte")] - [InlineData("integer", "int8", "sbyte")] - [InlineData("number", "uint8", "byte")] - [InlineData("integer", "uint8", "byte")] - [InlineData("number", "", "double")] - [InlineData("integer", "", "integer")] - [InlineData("boolean", "", "boolean")] - [InlineData("", "byte", "base64")] - [InlineData("", "binary", "binary")] - [InlineData("file", null, "binary")] + [InlineData(JsonSchemaType.Number, "int32", "integer")] + [InlineData(JsonSchemaType.Integer, "int32", "integer")] + [InlineData(JsonSchemaType.Number, "int64", "int64")] + [InlineData(JsonSchemaType.Integer, "int64", "int64")] + [InlineData(JsonSchemaType.Number, "int8", "sbyte")] + [InlineData(JsonSchemaType.Integer, "int8", "sbyte")] + [InlineData(JsonSchemaType.Number, "uint8", "byte")] + [InlineData(JsonSchemaType.Integer, "uint8", "byte")] + [InlineData(JsonSchemaType.Number, "", "double")] + [InlineData(JsonSchemaType.Integer, "", "integer")] + [InlineData(JsonSchemaType.Boolean, "", "boolean")] + [InlineData(JsonSchemaType.String, "byte", "base64")] + [InlineData(JsonSchemaType.String, "binary", "binary")] [Theory] - public void MapsQueryParameterTypes(string type, string format, string expected) + public void MapsQueryParameterTypes(JsonSchemaType type, string format, string expected) { var document = new OpenApiDocument { @@ -4725,9 +4724,9 @@ public void MapsQueryParameterArrayTypes() Name = "query", In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "integer", + Type = JsonSchemaType.Integer, Format = "int64" } } @@ -4773,10 +4772,10 @@ public void MapsEnumQueryParameterType(GenerationLanguage generationLanguage) Name = "query", In = ParameterLocation.Query, Schema = new OpenApiSchema { - Type = "string", - Enum = new List { - new OpenApiString("value1"), - new OpenApiString("value2") + Type = JsonSchemaType.String, + Enum = new List { + "value1", + "value2" } } } @@ -4883,12 +4882,12 @@ public void MapsQueryParameterCollectionKinds(bool isArray) { var baseSchema = new OpenApiSchema { - Type = "number", + Type = JsonSchemaType.Number, Format = "int64" }; var arraySchema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = baseSchema }; var document = new OpenApiDocument @@ -4971,11 +4970,11 @@ public void DoesntGenerateNamespacesWhenNotRequired() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -5034,11 +5033,11 @@ public void GeneratesNamesapacesWhenRequired() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -5097,11 +5096,11 @@ public void IdsResultInIndexers() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5164,25 +5163,25 @@ public void HandlesCollectionOfEnumSchemasInAnyOfWithNullable() var enumSchema = new OpenApiSchema { Title = "riskLevel", - Enum = new List + Enum = new List { - new OpenApiString("low"), - new OpenApiString("medium"), - new OpenApiString("high"), - new OpenApiString("hidden"), - new OpenApiString("none"), - new OpenApiString("unknownFutureValue") + "low", + "medium", + "high", + "hidden", + "none", + "unknownFutureValue" }, - Type = "string" + Type = JsonSchemaType.String }; var myObjectSchema = new OpenApiSchema { Title = "conditionalAccessConditionSet", - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "signInRiskLevels", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { AnyOf = new List @@ -5190,7 +5189,7 @@ public void HandlesCollectionOfEnumSchemasInAnyOfWithNullable() enumSchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Nullable = true } } @@ -5264,25 +5263,25 @@ public void HandlesCollectionOfEnumSchemas() var enumSchema = new OpenApiSchema { Title = "riskLevel", - Enum = new List + Enum = new List { - new OpenApiString("low"), - new OpenApiString("medium"), - new OpenApiString("high"), - new OpenApiString("hidden"), - new OpenApiString("none"), - new OpenApiString("unknownFutureValue") + "low", + "medium", + "high", + "hidden", + "none", + "unknownFutureValue" }, - Type = "string" + Type = JsonSchemaType.String }; var myObjectSchema = new OpenApiSchema { Title = "conditionalAccessConditionSet", - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "signInRiskLevels", new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = enumSchema } } @@ -5352,13 +5351,13 @@ public void InlinePropertiesGenerateTypes() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "tilleggsinformasjon", new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, AdditionalProperties = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -5419,11 +5418,11 @@ public void ModelsDoesntUsePathDescriptionWhenAvailable() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -5485,11 +5484,11 @@ public void CleansUpInvalidDescriptionCharacters() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5553,11 +5552,11 @@ public void AcceptVendorsTypes(string contentType) { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -5640,7 +5639,7 @@ public void ModelsUseDescriptionWhenAvailable(bool excludeBackwardCompatible) Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } } @@ -5693,11 +5692,11 @@ public void Considers200WithSchemaOver2XXWithSchema() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5710,11 +5709,11 @@ public void Considers200WithSchemaOver2XXWithSchema() }; var myOtherObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5788,11 +5787,11 @@ public void Considers2XXWithSchemaOver204WithNoSchema() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5861,11 +5860,11 @@ public void Considers204WithNoSchemaOver206WithNoSchema() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -5934,11 +5933,11 @@ public void DoesntGenerateVoidExecutorOnMixedNoContent(int statusCode) { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6006,11 +6005,11 @@ public void GeneratesVoidReturnTypeForNoContent(int statusCode) { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6081,11 +6080,11 @@ public void StripsCommonModelsPrefix(string[] componentNames, string stripPrefix { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6129,11 +6128,11 @@ public void HandlesContentParameters() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6162,9 +6161,9 @@ public void HandlesContentParameters() { "application/json", new OpenApiMediaType { Schema = new OpenApiSchema { - Type = "array", + Type = JsonSchemaType.Array, Items = new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } } @@ -6216,11 +6215,11 @@ public void HandlesPagingExtension() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6285,11 +6284,11 @@ public void SetsReadonlyProperties(bool isReadonly) { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, ReadOnly = isReadonly, } } @@ -6349,11 +6348,11 @@ public void SupportsIncludeFilterOnRootPath(string inputPattern, int expectedPat { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6414,11 +6413,11 @@ public void SupportsIncludeFilter() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6499,11 +6498,11 @@ public void SupportsExcludeFilter() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6584,11 +6583,11 @@ public void SupportsIncludeFilterWithOperation() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6739,11 +6738,11 @@ public void SupportsIndexingParametersInSubPaths() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -6769,7 +6768,7 @@ public void SupportsIndexingParametersInSubPaths() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -7210,16 +7209,16 @@ public void AddReservedPathParameterSymbol() { var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "displayName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -7241,7 +7240,7 @@ public void AddReservedPathParameterSymbol() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, Extensions = { ["x-ms-reserved-parameter"] = new OpenApiReservedParameterExtension { @@ -7292,16 +7291,16 @@ public void DoesNotAddReservedPathParameterSymbol() { var userSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "id", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } }, { "displayName", new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String } } }, @@ -7323,7 +7322,7 @@ public void DoesNotAddReservedPathParameterSymbol() In = ParameterLocation.Path, Required = true, Schema = new OpenApiSchema { - Type = "string" + Type = JsonSchemaType.String }, Extensions = { ["x-ms-reserved-parameter"] = new OpenApiReservedParameterExtension { @@ -9265,11 +9264,11 @@ public void SupportsIncludeFilterAndExcludeWithOperation() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -9410,11 +9409,11 @@ public void SupportsIncludeFilterAndExcludeWithOperationForSpecificPath() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -9555,11 +9554,11 @@ public void CleansUpOperationIdAddsMissingOperationId() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, @@ -9657,11 +9656,11 @@ public void CleansUpOperationIdChangesOperationId() { var myObjectSchema = new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { { "name", new OpenApiSchema { - Type = "string", + Type = JsonSchemaType.String, } } }, diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 3f74656037..73dddb3268 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -9,7 +9,7 @@ using Kiota.Builder.Plugins; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Readers; +using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Services; using Microsoft.Plugins.Manifest; using Moq; @@ -242,38 +242,36 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Equal(2, resultingManifest.Document.Capabilities.ConversationStarters.Count);// conversation starters are generated for each function Assert.Empty(resultingManifest.Problems);// no problems are expected with names - var openApiReader = new OpenApiStreamReader(); - // Validate the original file. - var originalOpenApiFile = File.OpenRead(simpleDescriptionPath); - var originalDocument = openApiReader.Read(originalOpenApiFile, out var originalDiagnostic); - Assert.Empty(originalDiagnostic.Errors); - - Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Description, resultingManifest.Document.Functions[0].Description);// pulls from description - Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Summary, resultingManifest.Document.Functions[1].Description);// pulls from summary - Assert.Single(originalDocument.Components.Schemas);// one schema originally - Assert.Single(originalDocument.Extensions); // single unsupported extension at root - Assert.Equal(2, originalDocument.Paths.Count); // document has only two paths - Assert.Equal(2, originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // 2 responses originally - Assert.Single(originalDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // 1 UNsupported extension - Assert.Equal(2, originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // 2 responses originally - Assert.Single(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension + using var originalOpenApiFile = File.OpenRead(simpleDescriptionPath); + var originalResult = await OpenApiDocument.LoadAsync(originalOpenApiFile, "yaml"); + Assert.Empty(originalResult.OpenApiDiagnostic.Errors); + + Assert.Equal(originalResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Description, resultingManifest.Document.Functions[0].Description);// pulls from description + Assert.Equal(originalResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Summary, resultingManifest.Document.Functions[1].Description);// pulls from summary + Assert.Single(originalResult.OpenApiDocument.Components.Schemas);// one schema originally + Assert.Single(originalResult.OpenApiDocument.Extensions); // single unsupported extension at root + Assert.Equal(2, originalResult.OpenApiDocument.Paths.Count); // document has only two paths + Assert.Equal(2, originalResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // 2 responses originally + Assert.Single(originalResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // 1 UNsupported extension + Assert.Equal(2, originalResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // 2 responses originally + Assert.Single(originalResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension // Validate the output open api file - var resultOpenApiFile = File.OpenRead(Path.Combine(outputDirectory, OpenApiFileName)); - var resultDocument = openApiReader.Read(resultOpenApiFile, out var diagnostic); - Assert.Empty(diagnostic.Errors); + using var resultOpenApiFile = File.OpenRead(Path.Combine(outputDirectory, OpenApiFileName)); + var resultResult = await OpenApiDocument.LoadAsync(originalOpenApiFile, "yaml"); + Assert.Empty(resultResult.OpenApiDiagnostic.Errors); // Assertions / validations - Assert.Empty(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed - Assert.Empty(resultDocument.Extensions); // no extension at root (unsupported extension is removed) - Assert.Equal(2, resultDocument.Paths.Count); // document has only two paths - Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count, resultDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. - Assert.NotEmpty(resultDocument.Paths["/test"].Operations[OperationType.Get].Responses["200"].Description); // response description string is not empty - Assert.Empty(resultDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // NO UNsupported extension - Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count, resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. - Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty - Assert.Single(resultDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension still present in operation + Assert.Empty(resultResult.OpenApiDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed + Assert.Empty(resultResult.OpenApiDocument.Extensions); // no extension at root (unsupported extension is removed) + Assert.Equal(2, resultResult.OpenApiDocument.Paths.Count); // document has only two paths + Assert.Equal(originalResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count, resultResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. + Assert.NotEmpty(resultResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Responses["200"].Description); // response description string is not empty + Assert.Empty(resultResult.OpenApiDocument.Paths["/test"].Operations[OperationType.Get].Extensions); // NO UNsupported extension + Assert.Equal(originalResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count, resultResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses.Count); // Responses are still intact. + Assert.NotEmpty(resultResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Responses["200"].Description);// response description string is not empty + Assert.Single(resultResult.OpenApiDocument.Paths["/test/{id}"].Operations[OperationType.Get].Extensions); // 1 supported extension still present in operation } #region Security @@ -686,7 +684,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("string", schema.Type); + Assert.Equal(JsonSchemaType.String, schema.Type.Value); Assert.Equal(5, schema.MaxLength); } }, @@ -706,7 +704,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("object", schema.Type); + Assert.Equal(JsonSchemaType.Object, schema.Type.Value); Assert.Equal(3, schema.Properties.Count); } }, @@ -726,7 +724,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("object", schema.Type); + Assert.Equal(JsonSchemaType.Object, schema.Type.Value); Assert.Equal(2, schema.Properties.Count); } }, @@ -746,7 +744,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("object", schema.Type); + Assert.Equal(JsonSchemaType.Object, schema.Type.Value); Assert.Equal(2, schema.Properties.Count); } }, @@ -766,7 +764,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("object", schema.Type); + Assert.Equal(JsonSchemaType.Object, schema.Type.Value); Assert.Single(schema.Properties); } }, @@ -782,7 +780,7 @@ public static TheoryData> Assert.NotEmpty(slicedDocument.Paths); var schema = slicedDocument.Paths["/test"].Operations[OperationType.Post].RequestBody .Content["application/json"].Schema; - Assert.Equal("object", schema.Type); + Assert.Equal(JsonSchemaType.Object, schema.Type.Value); Assert.Single(schema.Properties); } }, @@ -839,9 +837,8 @@ public async Task MergesAllOfRequestBodyAsync(string content, Action Date: Mon, 25 Nov 2024 09:17:17 -0500 Subject: [PATCH 13/41] fix: parsing of dependencies Signed-off-by: Vincent Biret --- src/Kiota.Builder/LanguageInformation.cs | 9 +++++---- .../OpenApiExtensions/OpenApiKiotaExtensionTests.cs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Kiota.Builder/LanguageInformation.cs b/src/Kiota.Builder/LanguageInformation.cs index 7ffa6555a6..2966c90f81 100644 --- a/src/Kiota.Builder/LanguageInformation.cs +++ b/src/Kiota.Builder/LanguageInformation.cs @@ -54,8 +54,9 @@ public static LanguageInformation Parse(JsonNode source) var extension = new LanguageInformation(); if (rawObject.TryGetPropertyValue(nameof(Dependencies).ToFirstCharacterLowerCase(), out var dependencies) && dependencies is JsonArray arrayValue) { - foreach (var entry in arrayValue.OfType()) - extension.Dependencies.Add(LanguageDependency.Parse(entry)); + foreach (var entry in arrayValue) + if (entry is not null) + extension.Dependencies.Add(LanguageDependency.Parse(entry)); } if (rawObject.TryGetPropertyValue(nameof(DependencyInstallCommand).ToFirstCharacterLowerCase(), out var installCommand) && installCommand is JsonValue stringValue) { @@ -75,11 +76,11 @@ public static LanguageInformation Parse(JsonNode source) foreach (var entry in structuredMimeTypesValue.OfType()) extension.StructuredMimeTypes.Add(entry.GetValue()); } - if (rawObject.TryGetValue(nameof(MaturityLevel).ToFirstCharacterLowerCase(), out var maturityLevel) && maturityLevel is OpenApiString maturityLevelValue && Enum.TryParse(maturityLevelValue.Value, true, out var parsedMaturityLevelValue)) + if (rawObject.TryGetPropertyValue(nameof(MaturityLevel).ToFirstCharacterLowerCase(), out var maturityLevel) && maturityLevel is JsonValue maturityLevelValue && maturityLevelValue.GetValueKind() is JsonValueKind.String && Enum.TryParse(maturityLevelValue.GetValue(), true, out var parsedMaturityLevelValue)) { extension.MaturityLevel = parsedMaturityLevelValue; } - if (rawObject.TryGetValue(nameof(SupportExperience).ToFirstCharacterLowerCase(), out var supportExperience) && supportExperience is OpenApiString supportExperienceValue && Enum.TryParse(supportExperienceValue.Value, true, out var parsedSupportExperienceValue)) + if (rawObject.TryGetPropertyValue(nameof(SupportExperience).ToFirstCharacterLowerCase(), out var supportExperience) && supportExperience is JsonValue supportExperienceValue && supportExperienceValue.GetValueKind() is JsonValueKind.String && Enum.TryParse(supportExperienceValue.GetValue(), true, out var parsedSupportExperienceValue)) { extension.SupportExperience = parsedSupportExperienceValue; } diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs index 762bdb1422..50d598a883 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiKiotaExtensionTests.cs @@ -64,7 +64,7 @@ public void Parses() ], "dependencyInstallCommand": "dotnet add package", "maturityLevel": "Preview", - "supportExperience", "Microsoft", + "supportExperience": "Microsoft", "clientClassName": "GraphServiceClient", "clientNamespaceName": "Microsoft.Graph", "structuredMimeTypes": [ From 5db7ad0a15c1ff4677fe4b5d5671ea4419655c93 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 Nov 2024 12:12:37 -0500 Subject: [PATCH 14/41] fix: aligns dependencies versions Signed-off-by: Vincent Biret --- src/kiota/kiota.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kiota/kiota.csproj b/src/kiota/kiota.csproj index f6e4a627db..ae577ae8b1 100644 --- a/src/kiota/kiota.csproj +++ b/src/kiota/kiota.csproj @@ -46,7 +46,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 4c1866df5e26f41a69a5a2fa58434f6675ea987b Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 27 Nov 2024 12:05:30 -0500 Subject: [PATCH 15/41] chore: upgrades additional code --- .../Extensions/OpenApiSchemaExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs index adc6104cc6..77a6fa8f0a 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs @@ -878,7 +878,7 @@ public void ReturnsEmptyPropertyNameOnCircularReferences() entitySchema, new OpenApiSchema { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary { ["firstName"] = new OpenApiSchema From 4daed721bfa62b8b0d20f428928f730ad4c6ff6d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 12:33:54 -0500 Subject: [PATCH 16/41] chore: upgrades to OAI.net preview3 Signed-off-by: Vincent Biret --- src/Kiota.Builder/Kiota.Builder.csproj | 4 +- src/Kiota.Builder/KiotaBuilder.cs | 2 +- .../OpenApiDocumentDownloadService.cs | 15 ++- src/kiota/kiota.csproj | 2 +- .../Plugins/PluginsGenerationServiceTests.cs | 10 +- .../DivergentResponseSchemaTests.cs | 2 +- .../Validation/GetWithBodyTests.cs | 60 ++++----- .../InconsistentTypeFormatPairTests.cs | 60 ++++----- .../KnownAndNotSupportedFormatsTests.cs | 60 ++++----- .../Validation/MissingDiscriminatorTests.cs | 88 ++++++------- .../Validation/MultipleServerEntriesTests.cs | 46 +++---- .../Validation/NoContentWithBodyTests.cs | 60 ++++----- .../Validation/NoServerEntryTests.cs | 46 +++---- .../Validation/UrlFormEncodedComplexTests.cs | 116 +++++++++--------- 14 files changed, 285 insertions(+), 286 deletions(-) diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index 6e020eeb8b..f49a92aa8a 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -44,9 +44,9 @@ - + - + diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 104afea1b5..0e84fd70f0 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -2510,7 +2510,7 @@ private static CodeType GetQueryParameterType(OpenApiSchema schema) var paramType = GetPrimitiveType(schema) ?? new() { IsExternal = true, - Name = schema.Items is not null && schema.Items.Type.HasValue ? schema.Items.Type.ToIdentifier() : schema.Type.ToIdentifier(), + Name = schema.Items is not null && schema.Items.Type.ToIdentifier() is string name ? name : "null", }; paramType.CollectionKind = schema.IsArray() ? CodeTypeBase.CodeTypeCollectionKind.Array : default; diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index 9e76322596..4b4f3376a1 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -135,25 +135,24 @@ ex is SecurityException || { // couldn't parse the URL, it's probably a local file } - //TODO update to remove the unknown format when the overload is available - var readResult = await OpenApiDocument.LoadAsync(input, "unknown", settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false); + var readResult = await OpenApiDocument.LoadAsync(input, settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false); stopwatch.Stop(); if (generating) - foreach (var warning in readResult.OpenApiDiagnostic.Warnings) + foreach (var warning in readResult.Diagnostic.Warnings) Logger.LogWarning("OpenAPI warning: {Pointer} - {Warning}", warning.Pointer, warning.Message); - if (readResult.OpenApiDiagnostic.Errors.Any()) + if (readResult.Diagnostic.Errors.Any()) { - Logger.LogTrace("{Timestamp}ms: Parsed OpenAPI with errors. {Count} paths found.", stopwatch.ElapsedMilliseconds, readResult.OpenApiDocument?.Paths?.Count ?? 0); - foreach (var parsingError in readResult.OpenApiDiagnostic.Errors) + Logger.LogTrace("{Timestamp}ms: Parsed OpenAPI with errors. {Count} paths found.", stopwatch.ElapsedMilliseconds, readResult.Document?.Paths?.Count ?? 0); + foreach (var parsingError in readResult.Diagnostic.Errors) { Logger.LogError("OpenAPI error: {Pointer} - {Message}", parsingError.Pointer, parsingError.Message); } } else { - Logger.LogTrace("{Timestamp}ms: Parsed OpenAPI successfully. {Count} paths found.", stopwatch.ElapsedMilliseconds, readResult.OpenApiDocument?.Paths?.Count ?? 0); + Logger.LogTrace("{Timestamp}ms: Parsed OpenAPI successfully. {Count} paths found.", stopwatch.ElapsedMilliseconds, readResult.Document?.Paths?.Count ?? 0); } - return readResult.OpenApiDocument; + return readResult.Document; } } diff --git a/src/kiota/kiota.csproj b/src/kiota/kiota.csproj index da67751739..3a39216ede 100644 --- a/src/kiota/kiota.csproj +++ b/src/kiota/kiota.csproj @@ -47,7 +47,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 83b327fc5b..7c95108189 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -263,8 +263,8 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() // Validate the original file. using var originalOpenApiFile = File.OpenRead(simpleDescriptionPath); var originalResult = await OpenApiDocument.LoadAsync(originalOpenApiFile, "yaml"); - var originalDocument = originalResult.OpenApiDocument; - Assert.Empty(originalResult.OpenApiDiagnostic.Errors); + var originalDocument = originalResult.Document; + Assert.Empty(originalResult.Diagnostic.Errors); Assert.Equal(originalDocument.Paths["/test"].Operations[OperationType.Get].Description, resultingManifest.Document.Functions[0].Description);// pulls from description Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[OperationType.Get].Summary, resultingManifest.Document.Functions[1].Description);// pulls from summary @@ -281,8 +281,8 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() // Validate the output open api file using var resultOpenApiFile = File.OpenRead(Path.Combine(outputDirectory, OpenApiFileName)); var resultResult = await OpenApiDocument.LoadAsync(originalOpenApiFile, "yaml"); - var resultDocument = resultResult.OpenApiDocument; - Assert.Empty(resultResult.OpenApiDiagnostic.Errors); + var resultDocument = resultResult.Document; + Assert.Empty(resultResult.Diagnostic.Errors); // Assertions / validations Assert.Empty(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed @@ -798,7 +798,7 @@ public async Task MergesAllOfRequestBodyAsync(string content, Action GetDiagnosticFromDocumentAsync(stri var settings = new OpenApiReaderSettings(); settings.RuleSet.Add(typeof(DivergentResponseSchema), [rule]); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; + return result.Diagnostic; } } diff --git a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs index e04999b87a..3512b156b0 100644 --- a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs @@ -12,10 +12,10 @@ namespace Kiota.Builder.Tests.Validation; public class GetWithBodyTests { - [Fact] - public async Task AddsAWarningWhenGetWithBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenGetWithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -31,13 +31,13 @@ public async Task AddsAWarningWhenGetWithBody() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenGetWithNoBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenGetWithNoBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -51,13 +51,13 @@ public async Task DoesntAddAWarningWhenGetWithNoBody() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenPostWithBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenPostWithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -73,16 +73,16 @@ public async Task DoesntAddAWarningWhenPostWithBody() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new GetWithBody(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(GetWithBody), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new GetWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(GetWithBody), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs index 34b965b2fe..070c33da97 100644 --- a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs @@ -9,10 +9,10 @@ namespace Kiota.Builder.Tests.Validation; public class InconsistentTypeFormatPairTests { - [Fact] - public async Task AddsAWarningWhenKnownInconsistentPair() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenKnownInconsistentPair() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -27,13 +27,13 @@ public async Task AddsAWarningWhenKnownInconsistentPair() schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSupportedPair() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSupportedPair() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -48,13 +48,13 @@ public async Task DoesntAddAWarningWhenSupportedPair() schema: type: string format: uuid"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntFailWhenKnownAlternative() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntFailWhenKnownAlternative() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -69,16 +69,16 @@ public async Task DoesntFailWhenKnownAlternative() schema: type: enum format: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new InconsistentTypeFormatPair(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new InconsistentTypeFormatPair(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs index 2a3dfbe407..fe4aec47ff 100644 --- a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs @@ -10,10 +10,10 @@ namespace Kiota.Builder.Tests.Validation; public class KnownAndNotSupportedFormatsTests { - [Fact] - public async Task AddsAWarningWhenKnownUnsupportedFormat() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenKnownUnsupportedFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -28,13 +28,13 @@ public async Task AddsAWarningWhenKnownUnsupportedFormat() schema: type: string format: email"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSupportedFormat() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSupportedFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -49,13 +49,13 @@ public async Task DoesntAddAWarningWhenSupportedFormat() schema: type: string format: uuid"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntFailWhenNoFormat() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntFailWhenNoFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -69,16 +69,16 @@ public async Task DoesntFailWhenNoFormat() application/json: schema: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new KnownAndNotSupportedFormats(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new KnownAndNotSupportedFormats(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs index 58404f74d6..8ac4e316e3 100644 --- a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs @@ -9,10 +9,10 @@ namespace Kiota.Builder.Tests.Validation; public class MissingDiscriminatorTests { - [Fact] - public async Task DoesntAddAWarningWhenBodyIsSimple() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task DoesntAddAWarningWhenBodyIsSimple() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -27,13 +27,13 @@ public async Task DoesntAddAWarningWhenBodyIsSimple() schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task AddsWarningOnInlineSchemas() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task AddsWarningOnInlineSchemas() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -56,13 +56,13 @@ public async Task AddsWarningOnInlineSchemas() properties: type2: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsWarningOnComponentSchemas() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsWarningOnComponentSchemas() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -93,13 +93,13 @@ public async Task AddsWarningOnComponentSchemas() application/json: schema: $ref: '#/components/schemas/type3'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -132,13 +132,13 @@ public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformatio application/json: schema: $ref: '#/components/schemas/type3'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddsWarningOnComponentSchemasScalars() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddsWarningOnComponentSchemasScalars() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -161,16 +161,16 @@ public async Task DoesntAddsWarningOnComponentSchemasScalars() application/json: schema: $ref: '#/components/schemas/type1'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new MissingDiscriminator(new()); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MissingDiscriminator(new()); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs index a4e0934e8b..6e195b4a69 100644 --- a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs @@ -10,10 +10,10 @@ namespace Kiota.Builder.Tests.Validation; public class MultipleServerEntriesTests { - [Fact] - public async Task AddsAWarningWhenMultipleServersPresent() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenMultipleServersPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -28,13 +28,13 @@ public async Task AddsAWarningWhenMultipleServersPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSingleServerPresent() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSingleServerPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -48,16 +48,16 @@ public async Task DoesntAddAWarningWhenSingleServerPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new MultipleServerEntries(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MultipleServerEntries(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs index 900228a339..50cc2f9149 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs @@ -10,10 +10,10 @@ namespace Kiota.Builder.Tests.Validation; public class NoContentWithBodyTests { - [Fact] - public async Task AddsAWarningWhen204WithBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhen204WithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -25,13 +25,13 @@ public async Task AddsAWarningWhen204WithBody() '204': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhen204WithNoBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhen204WithNoBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -43,13 +43,13 @@ public async Task DoesntAddAWarningWhen204WithNoBody() get: responses: '204':"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhen200WithBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhen200WithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -65,16 +65,16 @@ public async Task DoesntAddAWarningWhen200WithBody() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new NoContentWithBody(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoContentWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs index beeea627c6..5aecbb914d 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs @@ -10,10 +10,10 @@ namespace Kiota.Builder.Tests.Validation; public class NoServerEntryTests { - [Fact] - public async Task AddsAWarningWhenNoServersPresent() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenNoServersPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -25,13 +25,13 @@ public async Task AddsAWarningWhenNoServersPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenServerPresent() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenServerPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -45,16 +45,16 @@ public async Task DoesntAddAWarningWhenServerPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new NoServerEntry(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoServerEntry), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoServerEntry(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoServerEntry), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs index f74ecbcd80..ce49c615b7 100644 --- a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs @@ -9,10 +9,10 @@ namespace Kiota.Builder.Tests.Validation; public class UrlFormEncodedComplexTests { - [Fact] - public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -33,13 +33,13 @@ public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -54,13 +54,13 @@ public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -86,13 +86,13 @@ public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -112,13 +112,13 @@ public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenUrlEncoded() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenUrlEncoded() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -135,13 +135,13 @@ public async Task DoesntAddAWarningWhenUrlEncoded() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningOnArrayProperty() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningOnArrayProperty() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -169,13 +169,13 @@ public async Task DoesntAddAWarningOnArrayProperty() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenNotUrlEncoded() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenNotUrlEncoded() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -190,16 +190,16 @@ public async Task DoesntAddAWarningWhenNotUrlEncoded() schema: type: enum format: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new UrlFormEncodedComplex(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.OpenApiDiagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new UrlFormEncodedComplex(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } From 9c9f988fe9a7aca9c37110e60c6f5c22025dd00b Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 12:47:08 -0500 Subject: [PATCH 17/41] fix: registers missing reader Signed-off-by: Vincent Biret --- src/Kiota.Builder/OpenApiDocumentDownloadService.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index 4b4f3376a1..1739f502b5 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -17,6 +17,7 @@ using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Microsoft.OpenApi.Validations; namespace Kiota.Builder; @@ -30,6 +31,8 @@ public OpenApiDocumentDownloadService(HttpClient httpClient, ILogger logger) ArgumentNullException.ThrowIfNull(logger); HttpClient = httpClient; Logger = logger; + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); } private static readonly AsyncKeyedLocker localFilesLock = new(o => { From 9cebd6cacc99771e735bfaff56ce05cc57029a0e Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 13:03:39 -0500 Subject: [PATCH 18/41] fix: bad boolean algebra Signed-off-by: Vincent Biret --- src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index 585c1ae2ed..e3bad1ce44 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -80,7 +80,7 @@ public static bool IsInherited(this OpenApiSchema? schema) var meaningfulMemberSchemas = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf) .Where(static x => x.IsSemanticallyMeaningful(ignoreEnums: true, ignoreArrays: true, ignoreType: true)) // the next line ensures the meaningful schema are objects as it won't make sense inheriting from a primitive despite it being meaningful. - .Where(static x => string.IsNullOrEmpty(x.Reference?.Id) || x.Type is null || !x.Type.HasValue || (x.Type.Value ^ JsonSchemaType.Object) is JsonSchemaType.Object) + .Where(static x => string.IsNullOrEmpty(x.Reference?.Id) || x.Type is null || !x.Type.HasValue || (x.Type.Value & JsonSchemaType.Object) is JsonSchemaType.Object) .ToArray(); var isRootSchemaMeaningful = schema.IsSemanticallyMeaningful(ignoreEnums: true, ignoreArrays: true, ignoreType: true); return meaningfulMemberSchemas.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) == 1 && From 893a5ae791c4b2ae8507ff715abece26255dc403 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 13:20:40 -0500 Subject: [PATCH 19/41] chore: linting Signed-off-by: Vincent Biret --- src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index e3bad1ce44..8c814b0e07 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -309,7 +309,7 @@ internal static string GetDiscriminatorPropertyName(this OpenApiSchema schema, H internal static IEnumerable> GetDiscriminatorMappings(this OpenApiSchema schema, ConcurrentDictionary> inheritanceIndex) { if (schema == null) - return Enumerable.Empty>(); + return []; if (!(schema.Discriminator?.Mapping?.Any() ?? false)) if (schema.OneOf.Any()) return schema.OneOf.SelectMany(x => GetDiscriminatorMappings(x, inheritanceIndex)); @@ -322,9 +322,9 @@ internal static IEnumerable> GetDiscriminatorMappin return GetAllInheritanceSchemaReferences(schema.Reference.Id, inheritanceIndex) .Where(static x => !string.IsNullOrEmpty(x)) .Select(x => KeyValuePair.Create(x, x)) - .Union(new[] { KeyValuePair.Create(schema.Reference.Id, schema.Reference.Id) }); + .Union([KeyValuePair.Create(schema.Reference.Id, schema.Reference.Id)]); else - return Enumerable.Empty>(); + return []; return schema.Discriminator .Mapping; From c1e21aa93af256807e104e51d2ac291627ced9e3 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 14:13:06 -0500 Subject: [PATCH 20/41] fix: class naming for discriminator mapping Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 0e84fd70f0..f054297386 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -2240,8 +2240,11 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin logger.LogWarning("Discriminator {ComponentKey} not found in the OpenAPI document.", componentKey); return null; } + // the new version of OAI.net does not mutate the source schema anymore when resolving references which is a positive thing but is challenging for naming. + var schemaClone = new OpenApiSchema(discriminatorSchema); + schemaClone.Reference ??= new OpenApiReference { Id = referenceId }; // Call CreateModelDeclarations with isViaDiscriminator=true. This is for a special case where we always generate a base class when types are referenced via a oneOf discriminator. - if (CreateModelDeclarations(currentNode, discriminatorSchema, currentOperation, GetShortestNamespace(currentNamespace, discriminatorSchema), string.Empty, null, string.Empty, false, true) is not CodeType result) + if (CreateModelDeclarations(currentNode, schemaClone, currentOperation, GetShortestNamespace(currentNamespace, schemaClone), string.Empty, null, string.Empty, false, true) is not CodeType result) { logger.LogWarning("Discriminator {ComponentKey} is not a valid model and points to a union type.", componentKey); return null; From 5f7e287319f67ca910e32482f62a32674d52c1f6 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 14:24:18 -0500 Subject: [PATCH 21/41] fix: further fix of missing reference ids Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index f054297386..cda9fd26d4 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -2242,7 +2242,7 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin } // the new version of OAI.net does not mutate the source schema anymore when resolving references which is a positive thing but is challenging for naming. var schemaClone = new OpenApiSchema(discriminatorSchema); - schemaClone.Reference ??= new OpenApiReference { Id = referenceId }; + schemaClone.Reference ??= new OpenApiReference { Id = componentKey, Type = ReferenceType.Schema }; // Call CreateModelDeclarations with isViaDiscriminator=true. This is for a special case where we always generate a base class when types are referenced via a oneOf discriminator. if (CreateModelDeclarations(currentNode, schemaClone, currentOperation, GetShortestNamespace(currentNamespace, schemaClone), string.Empty, null, string.Empty, false, true) is not CodeType result) { From 77f3a55a74db00f16e3d14a233babdcc68e6eaff Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 14:28:13 -0500 Subject: [PATCH 22/41] fix: wrong method overload use Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationServiceTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 7c95108189..ddc6a98d9f 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -796,8 +796,8 @@ public async Task MergesAllOfRequestBodyAsync(string content, Action Date: Fri, 20 Dec 2024 14:31:17 -0500 Subject: [PATCH 23/41] fix: wrong test data Signed-off-by: Vincent Biret --- .../OpenApiAiReasoningInstructionsExtensionTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs index 1c511b92f2..cd7492744f 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiReasoningInstructionsExtensionTests.cs @@ -27,7 +27,7 @@ public void Parses() """ [ "This is a description", - "This is a description 2", + "This is a description 2" ] """; using var stream = new MemoryStream(Encoding.UTF8.GetBytes(oaiValueRepresentation)); From 52ede22a80712d224d502d8583c5c9e6d8fb070b Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 14:54:40 -0500 Subject: [PATCH 24/41] fix: missing readers fix: missing descriptions Signed-off-by: Vincent Biret --- .../DivergentResponseSchemaTests.cs | 8 ++ .../Validation/GetWithBodyTests.cs | 65 ++++----- .../InconsistentTypeFormatPairTests.cs | 66 ++++----- .../KnownAndNotSupportedFormatsTests.cs | 66 ++++----- .../Validation/MissingDiscriminatorTests.cs | 96 +++++++------ .../Validation/MultipleServerEntriesTests.cs | 51 +++---- .../Validation/NoContentWithBodyTests.cs | 68 +++++----- .../Validation/NoServerEntryTests.cs | 49 +++---- .../Validation/UrlFormEncodedComplexTests.cs | 126 ++++++++++-------- 9 files changed, 326 insertions(+), 269 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs index dc3ecfb1d1..8ea2af1ff7 100644 --- a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs @@ -4,6 +4,7 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; @@ -23,6 +24,7 @@ public async Task DoesntAddAWarningWhenBodyIsSingle() get: responses: '200': + description: some description content: application/json: schema: @@ -44,12 +46,14 @@ public async Task AddsAWarningWhenBodyIsDivergent() get: responses: '200': + description: some description content: application/json: schema: type: string format: int32 '201': + description: some description content: application/json: schema: @@ -71,12 +75,14 @@ public async Task DoesntAddAWarningWhenUsing2XX() get: responses: '200': + description: some description content: application/json: schema: type: string format: int32 '2XX': + description: some description content: application/json: schema: @@ -91,6 +97,8 @@ private static async Task GetDiagnosticFromDocumentAsync(stri using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); settings.RuleSet.Add(typeof(DivergentResponseSchema), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); return result.Diagnostic; } diff --git a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs index 3512b156b0..888c42230c 100644 --- a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs @@ -12,10 +12,10 @@ namespace Kiota.Builder.Tests.Validation; public class GetWithBodyTests { - [Fact] - public async Task AddsAWarningWhenGetWithBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenGetWithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -29,15 +29,16 @@ public async Task AddsAWarningWhenGetWithBody() application/json: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenGetWithNoBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenGetWithNoBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -49,15 +50,16 @@ public async Task DoesntAddAWarningWhenGetWithNoBody() get: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenPostWithBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenPostWithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -71,18 +73,21 @@ public async Task DoesntAddAWarningWhenPostWithBody() application/json: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new GetWithBody(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(GetWithBody), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new GetWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(GetWithBody), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs index 070c33da97..c71ce5488d 100644 --- a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs @@ -4,15 +4,16 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class InconsistentTypeFormatPairTests { - [Fact] - public async Task AddsAWarningWhenKnownInconsistentPair() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenKnownInconsistentPair() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -22,18 +23,19 @@ public async Task AddsAWarningWhenKnownInconsistentPair() get: responses: '200': + description: some description content: application/json: schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSupportedPair() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSupportedPair() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -43,18 +45,19 @@ public async Task DoesntAddAWarningWhenSupportedPair() get: responses: '200': + description: some description content: application/json: schema: type: string format: uuid"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntFailWhenKnownAlternative() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntFailWhenKnownAlternative() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -64,21 +67,24 @@ public async Task DoesntFailWhenKnownAlternative() get: responses: '200': + description: some description content: application/json: schema: type: enum format: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new InconsistentTypeFormatPair(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new InconsistentTypeFormatPair(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs index fe4aec47ff..a568470f3c 100644 --- a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs @@ -4,16 +4,17 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class KnownAndNotSupportedFormatsTests { - [Fact] - public async Task AddsAWarningWhenKnownUnsupportedFormat() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenKnownUnsupportedFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -23,18 +24,19 @@ public async Task AddsAWarningWhenKnownUnsupportedFormat() get: responses: '200': + description: some description content: application/json: schema: type: string format: email"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSupportedFormat() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSupportedFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -44,18 +46,19 @@ public async Task DoesntAddAWarningWhenSupportedFormat() get: responses: '200': + description: some description content: application/json: schema: type: string format: uuid"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntFailWhenNoFormat() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntFailWhenNoFormat() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -65,20 +68,23 @@ public async Task DoesntFailWhenNoFormat() get: responses: '200': + description: some description content: application/json: schema: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new KnownAndNotSupportedFormats(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new KnownAndNotSupportedFormats(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs index 8ac4e316e3..65bdb25849 100644 --- a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs @@ -4,15 +4,16 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class MissingDiscriminatorTests { - [Fact] - public async Task DoesntAddAWarningWhenBodyIsSimple() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task DoesntAddAWarningWhenBodyIsSimple() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -22,18 +23,19 @@ public async Task DoesntAddAWarningWhenBodyIsSimple() get: responses: '200': + description: some description content: application/json: schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task AddsWarningOnInlineSchemas() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task AddsWarningOnInlineSchemas() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -43,6 +45,7 @@ public async Task AddsWarningOnInlineSchemas() get: responses: '200': + description: some description content: application/json: schema: @@ -56,13 +59,13 @@ public async Task AddsWarningOnInlineSchemas() properties: type2: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsWarningOnComponentSchemas() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsWarningOnComponentSchemas() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -89,17 +92,18 @@ public async Task AddsWarningOnComponentSchemas() get: responses: '200': + description: some description content: application/json: schema: $ref: '#/components/schemas/type3'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformation() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -128,17 +132,18 @@ public async Task DoesntAddsWarningOnComponentSchemasWithDiscriminatorInformatio get: responses: '200': + description: some description content: application/json: schema: $ref: '#/components/schemas/type3'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddsWarningOnComponentSchemasScalars() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddsWarningOnComponentSchemasScalars() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -157,20 +162,23 @@ public async Task DoesntAddsWarningOnComponentSchemasScalars() get: responses: '200': + description: some description content: application/json: schema: $ref: '#/components/schemas/type1'"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new MissingDiscriminator(new()); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MissingDiscriminator(new()); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs index 6e195b4a69..f19f86f5be 100644 --- a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs @@ -4,16 +4,17 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class MultipleServerEntriesTests { - [Fact] - public async Task AddsAWarningWhenMultipleServersPresent() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenMultipleServersPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -26,15 +27,16 @@ public async Task AddsAWarningWhenMultipleServersPresent() get: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenSingleServerPresent() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenSingleServerPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -46,18 +48,21 @@ public async Task DoesntAddAWarningWhenSingleServerPresent() get: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new MultipleServerEntries(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new MultipleServerEntries(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs index 50cc2f9149..e63de927c3 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs @@ -4,16 +4,17 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class NoContentWithBodyTests { - [Fact] - public async Task AddsAWarningWhen204WithBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhen204WithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -23,15 +24,16 @@ public async Task AddsAWarningWhen204WithBody() get: responses: '204': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhen204WithNoBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhen204WithNoBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -42,14 +44,15 @@ public async Task DoesntAddAWarningWhen204WithNoBody() /enumeration: get: responses: - '204':"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhen200WithBody() - { - var documentTxt = @"openapi: 3.0.1 + '204': + description: some description"; + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhen200WithBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -63,18 +66,21 @@ public async Task DoesntAddAWarningWhen200WithBody() application/json: responses: '200': + description: some description content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new NoContentWithBody(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoContentWithBody(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs index 5aecbb914d..26ac6d6355 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs @@ -4,16 +4,17 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class NoServerEntryTests { - [Fact] - public async Task AddsAWarningWhenNoServersPresent() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenNoServersPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -25,13 +26,13 @@ public async Task AddsAWarningWhenNoServersPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenServerPresent() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenServerPresent() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -45,16 +46,18 @@ public async Task DoesntAddAWarningWhenServerPresent() '200': content: application/json:"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new NoServerEntry(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoServerEntry), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new NoServerEntry(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(NoServerEntry), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } diff --git a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs index ce49c615b7..abef8864cf 100644 --- a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs @@ -4,15 +4,16 @@ using Kiota.Builder.Validation; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Readers; using Xunit; namespace Kiota.Builder.Tests.Validation; public class UrlFormEncodedComplexTests { - [Fact] - public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() - { - var documentTxt = @"openapi: 3.0.1 + [Fact] + public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -28,18 +29,19 @@ public async Task AddsAWarningWhenUrlEncodedNotObjectRequestBody() format: int32 responses: '200': + description: some description content: application/json: schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -49,18 +51,19 @@ public async Task AddsAWarningWhenUrlEncodedNotObjectResponse() get: responses: '200': + description: some description content: application/x-www-form-urlencoded: schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -81,18 +84,19 @@ public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnRequestBody() type: string responses: '200': + description: some description content: application/json: schema: type: string format: int32"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -102,6 +106,7 @@ public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() get: responses: '200': + description: some description content: application/x-www-form-urlencoded: schema: @@ -112,13 +117,13 @@ public async Task AddsAWarningWhenUrlEncodedComplexPropertyOnResponse() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Single(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenUrlEncoded() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Single(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenUrlEncoded() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -128,6 +133,7 @@ public async Task DoesntAddAWarningWhenUrlEncoded() get: responses: '200': + description: some description content: application/x-www-form-urlencoded: schema: @@ -135,13 +141,13 @@ public async Task DoesntAddAWarningWhenUrlEncoded() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningOnArrayProperty() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningOnArrayProperty() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -162,6 +168,7 @@ public async Task DoesntAddAWarningOnArrayProperty() format: int32 responses: '200': + description: some description content: application/x-www-form-urlencoded: schema: @@ -169,13 +176,13 @@ public async Task DoesntAddAWarningOnArrayProperty() properties: prop: type: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - [Fact] - public async Task DoesntAddAWarningWhenNotUrlEncoded() - { - var documentTxt = @"openapi: 3.0.1 + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + [Fact] + public async Task DoesntAddAWarningWhenNotUrlEncoded() + { + var documentTxt = @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph description: This OData service is located at https://graph.microsoft.com/v1.0 @@ -185,21 +192,24 @@ public async Task DoesntAddAWarningWhenNotUrlEncoded() get: responses: '200': + description: some description content: application/json: schema: type: enum format: string"; - var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); - Assert.Empty(diagnostic.Warnings); - } - private static async Task GetDiagnosticFromDocumentAsync(string document) - { - var rule = new UrlFormEncodedComplex(); - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); - var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); - var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); - return result.Diagnostic; - } + var diagnostic = await GetDiagnosticFromDocumentAsync(documentTxt); + Assert.Empty(diagnostic.Warnings); + } + private static async Task GetDiagnosticFromDocumentAsync(string document) + { + var rule = new UrlFormEncodedComplex(); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); + var settings = new OpenApiReaderSettings(); + settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); + var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); + return result.Diagnostic; + } } From 85c67cd239c5028545d596d81ca7b5f140560807 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 15:23:10 -0500 Subject: [PATCH 25/41] fix: form encoded validation rule Signed-off-by: Vincent Biret --- .../Validation/UrlFormEncodedComplex.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs b/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs index f36ffb775b..917ba8a289 100644 --- a/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs +++ b/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs @@ -13,21 +13,19 @@ public class UrlFormEncodedComplex : ValidationRule }; public UrlFormEncodedComplex() : base(nameof(UrlFormEncodedComplex), static (context, operation) => { - if (string.IsNullOrEmpty(operation.OperationId)) - return; if (operation.GetRequestSchema(validContentTypes) is OpenApiSchema requestSchema) - ValidateSchema(requestSchema, context, operation.OperationId, "request body"); + ValidateSchema(requestSchema, context, "request body"); if (operation.GetResponseSchema(validContentTypes) is OpenApiSchema responseSchema) - ValidateSchema(responseSchema, context, operation.OperationId, "response body"); + ValidateSchema(responseSchema, context, "response body"); }) { } - private static void ValidateSchema(OpenApiSchema schema, IValidationContext context, string operationId, string schemaName) + private static void ValidateSchema(OpenApiSchema schema, IValidationContext context, string schemaName) { if (schema == null) return; if (!schema.IsObjectType()) - context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {operationId} has a {schemaName} which is not an object type. This is not supported by Kiota and serialization will fail."); + context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {context.PathString} has a {schemaName} which is not an object type. This is not supported by Kiota and serialization will fail."); if (schema.Properties.Any(static x => x.Value.IsObjectType())) - context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {operationId} has a {schemaName} with a complex properties and the url form encoded content type. This is not supported by Kiota and serialization of complex properties will fail."); + context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {context.PathString} has a {schemaName} with a complex properties and the url form encoded content type. This is not supported by Kiota and serialization of complex properties will fail."); } } From bc64b834d7ed2fd4beccf209531328c92928b833 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Fri, 20 Dec 2024 15:34:41 -0500 Subject: [PATCH 26/41] fix: validation rules registration Signed-off-by: Vincent Biret --- .../Validation/ValidationRuleSetExtensions.cs | 20 +++++++++---------- .../DivergentResponseSchemaTests.cs | 2 +- .../Validation/GetWithBodyTests.cs | 2 +- .../InconsistentTypeFormatPairTests.cs | 2 +- .../KnownAndNotSupportedFormatsTests.cs | 2 +- .../Validation/MissingDiscriminatorTests.cs | 2 +- .../Validation/MultipleServerEntriesTests.cs | 2 +- .../Validation/NoContentWithBodyTests.cs | 2 +- .../Validation/NoServerEntryTests.cs | 2 +- .../Validation/UrlFormEncodedComplexTests.cs | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs index 95d66e80e8..e80f6c2005 100644 --- a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs +++ b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs @@ -1,5 +1,6 @@ using System; using Kiota.Builder.Configuration; +using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Validations; namespace Kiota.Builder.Validation; @@ -13,18 +14,17 @@ public static void AddKiotaValidationRules(this ValidationRuleSet ruleSet, Gener configuration ??= new(); if (configuration.DisabledValidationRules.Contains(AllValidationRule)) return; - ruleSet.AddRuleIfEnabled(configuration, new NoServerEntry()); - ruleSet.AddRuleIfEnabled(configuration, new MultipleServerEntries()); - ruleSet.AddRuleIfEnabled(configuration, new GetWithBody()); - ruleSet.AddRuleIfEnabled(configuration, new KnownAndNotSupportedFormats()); - ruleSet.AddRuleIfEnabled(configuration, new InconsistentTypeFormatPair()); - ruleSet.AddRuleIfEnabled(configuration, new UrlFormEncodedComplex()); - ruleSet.AddRuleIfEnabled(configuration, new DivergentResponseSchema(configuration)); - ruleSet.AddRuleIfEnabled(configuration, new MissingDiscriminator(configuration)); + ruleSet.AddRuleIfEnabled(configuration, new NoServerEntry(), typeof(OpenApiDocument)); + ruleSet.AddRuleIfEnabled(configuration, new MultipleServerEntries(), typeof(OpenApiDocument)); + ruleSet.AddRuleIfEnabled(configuration, new GetWithBody(), typeof(OpenApiPathItem)); + ruleSet.AddRuleIfEnabled(configuration, new KnownAndNotSupportedFormats(), typeof(OpenApiSchema)); + ruleSet.AddRuleIfEnabled(configuration, new InconsistentTypeFormatPair(), typeof(OpenApiSchema)); + ruleSet.AddRuleIfEnabled(configuration, new UrlFormEncodedComplex(), typeof(OpenApiOperation)); + ruleSet.AddRuleIfEnabled(configuration, new DivergentResponseSchema(configuration), typeof(OpenApiOperation)); + ruleSet.AddRuleIfEnabled(configuration, new MissingDiscriminator(configuration), typeof(OpenApiDocument)); } - private static void AddRuleIfEnabled(this ValidationRuleSet ruleSet, GenerationConfiguration configuration, T instance) where T : ValidationRule + private static void AddRuleIfEnabled(this ValidationRuleSet ruleSet, GenerationConfiguration configuration, T instance, Type ruleType) where T : ValidationRule { - var ruleType = instance.GetType(); if (!configuration.DisabledValidationRules.Contains(ruleType.Name)) ruleSet.Add(ruleType, instance); } diff --git a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs index 8ea2af1ff7..596fb20e7e 100644 --- a/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/DivergentResponseSchemaTests.cs @@ -96,7 +96,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new DivergentResponseSchema(new()); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(DivergentResponseSchema), [rule]); + settings.RuleSet.Add(typeof(OpenApiOperation), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs index 888c42230c..89ea47f7b1 100644 --- a/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/GetWithBodyTests.cs @@ -84,7 +84,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new GetWithBody(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(GetWithBody), [rule]); + settings.RuleSet.Add(typeof(OpenApiPathItem), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs index c71ce5488d..4c3d61f8f3 100644 --- a/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/InconsistentTypeFormatPairTests.cs @@ -81,7 +81,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new InconsistentTypeFormatPair(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(InconsistentTypeFormatPair), [rule]); + settings.RuleSet.Add(typeof(OpenApiSchema), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs index a568470f3c..abc24f3ac3 100644 --- a/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/KnownAndNotSupportedFormatsTests.cs @@ -81,7 +81,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new KnownAndNotSupportedFormats(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(KnownAndNotSupportedFormats), [rule]); + settings.RuleSet.Add(typeof(OpenApiSchema), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs index 65bdb25849..efd89a1c2b 100644 --- a/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MissingDiscriminatorTests.cs @@ -175,7 +175,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new MissingDiscriminator(new()); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MissingDiscriminator), [rule]); + settings.RuleSet.Add(typeof(OpenApiDocument), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs index f19f86f5be..d6585196e9 100644 --- a/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/MultipleServerEntriesTests.cs @@ -59,7 +59,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new MultipleServerEntries(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(MultipleServerEntries), [rule]); + settings.RuleSet.Add(typeof(OpenApiDocument), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs index e63de927c3..ce59591fff 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoContentWithBodyTests.cs @@ -77,7 +77,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new NoContentWithBody(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoContentWithBody), [rule]); + settings.RuleSet.Add(typeof(OpenApiOperation), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs index 26ac6d6355..cc488df6db 100644 --- a/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/NoServerEntryTests.cs @@ -54,7 +54,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new NoServerEntry(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(NoServerEntry), [rule]); + settings.RuleSet.Add(typeof(OpenApiDocument), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); diff --git a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs index abef8864cf..3482735a3e 100644 --- a/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/UrlFormEncodedComplexTests.cs @@ -206,7 +206,7 @@ private static async Task GetDiagnosticFromDocumentAsync(stri var rule = new UrlFormEncodedComplex(); using var stream = new MemoryStream(Encoding.UTF8.GetBytes(document)); var settings = new OpenApiReaderSettings(); - settings.RuleSet.Add(typeof(UrlFormEncodedComplex), [rule]); + settings.RuleSet.Add(typeof(OpenApiOperation), [rule]); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader()); var result = await OpenApiDocument.LoadAsync(stream, "yaml", settings); From f5b95b71abd4647aac63e111ba709129afb1bae3 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 08:25:42 -0500 Subject: [PATCH 27/41] fix: rules disablement did not work anymore Signed-off-by: Vincent Biret --- src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs | 2 +- .../Validation/ValidationRuleSetExtensionsTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs index e80f6c2005..523bbcfc3a 100644 --- a/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs +++ b/src/Kiota.Builder/Validation/ValidationRuleSetExtensions.cs @@ -25,7 +25,7 @@ public static void AddKiotaValidationRules(this ValidationRuleSet ruleSet, Gener } private static void AddRuleIfEnabled(this ValidationRuleSet ruleSet, GenerationConfiguration configuration, T instance, Type ruleType) where T : ValidationRule { - if (!configuration.DisabledValidationRules.Contains(ruleType.Name)) + if (!configuration.DisabledValidationRules.Contains(typeof(T).Name)) ruleSet.Add(ruleType, instance); } } diff --git a/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs b/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs index 26800d8df4..1bba9f1448 100644 --- a/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/ValidationRuleSetExtensionsTests.cs @@ -33,7 +33,7 @@ public void DisablesNoRule() public void DisablesOneRule() { var ruleSet = new ValidationRuleSet(); - var configuration = new GenerationConfiguration { DisabledValidationRules = new() { nameof(NoServerEntry) } }; + var configuration = new GenerationConfiguration { DisabledValidationRules = [nameof(NoServerEntry)] }; ruleSet.AddKiotaValidationRules(configuration); Assert.NotEmpty(ruleSet.Rules); Assert.DoesNotContain(ruleSet.Rules, static x => x.GetType() == typeof(NoServerEntry)); From c539330cad9554b2f873ef1d877974e2ed46608f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 08:28:01 -0500 Subject: [PATCH 28/41] fix: invalid payload for unit test Signed-off-by: Vincent Biret --- .../OpenApiAiRespondingInstructionsExtensionTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs index 158f280ea6..e900673fbc 100644 --- a/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiExtensions/OpenApiAiRespondingInstructionsExtensionTests.cs @@ -27,7 +27,7 @@ public void Parses() """ [ "This is a description", - "This is a description 2", + "This is a description 2" ] """; using var stream = new MemoryStream(Encoding.UTF8.GetBytes(oaiValueRepresentation)); From c1cbea987d29eb99f4a2135a823f9528aee48bae Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 08:35:53 -0500 Subject: [PATCH 29/41] chore: improves validation tests performance for API export Signed-off-by: Vincent Biret --- .../Export/PublicAPIExportServiceTests.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs b/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs index 51b4306f49..13465008e5 100644 --- a/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs @@ -73,7 +73,7 @@ public void Defensive() Assert.Throws(() => new PublicApiExportService(null)); } - private static readonly Dictionary> Validators = new() + private static readonly Dictionary>> Validators = new() { { GenerationLanguage.CSharp, ValidateExportCSharp }, { GenerationLanguage.Go, ValidateExportGo }, @@ -122,7 +122,7 @@ public async Task GeneratesExportsAndFileHasExpectedAssertionsAsync(GenerationLa Assert.NotEqual(0, outputStream.Length); // output is not empty using var streamReader = new StreamReader(outputStream); - var contents = (await streamReader.ReadToEndAsync()).Split(Environment.NewLine); + var contents = new HashSet((await streamReader.ReadToEndAsync()).Split(Environment.NewLine), StringComparer.Ordinal); if (!Validators.TryGetValue(generationLanguage, out var validator)) { @@ -132,7 +132,7 @@ public async Task GeneratesExportsAndFileHasExpectedAssertionsAsync(GenerationLa validator.Invoke(contents); } - private static void ValidateExportCSharp(string[] exportContents) + private static void ValidateExportCSharp(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("ExportNamespace.Graph-->BaseRequestBuilder", exportContents); // captures class inheritance @@ -145,7 +145,7 @@ private static void ValidateExportCSharp(string[] exportContents) Assert.Contains("ExportNamespace.Models.Microsoft.Graph.user::|public|OtherNames:List", exportContents);// captures collection info in language specific format } - private static void ValidateExportJava(string[] exportContents) + private static void ValidateExportJava(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("exportnamespace.Graph-->BaseRequestBuilder", exportContents); // captures class inheritance @@ -160,7 +160,7 @@ private static void ValidateExportJava(string[] exportContents) Assert.Contains("exportnamespace.models.microsoft.graph.User::|public|setOtherNames(value?:java.util.List):void", exportContents);// captures collection info in language specific format } - private static void ValidateExportGo(string[] exportContents) + private static void ValidateExportGo(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("exportNamespace.Graph-->*i2ae4187f7daee263371cb1c977df639813ab50ffa529013b7437480d1ec0158f.BaseRequestBuilder", exportContents); // captures class inheritance @@ -178,7 +178,7 @@ private static void ValidateExportGo(string[] exportContents) Assert.Contains("exportNamespace.models.microsoft.graph.user::|public|SetOtherNames(value:[]string):void", exportContents);// captures collection info in language specific format } - private static void ValidateExportPython(string[] exportContents) + private static void ValidateExportPython(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("exportNamespace.Graph-->BaseRequestBuilder", exportContents); // captures class inheritance @@ -193,7 +193,7 @@ private static void ValidateExportPython(string[] exportContents) Assert.Contains("exportNamespace.models.microsoft.graph.User::|public|other_names(value:List[str]):None", exportContents);// captures collection info in language specific format } - private static void ValidateExportTypeScript(string[] exportContents) + private static void ValidateExportTypeScript(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("exportNamespace.Graph~~>BaseRequestBuilder", exportContents); // captures class inheritance. TS does not do inheritance due to interfaces. @@ -210,7 +210,7 @@ private static void ValidateExportTypeScript(string[] exportContents) Assert.Contains("exportNamespace.models.microsoft.graph.User::|public|otherNames:string[]", exportContents);// captures collection info in language specific format } - private static void ValidateExportPhp(string[] exportContents) + private static void ValidateExportPhp(HashSet exportContents) { Assert.NotEmpty(exportContents); Assert.Contains("exportNamespace.Graph-->BaseRequestBuilder", exportContents); // captures class inheritance From 3cdd3d4a932fcf277e3e3bb9ec5b54e2d91b53e5 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 08:48:35 -0500 Subject: [PATCH 30/41] fix: document path for manifest generation tests Signed-off-by: Vincent Biret --- .../Plugins/PluginsGenerationServiceTests.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index ddc6a98d9f..15d39158c0 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -75,13 +75,12 @@ public async Task GeneratesManifestAsync(string inputPluginName, string expected var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent); - var mockLogger = new Mock>(); var openAPIDocumentDS = new OpenApiDocumentDownloadService(_httpClient, _logger); var outputDirectory = Path.Combine(workingDirectory, "output"); var generationConfiguration = new GenerationConfiguration { OutputPath = outputDirectory, - OpenAPIFilePath = "openapiPath", + OpenAPIFilePath = simpleDescriptionPath, PluginTypes = [PluginType.APIPlugin, PluginType.APIManifest, PluginType.OpenAI], ClientClassName = inputPluginName, ApiRootUrl = "http://localhost/", //Kiota builder would set this for us @@ -234,7 +233,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() var generationConfiguration = new GenerationConfiguration { OutputPath = outputDirectory, - OpenAPIFilePath = "openapiPath", + OpenAPIFilePath = simpleDescriptionPath, PluginTypes = [PluginType.APIPlugin], ClientClassName = "client", ApiRootUrl = "http://localhost/", //Kiota builder would set this for us @@ -487,13 +486,12 @@ public async Task GeneratesManifestWithAuthAsync(string securitySchemesComponent var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, apiDescription); - var mockLogger = new Mock>(); var openApiDocumentDs = new OpenApiDocumentDownloadService(_httpClient, _logger); var outputDirectory = Path.Combine(workingDirectory, "output"); var generationConfiguration = new GenerationConfiguration { OutputPath = outputDirectory, - OpenAPIFilePath = "openapiPath", + OpenAPIFilePath = simpleDescriptionPath, PluginTypes = [PluginType.APIPlugin], ClientClassName = "client", ApiRootUrl = "http://localhost/", //Kiota builder would set this for us @@ -566,13 +564,12 @@ public async Task GeneratesManifestWithMultipleSecuritySchemesAsync() var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, apiDescription); - var mockLogger = new Mock>(); var openApiDocumentDs = new OpenApiDocumentDownloadService(_httpClient, _logger); var outputDirectory = Path.Combine(workingDirectory, "output"); var generationConfiguration = new GenerationConfiguration { OutputPath = outputDirectory, - OpenAPIFilePath = "openapiPath", + OpenAPIFilePath = simpleDescriptionPath, PluginTypes = [PluginType.APIPlugin], ClientClassName = "client", ApiRootUrl = "http://localhost/", //Kiota builder would set this for us @@ -777,7 +774,7 @@ public async Task MergesAllOfRequestBodyAsync(string content, Action Date: Mon, 23 Dec 2024 08:50:26 -0500 Subject: [PATCH 31/41] fix: invalid type for test data Signed-off-by: Vincent Biret --- tests/Kiota.Builder.Tests/KiotaBuilderTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 0bfb1abd3d..8f5c549c47 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -7717,7 +7717,8 @@ public async Task CleanupSymbolNameDoesNotCauseNameConflictsInQueryParametersAsy - name: select in: query schema: - type: int64 + type: number + format: int64 responses: '200': content: From 1886d77a23316cb05000cbe06dbe711edd483269 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 08:58:07 -0500 Subject: [PATCH 32/41] chore: linting removes unnecessary string interpolation Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index cda9fd26d4..9317f30fe4 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -539,18 +539,18 @@ public CodeNamespace CreateSourceModel(OpenApiUrlTreeNode? root) var codeNamespace = rootNamespace.AddNamespace(config.ClientNamespaceName); modelsNamespace = rootNamespace.AddNamespace(config.ModelsNamespaceName); InitializeInheritanceIndex(); - StopLogAndReset(stopwatch, $"{nameof(InitializeInheritanceIndex)}"); + StopLogAndReset(stopwatch, nameof(InitializeInheritanceIndex)); if (root != null) { CreateRequestBuilderClass(codeNamespace, root, root); - StopLogAndReset(stopwatch, $"{nameof(CreateRequestBuilderClass)}"); + StopLogAndReset(stopwatch, nameof(CreateRequestBuilderClass)); stopwatch.Start(); MapTypeDefinitions(codeNamespace); - StopLogAndReset(stopwatch, $"{nameof(MapTypeDefinitions)}"); + StopLogAndReset(stopwatch, nameof(MapTypeDefinitions)); TrimInheritedModels(); - StopLogAndReset(stopwatch, $"{nameof(TrimInheritedModels)}"); + StopLogAndReset(stopwatch, nameof(TrimInheritedModels)); CleanUpInternalState(); - StopLogAndReset(stopwatch, $"{nameof(CleanUpInternalState)}"); + StopLogAndReset(stopwatch, nameof(CleanUpInternalState)); logger.LogTrace("{Timestamp}ms: Created source model with {Count} classes", stopwatch.ElapsedMilliseconds, codeNamespace.GetChildElements(true).Count()); } From 7f16e6b781a929ce737c3594e993d5a5c94d51ca Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 09:46:08 -0500 Subject: [PATCH 33/41] fix: navigation properties type generation Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 63 ++++++++++++------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 9317f30fe4..c466d3ed4b 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1091,7 +1091,7 @@ private CodeIndexer[] CreateIndexer(string childIdentifier, string childType, Co var propertyName = childIdentifier.CleanupSymbolName(); if (structuralPropertiesReservedNameProvider.ReservedNames.Contains(propertyName)) propertyName += "Property"; - var resultType = existingType ?? GetPrimitiveType(propertySchema); + var resultType = existingType ?? GetPrimitiveType(propertySchema, childType); if ((propertySchema?.Items?.IsEnum() ?? false) && resultType is CodeType codeType) codeType.Name = childType; if (resultType == null) return null; @@ -1131,7 +1131,7 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten return prop; } private static readonly HashSet typeNamesToSkip = [JsonSchemaType.Object, JsonSchemaType.Array]; - private static CodeType? GetPrimitiveType(OpenApiSchema? typeSchema) + private static CodeType? GetPrimitiveType(OpenApiSchema? typeSchema, string? childType = default) { var typeNames = new List { typeSchema?.Items?.Type, typeSchema?.Type }; if (typeSchema?.AnyOf?.Any() ?? false) @@ -1141,45 +1141,30 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten // first value that's not null, and not "object" for primitive collections, the items type matters var typeName = typeNames.Find(static x => x is not null && !typeNamesToSkip.Contains(x.Value)); - var isExternal = false; var format = typeSchema?.Format ?? typeSchema?.Items?.Format; - var primitiveTypeName = (typeName, format?.ToLowerInvariant()) switch - { - (JsonSchemaType.String, "base64url") => "base64url", - (JsonSchemaType.String, "duration") => "TimeSpan", - (JsonSchemaType.String, "time") => "TimeOnly", - (JsonSchemaType.String, "date") => "DateOnly", - (JsonSchemaType.String, "date-time") => "DateTimeOffset", - (JsonSchemaType.String, "uuid") => "Guid", - (JsonSchemaType.String, _) => "string", // covers commonmark and html - (JsonSchemaType.Number, "double" or "float" or "decimal") => format.ToLowerInvariant(), - (JsonSchemaType.Number or JsonSchemaType.Integer, "int8") => "sbyte", - (JsonSchemaType.Number or JsonSchemaType.Integer, "uint8") => "byte", - (JsonSchemaType.Number or JsonSchemaType.Integer, "int64") => "int64", - (JsonSchemaType.Number, "int16") => "integer", - (JsonSchemaType.Number, "int32") => "integer", - (JsonSchemaType.Number, _) => "double", - (JsonSchemaType.Integer, _) => "integer", - (JsonSchemaType.Boolean, _) => "boolean", - (_, "byte") => "base64", - (_, "binary") => "binary", + return (typeName, format?.ToLowerInvariant()) switch + { + (JsonSchemaType.String, "base64url") => new CodeType { Name = "base64url", IsExternal = true }, + (JsonSchemaType.String, "duration") => new CodeType { Name = "TimeSpan", IsExternal = true }, + (JsonSchemaType.String, "time") => new CodeType { Name = "TimeOnly", IsExternal = true }, + (JsonSchemaType.String, "date") => new CodeType { Name = "DateOnly", IsExternal = true }, + (JsonSchemaType.String, "date-time") => new CodeType { Name = "DateTimeOffset", IsExternal = true }, + (JsonSchemaType.String, "uuid") => new CodeType { Name = "Guid", IsExternal = true }, + (JsonSchemaType.String, _) => new CodeType { Name = "string", IsExternal = true }, // covers commonmark and html + (JsonSchemaType.Number, "double" or "float" or "decimal") => new CodeType { Name = format.ToLowerInvariant(), IsExternal = true }, + (JsonSchemaType.Number or JsonSchemaType.Integer, "int8") => new CodeType { Name = "sbyte", IsExternal = true }, + (JsonSchemaType.Number or JsonSchemaType.Integer, "uint8") => new CodeType { Name = "byte", IsExternal = true }, + (JsonSchemaType.Number or JsonSchemaType.Integer, "int64") => new CodeType { Name = "int64", IsExternal = true }, + (JsonSchemaType.Number, "int16") => new CodeType { Name = "integer", IsExternal = true }, + (JsonSchemaType.Number, "int32") => new CodeType { Name = "integer", IsExternal = true }, + (JsonSchemaType.Number, _) => new CodeType { Name = "double", IsExternal = true }, + (JsonSchemaType.Integer, _) => new CodeType { Name = "integer", IsExternal = true }, + (JsonSchemaType.Boolean, _) => new CodeType { Name = "boolean", IsExternal = true }, + (_, "byte") => new CodeType { Name = "base64", IsExternal = true }, + (_, "binary") => new CodeType { Name = "binary", IsExternal = true }, //TODO handle the case where we have multiple entries - (_, _) => string.Empty, - }; - if (!string.IsNullOrEmpty(primitiveTypeName)) - { - return new CodeType - { - Name = primitiveTypeName, - IsExternal = true, - }; - } - if (typeName is null || typeName.ToIdentifier() is not string normalizedTypeName || string.IsNullOrEmpty(normalizedTypeName)) - return null; - return new CodeType - { - Name = normalizedTypeName, - IsExternal = isExternal, + (_, _) when !string.IsNullOrEmpty(childType) => new CodeType { Name = childType, IsExternal = false, }, + (_, _) => null, }; } private const string RequestBodyPlainTextContentType = "text/plain"; From 118e5242a2d98c020e7983e29dafd8c833294f79 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 10:13:04 -0500 Subject: [PATCH 34/41] fix: binary and byte format mapping Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 4 ++-- tests/Kiota.Builder.Tests/KiotaBuilderTests.cs | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index c466d3ed4b..9e6c72eb5e 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1144,6 +1144,8 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten var format = typeSchema?.Format ?? typeSchema?.Items?.Format; return (typeName, format?.ToLowerInvariant()) switch { + (_, "byte") => new CodeType { Name = "base64", IsExternal = true }, + (_, "binary") => new CodeType { Name = "binary", IsExternal = true }, (JsonSchemaType.String, "base64url") => new CodeType { Name = "base64url", IsExternal = true }, (JsonSchemaType.String, "duration") => new CodeType { Name = "TimeSpan", IsExternal = true }, (JsonSchemaType.String, "time") => new CodeType { Name = "TimeOnly", IsExternal = true }, @@ -1160,8 +1162,6 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten (JsonSchemaType.Number, _) => new CodeType { Name = "double", IsExternal = true }, (JsonSchemaType.Integer, _) => new CodeType { Name = "integer", IsExternal = true }, (JsonSchemaType.Boolean, _) => new CodeType { Name = "boolean", IsExternal = true }, - (_, "byte") => new CodeType { Name = "base64", IsExternal = true }, - (_, "binary") => new CodeType { Name = "binary", IsExternal = true }, //TODO handle the case where we have multiple entries (_, _) when !string.IsNullOrEmpty(childType) => new CodeType { Name = childType, IsExternal = false, }, (_, _) => null, diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 8f5c549c47..6a2c929781 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -7871,7 +7871,7 @@ public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMi var bodyParameter = postMethod.Parameters.FirstOrDefault(static x => x.IsOfKind(CodeParameterKind.RequestBody)); Assert.NotNull(bodyParameter); Assert.Equal("MultipartBody", bodyParameter.Type.Name, StringComparer.OrdinalIgnoreCase); - var addressClass = codeModel.FindChildByName("Address"); + var addressClass = codeModel.FindChildByName("Address"); // json is structured, we generated a model Assert.NotNull(addressClass); } [Fact] @@ -7929,9 +7929,8 @@ public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMi Assert.NotNull(postMethod); var bodyParameter = postMethod.Parameters.FirstOrDefault(static x => x.IsOfKind(CodeParameterKind.RequestBody)); Assert.NotNull(bodyParameter); - Assert.Equal("DirectoryObjectPostRequestBody", bodyParameter.Type.Name, StringComparer.OrdinalIgnoreCase); //generate the model type as we do not have the serializer for the schema registered. - var addressClass = codeModel.FindChildByName("Address"); - Assert.NotNull(addressClass); + Assert.Equal("MultipartBody", bodyParameter.Type.Name, StringComparer.OrdinalIgnoreCase); + Assert.Null(codeModel.FindChildByName("Address")); // json is not structured so we didn't generate a model for the address } [Fact] public async Task SupportsMultipleContentTypesAsRequestBodyWithDefaultMimeTypesAsync() From 8782bd6a6054b57f7f11735bdb64a8bbd35e7b8d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 23 Dec 2024 10:35:32 -0500 Subject: [PATCH 35/41] fix: enum values number parsing Signed-off-by: Vincent Biret --- src/Kiota.Builder/KiotaBuilder.cs | 4 ++-- tests/Kiota.Builder.Tests/KiotaBuilderTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index 9e6c72eb5e..8a47e6a4d9 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1945,8 +1945,8 @@ private static void SetEnumOptions(OpenApiSchema schema, CodeEnum target) if (schema.Extensions.TryGetValue(OpenApiEnumValuesDescriptionExtension.Name, out var rawExtension) && rawExtension is OpenApiEnumValuesDescriptionExtension localExtInfo) extensionInformation = localExtInfo; target.AddOption(schema.Enum.OfType() - .Where(static x => x.GetValueKind() is JsonValueKind.String) - .Select(static x => x.GetValue()) + .Where(static x => x.GetValueKind() is JsonValueKind.String or JsonValueKind.Number) + .Select(static x => x.GetValueKind() is JsonValueKind.String ? x.GetValue() : x.GetValue().ToString(CultureInfo.InvariantCulture)) .Where(static x => !string.IsNullOrEmpty(x)) .Distinct(StringComparer.OrdinalIgnoreCase) .Select((x) => diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 6a2c929781..88b05cd08c 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -427,7 +427,7 @@ public async Task ParsesEnumDescriptionsAsync() StorageAccountType: type: string enum: - - +1 + - '+1' - -1 - Standard_LRS - Standard_ZRS @@ -439,7 +439,7 @@ public async Task ParsesEnumDescriptionsAsync() name: AccountType modelAsString: false values: - - value: +1 + - value: '+1' - value: -1 - value: Standard_LRS description: Locally redundant storage. From 1ca8341f93d88e3963acd226dab00f53bd1bf53c Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 24 Dec 2024 10:12:15 -0500 Subject: [PATCH 36/41] chore: bumps oai.net preview version --- src/Kiota.Builder/Kiota.Builder.csproj | 4 ++-- src/kiota/kiota.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index 711f420863..6fcc1b6710 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -44,9 +44,9 @@ - + - + diff --git a/src/kiota/kiota.csproj b/src/kiota/kiota.csproj index 3a39216ede..2e2cb8fef4 100644 --- a/src/kiota/kiota.csproj +++ b/src/kiota/kiota.csproj @@ -47,7 +47,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 7a7ca1a3dc28677e02cb12adab90db16ac1cabae Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Thu, 2 Jan 2025 08:32:04 -0500 Subject: [PATCH 37/41] fix: tolerate more than strings for comparisons --- src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs index 1d7b2c1fcb..2505515d5f 100644 --- a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs +++ b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs @@ -151,7 +151,7 @@ public bool Equals(JsonNode? x, JsonNode? y) { if (x is null || y is null) return object.Equals(x, y); // TODO: Can we use the OpenAPI.NET implementation of Equals? - return x.GetValueKind() == y.GetValueKind() && string.Equals(x.GetValue(), y.GetValue(), StringComparison.OrdinalIgnoreCase); + return x.GetValueKind() == y.GetValueKind() && string.Equals(x.ToJsonString(), y.ToJsonString(), StringComparison.OrdinalIgnoreCase); } /// public int GetHashCode([DisallowNull] JsonNode obj) From f54ee9e37cec9b1c5836e302954a9fed62743173 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Thu, 2 Jan 2025 09:24:34 -0500 Subject: [PATCH 38/41] chore: updates api manifest reference Signed-off-by: Vincent Biret --- src/Kiota.Builder/Kiota.Builder.csproj | 2 +- src/kiota/kiota.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index 6fcc1b6710..65a9f42abb 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -45,7 +45,7 @@ - + diff --git a/src/kiota/kiota.csproj b/src/kiota/kiota.csproj index 2e2cb8fef4..cd1499a732 100644 --- a/src/kiota/kiota.csproj +++ b/src/kiota/kiota.csproj @@ -46,7 +46,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 3fe029434aef07aa377f04271c7b3984355b0cd3 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Thu, 2 Jan 2025 09:26:29 -0500 Subject: [PATCH 39/41] fix: references to schema type after merge Signed-off-by: Vincent Biret --- .../OpenApiSchemaExtensionsTests.cs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs index 360aae6822..e34351bc89 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs @@ -681,7 +681,7 @@ public void DoesMergeWithInheritance() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, AnyOf = [ new() @@ -701,7 +701,7 @@ public void DoesMergeWithInheritance() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), @@ -726,7 +726,7 @@ public void DoesMergeWithIntersection() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, AnyOf = [ new() @@ -739,7 +739,7 @@ public void DoesMergeWithIntersection() [ new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["first"] = new OpenApiSchema(), @@ -747,7 +747,7 @@ public void DoesMergeWithIntersection() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["second"] = new OpenApiSchema(), @@ -755,7 +755,7 @@ public void DoesMergeWithIntersection() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["third"] = new OpenApiSchema(), @@ -779,7 +779,7 @@ public void DoesNotMergeWithMoreThanOneInclusiveEntry() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, AnyOf = [ new() @@ -799,7 +799,7 @@ public void DoesNotMergeWithMoreThanOneInclusiveEntry() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), @@ -808,7 +808,7 @@ public void DoesNotMergeWithMoreThanOneInclusiveEntry() }, ] }, - new() { Type = "object" }, + new() { Type = JsonSchemaType.Object }, ], }; @@ -820,7 +820,7 @@ public void DoesNotMergeWithoutInheritanceOrIntersection() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, AnyOf = [ new() @@ -829,7 +829,7 @@ public void DoesNotMergeWithoutInheritanceOrIntersection() [ new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), @@ -853,7 +853,7 @@ public void DoesMergeWithInheritance() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, OneOf = [ new() @@ -873,7 +873,7 @@ public void DoesMergeWithInheritance() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), @@ -898,7 +898,7 @@ public void DoesMergeWithIntersection() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, OneOf = [ new() @@ -911,7 +911,7 @@ public void DoesMergeWithIntersection() [ new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["first"] = new OpenApiSchema(), @@ -919,7 +919,7 @@ public void DoesMergeWithIntersection() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["second"] = new OpenApiSchema(), @@ -927,7 +927,7 @@ public void DoesMergeWithIntersection() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["third"] = new OpenApiSchema(), @@ -951,7 +951,7 @@ public void DoesNotMergeWithMoreThanOneExclusiveEntry() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, OneOf = [ new() @@ -971,7 +971,7 @@ public void DoesNotMergeWithMoreThanOneExclusiveEntry() }, new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), @@ -980,7 +980,7 @@ public void DoesNotMergeWithMoreThanOneExclusiveEntry() }, ] }, - new() { Type = "object" }, + new() { Type = JsonSchemaType.Object }, ], }; @@ -992,7 +992,7 @@ public void DoesNotMergeWithoutInheritanceOrIntersection() { var schema = new OpenApiSchema() { - Type = "object", + Type = JsonSchemaType.Object, OneOf = [ new() @@ -1001,7 +1001,7 @@ public void DoesNotMergeWithoutInheritanceOrIntersection() [ new() { - Type = "object", + Type = JsonSchemaType.Object, Properties = new Dictionary() { ["firstName"] = new OpenApiSchema(), From fbfd05da80811d903a4a4210c2eb01ac1daf127f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 8 Jan 2025 09:43:38 -0500 Subject: [PATCH 40/41] chore; upgrades plugin manifest lib to align oai.net versions Signed-off-by: Vincent Biret --- src/Kiota.Builder/Kiota.Builder.csproj | 2 +- .../Plugins/PluginsGenerationServiceTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index d4208ba545..4d19956f95 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -47,7 +47,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 15d39158c0..db7d7b1072 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -279,7 +279,7 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() // Validate the output open api file using var resultOpenApiFile = File.OpenRead(Path.Combine(outputDirectory, OpenApiFileName)); - var resultResult = await OpenApiDocument.LoadAsync(originalOpenApiFile, "yaml"); + var resultResult = await OpenApiDocument.LoadAsync(resultOpenApiFile, "yaml"); var resultDocument = resultResult.Document; Assert.Empty(resultResult.Diagnostic.Errors); @@ -521,7 +521,7 @@ public async Task GeneratesManifestWithAuthAsync(string securitySchemesComponent // Cleanup try { - Directory.Delete(outputDirectory); + Directory.Delete(outputDirectory, true); } catch (Exception) { From e2a6e20ddcd3b3b1e7ac04bf42c86ad8c2a68a9a Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 8 Jan 2025 10:54:54 -0500 Subject: [PATCH 41/41] fix: adds missing serialization settings to get schemas inlined Signed-off-by: Vincent Biret --- src/Kiota.Builder/Plugins/PluginsGenerationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index 58a3458cbc..abdcb36495 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -59,7 +59,7 @@ public async Task GenerateManifestAsync(CancellationToken cancellationToken = de await using var descriptionStream = File.Create(descriptionFullPath, 4096); await using var fileWriter = new StreamWriter(descriptionStream); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task - var descriptionWriter = new OpenApiYamlWriter(fileWriter); + var descriptionWriter = new OpenApiYamlWriter(fileWriter, new() { InlineLocalReferences = true, InlineExternalReferences = true }); var trimmedPluginDocument = GetDocumentWithTrimmedComponentsAndResponses(OAIDocument); PrepareDescriptionForCopilot(trimmedPluginDocument); // trimming a second time to remove any components that are no longer used after the inlining