mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-09-15 22:31:49 +02:00
Upgrade dependency RamlToOpenApiConverter to version 0.40.0 (#1505)
* Upgrade dependency RamlToOpenApiConverter to version 0.40.0 * fix code comment * . * Potential fix for pull request finding 'Constant condition' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * Potential fix for pull request finding 'Constant condition' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * fix --------- Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
parent
84f4109a7c
commit
f0969e9618
+1
-1
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />
|
||||
<!--<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />-->
|
||||
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace System.Collections.Generic;
|
||||
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
#if NETSTANDARD2_0
|
||||
public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue>? dictionary, TKey key, TValue value)
|
||||
{
|
||||
if (dictionary is null || dictionary.ContainsKey(key))
|
||||
@@ -16,5 +19,29 @@ internal static class DictionaryExtensions
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public static bool TryGetFirstValue<TKey, TValue>(this IDictionary<TKey, TValue>? dictionary, out TValue? value)
|
||||
{
|
||||
if (dictionary != null && dictionary.Count > 0)
|
||||
{
|
||||
value = dictionary.First().Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetFirstOrDefault<TKey, TValue>(this IDictionary<TKey, TValue>? dictionary, out KeyValuePair<TKey, TValue> value)
|
||||
{
|
||||
if (dictionary != null && dictionary.Count > 0)
|
||||
{
|
||||
value = dictionary.First();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
@@ -56,37 +54,25 @@ internal static class OpenApiSchemaExtensions
|
||||
|
||||
public static SchemaFormat GetSchemaFormat(this IOpenApiSchema? schema)
|
||||
{
|
||||
switch (schema?.Format)
|
||||
return (schema?.Format) switch
|
||||
{
|
||||
case "float":
|
||||
return SchemaFormat.Float;
|
||||
"float" => SchemaFormat.Float,
|
||||
"double" => SchemaFormat.Double,
|
||||
"int32" => SchemaFormat.Int32,
|
||||
"int64" => SchemaFormat.Int64,
|
||||
"date" => SchemaFormat.Date,
|
||||
"date-time" => SchemaFormat.DateTime,
|
||||
"password" => SchemaFormat.Password,
|
||||
"byte" => SchemaFormat.Byte,
|
||||
"binary" => SchemaFormat.Binary,
|
||||
_ => SchemaFormat.Undefined,
|
||||
};
|
||||
}
|
||||
|
||||
case "double":
|
||||
return SchemaFormat.Double;
|
||||
|
||||
case "int32":
|
||||
return SchemaFormat.Int32;
|
||||
|
||||
case "int64":
|
||||
return SchemaFormat.Int64;
|
||||
|
||||
case "date":
|
||||
return SchemaFormat.Date;
|
||||
|
||||
case "date-time":
|
||||
return SchemaFormat.DateTime;
|
||||
|
||||
case "password":
|
||||
return SchemaFormat.Password;
|
||||
|
||||
case "byte":
|
||||
return SchemaFormat.Byte;
|
||||
|
||||
case "binary":
|
||||
return SchemaFormat.Binary;
|
||||
|
||||
default:
|
||||
return SchemaFormat.Undefined;
|
||||
}
|
||||
internal static JsonNode? FindFirstExample(this IOpenApiSchema? schema)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return schema?.Examples?.FirstOrDefault() ?? schema?.Example;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Reader;
|
||||
using Stef.Validation;
|
||||
using WireMock.Net.OpenApiParser.Models;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using WireMock.Server;
|
||||
|
||||
@@ -16,7 +14,8 @@ namespace WireMock.Net.OpenApiParser.Extensions;
|
||||
public static class WireMockServerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 file.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 file.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
@@ -28,7 +27,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 file.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 file.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
@@ -46,7 +46,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 stream.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 stream.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
@@ -58,7 +59,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 stream.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 stream.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
@@ -77,7 +79,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 document.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 document.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="document">The OpenAPI document to use as mappings.</param>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<!-- See also https://github.com/ravibpatel/ILRepack.Lib.MSBuild.Task/issues/26 -->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="ILRepacker" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
|
||||
<ItemGroup>
|
||||
<InputAssemblies Include="$(OutputPath)WireMock.Net.OpenApiParser.dll" />
|
||||
<InputAssemblies Include="@(ReferencePathWithRefAssemblies)" Condition="'%(filename)' == 'Microsoft.OpenApi.YamlReader'" />
|
||||
<InputAssemblies Include="@(ReferencePathWithRefAssemblies)" Condition="'%(filename)' == 'Microsoft.OpenApi'" />
|
||||
<LibraryPath Include="%(ReferencePathWithRefAssemblies.RelativeDir)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DoNotInternalizeAssemblies Include="WireMock.Net.OpenApiParser" />
|
||||
</ItemGroup>
|
||||
|
||||
<ILRepack
|
||||
Parallel="true"
|
||||
Internalize="true"
|
||||
RenameInternalized="true"
|
||||
InternalizeExclude="@(DoNotInternalizeAssemblies)"
|
||||
InputAssemblies="@(InputAssemblies)"
|
||||
LibraryPath="@(LibraryPath)"
|
||||
TargetKind="Dll"
|
||||
KeyFile="../../src/WireMock.Net/WireMock.Net.snk"
|
||||
OutputFile="$(OutputPath)$(AssemblyName).dll"
|
||||
/>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.OpenApi.Reader;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Models;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser;
|
||||
@@ -15,6 +13,7 @@ public interface IWireMockOpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -23,6 +22,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
@@ -40,6 +40,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -48,6 +49,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
@@ -57,6 +59,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="text">The source text</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -65,6 +68,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="text">The source text</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
|
||||
@@ -53,7 +53,7 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
Headers = MapRequestHeaders(requestHeaders),
|
||||
Body = GetRequestBodyModel(operation.RequestBody)
|
||||
},
|
||||
Response = GetResponseModel(operation.Responses?.FirstOrDefault())
|
||||
Response = operation.Responses?.TryGetFirstOrDefault(out var firstResponse) == true ? GetResponseModel(firstResponse) : new ResponseModel { StatusCode = 200 }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,8 +70,7 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
|
||||
var requestExample = requestContent?.Example;
|
||||
var requestExamples = requestContent?.Examples;
|
||||
var requestSchemaExample = requestContent?.Schema?.Example;
|
||||
var requestSchemaExamples = requestContent?.Schema?.Examples;
|
||||
var requestSchemaExample = requestContent?.Schema.FindFirstExample();
|
||||
|
||||
JsonNode? request;
|
||||
if (requestExample != null)
|
||||
@@ -86,10 +85,6 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
request = requestExamples.FirstOrDefault().Value.Value;
|
||||
}
|
||||
else if (requestSchemaExamples != null)
|
||||
{
|
||||
request = requestSchemaExamples.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestSchema = content?.FirstOrDefault().Value.Schema;
|
||||
@@ -99,16 +94,15 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
return MapRequestBody(request) ?? new BodyModel();
|
||||
}
|
||||
|
||||
private ResponseModel GetResponseModel(KeyValuePair<string, IOpenApiResponse>? openApiResponse)
|
||||
private ResponseModel GetResponseModel(KeyValuePair<string, IOpenApiResponse> openApiResponse)
|
||||
{
|
||||
var content = openApiResponse?.Value.Content;
|
||||
var content = openApiResponse.Value.Content;
|
||||
|
||||
TryGetContent(content, out var responseContent, out var contentType);
|
||||
|
||||
var responseExample = responseContent?.Example;
|
||||
var responseExamples = responseContent?.Examples;
|
||||
var responseSchemaExample = responseContent?.Schema?.Example;
|
||||
var responseSchemaExamples = responseContent?.Schema?.Examples;
|
||||
var responseSchemaExample = responseContent?.Schema.FindFirstExample();
|
||||
|
||||
JsonNode? response;
|
||||
if (responseExample != null)
|
||||
@@ -119,24 +113,19 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
response = responseSchemaExample;
|
||||
}
|
||||
else if (responseExamples != null)
|
||||
else if (responseExamples.TryGetFirstValue(out var firstResponseFromExamples))
|
||||
{
|
||||
response = responseExamples.FirstOrDefault().Value.Value;
|
||||
}
|
||||
else if (responseSchemaExamples != null)
|
||||
{
|
||||
response = responseSchemaExamples.FirstOrDefault();
|
||||
response = firstResponseFromExamples?.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var responseSchema = content?.FirstOrDefault().Value?.Schema;
|
||||
response = MapSchemaToObject(responseSchema);
|
||||
response = content.TryGetFirstValue(out var firstContent) ? MapSchemaToObject(firstContent?.Schema) : null;
|
||||
}
|
||||
|
||||
return new ResponseModel
|
||||
{
|
||||
StatusCode = int.TryParse(openApiResponse?.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
||||
Headers = MapHeaders(contentType, openApiResponse?.Value.Headers),
|
||||
StatusCode = int.TryParse(openApiResponse.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
||||
Headers = MapHeaders(contentType, openApiResponse.Value.Headers),
|
||||
BodyAsJson = response != null ? JsonConvert.DeserializeObject(SystemTextJsonSerializer.Serialize(response)) : null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using RamlToOpenApiConverter;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Object containing all diagnostic information related to Open API parsing.
|
||||
/// </summary>
|
||||
public class OpenApiDiagnostic
|
||||
{
|
||||
/// <summary>
|
||||
/// List of all errors.
|
||||
/// </summary>
|
||||
public List<OpenApiError> Errors { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// List of all warnings
|
||||
/// </summary>
|
||||
public List<OpenApiError> Warnings { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Open API specification version of the document parsed.
|
||||
/// </summary>
|
||||
public OpenApiSpecificationVersion SpecificationVersion { get; set; }
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Error related to the Open API Document.
|
||||
/// </summary>
|
||||
public class OpenApiError
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="OpenApiError"/> class.
|
||||
/// </summary>
|
||||
public OpenApiError(string? pointer, string message)
|
||||
{
|
||||
Pointer = pointer;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a copy of an <see cref="OpenApiError"/> object
|
||||
/// </summary>
|
||||
public OpenApiError(OpenApiError error)
|
||||
{
|
||||
Pointer = error.Pointer;
|
||||
Message = error.Message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message explaining the error.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pointer to the location of the error.
|
||||
/// </summary>
|
||||
public string? Pointer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representation of <see cref="OpenApiError"/>.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Message + (!string.IsNullOrEmpty(Pointer) ? " [" + Pointer + "]" : "");
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Linq;
|
||||
using RamlToOpenApiConverter;
|
||||
using MicrosoftOpenApiDiagnostic = Microsoft.OpenApi.Reader.OpenApiDiagnostic;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
|
||||
internal static class OpenApiMapper
|
||||
{
|
||||
internal static OpenApiDiagnostic? Map(MicrosoftOpenApiDiagnostic? openApiDiagnostic)
|
||||
{
|
||||
if (openApiDiagnostic == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new OpenApiDiagnostic
|
||||
{
|
||||
Errors = openApiDiagnostic.Errors.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||
Warnings = openApiDiagnostic.Warnings.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||
SpecificationVersion = (OpenApiSpecificationVersion)openApiDiagnostic.SpecificationVersion
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ internal class ExampleValueGenerator
|
||||
|
||||
public JsonNode GetExampleValue(IOpenApiSchema? schema)
|
||||
{
|
||||
var schemaExample = schema?.Example;
|
||||
var schemaExample = schema?.FindFirstExample();
|
||||
var schemaEnum = schema?.Enum?.FirstOrDefault();
|
||||
|
||||
_exampleValues.Schema = schema;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>An OpenApi (swagger) parser to generate MappingModel or mapping.json file.</Description>
|
||||
@@ -40,23 +40,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.21.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="18.1.0" />
|
||||
<PackageReference Include="RamlToOpenApiConverter" Version="0.40.0" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.43" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="3.7.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" PrivateAssets="All" />
|
||||
<PackageReference Include="SharpYaml" Version="2.1.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi;
|
||||
@@ -11,14 +9,12 @@ using Microsoft.OpenApi.YamlReader;
|
||||
using RamlToOpenApiConverter;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Mappers;
|
||||
using WireMock.Net.OpenApiParser.Models;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using OpenApiDiagnostic = WireMock.Net.OpenApiParser.Models.OpenApiDiagnostic;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser;
|
||||
|
||||
/// <summary>
|
||||
/// Parse a OpenApi/Swagger/V2/V3/V3.1 to WireMock.Net MappingModels.
|
||||
/// Parse a OpenApi/Swagger/V2/V3/V3.1/V3.2 to WireMock.Net MappingModels.
|
||||
/// </summary>
|
||||
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
{
|
||||
@@ -32,8 +28,15 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
_readerSettings = new OpenApiReaderSettings();
|
||||
_readerSettings.AddMicrosoftExtensionParsers();
|
||||
_readerSettings.AddJsonReader();
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yaml, new OpenApiYamlReader());
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yml, new OpenApiYamlReader());
|
||||
|
||||
var openApiYamlReaderSettings = new OpenApiYamlReaderSettings
|
||||
{
|
||||
MaxAliasExpansionNodeCount = 1_000_000
|
||||
};
|
||||
var openApiYamlReader = new OpenApiYamlReader(openApiYamlReaderSettings);
|
||||
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yaml, openApiYamlReader);
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yml, openApiYamlReader);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -55,7 +58,12 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
}
|
||||
else
|
||||
{
|
||||
document = Read(File.OpenRead(path), out diagnostic);
|
||||
if (!TryRead(File.OpenRead(path), out var documentFromYaml, out diagnostic))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
document = documentFromYaml;
|
||||
}
|
||||
|
||||
return FromDocument(document, settings);
|
||||
@@ -74,14 +82,24 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromDocument(Read(stream, out diagnostic));
|
||||
if (TryRead(stream, out var openApiDocument, out diagnostic))
|
||||
{
|
||||
return FromDocument(openApiDocument);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromDocument(Read(stream, out diagnostic), settings);
|
||||
if (TryRead(stream, out var openApiDocument, out diagnostic))
|
||||
{
|
||||
return FromDocument(openApiDocument, settings);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -98,7 +116,7 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
return FromStream(new MemoryStream(Encoding.UTF8.GetBytes(text)), settings, out diagnostic);
|
||||
}
|
||||
|
||||
private OpenApiDocument Read(Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
private bool TryRead(Stream stream, [NotNullWhen(true)] out OpenApiDocument? openApiDocument, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
if (stream is not MemoryStream memoryStream)
|
||||
{
|
||||
@@ -107,8 +125,9 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
|
||||
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
||||
|
||||
diagnostic = OpenApiMapper.Map(result.Diagnostic) ?? new OpenApiDiagnostic();
|
||||
return result.Document ?? throw new InvalidOperationException("The document is null.");
|
||||
diagnostic = result.Diagnostic ?? new OpenApiDiagnostic();
|
||||
openApiDocument = result.Document;
|
||||
return openApiDocument != null && !diagnostic.Errors.Any();
|
||||
}
|
||||
|
||||
private static MemoryStream ReadStreamIntoMemoryStream(Stream stream)
|
||||
|
||||
@@ -36,12 +36,38 @@ public class WireMockOpenApiParserTests
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "payroc-openapi-spec.yaml"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out _);
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().NotBeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().BeEmpty();
|
||||
|
||||
// Verify
|
||||
await Verify(mappings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromText_UsingInvalidYaml_ShouldReturnEmptyMappingsWithDiagnostic()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new WireMockOpenApiParserSettings
|
||||
{
|
||||
ExampleValues = _exampleValuesMock.Object
|
||||
};
|
||||
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "invalid.yaml"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().BeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().HaveCount(1);
|
||||
diagnostic.Errors[0].Message.Should().Be("Responses must contain at least one response");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FromText_UsingJson_WithPlainTextExample_ShouldReturnMappings()
|
||||
{
|
||||
@@ -54,7 +80,12 @@ public class WireMockOpenApiParserTests
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "oas-content-example.json"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out _);
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().NotBeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().BeEmpty();
|
||||
|
||||
// Verify
|
||||
await Verify(mappings);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
openapi: 3.2.0
|
||||
info:
|
||||
version: '1'
|
||||
title: Invalid API
|
||||
description: Invalid
|
||||
|
||||
paths:
|
||||
/funding-recipients:
|
||||
summary: Create and manage funding recipients.
|
||||
post:
|
||||
tags:
|
||||
- Funding recipients
|
||||
Reference in New Issue
Block a user