示例#1
0
        public async Task RootValueIsRegisterdAsService()
        {
            // arrange
            var services = new DictionaryServiceProvider(
                typeof(DisposableQuery), new DisposableQuery());

            var schema = Schema.Create(c =>
            {
                c.RegisterQueryType <DisposableQuery>();
            });

            var sourceText = "{ isDisposable }";

            var request = QueryRequestBuilder.New()
                          .SetQuery(sourceText)
                          .Create();

            var context = new QueryContext
                          (
                schema,
                MiddlewareTools.CreateRequestServiceScope(services),
                request,
                (f, s) => f.Middleware
                          );

            context.Document = Utf8GraphQLParser.Parse(sourceText);
            context.QueryKey = "foo";

            var middleware = new ResolveOperationMiddleware(
                c => Task.CompletedTask, null);

            // act
            await middleware.InvokeAsync(context);

            // assert
            DisposableQuery query = Assert.IsType <DisposableQuery>(
                context.Operation.RootValue);

            Assert.False(query.IsDisposed);
        }
示例#2
0
        public async Task ConvertSourceObject()
        {
            // arrange
            bool conversionTriggered = false;
            var  conversion          = new TypeConversion();

            conversion.Register <Foo, Baz>(source =>
            {
                conversionTriggered = true;
                return(new Baz {
                    Qux = source.Bar
                });
            });

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton <ITypeConversion>(conversion);
            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            ISchema schema =
                SchemaBuilder.New()
                .AddQueryType <QueryType>()
                .AddServices(services)
                .Create();

            // act
            IReadOnlyQueryRequest request =
                QueryRequestBuilder.New()
                .SetQuery("{ foo { qux } }")
                .SetServices(services)
                .Create();

            IExecutionResult result =
                await schema.MakeExecutable().ExecuteAsync(request);

            // assert
            Assert.True(conversionTriggered);
            result.MatchSnapshot();
        }
示例#3
0
        public void BuildRequest_QueryAndSetExtensions_RequestIsCreated_4()
        {
            // arrange
            IDictionary <string, object> ext =
                new Dictionary <string, object>
            {
                { "three", "baz" }
            };

            // act
            IReadOnlyQueryRequest request =
                QueryRequestBuilder.New()
                .SetQuery("{ foo }")
                .AddExtension("one", "foo")
                .AddExtension("two", "bar")
                .SetExtensions(ext)
                .Create();

            // assert
            // only three should exist
            request.MatchSnapshot();
        }
        public static QueryRequestBuilder From(IReadOnlyQueryRequest request)
        {
            var builder = new QueryRequestBuilder();

            builder._query                  = request.Query;
            builder._queryName              = request.QueryId;
            builder._queryHash              = request.QueryHash;
            builder._operationName          = request.OperationName;
            builder._readOnlyVariableValues = request.VariableValues;
            builder._initialValue           = request.InitialValue;
            builder._readOnlyProperties     = request.ContextData;
            builder._readOnlyExtensions     = request.Extensions;
            builder._services               = request.Services;

            if (builder._query is null && builder._queryName is null)
            {
                throw new QueryRequestBuilderException(
                          AbstractionResources.QueryRequestBuilder_QueryIsNull);
            }

            return(builder);
        }
示例#5
0
        public async Task AccessVariables_Fails_When_Variable_Not_Exists()
        {
            // arrange
            ISchema schema = SchemaBuilder.New()
                             .AddDocumentFromString(
                "type Query { foo(bar: String) : String }")
                             .AddResolver("Query", "foo", ctx =>
                                          ctx.Variables.GetVariable <string>("abc"))
                             .Create();

            IReadOnlyQueryRequest request = QueryRequestBuilder.New()
                                            .SetQuery("query abc($def: String){ foo(bar: $def) }")
                                            .SetVariableValue("def", "ghi")
                                            .Create();

            // act
            IExecutionResult result =
                await schema.MakeExecutable().ExecuteAsync(request);

            // assert
            result.MatchSnapshot();
        }
示例#6
0
        public async Task RootValueProvidedByRequest()
        {
            // arrange
            var schema = Schema.Create(c =>
            {
                c.RegisterQueryType <DisposableQuery>();
            });

            var rootValue = new DisposableQuery();

            var sourceText = "{ isDisposable }";

            var request = QueryRequestBuilder.New()
                          .SetQuery(sourceText)
                          .SetInitialValue(rootValue)
                          .Create();

            var context = new QueryContext
                          (
                schema,
                MiddlewareTools.CreateEmptyRequestServiceScope(),
                request,
                (f, s) => f.Middleware
                          );

            context.Document = Utf8GraphQLParser.Parse(sourceText);
            context.QueryKey = "foo";

            var middleware = new ResolveOperationMiddleware(
                c => Task.CompletedTask, null);

            // act
            await middleware.InvokeAsync(context);

            // assert
            Assert.True(object.ReferenceEquals(
                            rootValue, context.Operation.RootValue));
        }
示例#7
0
        public async Task OperationIsResolved()
        {
            // arrange
            var schema = Schema.Create(@"
                type Query { a: String }
                ", c =>
            {
                c.BindResolver(() => "hello world")
                .To("Query", "a");
            });

            var sourceText = "query a { a }";

            var request = QueryRequestBuilder.New()
                          .SetQuery(sourceText)
                          .Create();

            var context = new QueryContext
                          (
                schema,
                MiddlewareTools.CreateEmptyRequestServiceScope(),
                request,
                (f, s) => f.Middleware
                          );

            context.Document = Utf8GraphQLParser.Parse(sourceText);
            context.QueryKey = "foo";

            var middleware = new ResolveOperationMiddleware(
                c => Task.CompletedTask, null);

            // act
            await middleware.InvokeAsync(context);

            // assert
            Assert.NotNull(context.Operation);
            Assert.Equal("a", context.Operation.Name);
        }
        public async Task Extension_With_Scoped_Constructor_Injection()
        {
            IServiceProvider services =
                new ServiceCollection()
                .AddScoped <SomeService>()
                .AddScoped <ExtendQuery1>()
                .AddGraphQL()
                .AddQueryType <Query1>()
                .AddType <ExtendQuery1>()
                .Services
                .BuildServiceProvider();

            IRequestExecutor executor = await services.GetRequestExecutorAsync();

            using (IServiceScope scope = services.CreateScope())
            {
                await executor
                .ExecuteAsync(
                    QueryRequestBuilder
                    .New()
                    .SetQuery("{ hello }")
                    .SetServices(scope.ServiceProvider)
                    .Create())
                .MatchSnapshotAsync();
            }

            using (IServiceScope scope = services.CreateScope())
            {
                await executor
                .ExecuteAsync(
                    QueryRequestBuilder
                    .New()
                    .SetQuery("{ hello }")
                    .SetServices(scope.ServiceProvider)
                    .Create())
                .MatchSnapshotAsync();
            }
        }
示例#9
0
        public async Task Do_Not_Stream_Nodes()
        {
            IExecutionResult result =
                await new ServiceCollection()
                .AddStarWarsRepositories()
                .AddGraphQL()
                .AddStarWarsTypes()
                .ExecuteRequestAsync(
                    QueryRequestBuilder.New()
                    .SetQuery(
                        @"query($stream: Boolean) {
                                    hero(episode: NEW_HOPE) {
                                        id
                                        ... @defer(label: ""friends"") {
                                            friends {
                                                nodes @stream(initialCount: 1, if: $stream) {
                                                    id
                                                    name
                                                }
                                            }
                                        }
                                    }
                                }")
                    .SetVariableValue("stream", false)
                    .Create());

            IResponseStream stream = Assert.IsType <DeferredQueryResult>(result);

            var results = new StringBuilder();

            await foreach (IQueryResult payload in stream.ReadResultsAsync())
            {
                results.AppendLine(payload.ToJson());
                results.AppendLine();
            }

            results.ToString().MatchSnapshot();
        }
        public async Task ActivePersistedQueries_NonPersistedQuery_IsExecuted()
        {
            // arrange
            var serviceCollection = new ServiceCollection();

            // configure presistence
            serviceCollection.AddGraphQLSchema(b => b
                                               .AddDocumentFromString("type Query { foo: String }")
                                               .AddResolver("Query", "foo", "bar"));
            serviceCollection.AddQueryExecutor(b => b
                                               .AddSha256DocumentHashProvider()
                                               .UseActivePersistedQueryPipeline());

            // add in-memory query storage
            serviceCollection.AddSingleton <InMemoryQueryStorage>();
            serviceCollection.AddSingleton <IReadStoredQueries>(sp =>
                                                                sp.GetRequiredService <InMemoryQueryStorage>());
            serviceCollection.AddSingleton <IWriteStoredQueries>(sp =>
                                                                 sp.GetRequiredService <InMemoryQueryStorage>());

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            IQueryExecutor executor =
                services.GetRequiredService <IQueryExecutor>();

            var storage = services.GetRequiredService <InMemoryQueryStorage>();

            // act
            IExecutionResult result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery("{ foo }")
                .Create());

            // assert
            Assert.False(storage.WrittenQuery.HasValue);
            result.ToJson().MatchSnapshot();
        }
        public static Task <IExecutionResult> ExecuteAsync(
            this IRequestExecutor executor,
            Action <IQueryRequestBuilder> buildRequest,
            CancellationToken cancellationToken)
        {
            if (executor is null)
            {
                throw new ArgumentNullException(nameof(executor));
            }

            if (buildRequest is null)
            {
                throw new ArgumentNullException(nameof(buildRequest));
            }

            var builder = new QueryRequestBuilder();

            buildRequest(builder);

            return(executor.ExecuteAsync(
                       builder.Create(),
                       cancellationToken));
        }
示例#12
0
        public async Task ExecuteWithNonNullVariableInvalidType_Error()
        {
            // arrange
            var variableValues = new Dictionary <string, object>()
            {
                { "a", new IntValueNode(123) }
            };

            Schema         schema   = CreateSchema();
            IQueryExecutor executor = schema.MakeExecutable();
            var            request  =
                QueryRequestBuilder.New()
                .SetQuery("query x($a: String!) { b(a: $a) }")
                .SetVariableValues(variableValues)
                .Create();

            // act
            IExecutionResult result = await executor.ExecuteAsync(request);

            // assert
            Assert.NotNull(result.Errors);
            result.MatchSnapshot();
        }
示例#13
0
        public async Task ContextDataIsPassedAllongCorrectly()
        {
            // arrange
            bool allDataIsPassedAlong = false;

            ISchema schema = Schema.Create(
                "type Query { foo: String }",
                c => c.Use(next => context =>
            {
                context.ContextData["field"] = "abc";
                context.Result = context.ContextData["request"];
                return(Task.CompletedTask);
            }));

            IQueryExecutor executor = schema.MakeExecutable(
                b => b.UseDefaultPipeline()
                .Use(next => context =>
            {
                if (context.ContextData.ContainsKey("request") &&
                    context.ContextData.ContainsKey("field"))
                {
                    allDataIsPassedAlong = true;
                }
                return(Task.CompletedTask);
            }));

            // act
            IExecutionResult result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery("{ foo }")
                .SetProperty("request", "123")
                .Create());

            // assert
            Assert.True(allDataIsPassedAlong);
            result.MatchSnapshot();
        }
示例#14
0
        public async Task ParseQueryMiddleware_ValidQuery_DocumentIsSet()
        {
            // arrange
            Schema schema = CreateSchema();

            IReadOnlyQueryRequest request =
                QueryRequestBuilder.New()
                .SetQuery("{ a }")
                .Create();

            var context = new QueryContext
                          (
                schema,
                MiddlewareTools.CreateEmptyRequestServiceScope(),
                request,
                (f, s) => f.Middleware
                          );

            var diagnostics = new QueryExecutionDiagnostics(
                new DiagnosticListener("Foo"),
                new IDiagnosticObserver[0]);

            var middleware = new ParseQueryMiddleware(
                c => Task.CompletedTask,
                new DefaultQueryParser(),
                new Cache <ICachedQuery>(10),
                diagnostics,
                null);

            // act
            await middleware.InvokeAsync(context);

            // assert
            Assert.NotNull(context.Document);
            context.Document.MatchSnapshot();
        }
        public async Task ExecuteOperationMiddleware_Mutation_ExecutedSerially()
        {
            // arrange
            var state = 0;

            var schema = Schema.Create(
                FileResource.Open("MutationExecutionSchema.graphql"),
                cnf =>
            {
                cnf.BindResolver(() => state)
                .To("Query", "state");
                cnf.BindResolver(() => state)
                .To("CurrentState", "theNumber");
                cnf.BindResolver(
                    ctx => state = ctx.ArgumentValue <int>("newNumber"))
                .To("Mutation", "changeTheNumber");
            });

            DocumentNode query = Utf8GraphQLParser.Parse(
                FileResource.Open("MutationExecutionQuery.graphql"));

            OperationDefinitionNode operationNode = query.Definitions
                                                    .OfType <OperationDefinitionNode>()
                                                    .FirstOrDefault();

            var operation = new Operation
                            (
                query,
                operationNode,
                new VariableValueBuilder(
                    schema,
                    operationNode)
                .CreateValues(new Dictionary <string, object>()),
                schema.MutationType,
                null
                            );

            IReadOnlyQueryRequest request =
                QueryRequestBuilder.New()
                .SetQuery("{ a }")
                .Create();

            var observable = new DiagnosticListener("Foo");

            var services = new DictionaryServiceProvider(
                new KeyValuePair <Type, object>(
                    typeof(IErrorHandler),
                    ErrorHandler.Default),
                new KeyValuePair <Type, object>(
                    typeof(DiagnosticListener),
                    observable),
                new KeyValuePair <Type, object>(
                    typeof(DiagnosticSource),
                    observable));

            var context = new QueryContext
                          (
                schema,
                services.CreateRequestServiceScope(),
                request,
                (f, s) => f.Middleware
                          )
            {
                CachedQuery = new CachedQuery("{ a }", query),
                Document    = query,
                QueryKey    = "foo",
                Operation   = operation
            };

            var options          = new QueryExecutionOptions();
            var strategyResolver = new ExecutionStrategyResolver(options);

            var diagnostics = new QueryExecutionDiagnostics(
                new DiagnosticListener("Foo"),
                new IDiagnosticObserver[0]);

            var middleware = new ExecuteOperationMiddleware(
                c => Task.CompletedTask,
                strategyResolver,
                new Cache <DirectiveMiddlewareCompiler>(10),
                diagnostics);

            // act
            await middleware.InvokeAsync(context);

            // assert
            context.Result.MatchSnapshot();
        }
 public static IReadOnlyQueryRequest Create(string query) =>
 QueryRequestBuilder.New().SetQuery(query).Create();
        public async Task ActivePersistedQueries_SaveQuery_InvalidHash_MD5(
            HashFormat format)
        {
            // arrange
            var serviceCollection = new ServiceCollection();

            // configure presistence
            serviceCollection.AddGraphQLSchema(b => b
                                               .AddDocumentFromString("type Query { foo: String }")
                                               .AddResolver("Query", "foo", "bar"));
            serviceCollection.AddQueryExecutor(b => b
                                               .AddMD5DocumentHashProvider(format)
                                               .UseActivePersistedQueryPipeline());

            // add in-memory query storage
            serviceCollection.AddSingleton <InMemoryQueryStorage>();
            serviceCollection.AddSingleton <IReadStoredQueries>(sp =>
                                                                sp.GetRequiredService <InMemoryQueryStorage>());
            serviceCollection.AddSingleton <IWriteStoredQueries>(sp =>
                                                                 sp.GetRequiredService <InMemoryQueryStorage>());

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            IQueryExecutor executor =
                services.GetRequiredService <IQueryExecutor>();

            var hashProvider =
                services.GetRequiredService <IDocumentHashProvider>();
            var storage = services.GetRequiredService <InMemoryQueryStorage>();

            var    query = new QuerySourceText("{ foo }");
            string hash  = hashProvider.ComputeHash(query.AsSpan());

            // act and assert
            IExecutionResult result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQueryName(hash)
                .AddExtension("persistedQuery",
                              new Dictionary <string, object>
            {
                { hashProvider.Name, hash }
            })
                .Create());

            result.MatchSnapshot(new SnapshotNameExtension(
                                     "Query_Not_Found_" + format));

            result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQueryName(hash)
                .SetQuery("{ foo }")
                .AddExtension("persistedQuery",
                              new Dictionary <string, object>
            {
                { hashProvider.Name, hash }
            })
                .Create());

            result.MatchSnapshot(new SnapshotNameExtension(
                                     "Query_Stored_" + format));

            result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQueryName(hash)
                .AddExtension("persistedQuery",
                              new Dictionary <string, object>
            {
                { hashProvider.Name, hash }
            })
                .Create());

            result.MatchSnapshot(new SnapshotNameExtension(
                                     "Query_Loaded_From_Cache_" + format));
        }
        public async Task ValidateMaxComplexityWithMiddlewareWithObjectsAndVar(
            int count, bool valid)
        {
            // arrange
            var schema = Schema.Create(
                @"
                type Query {
                    foo(i: FooInput): String
                        @cost(complexity: 5 multipliers: [""i.index""])
                }

                input FooInput {
                    index : Int
                }
                ",
                c =>
            {
                c.BindResolver(() => "Hello")
                .To("Query", "foo");
            });

            var options = new Mock <IValidateQueryOptionsAccessor>();

            options.SetupGet(t => t.MaxOperationComplexity).Returns(20);
            options.SetupGet(t => t.UseComplexityMultipliers).Returns(true);

            DocumentNode query = Utf8GraphQLParser.Parse(
                "query f($i:Int) { foo(i: { index:$i }) }");

            OperationDefinitionNode operationNode = query.Definitions
                                                    .OfType <OperationDefinitionNode>()
                                                    .FirstOrDefault();

            var operation = new Operation
                            (
                query,
                operationNode,
                new VariableValueBuilder(
                    schema,
                    operationNode)
                .CreateValues(new Dictionary <string, object>
            {
                { "i", count }
            }),
                schema.QueryType,
                null
                            );

            IReadOnlyQueryRequest request =
                QueryRequestBuilder.New()
                .SetQuery("{ a }")
                .Create();

            var services = new DictionaryServiceProvider(
                new KeyValuePair <Type, object>(
                    typeof(IErrorHandler),
                    ErrorHandler.Default));

            var context = new QueryContext
                          (
                schema,
                services.CreateRequestServiceScope(),
                request,
                (f, s) => f.Middleware
                          )
            {
                Document  = query,
                Operation = operation
            };

            var middleware = new MaxComplexityMiddleware(
                c => Task.CompletedTask,
                options.Object,
                null);

            // act
            await middleware.InvokeAsync(context);

            // assert
            if (valid)
            {
                Assert.Null(context.Result);
            }
            else
            {
                context.Result.MatchSnapshot(
                    new SnapshotNameExtension("complexity", count));
            }
        }