diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/FSharp.Data.GraphQL.Server.AspNetCore.fsproj b/src/FSharp.Data.GraphQL.Server.AspNetCore/FSharp.Data.GraphQL.Server.AspNetCore.fsproj
index 543a96f1c..841184b7c 100644
--- a/src/FSharp.Data.GraphQL.Server.AspNetCore/FSharp.Data.GraphQL.Server.AspNetCore.fsproj
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/FSharp.Data.GraphQL.Server.AspNetCore.fsproj
@@ -13,6 +13,7 @@
+
diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLRequestHandler.fs b/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLRequestHandler.fs
index ebbe4c138..6e446d498 100644
--- a/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLRequestHandler.fs
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLRequestHandler.fs
@@ -16,28 +16,34 @@ open FSharp.Data.GraphQL.Server
open FSharp.Data.GraphQL.Shared
type DefaultGraphQLRequestHandler<'Root>
+ ///
+ /// Handles GraphQL requests using a provided root schema.
+ ///
+ /// The accessor to the current HTTP context.
+ /// The options monitor for GraphQL options.
+ /// The logger to log messages.
(
- /// The accessor to the current HTTP context
httpContextAccessor : IHttpContextAccessor,
- /// The options monitor for GraphQL options
options : IOptionsMonitor>,
- /// The logger to log messages
logger : ILogger>
) =
inherit GraphQLRequestHandler<'Root> (httpContextAccessor, options, logger)
-/// Provides logic to parse and execute GraphQL request
and [] GraphQLRequestHandler<'Root>
+ ///
+ /// Provides logic to parse and execute GraphQL requests.
+ ///
+ /// The accessor to the current HTTP context.
+ /// The options monitor for GraphQL options.
+ /// The logger to log messages.
(
- /// The accessor to the current HTTP context
httpContextAccessor : IHttpContextAccessor,
- /// The options monitor for GraphQL options
options : IOptionsMonitor>,
- /// The logger to log messages
logger : ILogger
) =
let ctx = httpContextAccessor.HttpContext
+ let getInputContext() = (HttpContextRequestExecutionContext ctx) :> IInputExecutionContext
let toResponse { DocumentId = documentId; Content = content; Metadata = metadata } =
@@ -142,8 +148,8 @@ and [] GraphQLRequestHandler<'Root>
let executeIntrospectionQuery (executor : Executor<_>) (ast : Ast.Document voption) : Task = task {
let! result =
match ast with
- | ValueNone -> executor.AsyncExecute IntrospectionQuery.Definition
- | ValueSome ast -> executor.AsyncExecute ast
+ | ValueNone -> executor.AsyncExecute (IntrospectionQuery.Definition, getInputContext)
+ | ValueSome ast -> executor.AsyncExecute (ast, getInputContext)
let response = result |> toResponse
return (TypedResults.Ok response) :> IResult
@@ -228,7 +234,7 @@ and [] GraphQLRequestHandler<'Root>
let! result =
Async.StartImmediateAsTask (
- executor.AsyncExecute (content.Ast, root, ?variables = variables, ?operationName = operationName),
+ executor.AsyncExecute (content.Ast, getInputContext, root, ?variables = variables, ?operationName = operationName),
cancellationToken = ctx.RequestAborted
)
diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLWebsocketMiddleware.fs b/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLWebsocketMiddleware.fs
index 12c521783..6d621e93f 100644
--- a/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLWebsocketMiddleware.fs
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/GraphQLWebsocketMiddleware.fs
@@ -45,7 +45,7 @@ type GraphQLWebSocketMiddleware<'Root>
| ServerPong p -> { Id = ValueNone; Type = "pong"; Payload = p |> ValueOption.map CustomResponse }
| Next (id, payload) -> { Id = ValueSome id; Type = "next"; Payload = ValueSome <| ExecutionResult payload }
| Complete id -> { Id = ValueSome id; Type = "complete"; Payload = ValueNone }
- | Error (id, errMsgs) -> { Id = ValueSome id; Type = "error"; Payload = ValueSome <| ErrorMessages errMsgs }
+ | Error (id, errMessages) -> { Id = ValueSome id; Type = "error"; Payload = ValueSome <| ErrorMessages errMessages }
return JsonSerializer.Serialize (raw, jsonSerializerOptions)
}
@@ -89,9 +89,9 @@ type GraphQLWebSocketMiddleware<'Root>
&& ((segmentResponse = null)
|| (not segmentResponse.EndOfMessage)) do
try
- let! r = socket.ReceiveAsync (new ArraySegment (buffer), cancellationToken)
+ let! r = socket.ReceiveAsync (ArraySegment(buffer), cancellationToken)
segmentResponse <- r
- completeMessage.AddRange (new ArraySegment (buffer, 0, r.Count))
+ completeMessage.AddRange (ArraySegment(buffer, 0, r.Count))
with :? OperationCanceledException ->
()
@@ -117,7 +117,7 @@ type GraphQLWebSocketMiddleware<'Root>
else
// TODO: Allocate string only if a debugger is attached
let! serializedMessage = message |> serializeServerMessage jsonSerializerOptions
- let segment = new ArraySegment (System.Text.Encoding.UTF8.GetBytes (serializedMessage))
+ let segment = ArraySegment(System.Text.Encoding.UTF8.GetBytes (serializedMessage))
if not (socket.State = WebSocketState.Open) then
logger.LogTrace ($"Ignoring message to be sent via socket, since its state is not '{nameof WebSocketState.Open}', but '{{state}}'", socket.State)
else
@@ -160,7 +160,7 @@ type GraphQLWebSocketMiddleware<'Root>
tryToGracefullyCloseSocket (WebSocketCloseStatus.NormalClosure, "Normal Closure")
let handleMessages (cancellationToken : CancellationToken) (httpContext : HttpContext) (socket : WebSocket) : Task =
- let subscriptions = new Dictionary ()
+ let subscriptions = Dictionary()
// ---------->
// Helpers -->
// ---------->
@@ -168,6 +168,7 @@ type GraphQLWebSocketMiddleware<'Root>
let sendMsg = sendMessageViaSocket serializerOptions socket
let rcv () = socket |> rcvMsgViaSocket serializerOptions
+ let getInputContext() = (HttpContextRequestExecutionContext httpContext) :> IInputExecutionContext
let sendOutput id (output : SubscriptionExecutionResult) =
sendMsg (Next (id, output))
@@ -234,10 +235,10 @@ type GraphQLWebSocketMiddleware<'Root>
&& socket |> isSocketOpen do
let! receivedMessage = rcv ()
match receivedMessage with
- | Result.Error failureMsgs ->
+ | Result.Error failureMessages ->
nameof InvalidMessage
|> logMsgReceivedWithOptionalPayload ValueNone
- match failureMsgs with
+ match failureMessages with
| InvalidMessage (code, explanation) -> do! socket.CloseAsync (enum code, explanation, CancellationToken.None)
| Ok ValueNone -> logger.LogTrace ("WebSocket received empty message! State = '{socketState}'", socket.State)
| Ok (ValueSome msg) ->
@@ -274,11 +275,11 @@ type GraphQLWebSocketMiddleware<'Root>
let variables = query.Variables |> Skippable.toOption
let! planExecutionResult =
let root = options.RootFactory httpContext
- options.SchemaExecutor.AsyncExecute (query.Query, root, ?variables = variables)
+ options.SchemaExecutor.AsyncExecute (query.Query, getInputContext, root, ?variables = variables)
do! planExecutionResult |> applyPlanExecutionResult id socket
with ex ->
logger.LogError (ex, "Unexpected error during subscription with id '{id}'", id)
- do! sendMsg (Error (id, [new Shared.NameValueLookup ([ ("subscription", "Unexpected error during subscription" :> obj) ])]))
+ do! sendMsg (Error (id, [NameValueLookup([ ("subscription", "Unexpected error during subscription" :> obj) ])]))
| ClientComplete id ->
"ClientComplete" |> logMsgWithIdReceived id
subscriptions
@@ -287,7 +288,7 @@ type GraphQLWebSocketMiddleware<'Root>
do! socket |> tryToGracefullyCloseSocketWithDefaultBehavior
with ex ->
logger.LogError (ex, "Cannot handle a message; dropping a websocket connection")
- // at this point, only something really weird must have happened.
+ // At this point, only something really weird must have happened.
// In order to avoid faulty state scenarios and unimagined damages,
// just close the socket without further ado.
do! socket |> tryToGracefullyCloseSocketWithDefaultBehavior
@@ -344,7 +345,7 @@ type GraphQLWebSocketMiddleware<'Root>
return Result.Error <| "{nameof ConnectionInit} timeout"
}
- member __.InvokeAsync (ctx : HttpContext) = task {
+ member _.InvokeAsync (ctx : HttpContext) = task {
if not (ctx.Request.Path = endpointUrl) then
do! next.Invoke (ctx)
else if ctx.WebSockets.IsWebSocketRequest then
diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/Helpers.fs b/src/FSharp.Data.GraphQL.Server.AspNetCore/Helpers.fs
index d281b3f22..285a98973 100644
--- a/src/FSharp.Data.GraphQL.Server.AspNetCore/Helpers.fs
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/Helpers.fs
@@ -3,7 +3,6 @@ namespace FSharp.Data.GraphQL.Server.AspNetCore
open System
open System.Text
-
[]
module Helpers =
@@ -48,4 +47,3 @@ module ReflectionHelpers =
| PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType
| FieldGet (_, fieldInfo) -> fieldInfo.DeclaringType
| _ -> failwith "Expression is no property."
-
diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/HttpContext.fs b/src/FSharp.Data.GraphQL.Server.AspNetCore/HttpContext.fs
index 92806132c..3f946cab0 100644
--- a/src/FSharp.Data.GraphQL.Server.AspNetCore/HttpContext.fs
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/HttpContext.fs
@@ -21,7 +21,7 @@ type HttpContext with
///
/// Type to deserialize to
///
- /// Retruns a Deserialized object or
+ /// Returns a Deserialized object or
/// ProblemDetails as IResult
/// if a body could not be deserialized.
///
@@ -31,10 +31,23 @@ type HttpContext with
let request = ctx.Request
try
- if not request.Body.CanSeek then
- request.EnableBuffering()
+ let! jsonStream =
+ task {
+ if request.HasFormContentType then
+ let! form = request.ReadFormAsync(ctx.RequestAborted)
+ match form.TryGetValue("operations") with
+ | true, values when values.Count > 0 ->
+ let bytes = System.Text.Encoding.UTF8.GetBytes(values[0])
+ return new MemoryStream(bytes) :> Stream
+ | _ ->
+ return request.Body
+ else
+ if not request.Body.CanSeek then
+ request.EnableBuffering()
+ return request.Body
+ }
- return! JsonSerializer.DeserializeAsync<'T>(request.Body, serializerOptions, ctx.RequestAborted)
+ return! JsonSerializer.DeserializeAsync<'T>(jsonStream, serializerOptions, ctx.RequestAborted)
with :? JsonException ->
let body = request.Body
body.Seek(0, SeekOrigin.Begin) |> ignore
diff --git a/src/FSharp.Data.GraphQL.Server.AspNetCore/RequestExecutionContext.fs b/src/FSharp.Data.GraphQL.Server.AspNetCore/RequestExecutionContext.fs
new file mode 100644
index 000000000..fa291a56f
--- /dev/null
+++ b/src/FSharp.Data.GraphQL.Server.AspNetCore/RequestExecutionContext.fs
@@ -0,0 +1,18 @@
+namespace FSharp.Data.GraphQL.Server.AspNetCore
+
+open FSharp.Data.GraphQL
+open Microsoft.AspNetCore.Http
+
+type HttpContextRequestExecutionContext (httpContext : HttpContext) =
+
+ interface IInputExecutionContext with
+
+ member this.GetFile(key) =
+ if not httpContext.Request.HasFormContentType then
+ Error "Request does not have form content type"
+ else
+ let form = httpContext.Request.Form
+ match (form.Files |> Seq.vtryFind (fun f -> f.Name = key)) with
+ | ValueSome file -> Ok (file.OpenReadStream())
+ | ValueNone -> Error $"File with key '{key}' not found"
+
diff --git a/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs b/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs
index 9938878d9..dfb82c8c0 100644
--- a/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs
+++ b/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs
@@ -2,6 +2,7 @@ namespace FSharp.Data.GraphQL.Server.Middleware
open System.Collections.Generic
open System.Collections.Immutable
+open FSharp.Data.GraphQL.Shared
open FsToolkit.ErrorHandling
open FSharp.Data.GraphQL
@@ -11,7 +12,7 @@ open FSharp.Data.GraphQL.Types
type internal QueryWeightMiddleware(threshold : float, reportToMetadata : bool) =
- let middleware (threshold : float) (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
+ let middleware (threshold : float) (inputContext : InputExecutionContextProvider) (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
let measureThreshold (threshold : float) (fields : ExecutionInfo list) =
let getWeight f =
if f.ParentDef = upcast ctx.ExecutionPlan.RootDef
@@ -72,7 +73,7 @@ type internal ObjectListFilterMiddleware<'ObjectType, 'ListType>(reportToMetadat
let compileMiddleware (ctx : SchemaCompileContext) (next : SchemaCompileContext -> unit) =
let modifyFields (object : ObjectDef<'ObjectType>) (fields : FieldDef<'ObjectType> seq) =
let args = [ Define.Input("filter", Nullable ObjectListFilterType) ]
- let fields = fields |> Seq.map (fun x -> x.WithArgs(args)) |> List.ofSeq
+ let fields = fields |> Seq.map _.WithArgs(args) |> List.ofSeq
object.WithFields(fields)
let typesWithListFields =
ctx.TypeMap.GetTypesWithListFields<'ObjectType, 'ListType>()
@@ -85,7 +86,7 @@ type internal ObjectListFilterMiddleware<'ObjectType, 'ListType>(reportToMetadat
ctx.TypeMap.AddTypes(modifiedTypes, overwrite = true)
next ctx
- let reportMiddleware (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
+ let reportMiddleware (inputContext : InputExecutionContextProvider) (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
let rec collectArgs (path: obj list) (acc : KeyValuePair list) (fields : ExecutionInfo list) =
let fieldArgs currentPath field =
let filterResults =
@@ -93,7 +94,7 @@ type internal ObjectListFilterMiddleware<'ObjectType, 'ListType>(reportToMetadat
|> Seq.map (fun x ->
match x.Name, x.Value with
| "filter", (VariableName variableName) -> Ok (ValueSome (ctx.Variables[variableName] :?> ObjectListFilter))
- | "filter", inlineConstant -> ObjectListFilterType.CoerceInput (InlineConstant inlineConstant) ctx.Variables |> Result.map ValueOption.ofObj
+ | "filter", inlineConstant -> ObjectListFilterType.CoerceInput inputContext (InlineConstant inlineConstant) ctx.Variables |> Result.map ValueOption.ofObj
| _ -> Ok ValueNone)
|> Seq.toList
match filterResults |> splitSeqErrorsList with
diff --git a/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs b/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs
index 7f4e5d067..e8239cad9 100644
--- a/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs
+++ b/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs
@@ -167,7 +167,7 @@ let ObjectListFilterType : InputCustomDefinition = {
Some
"The `Filter` scalar type represents a filter on one or more fields of an object in an object list. The filter is represented by a JSON object where the fields are the complemented by specific suffixes to represent a query."
CoerceInput =
- (fun input variables ->
+ (fun _ input variables ->
match input with
| InlineConstant c ->
(coerceObjectListFilterInput variables c)
diff --git a/src/FSharp.Data.GraphQL.Server/Execution.fs b/src/FSharp.Data.GraphQL.Server/Execution.fs
index 7a3122b2d..737ed4b50 100644
--- a/src/FSharp.Data.GraphQL.Server/Execution.fs
+++ b/src/FSharp.Data.GraphQL.Server/Execution.fs
@@ -25,26 +25,26 @@ let (|RequestError|Direct|Deferred|Stream|) (response : GQLExecutionResult) =
| Deferred (data, errors, deferred) -> Deferred (data, errors, deferred)
| Stream data -> Stream data
-let private collectDefaultArgValue acc (argdef: InputFieldDef) =
- match argdef.DefaultValue with
- | Some defVal -> Map.add argdef.Name defVal acc
+let private collectDefaultArgValue acc (argDef: InputFieldDef) =
+ match argDef.DefaultValue with
+ | Some defVal -> Map.add argDef.Name defVal acc
| None -> acc
-let internal argumentValue variables (argdef: InputFieldDef) (argument: Argument) =
- match argdef.ExecuteInput argument.Value variables with
+let internal argumentValue inputContext variables (argDef: InputFieldDef) (argument: Argument) =
+ match argDef.ExecuteInput inputContext argument.Value variables with
| Ok null ->
- match argdef.DefaultValue with
+ match argDef.DefaultValue with
| Some value -> Ok value
| None -> Ok null
| result -> result
-let private getArgumentValues (argDefs: InputFieldDef []) (args: Argument list) (variables: ImmutableDictionary) : Result
+
diff --git a/src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs b/src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs
index 863c359be..f38328d5c 100644
--- a/src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs
+++ b/src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs
@@ -24,7 +24,8 @@ module internal ValueTuple =
let fstv struct (a, _) = a
let sndv struct (_, b) = b
-module internal Seq =
+[]
+module Seq =
let vchoose mapping seq =
seq
diff --git a/src/FSharp.Data.GraphQL.Shared/InputContext.fs b/src/FSharp.Data.GraphQL.Shared/InputContext.fs
new file mode 100644
index 000000000..1ca352568
--- /dev/null
+++ b/src/FSharp.Data.GraphQL.Shared/InputContext.fs
@@ -0,0 +1,7 @@
+namespace FSharp.Data.GraphQL
+
+type IInputExecutionContext =
+ abstract GetFile : string -> Result
+
+type InputExecutionContextProvider = unit -> IInputExecutionContext
+
diff --git a/src/FSharp.Data.GraphQL.Shared/Output.fs b/src/FSharp.Data.GraphQL.Shared/Output.fs
index c044f139f..de048a55d 100644
--- a/src/FSharp.Data.GraphQL.Shared/Output.fs
+++ b/src/FSharp.Data.GraphQL.Shared/Output.fs
@@ -1,4 +1,4 @@
-namespace FSharp.Data.GraphQL.Shared
+namespace FSharp.Data.GraphQL
open System.Collections.Generic
open System
@@ -140,4 +140,4 @@ type NameValueLookup(keyValues: KeyValuePair []) =
module NameValueLookup =
/// Create new NameValueLookup from given list of key-value tuples.
- let ofList (l: (string * obj) list) = NameValueLookup(l)
\ No newline at end of file
+ let ofList (l: (string * obj) list) = NameValueLookup (l)
diff --git a/src/FSharp.Data.GraphQL.Shared/SchemaDefinitions.fs b/src/FSharp.Data.GraphQL.Shared/SchemaDefinitions.fs
index 8aa47282b..7e8e9e7ce 100644
--- a/src/FSharp.Data.GraphQL.Shared/SchemaDefinitions.fs
+++ b/src/FSharp.Data.GraphQL.Shared/SchemaDefinitions.fs
@@ -8,7 +8,6 @@ open System.Collections.Generic
open System.Text.Json
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Ast
-open FSharp.Data.GraphQL.Extensions
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Validation
open FSharp.Quotations
@@ -191,6 +190,12 @@ module SchemaDefinitions =
| Option o -> Some(o.ToString())
| _ -> Some(x.ToString())
+ /// Tries to convert any value to string.
+ let coerceFileValue (context : IInputExecutionContext) (value : obj) : Result =
+ match coerceStringValue value with
+ | Some fileName -> context.GetFile fileName
+ | None -> Error "Only string value can be used as file name"
+
/// Tries to convert any value to generic type parameter.
let coerceIdValue (x : obj) : string option =
match x with
@@ -371,7 +376,7 @@ module SchemaDefinitions =
/// to take collection of provided value.
let ListOf(innerDef : #TypeDef<'Val>) : ListOfDef<'Val, 'Seq> = upcast { ListOfDefinition.OfType = innerDef }
- let internal variableOrElse other value (variables : IReadOnlyDictionary) =
+ let internal variableOrElse other (_ : InputExecutionContextProvider) value (variables : IReadOnlyDictionary) =
match value with
// TODO: Use FSharp.Collection.Immutable
| VariableName variableName ->
@@ -473,10 +478,38 @@ module SchemaDefinitions =
{ Name = "Guid"
Description =
Some
- "The `Guid` scalar type represents a Globaly Unique Identifier value. It's a 128-bit long byte key, that can be serialized to string."
+ "The `Guid` scalar type represents a Globally Unique Identifier value. It's a 128-bit long byte key, that can be serialized to string."
CoerceInput = coerceGuidInput
CoerceOutput = coerceGuidValue }
+ /// Defines an object list filter for use as an argument for filter list of object fields.
+ let FileType : InputCustomDefinition = {
+ Name = "FileType"
+ Description =
+ Some
+ "The `File` type represents a file on one or more fields of an object in an object list. The filter is represented by a JSON object where the fields are the complemented by specific suffixes to represent a query."
+ CoerceInput =
+ (fun inputContext input variables ->
+ let getFileStream fileKey =
+ let inputExecutionContext = inputContext()
+ let streamResult = inputExecutionContext.GetFile fileKey
+ match streamResult with
+ | Ok stream -> Ok stream
+ | Error errorMessage -> IGQLError.createResultErrorList errorMessage
+
+ match input with
+ | InlineConstant c ->
+ match c with
+ | StringValue strValue -> getFileStream strValue
+ | VariableName varName ->
+ Ok (variables[varName] :?> System.IO.Stream)
+ | _ -> IGQLError.createResultErrorList "Only a string value or a variable with a string value can be used as a file name."
+ | Variable json ->
+ match (json |> InputValue.OfJsonElement) with
+ | StringValue str -> getFileStream str
+ | _ -> IGQLError.createResultErrorList "Only a variable with a string value can be used as a file name.")
+ }
+
/// GraphQL @include directive.
let IncludeDirective : DirectiveDef =
{ Name = "include"
diff --git a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs
index 05d41ed70..11006387b 100644
--- a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs
+++ b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs
@@ -859,7 +859,12 @@ and VarDef = {
/// The context used to hold all the information for a schema compiling proccess.
-and SchemaCompileContext = { Schema : ISchema; TypeMap : TypeMap; FieldExecuteMap : FieldExecuteMap }
+and SchemaCompileContext = {
+ Schema : ISchema
+ TypeMap : TypeMap
+ FieldExecuteMap : FieldExecuteMap
+ GetInputContext : InputExecutionContextProvider
+}
/// A planning of an execution phase.
/// It is used by the execution process to execute an operation.
@@ -893,11 +898,13 @@ and ExecutionContext = {
Schema : ISchema
/// Boxed value of the top level type, root query/mutation.
RootValue : obj
- /// Execution plan describing, what fiedls are going to be resolved.
+ /// Execution plan describing, what fields are going to be resolved.
ExecutionPlan : ExecutionPlan
- /// Collection of variables provided to execute current operation.
+ ///Get input execution context
+ GetInputContext : InputExecutionContextProvider
+ /// Collection of variables provided to execute a current operation.
Variables : ImmutableDictionary
- /// Collection of errors that occurred while executing current operation.
+ /// Collection of errors that occurred while executing a current operation.
Errors : ConcurrentDictionary>
/// A map of all fields of the query and their respective execution operations.
FieldExecuteMap : FieldExecuteMap
@@ -1115,7 +1122,20 @@ and [] ScalarDefinition<'Primitive, 'Val> = {
and ScalarDefinition<'Val> = ScalarDefinition<'Val, 'Val>
-/// A GraphQL representation of single case of the enum type.
+and FileDef =
+ interface
+ /// Name of the file type.
+ abstract Name : string
+ /// Optional scalar type description.
+ abstract Description : string option
+ /// A function used to retrieve a .NET object from provided GraphQL query or JsonElement variable.
+ abstract Coerce : IInputExecutionContext -> InputParameterValue -> Result
+ inherit TypeDef
+ inherit NamedDef
+ inherit InputDef
+ end
+
+/// A GraphQL representation for a single value of the enum type.
/// Enum value return value is always represented as string.
and EnumVal =
interface
@@ -1129,7 +1149,7 @@ and EnumVal =
abstract DeprecationReason : string option
end
-/// A GraphQL representation of single case of the enum type.
+/// A GraphQL representation of a single case of the enum type.
/// Enum value return value is always represented as string.
and EnumValue<'Val> = {
/// Identifier of the enum value.
@@ -1693,7 +1713,7 @@ and InputObjectDefinition<'Val> = {
override x.ToString () = x.Name + "!"
/// Function type used for resolving input object field values.
-and ExecuteInput = InputValue -> Variables -> Result
+and ExecuteInput = InputExecutionContextProvider -> InputValue -> Variables -> Result
/// GraphQL field input definition. Can be used as fields for
/// input objects or as arguments for any ordinary field definition.
@@ -1766,7 +1786,7 @@ and internal InputCustomDef =
/// Optional input field / argument description.
abstract Description : string option
/// A function used to retrieve a .NET object from provided GraphQL query or JsonElement variable.
- abstract CoerceInput : InputParameterValue -> Variables -> Result
+ abstract CoerceInput : InputExecutionContextProvider -> InputParameterValue -> Variables -> Result
inherit TypeDef
inherit NamedDef
inherit InputDef
@@ -1776,7 +1796,7 @@ and internal InputCustomDef =
and InputCustomDefinition<'Val> = internal {
Name : string
Description : string option
- CoerceInput : InputParameterValue -> Variables -> Result<'Val, IGQLError list>
+ CoerceInput : InputExecutionContextProvider -> InputParameterValue -> Variables -> Result<'Val, IGQLError list>
} with
interface TypeDef with
member _.Type = typeof<'Val>
@@ -1796,7 +1816,7 @@ and InputCustomDefinition<'Val> = internal {
interface InputCustomDef with
member x.Name = x.Name
member x.Description = x.Description
- member x.CoerceInput input variables = x.CoerceInput input variables |> Result.map box
+ member x.CoerceInput input variables context = x.CoerceInput input variables context |> Result.map box
interface NamedDef with
member x.Name = x.Name
diff --git a/src/FSharp.Data.GraphQL.Shared/Validation.fs b/src/FSharp.Data.GraphQL.Shared/Validation.fs
index 1e3951a46..72d841423 100644
--- a/src/FSharp.Data.GraphQL.Shared/Validation.fs
+++ b/src/FSharp.Data.GraphQL.Shared/Validation.fs
@@ -933,6 +933,7 @@ module Ast =
let invalidScalars = [| "Int"; "Float"; "Boolean" |]
match tref.Name, tref.Kind with
| (Some x, TypeKind.SCALAR) when not (Array.contains x invalidScalars) -> Success
+ | (Some x, TypeKind.INPUT_OBJECT) when x = FileType.Name -> Success
| _ -> canNotCoerce
| EnumValue _ ->
match tref.Kind with
diff --git a/tests/FSharp.Data.GraphQL.Benchmarks/ExecutionBenchmark.fs b/tests/FSharp.Data.GraphQL.Benchmarks/ExecutionBenchmark.fs
index a49b71696..04f6bb219 100644
--- a/tests/FSharp.Data.GraphQL.Benchmarks/ExecutionBenchmark.fs
+++ b/tests/FSharp.Data.GraphQL.Benchmarks/ExecutionBenchmark.fs
@@ -10,6 +10,10 @@ open FSharp.Data.GraphQL.Parser
open BenchmarkDotNet.Attributes
open FSharp.Data.GraphQL.Benchmarks
+type MockInputExecutionContext() =
+ interface IInputExecutionContext with
+ member this.GetFile _ = failwith "todo"
+
[)>]
[]
type SimpleExecutionBenchmark() =
@@ -23,6 +27,7 @@ type SimpleExecutionBenchmark() =
let mutable simpleExecutionPlan : ExecutionPlan = Unchecked.defaultof
let mutable flatExecutionPlan : ExecutionPlan = Unchecked.defaultof
let mutable nestedExecutionPlan : ExecutionPlan = Unchecked.defaultof
+ let getInputContext = fun () -> MockInputExecutionContext() :> IInputExecutionContext
[]
member _.Setup() =
@@ -38,31 +43,31 @@ type SimpleExecutionBenchmark() =
nestedExecutionPlan <- schemaProcessor.CreateExecutionPlanOrFail(nestedAst)
[]
- member _.BenchmarkSimpleQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.simple) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.simple, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkSimpleQueryParsed() = schemaProcessor.AsyncExecute(simpleAst) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryParsed() = schemaProcessor.AsyncExecute(simpleAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkSimpleQueryPlanned() = schemaProcessor.AsyncExecute(simpleExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryPlanned() = schemaProcessor.AsyncExecute(simpleExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.flat) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.flat, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryParsed() = schemaProcessor.AsyncExecute(flatAst) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryParsed() = schemaProcessor.AsyncExecute(flatAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryPlanned() = schemaProcessor.AsyncExecute(flatExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryPlanned() = schemaProcessor.AsyncExecute(flatExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.nested) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.nested, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryParsed() = schemaProcessor.AsyncExecute(nestedAst) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryParsed() = schemaProcessor.AsyncExecute(nestedAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryPlanned() = schemaProcessor.AsyncExecute(nestedExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryPlanned() = schemaProcessor.AsyncExecute(nestedExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkParallelQueryPlanned() = parallelSchemaProcessor.AsyncExecute({ nestedExecutionPlan with Strategy = Parallel }) |> Async.RunSynchronously
+ member _.BenchmarkParallelQueryPlanned() = parallelSchemaProcessor.AsyncExecute({ nestedExecutionPlan with Strategy = Parallel }, getInputContext) |> Async.RunSynchronously
diff --git a/tests/FSharp.Data.GraphQL.Benchmarks/MiddlewareBenchmark.fs b/tests/FSharp.Data.GraphQL.Benchmarks/MiddlewareBenchmark.fs
index c8327e010..404976ba2 100644
--- a/tests/FSharp.Data.GraphQL.Benchmarks/MiddlewareBenchmark.fs
+++ b/tests/FSharp.Data.GraphQL.Benchmarks/MiddlewareBenchmark.fs
@@ -5,6 +5,8 @@ module FSharp.Data.GraphQL.MiddlewaresBenchmark
#nowarn "40"
open FSharp.Data.GraphQL
+open FSharp.Data.GraphQL.ExecutionBenchmark
+open FSharp.Data.GraphQL.Shared
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open BenchmarkDotNet.Attributes
@@ -25,6 +27,7 @@ type SimpleExecutionWithMiddlewaresBenchmark() =
let mutable nestedExecutionPlan : ExecutionPlan = Unchecked.defaultof
let mutable filteredExecutionPlan : ExecutionPlan = Unchecked.defaultof
let mutable filteredAst : Ast.Document = Unchecked.defaultof
+ let getInputContext = fun () -> MockInputExecutionContext() :> IInputExecutionContext
[]
member _.Setup() =
@@ -41,37 +44,37 @@ type SimpleExecutionWithMiddlewaresBenchmark() =
filteredExecutionPlan <- schemaProcessor.CreateExecutionPlanOrFail(filteredAst)
[]
- member _.BenchmarkSimpleQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.simple) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.simple, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkSimpleQueryParsed() = schemaProcessor.AsyncExecute(simpleAst) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryParsed() = schemaProcessor.AsyncExecute(simpleAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkSimpleQueryPlanned() = schemaProcessor.AsyncExecute(simpleExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkSimpleQueryPlanned() = schemaProcessor.AsyncExecute(simpleExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.flat) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.flat, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryParsed() = schemaProcessor.AsyncExecute(flatAst) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryParsed() = schemaProcessor.AsyncExecute(flatAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFlatQueryPlanned() = schemaProcessor.AsyncExecute(flatExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkFlatQueryPlanned() = schemaProcessor.AsyncExecute(flatExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.nested) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.nested, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryParsed() = schemaProcessor.AsyncExecute(nestedAst) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryParsed() = schemaProcessor.AsyncExecute(nestedAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkNestedQueryPlanned() = schemaProcessor.AsyncExecute(nestedExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkNestedQueryPlanned() = schemaProcessor.AsyncExecute(nestedExecutionPlan, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFilteredQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.filtered) |> Async.RunSynchronously
+ member _.BenchmarkFilteredQueryUnparsed() = schemaProcessor.AsyncExecute(QueryStrings.filtered, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFilteredQueryParsed() = schemaProcessor.AsyncExecute(filteredAst) |> Async.RunSynchronously
+ member _.BenchmarkFilteredQueryParsed() = schemaProcessor.AsyncExecute(filteredAst, getInputContext) |> Async.RunSynchronously
[]
- member _.BenchmarkFilteredQueryPlanned() = schemaProcessor.AsyncExecute(filteredExecutionPlan) |> Async.RunSynchronously
+ member _.BenchmarkFilteredQueryPlanned() = schemaProcessor.AsyncExecute(filteredExecutionPlan, getInputContext) |> Async.RunSynchronously
diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests.Server/Schema.fs b/tests/FSharp.Data.GraphQL.IntegrationTests.Server/Schema.fs
index b94cd567d..b3f314c66 100644
--- a/tests/FSharp.Data.GraphQL.IntegrationTests.Server/Schema.fs
+++ b/tests/FSharp.Data.GraphQL.IntegrationTests.Server/Schema.fs
@@ -19,19 +19,25 @@ type InputField =
Int : int
StringOption : string option
IntOption : int option
- Uri : System.Uri
- Guid : System.Guid
- GuidOption : System.Guid option }
+ Uri : Uri
+ Guid : Guid
+ GuidOption : Guid option }
type Input =
{ Single : InputField option
List : InputField list option }
+type InputFile = { File : System.IO.Stream}
+
type UploadedFile =
{ Name : string
ContentType : string
ContentAsText : string }
+type UploadedContentFile =
+ { Name : string
+ ContentAsText : string }
+
type UploadRequest =
{ Single : File
Multiple : File list
@@ -130,56 +136,78 @@ module Schema =
args = [ Define.Input("input", Nullable InputType, description = "The input to be echoed as an output.") ],
resolve = fun ctx _ -> ctx.TryArg("input")) ])
+ let InputFileObject = Define.InputObject(
+ name = "InputFile",
+ fields =
+ [
+ Define.Input("file", FileType)
+ ])
+
+ // let MutationType =
+ // let contentAsText (stream : System.IO.Stream) =
+ // use reader = new System.IO.StreamReader(stream, Encoding.UTF8)
+ // reader.ReadToEnd()
+ // let mapUploadToOutput (file : File) =
+ // { Name = file.Name; ContentType = file.ContentType; ContentAsText = contentAsText file.Content }
+ // let mapUploadRequestToOutput (request : UploadRequest) =
+ // { Single = mapUploadToOutput request.Single
+ // Multiple = request.Multiple |> List.map mapUploadToOutput
+ // NullableMultiple = request.NullableMultiple |> Option.map (List.map mapUploadToOutput)
+ // NullableMultipleNullable = request.NullableMultipleNullable |> Option.map (List.map (Option.map mapUploadToOutput)) }
+ // Define.Object(
+ // name = "Mutation",
+ // fields =
+ // [ Define.Field(
+ // name = "singleUpload",
+ // typedef = UploadedFileType,
+ // description = "Uploads a single file to the server and get it back.",
+ // args = [ Define.Input("file", Upload, description = "The file to be uploaded.") ],
+ // resolve = fun ctx _ -> mapUploadToOutput (ctx.Arg("file")))
+ // Define.Field(
+ // name = "nullableSingleUpload",
+ // typedef = StructNullable UploadedFileType,
+ // description = "Uploads (maybe) a single file to the server and get it back (maybe).",
+ // args = [ Define.Input("file", Nullable Upload, description = "The file to be uploaded.") ],
+ // resolve = fun ctx _ -> ctx.TryArg("file") |> ValueOption.flatten |> ValueOption.map mapUploadToOutput)
+ // Define.Field(
+ // name = "multipleUpload",
+ // typedef = ListOf UploadedFileType,
+ // description = "Uploads a list of files to the server and get them back.",
+ // args = [ Define.Input("files", ListOf Upload, description = "The files to upload.") ],
+ // resolve = fun ctx _ -> ctx.Arg("files") |> Seq.map mapUploadToOutput)
+ // Define.Field(
+ // name = "nullableMultipleUpload",
+ // typedef = StructNullable (ListOf UploadedFileType),
+ // description = "Uploads (maybe) a list of files to the server and get them back (maybe).",
+ // args = [ Define.Input("files", Nullable (ListOf Upload), description = "The files to upload.") ],
+ // resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.flatten |> ValueOption.map (Seq.map mapUploadToOutput))
+ // Define.Field(
+ // name = "nullableMultipleNullableUpload",
+ // typedef = StructNullable (ListOf (Nullable UploadedFileType)),
+ // description = "Uploads (maybe) a list of files (maybe) to the server and get them back (maybe).",
+ // args = [ Define.Input("files", Nullable (ListOf (Nullable Upload)), description = "The files to upload.") ],
+ // resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.flatten |> ValueOption.map (Seq.map (Option.map mapUploadToOutput)))
+ // Define.Field(
+ // name = "uploadRequest",
+ // typedef = UploadResponseType,
+ // description = "Upload several files in different forms.",
+ // args = [ Define.Input("request", UploadRequestType, description = "The request for uploading several files in different forms.") ],
+ // resolve = fun ctx _ -> mapUploadRequestToOutput (ctx.Arg("request"))) ])
let MutationType =
- let contentAsText (stream : System.IO.Stream) =
- use reader = new System.IO.StreamReader(stream, Encoding.UTF8)
+ let getFileContent (ctx : ResolveFieldContext) argName =
+ let stream = ctx.Arg argName
+ use reader = new System.IO.StreamReader(stream, Encoding.UTF8, true)
reader.ReadToEnd()
- let mapUploadToOutput (file : File) =
- { Name = file.Name; ContentType = file.ContentType; ContentAsText = contentAsText file.Content }
- let mapUploadRequestToOutput (request : UploadRequest) =
- { Single = mapUploadToOutput request.Single
- Multiple = request.Multiple |> List.map mapUploadToOutput
- NullableMultiple = request.NullableMultiple |> Option.map (List.map mapUploadToOutput)
- NullableMultipleNullable = request.NullableMultipleNullable |> Option.map (List.map (Option.map mapUploadToOutput)) }
- Define.Object(
- name = "Mutation",
+
+ Define.Object (
+ name = "MutationType",
fields =
- [ Define.Field(
- name = "singleUpload",
- typedef = UploadedFileType,
- description = "Uploads a single file to the server and get it back.",
- args = [ Define.Input("file", Upload, description = "The file to be uploaded.") ],
- resolve = fun ctx _ -> mapUploadToOutput (ctx.Arg("file")))
- Define.Field(
- name = "nullableSingleUpload",
- typedef = StructNullable UploadedFileType,
- description = "Uploads (maybe) a single file to the server and get it back (maybe).",
- args = [ Define.Input("file", Nullable Upload, description = "The file to be uploaded.") ],
- resolve = fun ctx _ -> ctx.TryArg("file") |> ValueOption.flatten |> ValueOption.map mapUploadToOutput)
- Define.Field(
- name = "multipleUpload",
- typedef = ListOf UploadedFileType,
- description = "Uploads a list of files to the server and get them back.",
- args = [ Define.Input("files", ListOf Upload, description = "The files to upload.") ],
- resolve = fun ctx _ -> ctx.Arg("files") |> Seq.map mapUploadToOutput)
- Define.Field(
- name = "nullableMultipleUpload",
- typedef = StructNullable (ListOf UploadedFileType),
- description = "Uploads (maybe) a list of files to the server and get them back (maybe).",
- args = [ Define.Input("files", Nullable (ListOf Upload), description = "The files to upload.") ],
- resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.flatten |> ValueOption.map (Seq.map mapUploadToOutput))
- Define.Field(
- name = "nullableMultipleNullableUpload",
- typedef = StructNullable (ListOf (Nullable UploadedFileType)),
- description = "Uploads (maybe) a list of files (maybe) to the server and get them back (maybe).",
- args = [ Define.Input("files", Nullable (ListOf (Nullable Upload)), description = "The files to upload.") ],
- resolve = fun ctx _ -> ctx.TryArg("files") |> ValueOption.flatten |> ValueOption.map (Seq.map (Option.map mapUploadToOutput)))
- Define.Field(
- name = "uploadRequest",
- typedef = UploadResponseType,
- description = "Upload several files in different forms.",
- args = [ Define.Input("request", UploadRequestType, description = "The request for uploading several files in different forms.") ],
- resolve = fun ctx _ -> mapUploadRequestToOutput (ctx.Arg("request"))) ])
+ [ Define.Field ("uploadFile", StringType, "", [ Define.Input ("input", FileType) ],
+ (fun ctx _ -> getFileContent ctx "input"));
+ Define.Field ("uploadFileComplex", StringType, "", [ Define.Input ("input", InputFileObject) ],
+ (fun ctx _ -> getFileContent ctx "input"))
+ ]
+ )
let schema : ISchema = upcast Schema(QueryType, MutationType)
diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs
index 89e9201ce..3479825ab 100644
--- a/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs
+++ b/tests/FSharp.Data.GraphQL.IntegrationTests/LocalProviderTests.fs
@@ -9,6 +9,7 @@ let [] ServerUrl = "http://localhost:8085"
let [] EmptyGuidAsString = "00000000-0000-0000-0000-000000000000"
type Provider = GraphQLProvider
+// type FileProvider = GraphQLProvider
let context = Provider.GetContext(ServerUrl)
@@ -251,6 +252,13 @@ module SingleOptionalUploadOperation =
result.Data.Value.NullableSingleUpload.Value.ContentAsText |> equals file.Content
result.Data.Value.NullableSingleUpload.Value.ContentType |> equals file.ContentType)
+
+// []
+// let ``Should be able to execute a upload by passing a file with new approach``() =
+// let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" }
+// let result = SingleOptionalUploadOperation.fileOperation.Run(file.MakeUpload())
+// |> SingleOptionalUploadOperation.validateResult (Some file)
+
[]
let ``Should be able to execute a single optional upload by passing a file``() =
let file = { Name = "file.txt"; ContentType = "text/plain"; Content = "Sample text file contents" }
diff --git a/tests/FSharp.Data.GraphQL.IntegrationTests/introspection.json b/tests/FSharp.Data.GraphQL.IntegrationTests/introspection.json
index fed38ddc5..b397d2f41 100644
--- a/tests/FSharp.Data.GraphQL.IntegrationTests/introspection.json
+++ b/tests/FSharp.Data.GraphQL.IntegrationTests/introspection.json
@@ -1,5 +1,5 @@
{
- "documentId": -837497709,
+ "documentId": 1466593774,
"data": {
"__schema": {
"queryType": {
@@ -1438,7 +1438,7 @@
"name": "filter",
"description": null,
"type": {
- "kind": "SCALAR",
+ "kind": "INPUT_OBJECT",
"name": "ObjectListFilter",
"ofType": null
},
@@ -1551,6 +1551,22 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "satelitesCount",
+ "description": "The number of satelites of the planet.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -1605,6 +1621,51 @@
"name": "Mutation",
"description": null,
"fields": [
+ {
+ "name": "patchPlanet",
+ "description": null,
+ "args": [
+ {
+ "name": "id",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "planet",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "InputPatchPlanet",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "Planet",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "setMoon",
"description": "Defines if a planet is actually a moon or not.",
@@ -1653,11 +1714,52 @@
"possibleTypes": null
},
{
- "kind": "SCALAR",
+ "kind": "INPUT_OBJECT",
+ "name": "InputPatchPlanet",
+ "description": "A planet in the Star Wars universe.",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "name",
+ "description": null,
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "satelitesCount",
+ "description": null,
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "isMoon",
+ "description": null,
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
"name": "ObjectListFilter",
"description": "The `Filter` scalar type represents a filter on one or more fields of an object in an object list. The filter is represented by a JSON object where the fields are the complemented by specific suffixes to represent a query.",
"fields": null,
- "inputFields": null,
+ "inputFields": [],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
diff --git a/tests/FSharp.Data.GraphQL.Tests/AbstractionTests.fs b/tests/FSharp.Data.GraphQL.Tests/AbstractionTests.fs
index 98297ab33..1eb3fe22f 100644
--- a/tests/FSharp.Data.GraphQL.Tests/AbstractionTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/AbstractionTests.fs
@@ -101,7 +101,7 @@ let ``Execute handles execution of abstract types: isTypeOf is used to resolve r
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
let expected =
NameValueLookup.ofList
@@ -126,7 +126,7 @@ let ``Execute handles execution of abstract types: not specified Interface types
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
let expected = NameValueLookup.ofList [ "name", "Odie" :> obj; "woofs", upcast true ]
@@ -146,7 +146,7 @@ let ``Execute handles execution of abstract types: not specified Interface types
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
let expected = NameValueLookup.ofList [ "name", "Garfield" :> obj; "meows", upcast false ]
@@ -173,7 +173,7 @@ let ``Execute handles execution of abstract types: absent field resolution produ
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
ensureRequestError result <| fun [ dogError; catError ] ->
dogError |> ensureValidationError "Field 'unknownField1' is not defined in schema type 'Dog'." [ "pets"; "unknownField1" ]
catError |> ensureValidationError "Field 'unknownField2' is not defined in schema type 'Cat'." [ "pets"; "unknownField2" ]
@@ -195,7 +195,7 @@ let ``Execute handles execution of abstract types: absent type resolution produc
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
ensureRequestError result <| fun [ catError; dogError ] ->
catError |> ensureValidationError "Field 'unknownField2' is not defined in schema type 'Cat'." [ "pets"; "unknownField2" ]
dogError |> ensureValidationError "Inline fragment has type condition 'UnknownDog', but that type does not exist in the schema." [ "pets" ]
@@ -215,7 +215,7 @@ let ``Execute handles execution of abstract types: absent type resolution produc
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
ensureRequestError result <| fun [ catError; dogError ] ->
catError |> ensureValidationError "Field 'unknownField1' is not defined in schema type 'Dog'." [ "pets"; "unknownField1" ]
dogError |> ensureValidationError "Inline fragment has type condition 'UnknownCat', but that type does not exist in the schema." [ "pets" ]
@@ -272,7 +272,7 @@ let ``Execute handles execution of abstract types: isTypeOf is used to resolve r
}
}"""
- let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query, getMockInputContext)
let expected =
NameValueLookup.ofList
@@ -297,7 +297,7 @@ let ``Execute handles execution of abstract types: not specified Union types mus
}
}"""
- let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query, getMockInputContext)
let expected = NameValueLookup.ofList [ "name", "Odie" :> obj; "woofs", upcast true ]
@@ -317,7 +317,7 @@ let ``Execute handles execution of abstract types: not specified Union types mus
}
}"""
- let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithUnion.Value.AsyncExecute (parse query, getMockInputContext)
let expected = NameValueLookup.ofList [ "name", "Garfield" :> obj; "meows", upcast false ]
@@ -344,7 +344,7 @@ let ``Execute handles execution of abstract types: absent field resolution produ
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
ensureRequestError result <| fun [ dogError; catError ] ->
dogError |> ensureValidationError "Field 'unknownField1' is not defined in schema type 'Dog'." [ "pets"; "unknownField1" ]
catError |> ensureValidationError "Field 'unknownField2' is not defined in schema type 'Cat'." [ "pets"; "unknownField2" ]
@@ -366,7 +366,7 @@ let ``Execute handles execution of abstract types: absent type resolution produc
}
}"""
- let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query)
+ let result = sync <| schemaWithInterface.Value.AsyncExecute (parse query, getMockInputContext)
ensureRequestError result <| fun [ dogError; catError ] ->
dogError |> ensureValidationError "Field 'unknownField1' is not defined in schema type 'Dog'." [ "pets"; "unknownField1" ]
catError |> ensureValidationError "Inline fragment has type condition 'UnknownCat', but that type does not exist in the schema." [ "pets" ]
diff --git a/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs b/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs
index 8c45c458a..3ce28c0d7 100644
--- a/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs
@@ -286,7 +286,7 @@ let ``Resolver error`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -321,7 +321,7 @@ let ``Resolver list error`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -354,7 +354,7 @@ let ``Nullable error`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -386,7 +386,7 @@ let ``Single Root object field - Defer and Stream`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -423,7 +423,7 @@ let ``Single Root object list field - Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -465,7 +465,7 @@ let ``Single Root object list field - Stream`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -497,7 +497,7 @@ let ``Interface field - Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -532,7 +532,7 @@ let ``Interface list field - Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -572,7 +572,7 @@ let ``Each live result should be sent as soon as it is computed`` () =
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
resetLiveData()
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -611,7 +611,7 @@ let ``Live Query`` () =
}
}"""
resetLiveData()
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -653,7 +653,7 @@ let ``Parallel Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -705,7 +705,7 @@ let ``Parallel Stream`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -742,7 +742,7 @@ let ``Inner Object List Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -775,7 +775,7 @@ let ``Inner Object List Stream`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -823,7 +823,7 @@ let ``Nested Inner Object List Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -880,7 +880,7 @@ let ``Nested Inner Object List Stream`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -909,7 +909,7 @@ let ``Simple Defer and Stream`` () =
b
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -955,7 +955,7 @@ let ``List Defer``() =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -982,7 +982,7 @@ let ``List Fragment Defer and Stream - Exclusive``() =
]
]
let expectedDeferred = DeferredResult ("Union A", [ "testData"; "list"; 0; "a" ])
- let query = sprintf """{
+ let query = """{
testData {
a
list {
@@ -997,7 +997,7 @@ let ``List Fragment Defer and Stream - Exclusive``() =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1024,7 +1024,7 @@ let ``List Fragment Defer and Stream - Common``() =
]
]
let expectedDeferred = DeferredResult ("2", [ "testData"; "list"; 0; "id" ])
- let query = sprintf """{
+ let query = """{
testData {
a
list {
@@ -1039,7 +1039,7 @@ let ``List Fragment Defer and Stream - Common``() =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1083,7 +1083,7 @@ let ``List inside root - Stream``() =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1137,7 +1137,7 @@ let ``List Stream``() =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1188,7 +1188,7 @@ let ``Should buffer stream list correctly by timing information``() =
|> parse
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1249,7 +1249,7 @@ let ``Should buffer stream list correctly by count information``() =
}"""
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1290,7 +1290,7 @@ let ``Union Defer`` () =
NameValueLookup.ofList [ "id", upcast "1"; "a", upcast "Union A" ],
[ "testData"; "union" ]
)
- let query = sprintf """{
+ let query = """{
testData {
a
b
@@ -1306,7 +1306,7 @@ let ``Union Defer`` () =
}
}
}"""
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1336,7 +1336,7 @@ let ``Each deferred result should be sent as soon as it is computed``() =
}"""
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1345,7 +1345,7 @@ let ``Each deferred result should be sent as soon as it is computed``() =
elif Seq.length sub.Received = 2 then mre2.Set() |> ignore)
// The second result is a delayed async field, which is set to compute the value for 5 seconds.
// The first result should come almost instantly, as it is not a delayed computed field.
- // Therefore, let's assume that if it does not come in at least 3 seconds, test has failed.
+ // Therefore, let's assume that if it does not come in at least 3 seconds, the test has failed.
if TimeSpan.FromSeconds(float (ms 3)) |> mre1.WaitOne |> not
then fail "Timeout while waiting for first deferred result"
if TimeSpan.FromSeconds(float (ms 10)) |> mre2.WaitOne |> not
@@ -1383,7 +1383,7 @@ let ``Each deferred result of a list should be sent as soon as it is computed``
}"""
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
@@ -1392,7 +1392,7 @@ let ``Each deferred result of a list should be sent as soon as it is computed``
elif Seq.length sub.Received = 2 then mre2.Set() |> ignore)
// The first result is a delayed async field, which is set to compute the value for 5 seconds.
// The second result should come first, almost instantly, as it is not a delayed computed field.
- // Therefore, let's assume that if it does not come in at least 4 seconds, test has failed.
+ // Therefore, let's assume that if it does not come in at least 4 seconds, the test has failed.
if TimeSpan.FromSeconds(float (ms 4)) |> mre1.WaitOne |> not
then fail "Timeout while waiting for first deferred result"
if TimeSpan.FromSeconds(float (ms 10)) |> mre2.WaitOne |> not
@@ -1425,7 +1425,7 @@ let ``Each streamed result should be sent as soon as it is computed - async seq`
}"""
use mre1 = new ManualResetEvent(false)
use mre2 = new ManualResetEvent(false)
- let result = query |> executor.AsyncExecute |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
ensureDeferred result <| fun data errors deferred ->
empty errors
data |> equals (upcast expectedDirect)
diff --git a/tests/FSharp.Data.GraphQL.Tests/DirectivesTests.fs b/tests/FSharp.Data.GraphQL.Tests/DirectivesTests.fs
index a46cc2856..222cc0696 100644
--- a/tests/FSharp.Data.GraphQL.Tests/DirectivesTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/DirectivesTests.fs
@@ -17,7 +17,7 @@ let schema =
Schema(Define.Object("TestType", [ Define.AutoField("a", StringType); Define.AutoField("b", StringType) ])) :> Schema
let private execAndCompare query expected =
- let result = sync <| Executor(schema).AsyncExecute(parse query, data)
+ let result = sync <| Executor(schema).AsyncExecute(parse query, getMockInputContext, data)
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
diff --git a/tests/FSharp.Data.GraphQL.Tests/ExecutionTests.fs b/tests/FSharp.Data.GraphQL.Tests/ExecutionTests.fs
index a1820de10..07bc58271 100644
--- a/tests/FSharp.Data.GraphQL.Tests/ExecutionTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/ExecutionTests.fs
@@ -143,7 +143,7 @@ let ``Execution handles basic tasks: executes arbitrary code`` () =
let schema = Schema(DataType)
let schemaProcessor = Executor(schema)
let params' = JsonDocument.Parse("""{"size":100}""").RootElement.Deserialize>(serializerOptions)
- let result = sync <| schemaProcessor.AsyncExecute(ast, data, variables = params', operationName = "Example")
+ let result = sync <| schemaProcessor.AsyncExecute(ast, getMockInputContext, data, variables = params', operationName = "Example")
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
@@ -191,7 +191,7 @@ let ``Execution handles basic tasks: merges parallel fragments`` () =
]
"c", upcast "Cherry"
]
- let result = sync <| schemaProcessor.AsyncExecute(ast, obj())
+ let result = sync <| schemaProcessor.AsyncExecute(ast, getMockInputContext, obj())
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
@@ -201,8 +201,8 @@ let ``Execution handles basic tasks: threads root value context correctly`` () =
let query = "query Example { a }"
let data = { Thing = "" }
let Thing = Define.Object("Type", [ Define.Field("a", StringType, fun _ value -> value.Thing <- "thing"; value.Thing) ])
- let result = sync <| Executor(Schema(Thing)).AsyncExecute(parse query, data)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| Executor(Schema(Thing)).AsyncExecute(parse query, getMockInputContext, data)
+ ensureDirect result <| fun _ errors -> empty errors
equals "thing" data.Thing
type TestTarget =
@@ -223,8 +223,8 @@ let ``Execution handles basic tasks: correctly threads arguments`` () =
value.Str <- ctx.TryArg("stringArg")
value.Str) ])
- let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, data)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, getMockInputContext,data)
+ ensureDirect result <| fun _ errors -> empty errors
equals (ValueSome 123) data.Num
equals (ValueSome "foo") data.Str
@@ -242,8 +242,8 @@ let ``Execution handles basic tasks: correctly handles null arguments`` () =
value.Str <- ctx.TryArg("stringArg")
value.Str) ])
- let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, data)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, getMockInputContext, data)
+ ensureDirect result <| fun _ errors -> empty errors
equals ValueNone data.Num
equals ValueNone data.Str
@@ -272,8 +272,8 @@ let ``Execution handles basic tasks: correctly handles discriminated union argum
value.Num <- ValueSome 123
value.Str
| _ -> ValueNone) ])
- let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, data)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, getMockInputContext, data)
+ ensureDirect result <| fun _ errors -> empty errors
equals (ValueSome 123) data.Num
equals (ValueSome "foo") data.Str
@@ -300,8 +300,8 @@ let ``Execution handles basic tasks: correctly handles Enum arguments`` () =
value.Num <- ValueSome 123
value.Str
| _ -> ValueNone) ])
- let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, data)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| Executor(Schema(Type)).AsyncExecute(parse query, getMockInputContext, data)
+ ensureDirect result <| fun _ errors -> empty errors
equals (ValueSome 123) data.Num
equals (ValueSome "foo") data.Str
@@ -313,7 +313,7 @@ let ``Execution handles basic tasks: uses the inline operation if no operation n
"Type", [
Define.Field("a", StringType, fun _ x -> x.A)
]))
- let result = sync <| Executor(schema).AsyncExecute(parse "{ a }", { A = "b" })
+ let result = sync <| Executor(schema).AsyncExecute(parse "{ a }", getMockInputContext, { A = "b" })
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast NameValueLookup.ofList ["a", "b" :> obj])
@@ -325,7 +325,7 @@ let ``Execution handles basic tasks: uses the only operation if no operation nam
"Type", [
Define.Field("a", StringType, fun _ x -> x.A)
]))
- let result = sync <| Executor(schema).AsyncExecute(parse "query Example { a }", { A = "b" })
+ let result = sync <| Executor(schema).AsyncExecute(parse "query Example { a }", getMockInputContext, { A = "b" })
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast NameValueLookup.ofList ["a", "b" :> obj])
@@ -338,7 +338,7 @@ let ``Execution handles basic tasks: uses the named operation if operation name
Define.Field("a", StringType, fun _ x -> x.A)
]))
let query = "query Example { first: a } query OtherExample { second: a }"
- let result = sync <| Executor(schema).AsyncExecute(parse query, { A = "b" }, operationName = "OtherExample")
+ let result = sync <| Executor(schema).AsyncExecute(parse query, getMockInputContext, { A = "b" }, operationName = "OtherExample")
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast NameValueLookup.ofList ["second", "b" :> obj])
@@ -350,7 +350,7 @@ let ``Execution handles basic tasks: list of scalars`` () =
"Type", [
Define.Field("strings", ListOf StringType, fun _ _ -> ["foo"; "bar"; "baz"])
]))
- let result = sync <| Executor(schema).AsyncExecute("query Example { strings }")
+ let result = sync <| Executor(schema).AsyncExecute("query Example { strings }", getMockInputContext)
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast NameValueLookup.ofList ["strings", box [ box "foo"; upcast "bar"; upcast "baz" ]])
@@ -366,7 +366,7 @@ let ``Execution when querying the same field twice will return it`` () =
Define.Field("b", IntType, fun _ x -> x.B)
]))
let query = "query Example { a, b, a }"
- let result = sync <| Executor(schema).AsyncExecute(query, { A = "aa"; B = 2 });
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext, { A = "aa"; B = 2 });
let expected =
NameValueLookup.ofList [
"a", upcast "aa"
@@ -383,8 +383,8 @@ let ``Execution when querying returns unique document id with response`` () =
Define.Field("a", StringType, fun _ x -> x.A)
Define.Field("b", IntType, fun _ x -> x.B)
]))
- let result1 = sync <| Executor(schema).AsyncExecute("query Example { a, b, a }", { A = "aa"; B = 2 })
- let result2 = sync <| Executor(schema).AsyncExecute("query Example { a, b, a }", { A = "aa"; B = 2 })
+ let result1 = sync <| Executor(schema).AsyncExecute("query Example { a, b, a }", getMockInputContext, { A = "aa"; B = 2 })
+ let result2 = sync <| Executor(schema).AsyncExecute("query Example { a, b, a }", getMockInputContext, { A = "aa"; B = 2 })
result1.DocumentId |> notEquals Unchecked.defaultof
result1.DocumentId |> equals result2.DocumentId
match result1,result2 with
@@ -434,7 +434,7 @@ let ``Execution handles errors: properly propagates errors`` () =
]
let result =
let variables = { Inner = { Kaboom = null }; InnerPartialSuccess = { Kaboom = "Yes, Rico, Kaboom" } }
- sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } partialSuccess { kaboom } }", variables)
+ sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } partialSuccess { kaboom } }", getMockInputContext, variables)
ensureDirect result <| fun data errors ->
result.DocumentId |> notEquals Unchecked.defaultof
data |> equals (upcast expectedData)
@@ -448,7 +448,7 @@ let ``Execution handles errors: exceptions`` () =
Define.Field("a", StringType, fun _ _ -> failwith "Resolver Error!")
]))
let expectedError = GQLProblemDetails.CreateWithKind ("Resolver Error!", Execution, [ box "a" ])
- let result = sync <| Executor(schema).AsyncExecute("query Test { a }", ())
+ let result = sync <| Executor(schema).AsyncExecute("query Test { a }", getMockInputContext, ())
ensureRequestError result <| fun [ error ] -> error |> equals expectedError
[]
@@ -472,7 +472,7 @@ let ``Execution handles errors: nullable list fields`` () =
GQLProblemDetails.CreateWithKind ("Resolver Error!", Execution, [ box "list"; 0; "error" ])
GQLProblemDetails.CreateWithKind ("Resolver Error!", Execution, [ box "list"; 1; "error" ])
]
- let result = sync <| Executor(schema).AsyncExecute("query Test { list { error } }", ())
+ let result = sync <| Executor(schema).AsyncExecute("query Test { list { error } }", getMockInputContext, ())
ensureDirect result <| fun data errors ->
result.DocumentId |> notEquals Unchecked.defaultof
data |> equals (upcast expectedData)
@@ -480,12 +480,12 @@ let ``Execution handles errors: nullable list fields`` () =
[]
-let ``Execution handles errors: additional error added when exception is rised in a nullable field resolver`` () =
+let ``Execution handles errors: additional error added when exception is raised in a nullable field resolver`` () =
let InnerNullableExceptionObjType =
// executeResolvers/resolveWith, case 1
let resolveWithException (ctx : ResolveFieldContext) (_ : InnerNullableTest) : string option =
ctx.AddError { new IGQLError with member _.Message = "Non-critical error" }
- raise (System.Exception "Unexpected error")
+ raise (Exception "Unexpected error")
Define.Object(
"InnerNullableException", [
Define.Field("kaboom", Nullable StringType, resolve = resolveWithException)
@@ -508,7 +508,7 @@ let ``Execution handles errors: additional error added when exception is rised i
]
let result =
let variables = { Inner = { Kaboom = null }; InnerPartialSuccess = { Kaboom = "Yes, Rico, Kaboom" } }
- sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", variables)
+ sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", getMockInputContext, variables)
ensureDirect result <| fun data errors ->
result.DocumentId |> notEquals Unchecked.defaultof
data |> equals (upcast expectedData)
@@ -542,7 +542,7 @@ let ``Execution handles errors: additional error added when None returned from a
]
let result =
let variables = { Inner = { Kaboom = null }; InnerPartialSuccess = { Kaboom = "Yes, Rico, Kaboom" } }
- sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", variables)
+ sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", getMockInputContext, variables)
ensureDirect result <| fun data errors ->
result.DocumentId |> notEquals Unchecked.defaultof
data |> equals (upcast expectedData)
@@ -554,7 +554,7 @@ let ``Execution handles errors: additional error added when exception is rised i
// executeResolvers/resolveWith, case 3
let resolveWithException (ctx : ResolveFieldContext) (_ : InnerNullableTest) : string =
ctx.AddError { new IGQLError with member _.Message = "Non-critical error" }
- raise (System.Exception "Fatal error")
+ raise (Exception "Fatal error")
Define.Object(
"InnerNonNullableException", [
Define.Field("kaboom", StringType, resolve = resolveWithException)
@@ -571,7 +571,7 @@ let ``Execution handles errors: additional error added when exception is rised i
]
let result =
let variables = { Inner = { Kaboom = "Yes, Rico, Kaboom" }; InnerPartialSuccess = { Kaboom = "Yes, Rico, Kaboom" } }
- sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", variables)
+ sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", getMockInputContext, variables)
ensureRequestError result <| fun errors ->
result.DocumentId |> notEquals Unchecked.defaultof
errors |> equals expectedErrors
@@ -599,7 +599,7 @@ let ``Execution handles errors: additional error added and when null returned fr
]
let result =
let variables = { Inner = { Kaboom = "Yes, Rico, Kaboom" }; InnerPartialSuccess = { Kaboom = "Yes, Rico, Kaboom" } }
- sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", variables)
+ sync <| Executor(schema).AsyncExecute("query Example { inner { kaboom } }", getMockInputContext, variables)
ensureRequestError result <| fun errors ->
result.DocumentId |> notEquals Unchecked.defaultof
errors |> equals expectedErrors
diff --git a/tests/FSharp.Data.GraphQL.Tests/ExecutorMiddlewareTests.fs b/tests/FSharp.Data.GraphQL.Tests/ExecutorMiddlewareTests.fs
index 6611603b4..0039c3cbc 100644
--- a/tests/FSharp.Data.GraphQL.Tests/ExecutorMiddlewareTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/ExecutorMiddlewareTests.fs
@@ -55,10 +55,10 @@ let compileMiddleware (ctx : SchemaCompileContext) (next : SchemaCompileContext
// After the schema has been compiled, update the input fields to flip every boolean input
let postCompileMiddleware (schema : ISchema) (next : ISchema -> unit) =
- let flipBools execute value vars =
+ let flipBools ctx execute value vars =
match value with
- | BooleanValue b -> execute (BooleanValue (not b)) vars
- | _ -> execute value vars
+ | BooleanValue b -> ctx execute (BooleanValue (not b)) vars
+ | _ -> ctx execute value vars
schema.TypeMap.ToSeq()
|> Seq.iter(fun (n, def) ->
match def with
@@ -79,7 +79,7 @@ let planningMiddleware (ctx : PlanningContext) (next : PlanningContext -> Execut
{ result with Metadata = metadata }
// On the execution phase, we remove the evaluation of the c field
-let executionMiddleware (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
+let executionMiddleware (inputContext : InputExecutionContextProvider) (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) =
let chooserS set =
set |> List.choose (fun x -> match x with Field f when f.Name <> "c" -> Some x | _ -> None)
let chooserK kind =
@@ -108,7 +108,7 @@ let executor = Executor(schema, [ middleware ])
[]
let ``Executor middleware: change fields and measure planning time`` () =
- let result = sync <| executor.AsyncExecute(ast)
+ let result = sync <| executor.AsyncExecute(ast, getMockInputContext)
let expected =
NameValueLookup.ofList
[ "testData",
diff --git a/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj b/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj
index 0b0390c21..a640b5388 100644
--- a/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj
+++ b/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj
@@ -70,6 +70,7 @@
+
diff --git a/tests/FSharp.Data.GraphQL.Tests/FileTests.fs b/tests/FSharp.Data.GraphQL.Tests/FileTests.fs
new file mode 100644
index 000000000..42dfc93d3
--- /dev/null
+++ b/tests/FSharp.Data.GraphQL.Tests/FileTests.fs
@@ -0,0 +1,120 @@
+module FSharp.Data.GraphQL.Tests.FileTests
+
+open System.Collections.Immutable
+open System.IO
+open System.Text
+open System.Text.Json
+open FSharp.Data.GraphQL
+open FSharp.Data.GraphQL.Parser
+open FSharp.Data.GraphQL.Types
+open Xunit
+
+type Root = { File : Stream }
+
+let QueryType =
+ Define.Object (
+ name = "QueryType",
+ fields =
+ [ Define.Field ("dummy", StringType, fun _ _ -> "dummy")]
+ )
+
+type Input = {
+ File : Stream
+ File2 : Stream option
+}
+
+let InputObject = Define.InputObject(
+ name = "Input",
+ fields =
+ [
+ Define.Input("file", FileType)
+ Define.Input("file2", Nullable FileType)
+ ])
+
+let MutationType =
+ Define.Object (
+ name = "MutationType",
+ fields =
+ [ Define.Field ("uploadFile", StringType, "", [ Define.Input ("input", FileType) ],
+ (fun ctx () ->
+ let stream = ctx.Arg "input"
+ use reader = new StreamReader(stream, Encoding.UTF8, true)
+ reader.ReadToEnd()
+ ));
+ Define.Field ("uploadFileComplex", StringType, "", [ Define.Input ("input", InputObject) ],
+ (fun ctx () ->
+ let input = ctx.Arg "input"
+ let reader = new StreamReader(input.File, Encoding.UTF8, true)
+ let fileContent = reader.ReadToEnd()
+ let file2Content = match input.File2 with
+ | Some file2 ->
+ let reader2 = new StreamReader(file2, Encoding.UTF8, true)
+ reader2.ReadToEnd()
+ | None -> ""
+ fileContent + file2Content
+ ))
+ ]
+ )
+let schema = Schema (QueryType, MutationType)
+let executor = Executor (schema, [])
+let execute (query : string) = executor.AsyncExecute (query, getMockInputContext) |> sync
+let executeWithVariables ( query : string, variables : ImmutableDictionary) =
+ executor.AsyncExecute (ast = parse query, getInputContext = getMockInputContext, variables = variables) |> sync
+
+let mutationWithVariable = """mutation uploadFile ($file : FileType!) {
+ uploadFile (input : $file)
+}
+"""
+
+let mutationWithConstant = """mutation uploadFile () {
+ uploadFile (input : "fileKey")
+}"""
+
+let mutationComplexObject = """mutation uploadFile () {
+ uploadFileComplex (input : { file : "fileKey" })
+}"""
+
+let mutationComplexObjectWithTwoFiles = """mutation uploadFile () {
+ uploadFileComplex (input : {file : "fileKey", file2: "fileKey2" })
+}"""
+
+[]
+let ``File type: Must upload file as input scalar using inline string as a file name`` () =
+ let expected = NameValueLookup.ofList [ "uploadFile", MockInputContext.mockFileText ]
+ let result = execute mutationWithConstant
+ ensureDirect result <| fun data errors ->
+ empty errors
+ data |> equals (upcast expected)
+ ()
+
+[]
+let ``File type: Must upload a file as input scalar using a variable`` () =
+ let expected = NameValueLookup.ofList [ "uploadFile", MockInputContext.mockFileText ]
+ let jsonVariable = "\"fileKey\"" |> JsonDocument.Parse |> _.RootElement
+ let variables = ImmutableDictionary.Empty.Add ("file", jsonVariable)
+ let result = executeWithVariables (mutationWithVariable, variables)
+ ensureDirect result <| fun data errors ->
+ empty errors
+ data |> equals (upcast expected)
+ ()
+
+[]
+let ``File type: Must upload a file as input object field using inline string a file name`` () =
+ let expected = NameValueLookup.ofList [ "uploadFileComplex", MockInputContext.mockFileText ]
+ let result = execute mutationComplexObject
+ ensureDirect result <| fun data errors ->
+ empty errors
+ data |> equals (upcast expected)
+ ()
+
+[]
+let ``File type: Must upload two files as input object field using inline string a file name`` () =
+ let expectedContent = MockInputContext.mockFileText + MockInputContext.mockFileText2
+ let expected = NameValueLookup.ofList [
+ "uploadFileComplex", expectedContent
+ ]
+ let result = execute mutationComplexObjectWithTwoFiles
+ ensureDirect result <| fun data errors ->
+ empty errors
+ data |> equals (upcast expected)
+ ()
diff --git a/tests/FSharp.Data.GraphQL.Tests/Helpers and Extensions/NameValueLookupTests.fs b/tests/FSharp.Data.GraphQL.Tests/Helpers and Extensions/NameValueLookupTests.fs
index 339419dfb..ed8c9bd20 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Helpers and Extensions/NameValueLookupTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Helpers and Extensions/NameValueLookupTests.fs
@@ -2,7 +2,7 @@
open Helpers
open Xunit
-open FSharp.Data.GraphQL.Shared
+open FSharp.Data.GraphQL
[]
let ``Lookups containing different lists as inner items should not be equal`` () =
@@ -25,4 +25,4 @@ let ``Lookups containing different lists as inner items should not be equal`` ()
]
]
]
- lookup1 |> notEquals lookup2
\ No newline at end of file
+ lookup1 |> notEquals lookup2
diff --git a/tests/FSharp.Data.GraphQL.Tests/Helpers.fs b/tests/FSharp.Data.GraphQL.Tests/Helpers.fs
index a814938be..12bad6429 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Helpers.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Helpers.fs
@@ -5,12 +5,13 @@ module internal Helpers
open System
open System.Collections.Generic
+open System.IO
open System.Linq
+open System.Text
open System.Text.Json.Serialization
open System.Threading
-open System.Threading.Tasks
-open Xunit
open FSharp.Data.GraphQL
+open Xunit
let serializerOptions = Shared.Json.getWSSerializerOptions Seq.empty
@@ -180,3 +181,38 @@ type ExecutorExtensions =
match executor.CreateExecutionPlan(queryOrMutation, ?operationName = operationName, ?meta = meta) with
| Ok executionPlan -> executionPlan
| Error _ -> fail "invalid query"; Unchecked.defaultof<_>
+
+
+module MockInputContext =
+
+ let mockFileKey = "fileKey"
+ let mockFileKey2 = "fileKey2"
+ let mockFileText = "fileText"
+ let mockFileText2 = "fileText2"
+
+ type MockInputExecutionContext () =
+
+ member _.FileKey = mockFileKey
+ member _.FileKey2 = mockFileKey2
+ member _.FileText = mockFileText
+ member _.FileText2 = mockFileText2
+ member context.Stream =
+ let bytes = Encoding.UTF8.GetBytes context.FileText
+ new MemoryStream (bytes) :> Stream
+
+ member context.Stream2 =
+ let bytes = Encoding.UTF8.GetBytes context.FileText2
+ new MemoryStream (bytes) :> Stream
+
+ interface IInputExecutionContext with
+ member context.GetFile key =
+ if (key = context.FileKey) then
+ Ok context.Stream
+ else if (key = context.FileKey2) then
+ Ok context.Stream2
+ else
+ failwith $"only file {context.FileKey} and file {context.FileKey2} exist"
+
+ let mockInputContextInstance = MockInputExecutionContext()
+
+let getMockInputContext = fun () -> MockInputContext.mockInputContextInstance :> IInputExecutionContext
diff --git a/tests/FSharp.Data.GraphQL.Tests/IntrospectionTests.fs b/tests/FSharp.Data.GraphQL.Tests/IntrospectionTests.fs
index a3cea4422..fa33e3147 100644
--- a/tests/FSharp.Data.GraphQL.Tests/IntrospectionTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/IntrospectionTests.fs
@@ -50,7 +50,7 @@ let ``Input field must be marked as nullable when defaultValue is provided`` ()
], fun _ _ -> "Only value")
])
let schema = Schema(root)
- let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery)
+ let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery, getMockInputContext)
let expected = NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
"fields", upcast [
@@ -90,7 +90,7 @@ let ``Input field must be marked as non-nullable when defaultValue is not provid
], fun _ _ -> "Only value")
])
let schema = Schema(root)
- let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery)
+ let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery, getMockInputContext)
let expected = NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
"fields", upcast [
@@ -122,7 +122,7 @@ let ``Input field must be marked as nullable when its type is nullable`` () =
], fun _ _ -> "Only value")
])
let schema = Schema(root)
- let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery)
+ let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery, getMockInputContext)
let expected = NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
"fields", upcast [
@@ -154,7 +154,7 @@ let ``Input field must be marked as nullable when its type is nullable and have
], fun _ _ -> "Only value")
])
let schema = Schema(root)
- let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery)
+ let result = sync <| Executor(schema).AsyncExecute(inputFieldQuery, getMockInputContext)
let expected = NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
"fields", upcast [
@@ -282,7 +282,7 @@ let ``Introspection schema must be serializable back and forth using json`` () =
}
}
}"""
- let result = Executor(schema).AsyncExecute(query) |> sync
+ let result = Executor(schema).AsyncExecute(query, getMockInputContext) |> sync
ensureDirect result <| fun data errors ->
empty errors
let additionalConverters = Seq.empty //seq { NameValueLookupConverter() :> JsonConverter }
@@ -317,7 +317,7 @@ let ``Core type definitions are considered nullable`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -347,7 +347,7 @@ let ``Introspection works with query and mutation sharing same generic param`` (
Define.Object("Mutation",
[ Define.Field("addUser", user, "Adds an user", [ Define.Input("input", userInput) ], fun _ u -> u |> List.head)])
let schema = Schema(query, mutation)
- Executor(schema).AsyncExecute(IntrospectionQuery.Definition) |> sync |> ignore
+ Executor(schema).AsyncExecute(IntrospectionQuery.Definition, getMockInputContext) |> sync |> ignore
[]
let ``Default field type definitions are considered non-null`` () =
@@ -374,7 +374,7 @@ let ``Default field type definitions are considered non-null`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -417,7 +417,7 @@ let ``Nullabe field type definitions are considered nullable`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -457,7 +457,7 @@ let ``StructNullabe field type definitions are considered nullable`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -499,7 +499,7 @@ let ``Default field args type definitions are considered non-null`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -546,7 +546,7 @@ let ``Nullable field args type definitions are considered nullable`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -590,7 +590,7 @@ let ``StructNullable field args type definitions are considered nullable`` () =
}
}
} }"""
- let result = sync <| Executor(schema).AsyncExecute(query)
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"__type", upcast NameValueLookup.ofList [
@@ -612,7 +612,7 @@ let ``Introspection executes an introspection query`` () =
let root = Define.Object("QueryRoot", [ Define.Field("onlyField", StringType) ])
let schema = Schema(root)
let (Patterns.Object raw) = root
- let result = sync <| Executor(schema).AsyncExecute(parse IntrospectionQuery.Definition, raw)
+ let result = sync <| Executor(schema).AsyncExecute(parse IntrospectionQuery.Definition, getMockInputContext, raw)
let expected =
NameValueLookup.ofList [
"__schema", upcast NameValueLookup.ofList [
diff --git a/tests/FSharp.Data.GraphQL.Tests/MiddlewareTests.fs b/tests/FSharp.Data.GraphQL.Tests/MiddlewareTests.fs
index 19b86c642..8859057e8 100644
--- a/tests/FSharp.Data.GraphQL.Tests/MiddlewareTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/MiddlewareTests.fs
@@ -202,15 +202,15 @@ let getExecutor (expectedFilter : ObjectListFilter voption) =
let executor = getExecutor (ValueNone)
-let execute (query : Document) = executor.AsyncExecute (query) |> sync
+let execute (query : Document) = executor.AsyncExecute (query, getMockInputContext) |> sync
let executeWithVariables (query : Document, variables : ImmutableDictionary) =
- executor.AsyncExecute (ast = query, variables = variables)
+ executor.AsyncExecute (ast = query, getInputContext = getMockInputContext, variables = variables)
|> sync
let executeAndVerifyFilter (query : Document, variables : ImmutableDictionary, filterToVerify : ObjectListFilter) =
let ex = getExecutor (ValueSome filterToVerify)
- ex.AsyncExecute (ast = query, variables = variables) |> sync
+ ex.AsyncExecute (ast = query, getInputContext = getMockInputContext, variables = variables) |> sync
let expectedThresholdErrors : GQLProblemDetails list = [
GQLProblemDetails.Create ("Query complexity exceeds maximum threshold. Please reduce query complexity and try again.")
diff --git a/tests/FSharp.Data.GraphQL.Tests/MutationTests.fs b/tests/FSharp.Data.GraphQL.Tests/MutationTests.fs
index 5d1ac5ef5..1f1f16a23 100644
--- a/tests/FSharp.Data.GraphQL.Tests/MutationTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/MutationTests.fs
@@ -24,9 +24,9 @@ type Root =
x.NumberHolder.Number <- num
return x.NumberHolder
}
- member x.ChangeFail(num): NumberHolder option =
+ member x.ChangeFail _: NumberHolder option =
failwith "Cannot change number"
- member x.AsyncChangeFail(num): Async =
+ member x.AsyncChangeFail _: Async =
async {
return failwith "Cannot change number"
}
@@ -64,7 +64,7 @@ let ``Execute handles mutation execution ordering: evaluates mutations serially`
}
}"""
- let mutationResult = sync <| Executor(schema).AsyncExecute(parse query, {NumberHolder = {Number = 6}})
+ let mutationResult = sync <| Executor(schema).AsyncExecute(parse query, getMockInputContext, {NumberHolder = {Number = 6}})
let expected =
NameValueLookup.ofList [
"first", upcast NameValueLookup.ofList [ "theNumber", 1 :> obj]
@@ -103,7 +103,7 @@ let ``Execute handles mutation execution ordering: evaluates mutations correctly
}"""
let data = {NumberHolder = {Number = 6}}
- let mutationResult = sync <| Executor(schema).AsyncExecute(parse query, data)
+ let mutationResult = sync <| Executor(schema).AsyncExecute(parse query, getMockInputContext, data)
let expected =
NameValueLookup.ofList [
"first", upcast NameValueLookup.ofList [ "theNumber", 1 :> obj]
diff --git a/tests/FSharp.Data.GraphQL.Tests/PropertyTrackerTests.fs b/tests/FSharp.Data.GraphQL.Tests/PropertyTrackerTests.fs
index 46f48f0b2..e0914e9a4 100644
--- a/tests/FSharp.Data.GraphQL.Tests/PropertyTrackerTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/PropertyTrackerTests.fs
@@ -134,7 +134,7 @@ let ``Property tracker can track indirect properties`` () =
Tracker.Direct (track "LastName" typeof typeof, [])
]
)
- let actual = tracker ImmutableDictionary.Empty info
+ let actual = tracker getMockInputContext ImmutableDictionary.Empty info
actual |> equals expected
[]
@@ -175,5 +175,5 @@ let ``Property tracker can correctly jump over properties not being part of the
]
)
- let actual = tracker ImmutableDictionary.Empty info
+ let actual = tracker getMockInputContext ImmutableDictionary.Empty info
actual |> equals expected
diff --git a/tests/FSharp.Data.GraphQL.Tests/Relay/ConnectionTests.fs b/tests/FSharp.Data.GraphQL.Tests/Relay/ConnectionTests.fs
index 39c344723..769e57513 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Relay/ConnectionTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Relay/ConnectionTests.fs
@@ -145,7 +145,7 @@ let ``Connection definition includes connection and edge fields for simple cases
}
}
}"""
- let result = sync <| Executor(schema).AsyncExecute (query)
+ let result = sync <| Executor(schema).AsyncExecute (query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"strings", upcast NameValueLookup.ofList [
@@ -186,7 +186,7 @@ let ``Connection definition includes connection and edge fields for complex case
}
}
}"""
- let result = sync <| Executor(schema).AsyncExecute (query)
+ let result = sync <| Executor(schema).AsyncExecute (query, getMockInputContext)
let expected =
NameValueLookup.ofList [
"people", upcast NameValueLookup.ofList [
diff --git a/tests/FSharp.Data.GraphQL.Tests/Relay/CursorTests.fs b/tests/FSharp.Data.GraphQL.Tests/Relay/CursorTests.fs
index 74172dac6..4071e057e 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Relay/CursorTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Relay/CursorTests.fs
@@ -95,7 +95,7 @@ let ``Relay cursor works for types with nested fileds`` () =
}
}"""
- let result = sync <| schemaProcessor.AsyncExecute (parse query)
+ let result = sync <| schemaProcessor.AsyncExecute (parse query, getMockInputContext)
match result with
| Direct (_, errors) -> empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs b/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs
index 540866ae9..aad296f5c 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs
@@ -58,7 +58,7 @@ let schema =
let execAndValidateNode (query : string) expectedDirect expectedDeferred =
- let result = sync <| Executor(schema).AsyncExecute (query)
+ let result = sync <| Executor(schema).AsyncExecute (query, getMockInputContext)
match expectedDeferred with
| Some expectedDeferred ->
ensureDeferred result
diff --git a/tests/FSharp.Data.GraphQL.Tests/ResolveTests.fs b/tests/FSharp.Data.GraphQL.Tests/ResolveTests.fs
index b1dfbf576..5d9c5975e 100644
--- a/tests/FSharp.Data.GraphQL.Tests/ResolveTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/ResolveTests.fs
@@ -24,7 +24,7 @@ let ``Execute uses default resolve to accesses properties`` () =
let schema = testSchema [ Define.AutoField ("test", StringType) ]
let expected = NameValueLookup.ofList [ "test", "testValue" :> obj ]
- let result = sync <| Executor(schema).AsyncExecute (parse "{ test }", { Test = "testValue" })
+ let result = sync <| Executor(schema).AsyncExecute (parse "{ test }", getMockInputContext, { Test = "testValue" })
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
@@ -37,7 +37,7 @@ let ``Execute uses provided resolve function to accesses properties`` () =
]
let expected = NameValueLookup.ofList [ "test", "testValueString" :> obj ]
- let result = sync <| Executor(schema) .AsyncExecute (parse "{ test(a: \"String\") }", { Test = "testValue" })
+ let result = sync <| Executor(schema) .AsyncExecute (parse "{ test(a: \"String\") }", getMockInputContext, { Test = "testValue" })
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
@@ -73,11 +73,11 @@ let private fruitType =
let ``Execute resolves enums to their names`` () =
let schema =
testSchema [
- Define.Field ("fruits", ListOf fruitType, "", [], resolve = (fun ctx d -> [ Apple; Banana; Cherry; DragonFruit ]))
+ Define.Field ("fruits", ListOf fruitType, "", [], resolve = (fun _ _ -> [ Apple; Banana; Cherry; DragonFruit ]))
]
let expected = NameValueLookup.ofList [ "fruits", [ "APPLE"; "BANANA"; "CHERRY"; "DRAGON_FRUIT" ] :> obj ]
- let result = sync <| Executor(schema).AsyncExecute (parse "{ fruits() }")
+ let result = sync <| Executor(schema).AsyncExecute (parse "{ fruits() }", getMockInputContext)
ensureDirect result
<| fun data errors ->
empty errors
@@ -100,7 +100,7 @@ let ``Execute resolves enums arguments from their names`` () =
]
let expected = NameValueLookup.ofList [ "foo", box "You asked for dragon fruit" ]
- let result = sync <| Executor(schema).AsyncExecute (parse "{ foo(fruit: DRAGON_FRUIT) }")
+ let result = sync <| Executor(schema).AsyncExecute (parse "{ foo(fruit: DRAGON_FRUIT) }", getMockInputContext)
ensureDirect result <| fun data errors ->
empty errors
data |> equals (upcast expected)
diff --git a/tests/FSharp.Data.GraphQL.Tests/SchemaTests.fs b/tests/FSharp.Data.GraphQL.Tests/SchemaTests.fs
index bf04b8322..4b732b789 100644
--- a/tests/FSharp.Data.GraphQL.Tests/SchemaTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/SchemaTests.fs
@@ -69,7 +69,7 @@ let ``Schema config must be able to override default error handling`` () =
}
}
"""
- let result = sync <| Executor(schema).AsyncExecute query
+ let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
let expected =
NameValueLookup.ofList [ "test", box <| NameValueLookup.ofList [ "failing1", null; "passing", box "ok"; "failing2", null ] ]
let expectedErrors = [
diff --git a/tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs b/tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs
index 02a8b9ad8..dcad59739 100644
--- a/tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs
@@ -56,7 +56,7 @@ let internal undefined<'t> = Unchecked.defaultof<'t>
let resolveRoot ctx () =
let info = ctx.ExecutionInfo
let queryable = data.AsQueryable()
- let result = queryable.Apply(info) |> Seq.toList
+ let result = queryable.Apply(info, getMockInputContext) |> Seq.toList
result
let linqArgs =
@@ -83,7 +83,7 @@ let schema =
fun ctx () ->
let info = ctx.ExecutionInfo
let queryable = data.AsQueryable ()
- let result = queryable.Apply (info) |> Seq.toList
+ let result = queryable.Apply (info, getMockInputContext) |> Seq.toList
result
)
]
@@ -102,7 +102,7 @@ let ``LINQ interpreter works with auto-fields``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
result.FirstName |> equals "Ben"
@@ -120,7 +120,7 @@ let ``LINQ interpreter works with fields with defined resolvers``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
result.FirstName |> equals undefined
@@ -138,7 +138,7 @@ let ``LINQ interpreter works with fields referring to nested property resolver``
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
result.FirstName |> equals undefined
@@ -156,7 +156,7 @@ let ``LINQ interpreter works with nested collections``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
result.FirstName |> equals undefined
@@ -175,7 +175,7 @@ let ``LINQ interpreter works with nested property getters in resolve function``(
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
result.FirstName |> equals undefined
@@ -194,7 +194,7 @@ let ``LINQ interpreter resolves multiple properties from complex resolvers``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = List.head people
// both FirstName and LastName should be resolved, because
@@ -215,7 +215,7 @@ let ``LINQ interpreter works with id arg``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 1
let result = List.head people
result.ID |> equals 2
@@ -235,7 +235,7 @@ let ``LINQ interpreter works with skip arg``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 1
let result = List.head people
result.ID |> equals 7
@@ -255,7 +255,7 @@ let ``LINQ interpreter works with take arg``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 2
let result = people |> List.map (fun p -> (p.ID, p.FirstName))
result |> equals [ (4, "Ben")
@@ -272,7 +272,7 @@ let ``LINQ interpreter works with orderBy arg``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = people |> List.map (fun p -> (p.ID, p.FirstName))
result |> equals [ (4, "Ben")
@@ -290,7 +290,7 @@ let ``LINQ interpreter works with orderByDesc arg``() =
}
"""
let info = plan.["people"]
- let people = data.AsQueryable().Apply(info) |> Seq.toList
+ let people = data.AsQueryable().Apply(info, getMockInputContext) |> Seq.toList
List.length people |> equals 3
let result = people |> List.map (fun p -> (p.ID, p.FirstName))
result |> equals [ (2, "Jonathan")
diff --git a/tests/FSharp.Data.GraphQL.Tests/SubscriptionTests.fs b/tests/FSharp.Data.GraphQL.Tests/SubscriptionTests.fs
index 398d2ddb4..d3d2ada11 100644
--- a/tests/FSharp.Data.GraphQL.Tests/SubscriptionTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/SubscriptionTests.fs
@@ -115,7 +115,7 @@ let ``Can subscribe to sync field and get results``() =
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
@@ -142,7 +142,7 @@ let ``Can subscribe to tagged sync field and get results with expected tag``() =
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
@@ -162,7 +162,7 @@ let ``Can subscribe to tagged sync field and do not get results with unexpected
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
@@ -184,7 +184,7 @@ let ``Can subscribe to async field and get results``() =
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
@@ -211,7 +211,7 @@ let ``Can subscribe to tagged async field and get results with expected tag``()
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
@@ -231,7 +231,7 @@ let ``Can subscribe to tagged async field and do not get results with unexpected
data
}
}"""
- let result = executor.AsyncExecute(query) |> sync
+ let result = executor.AsyncExecute(query, getMockInputContext) |> sync
match result with
| Stream data ->
use sub = Observer.create data
diff --git a/tests/FSharp.Data.GraphQL.Tests/UnionInterfaceTests.fs b/tests/FSharp.Data.GraphQL.Tests/UnionInterfaceTests.fs
index e1c344142..291a8bf40 100644
--- a/tests/FSharp.Data.GraphQL.Tests/UnionInterfaceTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/UnionInterfaceTests.fs
@@ -113,7 +113,7 @@ let ``Execute can introspect on union and intersection types`` () =
inputFields { name }
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext)
let expected =
NameValueLookup.ofList [
"Named", upcast NameValueLookup.ofList [
@@ -155,7 +155,7 @@ let ``Executes union types`` () =
meows
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast, john)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext, john)
let expected =
NameValueLookup.ofList [
"__typename", box "Person"
@@ -191,7 +191,7 @@ let ``Executes union types with inline fragments`` () =
}
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast, john)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext, john)
let expected =
NameValueLookup.ofList [
"__typename", box "Person"
@@ -222,7 +222,7 @@ let ``Executes interface types`` () =
meows
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast, john)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext, john)
let expected =
NameValueLookup.ofList [
"__typename", box "Person"
@@ -256,7 +256,7 @@ let ``Executes interface types with inline fragments`` () =
}
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast, john)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext, john)
let expected =
NameValueLookup.ofList [
"__typename", box "Person"
@@ -304,7 +304,7 @@ let ``Execute allows fragment conditions to be abstract types`` () =
meows
}
}"""
- let result = sync <| Executor(schema).AsyncExecute(ast, john)
+ let result = sync <| Executor(schema).AsyncExecute(ast, getMockInputContext, john)
let expected =
NameValueLookup.ofList [
"__typename", box "Person"
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputComplexTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputComplexTests.fs
index af3625804..954ace7ec 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputComplexTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputComplexTests.fs
@@ -73,7 +73,7 @@ let schema = Schema (TestType)
let ``Execute handles objects and nullability using inline structs with complex input`` () =
let ast =
parse """{ fieldWithObjectInput(input: {mand: "baz", opt: "foo", optSeq: ["bar"], optArr: ["baf"]}) }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList
@@ -88,7 +88,7 @@ let ``Execute handles objects and nullability using inline structs with complex
[]
let ``Execute handles objects and nullability using inline structs and properly parses single value to list`` () =
let ast = parse """{ fieldWithObjectInput(input: {mand:"baz", opt: "foo", optSeq: "bar"}) }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList [ "fieldWithObjectInput", upcast """{"mand":"baz", "opt":"foo", "optSeq":["bar"], "glCode":null, "optArr":null}""" ]
ensureDirect result <| fun data errors ->
@@ -98,7 +98,7 @@ let ``Execute handles objects and nullability using inline structs and properly
[]
let ``Execute handles objects and nullability using inline structs and properly coerces complex scalar types`` () =
let ast = parse """{ fieldWithObjectInput(input: {mand: "foo", glCode: "SerializedValue"}) }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList
[ "fieldWithObjectInput",
@@ -127,7 +127,7 @@ let ``Execute handles variables with complex inputs`` () =
}"""
let params' = paramsWithValueInput testInputObject
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithObjectInput", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -141,7 +141,7 @@ let ``Execute handles variables with default value when no value was provided``
fieldWithObjectInput(input: $input)
}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithObjectInput", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -157,7 +157,7 @@ let ``Execute handles variables and errors on null for nested non-nulls`` () =
let testInputObject = """{"mand":null, "opt":"foo", "optSeq":["bar"], "voptSeq":["bar"]}"""
let params' = paramsWithValueInput testInputObject
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable field 'mand' expected value of type 'String!', but got 'null'."
error |> ensureInputObjectFieldCoercionError (Variable "input") message [] "TestInputObject" "String!"
@@ -172,7 +172,7 @@ let ``Execute handles variables and errors on incorrect type`` () =
let testInputObject = "\"foo bar\""
let params' = paramsWithValueInput testInputObject
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = $"A variable '$input' expected to be '%O{JsonValueKind.Object}' but got '%O{JsonValueKind.String}'."
error |> ensureInputCoercionError (Variable "input") message "TestInputObject"
@@ -187,7 +187,7 @@ let ``Execute handles variables and errors on omission of nested non-nulls`` ()
let testInputObject = """{"opt":"foo","optSeq":["bar"]}"""
let params' = paramsWithValueInput testInputObject
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable field 'mand' expected value of type 'String!', but got 'null'."
error |> ensureInputObjectFieldCoercionError (Variable "input") message [] "TestInputObject" "String!"
@@ -202,7 +202,7 @@ let ``Execute handles list inputs and nullability and does not allow invalid typ
// as that kind of an error inside of opt query is guaranteed to fail in every call, we're gonna to fail noisy here
let testInputList = "[\"A\",\"B\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = $"A variable '$input' expected to be '%O{JsonValueKind.Object}' but got '%O{JsonValueKind.Array}'."
error |> ensureInputCoercionError (Variable "input") message "TestInputObject!"
@@ -220,7 +220,7 @@ let ``Execute handles list inputs and nullability and does not allow unknown typ
// as that kind of an error inside of opt query is guaranteed to fail in every call, we're gonna to fail noisy here
let testInputValue = "\"whoknows\""
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expectedError =
let message = "A variable '$input' in operation 'q' has a type that is not an input type defined by the schema (UnknownType!)."
GQLProblemDetails.CreateWithKind (message, Validation)
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputEnumTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputEnumTests.fs
index 3ee801295..f8e8966ff 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputEnumTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputEnumTests.fs
@@ -56,7 +56,7 @@ let ``Execute handles enum input as variable`` () =
let testInputValue = "\"Foo\""
let params' = paramsWithEnumInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithEnumInput", upcast "\"Foo\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -72,7 +72,7 @@ let ``Execute handles nullable null enum input as variable`` () =
let testInputValue = "null"
let params' = paramsWithEnumInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNullableEnumInput", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
@@ -88,7 +88,7 @@ let ``Execute handles union enum input as variable`` () =
let testInputValue = "\"Bar\""
let params' = paramsWithEnumInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithEnumInput", upcast "\"Bar\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -104,7 +104,7 @@ let ``Execute handles Some union enum input as variable`` () =
let testInputValue = "\"Bar\""
let params' = paramsWithEnumInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNullableEnumInput", upcast "\"Bar\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -120,7 +120,7 @@ let ``Execute handles None enum input as variable`` () =
let testInputValue = "null"
let params' = paramsWithEnumInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNullableEnumInput", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputListTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputListTests.fs
index 06d393196..8c28d22e6 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputListTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputListTests.fs
@@ -52,7 +52,7 @@ let ``Execute handles list inputs and nullability and allows lists to be null``
let testInputValue = "null"
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "list", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
@@ -68,7 +68,7 @@ let ``Execute handles list inputs and nullability and allows lists to contain va
let testInputList = "[\"A\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "list", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -84,7 +84,7 @@ let ``Execute handles list inputs and nullability and allows lists to contain nu
let testInputList = "[\"A\",null,\"B\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "list", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -100,7 +100,7 @@ let ``Execute handles list inputs and nullability and does not allow non-null li
let testInputList = "null"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable variable '$input' expected value of type '[String]!', but got 'null'."
error |> ensureInputCoercionError (Variable "input") message "[String]!"
@@ -115,7 +115,7 @@ let ``Execute handles list inputs and nullability and allows non-null lists to c
let testInputList = "[\"A\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "nnList", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -131,7 +131,7 @@ let ``Execute handles list inputs and nullability and allows non-null lists to c
let testInputList = "[\"A\",null,\"B\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "nnList", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -147,7 +147,7 @@ let ``Execute handles list inputs and nullability and allows lists of non-nulls
let testInputList = "null"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "listNN", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -163,7 +163,7 @@ let ``Execute handles list inputs and nullability and allows lists of non-nulls
let testInputList = "[\"A\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "listNN", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -179,7 +179,7 @@ let ``Execute handles list inputs and nullability and does not allow lists of no
let testInputList = "[\"A\",null,\"B\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable variable '$input' expected value of type '[String!]', but got 'null'."
error |> ensureInputCoercionError (Variable "input") message "[String!]"
@@ -194,7 +194,7 @@ let ``Execute handles list inputs and nullability and does not allow non-null li
let testInputList = "null"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable variable '$input' expected value of type '[String!]!', but got 'null'."
error |> ensureInputCoercionError (Variable "input") message "[String!]!"
@@ -209,7 +209,7 @@ let ``Execute handles list inputs and nullability and does not allow non-null li
let testInputList = "[\"A\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "nnListNN", upcast testInputList ]
ensureDirect result <| fun data errors ->
empty errors
@@ -225,7 +225,7 @@ let ``Execute handles list inputs and nullability and does not allow non-null li
let testInputList = "[\"A\",null,\"B\"]"
let params' = paramsWithValueInput testInputList
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
let message = "Non-nullable variable '$input' expected value of type '[String!]!', but got 'null'."
error |> ensureInputCoercionError (Variable "input") message "[String!]!"
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNestedTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNestedTests.fs
index 714c02901..69fc2b825 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNestedTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNestedTests.fs
@@ -105,7 +105,7 @@ let schema = Schema (TestType)
let ``Execute handles nested input objects and nullability using inline structs and properly coerces complex scalar types`` () =
let ast =
parse """{ fieldWithNestedInputObject(input: {n:"optSeq", no:{mand:"mand"}, nvo:{mand:"mand"}, nl: []})}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList [
"fieldWithNestedInputObject",
@@ -122,7 +122,7 @@ let ``Execute handles nested input objects and nullability using inline structs
let ``Execute handles nested input objects and nullability using inline structs and properly coerces complex scalar types with empty lists`` () =
let ast =
parse """{ fieldWithNestedInputObject(input: {n:"optSeq", no:{mand:"mand"}, nvo:{mand:"mand"}, nl:[], nlo: [], nlvo: []})}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList [
"fieldWithNestedInputObject",
@@ -139,7 +139,7 @@ let ``Execute handles nested input objects and nullability using inline structs
let ``Execute handles nested input objects and nullability using inline structs and properly coerces complex scalar types with lists`` () =
let ast =
parse """{ fieldWithNestedInputObject(input: {n:"optSeq", nl:[{mand:"mand"}], nlo: [{mand:"mand"}], nlvo: [{mand:"mand"}]})}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList [
"fieldWithNestedInputObject",
@@ -156,7 +156,7 @@ let ``Execute handles nested input objects and nullability using inline structs
let ``Execute handles recursive input objects and nullability using inline structs and properly coerces complex scalar types`` () =
let ast =
parse """{ fieldWithRecursiveInputObject(input: {r:"optSeq", ro:{r:"mand"}, rvo:{r:"mand"}})}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected =
NameValueLookup.ofList [
"fieldWithRecursiveInputObject",
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNullableStringTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNullableStringTests.fs
index d9781696c..08039ad8f 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNullableStringTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputNullableStringTests.fs
@@ -50,7 +50,7 @@ let paramsWithValueInput input =
[]
let ``Execute handles variables and allows nullable inputs to be omitted`` () =
let ast = parse """{ fieldWithNullableStringInput }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithNullableStringInput", upcast "null" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -64,7 +64,7 @@ let ``Execute handles variables and allows nullable inputs to be omitted in a va
fieldWithNullableStringInput(input: $value)
}"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithNullableStringInput", upcast "null" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -81,7 +81,7 @@ let ``Execute handles variables and allows nullable inputs to be set to null in
let testInputValue = "null"
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNullableStringInput", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
@@ -103,7 +103,7 @@ let ``Execute handles variables and allows nullable inputs to be set to a value
let testInputValue = "\"a\""
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNullableStringInput", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
@@ -112,7 +112,7 @@ let ``Execute handles variables and allows nullable inputs to be set to a value
[]
let ``Execute handles variables and allows nullable inputs to be set to a value directly`` () =
let ast = parse """{ fieldWithNullableStringInput(input: "a") }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithNullableStringInput", upcast "\"a\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -133,7 +133,7 @@ let ``Execute handles non-nullable scalars and does not allow non-nullable input
let testInputValue = "null"
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
ensureRequestError result <| fun [ error ] ->
error |> ensureInputCoercionError (Variable "value") "Non-nullable variable '$value' expected value of type 'String!', but got 'null'." "String!"
@@ -153,7 +153,7 @@ let ``Execute handles non-nullable scalars and allows non-nullable inputs to be
let testInputValue = "\"a\""
let params' = paramsWithValueInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithNonNullableStringInput", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
@@ -162,7 +162,7 @@ let ``Execute handles non-nullable scalars and allows non-nullable inputs to be
[]
let ``Execute handles non-nullable scalars and allows non-nullable inputs to be set to a value directly`` () =
let ast = parse """{ fieldWithNonNullableStringInput(input: "a") }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithNonNullableStringInput", upcast "\"a\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -171,7 +171,7 @@ let ``Execute handles non-nullable scalars and allows non-nullable inputs to be
[]
let ``Execute uses argument default value when no argument was provided`` () =
let ast = parse """{ fieldWithDefaultArgumentValue }"""
- let result = sync <| Executor(schema).AsyncExecute (ast)
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext)
let expected = NameValueLookup.ofList [ "fieldWithDefaultArgumentValue", upcast "\"hello world\"" ]
ensureDirect result <| fun data errors ->
empty errors
@@ -192,7 +192,7 @@ let ``Execute uses argument default value when nullable variable provided`` () =
let testInputValue = "\"hello world\""
let params' = paramsWithOptionalInput testInputValue
- let result = sync <| Executor(schema).AsyncExecute (ast, variables = params')
+ let result = sync <| Executor(schema).AsyncExecute (ast, getMockInputContext, variables = params')
let expected = NameValueLookup.ofList [ "fieldWithDefaultArgumentValue", upcast testInputValue ]
ensureDirect result <| fun data errors ->
empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputObjectValidatorTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputObjectValidatorTests.fs
index 293f07574..ee1fcd188 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputObjectValidatorTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputObjectValidatorTests.fs
@@ -126,7 +126,7 @@ let ``Execute handles validation of valid inline input records with all fields``
recordNested: { homeAddress: { country: "US", zipCode: "12345", city: "Miami" }, workAddress: { country: "US", zipCode: "67890", city: "Miami" } }
)
}"""
- let result = sync <| schema.AsyncExecute(parse query)
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -138,7 +138,7 @@ let ``Execute handles validation of invalid inline input records with all fields
recordNested: { homeAddress: { country: "US", zipCode: "12345", city: "Miami" }, workAddress: { country: "US", zipCode: "67890", city: "Miami" }, mailingAddress: { country: "US", zipCode: "12345", city: "Miami" } }
)
}"""
- let result = sync <| schema.AsyncExecute(parse query)
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext)
match result with
| RequestError [ zipCodeError ; addressError ] ->
zipCodeError |> ensureInputObjectValidationError (Argument "record") "ZipCode must be 5 characters for US" [] "InputRecord!"
@@ -175,7 +175,7 @@ let ``Execute handles validation of valid input records from variables with all
"""{ "country": "US", "zipCode": "67890", "city": "Miami" }""",
"""null"""
) |> paramsWithValues
- let result = sync <| schema.AsyncExecute(parse query, variables = params')
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -197,7 +197,7 @@ let ``Execute handles validation of invalid input records from variables with al
"""{ "country": "US", "zipCode": "67890", "city": "Miami" }""",
"""{ "country": "US", "zipCode": "12345", "city": "Miami" }"""
) |> paramsWithValues
- let result = sync <| schema.AsyncExecute(parse query, variables = params')
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureRequestError result <| fun [ zipCodeError ; addressError ] ->
zipCodeError |> ensureInputObjectValidationError (Variable "record") "ZipCode must be 5 characters for US" [ box "mailingAddress" ] "InputRecord"
@@ -227,7 +227,7 @@ let ``Execute handles validation of valid input records from variables with all
"""{ "country": "US", "zipCode": "67890", "city": "Miami" }""",
"""null"""
) |> paramsWithValues
- let result = sync <| schema.AsyncExecute(parse query, variables = params')
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -248,10 +248,10 @@ let ``Execute handles validation of invalid input records from variables with al
"""{ "country": "US", "zipCode": "12345", "city": "Miami" }""",
"""{ "country": "US", "zipCode": "67890", "city": "Miami" }"""
) |> paramsWithValues
- let result = sync <| schema.AsyncExecute(parse query, variables = params')
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureRequestError result <| fun [ error ] ->
error |> ensureInputObjectValidationError (Variable "record1") "ZipCode must be 5 characters for US" [ box "mailingAddress" ] "InputRecord"
- // Because all variables are coerced together validation of the inline object that contains variables do not happen
+ // Because all variables are coerced together, validation of the inline object that contains variables do not happen
// as total variables coercion failed
//hasError "Object 'Query': field 'recordInputs': argument 'recordNested': HomeAddress and MailingAddress must be different" errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordListTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordListTests.fs
index 149005f0b..d9d3ca57f 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordListTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordListTests.fs
@@ -64,7 +64,7 @@ let ``Execute handles creation of inline empty input records list`` () =
recordsNested: []
)
}"""
- let result = sync <| (schema AllInclude).AsyncExecute(parse query)
+ let result = sync <| (schema AllInclude).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -83,7 +83,7 @@ let ``Execute handles creation of inline input records list with all fields`` ()
}]
)
}"""
- let result = sync <| (schema AllInclude).AsyncExecute(parse query)
+ let result = sync <| (schema AllInclude).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -96,7 +96,7 @@ let ``Execute handles creation of inline input records list with optional null f
recordsNested: [{ a: { a: "a", b: "b", c: "c" }, b: null, c: null, s: null, l: [] }]
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -108,7 +108,7 @@ let ``Execute handles creation of inline input records list with mandatory only
recordsNested: [{ a: { a: "a", b: "b", c: "c" }, l: [{ a: "a", b: "b", c: "c" }] }]
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
let variablesWithAllInputs (record, optRecord, skippable) =
@@ -142,7 +142,7 @@ let ``Execute handles creation of input records list from variables with all fie
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let params' =
variablesWithAllInputs(testInputObject, testInputObject, testInputObject) |> paramsWithValues
- let result = sync <| (schema AllInclude).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema AllInclude).AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -165,7 +165,7 @@ let ``Execute handles creation of input records list from variables with optiona
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let testInputSkippable = """{ "a": null, "b": null, "c": null }"""
let params' = variablesWithAllInputs(testInputObject, "null", testInputSkippable) |> paramsWithValues
- let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query, getMockInputContext, variables = params')
ensureDirect result <| fun data errors -> empty errors
[]
@@ -187,5 +187,5 @@ let ``Execute handles creation of input records from variables with mandatory on
}"""
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let params' = variablesWithAllInputs testInputObject |> paramsWithValues
- let result = sync <| (schema AllSkip).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema AllSkip).AsyncExecute(parse query, getMockInputContext, variables = params')
ensureDirect result <| fun data errors -> empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordTests.fs
index fc19e33d8..1c71d3619 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputRecordTests.fs
@@ -169,7 +169,7 @@ let ``Execute handles creation of inline input records with all fields`` () =
}
)
}"""
- let result = sync <| (schema AllInclude).AsyncExecute(parse query)
+ let result = sync <| (schema AllInclude).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -182,7 +182,7 @@ let ``Execute handles creation of inline input records with optional null fields
recordNested: { a: { a: "a", b: "b", c: "c" }, b: null, c: null, s: null, l: [] }
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -194,7 +194,7 @@ let ``Execute handles creation of inline input records with mandatory only field
recordNested: { a: { a: "a", b: "b", c: "c" }, l: [{ a: "a", b: "b", c: "c" }] }
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
let variablesWithAllInputs (record, optRecord, skippable) =
@@ -225,7 +225,7 @@ let ``Execute handles creation of input records from variables with all fields``
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let params' =
variablesWithAllInputs(testInputObject, testInputObject, testInputObject) |> paramsWithValues
- let result = sync <| (schema AllInclude).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema AllInclude).AsyncExecute(parse query, getMockInputContext, variables = params')
//let expected = NameValueLookup.ofList [ "recordInputs", upcast testInputObject ]
ensureDirect result <| fun data errors ->
empty errors
@@ -244,7 +244,7 @@ let ``Execute handles creation of input records from variables with optional nul
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let testInputSkippable = """{ "a": null, "b": null, "c": null }"""
let params' = variablesWithAllInputs(testInputObject, "null", testInputSkippable) |> paramsWithValues
- let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query, getMockInputContext, variables = params')
ensureDirect result <| fun data errors -> empty errors
[]
@@ -258,5 +258,5 @@ let ``Execute handles creation of input records from variables with mandatory on
}"""
let testInputObject = """{"a":"a","b":"b","c":"c"}"""
let params' = variablesWithAllInputs(testInputObject, "null", "{}") |> paramsWithValues
- let result = sync <| (schema AllSkip).AsyncExecute(parse query, variables = params')
+ let result = sync <| (schema AllSkip).AsyncExecute(parse query, getMockInputContext, variables = params')
ensureDirect result <| fun data errors -> empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputScalarAndAutoFieldScalarTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputScalarAndAutoFieldScalarTests.fs
index 186202a50..7a2a50e3e 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputScalarAndAutoFieldScalarTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/InputScalarAndAutoFieldScalarTests.fs
@@ -184,7 +184,7 @@ let ``Execute handles nullable auto-fields in input and output record fields coe
}
}"""
- let result = sync <| schema.Value.AsyncExecute (parse query)
+ let result = sync <| schema.Value.AsyncExecute (parse query, getMockInputContext)
let expected =
NameValueLookup.ofList [ "record", upcast NameValueLookup.ofList [ "a", "a" :> obj; "b", "b"; "c", "c"] ]
@@ -203,7 +203,7 @@ let ``Execute handles nullable auto-fields in input and output object fields coe
}
}"""
- let result = sync <| schema.Value.AsyncExecute (parse query)
+ let result = sync <| schema.Value.AsyncExecute (parse query, getMockInputContext)
let expected =
NameValueLookup.ofList [ "record", upcast NameValueLookup.ofList [ "a", "a" :> obj; "b", "b"; "c", "c" ] ]
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/OptionalsNormalizationTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/OptionalsNormalizationTests.fs
index 28e70d52d..29f859e8e 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/OptionalsNormalizationTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/OptionalsNormalizationTests.fs
@@ -220,7 +220,7 @@ let ``Execute handles validation of valid inline input records with all fields``
structOptional: { zipCode: "12345", city: "Miami" }
)
}"""
- let result = sync <| schema.AsyncExecute(parse query)
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -238,5 +238,5 @@ let ``Execute handles validation of valid inline input records with mandatory-on
struct: { zipCode: "12345", city: "Miami" },
)
}"""
- let result = sync <| schema.AsyncExecute(parse query)
+ let result = sync <| schema.AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
diff --git a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/SkippablesNormalizationTests.fs b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/SkippablesNormalizationTests.fs
index b15c36d84..ce31b5c5e 100644
--- a/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/SkippablesNormalizationTests.fs
+++ b/tests/FSharp.Data.GraphQL.Tests/Variables and Inputs/SkippablesNormalizationTests.fs
@@ -295,7 +295,7 @@ let ``Execute handles validation of valid inline input records with all fields``
structOptional: { zipCode: "12345", city: "Miami" }
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -313,7 +313,7 @@ let ``Execute handles validation of valid inline input records with mandatory-on
struct: { zipCode: "12345", city: "Miami" },
)
}"""
- let result = sync <| (schema Nothing).AsyncExecute(parse query)
+ let result = sync <| (schema Nothing).AsyncExecute(parse query, getMockInputContext)
ensureDirect result <| fun data errors -> empty errors
[]
@@ -334,8 +334,8 @@ let ``Execute handles validation of valid inline input records with null mandato
structOptional: { zipCode: null, city: null }
)
}"""
- let result = sync <| (schema Skip).AsyncExecute(parse query)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| (schema Skip).AsyncExecute(parse query, getMockInputContext)
+ ensureDirect result <| fun _ errors -> empty errors
[]
let ``Execute handles validation of valid inline input records with null optional field`` () =
@@ -355,5 +355,5 @@ let ``Execute handles validation of valid inline input records with null optiona
structOptional: { line2: null }
)
}"""
- let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query)
- ensureDirect result <| fun data errors -> empty errors
+ let result = sync <| (schema SkipAndIncludeNull).AsyncExecute(parse query, getMockInputContext)
+ ensureDirect result <| fun _ errors -> empty errors