Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
33 changes: 30 additions & 3 deletions src/WireMock.Net.OpenApiParser/Extensions/DictionaryExtensions.cs
Original file line number Diff line number Diff line change
@@ -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))
Expand All @@ -16,5 +19,29 @@ public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue>? dictionar

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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -56,37 +54,25 @@ public static bool TryGetXNullable(this IOpenApiSchema schema, out bool value)

public static SchemaFormat GetSchemaFormat(this IOpenApiSchema? schema)
{
switch (schema?.Format)
return (schema?.Format) switch
{
case "float":
return SchemaFormat.Float;

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;
"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,
};
}

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
}
}
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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>
Expand All @@ -28,7 +27,8 @@ public static IWireMockServer WithMappingFromOpenApiFile(this IWireMockServer se
}

/// <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>
Expand All @@ -46,7 +46,8 @@ public static IWireMockServer WithMappingFromOpenApiFile(this IWireMockServer se
}

/// <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>
Expand All @@ -58,7 +59,8 @@ public static IWireMockServer WithMappingFromOpenApiStream(this IWireMockServer
}

/// <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>
Expand All @@ -77,7 +79,8 @@ public static IWireMockServer WithMappingFromOpenApiStream(this IWireMockServer
}

/// <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>
Expand Down
29 changes: 0 additions & 29 deletions src/WireMock.Net.OpenApiParser/ILRepack.targets

This file was deleted.

10 changes: 7 additions & 3 deletions src/WireMock.Net.OpenApiParser/IWireMockOpenApiParser.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand All @@ -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>
Expand Down
31 changes: 10 additions & 21 deletions src/WireMock.Net.OpenApiParser/Mappers/OpenApiPathsMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private MappingModel MapOperationToMappingModel(string path, string httpMethod,
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 }
};
}

Expand All @@ -70,8 +70,7 @@ private BodyModel GetRequestBodyModel(IOpenApiRequestBody? openApiRequestBody)

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)
Expand All @@ -86,10 +85,6 @@ private BodyModel GetRequestBodyModel(IOpenApiRequestBody? openApiRequestBody)
{
request = requestExamples.FirstOrDefault().Value.Value;
}
else if (requestSchemaExamples != null)
{
request = requestSchemaExamples.FirstOrDefault();
}
else
{
var requestSchema = content?.FirstOrDefault().Value.Schema;
Expand All @@ -99,16 +94,15 @@ private BodyModel GetRequestBodyModel(IOpenApiRequestBody? openApiRequestBody)
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)
Expand All @@ -119,24 +113,19 @@ private ResponseModel GetResponseModel(KeyValuePair<string, IOpenApiResponse>? o
{
response = responseSchemaExample;
}
else if (responseExamples != null)
{
response = responseExamples.FirstOrDefault().Value.Value;
}
else if (responseSchemaExamples != null)
else if (responseExamples.TryGetFirstValue(out var firstResponseFromExamples))
{
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
};
}
Expand Down
28 changes: 0 additions & 28 deletions src/WireMock.Net.OpenApiParser/Models/OpenApiDiagnostic.cs

This file was deleted.

Loading
Loading