public void VariableUsedInComplexInput() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" query queryWithComplexInput($name: String) { findDog(complex: { name: $name }) { name } }"); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.False(result.HasErrors); }
public static ISchemaBuilder AddDocumentFromString( this ISchemaBuilder builder, string schema) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } if (string.IsNullOrEmpty(schema)) { throw new ArgumentException( TypeResources.SchemaBuilderExtensions_SchemaIsEmpty, nameof(schema)); } return(builder.AddDocument(sp => Utf8GraphQLParser.Parse(schema))); }
public void VariableUsedAndDeclared() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" query variableIsDefined($atOtherHomes: Boolean) { dog { isHousetrained(atOtherHomes: $atOtherHomes) } }"); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.False(result.HasErrors); }
public void UnionType_AddDuplicateDirectives() { // arrange const string schema = "union Foo @foo = A | B " + "type A { a: String } " + "type B { b: String } " + "directive @foo on INTERFACE"; const string extensions = "extend union Foo @foo"; // act var rewriter = new AddSchemaExtensionRewriter(); Action action = () => rewriter.AddExtensions( Utf8GraphQLParser.Parse(schema), Utf8GraphQLParser.Parse(extensions)); // assert Assert.Throws <SchemaMergeException>(action).Message.MatchSnapshot(); }
public void Use_MiddlewareDelegate() { // arrange // act ISchema schema = SchemaBuilder.New() .AddDocument(sp => Utf8GraphQLParser.Parse("type Query { a: String }")) .Use(next => context => { context.Result = "foo"; return(Task.CompletedTask); }) .Create(); // assert schema.MakeExecutable().Execute("{ a }").MatchSnapshot(); }
public void VariableUsedInListInput() { // arrange IDocumentValidatorContext context = ValidationUtils.CreateContext(); DocumentNode query = Utf8GraphQLParser.Parse(@" query queryWithListInput($value: Bool) { booleanList(booleanListArg: [ $value ]) }"); context.Prepare(query); // act Rule.Validate(context, query); // assert Assert.Empty(context.Errors); }
public void UnionType_AddDirectives() { // arrange const string schema = "union Foo = A | B " + "type A { a: String } " + "type B { b: String } " + "directive @foo on INTERFACE"; const string extensions = "extend union Foo @foo"; // act var rewriter = new AddSchemaExtensionRewriter(); DocumentNode merged = rewriter.AddExtensions( Utf8GraphQLParser.Parse(schema), Utf8GraphQLParser.Parse(extensions)); // assert merged.ToString().MatchSnapshot(); }
public void NonNullListToList() { // arrange IDocumentValidatorContext context = ValidationUtils.CreateContext(); DocumentNode query = Utf8GraphQLParser.Parse(@" query nonNullListToList($nonNullBooleanList: [Boolean]!) { arguments { booleanListArgField(booleanListArg: $nonNullBooleanList) } } "); // act Rule.Validate(context, query); // assert Assert.Empty(context.Errors); }
public void BooleanArgQueryWithDefault2() { // arrange IDocumentValidatorContext context = ValidationUtils.CreateContext(); DocumentNode query = Utf8GraphQLParser.Parse(@" query booleanArgQueryWithDefault($booleanArg: Boolean = true) { arguments { nonNullBooleanArgField(nonNullBooleanArg: $booleanArg) } } "); // act Rule.Validate(context, query); // assert Assert.Empty(context.Errors); }
public void BooleanVariableAsListElement() { // arrange IDocumentValidatorContext context = ValidationUtils.CreateContext(); DocumentNode query = Utf8GraphQLParser.Parse(@" query nonNullListToList($b: Boolean) { arguments { booleanListArgField(booleanListArg: [$b]) } } "); // act Rule.Validate(context, query); // assert Assert.Empty(context.Errors); }
public void SupportedDirective() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" { dog { name @skip(if: true) } } "); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.False(result.HasErrors); }
private async Task <IReadOnlyList <DocumentInfo> > GetGraphQLFiles( string path, ICollection <HCError> errors) { var documents = new List <DocumentInfo>(); foreach (string file in Directory.GetFiles(path, "*.graphql")) { byte[] buffer = await File.ReadAllBytesAsync(file); try { DocumentNode document = Utf8GraphQLParser.Parse(buffer); if (document.Definitions.Count > 0) { DocumentKind kind = document.Definitions.Any(t => t is ITypeSystemDefinitionNode) ? DocumentKind.Schema : DocumentKind.Query; documents.Add(new DocumentInfo { Kind = kind, FileName = file, Document = document }); } } catch (SyntaxException ex) { HCError error = HCErrorBuilder.New() .SetMessage(ex.Message) .AddLocation(ex.Line, ex.Column) .SetCode("SYNTAX_ERROR") .SetExtension("fileName", file) .Build(); errors.Add(error); return(Array.Empty <DocumentInfo>()); } } return(documents); }
public void FragmentCycle2() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" { dog { ...nameFragment } } fragment nameFragment on Dog { name ...barkVolumeFragment } fragment barkVolumeFragment on Dog { barkVolume ...barkVolumeFragment1 } fragment barkVolumeFragment1 on Dog { barkVolume ...barkVolumeFragment2 } fragment barkVolumeFragment2 on Dog { barkVolume ...nameFragment } "); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.True(result.HasErrors); Assert.Collection(result.Errors, t => Assert.Equal(t.Message, "The graph of fragment spreads must not form any " + "cycles including spreading itself. Otherwise an " + "operation could infinitely spread or infinitely " + "execute on cycles in the underlying data.")); }
public void Find_Enum_As_Return_Type() { // arrange ISchema schema = SchemaBuilder.New() .AddDocumentFromString(@" type Query { foo(input: A): D } input A { b: [B!]! } input B { c: [C!]! } enum C { A B C } enum D { A B C } ") .Use(next => context => Task.CompletedTask) .Create(); DocumentNode document = Utf8GraphQLParser.Parse( "query { foo(input: { }) }"); // act var analyzer = new EnumTypeUsageAnalyzer(schema); analyzer.Analyze(document); // assert Assert.Collection(analyzer.EnumTypes, t => Assert.Equal("D", t.Name)); }
public void Prepare_Fragment_Definition() { // arrange ISchema schema = SchemaBuilder.New() .AddStarWarsTypes() .Create(); DocumentNode document = Utf8GraphQLParser.Parse( @"{ hero(episode: EMPIRE) { name ... abc ... def } } fragment abc on Droid { primaryFunction } fragment def on Human { homePlanet } "); OperationDefinitionNode operation = document.Definitions.OfType <OperationDefinitionNode>().Single(); var fragments = new FragmentCollection(schema, document); // act IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets = OperationCompiler.Compile(schema, fragments, operation); // assert var op = new Operation( "abc", document, operation, schema.QueryType, selectionSets); op.Print().MatchSnapshot(); }
public void Find_Only_Selected_Return_Types() { // arrange ISchema schema = SchemaBuilder.New() .AddDocumentFromString(@" type Query { a: A c: C } enum A { A B C } enum B { A B C } enum C { A B C } ") .Use(next => context => Task.CompletedTask) .Create(); DocumentNode document = Utf8GraphQLParser.Parse( "query($a: [C!]!) { a c }"); // act var analyzer = new EnumTypeUsageAnalyzer(schema); analyzer.Analyze(document); // assert Assert.Collection(analyzer.EnumTypes.OrderBy(t => t.Name), t => Assert.Equal("A", t.Name), t => Assert.Equal("C", t.Name)); }
public void Object_Field_Visibility_Is_Correctly_Inherited_3() { // arrange var variables = new Mock <IVariableValueCollection>(); variables.Setup(t => t.GetVariable <bool>(It.IsAny <NameString>())) .Returns((NameString name) => name.Equals("v")); ISchema schema = SchemaBuilder.New() .AddStarWarsTypes() .Create(); ObjectType droid = schema.GetType <ObjectType>("Droid"); DocumentNode document = Utf8GraphQLParser.Parse( @"query foo($v: Boolean, $q: Boolean) { hero(episode: EMPIRE) @include(if: $v) { name @include(if: $q) } }"); OperationDefinitionNode operationDefinition = document.Definitions.OfType <OperationDefinitionNode>().Single(); // act var operation = (Operation)OperationCompiler.Compile( "a", document, operationDefinition, schema, schema.QueryType); // assert ISelectionSet rootSelections = operation.RootSelectionVariants.GetSelectionSet( operation.RootSelectionVariants.GetPossibleTypes().First()); ISelectionSet droidSelections = operation.GetSelectionSet(rootSelections.Selections[0].SelectionSet !, droid); Assert.Empty(droidSelections.Selections.Where(t => t.IsIncluded(variables.Object))); operation.Print().MatchSnapshot(); }
public void AliasesMapIsCorrect() { // arrange DocumentNode query_a = Utf8GraphQLParser.Parse( FileResource.Open("MergeQueryWithVariable.graphql")); DocumentNode query_b = Utf8GraphQLParser.Parse( FileResource.Open("MergeQueryWithVariable.graphql")); // act var rewriter = new MergeQueryRewriter(Array.Empty <string>()); IDictionary <string, string> a = rewriter.AddQuery(query_a, "_a", true); IDictionary <string, string> b = rewriter.AddQuery(query_b, "_b", true); // assert a.MatchSnapshot("AliasesMapIsCorrect_A"); b.MatchSnapshot("AliasesMapIsCorrect_B"); }
public void MergeDemoSchemaWithDefaultHandler() { // arrange DocumentNode schema_a = Utf8GraphQLParser.Parse( FileResource.Open("Contract.graphql")); DocumentNode schema_b = Utf8GraphQLParser.Parse( FileResource.Open("Customer.graphql")); // act DocumentNode schema = SchemaMerger.New() .AddSchema("A", schema_a) .AddSchema("B", schema_b) .Merge(); // assert SchemaSyntaxSerializer.Serialize(schema).MatchSnapshot(); }
public void FieldDefinitionDoesNotHaveSameTypeShape() { // arrange DocumentNode schema_a = Utf8GraphQLParser.Parse( "type A { b1: String b2: String } type B { c: String! }"); DocumentNode schema_b = Utf8GraphQLParser.Parse( "type A { b1: String b3: String } type B { c: String }"); // act DocumentNode merged = SchemaMerger.New() .AddSchema("A", schema_a) .AddSchema("B", schema_b) .Merge(); // assert SchemaSyntaxSerializer.Serialize(merged).MatchSnapshot(); }
public static IStitchingBuilder AddExtensionsFromString( this IStitchingBuilder builder, string extensions) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (string.IsNullOrEmpty(extensions)) { throw new ArgumentException( StitchingResources.Extensions_EmptyOrNull, nameof(extensions)); } builder.AddExtensions(s => Utf8GraphQLParser.Parse(extensions)); return(builder); }
/// <inheritdoc /> public async ValueTask <IExecutionResult> ExecuteAsync( OperationRequest request, CancellationToken cancellationToken = default) { if (request is null) { throw new ArgumentNullException(nameof(request)); } if (Executor is null) { throw ThrowHelper.InMemoryClient_NoExecutorConfigured(_name); } var requestBuilder = new QueryRequestBuilder(); if (request.Document.Body.Length > 0) { requestBuilder.SetQuery(Utf8GraphQLParser.Parse(request.Document.Body)); } else { requestBuilder.SetQueryId(request.Id); } requestBuilder.SetOperation(request.Name); requestBuilder.SetVariableValues(CreateVariables(request.Variables)); requestBuilder.SetExtensions(request.GetExtensionsOrNull()); requestBuilder.SetProperties(request.GetContextDataOrNull()); IServiceProvider applicationService = Executor.Services.GetApplicationServices(); foreach (var interceptor in RequestInterceptors) { await interceptor .OnCreateAsync(applicationService, request, requestBuilder, cancellationToken) .ConfigureAwait(false); } return(await Executor .ExecuteAsync(requestBuilder.Create(), cancellationToken) .ConfigureAwait(false)); }
public void InvalidDirectiveArgName() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" fragment invalidArgName on Dog { isHousetrained(atOtherHomes: true) @include(unless: false) } "); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.True(result.HasErrors); Assert.Collection(result.Errors, t => Assert.Equal( $"The argument `unless` does not exist.", t.Message)); }
public void InvalidFieldArgName() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" fragment invalidArgName on Dog { doesKnowCommand(command: CLEAN_UP_HOUSE) } "); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.True(result.HasErrors); Assert.Collection(result.Errors, t => Assert.Equal( $"The argument `command` does not exist.", t.Message)); }
public void QueryWithoutTypeSystemDefinitions() { // arrange IDocumentValidatorContext context = ValidationUtils.CreateContext(); DocumentNode query = Utf8GraphQLParser.Parse(@" query getDogName { dog { name color } } "); // act Rule.Validate(context, query); // assert Assert.Empty(context.Errors); }
public async Task Send_Start_ReceiveDataOnMutation() { using (TestServer testServer = CreateStarWarsServer()) { // arrange WebSocketClient client = CreateWebSocketClient(testServer); WebSocket webSocket = await ConnectToServerAsync(client); var document = Utf8GraphQLParser.Parse( "subscription { onReview(episode: NEWHOPE) { stars } }"); var request = new GraphQLRequest(document); const string subscriptionId = "abc"; // act await webSocket.SendSubscriptionStartAsync(subscriptionId, request); // assert await testServer.SendRequestAsync(new ClientQueryRequest { Query = @" mutation { createReview(episode:NEWHOPE review: { commentary: ""foo"" stars: 5 }) { stars } } " }); IReadOnlyDictionary <string, object> message = await WaitForMessage( webSocket, MessageTypes.Subscription.Data, TimeSpan.FromSeconds(15)); Assert.NotNull(message); message.MatchSnapshot(); } }
public void QueryContainsOneAnonymousOperation() { // arrange Schema schema = ValidationUtils.CreateSchema(); DocumentNode query = Utf8GraphQLParser.Parse(@" { dog { name } } "); // act QueryValidationResult result = Rule.Validate(schema, query); // assert Assert.False(result.HasErrors); Assert.Empty(result.Errors); }
public void QueryWithGlobalVariables() { // arrange DocumentNode query_a = Utf8GraphQLParser.Parse( FileResource.Open("MergeQueryWithVariable.graphql")); DocumentNode query_b = Utf8GraphQLParser.Parse( FileResource.Open("MergeQueryWithVariable.graphql")); // act var rewriter = new MergeQueryRewriter( new HashSet <string>(new[] { "global" })); rewriter.AddQuery(query_a, "_a", true); rewriter.AddQuery(query_b, "_b", true); DocumentNode document = rewriter.Merge(); // assert QuerySyntaxSerializer.Serialize(document).MatchSnapshot(); }
public async Task Interface_With_Default_Names_Two_Models() { // arrange var schema = await new ServiceCollection() .AddStarWarsRepositories() .AddGraphQL() .AddStarWars() .BuildSchemaAsync(); var document = Utf8GraphQLParser.Parse(@" query GetHero { hero(episode: NEW_HOPE) { name ... on Droid { primaryFunction } } }"); var context = new DocumentAnalyzerContext(schema, document); SelectionSetVariants selectionSetVariants = context.CollectFields(); FieldSelection fieldSelection = selectionSetVariants.ReturnType.Fields.First(); selectionSetVariants = context.CollectFields(fieldSelection); // act var analyzer = new InterfaceTypeSelectionSetAnalyzer(); var result = analyzer.Analyze(context, fieldSelection, selectionSetVariants); // assert Assert.Equal("IGetHero_Hero", result.Name); Assert.Collection( context.GetImplementations(result), model => Assert.Equal("IGetHero_Hero_Human", model.Name), model => Assert.Equal("IGetHero_Hero_Droid", model.Name)); Assert.Collection( result.Fields, field => Assert.Equal("Name", field.Name)); }
public async Task TwoOperations_ShortHand_QueryException() { // arrange var schema = Schema.Create(@" type Query { a: String } ", c => { c.BindResolver(() => "hello world") .To("Query", "a"); }); var sourceText = "{ a } 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 Func <Task> func = () => middleware.InvokeAsync(context); // assert QueryException exception = await Assert.ThrowsAsync <QueryException>(func); Assert.Equal( "Only queries that contain one operation can be executed " + "without specifying the opartion name.", exception.Message); }