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)));
        }
Ejemplo n.º 3
0
        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();
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 12
0
        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));
        }
Ejemplo n.º 15
0
        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));
        }
Ejemplo n.º 17
0
        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");
        }
Ejemplo n.º 19
0
        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();
        }
Ejemplo n.º 20
0
        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();
        }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
        /// <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));
        }
Ejemplo n.º 23
0
        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));
        }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 26
0
        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();
            }
        }
Ejemplo n.º 27
0
        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));
        }
Ejemplo n.º 30
0
        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);
        }