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>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
#if NETSTANDARD2_0
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace System.Collections.Generic;
|
namespace System.Collections.Generic;
|
||||||
|
|
||||||
internal static class DictionaryExtensions
|
internal static class DictionaryExtensions
|
||||||
{
|
{
|
||||||
|
#if NETSTANDARD2_0
|
||||||
public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue>? dictionary, TKey key, TValue value)
|
public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue>? dictionary, TKey key, TValue value)
|
||||||
{
|
{
|
||||||
if (dictionary is null || dictionary.ContainsKey(key))
|
if (dictionary is null || dictionary.ContainsKey(key))
|
||||||
@@ -16,5 +19,29 @@ internal static class DictionaryExtensions
|
|||||||
|
|
||||||
return true;
|
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
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
@@ -56,37 +54,25 @@ internal static class OpenApiSchemaExtensions
|
|||||||
|
|
||||||
public static SchemaFormat GetSchemaFormat(this IOpenApiSchema? schema)
|
public static SchemaFormat GetSchemaFormat(this IOpenApiSchema? schema)
|
||||||
{
|
{
|
||||||
switch (schema?.Format)
|
return (schema?.Format) switch
|
||||||
{
|
{
|
||||||
case "float":
|
"float" => SchemaFormat.Float,
|
||||||
return 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":
|
internal static JsonNode? FindFirstExample(this IOpenApiSchema? schema)
|
||||||
return SchemaFormat.Double;
|
{
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
case "int32":
|
return schema?.Examples?.FirstOrDefault() ?? schema?.Example;
|
||||||
return SchemaFormat.Int32;
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Microsoft.OpenApi.Reader;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Net.OpenApiParser.Models;
|
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
|
|
||||||
@@ -16,7 +14,8 @@ namespace WireMock.Net.OpenApiParser.Extensions;
|
|||||||
public static class WireMockServerExtensions
|
public static class WireMockServerExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <param name="server">The WireMockServer instance</param>
|
/// <param name="server">The WireMockServer instance</param>
|
||||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||||
@@ -28,7 +27,8 @@ public static class WireMockServerExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <param name="server">The WireMockServer instance</param>
|
/// <param name="server">The WireMockServer instance</param>
|
||||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||||
@@ -46,7 +46,8 @@ public static class WireMockServerExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <param name="server">The WireMockServer instance</param>
|
/// <param name="server">The WireMockServer instance</param>
|
||||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||||
@@ -58,7 +59,8 @@ public static class WireMockServerExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <param name="server">The WireMockServer instance</param>
|
/// <param name="server">The WireMockServer instance</param>
|
||||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||||
@@ -77,7 +79,8 @@ public static class WireMockServerExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
/// <param name="server">The WireMockServer instance</param>
|
/// <param name="server">The WireMockServer instance</param>
|
||||||
/// <param name="document">The OpenAPI document to use as mappings.</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
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using Microsoft.OpenApi.Reader;
|
||||||
using System.IO;
|
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Net.OpenApiParser.Models;
|
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser;
|
namespace WireMock.Net.OpenApiParser;
|
||||||
@@ -15,6 +13,7 @@ public interface IWireMockOpenApiParser
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||||
@@ -23,6 +22,7 @@ public interface IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||||
/// <param name="settings">Additional settings</param>
|
/// <param name="settings">Additional settings</param>
|
||||||
@@ -40,6 +40,7 @@ public interface IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="stream">The source stream</param>
|
/// <param name="stream">The source stream</param>
|
||||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||||
@@ -48,6 +49,7 @@ public interface IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="stream">The source stream</param>
|
/// <param name="stream">The source stream</param>
|
||||||
/// <param name="settings">Additional settings</param>
|
/// <param name="settings">Additional settings</param>
|
||||||
@@ -57,6 +59,7 @@ public interface IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="text">The source text</param>
|
/// <param name="text">The source text</param>
|
||||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||||
@@ -65,6 +68,7 @@ public interface IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="text">The source text</param>
|
/// <param name="text">The source text</param>
|
||||||
/// <param name="settings">Additional settings</param>
|
/// <param name="settings">Additional settings</param>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
|||||||
Headers = MapRequestHeaders(requestHeaders),
|
Headers = MapRequestHeaders(requestHeaders),
|
||||||
Body = GetRequestBodyModel(operation.RequestBody)
|
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 requestExample = requestContent?.Example;
|
||||||
var requestExamples = requestContent?.Examples;
|
var requestExamples = requestContent?.Examples;
|
||||||
var requestSchemaExample = requestContent?.Schema?.Example;
|
var requestSchemaExample = requestContent?.Schema.FindFirstExample();
|
||||||
var requestSchemaExamples = requestContent?.Schema?.Examples;
|
|
||||||
|
|
||||||
JsonNode? request;
|
JsonNode? request;
|
||||||
if (requestExample != null)
|
if (requestExample != null)
|
||||||
@@ -86,10 +85,6 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
|||||||
{
|
{
|
||||||
request = requestExamples.FirstOrDefault().Value.Value;
|
request = requestExamples.FirstOrDefault().Value.Value;
|
||||||
}
|
}
|
||||||
else if (requestSchemaExamples != null)
|
|
||||||
{
|
|
||||||
request = requestSchemaExamples.FirstOrDefault();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var requestSchema = content?.FirstOrDefault().Value.Schema;
|
var requestSchema = content?.FirstOrDefault().Value.Schema;
|
||||||
@@ -99,16 +94,15 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
|||||||
return MapRequestBody(request) ?? new BodyModel();
|
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);
|
TryGetContent(content, out var responseContent, out var contentType);
|
||||||
|
|
||||||
var responseExample = responseContent?.Example;
|
var responseExample = responseContent?.Example;
|
||||||
var responseExamples = responseContent?.Examples;
|
var responseExamples = responseContent?.Examples;
|
||||||
var responseSchemaExample = responseContent?.Schema?.Example;
|
var responseSchemaExample = responseContent?.Schema.FindFirstExample();
|
||||||
var responseSchemaExamples = responseContent?.Schema?.Examples;
|
|
||||||
|
|
||||||
JsonNode? response;
|
JsonNode? response;
|
||||||
if (responseExample != null)
|
if (responseExample != null)
|
||||||
@@ -119,24 +113,19 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
|||||||
{
|
{
|
||||||
response = responseSchemaExample;
|
response = responseSchemaExample;
|
||||||
}
|
}
|
||||||
else if (responseExamples != null)
|
else if (responseExamples.TryGetFirstValue(out var firstResponseFromExamples))
|
||||||
{
|
{
|
||||||
response = responseExamples.FirstOrDefault().Value.Value;
|
response = firstResponseFromExamples?.Value;
|
||||||
}
|
|
||||||
else if (responseSchemaExamples != null)
|
|
||||||
{
|
|
||||||
response = responseSchemaExamples.FirstOrDefault();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var responseSchema = content?.FirstOrDefault().Value?.Schema;
|
response = content.TryGetFirstValue(out var firstContent) ? MapSchemaToObject(firstContent?.Schema) : null;
|
||||||
response = MapSchemaToObject(responseSchema);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResponseModel
|
return new ResponseModel
|
||||||
{
|
{
|
||||||
StatusCode = int.TryParse(openApiResponse?.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
StatusCode = int.TryParse(openApiResponse.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
||||||
Headers = MapHeaders(contentType, openApiResponse?.Value.Headers),
|
Headers = MapHeaders(contentType, openApiResponse.Value.Headers),
|
||||||
BodyAsJson = response != null ? JsonConvert.DeserializeObject(SystemTextJsonSerializer.Serialize(response)) : null
|
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)
|
public JsonNode GetExampleValue(IOpenApiSchema? schema)
|
||||||
{
|
{
|
||||||
var schemaExample = schema?.Example;
|
var schemaExample = schema?.FindFirstExample();
|
||||||
var schemaEnum = schema?.Enum?.FirstOrDefault();
|
var schemaEnum = schema?.Enum?.FirstOrDefault();
|
||||||
|
|
||||||
_exampleValues.Schema = schema;
|
_exampleValues.Schema = schema;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>An OpenApi (swagger) parser to generate MappingModel or mapping.json file.</Description>
|
<Description>An OpenApi (swagger) parser to generate MappingModel or mapping.json file.</Description>
|
||||||
@@ -40,23 +40,11 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.21.0" />
|
<PackageReference Include="RamlToOpenApiConverter" Version="0.40.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="18.1.0" />
|
|
||||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
||||||
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
||||||
</ItemGroup>
|
</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>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
@@ -11,14 +9,12 @@ using Microsoft.OpenApi.YamlReader;
|
|||||||
using RamlToOpenApiConverter;
|
using RamlToOpenApiConverter;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Net.OpenApiParser.Mappers;
|
using WireMock.Net.OpenApiParser.Mappers;
|
||||||
using WireMock.Net.OpenApiParser.Models;
|
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
using OpenApiDiagnostic = WireMock.Net.OpenApiParser.Models.OpenApiDiagnostic;
|
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser;
|
namespace WireMock.Net.OpenApiParser;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||||
{
|
{
|
||||||
@@ -32,8 +28,15 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
_readerSettings = new OpenApiReaderSettings();
|
_readerSettings = new OpenApiReaderSettings();
|
||||||
_readerSettings.AddMicrosoftExtensionParsers();
|
_readerSettings.AddMicrosoftExtensionParsers();
|
||||||
_readerSettings.AddJsonReader();
|
_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 />
|
/// <inheritdoc />
|
||||||
@@ -55,7 +58,12 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
}
|
}
|
||||||
else
|
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);
|
return FromDocument(document, settings);
|
||||||
@@ -74,14 +82,24 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic)
|
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 />
|
/// <inheritdoc />
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
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 />
|
/// <inheritdoc />
|
||||||
@@ -98,7 +116,7 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
return FromStream(new MemoryStream(Encoding.UTF8.GetBytes(text)), settings, out diagnostic);
|
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)
|
if (stream is not MemoryStream memoryStream)
|
||||||
{
|
{
|
||||||
@@ -107,8 +125,9 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
|
|
||||||
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
||||||
|
|
||||||
diagnostic = OpenApiMapper.Map(result.Diagnostic) ?? new OpenApiDiagnostic();
|
diagnostic = result.Diagnostic ?? new OpenApiDiagnostic();
|
||||||
return result.Document ?? throw new InvalidOperationException("The document is null.");
|
openApiDocument = result.Document;
|
||||||
|
return openApiDocument != null && !diagnostic.Errors.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MemoryStream ReadStreamIntoMemoryStream(Stream stream)
|
private static MemoryStream ReadStreamIntoMemoryStream(Stream stream)
|
||||||
|
|||||||
@@ -36,12 +36,38 @@ public class WireMockOpenApiParserTests
|
|||||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "payroc-openapi-spec.yaml"));
|
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "payroc-openapi-spec.yaml"));
|
||||||
|
|
||||||
// Act
|
// 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
|
// Verify
|
||||||
await Verify(mappings);
|
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]
|
[Fact]
|
||||||
public async Task FromText_UsingJson_WithPlainTextExample_ShouldReturnMappings()
|
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"));
|
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "oas-content-example.json"));
|
||||||
|
|
||||||
// Act
|
// 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
|
// Verify
|
||||||
await Verify(mappings);
|
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