/// <summary> /// Searches current api for true mutation container /// </summary> /// <param name="apiMutation">The mutation</param> /// <param name="apiRoot">The api root</param> /// <returns>The mutation container</returns> private static MergedField FindContainer(ApiMutation apiMutation, MergedApiRoot apiRoot) { var path = apiMutation.Name.Split('.').ToList(); path.RemoveAt(path.Count - 1); MergedObjectType type = apiRoot; MergedField field = null; var queue = new Queue <string>(path); while (queue.Count > 0) { if (type == null) { return(null); } var fieldName = queue.Dequeue(); if (!type.Fields.TryGetValue(fieldName, out field)) { return(null); } type = field.Type as MergedObjectType; } return(field); }
public async Task SchemaDescriptionTest() { var checkAttributeArguments = new[] { ApiField.Scalar( "attribute", EnScalarType.String, description: "attribute to check") }; var objectFields = new[] { ApiField.Scalar( "uid", EnScalarType.Guid, description: "The object unique identifier"), ApiField.Scalar("name", EnScalarType.String, description: "The object name"), ApiField.Scalar( "attributes", EnScalarType.String, EnFieldFlags.IsArray, description: "The object attributes"), ApiField.Scalar( "checkAttribute", EnScalarType.Boolean, arguments: checkAttributeArguments, description: "checks the attribute") }; var objectType = new ApiObjectType("object", objectFields) { Description = "Some abstract object" }; var apiField = objectType.CreateField( "new", description: "The new object data"); var mutations = new[] { ApiMutation.CreateFromField( ApiField.Object( "objects_create", "object", arguments: new[] { apiField }, description: "creates a new object"), ApiMutation.EnType.ConnectionCreate, new List <ApiRequest>()) }; var api = new ApiDescription( "TestApi", "0.0.0.1", new[] { objectType }, new[] { objectType.CreateField("objects", EnFieldFlags.IsConnection, "The objects dataset") }, mutations) { Description = "The test api" }; var provider = new MoqProvider { Description = api }; var schema = SchemaGenerator.Generate(new List <ApiProvider> { provider }); var errors = SchemaGenerator.CheckSchema(schema).Select(e => $"Schema type error: {e}") .Union(SchemaGenerator.CheckSchemaIntrospection(schema)) .Select(e => $"Schema introspection error: {e}"); var hasErrors = false; foreach (var error in errors) { hasErrors = true; this.output.WriteLine(error); } using (var printer = new SchemaPrinter(schema)) { var description = printer.Print(); this.output.WriteLine("-------- Schema -----------"); this.output.WriteLine(description); Assert.False(string.IsNullOrWhiteSpace(description)); } Assert.False(hasErrors); var query = BaseInstaller.ReadTextResource( this.GetType().GetTypeInfo().Assembly, "KlusterKite.Web.Tests.GraphQL.Resources.IntrospectionQuery.txt"); var result = await new DocumentExecuter().ExecuteAsync( r => { r.Schema = schema; r.Query = query; }).ConfigureAwait(true); var response = new DocumentWriter(true).Write(result); this.output.WriteLine(response); var expectedResponse = BaseInstaller.ReadTextResource( this.GetType().GetTypeInfo().Assembly, "KlusterKite.Web.Tests.GraphQL.Resources.SchemaDescriptionTestSnapshot.txt"); Assert.Equal(CleanResponse(expectedResponse), CleanResponse(response)); }
/// <summary> /// Register the mutation /// </summary> /// <param name="provider">The mutation api provider</param> /// <param name="apiMutation">The mutation description</param> /// <param name="apiRoot">The api root</param> /// <param name="typesCreated">The list of created types</param> /// <returns>The mutation as merged field </returns> private static MergedField RegisterConnectionMutation( ApiProvider provider, ApiMutation apiMutation, MergedApiRoot apiRoot, Dictionary <string, MergedType> typesCreated) { var field = FindContainer(apiMutation, apiRoot); var connectionType = field?.Type as MergedConnectionType; if (connectionType == null) { return(null); } var errorDescriptionApiType = provider.Description.Types.FirstOrDefault(t => t.TypeName == "ErrorDescription") as ApiObjectType; MergedType errorDescriptionType = null; if (errorDescriptionApiType != null) { errorDescriptionType = CreateConnectionType(errorDescriptionApiType, provider, typesCreated); } var returnType = new MergedConnectionMutationResultType( connectionType.ElementType, apiRoot, errorDescriptionType, provider); typesCreated[returnType.ComplexTypeName] = returnType; var inputType = new MergedInputType(apiMutation.Name); inputType.AddProvider( new FieldProvider { Provider = provider, FieldType = new ApiObjectType(apiMutation.Name) }); typesCreated[inputType.ComplexTypeName] = inputType; foreach (var apiField in apiMutation.Arguments) { inputType.Fields.Add( apiField.Name, new MergedField( apiField.Name, CreateMergedType(provider, apiField, null, new List <string>(), true, typesCreated), provider, apiMutation, apiMutation.Flags, description: apiField.Description)); } inputType.Fields["clientMutationId"] = new MergedField( "clientMutationId", CreateScalarType(EnScalarType.String, typesCreated), provider, apiMutation); var arguments = new Dictionary <string, MergedField> { { "input", new MergedField( "input", inputType, provider, apiMutation) } }; return(new MergedField( apiMutation.Name, returnType, provider, apiMutation, apiMutation.Flags, arguments, apiMutation.Description)); }
/// <summary> /// Register the mutation /// </summary> /// <param name="provider">The mutation api provider</param> /// <param name="apiMutation">The mutation description</param> /// <param name="apiRoot">The api root</param> /// <param name="typesCreated">The list of created types</param> /// <returns>The mutation as merged field </returns> private static MergedField RegisterUntypedMutation( ApiProvider provider, ApiMutation apiMutation, MergedApiRoot apiRoot, Dictionary <string, MergedType> typesCreated) { var returnType = CreateMergedType(provider, apiMutation, null, new List <string>(), false, typesCreated); var inputType = new MergedInputType(apiMutation.Name); inputType.AddProvider( new FieldProvider { Provider = provider, FieldType = new ApiObjectType(apiMutation.Name) }); typesCreated[inputType.ComplexTypeName] = inputType; foreach (var apiField in apiMutation.Arguments) { inputType.Fields.Add( apiField.Name, new MergedField( apiField.Name, CreateMergedType(provider, apiField, null, new List <string>(), true, typesCreated), provider, apiMutation.Clone(), apiMutation.Flags, description: apiField.Description)); } inputType.Fields["clientMutationId"] = new MergedField( "clientMutationId", CreateScalarType(EnScalarType.String, typesCreated), provider, apiMutation); var arguments = new Dictionary <string, MergedField> { { "input", new MergedField( "input", inputType, provider, apiMutation) } }; var payload = new MergedUntypedMutationResult(returnType, apiRoot, provider, apiMutation); typesCreated[payload.ComplexTypeName] = payload; var untypedMutation = new MergedField( apiMutation.Name, payload, provider, apiMutation, apiMutation.Flags, arguments, apiMutation.Description); return(untypedMutation); }