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); }
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(); }
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); }
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(); }
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)); }
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(); } }
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)); }
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(); }
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(); }
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)); } }