using JetBrains.Annotations; using System; using System.Linq; using WireMock.Types; using WireMock.Validation; namespace WireMock.Matchers.Request { /// /// The request body matcher. /// public class RequestMessageBodyMatcher : IRequestMatcher { /// /// The body function /// public Func Func { get; } /// /// The body data function for byte[] /// public Func DataFunc { get; } /// /// The body data function for json /// public Func JsonFunc { get; } /// /// The matchers. /// public IMatcher[] Matchers { get; } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The body. public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast().ToArray()) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The body. public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast().ToArray()) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The body. public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast().ToArray()) { } /// /// Initializes a new instance of the class. /// /// The function. public RequestMessageBodyMatcher([NotNull] Func func) { Check.NotNull(func, nameof(func)); Func = func; } /// /// Initializes a new instance of the class. /// /// The function. public RequestMessageBodyMatcher([NotNull] Func func) { Check.NotNull(func, nameof(func)); DataFunc = func; } /// /// Initializes a new instance of the class. /// /// The function. public RequestMessageBodyMatcher([NotNull] Func func) { Check.NotNull(func, nameof(func)); JsonFunc = func; } /// /// Initializes a new instance of the class. /// /// The matchers. public RequestMessageBodyMatcher([NotNull] params IMatcher[] matchers) { Check.NotNull(matchers, nameof(matchers)); Matchers = matchers; } /// public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult) { double score = CalculateMatchScore(requestMessage); return requestMatchResult.AddScore(GetType(), score); } private double CalculateMatchScore(RequestMessage requestMessage, IMatcher matcher) { // Check if the matcher is a IObjectMatcher if (matcher is IObjectMatcher objectMatcher) { // If the body is a JSON object, try to match. if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json) { return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson); } // If the body is a byte array, try to match. if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes) { return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes); } } // Check if the matcher is a IStringMatcher if (matcher is IStringMatcher stringMatcher) { // If the body is a Json or a String, use the BodyAsString to match on. if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String) { return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString); } } return MatchScores.Mismatch; } private double CalculateMatchScore(RequestMessage requestMessage) { if (Matchers != null && Matchers.Any()) { return Matchers.Max(matcher => CalculateMatchScore(requestMessage, matcher)); } if (Func != null) { return MatchScores.ToScore(Func(requestMessage?.BodyData?.BodyAsString)); } if (JsonFunc != null) { return MatchScores.ToScore(JsonFunc(requestMessage?.BodyData?.BodyAsJson)); } if (DataFunc != null) { return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes)); } return MatchScores.Mismatch; } } }