// Copyright © WireMock.Net using System; using System.Collections.Generic; using System.Linq; using AnyOfTypes; using Stef.Validation; using WireMock.Models; using WireMock.Models.GraphQL; using WireMock.Types; using WireMock.Util; namespace WireMock.Matchers.Request; /// /// The request body GraphQL matcher. /// public class RequestMessageGraphQLMatcher : IRequestMatcher { /// /// The matchers. /// public IMatcher[]? Matchers { get; } /// /// The /// public MatchOperator MatchOperator { get; } = MatchOperator.Or; /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The schema. /// A dictionary defining the custom scalars used in this schema. [optional] public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, string schema, IDictionary? customScalars = null) : this(CreateMatcherArray(matchBehaviour, schema, customScalars)) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The schema. /// A dictionary defining the custom scalars used in this schema. [optional] public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, ISchemaData schema, IDictionary? customScalars = null) : this(CreateMatcherArray(matchBehaviour, new AnyOf(schema), customScalars)) { } /// /// Initializes a new instance of the class. /// /// The matchers. public RequestMessageGraphQLMatcher(params IMatcher[] matchers) { Matchers = Guard.NotNull(matchers); } /// /// Initializes a new instance of the class. /// /// The matchers. /// The to use. public RequestMessageGraphQLMatcher(MatchOperator matchOperator, params IMatcher[] matchers) { Matchers = Guard.NotNull(matchers); MatchOperator = matchOperator; } /// public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult) { var results = CalculateMatchResults(requestMessage); var (score, exception) = MatchResult.From(results, MatchOperator).Expand(); return requestMatchResult.AddScore(GetType(), score, exception); } private static MatchResult CalculateMatchResult(IRequestMessage requestMessage, IMatcher matcher) { // In case the matcher is a IStringMatcher and the body is a Json or a String, use the BodyAsString to match on. if (matcher is IStringMatcher stringMatcher && requestMessage.BodyData?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded) { return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString); } return default; } private IReadOnlyList CalculateMatchResults(IRequestMessage requestMessage) { return Matchers == null ? [new MatchResult()] : Matchers.Select(matcher => CalculateMatchResult(requestMessage, matcher)).ToArray(); } private static IMatcher[] CreateMatcherArray( MatchBehaviour matchBehaviour, AnyOf schema, IDictionary? customScalars ) { var graphQLMatcher = TypeLoader.LoadNewInstance(schema, customScalars, matchBehaviour, MatchOperator.Or); return [graphQLMatcher]; } }