public async Task EmptyCollectionOnContext_YieldsNothingPublished()
        {
            var nextCalled = false;

            Task CallNext(GraphQueryExecutionContext context, CancellationToken token)
            {
                nextCalled = true;
                return(Task.CompletedTask);
            }

            var next      = new GraphMiddlewareInvocationDelegate <GraphQueryExecutionContext>(CallNext);
            var queue     = new SubscriptionEventQueue();
            var publisher = new PublishRaisedSubscriptionEventsMiddleware <GraphSchema>(queue);

            var server = new TestServerBuilder()
                         .Build();

            var context = server.CreateQueryContextBuilder()
                          .Build();

            var col = context.Items.GetOrAdd(
                SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY, (_) => new List <SubscriptionEventProxy>());

            await publisher.InvokeAsync(context, next, default);

            Assert.IsTrue(nextCalled);
            Assert.AreEqual(0, queue.Count);
        }
Пример #2
0
        public async Task ListOfEnums_ProjectsIntoAListCorrectly()
        {
            // test the case where a leaf graph type is returne das a
            // list List<int>, List<string>, List<SomeEnum> etc.
            // ensure the data items are properly projected into a list
            // when rendered
            var server = new TestServerBuilder()
                         .AddGraphType <ListController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query  { createEnumList }");

            // ensure its a string when printed
            var result = await server.RenderResult(builder);

            var expectedOutput =
                @"{
                    ""data"": {
                       ""createEnumList"" : [""TESTVALUE1"", ""TESTVALUE2""]
                    }
                  }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
        }
Пример #3
0
        public void RequestCompletedLogEntry()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <LogTestController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText("{ testField }");
            var request = builder.OperationRequest;
            var context = builder.Build();

            var mock = new Mock <IGraphOperationResult>();

            mock.Setup(x => x.Request).Returns(request);
            mock.Setup(x => x.Data).Returns(new ResponseFieldSet());
            mock.Setup(x => x.Messages).Returns(new GraphMessageCollection());

            context.Result = mock.Object;

            var entry = new RequestCompletedLogEntry(context);

            Assert.AreEqual(LogEventIds.RequestCompleted.Id, entry.EventId);
            Assert.AreEqual(request.Id, entry.OperationRequestId);
            Assert.AreEqual(false, entry.ResultHasErrors);
            Assert.AreEqual(true, entry.ResultHasData);
            Assert.IsNotNull(entry.ToString());
        }
Пример #4
0
        public async Task ExtendedTypeOfToAKnownGraphType_ShouldBeProcessed()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <MixedReturnTypeController>()
                         .Build();

            // controller returns a MixedReturnTypeB, but is declared in the schema as MixedReturnTypeA
            // (the return type of the controller method signature)
            // MixedB should be able to masquerade as MixedA
            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query  { createReturnObject { field1 }}");

            // the returned object should be carried forward to produce a result
            var result = await server.RenderResult(builder);

            var expectedOutput =
                @"{
                ""data"": {
                    ""createReturnObject"" : {
                        ""field1"": ""FieldValue1""
                    }
                }
            }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
        }
        public void CollectionKeyIsNotACollection_ThrowsException()
        {
            Task CallNext(GraphQueryExecutionContext context, CancellationToken token)
            {
                return(Task.CompletedTask);
            }

            var next      = new GraphMiddlewareInvocationDelegate <GraphQueryExecutionContext>(CallNext);
            var queue     = new SubscriptionEventQueue();
            var publisher = new PublishRaisedSubscriptionEventsMiddleware <GraphSchema>(queue);

            var server = new TestServerBuilder()
                         .Build();

            var context = server.CreateQueryContextBuilder()
                          .Build();

            var col = context.Items.GetOrAdd(
                SubscriptionConstants.RAISED_EVENTS_COLLECTION_KEY, (_) => new object());

            Assert.ThrowsAsync <GraphExecutionException>(async() =>
            {
                await publisher.InvokeAsync(context, next, default);
            });
        }
Пример #6
0
        public async Task NestedScalarVariable_IsUsedInsteadOfDefault()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <InputValueController>()
                         .AddGraphQL(o =>
            {
                o.ResponseOptions.ExposeExceptions = true;
            })
                         .Build();

            // variable passed is just 1 value of hte input object (not the whole thing)
            var builder = server.CreateQueryContextBuilder();

            builder.AddVariableData("{ \"variable1\" : \"stringPassedValue\" }");
            builder.AddQueryText("query($variable1: String){ " +
                                 "complexValue(arg1: { property1: $variable1, property2: 15} ) " +
                                 "{ property1 property2 } }");
            var result = await server.RenderResult(builder);

            var expected = @"{
                                ""data"" : {
                                  ""complexValue"" : {
                                        ""property1"" : ""stringPassedValue"",
                                        ""property2"" : 15
                                    }
                                }
                            }";

            CommonAssertions.AreEqualJsonStrings(expected, result);
        }
        public async Task ExceptionThrownByChildFieldExecution_IsCapturedByParent()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .AddSchemaBuilderAction(a =>
            {
                a.FieldExecutionPipeline.AddMiddleware(new ForceExceptionForProperty1Middlware());
            })
                         .Build();

            // with the field execution pipeline addition
            // this query should run normally but resolving property results
            // in a random exception
            // the master query should capture and report this exception
            var query = server.CreateQueryContextBuilder()
                        .AddQueryText("query  { simple {simpleQueryMethod { property1 }}}")
                        .Build();

            await server.ExecuteQuery(query);

            Assert.IsFalse(query.Messages.IsSucessful);
            Assert.AreEqual(1, query.Messages.Count);
            Assert.AreEqual(Constants.ErrorCodes.EXECUTION_ERROR, query.Messages[0].Code);
            Assert.IsNotNull(query.Messages[0].Exception);
            Assert.AreEqual(GraphMessageSeverity.Critical, query.Messages[0].Severity);
            Assert.AreEqual("Forced Exception for testing", query.Messages[0].Exception.Message);
        }
Пример #8
0
        public async Task SingleFieldResolution_NoSuppliedVariables_ResolvePathThroughController_CallsResolutions_Correctly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText(@"query Operation1($var1: String = ""not-default string"") {
                                simple{
                                    simpleQueryMethod (arg1: $var1) {
                                        property1} } }");
            builder.AddOperationName("Operation1");

            // supply no values, allowing the defaults to take overand returning the single
            // requested "Property1" with the default string defined on the method.
            var result = await server.RenderResult(builder);

            CommonAssertions.AreEqualJsonStrings(
                @"{
                    ""data"": {
                        ""simple"": {
                            ""simpleQueryMethod"" : {
                                ""property1"" : ""not-default string""
                            }
                        }
                    }
                }",
                result);
        }
Пример #9
0
        public async Task TypeNameMetaField_OnObject_returnsValue()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText("query Operation1{  simple {  simpleQueryMethod { property1 __typename} } }");
            builder.AddOperationName("Operation1");

            // supply no values, allowing the defaults to take overand returning the single
            // requested "Property1" with the default string defined on the method.
            var result = await server.RenderResult(builder);

            CommonAssertions.AreEqualJsonStrings(
                @"{
                    ""data"": {
                        ""simple"": {
                                ""simpleQueryMethod"" : {
                                        ""property1"" : ""default string"",
                                        ""__typename"" : ""TwoPropertyObject""
                                }
                        }
                    }
                 }",
                result);
        }
Пример #10
0
        public async Task ObjectMethodAsField_Asyncronously_ResolvesCorrectly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <ObjectMethodController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query  { objects {  retrieveObject { asyncMethod} } }");

            // call the child AsyncMethod (which is a asycrnous method described as a field on an object, not a controller)
            // ensure it returns a value
            var result = await server.RenderResult(builder);

            var expectedOutput =
                @"{
                    ""data"": {
                       ""objects"" : {
                                ""retrieveObject"" : {
                                    ""asyncMethod"" : 8
                                }
                            }
                        }
                   }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
        }
Пример #11
0
        public async Task Rule_6_4_3_EnsureCorrectErrorIsGenerated(string expectedRuleError, string queryText)
        {
            var server = new TestServerBuilder()
                         .AddGraphType <PeopleMoverController>()
                         .AddGraphType <AllowDirective>()
                         .AddGraphType <RestrictDirective>()
                         .Build();

            var queryBuilder = server.CreateQueryContextBuilder();

            queryBuilder.AddQueryText(queryText);

            // execute the query
            var result = await server.ExecuteQuery(queryBuilder);

            // inspect for error codes
            if (result.Messages.Count != 1)
            {
                var errors = result.Messages.Where(
                    x => x.MetaData?.ContainsKey("Rule") == true)
                             .Select(x => x.MetaData["Rule"]);

                string errorMessage = $"Expected 1 error ({expectedRuleError}) but recieved {result.Messages.Count}: '{string.Join(", ", errors)}'";
                Assert.Fail(errorMessage);
            }

            var message = result.Messages[0];

            Assert.IsNotNull(message.MetaData);
            Assert.IsTrue(message.MetaData.ContainsKey("Rule"));

            var ruleBroke = message.MetaData["Rule"];

            Assert.AreEqual(expectedRuleError, ruleBroke.ToString());
        }
Пример #12
0
        public async Task FieldOnConcreteTypes_ButNotOnSharedInterface_WhenInterfaceIsReturned_IsDenied()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <ConcreteObjectA>()
                         .AddGraphType <ConcreteObjectB>()
                         .AddGraphType <InterfaceExtensionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText(@"
                                {
                                    multiObjects {
                                       middleName
                                       fullName
                                    }
                                }");

            // MiddleName is declared on ObjectA but NOT on the interface returned by 'multiObjects'
            // since the return type of multiObjects IS the interface it should be denied as a
            // valid field even though the underlying concrete types could process it
            var result = await server.ExecuteQuery(builder);

            Assert.AreEqual(GraphMessageSeverity.Critical, result.Messages.Severity);
        }
        public async Task NoItemsOnContext_YieldsNothingPublished()
        {
            var nextCalled = false;

            Task CallNext(GraphQueryExecutionContext context, CancellationToken token)
            {
                nextCalled = true;
                return(Task.CompletedTask);
            }

            var next      = new GraphMiddlewareInvocationDelegate <GraphQueryExecutionContext>(CallNext);
            var queue     = new SubscriptionEventQueue();
            var publisher = new PublishRaisedSubscriptionEventsMiddleware <GraphSchema>(queue);

            var server = new TestServerBuilder()
                         .Build();

            var context = server.CreateQueryContextBuilder()
                          .Build();

            await publisher.InvokeAsync(context, next, default);

            Assert.IsTrue(nextCalled);
            Assert.AreEqual(0, queue.Count);
        }
Пример #14
0
        public async Task IteratingACollection_CallsResolutions_Correctly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText("query Operation1{  simple {  collectionQueryMethod { property1 property2 } } }");
            builder.AddOperationName("Operation1");

            // supply no values, allowing the defaults to take overand returning the single
            // requested "Property1" with the default string defined on the method.
            var result = await server.RenderResult(builder);

            var output = @"{
                ""data"" : {
                    ""simple"": {
                        ""collectionQueryMethod"": [
                            { ""property1"": ""string0"", ""property2"": 0 },
                            { ""property1"": ""string1"", ""property2"": 1 },
                            { ""property1"": ""string2"", ""property2"": 2 }
                            ]
                        }
                    }
                }";

            CommonAssertions.AreEqualJsonStrings(
                output,
                result);
        }
        public async Task BasicBranch_ViaNamedFragments_RendersCorrectly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <FragmentProcessingController>()
                         .Build();
            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText(@"
                        query {
                            fragTester {
                                makeHybridData {
                                    ...aData
                                    ...bData
                                }
                            }
                        }

                        fragment aData on FragmentDataA{
                           property1
                        }

                        fragment bData on FragmentDataB{
                           property2
                           property1
                        }");

            var r = await server.ExecuteQuery(builder);

            var result = await server.RenderResult(builder);

            // note the ordering on bData fragment
            var expectedReslt = @"
                                {
                                    ""data"" : {
                                          ""fragTester"": {
                                                ""makeHybridData"": [
                                                {
                                                    ""property1"": ""fragmentA_prop1_0""
                                                },
                                                {
                                                    ""property1"": ""fragmentA_prop1_1""
                                                },
                                                {
                                                    ""property2"": ""fragmentB_prop2_0"",
                                                    ""property1"": ""fragmentB_prop1_0""
                                                },
                                                {
                                                    ""property2"": ""fragmentB_prop2_1"",
                                                    ""property1"": ""fragmentB_prop1_1""
                                                }]
                                            }
                                    }
                                }";

            CommonAssertions.AreEqualJsonStrings(expectedReslt, result);
        }
Пример #16
0
        public async Task TypeExtension_AppliedToAnInterface_CanBeActedOnByMultipleConcreteObjects()
        {
            var server = new TestServerBuilder()

                         .AddGraphType <ConcreteObjectA>()
                         .AddGraphType <ConcreteObjectB>()
                         .AddGraphType <InterfaceExtensionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText(@"
                                {
                                    multiObjects {
                                       firstName
                                       fullName
                                    }
                                }");

            // fullName is an type extension keyed on the interface that both object types inherit it does not exist as a declared
            // member of ObjectA, B or the common interface
            // the interface explicitly DOES NOT declare FirstName or LastName ensuring they must be generated from the
            // concrete types
            var result = await server.RenderResult(builder);

            // output combines declared methods on concrete objects, firstName, and the interface extension, fullName
            var expectedOutput = @"
                        {
                          ""data"": {
                                    ""multiObjects"": [
                                    {
                                        ""firstName"" : ""0A_prop1"",
                                        ""fullName"": ""0A_prop1 0A_prop2""
                                    },
                                    {
                                        ""firstName"" : ""1A_prop1"",
                                        ""fullName"": ""1A_prop1 1A_prop2""
                                    },
                                    {
                                        ""firstName"" : ""0B_prop1"",
                                        ""fullName"": ""0B_prop1 0B_prop2""
                                    },
                                    {
                                        ""firstName"" : ""1B_prop1"",
                                        ""fullName"": ""1B_prop1 1B_prop2""
                                    }
                                    ]
                                }
                            }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
        }
        public async Task WhenAnInterfaceIsSpreadInAUnion_TheUnionMembersThatImplementTheInterface_ShouldReturnInterfaceFields()
        {
            // sourceDataInheritance returns a union type (FragmentDataA | FragmentDataB | FragmentDataC)
            // All Three implement interface graph type FragmentDataItem and should include any fields in the "sampleFrag" fragment
            // which is typed to the interface
            var server = new TestServerBuilder()
                         .AddGraphType <FragmentProcessingController>()
                         .AddGraphType <IFragmentDataItem>()
                         .AddSchemaBuilderAction(o =>
            {
                o.Options.ResponseOptions.ExposeExceptions = true;
            })
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText(@"
                            query {
                                fragTester {
                                    sourceDataInheritance {
                                        ...sampleFrag
                                    }
                                }
                            }

                            fragment sampleFrag on FragmentDataItem {
                               property1
                            }");

            var expectedResult = @"
                                    {
                                        ""data"" : {
                                              ""fragTester"": {
                                                    ""sourceDataInheritance"": [
                                                    {
                                                        ""property1"": ""fragmentA_prop1_0""
                                                    },
                                                    {
                                                        ""property1"": ""fragmentB_prop1_0""
                                                    },
                                                    {
                                                        ""property1"": ""fragmentA_prop1_FromC""
                                                    }]
                                                }
                                        }
                                    }";

            var result = await server.RenderResult(builder);

            CommonAssertions.AreEqualJsonStrings(expectedResult, result);
        }
Пример #18
0
        public async Task WhenNoLeafValuesAreRequested_ItemIsReturnedAsNullAndPropegated()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText("query Operation1{  simple {  simpleQueryMethod  } }");
            builder.AddOperationName("Operation1");

            var result = await server.RenderResult(builder);

            CommonAssertions.AreEqualJsonStrings(
                "{ \"data\" : null }",
                result);
        }
Пример #19
0
        public async Task ListOfEnums_WithAnUnlabeledValue_Fails()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <ListController>()
                         .Build();

            // controller returns a list of {Value1, -3}
            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query  { createEnumListWithInValidValue }");

            // ensure hte -3 wasnt accepted as valid for the enum being
            // returned
            var result = await server.ExecuteQuery(builder);

            Assert.IsFalse(result.Messages.IsSucessful);
            Assert.AreEqual(1, result.Messages.Count);
        }
Пример #20
0
        public async Task SimpleResolution_WithDirective_CallsDirectiveCorrectly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .AddGraphType <CallTestDirective>()
                         .Build();

            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query Operation1{  simple {  simpleQueryMethod @callTest(arg: 3) { property1} } }")
                          .AddOperationName("Operation1");

            // supply no values, allowing the defaults to take overand returning the single
            // requested "Property1" with the default string defined on the method.
            var result = await server.ExecuteQuery(builder);

            Assert.AreEqual(0, result.Messages.Count);
            Assert.AreEqual(1, CallTestDirective.TotalCalls);
        }
Пример #21
0
        public async Task IndeterminateUnionType_ShouldCallIntoUnionProxyResolveMethod_AndProduceResult()
        {
            MixedTypeUnion.TotalCallCount = 0;
            var server = new TestServerBuilder()
                         .AddGraphType <MixedReturnTypeController>()
                         .AddSchemaBuilderAction(a =>
            {
                a.Options.ResponseOptions.ExposeExceptions = true;
            })
                         .Build();

            // controller actually returns a MixedReturnTypeC, but is declared in the schema as
            // MixedUnionType (of A and B)
            // MixedC inherits from both A and B and could be either
            // the library should call into MixedUnionType and ask it to resolve the relationship
            //
            // mixedUnion should return TypeA, thus rendering field 1
            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText(
                @"query  {
                    createIndeterminateReturn {
                        ... on MixedReturnTypeB {
                                field2
                        }
                        ... on MixedReturnTypeA {
                                field1
                        }
                }}");

            // the returned object should be carried forward to produce a result
            var result = await server.RenderResult(builder);

            var expectedOutput =
                @"{
                ""data"": {
                    ""createIndeterminateReturn"" : {
                        ""field1"": ""FieldValue1""
                    }
                }
            }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
            Assert.AreEqual(1, MixedTypeUnion.TotalCallCount);
        }
Пример #22
0
        public async Task DirectiveExecution_MaintainsRequestMetaDataCollection_CallsDirectiveCorrectly()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .AddGraphType <MetaDataShareDirective>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddQueryText("query Operation1{  simple {  simpleQueryMethod @metaDataShare(arg: 3) { property1} } }");
            builder.AddOperationName("Operation1");

            // supply no values, allowing the defaults to take overand returning the single
            // requested "Property1" with the default string defined on the method.
            var context = builder.Build();
            await server.ExecuteQuery(context);

            Assert.AreEqual(0, context.Messages.Count);
            Assert.IsTrue(MetaDataShareDirective.FoundInAfterCompletion);
        }
Пример #23
0
        public async Task UnhandledException_InUserCode_OnDirectGraphMethodCall_ResultsInMessageOnResponse()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query {  simple {  throwable  { executeThrow } } }");

            // the controller method returns an object with a single mapped method "ExecuteThrow" that throws an exception
            // this is executed through the graphmethod resolver (not the controller action resolver) allowing an internal
            // exception to fully bubble up (not captured by the action invoker)
            var result = await server.ExecuteQuery(builder);

            Assert.AreEqual(1, result.Messages.Count);
            Assert.AreEqual(GraphMessageSeverity.Critical, result.Messages.Severity);
            Assert.AreEqual(Constants.ErrorCodes.UNHANDLED_EXCEPTION, result.Messages[0].Code);
            Assert.IsNotNull(result.Messages[0].Exception);
            Assert.AreEqual("Failure from ObjectWithThrowMethod", result.Messages[0].Exception.Message);
        }
Пример #24
0
        public async Task IncludeDirective_ResponseAppropriately(bool includeValue, string expectedJson)
        {
            var server = new TestServerBuilder()
                         .AddGraphType <SimpleExecutionController>()
                         .AddGraphType <IncludeDirective>()
                         .Build();

            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText(
                "query Operation1{  simple {  simpleQueryMethod { property1, property2 @include(if: " +
                includeValue.ToString().ToLower() +
                ") } } }")
                          .AddOperationName("Operation1");

            var result = await server.RenderResult(builder);

            CommonAssertions.AreEqualJsonStrings(
                expectedJson,
                result);
        }
Пример #25
0
        public async Task DataMessage_WithData_SerializesCorrectly()
        {
            var server = new TestServerBuilder()
                         .AddGraphController <ApolloDataMessageController>()
                         .AddSubscriptionServer()
                         .Build();

            var client = server.CreateSubscriptionClient();

            var context = server.CreateQueryContextBuilder()
                          .AddQueryText("query { getValue { property1 property2 } }")
                          .Build();
            await server.ExecuteQuery(context);

            var message = new ApolloServerDataMessage("abc111", context.Result);

            var converter = new ApolloServerDataMessageConverter(
                server.Schema,
                server.ServiceProvider.GetRequiredService <IGraphResponseWriter <GraphSchema> >());

            var options = new JsonSerializerOptions();

            options.Converters.Add(converter);
            var response = JsonSerializer.Serialize(message, message.GetType(), options);

            var expected = @"
            {
                ""type"" : ""data"",
                ""id"" : ""abc111"",
                ""payload"": {
                    ""data"": {
                        ""getValue"" : {
                            ""property1"": ""abc123"",
                            ""property2"" : 15
                        }
                    }
                }
            }";

            CommonAssertions.AreEqualJsonStrings(expected, response);
        }
Пример #26
0
        public async Task SingleScalarValueVariable_IsUsedInsteadOfDefault()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <InputValueController>()
                         .Build();

            var builder = server.CreateQueryContextBuilder();

            builder.AddVariableData("{ \"variable1\" : \"test string 86\" }");
            builder.AddQueryText("query($variable1: String){ scalarValue(arg1: $variable1) }");
            var result = await server.RenderResult(builder);

            var expected = @"
                            {
                                ""data"" : {
                                  ""scalarValue"" : ""test string 86""
                                }
                            }";

            CommonAssertions.AreEqualJsonStrings(expected, result);
        }
Пример #27
0
        public async Task Rule_6_4_4_ErrorPropegation_InvalidatesParentObjects_MultiRootFields()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <PeopleMoverController>()
                         .AddGraphType <AllowDirective>()
                         .AddGraphType <RestrictDirective>()
                         .Build();

            // field "invalidMovers" will result in a null field because of an error caused by
            // down stream field peopleMovers.allElevatorsWithANull[1].Name
            //
            // however the field "validMovers" should resolve just fine
            // resulting in a data set with invalidMovers as null but with validMovers as having a value
            // fully populated
            var queryBuilder = server.CreateQueryContextBuilder();

            queryBuilder.AddQueryText(@"query Operation1{
                                    invalidMovers: peopleMovers { allElevatorsWithANull{ id name } }
                                    validMovers: peopleMovers { elevator(id: 5) { id name } }
                                }");

            var result = await server.ExecuteQuery(queryBuilder);

            // ensure error 6.4.3 is recorded (and that its all thats recorded)
            Assert.AreEqual(1, result.Messages.Count);
            var message = result.Messages[0];

            Assert.IsNotNull(message.MetaData);
            Assert.IsTrue(message.MetaData.ContainsKey("Rule"));

            var ruleBroke = message.MetaData["Rule"];

            Assert.AreEqual("6.4.3", ruleBroke.ToString());

            Assert.IsNotNull(result.Data);
            var data = result.Data as IResponseFieldSet;

            Assert.IsNull(data.Fields["invalidMovers"]);
            Assert.IsNotNull(data.Fields["validMovers"]);
        }
Пример #28
0
        public async Task CustomScalar_BecomesValidCoreScalarValue()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <GraphIdController>()
                         .Build();

            // retrieveid returns a "GraphId"
            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText("query  { retrieveId }");

            // ensure its a string when printed
            var result = await server.RenderResult(builder);

            var expectedOutput =
                @"{
                    ""data"": {
                       ""retrieveId"" : ""abc123""
                    }
                  }";

            CommonAssertions.AreEqualJsonStrings(expectedOutput, result);
        }
Пример #29
0
        public async Task IndeterminateUnionType_NullReturnType_Fails()
        {
            MixedTypeUnionNullReturn.TotalCallCount = 0;
            var server = new TestServerBuilder()
                         .AddGraphType <MixedReturnTypeController>()
                         .AddSchemaBuilderAction(a =>
            {
                a.Options.ResponseOptions.ExposeExceptions = true;
            })
                         .Build();

            // controller actually returns a MixedReturnTypeC, but is declared in the schema as
            // MixedTypeUnionNullReturn (of A and B)
            // MixedC inherits from both A and B and could be either
            // the library should call into MixedUnionType and ask it to resolve the relationship
            // the union type (MixedTypeUnionNullReturn) will return -null-
            // and the query should fail
            var builder = server.CreateQueryContextBuilder()
                          .AddQueryText(
                @"query  {
                    createNullIndeterminateReturn {
                        ... on MixedReturnTypeB {
                                field2
                        }
                        ... on MixedReturnTypeA {
                                field1
                        }
                }}");

            // the returned object should be carried forward to produce a result
            var result = await server.ExecuteQuery(builder);

            Assert.IsNotNull(result);
            Assert.IsFalse(result.Messages.IsSucessful);
            Assert.AreEqual(1, result.Messages.Count);
            Assert.AreEqual(Constants.ErrorCodes.EXECUTION_ERROR, result.Messages[0].Code);
            Assert.AreEqual(1, MixedTypeUnionNullReturn.TotalCallCount);
        }
Пример #30
0
        public async Task Rule_6_4_4_ErrorPropegation_InvalidatesParentObjects()
        {
            var server = new TestServerBuilder()
                         .AddGraphType <PeopleMoverController>()
                         .AddGraphType <AllowDirective>()
                         .AddGraphType <RestrictDirective>()
                         .Build();

            // allElevatorsWithANull is defined to be a list of elevators (type expression:  [Elevator!])
            // it returns a list but with the second item (of 3) having a null name that when resolved
            // fails validation for that individual list item as each elevator must have a name according
            // the the Elevator's individual type requirements.
            // This results in the second list item becoming null...which in turn results in the
            // list being invalid (since it now contains a null element) this fails rule 6.4.4
            //
            // ensure that this single invalid name in list item 2 is propegated to null out
            // the whole list
            var queryBuilder = server.CreateQueryContextBuilder();

            queryBuilder.AddQueryText("query Operation1{ peopleMovers { allElevatorsWithANull{ id name } } }");

            var result = await server.ExecuteQuery(queryBuilder);

            // ensure error 6.4.3 is recorded (and that its all thats recorded)
            Assert.AreEqual(1, result.Messages.Count);
            var message = result.Messages[0];

            Assert.IsNotNull(message.MetaData);
            Assert.IsTrue(message.MetaData.ContainsKey("Rule"));

            var ruleBroke = message.MetaData["Rule"];

            Assert.AreEqual("6.4.3", ruleBroke.ToString());

            // since only one top level query was made (peopleMovers)
            // this reslts in all fields of the query being null, forcing "data" to also be null
            Assert.IsNull(result.Data);
        }