mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-25 19:02:24 +01:00
Fix MimePartMatcher and add more tests (#1389)
* mp * . * --return * Fixed * -- * ... * fix * ... * .
This commit is contained in:
@@ -54,7 +54,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
return MatchResult.From(Name);
|
||||
}
|
||||
|
||||
var token = Regex.Replace(input, BearerPrefix, string.Empty, RegexOptions.IgnoreCase, RegexConstants.DefaultTimeout);
|
||||
@@ -83,11 +83,11 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
|
||||
// Throws an Exception as the token is invalid (expired, invalid-formatted, tenant mismatch, etc.)
|
||||
_jwtSecurityTokenHandler.ValidateToken(token, validationParameters, out _);
|
||||
|
||||
return MatchScores.Perfect;
|
||||
return MatchResult.From(Name, MatchScores.Perfect);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MatchResult(MatchScores.Mismatch, ex);
|
||||
return MatchResult.From(Name, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class WireMockConsoleLogger : IWireMockLogger
|
||||
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
|
||||
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
|
||||
{
|
||||
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
|
||||
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
Console.WriteLine(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
|
||||
}
|
||||
|
||||
|
||||
46
src/WireMock.Net.Minimal/Matchers/CompositeMatcher.cs
Normal file
46
src/WireMock.Net.Minimal/Matchers/CompositeMatcher.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a matcher that combines multiple matching strategies into a single composite operation.
|
||||
/// </summary>
|
||||
public class CompositeMatcher : IMatcher
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(CompositeMatcher);
|
||||
|
||||
/// <summary>
|
||||
/// The logical operator used to combine the results of the matchers.
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// All matchers.
|
||||
/// </summary>
|
||||
public IMatcher[] Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CompositeMatcher class with the specified matchers, operator, and match behaviour.
|
||||
/// </summary>
|
||||
/// <param name="matchers">An array of matchers to be combined. Cannot be null or contain null elements.</param>
|
||||
/// <param name="matchOperator">The logical operator used to combine the results of the matchers.</param>
|
||||
/// <param name="matchBehaviour">The behaviour that determines how the composite matcher interprets the combined results.</param>
|
||||
public CompositeMatcher(IMatcher[] matchers, MatchOperator matchOperator, MatchBehaviour matchBehaviour)
|
||||
{
|
||||
Matchers = matchers;
|
||||
MatchOperator = matchOperator;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
{
|
||||
if (string.IsNullOrEmpty(input) || !MediaTypeHeaderValue.TryParse(input, out var contentType))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
|
||||
return base.IsMatch(contentType.MediaType);
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
: pattern => pattern == input;
|
||||
|
||||
var score = MatchScores.ToScore(_values.Select(v => equals(v)).ToArray(), MatchOperator);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -106,18 +106,18 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
// Input is null or empty and if no patterns defined, return Perfect match.
|
||||
if (string.IsNullOrEmpty(input) && _patterns.Length == 0)
|
||||
{
|
||||
return new MatchResult(MatchScores.Perfect);
|
||||
return MatchResult.From(Name, MatchScores.Perfect);
|
||||
}
|
||||
|
||||
if (!QueryStringParser.TryParse(input, IgnoreCase, out var inputNameValueCollection))
|
||||
{
|
||||
return new MatchResult(MatchScores.Mismatch);
|
||||
return MatchResult.From(Name, MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
var matches = GetMatches(inputNameValueCollection);
|
||||
|
||||
var score = MatchScores.ToScore(matches, MatchOperator);
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
private bool[] GetMatches(IDictionary<string, string> inputNameValueCollection)
|
||||
|
||||
@@ -80,7 +80,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
}
|
||||
}
|
||||
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -104,7 +104,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
}
|
||||
}
|
||||
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -87,7 +87,7 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
}
|
||||
}
|
||||
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -102,7 +102,7 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
return IsMatch(inputAsString);
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -96,7 +96,7 @@ public class JsonMatcher : IJsonMatcher
|
||||
}
|
||||
}
|
||||
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -24,14 +24,26 @@ public class RequestMatchResult : IRequestMatchResult
|
||||
public double AverageTotalScore => TotalNumber == 0 ? MatchScores.Mismatch : TotalScore / TotalNumber;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<MatchDetail> MatchDetails { get; } = new List<MatchDetail>();
|
||||
public IList<MatchDetail> MatchDetails { get; } = [];
|
||||
|
||||
/// <inheritdoc />
|
||||
public double AddScore(Type matcherType, double score, Exception? exception)
|
||||
{
|
||||
MatchDetails.Add(new MatchDetail { MatcherType = matcherType, Score = score, Exception = exception });
|
||||
return AddMatchDetail(new MatchDetail
|
||||
{
|
||||
Name = matcherType.Name.Replace("RequestMessage", string.Empty),
|
||||
MatcherType = matcherType,
|
||||
Score = score,
|
||||
Exception = exception
|
||||
});
|
||||
}
|
||||
|
||||
return score;
|
||||
/// <inheritdoc />
|
||||
public double AddMatchDetail(MatchDetail matchDetail)
|
||||
{
|
||||
MatchDetails.Add(matchDetail);
|
||||
|
||||
return matchDetail.Score;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -17,27 +17,27 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <summary>
|
||||
/// The body function
|
||||
/// </summary>
|
||||
public Func<string?, bool>? Func { get; }
|
||||
public Func<string?, bool>? MatchOnBodyAsStringFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for byte[]
|
||||
/// </summary>
|
||||
public Func<byte[]?, bool>? DataFunc { get; }
|
||||
public Func<byte[]?, bool>? MatchOnBodyAsBytesFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for json
|
||||
/// </summary>
|
||||
public Func<object?, bool>? JsonFunc { get; }
|
||||
public Func<object?, bool>? MatchOnBodyAsJsonFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for BodyData
|
||||
/// </summary>
|
||||
public Func<IBodyData?, bool>? BodyDataFunc { get; }
|
||||
public Func<IBodyData?, bool>? MatchOnBodyAsBodyDataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for FormUrlEncoded
|
||||
/// </summary>
|
||||
public Func<IDictionary<string, string>?, bool>? FormUrlEncodedFunc { get; }
|
||||
public Func<IDictionary<string, string>?, bool>? MatchOnBodyAsFormUrlEncodedFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
@@ -85,7 +85,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<string?, bool> func)
|
||||
{
|
||||
Func = Guard.NotNull(func);
|
||||
MatchOnBodyAsStringFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -94,7 +94,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<byte[]?, bool> func)
|
||||
{
|
||||
DataFunc = Guard.NotNull(func);
|
||||
MatchOnBodyAsBytesFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,7 +103,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<object?, bool> func)
|
||||
{
|
||||
JsonFunc = Guard.NotNull(func);
|
||||
MatchOnBodyAsJsonFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -112,7 +112,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<IBodyData?, bool> func)
|
||||
{
|
||||
BodyDataFunc = Guard.NotNull(func);
|
||||
MatchOnBodyAsBodyDataFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,7 +121,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<IDictionary<string, string>?, bool> func)
|
||||
{
|
||||
FormUrlEncodedFunc = Guard.NotNull(func);
|
||||
MatchOnBodyAsFormUrlEncodedFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -147,43 +147,43 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var (score, exception) = CalculateMatchScore(requestMessage).Expand();
|
||||
var (score, exception) = CalculateMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private MatchResult CalculateMatchScore(IRequestMessage requestMessage)
|
||||
private MatchResult CalculateMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
var results = Matchers.Select(matcher => BodyDataMatchScoreCalculator.CalculateMatchScore(requestMessage.BodyData, matcher)).ToArray();
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
return MatchResult.From(nameof(RequestMessageBodyMatcher), results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
if (MatchOnBodyAsStringFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage.BodyData?.BodyAsString));
|
||||
return MatchResult.From($"{nameof(RequestMessageBodyMatcher)}:{nameof(MatchOnBodyAsStringFunc)}", MatchScores.ToScore(MatchOnBodyAsStringFunc(requestMessage.BodyData?.BodyAsString)));
|
||||
}
|
||||
|
||||
if (FormUrlEncodedFunc != null)
|
||||
if (MatchOnBodyAsFormUrlEncodedFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(FormUrlEncodedFunc(requestMessage.BodyData?.BodyAsFormUrlEncoded));
|
||||
return MatchResult.From($"{nameof(RequestMessageBodyMatcher)}:{nameof(MatchOnBodyAsFormUrlEncodedFunc)}", MatchScores.ToScore(MatchOnBodyAsFormUrlEncodedFunc(requestMessage.BodyData?.BodyAsFormUrlEncoded)));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
if (MatchOnBodyAsJsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(JsonFunc(requestMessage.BodyData?.BodyAsJson));
|
||||
return MatchResult.From($"{nameof(RequestMessageBodyMatcher)}:{nameof(MatchOnBodyAsJsonFunc)}", MatchScores.ToScore(MatchOnBodyAsJsonFunc(requestMessage.BodyData?.BodyAsJson)));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
if (MatchOnBodyAsBytesFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(DataFunc(requestMessage.BodyData?.BodyAsBytes));
|
||||
return MatchResult.From($"{nameof(RequestMessageBodyMatcher)}:{nameof(MatchOnBodyAsBytesFunc)}", MatchScores.ToScore(MatchOnBodyAsBytesFunc(requestMessage.BodyData?.BodyAsBytes)));
|
||||
}
|
||||
|
||||
if (BodyDataFunc != null)
|
||||
if (MatchOnBodyAsBodyDataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(BodyDataFunc(requestMessage.BodyData));
|
||||
return MatchResult.From($"{nameof(RequestMessageBodyMatcher)}:{nameof(MatchOnBodyAsBodyDataFunc)}", MatchScores.ToScore(MatchOnBodyAsBodyDataFunc(requestMessage.BodyData)));
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(nameof(RequestMessageBodyMatcher));
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher<T> : IRequestMatcher
|
||||
{
|
||||
private const string _name = nameof(RequestMessageBodyMatcher<T>);
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for type T
|
||||
/// </summary>
|
||||
@@ -46,15 +48,15 @@ public class RequestMessageBodyMatcher<T> : IRequestMatcher
|
||||
try
|
||||
{
|
||||
var bodyAsT = jsonObject.ToObject<T>();
|
||||
return MatchScores.ToScore(Func(bodyAsT));
|
||||
return MatchResult.From(_name, MatchScores.ToScore(Func(bodyAsT)));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MatchResult(ex);
|
||||
return MatchResult.From(_name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
{
|
||||
private const string _name = nameof(RequestMessageClientIPMatcher);
|
||||
|
||||
/// <summary>
|
||||
/// The matchers
|
||||
/// </summary>
|
||||
@@ -77,8 +79,8 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
var matchDetail = GetMatchResult(requestMessage).ToMatchDetail();
|
||||
return requestMatchResult.AddMatchDetail(matchDetail);
|
||||
}
|
||||
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
@@ -86,15 +88,15 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.ClientIP)).ToArray();
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
return MatchResult.From(_name, results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
var results = Funcs.Select(func => func(requestMessage.ClientIP)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(_name, MatchScores.ToScore(results, MatchOperator));
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ namespace WireMock.Matchers.Request;
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
{
|
||||
private const string _name = nameof(RequestMessageCookieMatcher);
|
||||
|
||||
/// <summary>
|
||||
/// MatchBehaviour
|
||||
/// </summary>
|
||||
@@ -104,7 +106,7 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
{
|
||||
if (requestMessage.Cookies == null)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
|
||||
// Check if we want to use IgnoreCase to compare the Cookie-Name and Cookie-Value
|
||||
@@ -112,19 +114,19 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
return MatchScores.ToScore(Funcs.Any(f => f(cookies)));
|
||||
return MatchResult.From(_name, MatchScores.ToScore(Funcs.Any(f => f(cookies))));
|
||||
}
|
||||
|
||||
if (Matchers == null)
|
||||
{
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
|
||||
if (!cookies.ContainsKey(Name))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
|
||||
return Matchers.Max(m => m.IsMatch(cookies[Name]));
|
||||
return MatchResult.From(_name, Matchers.Max(m => m.IsMatch(cookies[Name]))?.Score ?? MatchScores.Mismatch);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ namespace WireMock.Matchers.Request;
|
||||
/// <inheritdoc cref="IRequestMatcher"/>
|
||||
public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
private const string _name = nameof(RequestMessageCookieMatcher);
|
||||
|
||||
/// <summary>
|
||||
/// MatchBehaviour
|
||||
/// </summary>
|
||||
@@ -117,7 +119,7 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
if (requestMessage.Headers == null)
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
|
||||
// Check if we want to use IgnoreCase to compare the Header-Name and Header-Value(s)
|
||||
@@ -126,14 +128,14 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
if (Funcs != null)
|
||||
{
|
||||
var funcResults = Funcs.Select(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))).ToArray();
|
||||
return MatchScores.ToScore(funcResults, MatchOperator);
|
||||
return MatchResult.From(_name, MatchScores.ToScore(funcResults, MatchOperator));
|
||||
}
|
||||
|
||||
if (Matchers != null)
|
||||
{
|
||||
if (!headers.ContainsKey(Name))
|
||||
{
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
|
||||
var results = new List<MatchResult>();
|
||||
@@ -141,12 +143,12 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
{
|
||||
var resultsPerMatcher = headers[Name].Select(matcher.IsMatch).ToArray();
|
||||
|
||||
results.Add(MatchResult.From(resultsPerMatcher, MatchOperator.And));
|
||||
results.Add(MatchResult.From(_name, resultsPerMatcher, MatchOperator.And));
|
||||
}
|
||||
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
return MatchResult.From(_name, results, MatchOperator);
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch);
|
||||
return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch));
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public class RequestMessageHttpVersionMatcher : IRequestMatcher
|
||||
{
|
||||
private const string _name = nameof(RequestMessageHttpVersionMatcher);
|
||||
|
||||
/// <summary>
|
||||
/// The matcher.
|
||||
/// </summary>
|
||||
@@ -19,7 +21,7 @@ public class RequestMessageHttpVersionMatcher : IRequestMatcher
|
||||
/// <summary>
|
||||
/// The func.
|
||||
/// </summary>
|
||||
public Func<string, bool>? Func { get; }
|
||||
public Func<string, bool>? MatcherOnStringFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchBehaviour"/>
|
||||
@@ -61,7 +63,7 @@ public class RequestMessageHttpVersionMatcher : IRequestMatcher
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageHttpVersionMatcher(Func<string, bool> func)
|
||||
{
|
||||
Func = Guard.NotNull(func);
|
||||
MatcherOnStringFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -78,11 +80,11 @@ public class RequestMessageHttpVersionMatcher : IRequestMatcher
|
||||
return Matcher.IsMatch(requestMessage.HttpVersion);
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
if (MatcherOnStringFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage.HttpVersion));
|
||||
return MatchResult.From($"{_name}:{nameof(MatcherOnStringFunc)}", MatchScores.ToScore(MatcherOnStringFunc(requestMessage.HttpVersion)));
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(_name);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,11 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this matcher.
|
||||
/// </summary>
|
||||
public const string Name = "MultiPartMatcher";
|
||||
|
||||
private readonly IMimeKitUtils _mimeKitUtils = LoadMimeKitUtils();
|
||||
|
||||
/// <summary>
|
||||
@@ -22,7 +27,7 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.And;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchBehaviour"/>
|
||||
@@ -54,19 +59,20 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var score = MatchScores.Mismatch;
|
||||
var matchDetail = MatchResult.From(Name).ToMatchDetail();
|
||||
Exception? exception = null;
|
||||
|
||||
if (Matchers?.Any() != true)
|
||||
if (Matchers == null)
|
||||
{
|
||||
return requestMatchResult.AddScore(GetType(), score, null);
|
||||
return requestMatchResult.AddMatchDetail(matchDetail);
|
||||
}
|
||||
|
||||
if (!_mimeKitUtils.TryGetMimeMessage(requestMessage, out var message))
|
||||
{
|
||||
return requestMatchResult.AddScore(GetType(), score, null);
|
||||
return requestMatchResult.AddMatchDetail(matchDetail);
|
||||
}
|
||||
|
||||
double score = MatchScores.Mismatch;
|
||||
try
|
||||
{
|
||||
foreach (var mimePartMatcher in Matchers.OfType<IMimePartMatcher>().ToArray())
|
||||
@@ -94,7 +100,7 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
return requestMatchResult.AddMatchDetail(MatchResult.From(Name, score, exception).ToMatchDetail());
|
||||
}
|
||||
|
||||
private static IMimeKitUtils LoadMimeKitUtils()
|
||||
|
||||
@@ -77,8 +77,8 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
var matchDetail = GetMatchResult(requestMessage).ToMatchDetail();
|
||||
return requestMatchResult.AddMatchDetail(matchDetail);
|
||||
}
|
||||
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
@@ -86,15 +86,16 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Path)).ToArray();
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
return MatchResult.From(nameof(RequestMessagePathMatcher), results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
var results = Funcs.Select(func => func(requestMessage.Path)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
var score = MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(nameof(RequestMessagePathMatcher), score);
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(nameof(RequestMessagePathMatcher));
|
||||
}
|
||||
}
|
||||
@@ -86,15 +86,16 @@ public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
if (Matchers != null)
|
||||
{
|
||||
var results = Matchers.Select(m => m.IsMatch(requestMessage.Url)).ToArray();
|
||||
return MatchResult.From(results, MatchOperator);
|
||||
return MatchResult.From(nameof(RequestMessageUrlMatcher), results, MatchOperator);
|
||||
}
|
||||
|
||||
if (Funcs != null)
|
||||
{
|
||||
var results = Funcs.Select(func => func(requestMessage.Url)).ToArray();
|
||||
return MatchScores.ToScore(results, MatchOperator);
|
||||
var score = MatchScores.ToScore(results, MatchOperator);
|
||||
return MatchResult.From(nameof(RequestMessageUrlMatcher), score);
|
||||
}
|
||||
|
||||
return default;
|
||||
return MatchResult.From(nameof(RequestMessageUrlMatcher));
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
IStringMetric stringMetricType = GetStringMetricType();
|
||||
|
||||
var score = MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input)).ToArray(), MatchOperator);
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, score);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -116,7 +116,7 @@ public class XPathMatcher : IStringMatcher
|
||||
|
||||
private MatchResult CreateMatchResult(double score, Exception? exception = null)
|
||||
{
|
||||
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
|
||||
}
|
||||
|
||||
private sealed class XPathEvaluator
|
||||
|
||||
@@ -15,7 +15,7 @@ public partial class Request
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
|
||||
public IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.And)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMultiPartMatcher(matchBehaviour, matchOperator, matchers));
|
||||
return this;
|
||||
|
||||
@@ -166,11 +166,12 @@ internal class LogEntryMapper
|
||||
TotalScore = matchResult.TotalScore,
|
||||
TotalNumber = matchResult.TotalNumber,
|
||||
AverageTotalScore = matchResult.AverageTotalScore,
|
||||
MatchDetails = matchResult.MatchDetails.Select(md => new
|
||||
{
|
||||
Name = md.MatcherType.Name.Replace("RequestMessage", string.Empty),
|
||||
md.Score
|
||||
} as object).ToList()
|
||||
MatchDetails = matchResult.MatchDetails
|
||||
//MatchDetails = matchResult.MatchDetails.Select(md => new
|
||||
//{
|
||||
// Name = md.MatcherType.Name.Replace("RequestMessage", string.Empty),
|
||||
// md.Score
|
||||
//} as object).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -25,9 +25,9 @@ internal class MatcherMapper
|
||||
_settings = Guard.NotNull(settings);
|
||||
}
|
||||
|
||||
public IMatcher[]? Map(IEnumerable<MatcherModel>? matchers)
|
||||
public IMatcher[] Map(IEnumerable<MatcherModel>? matchers)
|
||||
{
|
||||
return matchers?.Select(Map).OfType<IMatcher>().ToArray();
|
||||
return matchers?.Select(Map).OfType<IMatcher>().ToArray() ?? [];
|
||||
}
|
||||
|
||||
public IMatcher? Map(MatcherModel? matcherModel)
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Serialization;
|
||||
@@ -253,7 +254,15 @@ public partial class WireMockServer
|
||||
else if (requestModel.Body?.Matchers != null)
|
||||
{
|
||||
var matchOperator = StringUtils.ParseMatchOperator(requestModel.Body.MatchOperator);
|
||||
requestBuilder = requestBuilder.WithBody(_matcherMapper.Map(requestModel.Body.Matchers)!, matchOperator);
|
||||
|
||||
if (requestModel.Body.MatcherName == RequestMessageMultiPartMatcher.Name)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithMultiPart(_matcherMapper.Map(requestModel.Body.Matchers), matchOperator: matchOperator);
|
||||
}
|
||||
else
|
||||
{
|
||||
requestBuilder = requestBuilder.WithBody(_matcherMapper.Map(requestModel.Body.Matchers), matchOperator);
|
||||
}
|
||||
}
|
||||
|
||||
return requestBuilder;
|
||||
|
||||
Reference in New Issue
Block a user