/// <summary>
            /// Creates an api requests to gather all data
            /// </summary>
            /// <param name="context">
            /// The request contexts
            /// </param>
            /// <param name="requestContext">
            /// The request Context.
            /// </param>
            /// <param name="responseType">
            /// The response type
            /// </param>
            /// <returns>
            /// The request data
            /// </returns>
            private async Task <JObject> DoUntypedMutationApiRequests(
                ResolveFieldContext context,
                RequestContext requestContext,
                MergedUntypedMutationResult responseType)
            {
                var topFields =
                    GetRequestedFields(context.FieldAst.SelectionSet, context, this.mergedField.Type).ToList();
                var requestedFields = new List <ApiRequest>();

                foreach (var topField in topFields.Where(f => f.Name == "result"))
                {
                    requestedFields.AddRange(responseType.OriginalReturnType.GatherSingleApiRequest(topField, context));
                }

                var arguments = context.FieldAst.Arguments.ToJson(context).Property("input")?.Value as JObject;

                var originalApiField = this.mergedField.OriginalFields.Values.FirstOrDefault();

                if (originalApiField != null &&
                    !originalApiField.CheckAuthorization(requestContext, EnConnectionAction.Query))
                {
                    var severity = originalApiField.LogAccessRules.Any()
                                       ? originalApiField.LogAccessRules.Max(l => l.Severity)
                                       : EnSeverity.Trivial;

                    SecurityLog.CreateRecord(
                        EnSecurityLogType.OperationDenied,
                        severity,
                        context.UserContext as RequestContext,
                        "Unauthorized call to {ApiPath}",
                        context.FieldAst.Name);

                    var emptyResponse = new JObject
                    {
                        {
                            "clientMutationId",
                            arguments?.Property("clientMutationId")?.ToObject <string>()
                        }
                    };
                    return(emptyResponse);
                }

                var request = new MutationApiRequest
                {
                    Arguments = arguments,
                    FieldName = this.mergedField.FieldName,
                    Fields    = requestedFields
                };

                var data = await this.provider.GetData(new List <ApiRequest> {
                    request
                }, requestContext);

                data?.Add("clientMutationId", arguments?.Property("clientMutationId")?.ToObject <string>());
                return(data);
            }
        /// <summary>
        /// Handles mutation requests
        /// </summary>
        /// <param name="request">The request</param>
        private void HandleMutation(MutationApiRequest request)
        {
            var system = Context.System;

            this.apiProvider.ResolveMutation(
                request,
                request.Context,
                exception => system.Log.Error(exception, "{Type}: mutation resolve exception", this.GetType().Name))
            .PipeTo(
                this.Sender,
                this.Self,
                json => (SurrogatableJObject)json,
                e => this.HandleResolveException(e, system));
        }
            /// <summary>
            /// Creates an api requests to gather all data
            /// </summary>
            /// <param name="context">
            /// The request contexts
            /// </param>
            /// <param name="requestContext">
            /// The request Context.
            /// </param>
            /// <returns>
            /// The request data
            /// </returns>
            private Task <JObject> DoApiRequests(ResolveFieldContext context, RequestContext requestContext)
            {
                var request = new MutationApiRequest
                {
                    Arguments = context.FieldAst.Arguments.ToJson(context),
                    FieldName = this.mergedField.FieldName,
                    Fields    =
                        this.mergedField.Type.GatherSingleApiRequest(
                            context.FieldAst,
                            context).ToList()
                };

                var apiRequests = this.provider.GetData(new List <ApiRequest> {
                    request
                }, requestContext);

                return(apiRequests);
            }
        public async Task MutationHandleTest()
        {
            this.ExpectNoMsg();
            var actor =
                this.ActorOfAsTestActorRef <ApiHandlerActor>(Props.Create(() => new ApiHandlerActor(new TestProvider(null))));

            var context = new RequestContext();

            const string MethodParameters = "{ \"name\": \"new name\"}";

            var request = new MutationApiRequest
            {
                FieldName = "nestedSync.setName",
                Arguments = (JObject)JsonConvert.DeserializeObject(MethodParameters),
                Fields    = new List <ApiRequest>
                {
                    new ApiRequest {
                        FieldName = "id"
                    },
                    new ApiRequest {
                        FieldName = "name"
                    },
                    new ApiRequest {
                        FieldName = "value"
                    }
                },
                Context = context
            };

            var result = (JObject)await actor.Ask <SurrogatableJObject>(request, TimeSpan.FromSeconds(1));

            Assert.NotNull(result);
            this.Sys.Log.Info(result.ToString(Formatting.Indented));
            var token = result.SelectToken("result.name");

            Assert.NotNull(token);
            Assert.Equal("new name", token.ToObject <string>());
        }
            /// <summary>
            /// Creates an api requests to gather all data
            /// </summary>
            /// <param name="context">
            /// The request contexts
            /// </param>
            /// <param name="requestContext">
            /// The request Context.
            /// </param>
            /// <param name="responseType">response type</param>
            /// <returns>
            /// The request data
            /// </returns>
            private async Task <JObject> DoConnectionMutationApiRequests(
                ResolveFieldContext context,
                RequestContext requestContext,
                MergedConnectionMutationResultType responseType)
            {
                var arguments = context.FieldAst.Arguments.ToJson(context).Property("input")?.Value as JObject;

                var actionName = this.mergedField.FieldName?.Split('.').LastOrDefault();
                EnConnectionAction action;
                var originalApiField = this.mergedField.OriginalFields.Values.FirstOrDefault();

                if (Enum.TryParse(actionName, true, out action) && originalApiField != null &&
                    !originalApiField.CheckAuthorization(requestContext, action))
                {
                    var severity = originalApiField.LogAccessRules.Any()
                                       ? originalApiField.LogAccessRules.Max(l => l.Severity)
                                       : EnSeverity.Trivial;

                    SecurityLog.CreateRecord(
                        EnSecurityLogType.OperationDenied,
                        severity,
                        context.UserContext as RequestContext,
                        "Unauthorized call to {ApiPath}",
                        context.FieldAst.Name);

                    var emptyResponse = new JObject
                    {
                        {
                            "clientMutationId",
                            arguments?.Property("clientMutationId")?.ToObject <string>()
                        }
                    };
                    return(emptyResponse);
                }

                var edgeType            = responseType.EdgeType;
                var nodeType            = responseType.EdgeType.ObjectType;
                var requestedFields     = new List <ApiRequest>();
                var idSubRequestRequest = new List <ApiRequest>
                {
                    new ApiRequest
                    {
                        FieldName =
                            nodeType.KeyField.FieldName,
                        Alias = "__id"
                    }
                };
                var idRequestRequest = new ApiRequest
                {
                    Alias     = "__idRequest",
                    FieldName = "result",
                    Fields    = idSubRequestRequest
                };

                requestedFields.Add(idRequestRequest);

                var topFields =
                    GetRequestedFields(context.FieldAst.SelectionSet, context, this.mergedField.Type).ToList();

                var nodeRequests = topFields.Where(f => f.Name == "node" || f.Name == "edge").ToList();

                foreach (var nodeRequest in nodeRequests)
                {
                    var nodeAlias = nodeRequest.Alias ?? nodeRequest.Name;
                    switch (nodeRequest.Name)
                    {
                    case "node":
                        var nodeFields = nodeType.GatherSingleApiRequest(nodeRequest, context).ToList();
                        nodeFields.Add(new ApiRequest {
                            Alias = "__id", FieldName = nodeType.KeyField.FieldName
                        });
                        requestedFields.Add(
                            new ApiRequest {
                            Alias = nodeAlias, FieldName = "result", Fields = nodeFields
                        });
                        break;

                    case "edge":
                        var edgeFields = new List <ApiRequest>();
                        foreach (var edgeNodeRequests in
                                 GetRequestedFields(nodeRequest.SelectionSet, context, edgeType)
                                 .Where(f => f.Name == "node"))
                        {
                            edgeFields.AddRange(
                                nodeType.GatherSingleApiRequest(edgeNodeRequests, context).Select(
                                    f =>
                            {
                                f.Alias =
                                    $"{edgeNodeRequests.Alias ?? edgeNodeRequests.Name}_{f.Alias ?? f.FieldName}";
                                return(f);
                            }));
                        }

                        edgeFields.Add(new ApiRequest {
                            Alias = "__id", FieldName = nodeType.KeyField.FieldName
                        });
                        requestedFields.Add(
                            new ApiRequest {
                            Alias = nodeAlias, FieldName = "result", Fields = edgeFields
                        });

                        break;
                    }
                }

                if (responseType.ErrorType != null)
                {
                    var errorsRequest = topFields.Where(f => f.Name == "errors");
                    foreach (var field in errorsRequest)
                    {
                        requestedFields.Add(
                            new ApiRequest
                        {
                            FieldName = "errors",
                            Alias     = field.Alias,
                            Fields    =
                                responseType.ErrorType.GatherSingleApiRequest(field, context)
                                .ToList()
                        });
                    }
                }

                var request = new MutationApiRequest
                {
                    Arguments = arguments,
                    FieldName = this.mergedField.FieldName,
                    Fields    = requestedFields
                };

                var data = await this.provider.GetData(new List <ApiRequest> {
                    request
                }, requestContext);

                if (data != null)
                {
                    var mutation = (ApiMutation)this.mergedField.OriginalFields[this.provider.Description.ApiName];
                    var treePath = mutation.Path.Take(mutation.Path.Count - 1).ToList();

                    var parentGlobalId = new JArray(treePath.Select(r => new JObject {
                        { "f", r.FieldName }
                    }));
                    data.Add(GlobalIdPropertyName, parentGlobalId);

                    var elementRequest = mutation.Path.LastOrDefault();
                    if (elementRequest != null)
                    {
                        var localRequest = new JObject {
                            { "f", elementRequest.FieldName }
                        };
                        data.Add(RequestPropertyName, localRequest);
                    }
                }

                data?.Add("clientMutationId", arguments?.Property("clientMutationId")?.ToObject <string>());
                return(data);
            }