diff --git a/CHANGELOG.md b/CHANGELOG.md index b503708b1a..15849cfe8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Fixed a bug where path items with a trailing slash would cause collisions, missing query parameters and more. - Fixed a bug where path items with a trailing slash would be missing query parameters. [#6569](https://github.com/microsoft/kiota/issues/6569) - Fixed an issue where migration from lock to workspace would fail because of stream management. [#6515](https://github.com/microsoft/kiota/issues/6515) diff --git a/src/Kiota.Builder/Constants.cs b/src/Kiota.Builder/Constants.cs index 1968837aa6..bff67dc246 100644 --- a/src/Kiota.Builder/Constants.cs +++ b/src/Kiota.Builder/Constants.cs @@ -1,6 +1,8 @@ namespace Kiota.Builder; + public static class Constants { public const string DefaultOpenApiLabel = "default"; public const string TempDirectoryName = "kiota"; + internal const string KiotaSegmentNameTreeNodeExtensionKey = "x-ms-kiota-new-segment-name"; } diff --git a/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs index 813d523170..e577ee5961 100644 --- a/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiDeprecationExtensionExtensions.cs @@ -34,7 +34,7 @@ internal static DeprecationInformation GetDeprecationInformation(this OpenApiOpe 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 - .SelectMany(static x => x.Content?.Values ?? []) + .SelectMany(static x => x.Content?.Values.Select(static x => x) ?? []) .Select(static x => x?.Schema) .OfType() .Select(static x => x.GetDeprecationInformation()) diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs index 4f745bbfce..987d32ddfc 100644 --- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text.Json; using Kiota.Builder.OpenApiExtensions; +using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; @@ -198,7 +199,7 @@ private static OpenApiSchema GetSchemaOrTargetShallowCopy(this IOpenApiSchema? s { if (string.IsNullOrEmpty(result.Discriminator.PropertyName) && !string.IsNullOrEmpty(discriminator.PropertyName)) result.Discriminator.PropertyName = discriminator.PropertyName; - if (discriminator.Mapping?.Any() ?? false) + if (discriminator.Mapping is { Count: > 0 }) result.Discriminator.Mapping = discriminator.Mapping.ToDictionary(static x => x.Key, static x => x.Value); } @@ -218,7 +219,8 @@ private static OpenApiSchema GetSchemaOrTargetShallowCopy(this IOpenApiSchema? s /// Resulting merged schema. private static void AddOriginalReferenceIdExtension(this IOpenApiSchema schema, OpenApiSchema result) { - if (schema is not OpenApiSchemaReference schemaReference || string.IsNullOrEmpty(schemaReference.Reference.Id) || result.Extensions is null) return; + if (schema is not OpenApiSchemaReference schemaReference || string.IsNullOrEmpty(schemaReference.Reference.Id)) return; + result.Extensions ??= new Dictionary(StringComparer.Ordinal); result.Extensions.TryAdd(OpenApiKiotaMergedExtension.Name, new OpenApiKiotaMergedExtension(schemaReference.Reference.Id)); } @@ -272,13 +274,13 @@ private static bool IsODataPrimitiveTypeBackwardCompatible(this IOpenApiSchema s { return schema.IsExclusiveUnion() && schema.OneOf is { Count: 3 } && - schema.OneOf.Count(static x => x.Enum?.Any() ?? false) == 1 && + schema.OneOf.Count(static x => x.Enum is { Count: > 0 }) == 1 && schema.OneOf.Count(isODataType) == 1 && schema.OneOf.Count(isStringType) == 1 || schema.IsInclusiveUnion() && schema.AnyOf is { Count: 3 } && - schema.AnyOf.Count(static x => x.Enum?.Any() ?? false) == 1 && + schema.AnyOf.Count(static x => x.Enum is { Count: > 0 }) == 1 && schema.AnyOf.Count(isODataType) == 1 && schema.AnyOf.Count(isStringType) == 1; } @@ -287,13 +289,13 @@ public static bool IsODataPrimitiveType(this IOpenApiSchema schema) if (schema is null) return false; return schema.IsExclusiveUnion() && schema.OneOf is { Count: 3 } && - schema.OneOf.Count(static x => isStringType(x) && (x.Enum?.Any() ?? false)) == 1 && + schema.OneOf.Count(static x => isStringType(x) && (x.Enum is { Count: > 0 })) == 1 && schema.OneOf.Count(isODataType) == 1 && schema.OneOf.Count(isStringType) == 2 || schema.IsInclusiveUnion() && schema.AnyOf is { Count: 3 } && - schema.AnyOf.Count(static x => isStringType(x) && (x.Enum?.Any() ?? false)) == 1 && + schema.AnyOf.Count(static x => isStringType(x) && (x.Enum is { Count: > 0 })) == 1 && schema.AnyOf.Count(isODataType) == 1 && schema.AnyOf.Count(isStringType) == 2 || @@ -411,14 +413,14 @@ internal static IEnumerable> GetDiscriminatorMappin { if (schema == null) return []; - if (!(schema.Discriminator?.Mapping?.Any() ?? false)) + if (schema.Discriminator?.Mapping is not { Count: > 0 }) if (schema.OneOf is { Count: > 0 }) return schema.OneOf.SelectMany(x => GetDiscriminatorMappings(x, inheritanceIndex)); else if (schema.AnyOf is { Count: > 0 }) return schema.AnyOf.SelectMany(x => GetDiscriminatorMappings(x, inheritanceIndex)); - else if ((schema.AllOf?.Any(allOfEvaluatorForMappings) ?? false) && schema.AllOf[^1].Equals(schema.AllOf.Last(allOfEvaluatorForMappings))) - // ensure the matched AllOf entry is the last in the list - return GetDiscriminatorMappings(schema.AllOf.Last(allOfEvaluatorForMappings), inheritanceIndex); + else if (schema.IsInherited() && schema.AllOf?.OfType().FirstOrDefault(allOfEvaluatorForMappings) is { } allOfEntry) + // ensure we're in an inheritance context and get the discriminator from the parent when available + return GetDiscriminatorMappings(allOfEntry, inheritanceIndex); else if (schema.GetReferenceId() is string refId && !string.IsNullOrEmpty(refId)) return GetAllInheritanceSchemaReferences(refId, inheritanceIndex) .Where(static x => !string.IsNullOrEmpty(x)) @@ -428,9 +430,11 @@ internal static IEnumerable> GetDiscriminatorMappin return []; return schema.Discriminator - .Mapping; + .Mapping + .Where(static x => !string.IsNullOrEmpty(x.Value.Reference.Id)) + .Select(static x => KeyValuePair.Create(x.Key, x.Value.Reference.Id!)); } - private static readonly Func allOfEvaluatorForMappings = static x => x.Discriminator?.Mapping?.Any() ?? false; + private static readonly Func allOfEvaluatorForMappings = static x => x.Discriminator?.Mapping is { Count: > 0 }; private static IEnumerable GetAllInheritanceSchemaReferences(string currentReferenceId, ConcurrentDictionary> inheritanceIndex) { ArgumentException.ThrowIfNullOrEmpty(currentReferenceId); diff --git a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs index bf177454a3..d66c31453c 100644 --- a/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs +++ b/src/Kiota.Builder/Extensions/OpenApiUrlTreeNodeExtensions.cs @@ -73,9 +73,7 @@ internal static string CleanupParametersFromPath(string pathSegment) } private static IEnumerable GetParametersForPathItem(IOpenApiPathItem pathItem, string nodeSegment) { - if (pathItem.Parameters is null) - return []; - return pathItem.Parameters + return (pathItem.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)); @@ -86,7 +84,7 @@ public static IEnumerable GetPathParametersForCurrentSegment( node.IsComplexPathMultipleParameters()) if (node.PathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem)) return GetParametersForPathItem(pathItem, node.DeduplicatedSegment()); - else if (node.Children.Any()) + else if (node.Children.Count > 0) return node.Children .Where(static x => x.Value.PathItems.ContainsKey(Constants.DefaultOpenApiLabel)) .SelectMany(x => GetParametersForPathItem(x.Value.PathItems[Constants.DefaultOpenApiLabel], node.DeduplicatedSegment())) @@ -104,16 +102,16 @@ internal static string GetClassName(this OpenApiUrlTreeNode currentNode, Structu ArgumentNullException.ThrowIfNull(currentNode); return currentNode.GetSegmentName(structuredMimeTypes, suffix, prefix, operation, response, schema, requestBody, static x => x.LastOrDefault() ?? string.Empty); } - internal static string GetNavigationPropertyName(this OpenApiUrlTreeNode currentNode, StructuredMimeTypesCollection structuredMimeTypes, string? suffix = default, string? prefix = default, OpenApiOperation? operation = default, OpenApiResponse? response = default, OpenApiSchema? schema = default, bool requestBody = false) + internal static string GetNavigationPropertyName(this OpenApiUrlTreeNode currentNode, StructuredMimeTypesCollection structuredMimeTypes, string? suffix = default, string? prefix = default, OpenApiOperation? operation = default, OpenApiResponse? response = default, OpenApiSchema? schema = default, bool requestBody = false, string? placeholder = null) { ArgumentNullException.ThrowIfNull(currentNode); - var result = currentNode.GetSegmentName(structuredMimeTypes, suffix, prefix, operation, response, schema, requestBody, static x => string.Join(string.Empty, x.Select(static (y, idx) => idx == 0 ? y : y.ToFirstCharacterUpperCase())), false); + var result = currentNode.GetSegmentName(structuredMimeTypes, suffix, prefix, operation, response, schema, requestBody, static x => string.Join(string.Empty, x.Select(static (y, idx) => idx == 0 ? y : y.ToFirstCharacterUpperCase())), false, placeholder); if (httpVerbs.Contains(result)) return $"{result}Path"; // we don't run the change of an operation conflicting with a path on the same request builder return result; } private static readonly HashSet httpVerbs = new(8, StringComparer.OrdinalIgnoreCase) { "get", "post", "put", "patch", "delete", "head", "options", "trace" }; - private static string GetSegmentName(this OpenApiUrlTreeNode currentNode, StructuredMimeTypesCollection structuredMimeTypes, string? suffix, string? prefix, OpenApiOperation? operation, IOpenApiResponse? response, IOpenApiSchema? schema, bool requestBody, Func, string> segmentsReducer, bool skipExtension = true) + private static string GetSegmentName(this OpenApiUrlTreeNode currentNode, StructuredMimeTypesCollection structuredMimeTypes, string? suffix, string? prefix, OpenApiOperation? operation, IOpenApiResponse? response, IOpenApiSchema? schema, bool requestBody, Func, string> segmentsReducer, bool skipExtension = true, string? placeholder = null) { var referenceName = schema?.GetClassName(); var rawClassName = referenceName is not null && !string.IsNullOrEmpty(referenceName) ? @@ -123,6 +121,8 @@ private static string GetSegmentName(this OpenApiUrlTreeNode currentNode, Struct ((requestBody ? operation?.GetRequestSchema(structuredMimeTypes) : operation?.GetResponseSchema(structuredMimeTypes))?.GetClassName() is string requestClassName && !string.IsNullOrEmpty(requestClassName) ? requestClassName : CleanupParametersFromPath(currentNode.DeduplicatedSegment())?.ReplaceValueIdentifier())); + if (string.IsNullOrEmpty(rawClassName) && !string.IsNullOrEmpty(placeholder)) + rawClassName = placeholder; if (!string.IsNullOrEmpty(rawClassName) && string.IsNullOrEmpty(referenceName)) { if (stripExtensionForIndexersTestRegex().IsMatch(rawClassName)) // {id}.json is considered as indexer @@ -207,13 +207,13 @@ public static bool HasRequiredQueryParametersAcrossOperations(this OpenApiUrlTre private static IOpenApiParameter[] GetParameters(this IOpenApiPathItem pathItem, HttpMethod? operationType = null) { - var operationQueryParameters = (operationType, pathItem.Operations is not null && pathItem.Operations.Any()) switch + var operationQueryParameters = (operationType, pathItem.Operations is { Count: > 0 }) switch { (HttpMethod 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), _ => [], }; - return pathItem.Parameters? + return (pathItem.Parameters ?? Enumerable.Empty()) .Union(operationQueryParameters) .Where(static x => x.In == ParameterLocation.Query) .DistinctBy(static x => x.Name, StringComparer.Ordinal) @@ -225,17 +225,12 @@ public static string GetUrlTemplate(this OpenApiUrlTreeNode currentNode, HttpMet { ArgumentNullException.ThrowIfNull(currentNode); var queryStringParameters = string.Empty; - if (currentNode.HasOperations(Constants.DefaultOpenApiLabel) && includeQueryParameters) + var trailingSlashItem = $"{currentNode.Path}\\"; + if (includeQueryParameters && currentNode.HasOperations(Constants.DefaultOpenApiLabel)) { var pathItem = currentNode.PathItems[Constants.DefaultOpenApiLabel]; var parameters = pathItem.GetParameters(operationType); - if (currentNode.Children.TryGetValue($"{currentNode.Path}\\", out var currentNodeWithTrailingSlash)) - { - // having a node with a trailing slash means we have 2 nodes in the tree - parameters = parameters.Union(currentNodeWithTrailingSlash.PathItems[Constants.DefaultOpenApiLabel].GetParameters(operationType)) - .ToArray(); - } if (parameters.Length != 0) { var requiredParameters = string.Join("&", parameters.Where(static x => x.Required) @@ -348,6 +343,7 @@ internal static void MergeIndexNodesAtSameLevel(this OpenApiUrlTreeNode node, IL var segmentIndex = indexNode.Value.Path.Split('\\', StringSplitOptions.RemoveEmptyEntries).ToList().IndexOf(indexNode.Value.Segment); var newSegmentParameterName = oldSegmentName.EndsWith("-id", StringComparison.OrdinalIgnoreCase) ? oldSegmentName : $"{{{oldSegmentName.TrimSuffix("id", StringComparison.OrdinalIgnoreCase)}-id}}"; indexNode.Value.Path = indexNode.Value.Path.Replace(indexNode.Key, newSegmentParameterName, StringComparison.OrdinalIgnoreCase); + indexNode.Value.AdditionalData.Add(Constants.KiotaSegmentNameTreeNodeExtensionKey, [newSegmentParameterName]); indexNode.Value.AddDeduplicatedSegment(newSegmentParameterName); node.Children.Add(newSegmentParameterName, indexNode.Value); CopyNodeIntoOtherNode(indexNode.Value, indexNode.Value, indexNode.Key, newSegmentParameterName, logger); @@ -409,34 +405,32 @@ private static void CopyNodeIntoOtherNode(OpenApiUrlTreeNode source, OpenApiUrlT pathParameterNameReplacement = pathParameterNameReplacement.Trim('{', '}'); foreach (var pathItem in source.PathItems) { - if (pathItem.Value.Parameters is not null && pathItem.Value.Operations is not null) + foreach (var pathParameter in (pathItem.Value.Parameters ?? Enumerable.Empty()) + .Where(x => x.In == ParameterLocation.Path && pathParameterNameToReplace.Equals(x.Name, StringComparison.Ordinal)) + .Union( + pathItem.Value.Operations is null ? + [] : + pathItem.Value.Operations + .SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty()) + .Where(x => x.In == ParameterLocation.Path && pathParameterNameToReplace.Equals(x.Name, StringComparison.Ordinal)) + )) { - foreach (var pathParameter in pathItem - .Value - .Parameters - .Where(x => x.In == ParameterLocation.Path && pathParameterNameToReplace.Equals(x.Name, StringComparison.Ordinal)) - .Union( - pathItem - .Value - .Operations - .SelectMany(static x => x.Value.Parameters ?? Enumerable.Empty()) - .Where(x => x.In == ParameterLocation.Path && pathParameterNameToReplace.Equals(x.Name, StringComparison.Ordinal)) - )) + switch (pathParameter) { - switch (pathParameter) - { - case OpenApiParameter openApiParameter: - openApiParameter.Name = pathParameterNameReplacement; - break; - case OpenApiParameterReference openApiReference when openApiReference.RecursiveTarget is { } openApiReferenceTarget: - openApiReferenceTarget.Name = pathParameterNameReplacement; - break; - default: - throw new InvalidOperationException("Unexpected parameter type"); - } + case OpenApiParameter openApiParameter: + openApiParameter.Name = pathParameterNameReplacement; + break; + case OpenApiParameterReference openApiReference when openApiReference.RecursiveTarget is { } openApiReferenceTarget: + openApiReferenceTarget.Name = pathParameterNameReplacement; + break; + default: + throw new InvalidOperationException("Unexpected parameter type"); } - if (source != destination && !destination.PathItems.TryAdd(pathItem.Key, pathItem.Value) && - destination.PathItems.TryGetValue(pathItem.Key, out var dpi) && dpi is OpenApiPathItem destinationPathItem) + } + if (source != destination && !destination.PathItems.TryAdd(pathItem.Key, pathItem.Value) && + destination.PathItems.TryGetValue(pathItem.Key, out var dpi) && dpi is OpenApiPathItem destinationPathItem) + { + if (pathItem.Value.Operations is { Count: > 0 }) { destinationPathItem.Operations ??= new Dictionary(); foreach (var operation in pathItem.Value.Operations) @@ -446,20 +440,23 @@ private static void CopyNodeIntoOtherNode(OpenApiUrlTreeNode source, OpenApiUrlT logger.LogWarning("Duplicate operation {Operation} in path {Path}", operation.Key, pathItem.Key); } } + } + if (pathItem.Value.Parameters is { Count: > 0 }) + { destinationPathItem.Parameters ??= new List(); foreach (var pathParameter in pathItem.Value.Parameters) { destinationPathItem.Parameters.Add(pathParameter); } - if (pathItem.Value.Extensions is not null) + } + if (pathItem.Value.Extensions is { Count: > 0 }) + { + destinationPathItem.Extensions ??= new Dictionary(); + foreach (var extension in pathItem.Value.Extensions) { - destinationPathItem.Extensions ??= new Dictionary(); - foreach (var extension in pathItem.Value.Extensions) + if (!destinationPathItem.Extensions.TryAdd(extension.Key, extension.Value)) { - if (!destinationPathItem.Extensions.TryAdd(extension.Key, extension.Value)) - { - logger.LogWarning("Duplicate extension {Extension} in path {Path}", extension.Key, pathItem.Key); - } + logger.LogWarning("Duplicate extension {Extension} in path {Path}", extension.Key, pathItem.Key); } } } diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index a6f3e5cc72..25e27b7479 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -39,10 +39,10 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index f69f6a9d97..04a7298e72 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -32,7 +32,6 @@ using Kiota.Builder.WorkspaceManagement; using Kiota.Builder.Writers; using Microsoft.Extensions.Logging; -using Microsoft.OpenApi.Any; using Microsoft.OpenApi.ApiManifest; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.MicrosoftExtensions; @@ -476,7 +475,7 @@ internal void FilterPathsByPatterns(OpenApiDocument doc) .ToList() .ForEach(x => path.Value.Operations.Remove(x)); } - foreach (var path in doc.Paths.Where(static x => x.Value.Operations is null || !x.Value.Operations.Any()).ToList()) + foreach (var path in doc.Paths.Where(static x => x.Value.Operations is null || x.Value.Operations.Count == 0).ToList()) doc.Paths.Remove(path.Key); } @@ -521,7 +520,7 @@ private async Task LoadStreamAsync(string inputPath, CancellationToken c } public static string GetDeeperMostCommonNamespaceNameForModels(OpenApiDocument document) { - if (!(document?.Components?.Schemas?.Any() ?? false)) return string.Empty; + if (!(document?.Components?.Schemas is { Count: > 0 })) return string.Empty; var distinctKeys = document.Components .Schemas .Keys @@ -609,7 +608,7 @@ private void AddOperationSecurityRequirementToDOM(OpenApiOperation operation, Co return; } - if (operation.Security == null || !operation.Security.Any() || openApiDocument.Components?.SecuritySchemes is null) + if (operation.Security == null || operation.Security.Count == 0 || openApiDocument.Components?.SecuritySchemes is null) return; var securitySchemes = openApiDocument.Components.SecuritySchemes; @@ -677,6 +676,7 @@ public async Task CreateLanguageSourceFilesAsync(GenerationLanguage language, Co private const string RequestAdapterParameterName = "requestAdapter"; private const string ConstructorMethodName = "constructor"; internal const string UntypedNodeName = "UntypedNode"; + internal const string TrailingSlashPlaceholder = "EmptyPathSegment"; /// /// Create a CodeClass instance that is a request builder class for the OpenApiUrlTreeNode /// @@ -698,7 +698,7 @@ private void CreateRequestBuilderClass(CodeNamespace currentNamespace, OpenApiUr else { var targetNS = currentNode.DoesNodeBelongToItemSubnamespace() ? currentNamespace.EnsureItemNamespace() : currentNamespace; - var className = currentNode.DoesNodeBelongToItemSubnamespace() ? currentNode.GetNavigationPropertyName(config.StructuredMimeTypes, ItemRequestBuilderSuffix) : currentNode.GetNavigationPropertyName(config.StructuredMimeTypes, RequestBuilderSuffix); + var className = currentNode.DoesNodeBelongToItemSubnamespace() ? currentNode.GetNavigationPropertyName(config.StructuredMimeTypes, ItemRequestBuilderSuffix, placeholder: TrailingSlashPlaceholder) : currentNode.GetNavigationPropertyName(config.StructuredMimeTypes, RequestBuilderSuffix, placeholder: TrailingSlashPlaceholder); codeClass = targetNS.AddClass(new CodeClass { Name = currentNamespace.Name.EndsWith(OpenApiUrlTreeNodeExtensions.ReservedItemNameEscaped, StringComparison.OrdinalIgnoreCase) ? className.CleanupSymbolName().Replace(OpenApiUrlTreeNodeExtensions.ReservedItemName, OpenApiUrlTreeNodeExtensions.ReservedItemNameEscaped, StringComparison.OrdinalIgnoreCase) : className.CleanupSymbolName(), @@ -715,14 +715,14 @@ private void CreateRequestBuilderClass(CodeNamespace currentNamespace, OpenApiUr // Add properties for children foreach (var child in currentNode.Children.Select(static x => x.Value)) { - var propIdentifier = child.GetNavigationPropertyName(config.StructuredMimeTypes); - var propType = child.GetNavigationPropertyName(config.StructuredMimeTypes, child.DoesNodeBelongToItemSubnamespace() ? ItemRequestBuilderSuffix : RequestBuilderSuffix); + var propIdentifier = child.GetNavigationPropertyName(config.StructuredMimeTypes, placeholder: TrailingSlashPlaceholder); + var propType = child.GetNavigationPropertyName(config.StructuredMimeTypes, child.DoesNodeBelongToItemSubnamespace() ? ItemRequestBuilderSuffix : RequestBuilderSuffix, placeholder: TrailingSlashPlaceholder); if (child.Segment.Equals(OpenApiUrlTreeNodeExtensions.ReservedItemName, StringComparison.OrdinalIgnoreCase) && !child.DoesNodeBelongToItemSubnamespace()) propType = propType.Replace(OpenApiUrlTreeNodeExtensions.ReservedItemName, OpenApiUrlTreeNodeExtensions.ReservedItemNameEscaped, StringComparison.OrdinalIgnoreCase); if (child.IsPathSegmentWithSingleSimpleParameter()) { - var indexerParameterType = GetIndexerParameter(child, currentNode); + var indexerParameterType = GetIndexerParameter(child); codeClass.AddIndexer(CreateIndexer($"{propIdentifier}-indexer", propType, indexerParameterType, child, currentNode)); } else if (child.IsComplexPathMultipleParameters()) @@ -1094,19 +1094,19 @@ private IEnumerable GetUnmappedTypeDefinitions(CodeElement codeElement }; } private static CodeType DefaultIndexerParameterType => new() { Name = "string", IsExternal = true }; - private const char OpenAPIUrlTreeNodePathSeparator = '\\'; - private CodeParameter GetIndexerParameter(OpenApiUrlTreeNode currentNode, OpenApiUrlTreeNode parentNode) + private CodeParameter GetIndexerParameter(OpenApiUrlTreeNode currentNode) { - var parameterName = string.Join(OpenAPIUrlTreeNodePathSeparator, currentNode.Path.Split(OpenAPIUrlTreeNodePathSeparator, StringSplitOptions.RemoveEmptyEntries) - .Skip(parentNode.Path.Count(static x => x == OpenAPIUrlTreeNodePathSeparator))) - .Trim(OpenAPIUrlTreeNodePathSeparator, ForwardSlash, '{', '}'); + var parameterName = (currentNode.AdditionalData.TryGetValue(Constants.KiotaSegmentNameTreeNodeExtensionKey, out var newNames) && newNames is { Count: > 0 } ? + newNames[0] : + currentNode.Segment).Trim('{', '}'); 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 }) ?? []) - .OrderBy(static x => x.IsPathParameter) - .Select(static x => x.Parameter) - .FirstOrDefault(x => parameterName.Equals(x.Name, StringComparison.OrdinalIgnoreCase) && x.In == ParameterLocation.Path) : + var parameter = pathItems.TryGetValue(Constants.DefaultOpenApiLabel, out var pathItem) ? + (pathItem.Parameters ?? Enumerable.Empty()) + .Select(static x => new { Parameter = x, IsPathParameter = true }) + .Union(pathItem.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 => parameterName.Equals(x.Name, StringComparison.OrdinalIgnoreCase) && x.In == ParameterLocation.Path) : default; var type = parameter switch { @@ -1129,12 +1129,12 @@ private CodeParameter GetIndexerParameter(OpenApiUrlTreeNode currentNode, OpenAp } private static IDictionary GetPathItems(OpenApiUrlTreeNode currentNode, bool validateIsParameterNode = true) { - if ((!validateIsParameterNode || currentNode.IsParameter) && currentNode.PathItems.Any()) + if ((!validateIsParameterNode || currentNode.IsParameter) && currentNode.PathItems.Count != 0) { return currentNode.PathItems; } - if (currentNode.Children.Any()) + if (currentNode.Children.Count != 0) { return currentNode.Children .SelectMany(static x => GetPathItems(x.Value, false)) @@ -1225,9 +1225,9 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten if (typeSchema?.Items?.IsEnum() ?? false) return null; var typeNames = new List { typeSchema?.Items?.Type, typeSchema?.Type }; - if (typeSchema?.AnyOf?.Any() ?? false) + if (typeSchema?.AnyOf is { Count: > 0 }) typeNames.AddRange(typeSchema.AnyOf.Select(x => x.Type)); // double is sometimes an anyof string, number and enum - if (typeSchema?.OneOf?.Any() ?? false) + if (typeSchema?.OneOf is { Count: > 0 }) 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 => x is not null && !typeNamesToSkip.Contains(x.Value)); @@ -1607,7 +1607,7 @@ private void AddRequestBuilderMethodParameters(OpenApiUrlTreeNode currentNode, N && requestBodySchema.Properties is not null) { var mediaType = operation.RequestBody.Content.First(x => x.Value.Schema == requestBodySchema).Value; - if (mediaType.Encoding is not null && mediaType.Encoding.Any()) + if (mediaType.Encoding is not null && mediaType.Encoding.Count != 0) { requestBodyType = new CodeType { Name = "MultipartBody", IsExternal = true, }; foreach (var encodingEntry in mediaType.Encoding @@ -1662,7 +1662,7 @@ private void AddRequestBuilderMethodParameters(OpenApiUrlTreeNode currentNode, N }); method.RequestBodyContentType = config.StructuredMimeTypes.GetContentTypes(operation.RequestBody.Content?.Where(x => schemaReferenceComparer.Equals(x.Value.Schema, requestBodySchema)).Select(static x => x.Key) ?? []).First(); } - else if (operation.RequestBody.Content?.Any() ?? false) + else if (operation.RequestBody.Content is { Count: > 0 }) { var nParam = new CodeParameter { @@ -1866,29 +1866,30 @@ private CodeTypeBase CreateComposedModelDeclaration(OpenApiUrlTreeNode currentNo ?.ToList() .ForEach(x => unionType.DiscriminatorInformation.AddDiscriminatorMapping(x.Key, x.Value)); var membersWithNoName = 0; - foreach (var currentSchema in schemas!) - { - var shortestNamespace = GetShortestNamespace(codeNamespace, currentSchema); - var className = currentSchema.GetSchemaName().CleanupSymbolName(); - if (string.IsNullOrEmpty(className)) - if (GetPrimitiveType(currentSchema) is CodeType primitiveType && !string.IsNullOrEmpty(primitiveType.Name)) - { - if (currentSchema.IsArray()) - primitiveType.CollectionKind = CodeTypeBase.CodeTypeCollectionKind.Complex; - if (!unionType.ContainsType(primitiveType)) - unionType.AddType(primitiveType); - continue; - } - else - className = $"{unionType.Name}Member{++membersWithNoName}"; - var declarationType = new CodeType + if (schemas is not null) + foreach (var currentSchema in schemas) { - TypeDefinition = AddModelDeclarationIfDoesntExist(currentNode, operation, currentSchema, className, shortestNamespace, null), - CollectionKind = currentSchema.IsArray() ? CodeTypeBase.CodeTypeCollectionKind.Complex : default - }; - if (!unionType.ContainsType(declarationType)) - unionType.AddType(declarationType); - } + var shortestNamespace = GetShortestNamespace(codeNamespace, currentSchema); + var className = currentSchema.GetSchemaName().CleanupSymbolName(); + if (string.IsNullOrEmpty(className)) + if (GetPrimitiveType(currentSchema) is CodeType primitiveType && !string.IsNullOrEmpty(primitiveType.Name)) + { + if (currentSchema.IsArray()) + primitiveType.CollectionKind = CodeTypeBase.CodeTypeCollectionKind.Complex; + if (!unionType.ContainsType(primitiveType)) + unionType.AddType(primitiveType); + continue; + } + else + className = $"{unionType.Name}Member{++membersWithNoName}"; + var declarationType = new CodeType + { + TypeDefinition = AddModelDeclarationIfDoesntExist(currentNode, operation, currentSchema, className, shortestNamespace, null), + CollectionKind = currentSchema.IsArray() ? CodeTypeBase.CodeTypeCollectionKind.Complex : default + }; + if (!unionType.ContainsType(declarationType)) + unionType.AddType(declarationType); + } if (schema.IsArrayOfTypes()) { AddTypeArrayMemberToComposedType(schema, JsonSchemaType.Boolean, unionType); @@ -2529,7 +2530,7 @@ internal static void AddSerializationMembers(CodeClass model, bool includeAdditi } private CodeClass? CreateOperationParameterClass(OpenApiUrlTreeNode node, NetHttpMethod operationType, OpenApiOperation operation, CodeClass parentClass) { - var parameters = node.PathItems[Constants.DefaultOpenApiLabel].Parameters?.Union(operation.Parameters ?? Enumerable.Empty()).Where(static p => p.In == ParameterLocation.Query).ToArray() ?? []; + var parameters = (node.PathItems[Constants.DefaultOpenApiLabel].Parameters ?? Enumerable.Empty()).Union(operation.Parameters ?? Enumerable.Empty()).Where(static p => p.In == ParameterLocation.Query).ToArray(); if (parameters.Length != 0) { var parameterClass = parentClass.AddInnerClass(new CodeClass diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index ea88661aa6..acab0e80b8 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -159,14 +159,9 @@ ex is SecurityException || return readResult; } - internal Task GetDocumentFromStreamAsync(Stream input, GenerationConfiguration config, bool generating = false, CancellationToken cancellationToken = default) + internal async Task GetDocumentFromStreamAsync(Stream input, GenerationConfiguration config, bool generating = false, CancellationToken cancellationToken = default) { - var documentWithResult = GetDocumentWithResultFromStreamAsync(input, config, generating, cancellationToken); - return documentWithResult.ContinueWith( - static x => x.Result?.Document, - cancellationToken, - TaskContinuationOptions.None, - TaskScheduler.Default - ); + var result = await GetDocumentWithResultFromStreamAsync(input, config, generating, cancellationToken).ConfigureAwait(false); + return result?.Document; } } diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index c7b54cc81b..1a81d519a4 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -567,7 +567,13 @@ public override void Visit(IOpenApiSchema schema) { if (schema.Discriminator?.Mapping is null) return; - var keysToRemove = schema.Discriminator.Mapping.Where(x => _document.Components?.Schemas is null || !_document.Components.Schemas.ContainsKey(x.Value.Split('/', StringSplitOptions.RemoveEmptyEntries)[^1])).Select(static x => x.Key).ToArray(); + var keysToRemove = schema.Discriminator + .Mapping + .Where(x => _document.Components?.Schemas is null || + x.Value.Reference.Id is not null && + !_document.Components.Schemas.ContainsKey(x.Value.Reference.Id.Split('/', StringSplitOptions.RemoveEmptyEntries)[^1])) + .Select(static x => x.Key) + .ToArray(); foreach (var key in keysToRemove) schema.Discriminator.Mapping.Remove(key); base.Visit(schema); @@ -1011,7 +1017,7 @@ private static (OpenApiRuntime[], Function[], ConversationStarter[]) GetRuntimes return (runtimes.ToArray(), functions.ToArray(), conversationStarters.ToArray()); } - private static Auth GetAuth(IList securityRequirements) + private static Auth GetAuth(List securityRequirements) { // Only one security requirement object is allowed const string tooManySchemesError = "Multiple security requirements are not supported. Operations can only list one security requirement."; diff --git a/src/Kiota.Builder/Validation/NoContentWithBody.cs b/src/Kiota.Builder/Validation/NoContentWithBody.cs index 29b1c5b960..d01e880cac 100644 --- a/src/Kiota.Builder/Validation/NoContentWithBody.cs +++ b/src/Kiota.Builder/Validation/NoContentWithBody.cs @@ -1,5 +1,4 @@ -using System.Linq; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Validations; namespace Kiota.Builder.Validation; @@ -8,7 +7,7 @@ public class NoContentWithBody : ValidationRule { public NoContentWithBody() : base(nameof(NoContentWithBody), static (context, operation) => { - if (operation.Responses is not null && 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 is { Count: > 0 }) context.CreateWarning(nameof(NoContentWithBody), "A 204 response with a body media type was found. The response body will be ignored."); }) { diff --git a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs index 2a390b0c6b..13eaf4765f 100644 --- a/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs +++ b/src/Kiota.Builder/Validation/OpenApiSchemaComparer.cs @@ -6,6 +6,7 @@ using Kiota.Builder.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; +using Microsoft.OpenApi.Models.References; namespace Kiota.Builder.Validation; @@ -134,8 +135,11 @@ public bool Equals(OpenApiDiscriminator? x, OpenApiDiscriminator? y) return x.PropertyName.EqualsIgnoreCase(y.PropertyName) && GetOrderedRequests(x.Mapping).SequenceEqual(GetOrderedRequests(y.Mapping), mappingComparer); } private static readonly IOrderedEnumerable> defaultOrderedDictionary = new Dictionary(0).OrderBy(x => x.Key, StringComparer.Ordinal); - private static IOrderedEnumerable> GetOrderedRequests(IDictionary? mappings) => - mappings?.OrderBy(x => x.Key, StringComparer.Ordinal) ?? defaultOrderedDictionary; + private static IOrderedEnumerable> GetOrderedRequests(Dictionary? mappings) => + mappings?.Where(static x => !string.IsNullOrEmpty(x.Value.Reference.Id)) + .Select(static x => KeyValuePair.Create(x.Key, x.Value.Reference.Id!)) + .OrderBy(x => x.Key, StringComparer.Ordinal) ?? + defaultOrderedDictionary; /// public int GetHashCode([DisallowNull] OpenApiDiscriminator obj) { diff --git a/src/kiota/Handlers/KiotaGitHubDeviceLoginCommandHanlder.cs b/src/kiota/Handlers/KiotaGitHubDeviceLoginCommandHandler.cs similarity index 100% rename from src/kiota/Handlers/KiotaGitHubDeviceLoginCommandHanlder.cs rename to src/kiota/Handlers/KiotaGitHubDeviceLoginCommandHandler.cs diff --git a/src/kiota/Handlers/KiotaGitHubLogoutCommandhandler.cs b/src/kiota/Handlers/KiotaGitHubLogoutCommandHandler.cs similarity index 100% rename from src/kiota/Handlers/KiotaGitHubLogoutCommandhandler.cs rename to src/kiota/Handlers/KiotaGitHubLogoutCommandHandler.cs diff --git a/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs b/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs index c5f4edc9eb..4a3ff6f07e 100644 --- a/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs +++ b/tests/Kiota.Builder.Tests/ContentTypeMappingTests.cs @@ -90,14 +90,18 @@ public void GeneratesTheRightReturnTypeBasedOnContentAndStatus(string contentTyp { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - [statusCode] = new OpenApiResponse { - Content = { - [contentType] = new OpenApiMediaType { + [statusCode] = new OpenApiResponse + { + Content = new() + { + [contentType] = new OpenApiMediaType + { Schema = addModel ? new OpenApiSchemaReference("myobject") : null } } @@ -179,12 +183,16 @@ public void GeneratesTheRightParameterTypeBasedOnContentAndStatus(string content { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - [contentType] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + [contentType] = new OpenApiMediaType + { Schema = addModel ? new OpenApiSchemaReference("myobject") : null } } @@ -254,13 +262,19 @@ public void GeneratesTheRightAcceptHeaderBasedOnContentAndStatus(string contentM { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = contentMediaTypes.Split(',').Select(x => new {Key = x.Trim(), value = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = contentMediaTypes.Split(',').Select(x => new + { + Key = x.Trim(), + value = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject"), } }).ToDictionary(x => x.Key, x => x.value) @@ -327,12 +341,17 @@ public void GeneratesTheRightContentTypeHeaderBasedOnContentAndStatus(string con { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Post] = new OpenApiOperation { RequestBody = new OpenApiRequestBody { - Content = contentMediaTypes.Split(',').Select(x => new {Key = x.Trim(), value = new OpenApiMediaType { + Content = contentMediaTypes.Split(',').Select(x => new + { + Key = x.Trim(), + value = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject"), } }).ToDictionary(x => x.Key, x => x.value) diff --git a/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs b/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs index d56217ccc5..aad7213cee 100644 --- a/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Export/PublicAPIExportServiceTests.cs @@ -92,7 +92,7 @@ public void Defensive() [InlineData(GenerationLanguage.PHP)] public async Task GeneratesExportsAndFileHasExpectedAssertionsAsync(GenerationLanguage generationLanguage) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var testDocumentStream = await GetTestDocumentStreamAsync(); var mockLogger = new Mock>(); var generationConfig = new GenerationConfiguration @@ -199,7 +199,7 @@ private static void ValidateExportTypeScript(HashSet exportContents) Assert.Contains("exportNamespace.Graph~~>BaseRequestBuilder", exportContents); // captures class inheritance. TS does not do inheritance due to interfaces. Assert.Contains("exportNamespace.models.microsoft.graph.User~~>AdditionalDataHolder; Parsable", exportContents);// captures implemented interfaces Assert.Contains("exportNamespace.models.microsoft.graph.User::|public|id:string", exportContents);// captures property location,type and access inheritance. No getter/setter in TS - // NOTE: No constructors in TS + // NOTE: No constructors in TS Assert.Contains("exportNamespace.me.meRequestBuilder::|public|toGetRequestInformation(requestConfiguration?:RequestConfiguration):RequestInformation", exportContents);// captures methods, their parameters(name and types), return and access Assert.Contains("exportNamespace.models.microsoft.graph::createUserFromDiscriminatorValue(parseNode:ParseNode):User", exportContents);// captures code functions Assert.Contains("exportNamespace.models.microsoft.graph::deserializeIntoUser(User:User={}):Record void>", exportContents);// captures code functions and default params diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs index 82971aacba..aacc63af86 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Kiota.Builder.Extensions; using Microsoft.OpenApi.Models; using Xunit; @@ -47,7 +48,13 @@ private OpenApiResponses CreateWithStatusCodes(string[] statusCodes) var responses = new OpenApiResponses(); foreach (var sc in statusCodes) { - responses.Add(sc, new OpenApiResponse()); + responses.Add(sc, new OpenApiResponse + { + Content = new Dictionary + { + ["application/json"] = new OpenApiMediaType() + } + }); } return responses; } diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs index dd5edbd963..ae7314be69 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs @@ -1107,6 +1107,7 @@ public void IsOdataPrimitiveBackwardCompatible() [Fact] public void ReturnsEmptyPropertyNameOnCircularReferences() { + var document = new OpenApiDocument(); var entitySchema = new OpenApiSchema { Properties = new Dictionary @@ -1130,14 +1131,13 @@ public void ReturnsEmptyPropertyNameOnCircularReferences() ], Discriminator = new OpenApiDiscriminator { - Mapping = new Dictionary + Mapping = new Dictionary { - ["microsoft.graph.entity"] = "entity", - ["microsoft.graph.user"] = "user" + ["microsoft.graph.entity"] = new OpenApiSchemaReference("entity", document), + ["microsoft.graph.user"] = new OpenApiSchemaReference("user", document) } } }; - var document = new OpenApiDocument(); document.AddComponent("microsoft.graph.entity", entitySchema); document.AddComponent("microsoft.graph.user", userSchema); document.SetReferenceHostDocument(); diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs index 15b25d4670..e3f1cf9d7d 100644 --- a/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs +++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiUrlTreeNodeExtensionsTests.cs @@ -331,7 +331,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInPathItem() }; doc.Paths.Add("users\\{id}\\manager", new OpenApiPathItem() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -356,7 +356,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInPathItem() Type = JsonSchemaType.String } } - }, + ], Operations = new Dictionary { { HttpMethod.Get, new() { } @@ -377,7 +377,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInOperation() { Operations = new Dictionary { { HttpMethod.Get, new() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -402,7 +402,7 @@ public void GeneratesRequiredQueryParametersAndOptionalMixInOperation() Type = JsonSchemaType.String } } - }, + ], } }, } @@ -419,7 +419,7 @@ public void GeneratesOnlyOptionalQueryParametersInPathItem() }; doc.Paths.Add("users\\{id}\\manager", new OpenApiPathItem() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -443,7 +443,7 @@ public void GeneratesOnlyOptionalQueryParametersInPathItem() Type = JsonSchemaType.String } } - }, + ], Operations = new Dictionary { { HttpMethod.Get, new() { } @@ -464,7 +464,7 @@ public void GeneratesOnlyOptionalQueryParametersInOperation() { Operations = new Dictionary { { HttpMethod.Get, new() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -487,7 +487,7 @@ public void GeneratesOnlyOptionalQueryParametersInOperation() Type = JsonSchemaType.String } } - }, + ], } }, } @@ -504,7 +504,7 @@ public void GeneratesOnlyRequiredQueryParametersInPathItem() }; doc.Paths.Add("users\\{id}\\manager", new OpenApiPathItem() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -529,7 +529,7 @@ public void GeneratesOnlyRequiredQueryParametersInPathItem() Type = JsonSchemaType.String } } - }, + ], Operations = new Dictionary { { HttpMethod.Get, new() { } @@ -550,7 +550,7 @@ public void GeneratesOnlyRequiredQueryParametersInOperation() { Operations = new Dictionary { { HttpMethod.Get, new() { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -575,7 +575,7 @@ public void GeneratesOnlyRequiredQueryParametersInOperation() Type = JsonSchemaType.String } } - }, + ], } }, } @@ -783,7 +783,7 @@ public void SinglePathParametersAreDeduplicated() { ["users/{foo}/careerAdvisor/{id}"] = new OpenApiPathItem { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "foo", In = ParameterLocation.Path, @@ -792,14 +792,17 @@ public void SinglePathParametersAreDeduplicated() Type = JsonSchemaType.String } }, - }, - Operations = { + ], + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("microsoft.graph.user") @@ -812,7 +815,7 @@ public void SinglePathParametersAreDeduplicated() }, ["users/{id}/careerAdvisor"] = new OpenApiPathItem { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -821,14 +824,17 @@ public void SinglePathParametersAreDeduplicated() Type = JsonSchemaType.String } }, - }, - Operations = { + ], + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("microsoft.graph.user") @@ -841,10 +847,11 @@ public void SinglePathParametersAreDeduplicated() }, ["users/{user-id}/manager"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "user-id", In = ParameterLocation.Path, @@ -853,11 +860,13 @@ public void SinglePathParametersAreDeduplicated() Type = JsonSchemaType.String } }, - }, - Responses = new OpenApiResponses { + ], + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("microsoft.graph.user") @@ -935,13 +944,16 @@ public void SinglePathParametersAreDeduplicatedAndOrderIsRespected() { ["/repos/{owner}/{repo}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("repo") @@ -954,13 +966,16 @@ public void SinglePathParametersAreDeduplicatedAndOrderIsRespected() }, ["/repos/{template_owner}/{template_repo}/generate"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("repo") @@ -1002,16 +1017,20 @@ public void repro4085() { ["/path/{thingId}/abc/{second}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.String } } @@ -1023,16 +1042,20 @@ public void repro4085() }, ["/path/{differentThingId}/def/{second}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [HttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.String } } diff --git a/tests/Kiota.Builder.Tests/FakeLogger.cs b/tests/Kiota.Builder.Tests/FakeLogger.cs index 977ed4b100..eb574b063c 100644 --- a/tests/Kiota.Builder.Tests/FakeLogger.cs +++ b/tests/Kiota.Builder.Tests/FakeLogger.cs @@ -23,8 +23,10 @@ public bool IsEnabled(LogLevel logLevel) return true; } - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) +#nullable enable + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { LogEntries.Add(new(logLevel, formatter(state, exception))); } +#nullable restore } diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 4c217706fe..8004a535a7 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -43,7 +43,7 @@ public void Dispose() [Fact] public async Task CreateOpenApiDocumentWithResultAsync_ReturnsDiagnostics() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.4 servers: - url: https://graph.microsoft.com/v1.0 @@ -70,9 +70,9 @@ public async Task CreateOpenApiDocumentWithResultAsync_ReturnsDiagnostics() [Fact] public async Task SupportsExternalReferences() { - var tempFilePathReferee = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePathReferee = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePathReferee, - """ +""" openapi: 3.1.1 info: title: OData Service for namespace microsoft.graph @@ -97,9 +97,9 @@ await File.WriteAllTextAsync(tempFilePathReferee, id: type: string """); - var tempFilePathReferrer = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePathReferrer = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePathReferrer, - $$$""" +$$$""" openapi: 3.1.1 info: title: OData Service for namespace microsoft.graph @@ -115,7 +115,7 @@ await File.WriteAllTextAsync(tempFilePathReferrer, content: application/json: schema: - $ref: './{{{Path.GetFileName(tempFilePathReferee)}}}#/components/schemas/MySchema' + $ref: '{{{tempFilePathReferee}}}#/components/schemas/MySchema' components: schemas: MySchema: @@ -144,7 +144,7 @@ await File.WriteAllTextAsync(tempFilePathReferrer, [Theory] public async Task SupportsRelativeServerUrlAsync(string descriptionUrl, string serverRelativeUrl, string expected) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -179,7 +179,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task HonoursNoneKeyForSerializationAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -215,7 +215,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task DeduplicatesHostNamesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -251,7 +251,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task DeduplicatesHostNamesWithOpenAPI2Async() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"swagger: 2.0 info: title: OData Service for namespace microsoft.graph @@ -289,7 +289,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"swagger: 2.0 [Fact] public async Task HandlesSpecialCharactersInPathSegmentAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -334,7 +334,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task HandlesPathWithRepeatedSegment() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -402,7 +402,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task HandlesPathWithItemInNameSegment() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -500,7 +500,7 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 [Fact] public async Task ParsesEnumDescriptionsAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -578,7 +578,7 @@ public async Task ParsesEnumDescriptionsAsync() [Fact] public async Task ParsesEnumFlagsInformationAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -628,7 +628,7 @@ public async Task ParsesEnumFlagsInformationAsync() [Fact] public async Task DoesntConflictOnModelsNamespaceAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -692,7 +692,7 @@ public async Task DoesntConflictOnModelsNamespaceAsync() [InlineData(GenerationLanguage.Ruby)] public async Task DoesNotAddSuperflousFieldsToModelsAsync(GenerationLanguage language) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.3 info: title: Example API @@ -782,7 +782,7 @@ public async Task DoesNotAddSuperflousFieldsToModelsAsync(GenerationLanguage lan [Fact] public async Task NamesComponentsInlineSchemasProperlyAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -853,7 +853,7 @@ public async Task NamesComponentsInlineSchemasProperlyAsync() [InlineData("deprecated: true")] public async Task DoesNotIntroduceIntermediateTypesForMeaninglessPropertiesAsync(string additionalInformation) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -907,7 +907,7 @@ public async Task DoesNotIntroduceIntermediateTypesForMeaninglessPropertiesAsync [Fact] public async Task TrimsInheritanceUnusedModelsAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1063,7 +1063,7 @@ public async Task TrimsInheritanceUnusedModelsAsync() [Fact] public async Task DisambiguatesReservedPropertiesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1140,7 +1140,7 @@ public async Task DisambiguatesReservedPropertiesAsync() [Fact] public async Task TrimsInheritanceUnusedModelsWithUnionAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1280,7 +1280,7 @@ internal static async Task GetDocumentStreamAsync(string document) [Fact] public async Task ParsesKiotaExtensionAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1312,7 +1312,7 @@ public async Task ParsesKiotaExtensionAsync() [Fact] public async Task UpdatesGenerationConfigurationFromInformationAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1347,7 +1347,7 @@ await File.WriteAllTextAsync(tempFilePath, @"openapi: 3.0.1 [Fact] public async Task DoesntFailOnEmptyKiotaExtensionAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1365,7 +1365,7 @@ public async Task DoesntFailOnEmptyKiotaExtensionAsync() [Fact] public async Task DoesntFailOnParameterWithoutSchemaKiotaExtensionAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1389,7 +1389,7 @@ public async Task DoesntFailOnParameterWithoutSchemaKiotaExtensionAsync() [Fact] public async Task GetsUrlTreeNodeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -1418,7 +1418,7 @@ await File.WriteAllTextAsync(tempFilePath, @"openapi: 3.0.1 [Fact] public async Task DoesntThrowOnMissingServerForV2Async() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllLinesAsync(tempFilePath, new[] { "swagger: 2.0", "title: \"Todo API\"", "version: \"1.0.0\"", "host: mytodos.doesntexit", "basePath: v2", "schemes:", " - https", " - http" }); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); @@ -1441,14 +1441,15 @@ public void Single_path_with_get_collection() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -1486,14 +1487,15 @@ public void OData_doubles_as_one_of() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -1538,14 +1540,15 @@ public void OData_doubles_as_one_of_format_inside() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -1590,14 +1593,15 @@ public void OData_doubles_as_any_of() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -1662,13 +1666,16 @@ public void MultiNestedArraysSupportedAsUntypedNodes() { ["foos/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("bar.foo") @@ -1718,16 +1725,20 @@ public void Object_Arrays_are_supported() { ["users/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Object, Properties = new Dictionary { { @@ -1780,16 +1791,20 @@ public void TextPlainEndpointsAreSupported() { ["users/$count"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["text/plain"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Number, Format = "int32", } @@ -1862,7 +1877,7 @@ public void Supports_Path_Parameters() { ["/deviceManagement/microsoft.graph.getEffectivePermissions(scope='{scope}')"] = new OpenApiPathItem { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "scope", @@ -1872,19 +1887,24 @@ public void Supports_Path_Parameters() Type = JsonSchemaType.String } } - }, - Operations = { + ], + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Array, - Items = new OpenApiSchema { + Items = new OpenApiSchema + { AnyOf = new List { new OpenApiSchemaReference("microsoft.graph.rolePermission"), } @@ -1969,7 +1989,7 @@ public void Supports_Path_Query_And_Header_Parameters() { ["/deviceManagement/microsoft.graph.getEffectivePermissions(scope='{scope}')"] = new OpenApiPathItem { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "scope", @@ -2008,19 +2028,24 @@ public void Supports_Path_Query_And_Header_Parameters() Type = JsonSchemaType.String }, } - }, - Operations = { + ], + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Array, - Items = new OpenApiSchema { + Items = new OpenApiSchema + { AnyOf = new List { new OpenApiSchemaReference("microsoft.graph.rolePermission"), } @@ -2075,7 +2100,7 @@ public void DeduplicatesConflictingParameterNamesForCLI() { ["/test/{id}/results"] = new OpenApiPathItem { - Parameters = { + Parameters = [ new OpenApiParameter { Name = "id", @@ -2103,17 +2128,21 @@ public void DeduplicatesConflictingParameterNamesForCLI() Type = JsonSchemaType.String }, }, - }, - Operations = { + ], + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Object, Properties = new Dictionary() { { "foo", new OpenApiSchema() { @@ -2171,16 +2200,20 @@ public void Inline_Property_Inheritance_Is_Supported() { ["resource/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Object, Properties = new Dictionary { { @@ -2260,16 +2293,20 @@ public void Inline_Property_Inheritance_Is_Supported2() { ["resource/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + Schema = new OpenApiSchema + { AllOf = new List() { new OpenApiSchemaReference("resource"), @@ -2305,14 +2342,15 @@ public void MapsTime() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2347,14 +2385,15 @@ public void MapsDate() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2389,14 +2428,15 @@ public void MapsDuration() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2431,14 +2471,15 @@ public void AddsErrorMapping() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2458,7 +2499,7 @@ public void AddsErrorMapping() }, ["4XX"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2486,7 +2527,7 @@ public void AddsErrorMapping() }, ["5XX"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2514,7 +2555,7 @@ public void AddsErrorMapping() }, ["402"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2527,7 +2568,7 @@ public void AddsErrorMapping() }, ["401"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2601,14 +2642,15 @@ public void IgnoresErrorCodesWithNoSchema() var node = OpenApiUrlTreeNode.Create(); node.Attach("tasks", new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2628,21 +2670,21 @@ public void IgnoresErrorCodesWithNoSchema() }, ["4XX"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType() } }, ["5XX"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType() } }, ["401"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType() } @@ -2674,7 +2716,7 @@ public void DoesntAddSuffixesToErrorTypesWhenComponents() }; var errorResponse = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2688,14 +2730,15 @@ public void DoesntAddSuffixesToErrorTypesWhenComponents() { ["tasks"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2762,7 +2805,7 @@ public void UsesDefaultAs4XXAnd5XXWhenAbsent() }; var errorResponse = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2776,14 +2819,15 @@ public void UsesDefaultAs4XXAnd5XXWhenAbsent() { ["tasks"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2857,7 +2901,7 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels() }; var weatherForecastResponse = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2871,7 +2915,8 @@ public void DoesntAddPropertyHolderOnNonAdditionalModels() { ["weatherforecast"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses @@ -2924,7 +2969,7 @@ public void AddPropertyHolderOnAdditionalPropertiesSchema() }; var weatherForecastResponse = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -2938,7 +2983,8 @@ public void AddPropertyHolderOnAdditionalPropertiesSchema() { ["weatherforecast"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses @@ -2991,14 +3037,16 @@ public void SquishesLonelyNullables() { ["createUploadSession"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = new Dictionary { + Content = new Dictionary + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema @@ -3062,14 +3110,16 @@ public void SquishesLonelyNullablesBothAnyOf() { ["createUploadSession"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = new Dictionary { + Content = new Dictionary + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema @@ -3138,14 +3188,16 @@ public void SupportsArraysInComposedTypes() { ["createUploadSession"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = new Dictionary { + Content = new Dictionary + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("anyOfNullable") @@ -3207,14 +3259,16 @@ public void SupportsNullableAnyOf() { ["createUploadSession"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { - Content = new Dictionary { + Content = new Dictionary + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("anyOfNullable") @@ -3273,9 +3327,9 @@ public void AddsDiscriminatorMappings() Discriminator = new() { PropertyName = "@odata.type", - Mapping = new Dictionary { + Mapping = new Dictionary { { - "#microsoft.graph.directoryObject", "#/components/schemas/microsoft.graph.directoryObject" + "#microsoft.graph.directoryObject", new OpenApiSchemaReference("microsoft.graph.directoryObject") } } }, @@ -3301,7 +3355,7 @@ public void AddsDiscriminatorMappings() }; var directoryObjects = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -3315,7 +3369,8 @@ public void AddsDiscriminatorMappings() { ["objects"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses @@ -3378,12 +3433,12 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() Discriminator = new() { PropertyName = "@odata.type", - Mapping = new Dictionary { + Mapping = new Dictionary { { - "#microsoft.graph.directoryObject", "#/components/schemas/microsoft.graph.directoryObject" + "#microsoft.graph.directoryObject", new OpenApiSchemaReference("microsoft.graph.directoryObject") }, { - "#microsoft.graph.file", "#/components/schemas/microsoft.graph.file" + "#microsoft.graph.file", new OpenApiSchemaReference("microsoft.graph.file") } } }, @@ -3425,7 +3480,7 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() }; var directoryObjects = new OpenApiResponse() { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType() { @@ -3439,8 +3494,10 @@ public void DoesntAddDiscriminatorMappingsOfNonDerivedTypes() { ["objects"] = new OpenApiPathItem() { - Operations = { - [NetHttpMethod.Get] = new OpenApiOperation() { + Operations = new() + { + [NetHttpMethod.Get] = new OpenApiOperation() + { Responses = new OpenApiResponses { ["200"] = new OpenApiResponseReference("microsoft.graph.directoryObjects"), @@ -3523,7 +3580,7 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() }; var directoryObjects = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { @@ -3537,7 +3594,8 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() { ["objects"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses @@ -3575,6 +3633,25 @@ public async Task AddsDiscriminatorMappingsOneOfImplicitAsync() [Fact] public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() { + var document = new OpenApiDocument + { + Paths = new OpenApiPaths + { + ["objects"] = new OpenApiPathItem + { + Operations = new() + { + [NetHttpMethod.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponseReference("microsoft.graph.directoryObjects"), + } + } + } + } + }, + }; var entitySchema = new OpenApiSchema { Type = JsonSchemaType.Object, @@ -3603,7 +3680,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() { Type = JsonSchemaType.Object, AllOf = new List { - new OpenApiSchemaReference("microsoft.graph.entity"), + new OpenApiSchemaReference("microsoft.graph.entity", document), new OpenApiSchema { Properties = new Dictionary { { @@ -3627,7 +3704,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() { Type = JsonSchemaType.Object, AllOf = new List { - new OpenApiSchemaReference("microsoft.graph.directoryObject"), + new OpenApiSchemaReference("microsoft.graph.directoryObject", document), new OpenApiSchema { Properties = new Dictionary { { @@ -3649,32 +3726,15 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() }; var directoryObjects = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchemaReference("microsoft.graph.directoryObject") - } - }, - }; - var document = new OpenApiDocument - { - Paths = new OpenApiPaths - { - ["objects"] = new OpenApiPathItem - { - Operations = { - [NetHttpMethod.Get] = new OpenApiOperation - { - Responses = new OpenApiResponses - { - ["200"] = new OpenApiResponseReference("microsoft.graph.directoryObjects"), - } - } - } + Schema = new OpenApiSchemaReference("microsoft.graph.directoryObject", document) } }, }; + document.AddComponent("microsoft.graph.entity", entitySchema); document.AddComponent("microsoft.graph.directoryObject", directoryObjectSchema); document.AddComponent("microsoft.graph.user", userSchema); @@ -3716,6 +3776,25 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitAsync() [Fact] public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappingsWhileChildDoesNotAsync() { + var document = new OpenApiDocument + { + Paths = new OpenApiPaths + { + ["objects"] = new OpenApiPathItem + { + Operations = new() + { + [NetHttpMethod.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponseReference("microsoft.graph.directoryObjects"), + } + } + } + } + }, + }; var entitySchema = new OpenApiSchema { Type = JsonSchemaType.Object, @@ -3738,13 +3817,13 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings Discriminator = new() { PropertyName = "@odata.type", - Mapping = new Dictionary + Mapping = new Dictionary { { - "microsoft.graph.directoryObject", "#/components/schemas/microsoft.graph.directoryObject" + "microsoft.graph.directoryObject", new OpenApiSchemaReference("microsoft.graph.directoryObject", document) }, { - "microsoft.graph.user", "#/components/schemas/microsoft.graph.user" + "microsoft.graph.user", new OpenApiSchemaReference("microsoft.graph.user", document) } } }, @@ -3753,7 +3832,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings { Type = JsonSchemaType.Object, AllOf = [ - new OpenApiSchemaReference("microsoft.graph.entity"), + new OpenApiSchemaReference("microsoft.graph.entity", document), new OpenApiSchema { Properties = new Dictionary { @@ -3778,7 +3857,7 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings { Type = JsonSchemaType.Object, AllOf = [ - new OpenApiSchemaReference("microsoft.graph.directoryObject"), + new OpenApiSchemaReference("microsoft.graph.directoryObject", document), new OpenApiSchema { Properties = new Dictionary { @@ -3801,29 +3880,11 @@ public async Task AddsDiscriminatorMappingsAllOfImplicitWithParentHavingMappings }; var directoryObjects = new OpenApiResponse { - Content = + Content = new() { ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchemaReference("microsoft.graph.directoryObject") - } - }, - }; - var document = new OpenApiDocument - { - Paths = new OpenApiPaths - { - ["objects"] = new OpenApiPathItem - { - Operations = { - [NetHttpMethod.Get] = new OpenApiOperation - { - Responses = new OpenApiResponses - { - ["200"] = new OpenApiResponseReference("microsoft.graph.directoryObjects"), - } - } - } + Schema = new OpenApiSchemaReference("microsoft.graph.directoryObject", document) } }, }; @@ -3876,15 +3937,20 @@ public void UnionOfPrimitiveTypesWorks() { ["unionType"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { OneOf = new List { new OpenApiSchemaReference("subNS.simpleObject"), new OpenApiSchema { @@ -3923,7 +3989,7 @@ public void UnionOfPrimitiveTypesWorks() [Fact] public async Task AnyOfArrayWorksAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: AnyOf Array @@ -3982,15 +4048,20 @@ public void UnionOfInlineSchemasWorks() { ["unionType"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { OneOf = new List { new OpenApiSchemaReference("subNS.simpleObject"), new OpenApiSchema { @@ -4053,15 +4124,20 @@ public void IntersectionOfPrimitiveTypesWorks() { ["unionType"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { AnyOf = new List { new OpenApiSchemaReference("subNS.simpleObject"), new OpenApiSchema { @@ -4117,15 +4193,20 @@ public void IntersectionOfInlineSchemasWorks() { ["unionType"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { AnyOf = new List { new OpenApiSchemaReference("subNS.simpleObject"), new OpenApiSchema { @@ -4171,6 +4252,34 @@ public void IntersectionOfInlineSchemasWorks() [Fact] public void InheritedTypeWithInlineSchemaWorks() { + var document = new OpenApiDocument + { + Paths = new OpenApiPaths + { + ["derivedType"] = new OpenApiPathItem + { + Operations = new() + { + [NetHttpMethod.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchemaReference("subNS.derivedObject") + } + } + }, + } + } + } + } + }, + }; var baseObject = new OpenApiSchema { Type = JsonSchemaType.Object, @@ -4189,9 +4298,9 @@ public void InheritedTypeWithInlineSchemaWorks() Discriminator = new OpenApiDiscriminator { PropertyName = "kind", - Mapping = new Dictionary { + Mapping = new Dictionary { { - "derivedObject", "#/components/schemas/subNS.derivedObject" + "derivedObject", new OpenApiSchemaReference("subNS.derivedObject", document) } } }, @@ -4200,7 +4309,7 @@ public void InheritedTypeWithInlineSchemaWorks() { Type = JsonSchemaType.Object, AllOf = [ - new OpenApiSchemaReference("subNS.baseObject"), + new OpenApiSchemaReference("subNS.baseObject", document), new OpenApiSchema { Type = JsonSchemaType.Object, @@ -4214,9 +4323,9 @@ public void InheritedTypeWithInlineSchemaWorks() Discriminator = new OpenApiDiscriminator { PropertyName = "kind", - Mapping = new Dictionary { + Mapping = new Dictionary { { - "secondLevelDerivedObject", "#/components/schemas/subNS.secondLevelDerivedObject" + "secondLevelDerivedObject", new OpenApiSchemaReference("subNS.secondLevelDerivedObject", document) } } }, @@ -4227,7 +4336,7 @@ public void InheritedTypeWithInlineSchemaWorks() { Type = JsonSchemaType.Object, AllOf = [ - new OpenApiSchemaReference("subNS.derivedObject"), + new OpenApiSchemaReference("subNS.derivedObject", document), new OpenApiSchema { Type = JsonSchemaType.Object, @@ -4241,30 +4350,7 @@ public void InheritedTypeWithInlineSchemaWorks() } ], }; - var document = new OpenApiDocument - { - Paths = new OpenApiPaths - { - ["derivedType"] = new OpenApiPathItem - { - Operations = { - [NetHttpMethod.Get] = new OpenApiOperation - { - Responses = new OpenApiResponses - { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchemaReference("subNS.derivedObject") - } - } - }, - } - } - } - } - }, - }; + document.AddComponent("subNS.baseObject", baseObject); document.AddComponent("subNS.derivedObject", derivedObject); document.AddComponent("subNS.secondLevelDerivedObject", secondLevelDerivedObject); @@ -4279,8 +4365,7 @@ public void InheritedTypeWithInlineSchemaWorks() Assert.NotNull(requestBuilderClass); var requestExecutorMethod = requestBuilderClass.Methods.FirstOrDefault(x => x.IsOfKind(CodeMethodKind.RequestExecutor)); Assert.NotNull(requestExecutorMethod); - var executorReturnType = requestExecutorMethod.ReturnType as CodeType; - Assert.NotNull(executorReturnType); + Assert.IsType(requestExecutorMethod.ReturnType); Assert.Contains("derivedObject", requestExecutorMethod.ReturnType.Name); var derivedObjectClass = codeModel.FindChildByName("derivedObject"); Assert.NotNull(derivedObjectClass); @@ -4356,15 +4441,20 @@ public void MapsPrimitiveFormats(JsonSchemaType type, string format, string expe { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { Type = type, Format = format } @@ -4449,7 +4539,8 @@ public void MapsQueryParameterTypes(JsonSchemaType type, string format, string e { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -4568,11 +4659,16 @@ public void IncludesQueryParameterInUriTemplate() var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", ApiRootUrl = "https://localhost" }, _httpClient); var node = builder.CreateUriSpace(document); var codeModel = builder.CreateSourceModel(node); - var requestBuilder = codeModel.FindChildByName("ContractsRequestBuilder"); - Assert.NotNull(requestBuilder); - var property = requestBuilder.Properties.First(static x => x.Kind is CodePropertyKind.UrlTemplate); - Assert.NotNull(property); - Assert.Equal("\"{+baseurl}/api/contracts/{?type*}\"", property.DefaultValue); + var contractsRequestBuilder = codeModel.FindChildByName("ContractsRequestBuilder"); + Assert.NotNull(contractsRequestBuilder); + var contractsProperty = contractsRequestBuilder.Properties.First(static x => x.Kind is CodePropertyKind.UrlTemplate); + Assert.NotNull(contractsProperty); + Assert.Equal("\"{+baseurl}/api/contracts\"", contractsProperty.DefaultValue); + var emptyRequestBuilder = codeModel.FindChildByName("EmptyPathSegmentRequestBuilder"); + Assert.NotNull(emptyRequestBuilder); + var emptyProperty = emptyRequestBuilder.Properties.First(static x => x.Kind is CodePropertyKind.UrlTemplate); + Assert.NotNull(emptyProperty); + Assert.Equal("\"{+baseurl}/api/contracts/{?type*}\"", emptyProperty.DefaultValue); } [Fact] public void MapsArrayOfTypesAsUnionType() @@ -4583,15 +4679,20 @@ public void MapsArrayOfTypesAsUnionType() { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { Type = JsonSchemaType.Number | JsonSchemaType.String, } } @@ -4625,7 +4726,8 @@ public void MapsQueryParameterArrayTypes() { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -4673,7 +4775,8 @@ public void MapsEnumQueryParameterType(GenerationLanguage generationLanguage) { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -4726,7 +4829,7 @@ public void MapsEnumQueryParameterType(GenerationLanguage generationLanguage) [Theory] public async Task AddsQueryParameterTypesAsModelsAsync(bool ecb) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -4805,7 +4908,8 @@ public void MapsQueryParameterCollectionKinds(bool isArray) { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -4845,7 +4949,8 @@ public void DefaultsQueryParametersWithNoSchemaToString() { ["primitive"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -4894,14 +4999,18 @@ public void DoesntGenerateNamespacesWhenNotRequired() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -4945,14 +5054,18 @@ public void GeneratesNamesapacesWhenRequired() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("subns.myobject") } } @@ -4996,14 +5109,18 @@ public void IdsResultInIndexers() { ["answers/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5077,14 +5194,18 @@ public void HandlesCollectionOfEnumSchemasInAnyOfWithNullable() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5151,14 +5272,18 @@ public void HandlesCollectionOfEnumSchemas() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5211,14 +5336,18 @@ public void InlinePropertiesGenerateTypes() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5265,16 +5394,20 @@ public void ModelsDoesntUsePathDescriptionWhenAvailable() { Description = "some path item description", Summary = "some path item summary", - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Description = "some operation description", Summary = "some operation summary", Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5319,14 +5452,18 @@ public void CleansUpInvalidDescriptionCharacters() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5373,14 +5510,18 @@ public void AcceptVendorsTypes(string contentType) { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - [contentType] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + [contentType] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5418,17 +5559,22 @@ public void ModelsUseDescriptionWhenAvailable(bool excludeBackwardCompatible) { Description = "some path item description", Summary = "some path item summary", - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Description = "some operation description", Summary = "some operation summary", Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchema { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { Description = "some description", Properties = new Dictionary { { @@ -5512,21 +5658,28 @@ public void Considers200WithSchemaOver2XXWithSchema() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["2XX"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["2XX"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myotherobject") } } }, - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5580,14 +5733,18 @@ public void Considers2XXWithSchemaOver204WithNoSchema() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["2XX"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["2XX"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5630,7 +5787,8 @@ public void Considers204WithNoSchemaOver206WithNoSchema() { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses @@ -5689,14 +5847,18 @@ public void DoesntGenerateVoidExecutorOnMixedNoContent(int statusCode) { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5749,14 +5911,18 @@ public void GeneratesVoidReturnTypeForNoContent(int statusCode) { ["answer"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - [statusCode.ToString()] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + [statusCode.ToString()] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5804,21 +5970,25 @@ public void StripsCommonModelsPrefix(string[] componentNames, string stripPrefix }; document.Paths.Add($"answer{componentName}", new OpenApiPathItem { - Operations = { - [NetHttpMethod.Get] = new OpenApiOperation + Operations = new() + { + [NetHttpMethod.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses { - Responses = new OpenApiResponses + ["200"] = new OpenApiResponse { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { - Schema = new OpenApiSchemaReference(componentName) - } + Content = new() + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchemaReference(componentName) } - }, - } + } + }, } } + } }); document.AddComponent(componentName, myObjectSchema); } @@ -5847,7 +6017,8 @@ public void HandlesContentParameters() { ["answer(ids={ids}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -5871,9 +6042,12 @@ public void HandlesContentParameters() }, Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5922,7 +6096,8 @@ public void HandlesPagingExtension() { ["users"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Extensions = new Dictionary { @@ -5930,9 +6105,12 @@ public void HandlesPagingExtension() }, Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -5980,14 +6158,18 @@ public void SetsReadonlyProperties(bool isReadonly) { ["users"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6031,14 +6213,18 @@ public void SupportsIncludeFilterOnRootPath(string inputPattern, int expectedPat { ["/"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6084,14 +6270,18 @@ public void SupportsIncludeFilter() { ["users"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6102,14 +6292,18 @@ public void SupportsIncludeFilter() }, ["groups"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6157,14 +6351,18 @@ public void SupportsExcludeFilter() { ["users"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6175,14 +6373,18 @@ public void SupportsExcludeFilter() }, ["groups"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6230,14 +6432,18 @@ public void SupportsIncludeFilterWithOperation() { ["users/{id}/messages"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6246,18 +6452,24 @@ public void SupportsIncludeFilterWithOperation() }, [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6266,18 +6478,24 @@ public void SupportsIncludeFilterWithOperation() }, [NetHttpMethod.Put] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6288,14 +6506,18 @@ public void SupportsIncludeFilterWithOperation() }, ["groups"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6306,14 +6528,18 @@ public void SupportsIncludeFilterWithOperation() }, ["students"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6373,7 +6599,8 @@ public void SupportsIndexingParametersInSubPaths() { ["users({userId})/manager"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Parameters = new List { @@ -6388,9 +6615,12 @@ public void SupportsIndexingParametersInSubPaths() }, Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -6423,7 +6653,7 @@ public void SupportsIndexingParametersInSubPaths() [Fact] public async Task DisambiguatesOperationsConflictingWithPath1Async() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6473,7 +6703,7 @@ public async Task DisambiguatesOperationsConflictingWithPath1Async() [Fact] public async Task DisambiguatesOperationsConflictingWithPath2Async() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6523,7 +6753,7 @@ public async Task DisambiguatesOperationsConflictingWithPath2Async() [Fact] public async Task IndexerAndRequestBuilderNamesMatchAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6570,7 +6800,7 @@ public async Task IndexerAndRequestBuilderNamesMatchAsync() [Fact] public async Task IndexerTypeIsAccurateAndBackwardCompatibleIndexersAreAddedAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6704,7 +6934,7 @@ public async Task IndexerTypeIsAccurateAndBackwardCompatibleIndexersAreAddedAsyn [Fact] public async Task MapsBooleanEnumToBooleanTypeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6740,7 +6970,7 @@ public async Task MapsBooleanEnumToBooleanTypeAsync() [Fact] public async Task MapsNumberEnumToDoubleTypeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.0 info: title: Microsoft Graph get user API @@ -6777,7 +7007,7 @@ public async Task MapsNumberEnumToDoubleTypeAsync() [Theory] public async Task CleansInlineTypeNamesAsync(string raw, string expected) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -6837,7 +7067,7 @@ public void AddReservedPathParameterSymbol() { ["users/{id}/manager"] = new OpenApiPathItem { - Parameters = new List { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -6845,20 +7075,23 @@ public void AddReservedPathParameterSymbol() Schema = new OpenApiSchema { Type = JsonSchemaType.String }, - Extensions = { + Extensions = new (){ ["x-ms-reserved-parameter"] = new OpenApiReservedParameterExtension { IsReserved = true } } } - }, - Operations = { + ], + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("microsoft.graph.user") @@ -6908,7 +7141,7 @@ public void DoesNotAddReservedPathParameterSymbol() { ["users/{id}/manager"] = new OpenApiPathItem { - Parameters = new List { + Parameters = [ new OpenApiParameter { Name = "id", In = ParameterLocation.Path, @@ -6916,20 +7149,23 @@ public void DoesNotAddReservedPathParameterSymbol() Schema = new OpenApiSchema { Type = JsonSchemaType.String }, - Extensions = { + Extensions = new() { ["x-ms-reserved-parameter"] = new OpenApiReservedParameterExtension { IsReserved = false } } } - }, - Operations = { + ], + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { - Responses = new OpenApiResponses { + Responses = new OpenApiResponses + { ["200"] = new OpenApiResponse { - Content = { + Content = new() + { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchemaReference("microsoft.graph.user") @@ -6957,7 +7193,7 @@ public void DoesNotAddReservedPathParameterSymbol() [Fact] public async Task MergesIntersectionTypesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -7015,7 +7251,7 @@ public async Task MergesIntersectionTypesAsync() [Fact] public async Task SkipsInvalidItemsPropertiesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -7060,7 +7296,7 @@ public async Task SkipsInvalidItemsPropertiesAsync() [Fact] public async Task GetsCorrectInheritedInlineSchemaNameAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.3 servers: - url: https://api.github.com @@ -7115,7 +7351,7 @@ public async Task GetsCorrectInheritedInlineSchemaNameAsync() [Fact] public async Task DescriptionTakenFromAllOfAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -7187,7 +7423,7 @@ public async Task DescriptionTakenFromAllOfAsync() [Fact] public async Task CleanupSymbolNameDoesNotCauseNameConflictsAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7227,7 +7463,7 @@ public async Task CleanupSymbolNameDoesNotCauseNameConflictsAsync() [Fact] public async Task CleanupSymbolNameDoesNotCauseNameConflictsWithSuperTypeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7284,7 +7520,7 @@ public async Task CleanupSymbolNameDoesNotCauseNameConflictsWithSuperTypeAsync() [Fact] public async Task CleanupSymbolNameDoesNotCauseNameConflictsInQueryParametersAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7328,7 +7564,7 @@ public async Task CleanupSymbolNameDoesNotCauseNameConflictsInQueryParametersAsy [Fact] public async Task SupportsMultiPartFormAsRequestBodyWithDefaultMimeTypesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7404,7 +7640,7 @@ public async Task SupportsMultiPartFormAsRequestBodyWithDefaultMimeTypesAsync() [Fact] public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMimeTypesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7463,7 +7699,7 @@ public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMi [Fact] public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMimeTypesAsyncWithNonDefaultMimeTypesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7521,7 +7757,7 @@ public async Task SupportsMultiPartFormAsRequestBodyWithoutEncodingWithDefaultMi [Fact] public async Task SupportsMultipleContentTypesAsRequestBodyWithDefaultMimeTypesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7592,7 +7828,7 @@ public async Task SupportsMultipleContentTypesAsRequestBodyWithDefaultMimeTypesA [Fact] public async Task SupportsMultipleContentTypesAsRequestBodyWithMultipartPriorityNoEncodingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7663,7 +7899,7 @@ public async Task SupportsMultipleContentTypesAsRequestBodyWithMultipartPriority [Fact] public async Task SupportsMultipleContentTypesAsRequestBodyWithMultipartPriorityAndEncodingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Example @@ -7741,7 +7977,7 @@ public async Task SupportsMultipleContentTypesAsRequestBodyWithMultipartPriority [Fact] public async Task ComplexInheritanceStructuresAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: Broken inheritance @@ -7844,7 +8080,7 @@ public async Task ComplexInheritanceStructuresAsync() [Fact] public async Task InheritanceWithAllOfInBaseTypeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -7897,7 +8133,7 @@ public async Task InheritanceWithAllOfInBaseTypeAsync() [Fact] public async Task InlineSchemaWithSingleAllOfReferenceAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -7979,7 +8215,7 @@ public async Task InlineSchemaWithSingleAllOfReferenceAsync() [Fact] public async Task InheritanceWithAllOfWith3Parts3SchemaChildClassAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -8051,7 +8287,7 @@ public async Task InheritanceWithAllOfWith3Parts3SchemaChildClassAsync() [Fact] public async Task InheritanceWithAllOfBaseClassNoAdditionalPropertiesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -8124,7 +8360,7 @@ public async Task InheritanceWithAllOfBaseClassNoAdditionalPropertiesAsync() [Fact] public async Task ExclusiveUnionSingleEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8212,7 +8448,7 @@ public async Task ExclusiveUnionSingleEntriesMergingAsync() [Fact] public async Task ExclusiveUnionInheritanceEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8330,7 +8566,7 @@ public async Task ExclusiveUnionInheritanceEntriesMergingAsync() [Fact] public async Task ExclusiveUnionIntersectionEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8467,7 +8703,7 @@ public async Task ExclusiveUnionIntersectionEntriesMergingAsync() [Fact] public async Task InclusiveUnionSingleEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8555,7 +8791,7 @@ public async Task InclusiveUnionSingleEntriesMergingAsync() [Fact] public async Task InclusiveUnionInheritanceEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8673,7 +8909,7 @@ public async Task InclusiveUnionInheritanceEntriesMergingAsync() [Fact] public async Task InclusiveUnionIntersectionEntriesMergingAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync( """ openapi: 3.0.0 @@ -8810,8 +9046,10 @@ public async Task InclusiveUnionIntersectionEntriesMergingAsync() [Fact] public async Task NestedIntersectionTypeAllOfAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); - await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.3 + var tempFilePath = Path.GetTempFileName(); + await using var fs = await GetDocumentStreamAsync( +""" +openapi: 3.0.3 info: title: Model Registry REST API version: v1alpha2 @@ -8824,7 +9062,7 @@ public async Task NestedIntersectionTypeAllOfAsync() - url: 'http://localhost:8080' paths: /api/model_registry/v1alpha2/registered_models: - summary: Path used to manage the list of registeredmodels. + summary: Path used to manage the list of registered models. description: >- The REST endpoint/path used to list and create zero or more `RegisteredModel` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: @@ -8891,7 +9129,8 @@ a database instance and cannot be changed once set. application/json: schema: $ref: '#/components/schemas/RegisteredModelList' - description: A response containing a list of `RegisteredModel` entities.\"); + description: A response containing a list of `RegisteredModel` entities. +"""); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); var document = await builder.CreateOpenApiDocumentAsync(fs); @@ -8907,7 +9146,7 @@ a database instance and cannot be changed once set. [Fact] public async Task InheritanceWithAllOfWith3Parts3SchemaParentClassAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -8986,7 +9225,7 @@ public async Task InheritanceWithAllOfWith3Parts3SchemaParentClassAsync() [Fact] public async Task InheritanceWithAllOfWith2Parts1Schema1InlineNoDiscriminatorAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -9036,7 +9275,7 @@ public async Task InheritanceWithAllOfWith2Parts1Schema1InlineNoDiscriminatorAsy [Fact] public async Task InheritanceWithAllOfWith1Part1SchemaAndPropertiesNoDiscriminatorAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -9086,7 +9325,7 @@ public async Task InheritanceWithAllOfWith1Part1SchemaAndPropertiesNoDiscriminat [Theory] public async Task InheritanceWithAllOfWith3Parts1Schema2InlineAsync(bool reverseOrder) { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -9142,7 +9381,7 @@ public async Task InheritanceWithAllOfWith3Parts1Schema2InlineAsync(bool reverse [Fact] public async Task InheritanceWithoutObjectTypeHasAllPropertiesAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.3 servers: - url: 'https://example.com' @@ -9191,7 +9430,7 @@ public async Task InheritanceWithoutObjectTypeHasAllPropertiesAsync() [Fact] public async Task EnumsWithNullableDoesNotResultInInlineTypeAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -9254,7 +9493,7 @@ public async Task EnumsWithNullableDoesNotResultInInlineTypeAsync() [Fact] public async Task EnumsWithNullableDoesNotResultInInlineTypeInReveredOrderAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph @@ -9317,7 +9556,7 @@ public async Task EnumsWithNullableDoesNotResultInInlineTypeInReveredOrderAsync( [Fact] public async Task AnyTypeResponseAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: The Jira Cloud platform REST API @@ -9499,7 +9738,7 @@ public async Task EnumArrayQueryParameterAsync() $ref: '#/components/schemas/EnumValue' """; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await GetDocumentStreamAsync(schemaDocument); var builder = new KiotaBuilder( @@ -9551,14 +9790,18 @@ public void SupportsIncludeFilterAndExcludeWithOperation() { ["directory/administrativeUnits"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9567,18 +9810,24 @@ public void SupportsIncludeFilterAndExcludeWithOperation() }, [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["201"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["201"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9589,14 +9838,18 @@ public void SupportsIncludeFilterAndExcludeWithOperation() }, ["directory/administrativeUnits/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9605,9 +9858,12 @@ public void SupportsIncludeFilterAndExcludeWithOperation() }, [NetHttpMethod.Patch] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9684,14 +9940,18 @@ public void SupportsIncludeFilterAndExcludeWithOperationForSpecificPath() { ["directory/administrativeUnits"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9700,18 +9960,24 @@ public void SupportsIncludeFilterAndExcludeWithOperationForSpecificPath() }, [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["201"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["201"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9722,14 +9988,18 @@ public void SupportsIncludeFilterAndExcludeWithOperationForSpecificPath() }, ["directory/administrativeUnits/{id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9738,9 +10008,12 @@ public void SupportsIncludeFilterAndExcludeWithOperationForSpecificPath() }, [NetHttpMethod.Patch] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9817,14 +10090,18 @@ public void CleansUpOperationIdAddsMissingOperationId() { ["directory/administrativeUnits"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9833,18 +10110,24 @@ public void CleansUpOperationIdAddsMissingOperationId() }, [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["201"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["201"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9907,14 +10190,18 @@ public void CleansUpOperationIdChangesOperationId() { ["directory/administrativeUnits"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9924,18 +10211,24 @@ public void CleansUpOperationIdChangesOperationId() }, [NetHttpMethod.Post] = new OpenApiOperation { - RequestBody = new OpenApiRequestBody { - Content = { - ["application/json"] = new OpenApiMediaType { + RequestBody = new OpenApiRequestBody + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } }, Responses = new OpenApiResponses { - ["201"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["201"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } @@ -9947,14 +10240,18 @@ public void CleansUpOperationIdChangesOperationId() }, ["directory/adminstativeUnits/{unit-id}"] = new OpenApiPathItem { - Operations = { + Operations = new() + { [NetHttpMethod.Get] = new OpenApiOperation { Responses = new OpenApiResponses { - ["200"] = new OpenApiResponse { - Content = { - ["application/json"] = new OpenApiMediaType { + ["200"] = new OpenApiResponse + { + Content = new() + { + ["application/json"] = new OpenApiMediaType + { Schema = new OpenApiSchemaReference("myobject") } } diff --git a/tests/Kiota.Builder.Tests/PathSegmenters/HttpPathSegmenterTests.cs b/tests/Kiota.Builder.Tests/PathSegmenters/HttpPathSegmenterTests.cs index 915ec3c01a..165574c719 100644 --- a/tests/Kiota.Builder.Tests/PathSegmenters/HttpPathSegmenterTests.cs +++ b/tests/Kiota.Builder.Tests/PathSegmenters/HttpPathSegmenterTests.cs @@ -11,7 +11,7 @@ public class HttpPathSegmenterTests public HttpPathSegmenterTests() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); segmenter = new HttpPathSegmenter(tempFilePath, "client"); } diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 5294111414..0606f766ee 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -43,7 +43,9 @@ public void Dispose() [InlineData("My-Super complex() %@#$& Name", "MySupercomplexName")]//drop the space and special characters public async Task GeneratesManifestAsync(string inputPluginName, string expectedPluginName) { - var simpleDescriptionContent = @"openapi: 3.0.0 + var simpleDescriptionContent = +""" +openapi: 3.0.0 info: title: test version: 1.0 @@ -51,6 +53,13 @@ public async Task GeneratesManifestAsync(string inputPluginName, string expected servers: - url: http://localhost/ description: There's no place like home +tags: + - name: test + description: test description we've created + externalDocs: + description: external docs for test path + url: http://localhost/test + x-random-extension: true paths: /test: get: @@ -76,7 +85,8 @@ public async Task GeneratesManifestAsync(string inputPluginName, string expected format: int32 responses: '200': - description: test"; + description: test +"""; var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent); @@ -297,18 +307,18 @@ public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() Assert.Empty(resultResult.Diagnostic.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.Null(resultDocument.Components.Schemas);// no schema is referenced. so ensure they are all removed + Assert.Null(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[HttpMethod.Get].Responses.Count - 1, resultDocument.Paths["/test"].Operations[HttpMethod.Get].Responses.Count); // We removed the error response Assert.NotEmpty(resultDocument.Paths["/test"].Operations[HttpMethod.Get].Responses["200"].Description); // response description string is not empty Assert.Null(resultDocument.Paths["/test"].Operations[HttpMethod.Get].ExternalDocs); // external docs are removed - Assert.Empty(resultDocument.Paths["/test"].Operations[HttpMethod.Get].Extensions); // NO UNsupported extension + Assert.Null(resultDocument.Paths["/test"].Operations[HttpMethod.Get].Extensions); // NO UNsupported extension Assert.Equal(originalDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses.Count - 1, resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses.Count); // Responses are still intact. Assert.NotEmpty(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Description);// response description string is not empty Assert.Single(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Extensions); // 1 supported extension still present in operation - Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.AllOf); // allOf were merged - Assert.Empty(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].AnyOf); // anyOf we selected + Assert.Null(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.AllOf); // allOf were merged + Assert.Null(resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].AnyOf); // anyOf we selected Assert.Equal(JsonSchemaType.String, resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses["200"].Content["application/json"].Schema.Properties["id"].Type.Value); Assert.DoesNotContain("500", resultDocument.Paths["/test/{id}"].Operations[HttpMethod.Get].Responses.Keys, StringComparer.OrdinalIgnoreCase); // We removed the error response } diff --git a/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs index 8d60a649fa..1bb26811bb 100644 --- a/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs +++ b/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs @@ -12,6 +12,7 @@ using Xunit; namespace Kiota.Builder.Tests.Refiners; + public class GoLanguageRefinerTests { private readonly CodeNamespace root = CodeNamespace.InitRootNamespace(); @@ -447,7 +448,7 @@ public async Task SupportsTypeSpecificOverrideIndexersAsync() [Fact] public async Task ValidatesNamingOfRequestBuilderDoesNotRepeatIdCharacterAsync() { - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await using var fs = await KiotaBuilderTests.GetDocumentStreamAsync(@"openapi: 3.0.1 info: title: OData Service for namespace microsoft.graph diff --git a/tests/Kiota.Builder.Tests/Refiners/TypeScriptLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/TypeScriptLanguageRefinerTests.cs index c0581cc2f1..f8e8b0e28a 100644 --- a/tests/Kiota.Builder.Tests/Refiners/TypeScriptLanguageRefinerTests.cs +++ b/tests/Kiota.Builder.Tests/Refiners/TypeScriptLanguageRefinerTests.cs @@ -14,6 +14,7 @@ using Xunit; namespace Kiota.Builder.Tests.Refiners; + public sealed class TypeScriptLanguageRefinerTests : IDisposable { private readonly HttpClient _httpClient = new(); @@ -951,7 +952,7 @@ public async Task AddsUsingForUntypedNodeAsync() public async Task ParsesAndRefinesUnionOfPrimitiveValuesAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, UnionOfPrimitiveValuesSample.Yaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Primitives", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); diff --git a/tests/Kiota.Builder.Tests/Validation/OpenApiSchemaComparerTests.cs b/tests/Kiota.Builder.Tests/Validation/OpenApiSchemaComparerTests.cs index 943255bb91..52befa8e84 100644 --- a/tests/Kiota.Builder.Tests/Validation/OpenApiSchemaComparerTests.cs +++ b/tests/Kiota.Builder.Tests/Validation/OpenApiSchemaComparerTests.cs @@ -27,13 +27,15 @@ public void DoesNotStackOverFlowOnCircularReferencesForEquals() { var schema = new OpenApiSchema { - + AnyOf = [], + Properties = [], }; schema.Properties.Add("test", schema); schema.AnyOf.Add(schema); var schema2 = new OpenApiSchema { - + AnyOf = [], + Properties = [], }; schema2.Properties.Add("test", schema2); schema2.AnyOf.Add(schema2); diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs index f8bb5a19c4..f40428c05e 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs @@ -17,6 +17,7 @@ using static Kiota.Builder.Refiners.TypeScriptRefiner; namespace Kiota.Builder.Tests.Writers.TypeScript; + public sealed class CodeFunctionWriterTests : IDisposable { private const string DefaultPath = "./"; @@ -1205,7 +1206,7 @@ public async Task WritesConstructorWithEnumValueAsync() public async Task Writes_UnionOfPrimitiveValues_FactoryFunctionAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, UnionOfPrimitiveValuesSample.Yaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Primitives", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1252,7 +1253,7 @@ export function createPrimitivesFromDiscriminatorValue(parseNode: ParseNode | un public async Task Writes_UnionOfObjects_FactoryMethodAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, PetsUnion.OpenApiYaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Pets", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1293,7 +1294,7 @@ public async Task Writes_UnionOfObjects_FactoryMethodAsync() public async Task Writes_UnionOfPrimitiveValues_SerializerFunctionAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, UnionOfPrimitiveValuesSample.Yaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Primitives", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1332,7 +1333,7 @@ public async Task Writes_UnionOfPrimitiveValues_SerializerFunctionAsync() public async Task Writes_UnionOfObjects_SerializerFunctionsAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, PetsUnion.OpenApiYaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Pets", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1373,7 +1374,7 @@ public async Task Writes_UnionOfObjects_SerializerFunctionsAsync() public async Task Writes_CodeIntersectionType_FactoryMethodAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, CodeIntersectionTypeSampleYml.OpenApiYaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "FooBar", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1411,7 +1412,7 @@ public async Task Writes_CodeIntersectionType_FactoryMethodAsync() public async Task Writes_CodeIntersectionType_DeserializerFunctionsAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, CodeIntersectionTypeSampleYml.OpenApiYaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "FooBar", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); @@ -1449,7 +1450,7 @@ public async Task Writes_CodeIntersectionType_DeserializerFunctionsAsync() public async Task Writes_CodeIntersectionType_SerializerFunctionsAsync() { var generationConfiguration = new GenerationConfiguration { Language = GenerationLanguage.TypeScript }; - var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + var tempFilePath = Path.GetTempFileName(); await File.WriteAllTextAsync(tempFilePath, CodeIntersectionTypeSampleYml.OpenApiYaml); var mockLogger = new Mock>(); var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "FooBar", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); diff --git a/vscode/npm-package/tests/integration/integrationGeneratePlugin.spec.ts b/vscode/npm-package/tests/integration/integrationGeneratePlugin.spec.ts index fb4c3ffb66..80c0ec5a0f 100644 --- a/vscode/npm-package/tests/integration/integrationGeneratePlugin.spec.ts +++ b/vscode/npm-package/tests/integration/integrationGeneratePlugin.spec.ts @@ -288,7 +288,7 @@ describe("GeneratePlugin", () => { } const actualSecurityScheme = actualSecuritySchemes['oAuth2AuthCode']; expect(actualSecurityScheme).toBeDefined(); - expect(actualSecurityScheme.referenceId).toEqual(''); + expect(actualSecurityScheme.referenceId).toBeUndefined(); });