#if GRAPHQL using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using AnyOfTypes; using GraphQL; using GraphQL.Types; using Newtonsoft.Json; using Stef.Validation; using WireMock.Extensions; using WireMock.Models; namespace WireMock.Matchers; /// /// GrapQLMatcher Schema Matcher /// /// public class GraphQLMatcher : IStringMatcher { private sealed class GraphQLRequest { // ReSharper disable once UnusedAutoPropertyAccessor.Local public string? Query { get; set; } // ReSharper disable once UnusedAutoPropertyAccessor.Local public Dictionary? Variables { get; set; } } private readonly AnyOf[] _patterns; private readonly ISchema _schema; /// public MatchBehaviour MatchBehaviour { get; } /// /// Initializes a new instance of the class. /// /// The schema. /// The match behaviour. /// The to use. (default = "Or") public GraphQLMatcher(AnyOf schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or) { Guard.NotNull(schema); MatchBehaviour = matchBehaviour; MatchOperator = matchOperator; var patterns = new List>(); switch (schema.CurrentType) { case AnyOfType.First: patterns.Add(schema.First); _schema = BuildSchema(schema); break; case AnyOfType.Second: patterns.Add(schema.Second); _schema = BuildSchema(schema.Second.Pattern); break; case AnyOfType.Third: _schema = schema.Third; break; default: throw new NotSupportedException(); } _patterns = patterns.ToArray(); } /// public MatchResult IsMatch(string? input) { var score = MatchScores.Mismatch; Exception? exception = null; if (input != null && TryGetGraphQLRequest(input, out var graphQLRequest)) { try { var executionResult = new DocumentExecuter().ExecuteAsync(_ => { _.ThrowOnUnhandledException = true; _.Schema = _schema; _.Query = graphQLRequest.Query; if (graphQLRequest.Variables != null) { _.Variables = new Inputs(graphQLRequest.Variables); } }).GetAwaiter().GetResult(); if (executionResult.Errors == null || executionResult.Errors.Count == 0) { score = MatchScores.Perfect; } else { exception = executionResult.Errors.OfType().ToArray().ToException(); } } catch (Exception ex) { exception = ex; } } return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); } /// public AnyOf[] GetPatterns() { return _patterns; } /// public MatchOperator MatchOperator { get; } /// public string Name => nameof(GraphQLMatcher); private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest) { try { graphQLRequest = JsonConvert.DeserializeObject(input); return graphQLRequest != null; } catch { graphQLRequest = default; return false; } } private static ISchema BuildSchema(string schema) { return Schema.For(schema); } } #endif