mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-05-21 15:36:55 +02:00
Merge branch 'master' into SystemTextJsonMatcher
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.Admin.Mappings;
|
||||
|
||||
/// <summary>
|
||||
@@ -61,9 +63,15 @@ public class RequestModel
|
||||
/// Gets or sets the Params.
|
||||
/// </summary>
|
||||
public IList<ParamModel>? Params { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body.
|
||||
/// </summary>
|
||||
public BodyModel? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type of the request matcher to return an immediate mismatch during mapping processing.
|
||||
/// Optional.
|
||||
/// </summary>
|
||||
public RequestMatcherType? EarlyMatcherType { get; set; }
|
||||
}
|
||||
@@ -7,6 +7,11 @@ namespace WireMock.Matchers.Request;
|
||||
/// </summary>
|
||||
public interface IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the request matcher's type.
|
||||
/// </summary>
|
||||
public RequestMatcherType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified RequestMessage is match.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// List of predefined request matcher types.
|
||||
/// </summary>
|
||||
public enum RequestMatcherType
|
||||
{
|
||||
/// <summary>
|
||||
/// RequestMessageBodyMatcher
|
||||
/// </summary>
|
||||
Body = 0,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageBodyMatcher{T}
|
||||
/// </summary>
|
||||
BodyOfT = 1,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageClientIPMatcher
|
||||
/// </summary>
|
||||
ClientIP = 2,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageCookieMatcher
|
||||
/// </summary>
|
||||
Cookie = 3,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageGraphQLMatcher
|
||||
/// </summary>
|
||||
GraphQL = 4,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageHeaderMatcher
|
||||
/// </summary>
|
||||
Header = 5,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageHttpVersionMatcher
|
||||
/// </summary>
|
||||
HttpVersion = 6,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageMethodMatcher
|
||||
/// </summary>
|
||||
Method = 7,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageMultiPartMatcher
|
||||
/// </summary>
|
||||
MultiPart = 8,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageParamMatcher
|
||||
/// </summary>
|
||||
Param = 9,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessagePathMatcher
|
||||
/// </summary>
|
||||
Path = 10,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageProtoBufMatcher
|
||||
/// </summary>
|
||||
ProtoBuf = 11,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageScenarioAndStateMatcher
|
||||
/// </summary>
|
||||
ScenarioAndState = 12,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageUrlMatcher
|
||||
/// </summary>
|
||||
Url = 13,
|
||||
|
||||
/// <summary>
|
||||
/// RequestMessageCompositeMatcher
|
||||
/// </summary>
|
||||
Composite = 14
|
||||
}
|
||||
@@ -141,6 +141,9 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Body;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,9 @@ public class RequestMessageBodyMatcher<T> : IRequestMatcher
|
||||
Func = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.BodyOfT;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,9 @@ public class RequestMessageClientIPMatcher : IRequestMatcher
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.ClientIP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,11 @@ public abstract class RequestMessageCompositeMatcher : IRequestMatcher
|
||||
/// </value>
|
||||
private IEnumerable<IRequestMatcher> RequestMatchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Selected type to choose the matcher from <see cref="RequestMatchers"/> which will immediately return a mismatch.
|
||||
/// </summary>
|
||||
internal RequestMatcherType? EarlyMatcherType { get; private protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.
|
||||
/// </summary>
|
||||
@@ -31,6 +36,9 @@ public abstract class RequestMessageCompositeMatcher : IRequestMatcher
|
||||
_type = type;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Composite;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
@@ -39,6 +47,13 @@ public abstract class RequestMessageCompositeMatcher : IRequestMatcher
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
var earlyMatcher = new RequestMessageEarlyMatcher(EarlyMatcherType, RequestMatchers);
|
||||
var earlyMatchResult = earlyMatcher.GetMatchingScore(requestMessage, requestMatchResult);
|
||||
if (!MatchScores.IsPerfect(earlyMatchResult))
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
if (_type == CompositeMatcherType.And)
|
||||
{
|
||||
return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchResult));
|
||||
|
||||
@@ -93,6 +93,9 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
Name = string.Empty; // Not used when Func, but set to a non-null valid value.
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Cookie;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// Return the mismatch if the matching score of matchers is not perfect.
|
||||
/// </summary>
|
||||
internal sealed class RequestMessageEarlyMatcher(
|
||||
RequestMatcherType? earlyMatcherType,
|
||||
IEnumerable<IRequestMatcher> requestMatchers) : IRequestMatcher
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Composite;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
if (earlyMatcherType is null)
|
||||
{
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
|
||||
var earlyMatchers = requestMatchers
|
||||
.Where(m => m.Type == earlyMatcherType)
|
||||
.ToList();
|
||||
|
||||
if (earlyMatchers.Count is 0)
|
||||
{
|
||||
return MatchScores.Perfect;
|
||||
}
|
||||
|
||||
var compositeMatcher = new RequestBuilders.Request(earlyMatchers);
|
||||
return compositeMatcher.GetMatchingScore(requestMessage, requestMatchResult);
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,9 @@ public class RequestMessageHeaderMatcher : IRequestMatcher
|
||||
Name = string.Empty; // Not used when Func, but set to a non-null valid value.
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Header;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,9 @@ public class RequestMessageHttpVersionMatcher : IRequestMatcher
|
||||
MatcherOnStringFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.HttpVersion;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,9 @@ internal class RequestMessageMethodMatcher : IRequestMatcher
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Method;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -55,6 +55,9 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.MultiPart;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -82,6 +82,9 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Param;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,9 @@ public class RequestMessagePathMatcher : IRequestMatcher
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Path;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,9 @@ internal class RequestMessageScenarioAndStateMatcher : IRequestMatcher
|
||||
_executionConditionState = executionConditionState;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.ScenarioAndState;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,9 @@ public class RequestMessageUrlMatcher : IRequestMatcher
|
||||
Funcs = Guard.NotNull(funcs);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.Url;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
/// Initializes a new instance of the <see cref="Request"/> class.
|
||||
/// </summary>
|
||||
/// <param name="requestMatchers">The request matchers.</param>
|
||||
private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
|
||||
internal Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
|
||||
{
|
||||
_requestMatchers = Guard.NotNull(requestMatchers);
|
||||
}
|
||||
@@ -81,6 +81,13 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithEarlyMismatch(RequestMatcherType? earlyMatcherType)
|
||||
{
|
||||
EarlyMatcherType = earlyMatcherType;
|
||||
return this;
|
||||
}
|
||||
|
||||
internal bool TryGetProtoBufMatcher([NotNullWhen(true)] out IProtoBufMatcher? protoBufMatcher)
|
||||
{
|
||||
protoBufMatcher = GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;
|
||||
|
||||
@@ -66,6 +66,12 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
|
||||
// Request
|
||||
sb.AppendLine(" .Given(Request.Create()");
|
||||
|
||||
if (request.EarlyMatcherType != null)
|
||||
{
|
||||
sb.AppendLine($" .WithEarlyMismatch({request.EarlyMatcherType.Value.GetFullyQualifiedEnumValue()})");
|
||||
}
|
||||
|
||||
sb.AppendLine($" .UsingMethod({To1Or2Or3Arguments(methodMatcher?.MatchBehaviour, methodMatcher?.MatchOperator, methodMatcher?.Methods, HttpRequestMethod.GET)})");
|
||||
|
||||
if (pathMatcher?.Matchers != null)
|
||||
@@ -300,7 +306,9 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
IgnoreCase = pm.IgnoreCase ? true : null,
|
||||
RejectOnMatch = pm.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null,
|
||||
Matchers = _mapper.Map(pm.Matchers)
|
||||
}).ToList() : null
|
||||
}).ToList() : null,
|
||||
|
||||
EarlyMatcherType = request.EarlyMatcherType
|
||||
},
|
||||
Response = new ResponseModel()
|
||||
};
|
||||
|
||||
@@ -267,6 +267,8 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
requestBuilder = requestBuilder.WithEarlyMismatch(requestModel.EarlyMatcherType);
|
||||
|
||||
return requestBuilder;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.GraphQL;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,9 @@ public class RequestMessageProtoBufMatcher : IRequestMatcher
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RequestMatcherType Type => RequestMatcherType.ProtoBuf;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,8 @@ namespace WireMock.RequestBuilders;
|
||||
public interface IRequestBuilder : IClientIPRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a request matcher to the builder.
|
||||
/// Adds a request matcher to the builder.<br/>
|
||||
/// If the request matcher is already present, it will be replaced.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the request matcher.</typeparam>
|
||||
/// <param name="requestMatcher">The request matcher to add.</param>
|
||||
@@ -21,4 +22,11 @@ public interface IRequestBuilder : IClientIPRequestBuilder
|
||||
/// The link back to the Mapping.
|
||||
/// </summary>
|
||||
IMapping Mapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Chooses the <see cref="IRequestMatcher"/> which immediately returns a mismatch during mappings enumeration.
|
||||
/// </summary>
|
||||
/// <param name="earlyMatcherType">Selected type to choose the matcher from available list.</param>
|
||||
/// <returns>The current <see cref="IRequestBuilder"/> instance.</returns>
|
||||
IRequestBuilder WithEarlyMismatch(RequestMatcherType? earlyMatcherType);
|
||||
}
|
||||
Reference in New Issue
Block a user