mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-11 03:06:48 +02:00
Initial support for converting the mappings to a Pact(flow) json file (#748)
* WithDescription * WithConsumer / WithProvider * x * . * . * . * . * fix * pact * nullable * ficx * . * fix
This commit is contained in:
@@ -106,7 +106,7 @@ namespace WireMock.Handlers
|
||||
return File.Exists(AdjustPathForMappingFolder(filename));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.WriteFile(string, byte[])"/>
|
||||
/// <inheritdoc />
|
||||
public virtual void WriteFile(string filename, byte[] bytes)
|
||||
{
|
||||
Guard.NotNullOrEmpty(filename, nameof(filename));
|
||||
@@ -115,6 +115,16 @@ namespace WireMock.Handlers
|
||||
File.WriteAllBytes(AdjustPathForMappingFolder(filename), bytes);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void WriteFile(string folder, string filename, byte[] bytes)
|
||||
{
|
||||
Guard.NotNullOrEmpty(folder);
|
||||
Guard.NotNullOrEmpty(filename);
|
||||
Guard.NotNull(bytes);
|
||||
|
||||
File.WriteAllBytes(PathUtils.Combine(folder, filename), bytes);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.DeleteFile"/>
|
||||
public virtual void DeleteFile(string filename)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@@ -12,7 +12,7 @@ namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpRequestMessageHelper
|
||||
{
|
||||
internal static HttpRequestMessage Create([NotNull] RequestMessage requestMessage, [NotNull] string url)
|
||||
internal static HttpRequestMessage Create([NotNull] IRequestMessage requestMessage, [NotNull] string url)
|
||||
{
|
||||
Guard.NotNull(requestMessage, nameof(requestMessage));
|
||||
Guard.NotNullOrEmpty(url, nameof(url));
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace WireMock.Http
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] IWebhookRequest request, [NotNull] RequestMessage originalRequestMessage, [NotNull] ResponseMessage originalResponseMessage)
|
||||
public Task<HttpResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] IWebhookRequest request, [NotNull] IRequestMessage originalRequestMessage, [NotNull] IResponseMessage originalResponseMessage)
|
||||
{
|
||||
Guard.NotNull(client, nameof(client));
|
||||
Guard.NotNull(request, nameof(request));
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace WireMock
|
||||
/// </summary>
|
||||
string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The full filename path for this mapping (only defined for static mappings).
|
||||
/// </summary>
|
||||
@@ -117,7 +122,7 @@ namespace WireMock
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage);
|
||||
Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RequestMatchResult based on the RequestMessage.
|
||||
@@ -125,6 +130,6 @@ namespace WireMock
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <param name="nextState">The Next State.</param>
|
||||
/// <returns>The <see cref="IRequestMatchResult"/>.</returns>
|
||||
RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] string nextState);
|
||||
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, [CanBeNull] string nextState);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@ namespace WireMock
|
||||
/// <inheritdoc />
|
||||
public string Title { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Path { get; set; }
|
||||
|
||||
@@ -69,6 +72,7 @@ namespace WireMock
|
||||
/// </summary>
|
||||
/// <param name="guid">The unique identifier.</param>
|
||||
/// <param name="title">The unique title (can be null).</param>
|
||||
/// <param name="description">The description (can be null).</param>
|
||||
/// <param name="path">The full file path from this mapping title (can be null).</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <param name="requestMatcher">The request matcher.</param>
|
||||
@@ -82,21 +86,23 @@ namespace WireMock
|
||||
/// <param name="timeSettings">The TimeSettings. [Optional]</param>
|
||||
public Mapping(
|
||||
Guid guid,
|
||||
[CanBeNull] string title,
|
||||
[CanBeNull] string path,
|
||||
[NotNull] WireMockServerSettings settings,
|
||||
[NotNull] IRequestMatcher requestMatcher,
|
||||
[NotNull] IResponseProvider provider,
|
||||
string? title,
|
||||
string? description,
|
||||
string? path,
|
||||
WireMockServerSettings settings,
|
||||
IRequestMatcher requestMatcher,
|
||||
IResponseProvider provider,
|
||||
int priority,
|
||||
[CanBeNull] string scenario,
|
||||
[CanBeNull] string executionConditionState,
|
||||
[CanBeNull] string nextState,
|
||||
[CanBeNull] int? stateTimes,
|
||||
[CanBeNull] IWebhook[] webhooks,
|
||||
[CanBeNull] ITimeSettings timeSettings)
|
||||
string? scenario,
|
||||
string? executionConditionState,
|
||||
string? nextState,
|
||||
int? stateTimes,
|
||||
IWebhook[]? webhooks,
|
||||
ITimeSettings? timeSettings)
|
||||
{
|
||||
Guid = guid;
|
||||
Title = title;
|
||||
Description = description;
|
||||
Path = path;
|
||||
Settings = settings;
|
||||
RequestMatcher = requestMatcher;
|
||||
@@ -111,13 +117,13 @@ namespace WireMock
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.ProvideResponseAsync" />
|
||||
public Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage)
|
||||
public Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage)
|
||||
{
|
||||
return Provider.ProvideResponseAsync(requestMessage, Settings);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.GetRequestMatchResult" />
|
||||
public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, string nextState)
|
||||
public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string nextState)
|
||||
{
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The RequestMatcher interface.
|
||||
/// </summary>
|
||||
public interface IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified RequestMessage is match.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The RequestMessage.</param>
|
||||
/// <param name="requestMatchResult">The RequestMatchResult.</param>
|
||||
/// <returns>
|
||||
/// A value between 0.0 - 1.0 of the similarity.
|
||||
/// </returns>
|
||||
double GetMatchingScore([NotNull] IRequestMessage requestMessage, [NotNull] RequestMatchResult requestMatchResult);
|
||||
}
|
||||
}
|
||||
@@ -114,8 +114,8 @@ namespace WireMock.Matchers.Request
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <see cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
@@ -50,8 +50,8 @@ namespace WireMock.Matchers.Request
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
@@ -33,8 +33,8 @@ namespace WireMock.Matchers.Request
|
||||
RequestMatchers = requestMatchers;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
if (!RequestMatchers.Any())
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
@@ -90,8 +90,8 @@ namespace WireMock.Matchers.Request
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using JetBrains.Annotations;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -91,8 +91,8 @@ namespace WireMock.Matchers.Request
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
@@ -30,8 +30,8 @@ namespace WireMock.Matchers.Request
|
||||
Methods = methods;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using JetBrains.Annotations;
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -83,8 +83,8 @@ namespace WireMock.Matchers.Request
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
@@ -53,7 +53,7 @@ namespace WireMock.Matchers.Request
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using JetBrains.Annotations;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace WireMock.Matchers.Request
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch();
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
@@ -50,8 +50,8 @@ namespace WireMock.Matchers.Request
|
||||
Funcs = funcs;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = IsMatch(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Util
|
||||
@@ -9,33 +9,33 @@ namespace WireMock.Util
|
||||
public class BodyData : IBodyData
|
||||
{
|
||||
/// <inheritdoc cref="IBodyData.Encoding" />
|
||||
public Encoding Encoding { get; set; }
|
||||
public Encoding? Encoding { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsBytes" />
|
||||
public string BodyAsString { get; set; }
|
||||
public string? BodyAsString { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsJson" />
|
||||
public object BodyAsJson { get; set; }
|
||||
public object? BodyAsJson { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsBytes" />
|
||||
public byte[] BodyAsBytes { get; set; }
|
||||
public byte[]? BodyAsBytes { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsJsonIndented" />
|
||||
public bool? BodyAsJsonIndented { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsFile" />
|
||||
public string BodyAsFile { get; set; }
|
||||
public string? BodyAsFile { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.BodyAsFileIsCached" />
|
||||
public bool? BodyAsFileIsCached { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.DetectedBodyType" />
|
||||
public BodyType DetectedBodyType { get; set; }
|
||||
public BodyType? DetectedBodyType { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IBodyData.DetectedBodyTypeFromContentType" />
|
||||
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
||||
public BodyType? DetectedBodyTypeFromContentType { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IRequestMessage.DetectedCompression" />
|
||||
public string DetectedCompression { get; set; }
|
||||
public string? DetectedCompression { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Util;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Types;
|
||||
#if !USE_ASPNETCORE
|
||||
using Owin;
|
||||
@@ -21,7 +20,7 @@ namespace WireMock.Owin
|
||||
|
||||
TimeSpan? RequestProcessingDelay { get; set; }
|
||||
|
||||
IStringMatcher AuthenticationMatcher { get; set; }
|
||||
IStringMatcher? AuthenticationMatcher { get; set; }
|
||||
|
||||
bool? AllowPartialMapping { get; set; }
|
||||
|
||||
@@ -35,17 +34,17 @@ namespace WireMock.Owin
|
||||
|
||||
int? MaxRequestLogCount { get; set; }
|
||||
|
||||
Action<IAppBuilder> PreWireMockMiddlewareInit { get; set; }
|
||||
Action<IAppBuilder>? PreWireMockMiddlewareInit { get; set; }
|
||||
|
||||
Action<IAppBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||
Action<IAppBuilder>? PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
|
||||
|
||||
CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
IFileSystemHandler? FileSystemHandler { get; set; }
|
||||
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
@@ -57,15 +56,15 @@ namespace WireMock.Owin
|
||||
|
||||
bool? HandleRequestsSynchronously { get; set; }
|
||||
|
||||
string X509StoreName { get; set; }
|
||||
string? X509StoreName { get; set; }
|
||||
|
||||
string X509StoreLocation { get; set; }
|
||||
string? X509StoreLocation { get; set; }
|
||||
|
||||
string X509ThumbprintOrSubjectName { get; set; }
|
||||
string? X509ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
string X509CertificateFilePath { get; set; }
|
||||
string? X509CertificateFilePath { get; set; }
|
||||
|
||||
string X509CertificatePassword { get; set; }
|
||||
string? X509CertificatePassword { get; set; }
|
||||
|
||||
bool CustomCertificateDefined { get; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
#if !USE_ASPNETCORE
|
||||
using IResponse = Microsoft.Owin.IOwinResponse;
|
||||
#else
|
||||
@@ -17,6 +17,6 @@ namespace WireMock.Owin.Mappers
|
||||
/// </summary>
|
||||
/// <param name="responseMessage">The ResponseMessage</param>
|
||||
/// <param name="response">The OwinResponse/HttpResponse</param>
|
||||
Task MapAsync(ResponseMessage responseMessage, IResponse response);
|
||||
Task MapAsync(IResponseMessage responseMessage, IResponse response);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IOwinResponseMapper.MapAsync"/>
|
||||
public async Task MapAsync(ResponseMessage responseMessage, IResponse response)
|
||||
public async Task MapAsync(IResponseMessage responseMessage, IResponse response)
|
||||
{
|
||||
if (responseMessage == null)
|
||||
{
|
||||
@@ -117,12 +117,12 @@ namespace WireMock.Owin.Mappers
|
||||
return code;
|
||||
}
|
||||
|
||||
private bool IsFault(ResponseMessage responseMessage)
|
||||
private bool IsFault(IResponseMessage responseMessage)
|
||||
{
|
||||
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
|
||||
}
|
||||
|
||||
private byte[] GetNormalBody(ResponseMessage responseMessage)
|
||||
private byte[] GetNormalBody(IResponseMessage responseMessage)
|
||||
{
|
||||
byte[] bytes = null;
|
||||
switch (responseMessage.BodyData?.DetectedBodyType)
|
||||
@@ -151,7 +151,7 @@ namespace WireMock.Owin.Mappers
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static void SetResponseHeaders(ResponseMessage responseMessage, IResponse response)
|
||||
private static void SetResponseHeaders(IResponseMessage responseMessage, IResponse response)
|
||||
{
|
||||
// Force setting the Date header (#577)
|
||||
AppendResponseHeader(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
@@ -6,6 +6,6 @@ namespace WireMock.Owin
|
||||
{
|
||||
public IMapping Mapping { get; set; }
|
||||
|
||||
public RequestMatchResult RequestMatchResult { get; set; }
|
||||
public IRequestMatchResult RequestMatchResult { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ namespace WireMock.Owin
|
||||
var request = await _requestMapper.MapAsync(ctx.Request, _options).ConfigureAwait(false);
|
||||
|
||||
var logRequest = false;
|
||||
ResponseMessage response = null;
|
||||
IResponseMessage response = null;
|
||||
(MappingMatcherResult Match, MappingMatcherResult Partial) result = (null, null);
|
||||
try
|
||||
{
|
||||
@@ -192,7 +192,7 @@ namespace WireMock.Owin
|
||||
await CompletedTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task SendToWebhooksAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
|
||||
private async Task SendToWebhooksAsync(IMapping mapping, IRequestMessage request, IResponseMessage response)
|
||||
{
|
||||
for (int index = 0; index < mapping.Webhooks.Length; index++)
|
||||
{
|
||||
|
||||
13
src/WireMock.Net/Pact/Models/V2/Interaction.cs
Normal file
13
src/WireMock.Net/Pact/Models/V2/Interaction.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class Interaction
|
||||
{
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public string ProviderState { get; set; }
|
||||
|
||||
public Request Request { get; set; } = new Request();
|
||||
|
||||
public Response Response { get; set; } = new Response();
|
||||
}
|
||||
}
|
||||
25
src/WireMock.Net/Pact/Models/V2/MatchingRule.cs
Normal file
25
src/WireMock.Net/Pact/Models/V2/MatchingRule.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class MatchingRule
|
||||
{
|
||||
/// <summary>
|
||||
/// type or regex
|
||||
/// </summary>
|
||||
public string Match { get; set; } = "type";
|
||||
|
||||
/// <summary>
|
||||
/// Used for Match = "type"
|
||||
/// </summary>
|
||||
public string Min { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used for Match = "type"
|
||||
/// </summary>
|
||||
public string Max { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used for Match = "regex"
|
||||
/// </summary>
|
||||
public string Regex { get; set; }
|
||||
}
|
||||
}
|
||||
9
src/WireMock.Net/Pact/Models/V2/Metadata.cs
Normal file
9
src/WireMock.Net/Pact/Models/V2/Metadata.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class Metadata
|
||||
{
|
||||
public string PactSpecificationVersion { get; set; }
|
||||
|
||||
public PactSpecification PactSpecification { get; set; } = new PactSpecification();
|
||||
}
|
||||
}
|
||||
15
src/WireMock.Net/Pact/Models/V2/Pact.cs
Normal file
15
src/WireMock.Net/Pact/Models/V2/Pact.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class Pact
|
||||
{
|
||||
public Pacticipant Consumer { get; set; }
|
||||
|
||||
public List<Interaction> Interactions { get; set; } = new List<Interaction>();
|
||||
|
||||
public Metadata Metadata { get; set; }
|
||||
|
||||
public Pacticipant Provider { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/WireMock.Net/Pact/Models/V2/PactRust.cs
Normal file
11
src/WireMock.Net/Pact/Models/V2/PactRust.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class PactRust
|
||||
{
|
||||
public string Ffi { get; set; }
|
||||
|
||||
public string Mockserver { get; set; }
|
||||
|
||||
public string Models { get; set; }
|
||||
}
|
||||
}
|
||||
7
src/WireMock.Net/Pact/Models/V2/PactSpecification.cs
Normal file
7
src/WireMock.Net/Pact/Models/V2/PactSpecification.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class PactSpecification
|
||||
{
|
||||
public string Version { get; set; } = "2.0";
|
||||
}
|
||||
}
|
||||
7
src/WireMock.Net/Pact/Models/V2/Pacticipant.cs
Normal file
7
src/WireMock.Net/Pact/Models/V2/Pacticipant.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class Pacticipant
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/WireMock.Net/Pact/Models/V2/ProviderState.cs
Normal file
11
src/WireMock.Net/Pact/Models/V2/ProviderState.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2
|
||||
{
|
||||
public class ProviderState
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public IDictionary<string, string> Params { get; set; }
|
||||
}
|
||||
}
|
||||
16
src/WireMock.Net/Pact/Models/V2/Request.cs
Normal file
16
src/WireMock.Net/Pact/Models/V2/Request.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2;
|
||||
|
||||
public class Request
|
||||
{
|
||||
public IDictionary<string, string>? Headers { get; set; }
|
||||
|
||||
public string Method { get; set; } = "GET";
|
||||
|
||||
public string? Path { get; set; } = "/";
|
||||
|
||||
public string? Query { get; set; }
|
||||
|
||||
public object? Body { get; set; }
|
||||
}
|
||||
12
src/WireMock.Net/Pact/Models/V2/Response.cs
Normal file
12
src/WireMock.Net/Pact/Models/V2/Response.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Pact.Models.V2;
|
||||
|
||||
public class Response
|
||||
{
|
||||
public object? Body { get; set; }
|
||||
|
||||
public IDictionary<string, string>? Headers { get; set; }
|
||||
|
||||
public int Status { get; set; } = 200;
|
||||
}
|
||||
206
src/WireMock.Net/Pact/Models/V2/_v2.json
Normal file
206
src/WireMock.Net/Pact/Models/V2/_v2.json
Normal file
@@ -0,0 +1,206 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"definitions": {
|
||||
"headers": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"interaction": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"providerState": {
|
||||
"type": "string"
|
||||
},
|
||||
"request": {
|
||||
"$ref": "#/definitions/request"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#/definitions/response"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"interactions": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/interaction"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"matchingRules": {
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^\\$.*$": {
|
||||
"oneOf": [
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"match": {
|
||||
"enum": [ "type" ],
|
||||
"type": "string"
|
||||
},
|
||||
"max": {
|
||||
"type": "number"
|
||||
},
|
||||
"min": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [ "match" ],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"match": {
|
||||
"enum": [ "regex" ],
|
||||
"type": "string"
|
||||
},
|
||||
"regex": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"match",
|
||||
"regex"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"metadata": {
|
||||
"properties": {
|
||||
"pactSpecification": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [ "version" ],
|
||||
"type": "object"
|
||||
},
|
||||
"pactSpecificationVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"pact-specification": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [ "version" ],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"pacticipant": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [ "name" ],
|
||||
"type": "object"
|
||||
},
|
||||
"request": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"body": {},
|
||||
"headers": {
|
||||
"$ref": "#/definitions/headers"
|
||||
},
|
||||
"matchingRules": {
|
||||
"$ref": "#/definitions/matchingRules"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"connect",
|
||||
"CONNECT",
|
||||
"delete",
|
||||
"DELETE",
|
||||
"get",
|
||||
"GET",
|
||||
"head",
|
||||
"HEAD",
|
||||
"options",
|
||||
"OPTIONS",
|
||||
"post",
|
||||
"POST",
|
||||
"put",
|
||||
"PUT",
|
||||
"trace",
|
||||
"TRACE"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"query": {
|
||||
"pattern": "^$|^[^=&]+=[^=&]+&?$|^[^=&]+=[^=&]+(&[^=&]+=[^=&]+)*&?$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"response": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"body": {},
|
||||
"headers": {
|
||||
"$ref": "#/definitions/headers"
|
||||
},
|
||||
"matchingRules": {
|
||||
"$ref": "#/definitions/matchingRules"
|
||||
},
|
||||
"status": {
|
||||
"maximum": 599,
|
||||
"minimum": 100,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [ "status" ],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "Schema for a Pact file",
|
||||
"properties": {
|
||||
"consumer": {
|
||||
"$ref": "#/definitions/pacticipant"
|
||||
},
|
||||
"interactions": {
|
||||
"$ref": "#/definitions/interactions"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "#/definitions/metadata"
|
||||
},
|
||||
"provider": {
|
||||
"$ref": "#/definitions/pacticipant"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"consumer",
|
||||
"interactions",
|
||||
"provider"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("WireMock.Net.Matchers.CSharpCode, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e138ec44d93acac565953052636eb8d5e7e9f27ddb030590055cd1a0ab2069a5623f1f77ca907d78e0b37066ca0f6d63da7eecc3fcb65b76aa8ebeccf7ebe1d11264b8404cd9b1cbbf2c83f566e033b3e54129f6ef28daffff776ba7aebbc53c0d635ebad8f45f78eb3f7e0459023c218f003416e080f96a1a3c5ffeb56bee9e")]
|
||||
[assembly: InternalsVisibleTo("WireMock.Net.StandAlone, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e138ec44d93acac565953052636eb8d5e7e9f27ddb030590055cd1a0ab2069a5623f1f77ca907d78e0b37066ca0f6d63da7eecc3fcb65b76aa8ebeccf7ebe1d11264b8404cd9b1cbbf2c83f566e033b3e54129f6ef28daffff776ba7aebbc53c0d635ebad8f45f78eb3f7e0459023c218f003416e080f96a1a3c5ffeb56bee9e")]
|
||||
[assembly: InternalsVisibleTo("WireMock.Net.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e138ec44d93acac565953052636eb8d5e7e9f27ddb030590055cd1a0ab2069a5623f1f77ca907d78e0b37066ca0f6d63da7eecc3fcb65b76aa8ebeccf7ebe1d11264b8404cd9b1cbbf2c83f566e033b3e54129f6ef28daffff776ba7aebbc53c0d635ebad8f45f78eb3f7e0459023c218f003416e080f96a1a3c5ffeb56bee9e")]
|
||||
|
||||
// Needed for Moq in the UnitTest project
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
|
||||
@@ -24,10 +24,10 @@ namespace WireMock.Proxy
|
||||
_settings = Guard.NotNull(settings, nameof(settings));
|
||||
}
|
||||
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> SendAsync(
|
||||
public async Task<(IResponseMessage Message, IMapping Mapping)> SendAsync(
|
||||
[NotNull] ProxyAndRecordSettings proxyAndRecordSettings,
|
||||
[NotNull] HttpClient client,
|
||||
[NotNull] RequestMessage requestMessage,
|
||||
[NotNull] IRequestMessage requestMessage,
|
||||
[NotNull] string url)
|
||||
{
|
||||
Guard.NotNull(client, nameof(client));
|
||||
@@ -59,7 +59,7 @@ namespace WireMock.Proxy
|
||||
return (responseMessage, mapping);
|
||||
}
|
||||
|
||||
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, RequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
{
|
||||
string[] excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
||||
string[] excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||
@@ -104,7 +104,7 @@ namespace WireMock.Proxy
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, string.Empty, null, _settings, request, response, 0, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -17,7 +16,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] string body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a callback function.
|
||||
@@ -26,7 +25,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] Func<RequestMessage, string> bodyFactory, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a callback function.
|
||||
@@ -35,7 +34,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] Func<RequestMessage, Task<string>> bodyFactory, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a bytearray.
|
||||
@@ -44,7 +43,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] byte[] body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string).
|
||||
@@ -53,7 +52,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <param name="indented">Use JSON indented.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson([NotNull] object body, [CanBeNull] Encoding encoding = null, bool? indented = null);
|
||||
IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string).
|
||||
@@ -61,7 +60,7 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="indented">Define whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson([NotNull] object body, bool indented);
|
||||
IResponseBuilder WithBodyAsJson(object body, bool indented);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyFromFile : Create a ... response based on a File.
|
||||
@@ -69,6 +68,6 @@ namespace WireMock.ResponseBuilders
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk every time the response is created.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyFromFile([NotNull] string filename, bool cache = true);
|
||||
IResponseBuilder WithBodyFromFile(string filename, bool cache = true);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.ResponseProviders;
|
||||
@@ -15,13 +15,13 @@ namespace WireMock.ResponseBuilders
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
[PublicAPI]
|
||||
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler);
|
||||
IResponseBuilder WithCallback([NotNull] Func<IRequestMessage, ResponseMessage> callbackHandler);
|
||||
|
||||
/// <summary>
|
||||
/// The async callback builder
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
[PublicAPI]
|
||||
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, Task<ResponseMessage>> callbackHandler);
|
||||
IResponseBuilder WithCallback([NotNull] Func<IRequestMessage, Task<ResponseMessage>> callbackHandler);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Stef.Validation;
|
||||
|
||||
@@ -9,35 +9,35 @@ namespace WireMock.ResponseBuilders
|
||||
/// <summary>
|
||||
/// A delegate to execute to generate the response.
|
||||
/// </summary>
|
||||
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
|
||||
public Func<IRequestMessage, ResponseMessage> Callback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to execute to generate the response async.
|
||||
/// </summary>
|
||||
public Func<RequestMessage, Task<ResponseMessage>> CallbackAsync { get; private set; }
|
||||
public Func<IRequestMessage, Task<ResponseMessage>> CallbackAsync { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the method WithCallback(...) is used.
|
||||
/// </summary>
|
||||
public bool WithCallbackUsed { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, ResponseMessage})"/>
|
||||
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, ResponseMessage> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler, nameof(callbackHandler));
|
||||
|
||||
return WithCallbackInternal(true, callbackHandler);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, Task{ResponseMessage}})"/>
|
||||
public IResponseBuilder WithCallback(Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler, nameof(callbackHandler));
|
||||
|
||||
return WithCallbackInternal(true, callbackHandler);
|
||||
}
|
||||
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, ResponseMessage> callbackHandler)
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, ResponseMessage> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler, nameof(callbackHandler));
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace WireMock.ResponseBuilders
|
||||
return this;
|
||||
}
|
||||
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler, nameof(callbackHandler));
|
||||
|
||||
|
||||
@@ -195,8 +195,8 @@ namespace WireMock.ResponseBuilders
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, string}, string, Encoding)"/>
|
||||
public IResponseBuilder WithBody(Func<RequestMessage, string> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
{
|
||||
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
||||
|
||||
@@ -211,8 +211,8 @@ namespace WireMock.ResponseBuilders
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, Task{string}}, string, Encoding)"/>
|
||||
public IResponseBuilder WithBody(Func<RequestMessage, Task<string>> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
{
|
||||
Guard.NotNull(bodyFactory, nameof(bodyFactory));
|
||||
|
||||
@@ -383,8 +383,8 @@ namespace WireMock.ResponseBuilders
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, WireMockServerSettings)"/>
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, WireMockServerSettings settings)
|
||||
/// <inheritdoc />
|
||||
public async Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
Guard.NotNull(requestMessage, nameof(requestMessage));
|
||||
Guard.NotNull(settings, nameof(settings));
|
||||
|
||||
@@ -6,14 +6,14 @@ namespace WireMock.ResponseProviders
|
||||
{
|
||||
internal class DynamicAsyncResponseProvider : IResponseProvider
|
||||
{
|
||||
private readonly Func<RequestMessage, Task<ResponseMessage>> _responseMessageFunc;
|
||||
private readonly Func<IRequestMessage, Task<IResponseMessage>> _responseMessageFunc;
|
||||
|
||||
public DynamicAsyncResponseProvider(Func<RequestMessage, Task<ResponseMessage>> responseMessageFunc)
|
||||
public DynamicAsyncResponseProvider(Func<IRequestMessage, Task<IResponseMessage>> responseMessageFunc)
|
||||
{
|
||||
_responseMessageFunc = responseMessageFunc;
|
||||
}
|
||||
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, WireMockServerSettings settings)
|
||||
public async Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
return (await _responseMessageFunc(requestMessage).ConfigureAwait(false), null);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@ namespace WireMock.ResponseProviders
|
||||
{
|
||||
internal class DynamicResponseProvider : IResponseProvider
|
||||
{
|
||||
private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;
|
||||
private readonly Func<IRequestMessage, IResponseMessage> _responseMessageFunc;
|
||||
|
||||
public DynamicResponseProvider(Func<RequestMessage, ResponseMessage> responseMessageFunc)
|
||||
public DynamicResponseProvider(Func<IRequestMessage, IResponseMessage> responseMessageFunc)
|
||||
{
|
||||
_responseMessageFunc = responseMessageFunc;
|
||||
}
|
||||
|
||||
public Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, WireMockServerSettings settings)
|
||||
public Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
(ResponseMessage responseMessage, IMapping mapping) result = (_responseMessageFunc(requestMessage), null);
|
||||
(IResponseMessage responseMessage, IMapping mapping) result = (_responseMessageFunc(requestMessage), null);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
@@ -17,6 +17,6 @@ namespace WireMock.ResponseProviders
|
||||
/// <param name="requestMessage">The request.</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync([NotNull] RequestMessage requestMessage, [NotNull] WireMockServerSettings settings);
|
||||
Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync([NotNull] IRequestMessage requestMessage, [NotNull] WireMockServerSettings settings);
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,16 @@ namespace WireMock.ResponseProviders
|
||||
{
|
||||
internal class ProxyAsyncResponseProvider : IResponseProvider
|
||||
{
|
||||
private readonly Func<RequestMessage, WireMockServerSettings, Task<ResponseMessage>> _responseMessageFunc;
|
||||
private readonly Func<IRequestMessage, WireMockServerSettings, Task<IResponseMessage>> _responseMessageFunc;
|
||||
private readonly WireMockServerSettings _settings;
|
||||
|
||||
public ProxyAsyncResponseProvider(Func<RequestMessage, WireMockServerSettings, Task<ResponseMessage>> responseMessageFunc, WireMockServerSettings settings)
|
||||
public ProxyAsyncResponseProvider(Func<IRequestMessage, WireMockServerSettings, Task<IResponseMessage>> responseMessageFunc, WireMockServerSettings settings)
|
||||
{
|
||||
_responseMessageFunc = responseMessageFunc;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, WireMockServerSettings settings)
|
||||
public async Task<(IResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
return (await _responseMessageFunc(requestMessage, _settings).ConfigureAwait(false), null);
|
||||
}
|
||||
|
||||
@@ -20,5 +20,11 @@ namespace WireMock.Serialization
|
||||
{
|
||||
DateParseHandling = DateParseHandling.None
|
||||
};
|
||||
|
||||
public static readonly JsonSerializerSettings JsonSerializerSettingsPact = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Logging;
|
||||
@@ -29,8 +29,8 @@ namespace WireMock.Serialization
|
||||
|
||||
if (logEntry.RequestMessage.BodyData != null)
|
||||
{
|
||||
logRequestModel.DetectedBodyType = logEntry.RequestMessage.BodyData.DetectedBodyType.ToString();
|
||||
logRequestModel.DetectedBodyTypeFromContentType = logEntry.RequestMessage.BodyData.DetectedBodyTypeFromContentType.ToString();
|
||||
logRequestModel.DetectedBodyType = logEntry.RequestMessage.BodyData.DetectedBodyType?.ToString();
|
||||
logRequestModel.DetectedBodyTypeFromContentType = logEntry.RequestMessage.BodyData.DetectedBodyTypeFromContentType?.ToString();
|
||||
|
||||
switch (logEntry.RequestMessage.BodyData.DetectedBodyType)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace WireMock.Serialization
|
||||
Guid = mapping.Guid,
|
||||
TimeSettings = TimeSettingsMapper.Map(mapping.TimeSettings),
|
||||
Title = mapping.Title,
|
||||
Description = mapping.Description,
|
||||
Priority = mapping.Priority != 0 ? mapping.Priority : (int?)null,
|
||||
Scenario = mapping.Scenario,
|
||||
WhenStateIs = mapping.ExecutionConditionState,
|
||||
|
||||
@@ -1,51 +1,49 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Settings;
|
||||
using Stef.Validation;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
namespace WireMock.Serialization;
|
||||
|
||||
internal class MappingToFileSaver
|
||||
{
|
||||
internal class MappingToFileSaver
|
||||
private readonly WireMockServerSettings _settings;
|
||||
private readonly MappingConverter _mappingConverter;
|
||||
|
||||
public MappingToFileSaver(WireMockServerSettings settings, MappingConverter mappingConverter)
|
||||
{
|
||||
private readonly WireMockServerSettings _settings;
|
||||
private readonly MappingConverter _mappingConverter;
|
||||
Guard.NotNull(settings);
|
||||
Guard.NotNull(mappingConverter);
|
||||
|
||||
public MappingToFileSaver(WireMockServerSettings settings, MappingConverter mappingConverter)
|
||||
_settings = settings;
|
||||
_mappingConverter = mappingConverter;
|
||||
}
|
||||
|
||||
public void SaveMappingToFile(IMapping mapping, string? folder = null)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
Guard.NotNull(settings);
|
||||
Guard.NotNull(mappingConverter);
|
||||
|
||||
_settings = settings;
|
||||
_mappingConverter = mappingConverter;
|
||||
folder = _settings.FileSystemHandler.GetMappingFolder();
|
||||
}
|
||||
|
||||
public void SaveMappingToFile(IMapping mapping, [CanBeNull] string folder = null)
|
||||
if (!_settings.FileSystemHandler.FolderExists(folder))
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
folder = _settings.FileSystemHandler.GetMappingFolder();
|
||||
}
|
||||
|
||||
if (!_settings.FileSystemHandler.FolderExists(folder))
|
||||
{
|
||||
_settings.FileSystemHandler.CreateFolder(folder);
|
||||
}
|
||||
|
||||
var model = _mappingConverter.ToMappingModel(mapping);
|
||||
string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString()) + ".json";
|
||||
|
||||
string path = Path.Combine(folder, filename);
|
||||
|
||||
_settings.Logger.Info("Saving Mapping file {0}", filename);
|
||||
|
||||
_settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, JsonSerializationConstants.JsonSerializerSettingsDefault));
|
||||
_settings.FileSystemHandler.CreateFolder(folder);
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string name, char replaceChar = '_')
|
||||
{
|
||||
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));
|
||||
}
|
||||
var model = _mappingConverter.ToMappingModel(mapping);
|
||||
string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString()) + ".json";
|
||||
|
||||
string path = Path.Combine(folder, filename);
|
||||
|
||||
_settings.Logger.Info("Saving Mapping file {0}", filename);
|
||||
|
||||
_settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, JsonSerializationConstants.JsonSerializerSettingsDefault));
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string name, char replaceChar = '_')
|
||||
{
|
||||
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,13 @@ namespace WireMock.Server
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithTitle(string title);
|
||||
|
||||
/// <summary>
|
||||
/// Define a description for this mapping.
|
||||
/// </summary>
|
||||
/// <param name="description">The description.</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithDescription(string description);
|
||||
|
||||
/// <summary>
|
||||
/// Define the full filepath for this mapping.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace WireMock.Server
|
||||
{
|
||||
private int _priority;
|
||||
private string _title;
|
||||
private string _description;
|
||||
private string _path;
|
||||
private string _executionConditionState;
|
||||
private string _nextState;
|
||||
@@ -58,16 +59,16 @@ namespace WireMock.Server
|
||||
/// <param name="provider">The provider.</param>
|
||||
public void RespondWith(IResponseProvider provider)
|
||||
{
|
||||
_registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks, TimeSettings), _saveToFile);
|
||||
_registrationCallback(new Mapping(Guid, _title, _description, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks, TimeSettings), _saveToFile);
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithGuid(string guid)
|
||||
{
|
||||
return WithGuid(Guid.Parse(guid));
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithGuid(Guid guid)
|
||||
{
|
||||
Guid = guid;
|
||||
@@ -75,7 +76,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithTitle"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithTitle(string title)
|
||||
{
|
||||
_title = title;
|
||||
@@ -83,6 +84,14 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithDescription(string description)
|
||||
{
|
||||
_description = description;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithPath"/>
|
||||
public IRespondWithAProvider WithPath(string path)
|
||||
{
|
||||
@@ -91,7 +100,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.AtPriority"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider AtPriority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
@@ -99,7 +108,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider InScenario(string scenario)
|
||||
{
|
||||
_scenario = scenario;
|
||||
@@ -107,13 +116,13 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(int)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider InScenario(int scenario)
|
||||
{
|
||||
return InScenario(scenario.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(string)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WhenStateIs(string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
@@ -126,13 +135,13 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(int)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WhenStateIs(int state)
|
||||
{
|
||||
return WhenStateIs(state.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(string, int?)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
@@ -146,7 +155,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(int, int?)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
|
||||
{
|
||||
return WillSetStateTo(state.ToString(), times);
|
||||
@@ -162,7 +171,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(IWebhook[])"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithWebhook(params IWebhook[] webhooks)
|
||||
{
|
||||
Guard.HasNoNulls(webhooks, nameof(webhooks));
|
||||
@@ -172,7 +181,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, string, bool, TransformerType)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
@@ -196,7 +205,7 @@ namespace WireMock.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, object, bool, TransformerType)"/>
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
|
||||
@@ -44,12 +44,12 @@ public partial class WireMockServer
|
||||
private const string AdminScenarios = "/__admin/scenarios";
|
||||
private const string QueryParamReloadStaticMappings = "reloadStaticMappings";
|
||||
|
||||
private readonly Guid _proxyMappingGuid = new Guid("e59914fd-782e-428e-91c1-4810ffb86567");
|
||||
private readonly Guid _proxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567");
|
||||
private readonly RegexMatcher _adminRequestContentTypeJson = new ContentTypeMatcher(ContentTypeJson, true);
|
||||
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
|
||||
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
|
||||
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
|
||||
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
|
||||
|
||||
private EnhancedFileSystemWatcher _enhancedFileSystemWatcher;
|
||||
private EnhancedFileSystemWatcher? _enhancedFileSystemWatcher;
|
||||
|
||||
#region InitAdmin
|
||||
private void InitAdmin()
|
||||
@@ -108,7 +108,7 @@ public partial class WireMockServer
|
||||
#region StaticMappings
|
||||
/// <inheritdoc cref="IWireMockServer.SaveStaticMappings" />
|
||||
[PublicAPI]
|
||||
public void SaveStaticMappings([CanBeNull] string folder = null)
|
||||
public void SaveStaticMappings(string? folder = null)
|
||||
{
|
||||
foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
|
||||
{
|
||||
@@ -118,7 +118,7 @@ public partial class WireMockServer
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.ReadStaticMappings" />
|
||||
[PublicAPI]
|
||||
public void ReadStaticMappings([CanBeNull] string folder = null)
|
||||
public void ReadStaticMappings(string? folder = null)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
@@ -207,8 +207,7 @@ public partial class WireMockServer
|
||||
#endregion
|
||||
|
||||
#region Proxy and Record
|
||||
[CanBeNull]
|
||||
private HttpClient _httpClientForProxy;
|
||||
private HttpClient? _httpClientForProxy;
|
||||
|
||||
private void InitProxyAndRecord(WireMockServerSettings settings)
|
||||
{
|
||||
@@ -230,7 +229,7 @@ public partial class WireMockServer
|
||||
proxyRespondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
|
||||
}
|
||||
|
||||
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, WireMockServerSettings settings)
|
||||
private async Task<IResponseMessage> ProxyAndRecordAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
|
||||
@@ -263,7 +262,7 @@ public partial class WireMockServer
|
||||
#endregion
|
||||
|
||||
#region Settings
|
||||
private ResponseMessage SettingsGet(RequestMessage requestMessage)
|
||||
private IResponseMessage SettingsGet(IRequestMessage requestMessage)
|
||||
{
|
||||
var model = new SettingsModel
|
||||
{
|
||||
@@ -290,7 +289,7 @@ public partial class WireMockServer
|
||||
return ToJson(model);
|
||||
}
|
||||
|
||||
private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
|
||||
private IResponseMessage SettingsUpdate(IRequestMessage requestMessage)
|
||||
{
|
||||
var settings = DeserializeObject<SettingsModel>(requestMessage);
|
||||
|
||||
@@ -335,7 +334,7 @@ public partial class WireMockServer
|
||||
#endregion Settings
|
||||
|
||||
#region Mapping/{guid}
|
||||
private ResponseMessage MappingGet(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingGet(IRequestMessage requestMessage)
|
||||
{
|
||||
Guid guid = ParseGuidFromRequestMessage(requestMessage);
|
||||
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
|
||||
@@ -351,7 +350,7 @@ public partial class WireMockServer
|
||||
return ToJson(model);
|
||||
}
|
||||
|
||||
private ResponseMessage MappingPut(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingPut(IRequestMessage requestMessage)
|
||||
{
|
||||
Guid guid = ParseGuidFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -361,7 +360,7 @@ public partial class WireMockServer
|
||||
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
|
||||
}
|
||||
|
||||
private ResponseMessage MappingDelete(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
Guid guid = ParseGuidFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -373,14 +372,14 @@ public partial class WireMockServer
|
||||
return ResponseMessageBuilder.Create("Mapping not found", 404);
|
||||
}
|
||||
|
||||
private Guid ParseGuidFromRequestMessage(RequestMessage requestMessage)
|
||||
private Guid ParseGuidFromRequestMessage(IRequestMessage requestMessage)
|
||||
{
|
||||
return Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
|
||||
}
|
||||
#endregion Mapping/{guid}
|
||||
|
||||
#region Mappings
|
||||
private ResponseMessage MappingsSave(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsSave(IRequestMessage requestMessage)
|
||||
{
|
||||
SaveStaticMappings();
|
||||
|
||||
@@ -392,12 +391,12 @@ public partial class WireMockServer
|
||||
return Mappings.Where(m => !m.IsAdminInterface).Select(_mappingConverter.ToMappingModel);
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsGet(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsGet(IRequestMessage requestMessage)
|
||||
{
|
||||
return ToJson(ToMappingModels());
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsPost(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsPost(IRequestMessage requestMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -427,7 +426,7 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string path = null)
|
||||
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
|
||||
{
|
||||
Guard.NotNull(mappingModel, nameof(mappingModel));
|
||||
Guard.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
||||
@@ -494,7 +493,7 @@ public partial class WireMockServer
|
||||
return respondProvider.Guid;
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsDelete(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(requestMessage.Body))
|
||||
{
|
||||
@@ -519,7 +518,7 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Guid> MappingsDeleteMappingFromBody(RequestMessage requestMessage)
|
||||
private IEnumerable<Guid> MappingsDeleteMappingFromBody(IRequestMessage requestMessage)
|
||||
{
|
||||
var deletedGuids = new List<Guid>();
|
||||
|
||||
@@ -555,7 +554,7 @@ public partial class WireMockServer
|
||||
return deletedGuids;
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsReset(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsReset(IRequestMessage requestMessage)
|
||||
{
|
||||
ResetMappings();
|
||||
|
||||
@@ -575,7 +574,7 @@ public partial class WireMockServer
|
||||
#endregion Mappings
|
||||
|
||||
#region Request/{guid}
|
||||
private ResponseMessage RequestGet(RequestMessage requestMessage)
|
||||
private IResponseMessage RequestGet(IRequestMessage requestMessage)
|
||||
{
|
||||
Guid guid = ParseGuidFromRequestMessage(requestMessage);
|
||||
var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
|
||||
@@ -591,7 +590,7 @@ public partial class WireMockServer
|
||||
return ToJson(model);
|
||||
}
|
||||
|
||||
private ResponseMessage RequestDelete(RequestMessage requestMessage)
|
||||
private IResponseMessage RequestDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
Guid guid = ParseGuidFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -605,7 +604,7 @@ public partial class WireMockServer
|
||||
#endregion Request/{guid}
|
||||
|
||||
#region Requests
|
||||
private ResponseMessage RequestsGet(RequestMessage requestMessage)
|
||||
private IResponseMessage RequestsGet(IRequestMessage requestMessage)
|
||||
{
|
||||
var result = LogEntries
|
||||
.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
|
||||
@@ -614,7 +613,7 @@ public partial class WireMockServer
|
||||
return ToJson(result);
|
||||
}
|
||||
|
||||
private ResponseMessage RequestsDelete(RequestMessage requestMessage)
|
||||
private IResponseMessage RequestsDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
ResetLogEntries();
|
||||
|
||||
@@ -623,7 +622,7 @@ public partial class WireMockServer
|
||||
#endregion Requests
|
||||
|
||||
#region Requests/find
|
||||
private ResponseMessage RequestsFind(RequestMessage requestMessage)
|
||||
private IResponseMessage RequestsFind(IRequestMessage requestMessage)
|
||||
{
|
||||
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
||||
|
||||
@@ -646,7 +645,7 @@ public partial class WireMockServer
|
||||
#endregion Requests/find
|
||||
|
||||
#region Scenarios
|
||||
private ResponseMessage ScenariosGet(RequestMessage requestMessage)
|
||||
private IResponseMessage ScenariosGet(IRequestMessage requestMessage)
|
||||
{
|
||||
var scenariosStates = Scenarios.Values.Select(s => new ScenarioStateModel
|
||||
{
|
||||
@@ -660,7 +659,7 @@ public partial class WireMockServer
|
||||
return ToJson(scenariosStates, true);
|
||||
}
|
||||
|
||||
private ResponseMessage ScenariosReset(RequestMessage requestMessage)
|
||||
private IResponseMessage ScenariosReset(IRequestMessage requestMessage)
|
||||
{
|
||||
ResetScenarios();
|
||||
|
||||
@@ -668,7 +667,29 @@ public partial class WireMockServer
|
||||
}
|
||||
#endregion
|
||||
|
||||
private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
|
||||
/// <summary>
|
||||
/// This stores details about the consumer of the interaction.
|
||||
/// </summary>
|
||||
/// <param name="consumer">the consumer</param>
|
||||
[PublicAPI]
|
||||
public WireMockServer WithConsumer(string consumer)
|
||||
{
|
||||
Consumer = consumer;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This stores details about the provider of the interaction.
|
||||
/// </summary>
|
||||
/// <param name="provider">the provider</param>
|
||||
[PublicAPI]
|
||||
public WireMockServer WithProvider(string provider)
|
||||
{
|
||||
Provider = provider;
|
||||
return this;
|
||||
}
|
||||
|
||||
private IRequestBuilder? InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
|
||||
{
|
||||
IRequestBuilder requestBuilder = Request.Create();
|
||||
|
||||
@@ -743,7 +764,7 @@ public partial class WireMockServer
|
||||
headerModel.Name,
|
||||
headerModel.IgnoreCase == true,
|
||||
headerModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
|
||||
headerModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -756,16 +777,16 @@ public partial class WireMockServer
|
||||
cookieModel.Name,
|
||||
cookieModel.IgnoreCase == true,
|
||||
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
cookieModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
if (requestModel.Params != null)
|
||||
{
|
||||
foreach (var paramModel in requestModel.Params.Where(p => p != null && p.Matchers != null))
|
||||
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
|
||||
{
|
||||
bool ignoreCase = paramModel.IgnoreCase == true;
|
||||
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,12 +918,12 @@ public partial class WireMockServer
|
||||
};
|
||||
}
|
||||
|
||||
private Encoding ToEncoding(EncodingModel encodingModel)
|
||||
private Encoding? ToEncoding(EncodingModel? encodingModel)
|
||||
{
|
||||
return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;
|
||||
}
|
||||
|
||||
private T DeserializeObject<T>(RequestMessage requestMessage)
|
||||
private T? DeserializeObject<T>(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
@@ -917,9 +938,9 @@ public partial class WireMockServer
|
||||
return default(T);
|
||||
}
|
||||
|
||||
private T[] DeserializeRequestMessageToArray<T>(RequestMessage requestMessage)
|
||||
private T[] DeserializeRequestMessageToArray<T>(IRequestMessage requestMessage)
|
||||
{
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
var bodyAsJson = requestMessage.BodyData.BodyAsJson;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace WireMock.Server
|
||||
private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII };
|
||||
|
||||
#region Files/{filename}
|
||||
private ResponseMessage FilePost(RequestMessage requestMessage)
|
||||
private IResponseMessage FilePost(IRequestMessage requestMessage)
|
||||
{
|
||||
string filename = GetFileNameFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace WireMock.Server
|
||||
return ResponseMessageBuilder.Create("File created");
|
||||
}
|
||||
|
||||
private ResponseMessage FilePut(RequestMessage requestMessage)
|
||||
private IResponseMessage FilePut(IRequestMessage requestMessage)
|
||||
{
|
||||
string filename = GetFileNameFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace WireMock.Server
|
||||
return ResponseMessageBuilder.Create("File updated");
|
||||
}
|
||||
|
||||
private ResponseMessage FileGet(RequestMessage requestMessage)
|
||||
private IResponseMessage FileGet(IRequestMessage requestMessage)
|
||||
{
|
||||
string filename = GetFileNameFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace WireMock.Server
|
||||
/// Note: Response is returned with no body as a head request doesn't accept a body, only the status code.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
private ResponseMessage FileHead(RequestMessage requestMessage)
|
||||
private IResponseMessage FileHead(IRequestMessage requestMessage)
|
||||
{
|
||||
string filename = GetFileNameFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace WireMock.Server
|
||||
return ResponseMessageBuilder.Create(204);
|
||||
}
|
||||
|
||||
private ResponseMessage FileDelete(RequestMessage requestMessage)
|
||||
private IResponseMessage FileDelete(IRequestMessage requestMessage)
|
||||
{
|
||||
string filename = GetFileNameFromRequestMessage(requestMessage);
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace WireMock.Server
|
||||
return ResponseMessageBuilder.Create("File deleted.");
|
||||
}
|
||||
|
||||
private string GetFileNameFromRequestMessage(RequestMessage requestMessage)
|
||||
private string GetFileNameFromRequestMessage(IRequestMessage requestMessage)
|
||||
{
|
||||
return Path.GetFileName(requestMessage.Path.Substring(AdminFiles.Length + 1));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace WireMock.Server
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the WireMock.org mapping json file.</param>
|
||||
[PublicAPI]
|
||||
public void ReadStaticWireMockOrgMappingAndAddOrUpdate([NotNull] string path)
|
||||
public void ReadStaticWireMockOrgMappingAndAddOrUpdate(string path)
|
||||
{
|
||||
Guard.NotNull(path, nameof(path));
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace WireMock.Server
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsPostWireMockOrg(RequestMessage requestMessage)
|
||||
private IResponseMessage MappingsPostWireMockOrg(IRequestMessage requestMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
167
src/WireMock.Net/Server/WireMockServer.Pact.cs
Normal file
167
src/WireMock.Net/Server/WireMockServer.Pact.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Pact.Models.V2;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Server;
|
||||
|
||||
public partial class WireMockServer
|
||||
{
|
||||
private const string DefaultPath = "/";
|
||||
private const string DefaultMethod = "GET";
|
||||
private const int DefaultStatus = 200;
|
||||
private const string DefaultConsumer = "Default Consumer";
|
||||
private const string DefaultProvider = "Default Provider";
|
||||
|
||||
/// <summary>
|
||||
/// Save the mappings as a Pact Json file V2.
|
||||
/// </summary>
|
||||
/// <param name="folder">The folder to save the pact file.</param>
|
||||
/// <param name="filename">The filename for the .json file [optional].</param>
|
||||
public void SavePact(string folder, string? filename = null)
|
||||
{
|
||||
var consumer = Consumer ?? DefaultConsumer;
|
||||
var provider = Provider ?? DefaultProvider;
|
||||
|
||||
filename ??= $"{consumer} - {provider}.json";
|
||||
|
||||
var pact = new Pact.Models.V2.Pact
|
||||
{
|
||||
Consumer = new Pacticipant { Name = consumer },
|
||||
Provider = new Pacticipant { Name = provider }
|
||||
};
|
||||
|
||||
foreach (var mapping in MappingModels)
|
||||
{
|
||||
var interaction = new Interaction
|
||||
{
|
||||
Description = mapping.Description,
|
||||
ProviderState = mapping.Title,
|
||||
Request = MapRequest(mapping.Request),
|
||||
Response = MapResponse(mapping.Response)
|
||||
};
|
||||
|
||||
pact.Interactions.Add(interaction);
|
||||
}
|
||||
|
||||
var bytes = JsonUtils.SerializeAsPactFile(pact);
|
||||
_settings.FileSystemHandler.WriteFile(folder, filename, bytes);
|
||||
}
|
||||
|
||||
private static Request MapRequest(RequestModel request)
|
||||
{
|
||||
string path;
|
||||
switch (request.Path)
|
||||
{
|
||||
case string pathAsString:
|
||||
path = pathAsString;
|
||||
break;
|
||||
|
||||
case PathModel pathModel:
|
||||
path = GetPatternAsStringFromMatchers(pathModel.Matchers, DefaultPath);
|
||||
break;
|
||||
|
||||
default:
|
||||
path = DefaultPath;
|
||||
break;
|
||||
}
|
||||
|
||||
return new Request
|
||||
{
|
||||
Method = request.Methods?.FirstOrDefault() ?? DefaultMethod,
|
||||
Path = path,
|
||||
Query = MapQueryParameters(request.Params),
|
||||
Headers = MapRequestHeaders(request.Headers),
|
||||
Body = MapBody(request.Body)
|
||||
};
|
||||
}
|
||||
|
||||
private static Response MapResponse(ResponseModel? response)
|
||||
{
|
||||
if (response == null)
|
||||
{
|
||||
return new Response();
|
||||
}
|
||||
|
||||
return new Response
|
||||
{
|
||||
Status = MapStatusCode(response.StatusCode),
|
||||
Headers = MapResponseHeaders(response.Headers),
|
||||
Body = response.BodyAsJson
|
||||
};
|
||||
}
|
||||
|
||||
private static int MapStatusCode(object? statusCode)
|
||||
{
|
||||
if (statusCode is string statusCodeAsString)
|
||||
{
|
||||
return int.TryParse(statusCodeAsString, out var statusCodeAsInt) ? statusCodeAsInt : DefaultStatus;
|
||||
}
|
||||
|
||||
if (statusCode != null)
|
||||
{
|
||||
// Convert to Int32 because Newtonsoft deserializes an 'object' with a number value to a long.
|
||||
return Convert.ToInt32(statusCode);
|
||||
}
|
||||
|
||||
return DefaultStatus;
|
||||
}
|
||||
|
||||
private static string? MapQueryParameters(IList<ParamModel>? queryParameters)
|
||||
{
|
||||
if (queryParameters == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var values = queryParameters
|
||||
.Where(qp => qp.Matchers != null && qp.Matchers.Any() && qp.Matchers[0].Pattern is string)
|
||||
.Select(param => $"{Uri.EscapeDataString(param.Name)}={Uri.EscapeDataString((string)param.Matchers![0].Pattern)}");
|
||||
|
||||
return string.Join("&", values);
|
||||
}
|
||||
|
||||
private static IDictionary<string, string>? MapRequestHeaders(IList<HeaderModel>? headers)
|
||||
{
|
||||
if (headers == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var validHeaders = headers.Where(h => h.Matchers != null && h.Matchers.Any() && h.Matchers[0].Pattern is string);
|
||||
return validHeaders.ToDictionary(x => x.Name, y => (string)y.Matchers![0].Pattern);
|
||||
}
|
||||
|
||||
private static IDictionary<string, string>? MapResponseHeaders(IDictionary<string, object>? headers)
|
||||
{
|
||||
if (headers == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var validHeaders = headers.Where(h => h.Value is string);
|
||||
return validHeaders.ToDictionary(x => x.Key, y => (string)y.Value);
|
||||
}
|
||||
|
||||
private static object? MapBody(BodyModel? body)
|
||||
{
|
||||
if (body == null || body.Matcher.Name != "JsonMatcher")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return body.Matcher.Pattern;
|
||||
}
|
||||
|
||||
private static string GetPatternAsStringFromMatchers(MatcherModel[]? matchers, string defaultValue)
|
||||
{
|
||||
if (matchers != null && matchers.Any() && matchers[0].Pattern is string patternAsString)
|
||||
{
|
||||
return patternAsString;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
private const int ServerStartDelayInMs = 100;
|
||||
|
||||
private readonly WireMockServerSettings _settings;
|
||||
private readonly IOwinSelfHost _httpServer;
|
||||
private readonly IOwinSelfHost? _httpServer;
|
||||
private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
|
||||
private readonly MappingConverter _mappingConverter;
|
||||
private readonly MatcherMapper _matcherMapper;
|
||||
@@ -38,7 +38,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.IsStarted" />
|
||||
[PublicAPI]
|
||||
public bool IsStarted => _httpServer != null && _httpServer.IsStarted;
|
||||
public bool IsStarted => _httpServer is { IsStarted: true };
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
@@ -54,7 +54,15 @@ public partial class WireMockServer : IWireMockServer
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public string Url => Urls?.FirstOrDefault();
|
||||
public string? Url => Urls?.FirstOrDefault();
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public string? Consumer { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public string? Provider { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mappings.
|
||||
@@ -100,9 +108,9 @@ public partial class WireMockServer : IWireMockServer
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <returns>The <see cref="WireMockServer"/>.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start([NotNull] WireMockServerSettings settings)
|
||||
public static WireMockServer Start(WireMockServerSettings settings)
|
||||
{
|
||||
Guard.NotNull(settings, nameof(settings));
|
||||
Guard.NotNull(settings);
|
||||
|
||||
return new WireMockServer(settings);
|
||||
}
|
||||
@@ -114,7 +122,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
/// <param name="ssl">The SSL support.</param>
|
||||
/// <returns>The <see cref="WireMockServer"/>.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
|
||||
public static WireMockServer Start(int? port = 0, bool ssl = false)
|
||||
{
|
||||
return new WireMockServer(new WireMockServerSettings
|
||||
{
|
||||
@@ -239,7 +247,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
|
||||
if (settings.CustomCertificateDefined)
|
||||
{
|
||||
_options.X509StoreName = settings.CertificateSettings.X509StoreName;
|
||||
_options.X509StoreName = settings.CertificateSettings!.X509StoreName;
|
||||
_options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation;
|
||||
_options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName;
|
||||
_options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath;
|
||||
@@ -308,7 +316,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
Given(Request.Create().WithPath("/*").UsingAnyMethod())
|
||||
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
|
||||
.AtPriority(1000)
|
||||
.RespondWith(new DynamicResponseProvider(request => ResponseMessageBuilder.Create("No matching mapping found", 404)));
|
||||
.RespondWith(new DynamicResponseProvider(_ => ResponseMessageBuilder.Create("No matching mapping found", 404)));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.Reset" />
|
||||
@@ -373,7 +381,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
Guard.NotNull(audience, nameof(audience));
|
||||
|
||||
#if NETSTANDARD1_3
|
||||
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
|
||||
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
|
||||
#else
|
||||
_options.AuthenticationMatcher = new AzureADAuthenticationMatcher(tenant, audience);
|
||||
#endif
|
||||
@@ -381,7 +389,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication(string, string)" />
|
||||
[PublicAPI]
|
||||
public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
|
||||
public void SetBasicAuthentication(string username, string password)
|
||||
{
|
||||
Guard.NotNull(username, nameof(username));
|
||||
Guard.NotNull(password, nameof(password));
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
namespace WireMock.Settings
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// HttpClientSettings
|
||||
/// </summary>
|
||||
public class HttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// HttpClientSettings
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
public class HttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
public string? ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
public WebProxySettings WebProxySettings { get; set; }
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
public WebProxySettings? WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
@@ -15,31 +15,31 @@ namespace WireMock.Settings
|
||||
/// X509 StoreName (AddressBook, AuthRoot, CertificateAuthority, My, Root, TrustedPeople or TrustedPublisher)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string X509StoreName { get; set; }
|
||||
public string? X509StoreName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509 StoreLocation (CurrentUser or LocalMachine)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string X509StoreLocation { get; set; }
|
||||
public string? X509StoreLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509 Thumbprint or SubjectName (if not defined, the 'host' is used)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string X509StoreThumbprintOrSubjectName { get; set; }
|
||||
public string? X509StoreThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509Certificate FilePath
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string X509CertificateFilePath { get; set; }
|
||||
public string? X509CertificateFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509Certificate Password
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string X509CertificatePassword { get; set; }
|
||||
public string? X509CertificatePassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509StoreName and X509StoreLocation should be defined
|
||||
|
||||
@@ -62,13 +62,13 @@ namespace WireMock.Settings
|
||||
/// Gets or sets if the proxy and record settings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
||||
public ProxyAndRecordSettings? ProxyAndRecordSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the urls.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string[] Urls { get; set; }
|
||||
public string[]? Urls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StartTimeout
|
||||
@@ -86,25 +86,25 @@ namespace WireMock.Settings
|
||||
/// The username needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string AdminUsername { get; set; }
|
||||
public string? AdminUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The password needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string AdminPassword { get; set; }
|
||||
public string? AdminPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AzureAD Tenant needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string AdminAzureADTenant { get; set; }
|
||||
public string? AdminAzureADTenant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AzureAD Audience / Resource for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string AdminAzureADAudience { get; set; }
|
||||
public string? AdminAzureADAudience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The RequestLog expiration in hours (optional).
|
||||
@@ -123,14 +123,14 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<object> PreWireMockMiddlewareInit { get; set; }
|
||||
public Action<object>? PreWireMockMiddlewareInit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<object> PostWireMockMiddlewareInit { get; set; }
|
||||
public Action<object>? PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <summary>
|
||||
@@ -138,7 +138,7 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
public Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Policies to use when using CORS. By default CORS is disabled. [Optional]
|
||||
@@ -152,21 +152,21 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IWireMockLogger Logger { get; set; }
|
||||
public IWireMockLogger Logger { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IFileSystemHandler FileSystemHandler { get; set; }
|
||||
public IFileSystemHandler FileSystemHandler { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Action which can be used to add additional Handlebars registrations. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IHandlebars, IFileSystemHandler> HandlebarsRegistrationCallback { get; set; }
|
||||
public Action<IHandlebars, IFileSystemHandler>? HandlebarsRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
@@ -220,7 +220,7 @@ namespace WireMock.Settings
|
||||
/// X509CertificateFilePath and X509CertificatePassword should be defined
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public WireMockCertificateSettings CertificateSettings { get; set; }
|
||||
public WireMockCertificateSettings? CertificateSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if custom CertificateSettings are defined
|
||||
@@ -232,7 +232,7 @@ namespace WireMock.Settings
|
||||
/// Defines the global IWebhookSettings to use.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public WebhookSettings WebhookSettings { get; set; }
|
||||
public WebhookSettings? WebhookSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use the <see cref="RegexExtended"/> instead of the default <see cref="Regex"/> (default set to true).
|
||||
@@ -250,6 +250,6 @@ namespace WireMock.Settings
|
||||
/// Custom matcher mappings for static mappings
|
||||
/// </summary>
|
||||
[PublicAPI, JsonIgnore]
|
||||
public IDictionary<string, Func<MatcherModel, IMatcher>> CustomMatcherMappings { get; set; }
|
||||
public IDictionary<string, Func<MatcherModel, IMatcher>>? CustomMatcherMappings { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ namespace WireMock.Transformers
|
||||
{
|
||||
interface ITransformer
|
||||
{
|
||||
ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile, ReplaceNodeOptions options);
|
||||
ResponseMessage Transform(IRequestMessage requestMessage, IResponseMessage original, bool useTransformerForBodyAsFile, ReplaceNodeOptions options);
|
||||
|
||||
(IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(RequestMessage originalRequestMessage, ResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers, ReplaceNodeOptions options);
|
||||
(IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(IRequestMessage originalRequestMessage, IResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers, ReplaceNodeOptions options);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace WireMock.Transformers
|
||||
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
|
||||
}
|
||||
|
||||
public (IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(RequestMessage originalRequestMessage, ResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers, ReplaceNodeOptions options)
|
||||
public (IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(IRequestMessage originalRequestMessage, IResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers, ReplaceNodeOptions options)
|
||||
{
|
||||
var transformerContext = _factory.Create();
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace WireMock.Transformers
|
||||
return (newBodyData, TransformHeaders(transformerContext, model, headers));
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile, ReplaceNodeOptions options)
|
||||
public ResponseMessage Transform(IRequestMessage requestMessage, IResponseMessage original, bool useTransformerForBodyAsFile, ReplaceNodeOptions options)
|
||||
{
|
||||
var transformerContext = _factory.Create();
|
||||
|
||||
|
||||
@@ -1,213 +1,220 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Pact.Models.V2;
|
||||
using WireMock.Serialization;
|
||||
|
||||
namespace WireMock.Util
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal static class JsonUtils
|
||||
{
|
||||
internal static class JsonUtils
|
||||
public static bool TryParseAsComplexObject(string strInput, [NotNullWhen(true)] out JToken? token)
|
||||
{
|
||||
public static bool TryParseAsComplexObject(string strInput, out JToken token)
|
||||
token = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(strInput))
|
||||
{
|
||||
token = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(strInput))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
strInput = strInput.Trim();
|
||||
if ((!strInput.StartsWith("{") || !strInput.EndsWith("}")) && (!strInput.StartsWith("[") || !strInput.EndsWith("]")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a JToken
|
||||
token = JToken.Parse(strInput);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T value)
|
||||
strInput = strInput.Trim();
|
||||
if ((!strInput.StartsWith("{") || !strInput.EndsWith("}")) && (!strInput.StartsWith("[") || !strInput.EndsWith("]")))
|
||||
{
|
||||
return JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsIncludeNullValues);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a Newtonsoft.Json.Linq.JObject from a string that contains JSON.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>A Newtonsoft.Json.Linq.JToken populated from the string that contains JSON.</returns>
|
||||
public static JToken Parse(string json)
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<JToken>(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
// Try to convert this string into a JToken
|
||||
token = JToken.Parse(strInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to a .NET object.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
public static object DeserializeObject(string json)
|
||||
catch
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to the specified .NET type.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
public static T DeserializeObject<T>(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
}
|
||||
|
||||
public static T ParseJTokenToObject<T>(object value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case JToken tokenValue:
|
||||
return tokenValue.ToObject<T>();
|
||||
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerateDynamicLinqStatement(JToken jsonObject)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
WalkNode(jsonObject, null, null, lines);
|
||||
|
||||
return lines.First();
|
||||
}
|
||||
|
||||
private static void WalkNode(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
ProcessObject(node, propertyName, lines);
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
ProcessArray(node, propertyName, lines);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessItem(node, path ?? "it", propertyName, lines);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessObject(JToken node, string propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("new (");
|
||||
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(child.Value, child.Path, child.Name, items);
|
||||
}
|
||||
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append(")");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessArray(JToken node, string propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("(new [] { ");
|
||||
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
int idx = 0;
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(child, $"{node.Path}[{idx}]", null, items);
|
||||
idx++;
|
||||
}
|
||||
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append("})");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessItem(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
string castText;
|
||||
switch (node.Type)
|
||||
{
|
||||
case JTokenType.Boolean:
|
||||
castText = $"bool({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Date:
|
||||
castText = $"DateTime({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Float:
|
||||
castText = $"double({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Guid:
|
||||
castText = $"Guid({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Integer:
|
||||
castText = $"long({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Null:
|
||||
castText = "null";
|
||||
break;
|
||||
|
||||
case JTokenType.String:
|
||||
castText = $"string({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.TimeSpan:
|
||||
castText = $"TimeSpan({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Uri:
|
||||
castText = $"Uri({path})";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
castText += $" as {propertyName}";
|
||||
}
|
||||
|
||||
lines.Add(castText);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Serialize(object value)
|
||||
{
|
||||
return JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsIncludeNullValues);
|
||||
}
|
||||
|
||||
public static byte[] SerializeAsPactFile(object value)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsPact);
|
||||
return Encoding.UTF8.GetBytes(json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a Newtonsoft.Json.Linq.JObject from a string that contains JSON.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>A Newtonsoft.Json.Linq.JToken populated from the string that contains JSON.</returns>
|
||||
public static JToken Parse(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<JToken>(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to a .NET object.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
public static object DeserializeObject(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to the specified .NET type.
|
||||
/// Using : DateParseHandling = DateParseHandling.None
|
||||
/// </summary>
|
||||
/// <param name="json">A System.String that contains JSON.</param>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
public static T DeserializeObject<T>(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone);
|
||||
}
|
||||
|
||||
public static T ParseJTokenToObject<T>(object value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case JToken tokenValue:
|
||||
return tokenValue.ToObject<T>();
|
||||
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerateDynamicLinqStatement(JToken jsonObject)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
WalkNode(jsonObject, null, null, lines);
|
||||
|
||||
return lines.First();
|
||||
}
|
||||
|
||||
private static void WalkNode(JToken node, string? path, string? propertyName, List<string> lines)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
ProcessObject(node, propertyName, lines);
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
ProcessArray(node, propertyName, lines);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessItem(node, path ?? "it", propertyName, lines);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessObject(JToken node, string? propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("new (");
|
||||
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(child.Value, child.Path, child.Name, items);
|
||||
}
|
||||
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append(")");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessArray(JToken node, string? propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("(new [] { ");
|
||||
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
int idx = 0;
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(child, $"{node.Path}[{idx}]", null, items);
|
||||
idx++;
|
||||
}
|
||||
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append("})");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessItem(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
string castText;
|
||||
switch (node.Type)
|
||||
{
|
||||
case JTokenType.Boolean:
|
||||
castText = $"bool({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Date:
|
||||
castText = $"DateTime({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Float:
|
||||
castText = $"double({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Guid:
|
||||
castText = $"Guid({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Integer:
|
||||
castText = $"long({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Null:
|
||||
castText = "null";
|
||||
break;
|
||||
|
||||
case JTokenType.String:
|
||||
castText = $"string({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.TimeSpan:
|
||||
castText = $"TimeSpan({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Uri:
|
||||
castText = $"Uri({path})";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
castText += $" as {propertyName}";
|
||||
}
|
||||
|
||||
lines.Add(castText);
|
||||
}
|
||||
}
|
||||
@@ -2,29 +2,28 @@ using Nelibur.ObjectMapper;
|
||||
using WireMock.Admin.Settings;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Util
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal sealed class TinyMapperUtils
|
||||
{
|
||||
internal sealed class TinyMapperUtils
|
||||
public static TinyMapperUtils Instance { get; } = new();
|
||||
|
||||
private TinyMapperUtils()
|
||||
{
|
||||
public static TinyMapperUtils Instance { get; } = new TinyMapperUtils();
|
||||
TinyMapper.Bind<ProxyAndRecordSettings, ProxyAndRecordSettingsModel>();
|
||||
TinyMapper.Bind<WebProxySettings, WebProxySettingsModel>();
|
||||
|
||||
private TinyMapperUtils()
|
||||
{
|
||||
TinyMapper.Bind<ProxyAndRecordSettings, ProxyAndRecordSettingsModel>();
|
||||
TinyMapper.Bind<WebProxySettings, WebProxySettingsModel>();
|
||||
TinyMapper.Bind<ProxyAndRecordSettingsModel, ProxyAndRecordSettings>();
|
||||
TinyMapper.Bind<WebProxySettingsModel, WebProxySettings>();
|
||||
}
|
||||
|
||||
TinyMapper.Bind<ProxyAndRecordSettingsModel, ProxyAndRecordSettings>();
|
||||
TinyMapper.Bind<WebProxySettingsModel, WebProxySettings>();
|
||||
}
|
||||
public ProxyAndRecordSettingsModel? Map(ProxyAndRecordSettings? instance)
|
||||
{
|
||||
return instance == null ? null : TinyMapper.Map<ProxyAndRecordSettingsModel>(instance);
|
||||
}
|
||||
|
||||
public ProxyAndRecordSettingsModel Map(ProxyAndRecordSettings instance)
|
||||
{
|
||||
return instance == null ? null : TinyMapper.Map<ProxyAndRecordSettingsModel>(instance);
|
||||
}
|
||||
|
||||
public ProxyAndRecordSettings Map(ProxyAndRecordSettingsModel model)
|
||||
{
|
||||
return model == null ? null : TinyMapper.Map<ProxyAndRecordSettings>(model);
|
||||
}
|
||||
public ProxyAndRecordSettings? Map(ProxyAndRecordSettingsModel? model)
|
||||
{
|
||||
return model == null ? null : TinyMapper.Map<ProxyAndRecordSettings>(model);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Util\FileSystemWatcherExtensions.cs" />
|
||||
<Compile Remove="Matchers\Request\IRequestMatcher.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -88,6 +89,7 @@
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
|
||||
<!--<PackageReference Include="Mapster" Version="7.2.0" />-->
|
||||
<PackageReference Include="Nullable" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
@@ -98,11 +100,13 @@
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
|
||||
<PackageReference Include="Nullable" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
|
||||
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
<PackageReference Include="Nullable" Version="1.3.0" />
|
||||
|
||||
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/697 -->
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="4.7.2" />
|
||||
@@ -112,17 +116,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<PackageReference Include="System.Collections.Specialized" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="1.1.3" />
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
|
||||
<PackageReference Include="Nullable" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<PackageReference Include="Scriban.Signed" Version="3.3.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
<PackageReference Include="Nullable" Version="1.3.0" />
|
||||
|
||||
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/507 -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
|
||||
@@ -133,6 +140,12 @@
|
||||
<PackageReference Include="Scriban.Signed" Version="3.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Server\WireMockServer.*.cs">
|
||||
<DependentUpon>WireMockServer.cs</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.3.3" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.3.3" />
|
||||
|
||||
Reference in New Issue
Block a user