├── .editorconfig
├── .gitattributes
├── .gitignore
├── GraphQL.nuspec
├── GraphQL.sln
├── LICENSE.md
├── README.md
├── appveyor.yml
├── lib
└── netstandard2.0
│ ├── GraphQL-Parser.dll
│ ├── GraphQL.dll
│ └── GraphQL.pdb
├── nuget.exe
├── package.json
├── src
├── CommonAssemblyInfo.cs
├── GraphQl.SchemaGenerator.Tests
│ ├── GraphQl.SchemaGenerator.Tests.csproj
│ ├── Helpers
│ │ └── AssertExtensions.cs
│ ├── Mocks
│ │ └── MockServiceProvider.cs
│ ├── Schemas
│ │ ├── AsyncSchema.cs
│ │ ├── DateSchema.cs
│ │ ├── DictionarySchema.cs
│ │ ├── DuplicateSchema.cs
│ │ ├── EchoSchema.cs
│ │ ├── EchoStateSchema.cs
│ │ ├── GenericsSchema.cs
│ │ ├── PerformanceSchema.cs
│ │ └── PrimitiveSchema.cs
│ ├── Tests
│ │ ├── AsyncSchemaTests.cs
│ │ ├── DateTests.cs
│ │ ├── ErrorTests.cs
│ │ ├── GenericQueryTests.cs
│ │ ├── MutationTests.cs
│ │ ├── PerformanceTests.cs
│ │ ├── QueryTests.cs
│ │ └── TypeHelperTests.cs
│ ├── app.config
│ └── packages.config
└── GraphQl.SchemaGenerator
│ ├── Attributes
│ ├── GraphKnownTypeAttribute.cs
│ ├── GraphNotRequiredAttribute.cs
│ ├── GraphRouteAttribute.cs
│ ├── GraphTypeAttribute.cs
│ └── NotNullAttribute.cs
│ ├── CHANGELOG.md
│ ├── DeepDictionaryRequest.cs
│ ├── DocumentOperations.cs
│ ├── Extensions
│ ├── AssignableExtensions.cs
│ ├── ResolveFieldContextExtensions.cs
│ └── TypeExtensions.cs
│ ├── GraphQl.SchemaGenerator.csproj
│ ├── GraphTypeConverter.cs
│ ├── GraphTypeResolver.cs
│ ├── Helpers
│ ├── StringHelper.cs
│ └── TypeHelper.cs
│ ├── IGraphTypeResolver.cs
│ ├── Models
│ ├── FieldDefinition.cs
│ ├── FieldInformation.cs
│ ├── GraphControllerDefinition.cs
│ ├── GraphRouteDefinition.cs
│ └── RequiredType.cs
│ ├── ObjectGraphTypeBuilder.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── README.md
│ ├── Schema
│ ├── GraphTypesLookup.cs
│ ├── IDomainSchemaTypeMapping.cs
│ ├── ISchemaFactory.cs
│ └── SchemaBuilder.cs
│ ├── SchemaGenerator.cs
│ ├── Types
│ ├── OriginalDateGraphType.cs
│ └── TimeSpanGraphType.cs
│ ├── Wrappers
│ ├── ByteArrayGraphType.cs
│ ├── EnumerationGraphTypeWrapper.cs
│ ├── IIGnore.cs
│ ├── InputObjectGraphTypeWrapper.cs
│ ├── InterfaceGraphTypeWrapper.cs
│ ├── KeyValuePairGraphType.cs
│ ├── KeyValuePairInputGraphType.cs
│ └── ObjectGraphTypeWrapper.cs
│ ├── app.config
│ └── packages.config
├── test-local.ps1
└── test.ps1
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | [*.{cs}]
12 | indent_size = 4
13 |
14 | [*.js]
15 | charset = utf-8
16 | indent_style = space
17 | indent_size = 2
18 |
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 |
3 | .vs/
4 | *.user
5 | *.suo
6 | *.nupkg
7 | npm-debug.log
8 | bundle.js
9 | fixie-results.xml
10 |
11 | TestResults/
12 | [Oo]bj/
13 | [Bb]in/
14 | packages/
15 | node_modules/
16 | nuget/lib
17 | /src/GraphQL/project.lock.json
18 | /src/GraphQL.Tests/project.lock.json
19 |
--------------------------------------------------------------------------------
/GraphQL.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Navitaire.DotRez.Core.GraphQL
5 | 0.2.0.2
6 | Derek Holmes
7 | https://github.com/holm0563
8 | https://raw.githubusercontent.com/holm0563/graphql-schemaGenerator/AsReference/LICENSE.md
9 | https://github.com/holm0563/graphql-schemaGenerator
10 | false
11 | Generate graph ql queries and schemas easily from dot net models.
12 |
13 | GraphQL json api
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/GraphQL.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.32112.339
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.SchemaGenerator", "src\GraphQl.SchemaGenerator\GraphQL.SchemaGenerator.csproj", "{0FF5301B-4CD7-409A-9D02-9390DE7BEBA3}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.SchemaGenerator.Tests", "src\GraphQl.SchemaGenerator.Tests\GraphQL.SchemaGenerator.Tests.csproj", "{4052E386-847B-4F3C-957C-0B957E319127}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {0FF5301B-4CD7-409A-9D02-9390DE7BEBA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {0FF5301B-4CD7-409A-9D02-9390DE7BEBA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {0FF5301B-4CD7-409A-9D02-9390DE7BEBA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {0FF5301B-4CD7-409A-9D02-9390DE7BEBA3}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {4052E386-847B-4F3C-957C-0B957E319127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {4052E386-847B-4F3C-957C-0B957E319127}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {4052E386-847B-4F3C-957C-0B957E319127}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {4052E386-847B-4F3C-957C-0B957E319127}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {CB2FBE11-C733-4101-81BB-A7C99B986004}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Navitaire, an Amadeus Company
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Schema Generator - GraphQL for .NET
2 |
3 | This uses [GraphQL for .NET](https://github.com/graphql-dotnet/graphql-dotnet) and wraps it to easily generate a GraphQL schema based on C# models. The schema generator will automatically create a schema from existing C# models. This includes every response model, request model, and composed class in these models. This can save a lot of time with an existing SDK or API project that is adding GraphQL support.
4 |
5 | ## Installation
6 |
7 | *Todo
8 |
9 | ## Configuration
10 |
11 | Define your routes with the GraphRoute attribute:
12 |
13 | ```csharp
14 | ///
15 | /// An example of the sdk that could be exposed. This is decorated with
16 | /// attributes to self generate a graph schema.
17 | ///
18 | public class StarWarsAttributeSchema
19 | {
20 | private readonly StarWarsData _data = new StarWarsData();
21 |
22 | ///
23 | /// Get the current hero.
24 | ///
25 | ///
26 | /// Example of graph ql attribute using the defaults.
27 | ///
28 | /// Droid.
29 | [GraphRoute]
30 | public Droid Hero()
31 | {
32 | var item = _data.GetDroidByIdAsync("3").Result;
33 |
34 | return item;
35 | }
36 | }
37 | ```
38 |
39 | ## Example Usage
40 |
41 | ```csharp
42 | IServiceProvider provider = new MockServiceProvider(); //Resolves your classes
43 | var schemaGenerator = new SchemaGenerator(provider);
44 | //See the readme.md in the schema generator project for more details on what this is doing.
45 | var schema = schemaGenerator.CreateSchema(typeof(StarWarsAttributeSchema));
46 |
47 | //Standard GraphQL execution
48 | var query = @"
49 | query HeroNameQuery {
50 | hero {
51 | name
52 | }
53 | }
54 | ";
55 | var exec = new DocumentExecuter(new AntlrDocumentBuilder(), new DocumentValidator());
56 | var result = exec.ExecuteAsync(schema, null, query, null).Result;
57 | ```
58 |
59 | ## Roadmap
60 |
61 | ### Supported Data Types
62 | - [x] Enums
63 | - [x] Dictionaries
64 | - [x] IEnumerable
65 | - [x] DateTime, DateTimeOffset
66 | - [x] Timespan
67 | - [x] Byte Array
68 | - [x] Key value pair
69 |
70 | ### Supported Conversions
71 | - [x] Mutations
72 | - [x] Queries
73 | - [ ] Interfaces
74 | - [x] Descriptions (via description attribute)
75 | - [ ] Descriptions (via summary text)
76 | - [x] Enumerations
77 | - [x] Input Objects
78 | - [x] Mutations
79 | - [ ] Unions
80 | - [ ] Async execution
81 | - [ ] Methods converting to inner queries
82 | - Void return types are not supported, doesn't make sense per the graph spec.
83 |
84 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 0.1.0.{build}
2 | environment:
3 | CI: true
4 | nuget:
5 | account_feed: true
6 | project_feed: true
7 | disable_publish_on_pr: true
8 | build_script:
9 | - cmd: >-
10 | npm install -g npm
11 |
12 | npm --version
13 |
14 | node --version
15 |
16 | npm run build-ci
17 |
--------------------------------------------------------------------------------
/lib/netstandard2.0/GraphQL-Parser.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holm0563/graphql-schemaGenerator/a04230e4dfd54deced4054041cb0ab29f526f48a/lib/netstandard2.0/GraphQL-Parser.dll
--------------------------------------------------------------------------------
/lib/netstandard2.0/GraphQL.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holm0563/graphql-schemaGenerator/a04230e4dfd54deced4054041cb0ab29f526f48a/lib/netstandard2.0/GraphQL.dll
--------------------------------------------------------------------------------
/lib/netstandard2.0/GraphQL.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holm0563/graphql-schemaGenerator/a04230e4dfd54deced4054041cb0ab29f526f48a/lib/netstandard2.0/GraphQL.pdb
--------------------------------------------------------------------------------
/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holm0563/graphql-schemaGenerator/a04230e4dfd54deced4054041cb0ab29f526f48a/nuget.exe
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql-dotnet",
3 | "version": "0.10.1",
4 | "description": "GraphQL for .NET",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack --progress",
8 | "test": "babel-node tools/build.js test",
9 | "build": "babel-node tools/build.js",
10 | "build-release": "set CONFIGURATION=Release&& babel-node tools/build.js",
11 | "build-ci": "set CONFIGURATION=Release&& npm install && babel-node tools/build.js ci",
12 | "build-nuget": "babel-node tools/build.js nuget",
13 | "build-artifacts": "babel-node tools/build.js artifacts",
14 | "release": "set CONFIGURATION=Release&& babel-node tools/build.js ci",
15 | "restore": "babel-node tools/build.js restore",
16 | "setVersion": "babel-node tools/build.js setVersion"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/holm0563/graphql-schemaGenerator.git"
21 | },
22 | "author": "Joe McBride",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/holm0563/graphql-schemaGenerator/issues"
26 | },
27 | "homepage": "https://github.com/holm0563/graphql-schemaGenerator",
28 | "dependencies": {
29 | "graphql": "^0.12.x"
30 | },
31 | "devDependencies": {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/CommonAssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | [assembly: AssemblyDescription("GraphQL for .NET")]
4 | [assembly: AssemblyTitle("GraphQL")]
5 | [assembly: AssemblyProduct("GraphQL")]
6 | [assembly: AssemblyCopyright("Copyright 2015-2016 Joseph T. McBride et al. All rights reserved.")]
7 | [assembly: AssemblyTrademark("")]
8 | [assembly: AssemblyVersion("0.9.3.0")]
9 | [assembly: AssemblyFileVersion("0.9.3.0")]
10 | [assembly: AssemblyInformationalVersion("0.9.3.0")]
11 | [assembly: CLSCompliant(false)]
12 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/GraphQl.SchemaGenerator.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 | GraphQl.SchemaGenerator.Tests
6 | GraphQl.SchemaGenerator.Tests
7 | Copyright © 2016
8 | true
9 |
10 |
11 |
12 | full
13 | CS0618
14 |
15 |
16 |
17 | pdbonly
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | ..\..\lib\netstandard2.0\GraphQL.dll
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Helpers/AssertExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using GraphQL.Execution;
4 | using GraphQL.Http;
5 | using GraphQL.Validation;
6 | using GraphQL.Validation.Complexity;
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Linq;
9 | using Xunit;
10 |
11 | namespace GraphQL.SchemaGenerator.Tests.Helpers
12 | {
13 | public static class GraphAssert
14 | {
15 | public static void QuerySuccess(GraphQL.Types.Schema schema, string query, string expected, string variables = null, bool compareBoth = true)
16 | {
17 | var exec = new DocumentExecuter(new GraphQLDocumentBuilder(), new DocumentValidator(), new ComplexityAnalyzer());
18 | var result = exec.ExecuteAsync(schema, null, query, null, variables?.ToInputs()).Result;
19 | var result2 = DocumentOperations.ExecuteOperationsAsync(schema, null, query, variables?.ToInputs()).Result;
20 |
21 | var writtenResult = JsonConvert.SerializeObject(result.Data);
22 | var writtenResult2 = JsonConvert.SerializeObject(result2.Data);
23 | var queryResult = CreateQueryResult(expected);
24 | var expectedResult = JsonConvert.SerializeObject(queryResult.Data);
25 |
26 | var errors = result.Errors?.FirstOrDefault();
27 | var errors2 = result2.Errors?.FirstOrDefault();
28 | //for easy debugging
29 | var allTypes = schema.AllTypes;
30 |
31 | Assert.Null(errors?.Message);
32 | Assert.Null(errors2?.Message);
33 | Assert.Equal(expectedResult, writtenResult);
34 | Assert.Equal(expectedResult, writtenResult2);
35 | }
36 |
37 | public static void QueryOperationsSuccess(GraphQL.Types.Schema schema, string query, string expected, string variables = null, bool compareBoth = true, IList blackListedOperations = null)
38 | {
39 | var result2 = DocumentOperations.ExecuteOperationsAsync(schema, null, query, variables?.ToInputs(), blackListedOperations: blackListedOperations).Result;
40 |
41 | var writtenResult2 = JsonConvert.SerializeObject(result2.Data);
42 | var queryResult = CreateQueryResult(expected);
43 | var expectedResult = JsonConvert.SerializeObject(queryResult.Data);
44 |
45 | var errors = result2.Errors?.FirstOrDefault();
46 | //for easy debugging
47 | var allTypes = schema.AllTypes;
48 |
49 | Assert.Null(errors?.Message);
50 | Assert.Equal(expectedResult, writtenResult2);
51 | }
52 |
53 | private static ExecutionResult CreateQueryResult(string result)
54 | {
55 | object expected = null;
56 | if (!string.IsNullOrWhiteSpace(result))
57 | {
58 | expected = JObject.Parse(result);
59 | }
60 |
61 | var eResult = new ExecutionResult { Data = expected };
62 |
63 | return eResult;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Mocks/MockServiceProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GraphQL.SchemaGenerator.Tests.Mocks
4 | {
5 | class MockServiceProvider : IServiceProvider
6 | {
7 | public object Data { get; set; }
8 |
9 | public MockServiceProvider()
10 | {
11 |
12 | }
13 |
14 | public MockServiceProvider(object data)
15 | {
16 | Data = data;
17 | }
18 |
19 | public object GetService(Type serviceType)
20 | {
21 | if (Data == null)
22 | {
23 | return Activator.CreateInstance(serviceType);
24 | }
25 |
26 | return Data;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/AsyncSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using GraphQL.SchemaGenerator.Attributes;
7 |
8 | namespace GraphQL.SchemaGenerator.Tests.Schemas
9 | {
10 | [GraphType]
11 | public class AsyncSchema
12 | {
13 | [Description(@"Tests a variety or request and response types.{VerifyComment}")]
14 | [GraphRoute]
15 | public Task TestRequest(Schema1Request request)
16 | {
17 | var schema = new EchoSchema();
18 | return Task.FromResult(schema.TestRequest(request));
19 | }
20 |
21 | [GraphRoute]
22 | public async Task TestEnumerableRequest(IEnumerable request)
23 | {
24 | var schema = new EchoSchema();
25 | return await Task.FromResult(schema.TestEnumerableRequest(request));
26 | }
27 |
28 |
29 | [GraphRoute]
30 | public async Task> TestEnumerable(Schema1Request request)
31 | {
32 | var schema = new EchoSchema();
33 | return await Task.FromResult(schema.TestEnumerable(request));
34 | }
35 |
36 | [GraphRoute]
37 | public async Task NotRecommendedToReturnATask()
38 | {
39 | await Task.Delay(1);
40 | }
41 |
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/DateSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Threading;
4 | using GraphQL.SchemaGenerator.Attributes;
5 |
6 | namespace GraphQL.SchemaGenerator.Tests.Schemas
7 | {
8 | [GraphType]
9 | public class DateSchema
10 | {
11 | [GraphRoute]
12 | public Dates Dates(Dates dates)
13 | {
14 | Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
15 | return dates;
16 | }
17 |
18 | }
19 |
20 | public class Dates
21 | {
22 | public DateTimeOffset? Offset { get; set; }
23 | public DateTime? DateTime { get; set; }
24 |
25 | public DateTime? DateUTC => DateTime.Value.ToUniversalTime();
26 |
27 | public DateTime? Y2k { get; } = new DateTime(2000, 1, 1);
28 |
29 | public DateTime? Y2kUtc { get; } = new DateTime(2000,1,1,0,0,0, DateTimeKind.Utc);
30 |
31 | public TimeSpan? TimeSpan { get; set; } = new TimeSpan(0,1,1,1);
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/DictionarySchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using GraphQL.SchemaGenerator.Attributes;
6 |
7 | namespace GraphQL.SchemaGenerator.Tests.Schemas
8 | {
9 | [GraphType]
10 | public class DictionarySchema
11 | {
12 | [GraphRoute]
13 | public IDictionary DictionaryRequest(DictionaryRequest request)
14 | {
15 | return request.Dictionary;
16 | }
17 | }
18 |
19 | public class DictionaryRequest
20 | {
21 | public IDictionary Dictionary { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/DuplicateSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using GraphQL.SchemaGenerator.Attributes;
5 |
6 | namespace GraphQL.SchemaGenerator.Tests.Schemas
7 | {
8 | [GraphType]
9 | public class DuplicateSchema
10 | {
11 | [Description(@"Tests error handling.")]
12 | [GraphRoute(name:"SameRoute")]
13 | public DuplicateResponse TestRequest()
14 | {
15 | return new DuplicateResponse
16 | {
17 | Value = 9
18 | };
19 | }
20 |
21 | [Description(@"Tests error handling.")]
22 | [GraphRoute(name: "SameRoute")]
23 | public DuplicateResponse TestRequest2()
24 | {
25 | return new DuplicateResponse
26 | {
27 | Value = 2
28 | };
29 | }
30 | }
31 |
32 | public class DuplicateResponse
33 | {
34 | public int Value { get; set; }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/EchoSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using GraphQL.SchemaGenerator.Attributes;
6 |
7 | namespace GraphQL.SchemaGenerator.Tests.Schemas
8 | {
9 | [GraphType]
10 | public class EchoSchema
11 | {
12 | [Description(@"Tests a variety or request and response types.{VerifyComment}")]
13 | [GraphRoute]
14 | public SchemaResponse TestRequest(Schema1Request request)
15 | {
16 | return new SchemaResponse
17 | {
18 | Value = request?.Echo ?? 5,
19 | StringValue = request?.Data,
20 | DecimalValue = request?.Decimal
21 | };
22 | }
23 |
24 | [GraphRoute]
25 | public SchemaResponse TestEnumerableRequest(IEnumerable request)
26 | {
27 | if (request == null)
28 | {
29 | return null;
30 | }
31 | return new SchemaResponse
32 | {
33 | Value = request.First().Echo ?? 5,
34 | StringValue = request.First().Data
35 | };
36 | }
37 |
38 |
39 | [GraphRoute]
40 | public IEnumerable TestEnumerable(Schema1Request request)
41 | {
42 | return new List
43 | {
44 | new SchemaResponse
45 | {
46 | Value = 1
47 | },
48 | new SchemaResponse
49 | {
50 | Value = request?.Echo ?? 5
51 | },
52 | };
53 | }
54 |
55 | [GraphRoute]
56 | public IResponse TestInterface()
57 | {
58 | return new SchemaResponse
59 | {
60 | Value = 8,
61 | Enum = Episode.JEDI
62 | };
63 | }
64 | }
65 |
66 | //todo: note sure why we had two types and what they are for.
67 | [GraphKnownType(typeof(SchemaResponse), typeof(SchemaResponse))]
68 | public interface IResponse
69 | {
70 | int Value { get; }
71 | }
72 |
73 | public class Schema1Request
74 | {
75 | public int? Echo { get; set; }
76 | public string Data { get; set; }
77 |
78 | public decimal? Decimal { get; set; }
79 |
80 | public DateTimeOffset? Offset { get; set; }
81 |
82 | public IEnumerable ComplexRequests { get; set; }
83 |
84 | public InnerRequest InnerRequest { get; set; }
85 | }
86 |
87 | public class InnerRequest
88 | {
89 | public string InnerData { get; set; }
90 | }
91 |
92 | public class SchemaResponse : IResponse
93 | {
94 | public Episode Enum { get; set; } = Episode.NEWHOPE;
95 |
96 | public int Value { get; set; }
97 |
98 | public int? NullValue { get; } = null;
99 |
100 | public decimal? DecimalValue { get; set; }
101 |
102 | public DateTimeOffset? Date { get; set; } = new DateTime(1999,1,1);
103 |
104 | public TimeSpan TimeSpan { get; set; }
105 |
106 | public byte[] ByteArray { get; set; }
107 |
108 | public string StringValue { get; set; }
109 |
110 | public IDictionary> NestDictionary { get; set; }
111 |
112 | public IDictionary Values { get; set; } = new Dictionary
113 | {
114 | {"99", new Response2 {ComplicatedResponse = new Schema1Request {Data = "99", Echo = 99} } },
115 | {"59", new Response2 {ComplicatedResponse = new Schema1Request {Data = "59", Echo = 59} } },
116 | {"null", null}
117 | };
118 | }
119 |
120 | public class Response2
121 | {
122 | public Schema1Request ComplicatedResponse { get; set; }
123 | }
124 |
125 | public enum Episode
126 | {
127 | NEWHOPE,
128 | JEDI
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/EchoStateSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.ComponentModel.DataAnnotations;
5 | using GraphQL.SchemaGenerator.Attributes;
6 | using GraphQL.SchemaGenerator.Models;
7 |
8 | namespace GraphQL.SchemaGenerator.Tests.Schemas
9 | {
10 | [GraphType]
11 | public class EchoStateSchema
12 | {
13 | private static StateResponse State { get; } = new StateResponse();
14 |
15 | [Description(@"Sets the data.")]
16 | [GraphRoute(isMutation:true)]
17 | public StateResponse SetData(int request)
18 | {
19 | State.Data = request;
20 |
21 | return GetState();
22 | }
23 |
24 | [Description(@"Sets both the data and state.")]
25 | [GraphRoute(isMutation: true)]
26 | public StateResponse Set(SetRequest request)
27 | {
28 | State.Data = request.Data;
29 | State.State = request.State ?? ValidStates.Open;
30 | State.Decimal = request.Decimal;
31 |
32 | return GetState();
33 | }
34 |
35 | [GraphRoute(isMutation: true)]
36 | public StateResponse SetAdvanced(SetRequestAdvanced request)
37 | {
38 | State.Data = request.Data + request.NonRequiredInt;
39 | State.State = request.State ?? ValidStates.Open;
40 | State.Decimal = request.Decimal;
41 |
42 | if (request.NonRequiredBool)
43 | {
44 | State.State = ValidStates.Closed;
45 | }
46 |
47 | return GetState();
48 | }
49 |
50 | [GraphRoute(isMutation: true)]
51 | public SetRequestAdvancedString SetAdvancedString(SetRequestAdvancedString request)
52 | {
53 | return request;
54 | }
55 |
56 | [Description(@"Sets the state.")]
57 | [GraphRoute(isMutation: true)]
58 | public StateResponse SetState(ValidStates request)
59 | {
60 | State.State = request;
61 |
62 | return GetState();
63 | }
64 |
65 | [Description(@"Reads the state.")]
66 | [GraphRoute] //since it returns a value, query will be assumed
67 | public StateResponse GetState()
68 | {
69 | return State;
70 | }
71 | }
72 |
73 | public enum ValidStates
74 | {
75 | Open = 1,
76 | Closed = 0
77 | };
78 |
79 | public class StateResponse
80 | {
81 | public ValidStates State { get; set; }
82 | public decimal? Decimal { get; set; }
83 | public int Data { get; set; }
84 | }
85 |
86 | public class SetRequest
87 | {
88 | public ValidStates? State { get; set; }
89 |
90 | public decimal? Decimal { get; set; }
91 |
92 | [Required]
93 | public int Data { get; set; }
94 | }
95 |
96 | public class SetRequestAdvanced: SetRequest
97 | {
98 | [GraphNotRequired]
99 | public bool NonRequiredBool { get; set; }
100 | [GraphNotRequired]
101 | public int NonRequiredInt { get; set; }
102 | //defaults to not required unless [GraphNotRequired(required)] is set.
103 | [Required]
104 | public DateTime? NullRequiredDateTime { get; set; }
105 | public string NotRequiredString{ get; set; }
106 | }
107 |
108 | public class SetRequestAdvancedString
109 | {
110 | [GraphNotRequired]
111 | public bool NonRequiredBool { get; set; }
112 | //defaults to required (strings can be null)
113 | [Required]
114 | public string RequiredString { get; set; }
115 | //defaults to not required unless [GraphNotRequired(required)] is set.
116 | [Required]
117 | public DateTime? NullRequiredDateTime { get; set; }
118 | //default to not required
119 | public string NotRequiredString { get; set; }
120 | //defaults to not required unless [GraphNotRequired(required)] is set.
121 | [Required]
122 | public IList RequiredObjects{get;set;}
123 | public SetRequest NonRequiredObject { get; set; }
124 | [Required]
125 | public SetRequest RequiredObject { get; set; }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/GenericsSchema.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using GraphQL.SchemaGenerator.Attributes;
4 |
5 | namespace GraphQL.SchemaGenerator.Tests.Schemas
6 | {
7 | public class GenericsSchema
8 | {
9 | [Description(@"Tests a multiple types")]
10 | [GraphRoute]
11 | public EchoGeneric EchoGenerics(EchoGeneric int1, EchoGeneric int2,
12 | EchoGeneric string1)
13 | {
14 | return new EchoGeneric
15 | {
16 | data = $"{int1?.data}{int2?.data}{string1?.data}"
17 | };
18 | }
19 |
20 | [Description(@"Tests int types")]
21 | [GraphRoute]
22 | public EchoGenericList EchoClassGenerics()
23 | {
24 | return new EchoGenericList(new List
25 | {
26 | new Inner
27 | {
28 | InnerInt = 1,
29 | InnerString = "Hi"
30 | }
31 | }
32 | );
33 | }
34 |
35 | [Description(@"Tests int types")]
36 | [GraphRoute]
37 | public EchoGenericList EchoClassGenerics2()
38 | {
39 | return new EchoGenericList(new List
40 | {
41 | new Inner2
42 | {
43 | Inner2Int = 2,
44 | Inner2String = "Bye"
45 | }
46 | }
47 | );
48 | }
49 | }
50 |
51 | public class EchoGeneric
52 | {
53 | public T data { get; set; }
54 | }
55 |
56 | public class EchoGenericList : EchoGeneric where T : class
57 | {
58 | public EchoGenericList(IEnumerable values)
59 | {
60 | list = values;
61 | }
62 |
63 | public IEnumerable list { get; }
64 | }
65 |
66 | public class Inner
67 | {
68 | public string InnerString { get; set; }
69 | public int InnerInt { get; set; }
70 | }
71 |
72 | public class Inner2
73 | {
74 | public string Inner2String { get; set; }
75 | public int Inner2Int { get; set; }
76 | }
77 | }
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/PerformanceSchema.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using GraphQL.SchemaGenerator.Attributes;
5 |
6 | namespace GraphQL.SchemaGenerator.Tests.Schemas
7 | {
8 | [GraphType]
9 | public class PerformanceSchema
10 | {
11 | private readonly List largeList;
12 |
13 | public PerformanceSchema()
14 | {
15 | largeList = new List();
16 |
17 | for (var x = 0; x < 10000; x++)
18 | largeList.Add(new SchemaResponse
19 | {
20 | Date = DateTimeOffset.Now
21 | });
22 | }
23 |
24 | [GraphRoute]
25 | public List TestList()
26 | {
27 | return largeList;
28 | }
29 |
30 | [GraphRoute]
31 | public List SlowCall()
32 | {
33 | Thread.Sleep(1000);
34 | return new List();
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Schemas/PrimitiveSchema.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using GraphQL.SchemaGenerator.Attributes;
3 |
4 | namespace GraphQL.SchemaGenerator.Tests.Schemas
5 | {
6 | [GraphType]
7 | public class PrimitiveSchema
8 | {
9 | [Description(@"Tests a null response mutation")]
10 | [GraphRoute(IsMutation = true)]
11 | public void TestRequest(bool clear)
12 | {
13 |
14 | }
15 |
16 | [Description(@"Tests a string response mutation")]
17 | [GraphRoute]
18 | public string TestString()
19 | {
20 | return "Hi";
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/AsyncSchemaTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using GraphQL.Execution;
5 | using GraphQL.Http;
6 | using GraphQL.SchemaGenerator.Tests.Helpers;
7 | using GraphQL.SchemaGenerator.Tests.Mocks;
8 | using GraphQL.SchemaGenerator.Tests.Schemas;
9 | using GraphQL.Validation;
10 | using GraphQL.Validation.Complexity;
11 | using Xunit;
12 |
13 | namespace GraphQL.SchemaGenerator.Tests.Tests
14 | {
15 | public class AsyncSchemaTests
16 | {
17 | [Fact]
18 | public void CreateSchema_WithClassArgument_HasExpectedSchema()
19 | {
20 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
21 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
22 |
23 | var sut = schema.AllTypes;
24 | Assert.True(sut.Any(t=>t.Name == "Input_Schema1Request"));
25 | }
26 |
27 | [Fact]
28 | public void BasicParameterExample_Works()
29 | {
30 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
31 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
32 |
33 | var query = @"{
34 | testRequest {value}
35 | }";
36 |
37 | var expected = @"{
38 | testRequest: {value:5}
39 | }";
40 |
41 | GraphAssert.QuerySuccess(schema, query, expected);
42 | }
43 |
44 | [Fact]
45 | public void WithParameterExample_Works()
46 | {
47 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
48 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
49 |
50 | var query = @"{
51 | testRequest(request:{echo:1}) {value}
52 | }";
53 |
54 | var expected = @"{
55 | testRequest: {value:1}
56 | }";
57 |
58 | GraphAssert.QuerySuccess(schema, query, expected);
59 | }
60 |
61 | [Fact]
62 | public void WithEnumerableParameterExample_Works()
63 | {
64 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
65 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
66 |
67 | var query = @"{
68 | testEnumerableRequest(request:[{echo:1}]) {value}
69 | }";
70 |
71 | var expected = @"{
72 | testEnumerableRequest: {value:1}
73 | }";
74 |
75 | GraphAssert.QuerySuccess(schema, query, expected);
76 | }
77 |
78 | [Fact]
79 | public void WithStringParameterExample_Works()
80 | {
81 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
82 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
83 |
84 | var query = @"{
85 | testRequest(request:{data:""yes""}) {stringValue}
86 | }";
87 |
88 | var expected = @"{
89 | testRequest: {stringValue:""yes""}
90 | }";
91 |
92 | GraphAssert.QuerySuccess(schema, query, expected);
93 | }
94 |
95 | [Fact]
96 | public void WithStringEscapedParameterExample_Works()
97 | {
98 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
99 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
100 |
101 | //data = y\es m"am
102 | var query = @"{
103 | testRequest(request:{data:""y\\es m\""am""}) {stringValue}
104 | }";
105 |
106 | var expected = @"{
107 | testRequest: {stringValue:""y\\es m\""am""}
108 | }";
109 |
110 | GraphAssert.QuerySuccess(schema, query, expected);
111 | }
112 |
113 | [Fact]
114 | public void WithComplexParameters_Works()
115 | {
116 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
117 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
118 |
119 | var query = @"{
120 | testRequest(request:{
121 | complexRequests:[{
122 | innerData:""345""
123 | }]
124 | }) {value}
125 | }";
126 |
127 | var expected = @"{
128 | testRequest: {value:5}
129 | }";
130 |
131 | GraphAssert.QuerySuccess(schema, query, expected);
132 | }
133 |
134 | [Fact]
135 | public void WithComplexParameters_HaveCorrectType()
136 | {
137 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
138 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
139 |
140 | var query = @"{
141 | __type(name : ""Input_InnerRequest"") {
142 | name
143 | kind
144 | }}";
145 |
146 | var expected = @"{
147 | __type: {
148 | name: ""Input_InnerRequest"",
149 | kind: ""INPUT_OBJECT""
150 | }
151 | }";
152 |
153 | GraphAssert.QuerySuccess(schema, query, expected);
154 | }
155 |
156 | [Fact]
157 | public void WithEnumerableExample_Works()
158 | {
159 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
160 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
161 |
162 | var query = @"{
163 | testEnumerable{value}
164 | }";
165 |
166 | var expected = @"{
167 | testEnumerable: [{value: 1},{value: 5}]
168 | }";
169 |
170 | GraphAssert.QuerySuccess(schema, query, expected);
171 | }
172 |
173 | [Fact]
174 | public void WithEnum_Works()
175 | {
176 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
177 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
178 |
179 | var query = @"{
180 | testRequest {enum}
181 | }";
182 |
183 | var expected = @"{
184 | testRequest: {enum:""NEWHOPE""}
185 | }";
186 |
187 | GraphAssert.QuerySuccess(schema, query, expected);
188 | }
189 |
190 | [Fact]
191 | public void WithDateTimeOffset_Works()
192 | {
193 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
194 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
195 |
196 | var query = @"{
197 | testRequest {date}
198 | }";
199 |
200 | var expected = @"{
201 | testRequest: {date:""1999-01-01T00:00:00-07:00""}
202 | }";
203 |
204 | GraphAssert.QuerySuccess(schema, query, expected);
205 | }
206 |
207 | [Fact]
208 | public void FieldDescription_Works()
209 | {
210 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
211 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
212 |
213 | var query = @"{
214 | __schema{
215 | types{
216 | name,
217 | fields {
218 | name
219 | description
220 | }
221 | }
222 | }
223 | }";
224 |
225 | var exec = new DocumentExecuter(new GraphQLDocumentBuilder(), new DocumentValidator(), new ComplexityAnalyzer());
226 | var result = exec.ExecuteAsync(schema, null, query, null).Result;
227 |
228 | var writer = new DocumentWriter(indent: true);
229 | var writtenResult = writer.Write(result.Data);
230 |
231 | var errors = result.Errors?.FirstOrDefault();
232 |
233 | Assert.Null(errors?.Message);
234 | Assert.True(writtenResult.Contains("{VerifyComment}"));
235 | Assert.False(writtenResult.Contains("\"Task\""));
236 | Assert.False(writtenResult.Contains("\"MethodBase\""));
237 | }
238 |
239 | [Fact]
240 | public void WithNull_Works()
241 | {
242 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
243 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
244 |
245 | var query = @"{
246 | testRequest {nullValue}
247 | }";
248 |
249 | var expected = @"{
250 | testRequest: {nullValue:null}
251 | }";
252 |
253 | GraphAssert.QuerySuccess(schema, query, expected);
254 | }
255 |
256 | [Fact]
257 | public void WithTask_Works()
258 | {
259 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
260 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
261 |
262 | var query = @"{
263 | notRecommendedToReturnATask
264 | }";
265 |
266 | var expected = @"{
267 | notRecommendedToReturnATask:{}
268 | }";
269 |
270 | GraphAssert.QuerySuccess(schema, query, expected);
271 | }
272 |
273 |
274 | [Fact]
275 | public void WithTaskReturnType_HidesTask()
276 | {
277 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
278 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
279 |
280 | var query = @"{
281 | testRequest {nullValue}
282 | }";
283 |
284 | var expected = @"{
285 | testRequest: {nullValue:null}
286 | }";
287 |
288 | GraphAssert.QuerySuccess(schema, query, expected);
289 | }
290 |
291 | [Fact]
292 | public void WithDictionary_Works()
293 | {
294 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
295 | var schema = schemaGenerator.CreateSchema(typeof(AsyncSchema));
296 |
297 | var query = @"{
298 | testRequest {
299 | values{
300 | key
301 | value{
302 | complicatedResponse{
303 | echo
304 | }
305 | }
306 | }
307 | }
308 | }";
309 |
310 | var expected = @"{
311 | testRequest: {
312 | values: [
313 | {
314 | key: ""99"",
315 | value: {
316 | complicatedResponse: {
317 | echo: 99
318 | }
319 | }
320 | },
321 | {
322 | key: ""59"",
323 | value: {
324 | complicatedResponse: {
325 | echo: 59
326 | }
327 | }
328 | },
329 | {
330 | key: ""null"",
331 | value: null
332 | }
333 | ]
334 | }
335 | }";
336 |
337 | GraphAssert.QuerySuccess(schema, query, expected);
338 | }
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/DateTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GraphQL.SchemaGenerator.Tests.Helpers;
3 | using GraphQL.SchemaGenerator.Tests.Mocks;
4 | using GraphQL.SchemaGenerator.Tests.Schemas;
5 | using Xunit;
6 |
7 | namespace GraphQL.SchemaGenerator.Tests.Tests
8 | {
9 | public class DateTests
10 | {
11 |
12 | [Fact]
13 | public void GetTimeSpan_IsSafe()
14 | {
15 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
16 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
17 |
18 | var query = @"
19 | {dates(dates:{timeSpan:""1.23:59:59""}) {
20 | timeSpan
21 | }}
22 | ";
23 |
24 | var expected = @"{
25 | dates: {
26 | timeSpan:""1.23:59:59""
27 | }
28 | }";
29 |
30 | GraphAssert.QuerySuccess(schema, query, expected);
31 | }
32 |
33 | [Fact]
34 | public void GetTimeSpanAsVariable_IsSafe()
35 | {
36 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
37 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
38 |
39 | var query = @"
40 | query($ts:TimeSpan!)
41 | {
42 | dates(dates:{timeSpan:$ts}) {
43 | timeSpan
44 | }
45 | }
46 | ";
47 |
48 | var variables = @"{
49 | ts:""1.23:59:59""
50 | }";
51 |
52 | var expected = @"{
53 | dates: {
54 | timeSpan:""1.23:59:59""
55 | }
56 | }";
57 |
58 | GraphAssert.QuerySuccess(schema, query, expected, variables);
59 | }
60 |
61 |
62 | [Fact]
63 | public void GetOffset_IsSafe()
64 | {
65 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
66 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
67 |
68 | var query = @"
69 | {dates(dates:{offset:""2013-07-02T09:00:00"", dateTime:""2013-07-02T09:00""}) {
70 | offset
71 | dateTime
72 | }}
73 | ";
74 |
75 | var expected = @"{
76 | dates: {
77 | offset:""2013-07-02T09:00:00-06:00"",
78 | dateTime:""2013-07-02T09:00:00""
79 | }
80 | }";
81 |
82 | GraphAssert.QuerySuccess(schema, query, expected);
83 | }
84 |
85 | [Fact]
86 | public void GetUtcDates_IsSafe()
87 | {
88 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
89 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
90 |
91 | var query = @"
92 | {dates(dates:{offset:""2013-07-02T09:00:00Z"", dateTime:""2013-07-02T09:00Z""}) {
93 | y2k
94 | y2kUtc
95 | }}
96 | ";
97 |
98 | var expected = @"{
99 | dates: {
100 | y2k:""2000-01-01T00:00:00"",
101 | y2kUtc:""2000-01-01T00:00:00Z""
102 | }
103 | }";
104 |
105 | GraphAssert.QuerySuccess(schema, query, expected);
106 | }
107 |
108 | [Fact]
109 | public void GetZuluOffset_IsSafe()
110 | {
111 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
112 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
113 |
114 | var query = @"
115 | {dates(dates:{offset:""2013-07-02T09:00:00Z"", dateTime:""2013-07-02T09:00Z""}) {
116 | offset
117 | dateTime
118 | dateUTC
119 | }}
120 | ";
121 |
122 | var expected = @"{
123 | dates: {
124 | offset:""2013-07-02T03:00:00-06:00"",
125 | dateTime:""2013-07-02T09:00:00Z"",
126 | dateUTC:""2013-07-02T09:00:00Z""
127 | }
128 | }";
129 |
130 | GraphAssert.QuerySuccess(schema, query, expected);
131 | }
132 |
133 | [Fact]
134 | public void GetTimeZoneOffset_IsSafe()
135 | {
136 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
137 | var schema = schemaGenerator.CreateSchema(typeof(DateSchema));
138 |
139 | var query = @"
140 | {dates(dates:{offset:""2013-07-02T09:00:00-06:00"", dateTime:""2013-07-02T09:00-06:00""}) {
141 | offset
142 | dateTime
143 | dateUTC
144 | }}
145 | ";
146 |
147 | var expected = @"{
148 | dates: {
149 | offset:""2013-07-02T09:00:00-06:00"",
150 | dateTime:""2013-07-02T09:00:00-06:00"",
151 | dateUTC:""2013-07-02T15:00:00Z""
152 | }
153 | }";
154 |
155 | GraphAssert.QuerySuccess(schema, query, expected);
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/ErrorTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using GraphQL.SchemaGenerator.Tests.Mocks;
4 | using GraphQL.SchemaGenerator.Tests.Schemas;
5 | using Xunit;
6 |
7 | namespace GraphQL.SchemaGenerator.Tests.Tests
8 | {
9 | public class ErrorTests
10 | {
11 | [Fact]
12 | public void Duplicate_Name_Throws()
13 | {
14 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
15 | Exception e = null;
16 | try
17 | {
18 | schemaGenerator.CreateSchema(typeof(DuplicateSchema));
19 | }
20 | catch (Exception er)
21 | {
22 | e = er;
23 | }
24 |
25 | //this should pass whenever the change is pushed.
26 | Assert.NotNull(e);
27 | Assert.Contains("SameRoute", e.Message);
28 | }
29 |
30 | [Fact]
31 | public async void OperationLimit_WhenExceeded_Throws()
32 | {
33 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
34 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
35 |
36 | var query = @"{
37 | testRequest {value}
38 | t2:testRequest {value}
39 | }";
40 |
41 | await Assert.ThrowsAsync(() =>
42 | DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 1));
43 | }
44 |
45 | [Fact]
46 | public async void OperationLimit_WhenExceededWithNodes_Throws()
47 | {
48 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
49 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
50 |
51 | var query = @"query{
52 | t2:testRequest {value, value, value}
53 | }
54 | query{t1:testRequest{value}}
55 | ";
56 |
57 | await Assert.ThrowsAsync(() =>
58 | DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 1));
59 | }
60 |
61 | [Fact]
62 | public async void OperationLimit_WhenExceededWithMutations_Throws()
63 | {
64 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
65 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
66 |
67 | var query = @"
68 | mutation SetState{
69 | setState (request:Open){
70 | state
71 | }
72 | }
73 | query GetState{
74 | getState{
75 | state
76 | }
77 | }
78 | ";
79 |
80 | await Assert.ThrowsAsync(() =>
81 | DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 1));
82 | }
83 |
84 | [Fact]
85 | public async void OperationLimit_WhenNotExceeded_Runs()
86 | {
87 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
88 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
89 |
90 | var query = @"{
91 | testRequest {value}
92 | t2:testRequest {value}
93 | }";
94 |
95 | await DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 2);
96 | }
97 |
98 | [Fact]
99 | public async void OperationLimit_WhenNotExceededWithNodes_Runs()
100 | {
101 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
102 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
103 |
104 | var query = @"query{
105 | t2:testRequest {value, value, value}
106 | }
107 | query{t1:testRequest{value}}
108 | ";
109 |
110 | await DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 2);
111 | }
112 |
113 | [Fact]
114 | public async void OperationLimit_WhenNotExceededWithMutations_Runs()
115 | {
116 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
117 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
118 |
119 | var query = @"
120 | mutation SetState{
121 | setState (request:Open){
122 | state
123 | }
124 | }
125 | query GetState{
126 | getState{
127 | state
128 | }
129 | }
130 | ";
131 |
132 | await DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 2);
133 | }
134 |
135 | [Fact]
136 | public async void OperationLimit_WhenNotExceededWithParameters_Runs()
137 | {
138 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
139 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
140 |
141 | var query = @"
142 | mutation SetState($begin: Date!, $end: Date!, $test: String, $test2: String){
143 | setState (request:Open){
144 | state
145 | }
146 | }
147 | query GetState($begin: Date!, $end: Date!, $test: String, $test2: String){
148 | getState{
149 | state
150 | }
151 | state2:getState{
152 | state
153 | }
154 | }
155 | ";
156 |
157 | await DocumentOperations.ExecuteOperationsAsync(schema, null, query, maxOperationNodes: 3);
158 | }
159 |
160 |
161 | [Fact]
162 | public async void Blacklist_WithQueryAndMutation_Fails()
163 | {
164 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
165 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
166 |
167 | var query = @"
168 | mutation SetState{
169 | outer:setState (request:Open){
170 | state
171 | }
172 | }
173 | query GetState{
174 | getState{
175 | state
176 | }
177 | }
178 | ";
179 |
180 | var blackList = new List
181 | {
182 | "setState"
183 | };
184 |
185 | await Assert.ThrowsAsync(() =>
186 | DocumentOperations.ExecuteOperationsAsync(schema, null, query, blackListedOperations:blackList));
187 | }
188 |
189 | [Theory]
190 | [InlineData("")]
191 | [InlineData(null)]
192 | [InlineData("SetState")]
193 | [InlineData("GetState")]
194 | [InlineData("setStatev2")]
195 | [InlineData("inner")]
196 | [InlineData("outer")]
197 | public async void Blacklist_WithQueryAndMutation_Works(string testOp)
198 | {
199 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
200 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
201 |
202 | var query = @"
203 | mutation SetState{
204 | outer:setState (request:Open){
205 | inner:state
206 | }
207 | }
208 | query GetState{
209 | getState{
210 | state
211 | }
212 | }
213 | ";
214 |
215 | var blackList = new List
216 | {
217 | testOp
218 | };
219 |
220 |
221 | await DocumentOperations.ExecuteOperationsAsync(schema, null, query, blackListedOperations: blackList);
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/GenericQueryTests.cs:
--------------------------------------------------------------------------------
1 | using GraphQL.SchemaGenerator.Tests.Helpers;
2 | using GraphQL.SchemaGenerator.Tests.Mocks;
3 | using GraphQL.SchemaGenerator.Tests.Schemas;
4 | using Xunit;
5 |
6 | namespace GraphQL.SchemaGenerator.Tests.Tests
7 | {
8 | public class GenericQueryTests
9 | {
10 | [Fact]
11 | public void BasicExample_Works()
12 | {
13 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
14 | var schema = schemaGenerator.CreateSchema(typeof(GenericsSchema));
15 |
16 | var query = @"
17 | {
18 | echoGenerics{data}
19 | }
20 | ";
21 |
22 | var expected = @"{
23 | echoGenerics: {
24 | data: """"
25 | }
26 | }";
27 |
28 | GraphAssert.QuerySuccess(schema, query, expected);
29 | }
30 |
31 | [Fact]
32 | public void BasicInputExample_Works()
33 | {
34 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
35 | var schema = schemaGenerator.CreateSchema(typeof(GenericsSchema));
36 |
37 | var query = @"
38 | {
39 | echoGenerics(
40 | int1:{data:2}
41 | string1:{data:""test""},
42 | )
43 | {data}
44 | }
45 | ";
46 |
47 | var expected = @"{
48 | echoGenerics: {
49 | data: ""2test""
50 | }
51 | }";
52 |
53 | GraphAssert.QuerySuccess(schema, query, expected);
54 | }
55 |
56 | [Fact]
57 | public void BasicClassInputExample_Works()
58 | {
59 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
60 | var schema = schemaGenerator.CreateSchema(typeof(GenericsSchema));
61 |
62 | var query = @"
63 | {
64 | echoClassGenerics{
65 | list{innerInt}
66 | }
67 | echoClassGenerics2{
68 | list{inner2Int}
69 | }
70 | }
71 | ";
72 |
73 | var expected = @"{
74 | echoClassGenerics: {
75 | list: [{innerInt:1}]
76 | },
77 | echoClassGenerics2: {
78 | list: [{inner2Int:2}]
79 | }
80 | }";
81 |
82 | GraphAssert.QuerySuccess(schema, query, expected);
83 | }
84 |
85 | [Fact]
86 | public void Schema_HasUniqueTypes()
87 | {
88 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
89 | var schema = schemaGenerator.CreateSchema(typeof(GenericsSchema));
90 |
91 | var query = @"
92 | {
93 | __schema{
94 | queryType {
95 | name,
96 | fields{
97 | name
98 | type{
99 | name
100 | kind
101 | }
102 | }
103 | }
104 | }
105 | }
106 | ";
107 |
108 | var expected = @"{
109 | __schema: {
110 | queryType: {
111 | name: ""RootQueries"",
112 | fields: [
113 | {
114 | name: ""echoGenerics"",
115 | type: {
116 | name: ""EchoGeneric__String"",
117 | kind: ""OBJECT""
118 | }
119 | },
120 | {
121 | name: ""echoClassGenerics"",
122 | type: {
123 | name: ""EchoGenericList__Inner"",
124 | kind: ""OBJECT""
125 | }
126 | },
127 | {
128 | name: ""echoClassGenerics2"",
129 | type: {
130 | name: ""EchoGenericList__Inner2"",
131 | kind: ""OBJECT""
132 | }
133 | }
134 | ]
135 | }
136 | }
137 | }";
138 |
139 | GraphAssert.QuerySuccess(schema, query, expected);
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/MutationTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using GraphQL.SchemaGenerator.Tests.Helpers;
4 | using GraphQL.SchemaGenerator.Tests.Mocks;
5 | using GraphQL.SchemaGenerator.Tests.Schemas;
6 | using Xunit;
7 |
8 | namespace GraphQL.SchemaGenerator.Tests.Tests
9 | {
10 | public class MutationTests
11 | {
12 | [Fact]
13 | public void BasicExample_Works()
14 | {
15 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
16 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
17 |
18 | var query = @"
19 | mutation SetData{
20 | setData (request:4){
21 | data
22 | }
23 | }
24 | ";
25 |
26 | var expected = @"{
27 | setData: {
28 | data: 4
29 | }
30 | }";
31 |
32 | GraphAssert.QuerySuccess(schema, query, expected);
33 | }
34 |
35 | [Fact]
36 | public void BasicExample_WithEnums_Works()
37 | {
38 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
39 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
40 |
41 | var query = @"
42 | mutation SetState{
43 | setState (request:Open){
44 | state
45 | }
46 | }
47 | ";
48 |
49 | var expected = @"{
50 | setState: {
51 | state: ""Open""
52 | }
53 | }";
54 |
55 | GraphAssert.QuerySuccess(schema, query, expected);
56 | }
57 |
58 |
59 | [Fact]
60 | public void BasicExample_WithQueryAndMutation_Works()
61 | {
62 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
63 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
64 |
65 | var query = @"
66 | mutation SetState{
67 | setState (request:Open){
68 | state
69 | }
70 | }
71 | query GetState{
72 | getState{
73 | state
74 | }
75 | }
76 | ";
77 |
78 | var expected = @"{
79 | SetState:{setState: {
80 | state: ""Open""
81 | }},
82 | GetState:{getState: {
83 | state: ""Open""
84 | }
85 | }}";
86 |
87 | GraphAssert.QueryOperationsSuccess(schema, query, expected);
88 | }
89 |
90 | [Fact]
91 | public void BasicExample_WithDecimal_Works()
92 | {
93 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
94 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
95 |
96 | var query = @"
97 | mutation SetState{
98 | set(request:{decimal:24.15, data:2}){
99 | decimal
100 | }
101 | }
102 | ";
103 |
104 | var expected = @"{
105 | set: {
106 | decimal: 24.15
107 | }
108 | }";
109 |
110 | GraphAssert.QuerySuccess(schema, query, expected);
111 | }
112 |
113 | [Fact]
114 | public async void BasicExample_WithoutInt_Fails()
115 | {
116 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
117 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
118 |
119 | var query = @"
120 | mutation SetState{
121 | set(request:{decimal:24.15}){
122 | decimal
123 | }
124 | }
125 | ";
126 |
127 | var result = await DocumentOperations.ExecuteOperationsAsync(schema, null, query);
128 | Assert.NotEmpty(result.Errors);
129 | }
130 |
131 | [Fact]
132 | public void SetAdvanced_WithSameQuery_WorksBackwardsCompatible()
133 | {
134 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
135 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
136 |
137 | var query = @"
138 | mutation SetState{
139 | set:setAdvanced(request:{decimal:24.15, data:2}){
140 | data
141 | state
142 | }
143 | }
144 | ";
145 |
146 | var expected = @"{
147 | set: {
148 | data: 2,
149 | state: ""Open""
150 | }
151 | }";
152 |
153 | GraphAssert.QuerySuccess(schema, query, expected);
154 | }
155 |
156 | [Fact]
157 | public void SetAdvanced_WithNullableParam_Works()
158 | {
159 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
160 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
161 |
162 | var query = @"
163 | mutation SetState($dec:Decimal!, $int:Int!, $int2:Int!, $date1:Date!, $str:String){
164 | set:setAdvanced(request:{decimal:$dec, data:$int, nonRequiredInt:$int2, nullRequiredDateTime:$date1, notRequiredString:$str}){
165 | decimal
166 | data
167 | state
168 | }
169 | }
170 | ";
171 |
172 | var expected = @"{
173 | set: {
174 | decimal:24.15,
175 | data: 3,
176 | state: ""Open""
177 | }
178 | }";
179 |
180 | GraphAssert.QuerySuccess(schema, query, expected, "{dec:24.15, int:2, int2:1, date1:\"1-1-2011\"}");
181 | }
182 |
183 | [Theory]
184 | [InlineData("String!","String!")]
185 | [InlineData("String","String!")]
186 | [InlineData("String!","String")]
187 | [InlineData("String", "String")]
188 | public void SetAdvancedString_WithStringParam_Works(string var1, string var2)
189 | {
190 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
191 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
192 |
193 | var query = @"
194 | mutation SetState($str:"+var1+ @", $str2:" + var2 + @"){
195 | set:setAdvancedString(request:{requiredString:$str, notRequiredString:$str2}){
196 | requiredString
197 | notRequiredString
198 | }
199 | }
200 | ";
201 |
202 | var expected = @"{
203 | set: {
204 | requiredString:""Yes"",
205 | notRequiredString: """"
206 | }
207 | }";
208 |
209 | GraphAssert.QuerySuccess(schema, query, expected, "{str:\"Yes\", str2:\"\"}");
210 | }
211 |
212 | [Fact]
213 | public void AdvancedExample_WithEnums_Works()
214 | {
215 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
216 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
217 |
218 | var query = @"
219 | mutation SetState{
220 | set (request:{state:Open, data:2}){
221 | state
222 | data
223 | }
224 | }
225 | ";
226 |
227 | var expected = @"{
228 | set: {
229 | state: ""Open"",
230 | data: 2
231 | }
232 | }";
233 |
234 | GraphAssert.QuerySuccess(schema, query, expected);
235 | }
236 |
237 | ///
238 | /// Introspection was not working on Inputs due to a bug in GraphQl
239 | ///
240 | [Fact]
241 | public void AdvancedExample_Introspection_Works()
242 | {
243 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
244 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
245 |
246 | var query = @"{
247 | __type(name:""Input_SetRequest""){
248 | name
249 | inputFields{
250 | name
251 | type{
252 | kind
253 | ofType{
254 | kind
255 | }
256 | }
257 | }
258 | }
259 | }
260 | ";
261 |
262 | var expected = @"{
263 | __type: {
264 | name: ""Input_SetRequest"",
265 | inputFields: [
266 | {
267 | name: ""data"",
268 | type: {
269 | kind: ""NON_NULL"",
270 | ofType: {
271 | kind: ""SCALAR""
272 | }
273 | }
274 | },
275 | {
276 | name: ""decimal"",
277 | type: {
278 | kind: ""SCALAR"",
279 | ofType: null
280 | }
281 | },
282 | {
283 | name: ""state"",
284 | type: {
285 | kind: ""ENUM"",
286 | ofType: null
287 | }
288 | }
289 | ]
290 | }
291 | }";
292 |
293 | GraphAssert.QuerySuccess(schema, query, expected);
294 | }
295 |
296 | ///
297 | /// Introspection was not working on Inputs due to a bug in GraphQl
298 | ///
299 | [Fact]
300 | public void SetRequestAdvancedString_Introspection_Works()
301 | {
302 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
303 | var schema = schemaGenerator.CreateSchema(typeof(EchoStateSchema));
304 |
305 | var query = @"{
306 | __type(name:""Input_SetRequestAdvancedString""){
307 | name
308 | inputFields{
309 | name
310 | type{
311 | kind
312 | ofType{
313 | kind
314 | }
315 | }
316 | }
317 | }
318 | }
319 | ";
320 |
321 | var expected =
322 | @"{""__type"":{""name"":""Input_SetRequestAdvancedString"",""inputFields"":[{""name"":""nonRequiredBool"",""type"":{""kind"":""SCALAR"",""ofType"":null}},{""name"":""nonRequiredObject"",""type"":{""kind"":""INPUT_OBJECT"",""ofType"":null}},{""name"":""notRequiredString"",""type"":{""kind"":""SCALAR"",""ofType"":null}},{""name"":""nullRequiredDateTime"",""type"":{""kind"":""SCALAR"",""ofType"":null}},{""name"":""requiredObject"",""type"":{""kind"":""INPUT_OBJECT"",""ofType"":null}},{""name"":""requiredObjects"",""type"":{""kind"":""LIST"",""ofType"":{""kind"":""INPUT_OBJECT""}}},{""name"":""requiredString"",""type"":{""kind"":""SCALAR"",""ofType"":null}}]}}";
323 |
324 | GraphAssert.QuerySuccess(schema, query, expected);
325 | }
326 |
327 | [Fact]
328 | public void PrimitiveExample_Works()
329 | {
330 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
331 | var schema = schemaGenerator.CreateSchema(typeof(PrimitiveSchema));
332 |
333 | var query = @"
334 | mutation Test{
335 | testRequest (clear:true)
336 | }
337 | ";
338 |
339 | var expected = @"{testRequest:null}";
340 |
341 | GraphAssert.QuerySuccess(schema, query, expected);
342 | }
343 |
344 |
345 | }
346 | }
347 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/PerformanceTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Threading.Tasks;
4 | using GraphQL.Execution;
5 | using GraphQL.SchemaGenerator.Tests.Helpers;
6 | using GraphQL.SchemaGenerator.Tests.Mocks;
7 | using GraphQL.SchemaGenerator.Tests.Schemas;
8 | using GraphQL.Validation;
9 | using GraphQL.Validation.Complexity;
10 | using Xunit;
11 | using Xunit.Abstractions;
12 |
13 | namespace GraphQL.SchemaGenerator.Tests.Tests
14 | {
15 | public class PerformanceTests
16 | {
17 | [Fact]
18 | public async Task LargeLists_Perform_UnderThreshold()
19 | {
20 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
21 |
22 | var schema = schemaGenerator.CreateSchema(typeof(PerformanceSchema));
23 |
24 | var query = @"{
25 | testList{
26 | date
27 | enum
28 | value
29 | nullValue
30 | decimalValue
31 | timeSpan
32 | byteArray
33 | stringValue
34 | values{
35 | value{
36 | complicatedResponse{
37 | echo
38 | data
39 | }
40 | }
41 | }
42 | }
43 | }";
44 |
45 | var stopwatch = new Stopwatch();
46 |
47 | stopwatch.Start();
48 |
49 | var result = await DocumentOperations.ExecuteOperationsAsync(schema, null, query, validate:false);
50 |
51 | stopwatch.Stop();
52 |
53 | _output.WriteLine($"Total Milliseconds: {stopwatch.ElapsedMilliseconds}");
54 |
55 | Assert.True(stopwatch.Elapsed.TotalSeconds < 2);
56 | Assert.Null(result.Errors);
57 | }
58 |
59 | [Fact]
60 | public async Task Methods_Perform_Async()
61 | {
62 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
63 |
64 | var schema = schemaGenerator.CreateSchema(typeof(PerformanceSchema));
65 |
66 | var query = @"{
67 | slow1:slowCall{
68 | date
69 | }
70 | slow2:slowCall{
71 | date
72 | }
73 | slow3:slowCall{
74 | date
75 | }
76 |
77 | }";
78 |
79 | var stopwatch = new Stopwatch();
80 |
81 | stopwatch.Start();
82 |
83 | var result = await DocumentOperations.ExecuteOperationsAsync(schema, null, query, validate: false);
84 |
85 | stopwatch.Stop();
86 |
87 | _output.WriteLine($"Total Milliseconds: {stopwatch.ElapsedMilliseconds}");
88 |
89 | Assert.True(stopwatch.Elapsed.TotalSeconds < 2);
90 | Assert.Null(result.Errors);
91 | }
92 |
93 | private readonly ITestOutputHelper _output;
94 |
95 | public PerformanceTests(ITestOutputHelper output)
96 | {
97 | _output = output;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/QueryTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using GraphQL.Execution;
3 | using GraphQL.Http;
4 | using GraphQL.SchemaGenerator.Tests.Helpers;
5 | using GraphQL.SchemaGenerator.Tests.Mocks;
6 | using GraphQL.SchemaGenerator.Tests.Schemas;
7 | using GraphQL.Validation;
8 | using GraphQL.Validation.Complexity;
9 | using Xunit;
10 |
11 | namespace GraphQL.SchemaGenerator.Tests.Tests
12 | {
13 | public class QueryTests
14 | {
15 | [Fact]
16 | public void CreateSchema_WithClassArgument_HasExpectedSchema()
17 | {
18 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
19 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
20 |
21 | var sut = schema.AllTypes;
22 | Assert.True(sut.Any(t => t.Name == "Input_Schema1Request"));
23 | }
24 |
25 | [Fact]
26 | public void BasicParameterExample_Works()
27 | {
28 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
29 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
30 |
31 | var query = @"{
32 | testRequest {value}
33 | }";
34 |
35 | var expected = @"{
36 | testRequest: {value:5}
37 | }";
38 |
39 | GraphAssert.QuerySuccess(schema, query, expected);
40 | }
41 |
42 | [Fact]
43 | public void WithParameterExample_Works()
44 | {
45 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
46 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
47 |
48 | var query = @"{
49 | testRequest(request:{echo:1}) {value}
50 | }";
51 |
52 | var expected = @"{
53 | testRequest: {value:1}
54 | }";
55 |
56 | GraphAssert.QuerySuccess(schema, query, expected);
57 | }
58 |
59 | [Fact]
60 | public void WithEnumerableParameterExample_Works()
61 | {
62 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
63 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
64 |
65 | var query = @"{
66 | testEnumerableRequest(request:[{echo:1}]) {value}
67 | }";
68 |
69 | var expected = @"{
70 | testEnumerableRequest: {value:1}
71 | }";
72 |
73 | GraphAssert.QuerySuccess(schema, query, expected);
74 | }
75 |
76 | [Fact]
77 | public void WithStringParameterExample_Works()
78 | {
79 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
80 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
81 |
82 | var query = @"{
83 | testRequest(request:{data:""yes""}) {stringValue}
84 | }";
85 |
86 | var expected = @"{
87 | testRequest: {stringValue:""yes""}
88 | }";
89 |
90 | GraphAssert.QuerySuccess(schema, query, expected);
91 | }
92 |
93 | [Fact]
94 | public void WithDictionaryParameterExample_Works()
95 | {
96 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
97 | var schema = schemaGenerator.CreateSchema(typeof(DictionarySchema));
98 |
99 | var query = @"{
100 | dictionaryRequest(request:{dictionary:[{key:""name"", value:""bob""}]}) {key,value}
101 | }";
102 |
103 | var expected = @"{
104 | dictionaryRequest: [{""key"":""name"",""value"":""bob""}]
105 | }";
106 |
107 | GraphAssert.QuerySuccess(schema, query, expected);
108 | }
109 |
110 | [Fact]
111 | public void WithStringEscapedParameterExample_Works()
112 | {
113 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
114 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
115 |
116 | //data = y\es m"am
117 | var query = @"{
118 | testRequest(request:{data:""y\\es m\""am""}) {stringValue}
119 | }";
120 |
121 | var expected = @"{
122 | testRequest: {stringValue:""y\\es m\""am""}
123 | }";
124 |
125 | GraphAssert.QuerySuccess(schema, query, expected);
126 | }
127 |
128 | [Fact]
129 | public void WithComplexParameters_Works()
130 | {
131 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
132 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
133 |
134 | var query = @"{
135 | testRequest(request:{
136 | complexRequests:[{
137 | innerData:""345""
138 | }]
139 | }) {value}
140 | }";
141 |
142 | var expected = @"{
143 | testRequest: {value:5}
144 | }";
145 |
146 | GraphAssert.QuerySuccess(schema, query, expected);
147 | }
148 |
149 | [Fact]
150 | public void WithComplexParameters_HaveCorrectType()
151 | {
152 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
153 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
154 |
155 | var query = @"{
156 | __type(name : ""Input_InnerRequest"") {
157 | name
158 | kind
159 | }}";
160 |
161 | var expected = @"{
162 | __type: {
163 | name: ""Input_InnerRequest"",
164 | kind: ""INPUT_OBJECT""
165 | }
166 | }";
167 |
168 | GraphAssert.QuerySuccess(schema, query, expected);
169 | }
170 |
171 | [Fact]
172 | public void WithEnumerableExample_Works()
173 | {
174 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
175 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
176 |
177 | var query = @"{
178 | testEnumerable{value}
179 | }";
180 |
181 | var expected = @"{
182 | testEnumerable: [{value: 1},{value: 5}]
183 | }";
184 |
185 | GraphAssert.QuerySuccess(schema, query, expected);
186 | }
187 |
188 | [Fact]
189 | public void WithEnum_Works()
190 | {
191 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
192 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
193 |
194 | var query = @"{
195 | testRequest {enum}
196 | }";
197 |
198 | var expected = @"{
199 | testRequest: {enum:""NEWHOPE""}
200 | }";
201 |
202 | GraphAssert.QuerySuccess(schema, query, expected);
203 | }
204 |
205 | [Fact]
206 | public void WithDateTimeOffset_Works()
207 | {
208 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
209 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
210 |
211 | var query = @"{
212 | testRequest {date}
213 | }";
214 |
215 | var expected = @"{
216 | testRequest: {date:""1999-01-01T00:00:00-07:00""}
217 | }";
218 |
219 | GraphAssert.QuerySuccess(schema, query, expected);
220 | }
221 |
222 | [Fact]
223 | public void FieldDescription_Works()
224 | {
225 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
226 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
227 |
228 | var query = @"{
229 | __schema{
230 | types{
231 | name,
232 | fields {
233 | name
234 | description
235 | }
236 | }
237 | }
238 | }";
239 |
240 | var exec = new DocumentExecuter(new GraphQLDocumentBuilder(), new DocumentValidator(), new ComplexityAnalyzer());
241 | var result = exec.ExecuteAsync(schema, null, query, null).Result;
242 |
243 | var writer = new DocumentWriter(indent: true);
244 | var writtenResult = writer.Write(result.Data);
245 |
246 | var errors = result.Errors?.FirstOrDefault();
247 |
248 | Assert.Null(errors?.Message);
249 | Assert.True(writtenResult.Contains("{VerifyComment}"));
250 | }
251 |
252 | [Fact]
253 | public void WithNull_Works()
254 | {
255 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
256 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
257 |
258 | var query = @"{
259 | testRequest {nullValue}
260 | }";
261 |
262 | var expected = @"{
263 | testRequest: {nullValue:null}
264 | }";
265 |
266 | GraphAssert.QuerySuccess(schema, query, expected);
267 | }
268 |
269 | [Fact]
270 | public void WithDictionary_Works()
271 | {
272 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
273 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
274 |
275 | var query = @"{
276 | testRequest {
277 | values{
278 | key
279 | value{
280 | complicatedResponse{
281 | echo
282 | }
283 | }
284 | }
285 | }
286 | }";
287 |
288 | var expected = @"{
289 | testRequest: {
290 | values: [
291 | {
292 | key: ""99"",
293 | value: {
294 | complicatedResponse: {
295 | echo: 99
296 | }
297 | }
298 | },
299 | {
300 | key: ""59"",
301 | value: {
302 | complicatedResponse: {
303 | echo: 59
304 | }
305 | }
306 | },
307 | {
308 | key: ""null"",
309 | value: null
310 | }
311 | ]
312 | }
313 | }";
314 |
315 | GraphAssert.QuerySuccess(schema, query, expected);
316 | }
317 |
318 | [Fact]
319 | public void PrimitiveString_Works()
320 | {
321 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
322 | var schema = schemaGenerator.CreateSchema(typeof(PrimitiveSchema));
323 |
324 | var query = @"
325 | {
326 | testString
327 | }
328 | ";
329 |
330 | var expected = @"{testString:""Hi""}";
331 |
332 | GraphAssert.QuerySuccess(schema, query, expected);
333 | }
334 |
335 | [Fact]
336 | public void GetNullDecimalAsVariable_IsSafe()
337 | {
338 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
339 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
340 |
341 | var query = @"
342 | query($ts:Decimal!)
343 | {
344 | testRequest(request:{decimal:$ts}){decimalValue}
345 | }
346 | ";
347 |
348 | var variables = @"{
349 | ts:1.23
350 | }";
351 |
352 | var expected = @"{
353 | testRequest: {
354 | decimalValue:1.23
355 | }
356 | }";
357 |
358 | GraphAssert.QuerySuccess(schema, query, expected, variables);
359 | }
360 |
361 | //todo:
362 | //[Fact]
363 | public void BasicInterfaceExample_Works()
364 | {
365 | var schemaGenerator = new SchemaGenerator(new MockServiceProvider());
366 | var schema = schemaGenerator.CreateSchema(typeof(EchoSchema));
367 |
368 | var query = @"{
369 | testInterface{value}
370 | }";
371 |
372 | var expected = @"{
373 | testInterface: {value:8}
374 | }";
375 |
376 | GraphAssert.QuerySuccess(schema, query, expected);
377 | }
378 | }
379 | }
380 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/Tests/TypeHelperTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using GraphQL.SchemaGenerator.Helpers;
4 | using GraphQL.SchemaGenerator.Tests.Schemas;
5 | using Xunit;
6 |
7 | namespace GraphQL.SchemaGenerator.Tests.Tests
8 | {
9 | public class TypeHelperTests
10 | {
11 | [Fact]
12 | public void GetFullName_With_NestedDictionary_IsSafe()
13 | {
14 | var data = new SchemaResponse()
15 | {
16 | NestDictionary = new Dictionary>()
17 | };
18 | var type = data.NestDictionary.GetType();
19 |
20 | var sut = TypeHelper.GetFullName(type);
21 |
22 | var prohibitedCharacters = new List {'~', ' ', ','};
23 |
24 | Assert.NotNull(sut);
25 | Assert.True(!sut.Any(t=> prohibitedCharacters.Contains(t)));
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/Attributes/GraphKnownTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GraphQL.SchemaGenerator.Schema;
3 |
4 | namespace GraphQL.SchemaGenerator.Attributes
5 | {
6 | [AttributeUsage(AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
7 | public class GraphKnownTypeAttribute : Attribute, IDomainSchemaTypeMapping
8 | {
9 | public Type DomainType { get; set; }
10 | public Type SchemaType { get; set; }
11 |
12 | public GraphKnownTypeAttribute(Type domainType, Type schemaType)
13 | {
14 | DomainType = domainType;
15 | SchemaType = schemaType;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/Attributes/GraphNotRequiredAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using GraphQL.SchemaGenerator.Models;
3 |
4 | namespace GraphQL.SchemaGenerator.Attributes
5 | {
6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field)]
7 | public class GraphNotRequiredAttribute : Attribute
8 | {
9 | public RequiredType Type { get; set; }
10 |
11 | public GraphNotRequiredAttribute(RequiredType type = RequiredType.NotRequired)
12 | {
13 | Type = type;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/Attributes/GraphRouteAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GraphQL.SchemaGenerator.Attributes
4 | {
5 | ///
6 | /// Attribute provided on an api endpoint can be converted into graph ql.
7 | ///
8 | [AttributeUsage(AttributeTargets.Method)]
9 | public class GraphRouteAttribute : Attribute
10 | {
11 | ///
12 | ///
13 | ///
14 | public string Name { get; set; }
15 |
16 | ///
17 | ///
18 | ///
19 | public bool IsMutation { get; set; }
20 |
21 |
22 | ///
23 | ///
24 | ///
25 | public GraphRouteAttribute()
26 | {
27 |
28 | }
29 |
30 | ///
31 | ///
32 | ///
33 | ///
34 | ///
35 | public GraphRouteAttribute(string name = null, bool isMutation = false)
36 | {
37 | Name = name;
38 | IsMutation = isMutation;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/Attributes/GraphTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GraphQL.SchemaGenerator.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field)]
6 | public class GraphTypeAttribute : Attribute
7 | {
8 | public Type Type { get; set; }
9 |
10 | public bool Exclude { get; set; }
11 |
12 | public GraphTypeAttribute(Type type = null, bool exclude = false)
13 | {
14 | Type = type;
15 | Exclude = exclude;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/Attributes/NotNullAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace GraphQL.SchemaGenerator.Attributes
4 | {
5 | public class NotNullAttribute : Attribute
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | #Change Log
2 |
3 | ## [0.1.0.6] - 10/17/2017
4 |
5 | - Switched to a fork of graph ql dot net for significant performance improvements: https://github.com/holm0563/graphql-dotnet/tree/performance2withrollback
6 |
--------------------------------------------------------------------------------
/src/GraphQl.SchemaGenerator/DeepDictionaryRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Dynamic;
4 | using System.Linq;
5 | using Newtonsoft.Json;
6 | using Newtonsoft.Json.Linq;
7 |
8 | namespace GraphQL.SchemaGenerator
9 | {
10 | public class DeepDictionaryRequest : JsonConverter
11 | {
12 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
13 | {
14 | WriteValue(writer, value);
15 | }
16 |
17 | private void WriteValue(JsonWriter writer, object value)
18 | {
19 | var t = JToken.FromObject(value);
20 | switch (t.Type)
21 | {
22 | case JTokenType.Object:
23 | WriteObject(writer, value);
24 | break;
25 | case JTokenType.Array:
26 | WriteArray(writer, value);
27 | break;
28 | default:
29 | writer.WriteValue(value);
30 | break;
31 | }
32 | }
33 |
34 | private void WriteObject(JsonWriter writer, object value)
35 | {
36 | writer.WriteStartObject();
37 | var obj = value as IDictionary;
38 | foreach (var kvp in obj)
39 | {
40 | writer.WritePropertyName(kvp.Key);
41 | WriteValue(writer, kvp.Value);
42 | }
43 | writer.WriteEndObject();
44 | }
45 |
46 | private void WriteArray(JsonWriter writer, object value)
47 | {
48 | var array = value as IEnumerable