public void AddSingleQueryAction_AllDefaults_EnsureFieldStructure()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <SimpleMethodController>();

            var action = TemplateHelper.CreateFieldTemplate <SimpleMethodController>(nameof(SimpleMethodController.TestActionMethod));

            // query root exists, mutation does not (nothing was added to it)
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Query));
            Assert.IsFalse(schema.OperationTypes.ContainsKey(GraphCollection.Mutation));

            // field for the controller exists
            var topFieldName = nameof(SimpleMethodController).Replace(Constants.CommonSuffix.CONTROLLER_SUFFIX, string.Empty);

            Assert.IsTrue(schema.OperationTypes[GraphCollection.Query].Fields.ContainsKey(topFieldName));

            // ensure the field on the query is the right name (or throw)
            var topField = schema.OperationTypes[GraphCollection.Query][topFieldName];

            Assert.IsNotNull(topField);

            var type = schema.KnownTypes.FindGraphType(topField) as IObjectGraphType;

            // ensure the action was put into the field collection of the controller operation
            Assert.IsTrue(type.Fields.ContainsKey(action.Route.Name));
        }
        public void AddSingleQueryAction_NestedObjectsOnReturnType_EnsureAllTypesAreAdded()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <NestedMutationMethodController>();

            // mutation root exists and query exists (it must by definition even if blank)
            Assert.AreEqual(2, schema.OperationTypes.Count);
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Query));
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Mutation));

            // 5 distinct scalars (int, uint, float, decimal, string)
            Assert.AreEqual(5, schema.KnownTypes.Count(x => x.Kind == TypeKind.SCALAR));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.STRING)));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.INT)));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.DECIMAL)));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.FLOAT)));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.UINT)));

            // 8 types
            // ----------------------
            //  mutation operation-type
            //  query operation-type
            //  path0 segment
            //  PersonData
            //  JobData
            //  AddressData
            //  CountryData
            //  VirtualResolvedObject
            Assert.AreEqual(8, schema.KnownTypes.Count(x => x.Kind == TypeKind.OBJECT));

            // expect a type for the root operation type
            Assert.IsTrue(schema.KnownTypes.Contains(Constants.ReservedNames.MUTATION_TYPE_NAME));
            Assert.IsTrue(schema.KnownTypes.Contains(Constants.ReservedNames.QUERY_TYPE_NAME));

            // expect a type representing the controller top level path
            Assert.IsTrue(schema.KnownTypes.Contains($"{Constants.ReservedNames.MUTATION_TYPE_NAME}_path0"));

            // expect a type for the method return type
            Assert.IsTrue(schema.KnownTypes.Contains(nameof(PersonData)));

            // person data contains job data
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(JobData), TypeKind.OBJECT));

            // person data contains address data
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(AddressData), TypeKind.OBJECT));

            // address data contains country data
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(CountryData), TypeKind.OBJECT));
        }
        public void EnsureGraphType_WhenTwoControllersDecalreTheNameRootRouteName_AMeaningfulExceptionisThrown()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <ControllerWithRootName1>();

            Assert.Throws <GraphTypeDeclarationException>(() =>
            {
                manager.EnsureGraphType <ControllerWithRootName2>();
            });
        }
Пример #4
0
        public void AddASubscriptionAction_WithoutUpdatingTheConfiguration_ThrowsDeclarationException()
        {
            using var restorePoint = new GraphQLProviderRestorePoint();

            GraphQLProviders.TemplateProvider = new SubscriptionEnabledTemplateProvider();
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();

            // do not tell the schema to allow the subscription operation type
            // schema.SetSubscriptionAllowances();

            // attempt to add a controller with a subscription
            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                var manager = new GraphSchemaManager(schema);
                manager.EnsureGraphType <SimpleMethodController>();
            });
        }
        public void EnsureGraphType_WithSubTypes_AreAddedCorrectly()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType(typeof(PersonData));

            Assert.AreEqual(10, schema.KnownTypes.Count); // added types + query
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(AddressData)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(PersonData)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(CountryData)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(JobData)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(string)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(float)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(float?)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(uint)));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(decimal)));
        }
        public void EnsureGraphType_WhenRootControllerActionOfSameNameAsAType_IsAdded_ThrowsException()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            // ThingController declares two routes
            // [Query]/Thing  (A root operation)
            // [Query]/Thing/moreData  (a nested operation under a "thing" controller)
            // there is also a type [Type]/Thing in the schema
            //
            // this should create an impossible situation where
            // [Query]/Thing returns the "Thing" graph type
            // and the controller will try to nest "moreData" into this OBJECT type
            // which should fail
            Assert.Throws <GraphTypeDeclarationException>(() =>
            {
                manager.EnsureGraphType <ThingController>();
            });
        }
        public void AddSingleQueryAction_NestedRouting_EnsureTypeStructure()
        {
            var schema = new GraphSchema();

            schema.SetNoAlterationConfiguration();

            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <NestedQueryMethodController>();

            // query root exists, mutation does not (nothing was added to it)
            Assert.AreEqual(1, schema.OperationTypes.Count);
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Query));
            Assert.IsFalse(schema.OperationTypes.ContainsKey(GraphCollection.Mutation));

            Assert.AreEqual(7, schema.KnownTypes.Count);

            // expect 2 scalars
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.FLOAT)));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(Constants.ScalarNames.DATETIME)));

            // expect 5 types to be generated
            // ----------------------------------
            // the query operation type
            // the top level field representing the controller, "path0"
            // the middle level defined on the method "path1"
            // the return type from the method itself
            // the return type of the routes
            Assert.IsTrue(schema.KnownTypes.Contains("Query"));
            Assert.IsTrue(schema.KnownTypes.Contains("Query_path0"));
            Assert.IsTrue(schema.KnownTypes.Contains("Query_path0_path1"));
            Assert.IsTrue(schema.KnownTypes.Contains(nameof(TwoPropertyObjectV2)));
            Assert.IsTrue(schema.KnownTypes.Contains(nameof(VirtualResolvedObject)));

            // expect 2 actual reference type to be assigned
            //      the return type from the method and the virtual result fro the route
            // all others are virtual types in this instance
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(TwoPropertyObjectV2), TypeKind.OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(VirtualResolvedObject), TypeKind.OBJECT));
        }
Пример #8
0
        public void ActionTemplate_CreateUnionType_PropertyCheck()
        {
            var schema = new GraphSchema();

            schema.SetNoAlterationConfiguration();

            var action = TemplateHelper.CreateActionMethodTemplate <UnionTestController>(nameof(UnionTestController.TwoTypeUnion));
            var union  = new UnionGraphTypeMaker(schema).CreateGraphType(action.UnionProxy, TypeKind.OBJECT);

            Assert.IsNotNull(union);
            Assert.IsTrue(union is UnionGraphType);
            Assert.AreEqual("FragmentData", union.Name);
            Assert.IsNull(union.Description);

            Assert.AreEqual(2, union.PossibleGraphTypeNames.Count());
            Assert.AreEqual(2, union.PossibleConcreteTypes.Count());

            Assert.IsTrue(union.PossibleGraphTypeNames.Contains(nameof(UnionDataA)));
            Assert.IsTrue(union.PossibleGraphTypeNames.Contains(nameof(UnionDataB)));
            Assert.IsTrue(union.PossibleConcreteTypes.Contains(typeof(UnionDataA)));
            Assert.IsTrue(union.PossibleConcreteTypes.Contains(typeof(UnionDataB)));
        }
Пример #9
0
        public void AddSingleSubscriptionAction_AllDefaults_EnsureFieldStructure()
        {
            using var restorePoint = new GraphQLProviderRestorePoint();

            GraphQLProviders.TemplateProvider = new SubscriptionEnabledTemplateProvider();
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            schema.SetSubscriptionAllowances();

            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <SimpleMethodController>();

            // query always exists
            // subscription root was found via the method parsed
            // mutation was not provided
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Query));
            Assert.IsFalse(schema.OperationTypes.ContainsKey(GraphCollection.Mutation));
            Assert.IsTrue(schema.OperationTypes.ContainsKey(GraphCollection.Subscription));

            // field for the controller exists
            var topFieldName = nameof(SimpleMethodController).Replace(Constants.CommonSuffix.CONTROLLER_SUFFIX, string.Empty);

            Assert.IsTrue(schema.OperationTypes[GraphCollection.Subscription].Fields.ContainsKey(topFieldName));

            // ensure the field on the subscription operation  is the right name (i.e. the controller name)
            var topField = schema.OperationTypes[GraphCollection.Subscription][topFieldName];

            Assert.IsNotNull(topField);

            var type = schema.KnownTypes.FindGraphType(topField) as IObjectGraphType;

            var action = TemplateHelper.CreateFieldTemplate <SimpleMethodController>(nameof(SimpleMethodController.TestActionMethod));

            // ensure the action was put into the field collection of the controller operation
            Assert.IsTrue(type.Fields.ContainsKey(action.Route.Name));
        }
        public void KitchenSinkController_SchemaInjection_FullFieldStructureAndTypeCheck()
        {
            var schema = new GraphSchema() as ISchema;

            schema.SetNoAlterationConfiguration();
            var manager = new GraphSchemaManager(schema);

            manager.EnsureGraphType <KitchenSinkController>();

            // mutation and query
            Assert.AreEqual(2, schema.OperationTypes.Count);

            // Query Inspection
            // ------------------------------

            // the controller segment: "Query_path0"
            // the method "myActionOperation" should register as a root query
            // The Query root itself contains the `__typename` metafield
            Assert.AreEqual(3, schema.OperationTypes[GraphCollection.Query].Fields.Count);
            var controllerQueryField   = schema.OperationTypes[GraphCollection.Query]["path0"];
            var methodAsQueryRootField = schema.OperationTypes[GraphCollection.Query]["myActionOperation"];

            Assert.IsNotNull(schema.OperationTypes[GraphCollection.Query][Constants.ReservedNames.TYPENAME_FIELD]);

            // deep inspection of the created controller-query-field
            Assert.IsNotNull(controllerQueryField);
            Assert.AreEqual(0, controllerQueryField.Arguments.Count);
            Assert.AreEqual("Kitchen sinks are great", controllerQueryField.Description);

            // the top level controller field should have one field on it
            // created from the sub path on the controller route definition "path1"
            // that field should be registered as a virtual field
            var controllerQueryFieldType = schema.KnownTypes.FindGraphType(controllerQueryField) as IObjectGraphType;

            Assert.AreEqual(2, controllerQueryFieldType.Fields.Count); // declared field + __typename
            var queryPath1 = controllerQueryFieldType.Fields["path1"];

            Assert.IsTrue(queryPath1 is VirtualGraphField);
            Assert.AreEqual(string.Empty, queryPath1.Description);

            // the virtual field (path1) should have two real actions (TestActionMethod, TestAction2)
            // and 1 virtual field ("path2") hung off it
            var queryPath1Type = schema.KnownTypes.FindGraphType(queryPath1) as IObjectGraphType;

            Assert.IsTrue(queryPath1Type is VirtualObjectGraphType);
            Assert.AreEqual(3, queryPath1Type.Fields.Count); // declared fields + __typename

            Assert.IsTrue(queryPath1Type.Fields.Any(x => x.Name == "TestActionMethod"));
            Assert.IsTrue(queryPath1Type.Fields.Any(x => x.Name == "TestAction2"));

            // path 2 is only declared on mutations
            Assert.IsFalse(queryPath1Type.Fields.ContainsKey("path2"));

            // top level query field made from a controller method
            Assert.IsNotNull(methodAsQueryRootField);
            Assert.AreEqual("myActionOperation", methodAsQueryRootField.Name);
            Assert.AreEqual("This is my\n Top Level Query Field", methodAsQueryRootField.Description);

            // Mutation Inspection
            // ------------------------------
            var controllerMutationField       = schema.OperationTypes[GraphCollection.Mutation]["path0"];
            var methodAsMutationTopLevelField = schema.OperationTypes[GraphCollection.Mutation]["SupeMutation"];

            // deep inspection of the created controller-mutation-field
            Assert.IsNotNull(controllerMutationField);
            Assert.AreEqual(0, controllerMutationField.Arguments.Count);
            Assert.AreEqual("Kitchen sinks are great", controllerMutationField.Description);

            // the controller field on the mutation side should have one field on it
            // created from the sub path on the controller route definition "path1"
            // that field should be registered as a virtual field
            var controllerMutationFieldType = schema.KnownTypes.FindGraphType(controllerMutationField) as IObjectGraphType;

            Assert.AreEqual(2, controllerMutationFieldType.Fields.Count); // declared field + __typename
            var mutationPath1 = controllerMutationFieldType.Fields["path1"];

            Assert.IsTrue(mutationPath1 is VirtualGraphField);
            Assert.AreEqual(string.Empty, mutationPath1.Description);

            // walk down the mutationPath through all its nested layers to the action method
            // let an exception be thrown (incorrectly) if any path segment doesnt exist
            var mutationPath1Type = schema.KnownTypes.FindGraphType(mutationPath1) as IObjectGraphType;
            var childField        = mutationPath1Type.Fields["path2"];
            var childFieldType    = schema.KnownTypes.FindGraphType(childField) as IObjectGraphType;

            Assert.AreEqual(string.Empty, childField.Description);
            Assert.IsFalse(childField.IsDeprecated);

            childField     = childFieldType.Fields["PAth3"];
            childFieldType = schema.KnownTypes.FindGraphType(childField) as IObjectGraphType;
            Assert.AreEqual(string.Empty, childField.Description);
            Assert.IsFalse(childField.IsDeprecated);

            childField     = childFieldType.Fields["PaTh4"];
            childFieldType = schema.KnownTypes.FindGraphType(childField) as IObjectGraphType;
            Assert.AreEqual(string.Empty, childField.Description);
            Assert.IsFalse(childField.IsDeprecated);

            childField     = childFieldType.Fields["PAT_H5"];
            childFieldType = schema.KnownTypes.FindGraphType(childField) as IObjectGraphType;
            Assert.AreEqual(string.Empty, childField.Description);
            Assert.IsFalse(childField.IsDeprecated);

            childField     = childFieldType.Fields["pathSix"];
            childFieldType = schema.KnownTypes.FindGraphType(childField) as IObjectGraphType;
            Assert.AreEqual(string.Empty, childField.Description);
            Assert.IsFalse(childField.IsDeprecated);

            var mutationAction = childFieldType.Fields["deepNestedMethod"];

            Assert.AreEqual("This is a mutation", mutationAction.Description);
            Assert.IsTrue(mutationAction.IsDeprecated);
            Assert.AreEqual("To be removed tomorrow", mutationAction.DeprecationReason);

            // check the top level mutation  field
            Assert.AreEqual("SupeMutation", methodAsMutationTopLevelField.Name);
            Assert.AreEqual("This is my\n Top Level MUtation Field!@@!!", methodAsMutationTopLevelField.Description);

            // Type Checks
            // -----------------------------------------------------
            // scalars (2): string, int (from TwoPropertyObject)
            // scalars (2): float, datetime (from TwoPropertyObjectV2)
            // scalars (2): ulong, long (from method declarations)
            // scalars (1): dceimal (from CompletePropertyObject)
            // the nullable<T> types resolve to their non-nullable scalar in the type list
            Assert.AreEqual(7, schema.KnownTypes.Count(x => x.Kind == TypeKind.SCALAR));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(string))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(int))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(ulong))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(DateTime))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(DateTime?))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(long))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(long?))));
            Assert.IsTrue(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(decimal))));

            Assert.IsFalse(schema.KnownTypes.Contains(GraphQLProviders.ScalarProvider.RetrieveScalar(typeof(double))));

            // enumerations
            Assert.AreEqual(1, schema.KnownTypes.Count(x => x.Kind == TypeKind.ENUM));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(TestEnumerationOptions), TypeKind.ENUM));

            // input type checks  (TwoPropertyObject, EmptyObject)
            Assert.AreEqual(2, schema.KnownTypes.Count(x => x.Kind == TypeKind.INPUT_OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(EmptyObject), TypeKind.INPUT_OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(TwoPropertyObject), TypeKind.INPUT_OBJECT));

            // general object types
            var concreteTypes = schema.KnownTypes.Where(x => (x is ObjectGraphType)).ToList();

            Assert.AreEqual(5, concreteTypes.Count);
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(Person), TypeKind.OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(CompletePropertyObject), TypeKind.OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(TwoPropertyObject), TypeKind.OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(TwoPropertyObjectV2), TypeKind.OBJECT));
            Assert.IsTrue(schema.KnownTypes.Contains(typeof(VirtualResolvedObject), TypeKind.OBJECT));

            // 9 "route" types should ahve been created
            // -----------------------------
            // 1.  controller query field (path0)
            // 2.       query virtual path segment path1
            // 3.  controller mutation field (path0)
            // 4.        mutation virtual path segment path1
            // 5.        mutation virtual path segment path2
            // 6.        mutation virtual path segment PAth3
            // 7.        mutation virtual path segment PaTh4
            // 8.        mutation virtual path segment PAT_H5
            // 9.        mutation virtual path segment pathSix
            var virtualTypes = schema.KnownTypes.Where(x => x is VirtualObjectGraphType).ToList();

            Assert.AreEqual(9, virtualTypes.Count);

            // pathSix should have one "real" field, the method named 'deepNestedMethod'
            var pathSix = virtualTypes.FirstOrDefault(x => x.Name.Contains("pathSix")) as IObjectGraphType;

            Assert.IsNotNull(pathSix);
            Assert.AreEqual(2, pathSix.Fields.Count); // declared field + __typename
            Assert.IsNotNull(pathSix["deepNestedMethod"]);

            // query_path1 should have two "real" fields, the method named 'TestActionMethod' and 'TestAction2'
            var querPath1 = virtualTypes.FirstOrDefault(x => x.Name.Contains("Query_path0_path1")) as IObjectGraphType;

            Assert.IsNotNull(querPath1);
            Assert.AreEqual(3, querPath1.Fields.Count); // declared field + __typename
            Assert.IsNotNull(querPath1[nameof(KitchenSinkController.TestActionMethod)]);
            Assert.IsNotNull(querPath1["TestAction2"]);
        }