From ce649f78b556f34663216f1adc155924e94a1b96 Mon Sep 17 00:00:00 2001 From: Alexander Rose Date: Mon, 13 Sep 2021 14:50:51 +0200 Subject: [PATCH 1/2] update dependencies of integration tests --- .../Chat/AddMessageVariables.cs | 2 +- .../Chat/GraphQLClientChatExtensions.cs | 4 +-- .../Chat/Schema/ChatMutation.cs | 2 +- .../Chat/Schema/ChatSchema.cs | 13 +++++---- .../Chat/Schema/ChatSubscriptions.cs | 10 +++---- .../Chat/Schema/MessageType.cs | 2 +- tests/GraphQL.Client.Tests.Common/Common.cs | 2 -- .../GraphQL.Client.Tests.Common.csproj | 10 +++---- .../GraphQL.Integration.Tests.csproj | 4 +-- .../WebsocketTests/Base.cs | 5 ++++ .../IntegrationTestServer.csproj | 11 ++----- .../Properties/launchSettings.json | 4 +-- tests/IntegrationTestServer/Startup.cs | 29 +++++++++---------- 13 files changed, 47 insertions(+), 51 deletions(-) diff --git a/tests/GraphQL.Client.Tests.Common/Chat/AddMessageVariables.cs b/tests/GraphQL.Client.Tests.Common/Chat/AddMessageVariables.cs index 0a330007..887c55cd 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/AddMessageVariables.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/AddMessageVariables.cs @@ -12,7 +12,7 @@ public class AddMessageInput public string Content { get; set; } - public DateTime SentAt { get; set; } + public string SentAt { get; set; } } } } diff --git a/tests/GraphQL.Client.Tests.Common/Chat/GraphQLClientChatExtensions.cs b/tests/GraphQL.Client.Tests.Common/Chat/GraphQLClientChatExtensions.cs index f4417860..07648f06 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/GraphQLClientChatExtensions.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/GraphQLClientChatExtensions.cs @@ -10,7 +10,7 @@ public static class GraphQLClientChatExtensions @"mutation($input: MessageInputType){ addMessage(message: $input){ content - } + } }"; public static Task> AddMessageAsync(this IGraphQLClient client, string message) @@ -21,7 +21,7 @@ public static Task> AddMessageAsync(th { FromId = "2", Content = message, - SentAt = DateTime.Now + SentAt = DateTime.Now.ToString("s") } }; diff --git a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatMutation.cs b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatMutation.cs index 1d2cdd28..b005ebc2 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatMutation.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatMutation.cs @@ -36,7 +36,7 @@ public MessageInputType() { Field("fromId"); Field("content"); - Field("sentAt"); + Field("sentAt"); } } } diff --git a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSchema.cs b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSchema.cs index 49126f8a..fbdfedf1 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSchema.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSchema.cs @@ -1,13 +1,16 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + namespace GraphQL.Client.Tests.Common.Chat.Schema { public class ChatSchema : Types.Schema { - public ChatSchema(IDependencyResolver resolver) - : base(resolver) + public ChatSchema(IServiceProvider services) + : base(services) { - Query = resolver.Resolve(); - Mutation = resolver.Resolve(); - Subscription = resolver.Resolve(); + Query = services.GetRequiredService(); + Mutation = services.GetRequiredService(); + Subscription = services.GetRequiredService(); } } } diff --git a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSubscriptions.cs b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSubscriptions.cs index f0d08efb..b15ba334 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSubscriptions.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/Schema/ChatSubscriptions.cs @@ -61,9 +61,9 @@ public ChatSubscriptions(IChat chat) }); } - private IObservable SubscribeById(ResolveEventStreamContext context) + private IObservable SubscribeById(IResolveEventStreamContext context) { - var messageContext = context.UserContext.As(); + var messageContext = (MessageHandlingContext) context.UserContext; var user = messageContext.Get("user"); var sub = "Anonymous"; @@ -76,16 +76,16 @@ private IObservable SubscribeById(ResolveEventStreamContext context) return messages.Where(message => message.From.Id == id); } - private Message ResolveMessage(ResolveFieldContext context) + private Message ResolveMessage(IResolveFieldContext context) { var message = context.Source as Message; return message; } - private IObservable Subscribe(ResolveEventStreamContext context) + private IObservable Subscribe(IResolveEventStreamContext context) { - var messageContext = context.UserContext.As(); + var messageContext = (MessageHandlingContext) context.UserContext; var user = messageContext.Get("user"); var sub = "Anonymous"; diff --git a/tests/GraphQL.Client.Tests.Common/Chat/Schema/MessageType.cs b/tests/GraphQL.Client.Tests.Common/Chat/Schema/MessageType.cs index 2636390c..e72a0067 100644 --- a/tests/GraphQL.Client.Tests.Common/Chat/Schema/MessageType.cs +++ b/tests/GraphQL.Client.Tests.Common/Chat/Schema/MessageType.cs @@ -12,7 +12,7 @@ public MessageType() Field(o => o.From, false, typeof(MessageFromType)).Resolve(ResolveFrom); } - private MessageFrom ResolveFrom(ResolveFieldContext context) + private MessageFrom ResolveFrom(IResolveFieldContext context) { var message = context.Source; return message.From; diff --git a/tests/GraphQL.Client.Tests.Common/Common.cs b/tests/GraphQL.Client.Tests.Common/Common.cs index 97dd30fe..af437bad 100644 --- a/tests/GraphQL.Client.Tests.Common/Common.cs +++ b/tests/GraphQL.Client.Tests.Common/Common.cs @@ -13,7 +13,6 @@ public static class Common public static StarWarsSchema GetStarWarsSchema() { var services = new ServiceCollection(); - services.AddTransient(provider => new FuncDependencyResolver(provider.GetService)); services.AddStarWarsSchema(); return services.BuildServiceProvider().GetRequiredService(); } @@ -21,7 +20,6 @@ public static StarWarsSchema GetStarWarsSchema() public static ChatSchema GetChatSchema() { var services = new ServiceCollection(); - services.AddTransient(provider => new FuncDependencyResolver(provider.GetService)); services.AddChatSchema(); return services.BuildServiceProvider().GetRequiredService(); } diff --git a/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj b/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj index 6aeff4a3..f2fefe45 100644 --- a/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj +++ b/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj @@ -7,13 +7,11 @@ - - + + - - - - + + diff --git a/tests/GraphQL.Integration.Tests/GraphQL.Integration.Tests.csproj b/tests/GraphQL.Integration.Tests/GraphQL.Integration.Tests.csproj index 3cc7fd29..6aca8a5b 100644 --- a/tests/GraphQL.Integration.Tests/GraphQL.Integration.Tests.csproj +++ b/tests/GraphQL.Integration.Tests/GraphQL.Integration.Tests.csproj @@ -8,9 +8,7 @@ - - - + diff --git a/tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs b/tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs index ba3ccb17..4bedde89 100644 --- a/tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs +++ b/tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs @@ -67,6 +67,7 @@ public async void CanSendRequestViaWebsocket() await ChatClient.InitializeWebsocketConnection(); const string message = "some random testing message"; var response = await ChatClient.AddMessageAsync(message); + response.Errors.Should().BeNullOrEmpty(); response.Data.AddMessage.Content.Should().Be(message); } @@ -77,6 +78,7 @@ public async void CanUseWebSocketScheme() await ChatClient.InitializeWebsocketConnection(); const string message = "some random testing message"; var response = await ChatClient.AddMessageAsync(message); + response.Errors.Should().BeNullOrEmpty(); response.Data.AddMessage.Content.Should().Be(message); } @@ -89,6 +91,7 @@ public async void CanUseDedicatedWebSocketEndpoint() await ChatClient.InitializeWebsocketConnection(); const string message = "some random testing message"; var response = await ChatClient.AddMessageAsync(message); + response.Errors.Should().BeNullOrEmpty(); response.Data.AddMessage.Content.Should().Be(message); } @@ -174,10 +177,12 @@ public async void CanCreateObservableSubscription() Debug.WriteLine("subscribing..."); using var observer = observable.Observe(); await observer.Should().PushAsync(1); + observer.RecordedMessages.Last().Errors.Should().BeNullOrEmpty(); observer.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(InitialMessage.Content); const string message1 = "Hello World"; var response = await ChatClient.AddMessageAsync(message1); + response.Errors.Should().BeNullOrEmpty(); response.Data.AddMessage.Content.Should().Be(message1); await observer.Should().PushAsync(2); observer.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(message1); diff --git a/tests/IntegrationTestServer/IntegrationTestServer.csproj b/tests/IntegrationTestServer/IntegrationTestServer.csproj index da280f0f..2eaf45ba 100644 --- a/tests/IntegrationTestServer/IntegrationTestServer.csproj +++ b/tests/IntegrationTestServer/IntegrationTestServer.csproj @@ -10,15 +10,10 @@ - - - - - - + - - + + diff --git a/tests/IntegrationTestServer/Properties/launchSettings.json b/tests/IntegrationTestServer/Properties/launchSettings.json index cd6aedd6..987589b7 100644 --- a/tests/IntegrationTestServer/Properties/launchSettings.json +++ b/tests/IntegrationTestServer/Properties/launchSettings.json @@ -22,7 +22,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:5005/" + "applicationUrl": "http://localhost:5005" } } -} \ No newline at end of file +} diff --git a/tests/IntegrationTestServer/Startup.cs b/tests/IntegrationTestServer/Startup.cs index 49586dc0..5faae7f7 100644 --- a/tests/IntegrationTestServer/Startup.cs +++ b/tests/IntegrationTestServer/Startup.cs @@ -2,6 +2,7 @@ using GraphQL.Client.Tests.Common; using GraphQL.Client.Tests.Common.Chat.Schema; using GraphQL.Server; +using GraphQL.Server.Ui.Altair; using GraphQL.Server.Ui.GraphiQL; using GraphQL.Server.Ui.Playground; using GraphQL.StarWars; @@ -12,6 +13,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; namespace IntegrationTestServer { @@ -32,16 +34,21 @@ public Startup(IConfiguration configuration, IWebHostEnvironment environment) public void ConfigureServices(IServiceCollection services) { services.Configure(options => options.AllowSynchronousIO = true); - - services.AddTransient(provider => new FuncDependencyResolver(provider.GetService)); + // services.AddChatSchema(); services.AddStarWarsSchema(); - services.AddGraphQL(options => + services.AddSingleton(); + services.AddGraphQL((options, services) => { options.EnableMetrics = true; - options.ExposeExceptions = Environment.IsDevelopment(); + var logger = services.GetRequiredService>(); + options.UnhandledExceptionDelegate = ctx => logger.LogError("{Error} occurred", ctx.OriginalException.Message); }) - .AddWebSockets(); + .AddErrorInfoProvider(opt => opt.ExposeExceptionStackTrace = Environment.IsDevelopment()) + .AddSystemTextJson() + .AddWebSockets() + .AddGraphTypes(typeof(ChatSchema)) + .AddGraphTypes(typeof(StarWarsSchema)); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -57,16 +64,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) ConfigureGraphQLSchema(app, Common.CHAT_ENDPOINT); ConfigureGraphQLSchema(app, Common.STAR_WARS_ENDPOINT); - app.UseGraphiQLServer(new GraphiQLOptions - { - GraphiQLPath = "/ui/graphiql", - GraphQLEndPoint = Common.STAR_WARS_ENDPOINT - }); - app.UseGraphQLPlayground(new GraphQLPlaygroundOptions - { - Path = "/ui/playground", - GraphQLEndPoint = Common.CHAT_ENDPOINT - }); + app.UseGraphQLGraphiQL(new GraphiQLOptions { GraphQLEndPoint = Common.STAR_WARS_ENDPOINT }); + app.UseGraphQLAltair(new AltairOptions { GraphQLEndPoint = Common.CHAT_ENDPOINT }); } private void ConfigureGraphQLSchema(IApplicationBuilder app, string endpoint) where TSchema : Schema From fe110b6201d6165bb1bcad6065b738921137c98f Mon Sep 17 00:00:00 2001 From: Alexander Rose Date: Tue, 14 Sep 2021 10:36:52 +0200 Subject: [PATCH 2/2] add StarWars schema classes, fix local execution client --- .../GraphQL.Client.LocalExecution.csproj | 6 +- .../GraphQLLocalExecutionClient.cs | 10 ++- .../BaseSerializerTest.cs | 1 + tests/GraphQL.Client.Tests.Common/Common.cs | 4 +- .../GraphQL.Client.Tests.Common.csproj | 1 - .../ResolveFieldContextExtensions.cs | 65 ++++++++++++++ .../StarWars/StarWarsData.cs | 90 +++++++++++++++++++ .../StarWars/StarWarsMutation.cs | 35 ++++++++ .../StarWars/StarWarsQuery.cs | 33 +++++++ .../StarWars/StarWarsSchema.cs | 18 ++++ .../StarWars/{ => TestData}/StarWarsHumans.cs | 5 +- .../StarWars/Types/CharacterInterface.cs | 20 +++++ .../StarWars/Types/DroidType.cs | 30 +++++++ .../StarWars/Types/EpisodeEnum.cs | 23 +++++ .../StarWars/Types/HumanInputType.cs | 14 +++ .../StarWars/Types/HumanType.cs | 30 +++++++ .../StarWars/Types/StarWarsCharacter.cs | 23 +++++ .../QueryAndMutationTests/Base.cs | 1 + .../IntegrationTestServer.csproj | 1 - tests/IntegrationTestServer/Startup.cs | 3 +- 20 files changed, 400 insertions(+), 13 deletions(-) create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Extensions/ResolveFieldContextExtensions.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/StarWarsData.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/StarWarsMutation.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/StarWarsQuery.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/StarWarsSchema.cs rename tests/GraphQL.Client.Tests.Common/StarWars/{ => TestData}/StarWarsHumans.cs (76%) create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/CharacterInterface.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/DroidType.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/EpisodeEnum.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanInputType.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanType.cs create mode 100644 tests/GraphQL.Client.Tests.Common/StarWars/Types/StarWarsCharacter.cs diff --git a/src/GraphQL.Client.LocalExecution/GraphQL.Client.LocalExecution.csproj b/src/GraphQL.Client.LocalExecution/GraphQL.Client.LocalExecution.csproj index e8e162cb..d69fc21b 100644 --- a/src/GraphQL.Client.LocalExecution/GraphQL.Client.LocalExecution.csproj +++ b/src/GraphQL.Client.LocalExecution/GraphQL.Client.LocalExecution.csproj @@ -8,9 +8,9 @@ - - - + + + diff --git a/src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs b/src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs index 65098ae8..f2c077f6 100644 --- a/src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs +++ b/src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using GraphQL.Client.Abstractions; using GraphQL.Client.Serializer.Newtonsoft; +using GraphQL.NewtonsoftJson; using GraphQL.Subscription; using GraphQL.Types; using Newtonsoft.Json; @@ -41,6 +42,7 @@ public class GraphQLLocalExecutionClient : IGraphQLClient where TSchema public IGraphQLJsonSerializer Serializer { get; } private readonly DocumentExecuter _documentExecuter; + private readonly DocumentWriter _documentWriter; public GraphQLLocalExecutionClient(TSchema schema, IGraphQLJsonSerializer serializer) { @@ -50,6 +52,7 @@ public GraphQLLocalExecutionClient(TSchema schema, IGraphQLJsonSerializer serial if (!Schema.Initialized) Schema.Initialize(); _documentExecuter = new DocumentExecuter(); + _documentWriter = new DocumentWriter(); } public void Dispose() { } @@ -109,12 +112,13 @@ private async Task ExecuteAsync(GraphQLRequest request, Cancell return result; } - private Task> ExecutionResultToGraphQLResponse(ExecutionResult executionResult, CancellationToken cancellationToken = default) + private async Task> ExecutionResultToGraphQLResponse(ExecutionResult executionResult, CancellationToken cancellationToken = default) { + string json = await _documentWriter.WriteToStringAsync(executionResult); // serialize result into utf8 byte stream - var resultStream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(executionResult, _variablesSerializerSettings))); + var resultStream = new MemoryStream(Encoding.UTF8.GetBytes(json)); // deserialize using the provided serializer - return Serializer.DeserializeFromUtf8StreamAsync(resultStream, cancellationToken); + return await Serializer.DeserializeFromUtf8StreamAsync(resultStream, cancellationToken); } #endregion diff --git a/tests/GraphQL.Client.Serializer.Tests/BaseSerializerTest.cs b/tests/GraphQL.Client.Serializer.Tests/BaseSerializerTest.cs index 53cba0c1..863974ae 100644 --- a/tests/GraphQL.Client.Serializer.Tests/BaseSerializerTest.cs +++ b/tests/GraphQL.Client.Serializer.Tests/BaseSerializerTest.cs @@ -16,6 +16,7 @@ using GraphQL.Client.Tests.Common.Chat.Schema; using GraphQL.Client.Tests.Common.Helpers; using GraphQL.Client.Tests.Common.StarWars; +using GraphQL.Client.Tests.Common.StarWars.TestData; using Xunit; namespace GraphQL.Client.Serializer.Tests diff --git a/tests/GraphQL.Client.Tests.Common/Common.cs b/tests/GraphQL.Client.Tests.Common/Common.cs index af437bad..269ea257 100644 --- a/tests/GraphQL.Client.Tests.Common/Common.cs +++ b/tests/GraphQL.Client.Tests.Common/Common.cs @@ -1,6 +1,6 @@ using GraphQL.Client.Tests.Common.Chat.Schema; -using GraphQL.StarWars; -using GraphQL.StarWars.Types; +using GraphQL.Client.Tests.Common.StarWars; +using GraphQL.Client.Tests.Common.StarWars.Types; using Microsoft.Extensions.DependencyInjection; namespace GraphQL.Client.Tests.Common diff --git a/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj b/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj index f2fefe45..24cbf419 100644 --- a/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj +++ b/tests/GraphQL.Client.Tests.Common/GraphQL.Client.Tests.Common.csproj @@ -9,7 +9,6 @@ - diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Extensions/ResolveFieldContextExtensions.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Extensions/ResolveFieldContextExtensions.cs new file mode 100644 index 00000000..44ba5895 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Extensions/ResolveFieldContextExtensions.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using GraphQL.Builders; +using GraphQL.Client.Tests.Common.StarWars.Types; +using GraphQL.Types.Relay.DataObjects; + +namespace GraphQL.Client.Tests.Common.StarWars.Extensions +{ + public static class ResolveFieldContextExtensions + { + public static Connection GetPagedResults(this IResolveConnectionContext context, StarWarsData data, List ids) where U : StarWarsCharacter + { + List idList; + List list; + string cursor; + string endCursor; + var pageSize = context.PageSize ?? 20; + + if (context.IsUnidirectional || context.After != null || context.Before == null) + { + if (context.After != null) + { + idList = ids + .SkipWhile(x => !Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(x)).Equals(context.After)) + .Take(context.First ?? pageSize).ToList(); + } + else + { + idList = ids + .Take(context.First ?? pageSize).ToList(); + } + } + else + { + if (context.Before != null) + { + idList = ids.Reverse() + .SkipWhile(x => !Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(x)).Equals(context.Before)) + .Take(context.Last ?? pageSize).ToList(); + } + else + { + idList = ids.Reverse() + .Take(context.Last ?? pageSize).ToList(); + } + } + + list = data.GetCharactersAsync(idList).Result as List ?? throw new InvalidOperationException($"GetCharactersAsync method should return list of '{typeof(U).Name}' items."); + cursor = list.Count > 0 ? list.Last().Cursor : null; + endCursor = ids.Count > 0 ? Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ids.Last())) : null; + + return new Connection + { + Edges = list.Select(x => new Edge { Cursor = x.Cursor, Node = x }).ToList(), + TotalCount = list.Count, + PageInfo = new PageInfo + { + EndCursor = endCursor, + HasNextPage = endCursor == null ? false : cursor != endCursor, + } + }; + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsData.cs b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsData.cs new file mode 100644 index 00000000..f561ed87 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsData.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using GraphQL.Client.Tests.Common.StarWars.Types; + +namespace GraphQL.Client.Tests.Common.StarWars +{ + public class StarWarsData + { + private readonly List _characters = new List(); + + public StarWarsData() + { + _characters.Add(new Human + { + Id = "1", + Name = "Luke", + Friends = new List { "3", "4" }, + AppearsIn = new[] { 4, 5, 6 }, + HomePlanet = "Tatooine", + Cursor = "MQ==" + }); + _characters.Add(new Human + { + Id = "2", + Name = "Vader", + AppearsIn = new[] { 4, 5, 6 }, + HomePlanet = "Tatooine", + Cursor = "Mg==" + }); + + _characters.Add(new Droid + { + Id = "3", + Name = "R2-D2", + Friends = new List { "1", "4" }, + AppearsIn = new[] { 4, 5, 6 }, + PrimaryFunction = "Astromech", + Cursor = "Mw==" + }); + _characters.Add(new Droid + { + Id = "4", + Name = "C-3PO", + AppearsIn = new[] { 4, 5, 6 }, + PrimaryFunction = "Protocol", + Cursor = "NA==" + }); + } + + public IEnumerable GetFriends(StarWarsCharacter character) + { + if (character == null) + { + return null; + } + + var friends = new List(); + var lookup = character.Friends; + if (lookup != null) + { + foreach (var c in _characters.Where(h => lookup.Contains(h.Id))) + friends.Add(c); + } + return friends; + } + + public StarWarsCharacter AddCharacter(StarWarsCharacter character) + { + character.Id = _characters.Count.ToString(); + _characters.Add(character); + return character; + } + + public Task GetHumanByIdAsync(string id) + { + return Task.FromResult(_characters.FirstOrDefault(h => h.Id == id && h is Human) as Human); + } + + public Task GetDroidByIdAsync(string id) + { + return Task.FromResult(_characters.FirstOrDefault(h => h.Id == id && h is Droid) as Droid); + } + + public Task> GetCharactersAsync(List guids) + { + return Task.FromResult(_characters.Where(c => guids.Contains(c.Id)).ToList()); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsMutation.cs b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsMutation.cs new file mode 100644 index 00000000..cd577688 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsMutation.cs @@ -0,0 +1,35 @@ +using GraphQL.Client.Tests.Common.StarWars.Types; +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars +{ + /// + /// This is an example JSON request for a mutation + /// { + /// "query": "mutation ($human:HumanInput!){ createHuman(human: $human) { id name } }", + /// "variables": { + /// "human": { + /// "name": "Boba Fett" + /// } + /// } + /// } + /// + public class StarWarsMutation : ObjectGraphType + { + public StarWarsMutation(StarWarsData data) + { + Name = "Mutation"; + + Field( + "createHuman", + arguments: new QueryArguments( + new QueryArgument> { Name = "human" } + ), + resolve: context => + { + var human = context.GetArgument("human"); + return data.AddCharacter(human); + }); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsQuery.cs b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsQuery.cs new file mode 100644 index 00000000..c416e8c5 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsQuery.cs @@ -0,0 +1,33 @@ +using System; +using GraphQL.Client.Tests.Common.StarWars.Types; +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars +{ + public class StarWarsQuery : ObjectGraphType + { + public StarWarsQuery(StarWarsData data) + { + Name = "Query"; + + Field("hero", resolve: context => data.GetDroidByIdAsync("3")); + Field( + "human", + arguments: new QueryArguments( + new QueryArgument> { Name = "id", Description = "id of the human" } + ), + resolve: context => data.GetHumanByIdAsync(context.GetArgument("id")) + ); + + Func func = (context, id) => data.GetDroidByIdAsync(id); + + FieldDelegate( + "droid", + arguments: new QueryArguments( + new QueryArgument> { Name = "id", Description = "id of the droid" } + ), + resolve: func + ); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsSchema.cs b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsSchema.cs new file mode 100644 index 00000000..eff7cff4 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsSchema.cs @@ -0,0 +1,18 @@ +using System; +using GraphQL.Types; +using Microsoft.Extensions.DependencyInjection; + +namespace GraphQL.Client.Tests.Common.StarWars +{ + public class StarWarsSchema : Schema + { + public StarWarsSchema(IServiceProvider serviceProvider) + : base(serviceProvider) + { + Query = serviceProvider.GetRequiredService(); + Mutation = serviceProvider.GetRequiredService(); + + Description = "Example StarWars universe schema"; + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsHumans.cs b/tests/GraphQL.Client.Tests.Common/StarWars/TestData/StarWarsHumans.cs similarity index 76% rename from tests/GraphQL.Client.Tests.Common/StarWars/StarWarsHumans.cs rename to tests/GraphQL.Client.Tests.Common/StarWars/TestData/StarWarsHumans.cs index 88c64759..1e93ccb6 100644 --- a/tests/GraphQL.Client.Tests.Common/StarWars/StarWarsHumans.cs +++ b/tests/GraphQL.Client.Tests.Common/StarWars/TestData/StarWarsHumans.cs @@ -1,8 +1,11 @@ using System.Collections; using System.Collections.Generic; -namespace GraphQL.Client.Tests.Common.StarWars +namespace GraphQL.Client.Tests.Common.StarWars.TestData { + /// + /// Test data object + /// public class StarWarsHumans : IEnumerable { public IEnumerator GetEnumerator() diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/CharacterInterface.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/CharacterInterface.cs new file mode 100644 index 00000000..e45db3d4 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/CharacterInterface.cs @@ -0,0 +1,20 @@ +using GraphQL.Types; +using GraphQL.Types.Relay; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public class CharacterInterface : InterfaceGraphType + { + public CharacterInterface() + { + Name = "Character"; + + Field>("id", "The id of the character.", resolve: context => context.Source.Id); + Field("name", "The name of the character.", resolve: context => context.Source.Name); + + Field>("friends"); + Field>>("friendsConnection"); + Field>("appearsIn", "Which movie they appear in."); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/DroidType.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/DroidType.cs new file mode 100644 index 00000000..8d8fc867 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/DroidType.cs @@ -0,0 +1,30 @@ +using GraphQL.Client.Tests.Common.StarWars.Extensions; +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public class DroidType : ObjectGraphType + { + public DroidType(StarWarsData data) + { + Name = "Droid"; + Description = "A mechanical creature in the Star Wars universe."; + + Field>("id", "The id of the droid.", resolve: context => context.Source.Id); + Field("name", "The name of the droid.", resolve: context => context.Source.Name); + + Field>("friends", resolve: context => data.GetFriends(context.Source)); + + Connection() + .Name("friendsConnection") + .Description("A list of a character's friends.") + .Bidirectional() + .Resolve(context => context.GetPagedResults(data, context.Source.Friends)); + + Field>("appearsIn", "Which movie they appear in."); + Field("primaryFunction", "The primary function of the droid.", resolve: context => context.Source.PrimaryFunction); + + Interface(); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/EpisodeEnum.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/EpisodeEnum.cs new file mode 100644 index 00000000..6823376e --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/EpisodeEnum.cs @@ -0,0 +1,23 @@ +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public class EpisodeEnum : EnumerationGraphType + { + public EpisodeEnum() + { + Name = "Episode"; + Description = "One of the films in the Star Wars Trilogy."; + AddValue("NEWHOPE", "Released in 1977.", 4); + AddValue("EMPIRE", "Released in 1980.", 5); + AddValue("JEDI", "Released in 1983.", 6); + } + } + + public enum Episodes + { + NEWHOPE = 4, + EMPIRE = 5, + JEDI = 6 + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanInputType.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanInputType.cs new file mode 100644 index 00000000..c44c381c --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanInputType.cs @@ -0,0 +1,14 @@ +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public class HumanInputType : InputObjectGraphType + { + public HumanInputType() + { + Name = "HumanInput"; + Field>("name"); + Field("homePlanet"); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanType.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanType.cs new file mode 100644 index 00000000..93da8165 --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/HumanType.cs @@ -0,0 +1,30 @@ +using GraphQL.Client.Tests.Common.StarWars.Extensions; +using GraphQL.Types; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public class HumanType : ObjectGraphType + { + public HumanType(StarWarsData data) + { + Name = "Human"; + + Field>("id", "The id of the human.", resolve: context => context.Source.Id); + Field("name", "The name of the human.", resolve: context => context.Source.Name); + + Field>("friends", resolve: context => data.GetFriends(context.Source)); + + Connection() + .Name("friendsConnection") + .Description("A list of a character's friends.") + .Bidirectional() + .Resolve(context => context.GetPagedResults(data, context.Source.Friends)); + + Field>("appearsIn", "Which movie they appear in."); + + Field("homePlanet", "The home planet of the human.", resolve: context => context.Source.HomePlanet); + + Interface(); + } + } +} diff --git a/tests/GraphQL.Client.Tests.Common/StarWars/Types/StarWarsCharacter.cs b/tests/GraphQL.Client.Tests.Common/StarWars/Types/StarWarsCharacter.cs new file mode 100644 index 00000000..b39d4cdc --- /dev/null +++ b/tests/GraphQL.Client.Tests.Common/StarWars/Types/StarWarsCharacter.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace GraphQL.Client.Tests.Common.StarWars.Types +{ + public abstract class StarWarsCharacter + { + public string Id { get; set; } + public string Name { get; set; } + public List Friends { get; set; } + public int[] AppearsIn { get; set; } + public string Cursor { get; set; } + } + + public class Human : StarWarsCharacter + { + public string HomePlanet { get; set; } + } + + public class Droid : StarWarsCharacter + { + public string PrimaryFunction { get; set; } + } +} diff --git a/tests/GraphQL.Integration.Tests/QueryAndMutationTests/Base.cs b/tests/GraphQL.Integration.Tests/QueryAndMutationTests/Base.cs index 5855e626..b1f56e62 100644 --- a/tests/GraphQL.Integration.Tests/QueryAndMutationTests/Base.cs +++ b/tests/GraphQL.Integration.Tests/QueryAndMutationTests/Base.cs @@ -9,6 +9,7 @@ using GraphQL.Client.Tests.Common.Chat.Schema; using GraphQL.Client.Tests.Common.Helpers; using GraphQL.Client.Tests.Common.StarWars; +using GraphQL.Client.Tests.Common.StarWars.TestData; using GraphQL.Integration.Tests.Helpers; using Microsoft.Extensions.DependencyInjection; using Xunit; diff --git a/tests/IntegrationTestServer/IntegrationTestServer.csproj b/tests/IntegrationTestServer/IntegrationTestServer.csproj index 2eaf45ba..fab13b6e 100644 --- a/tests/IntegrationTestServer/IntegrationTestServer.csproj +++ b/tests/IntegrationTestServer/IntegrationTestServer.csproj @@ -11,7 +11,6 @@ - diff --git a/tests/IntegrationTestServer/Startup.cs b/tests/IntegrationTestServer/Startup.cs index 5faae7f7..f41856d7 100644 --- a/tests/IntegrationTestServer/Startup.cs +++ b/tests/IntegrationTestServer/Startup.cs @@ -1,11 +1,10 @@ using GraphQL; using GraphQL.Client.Tests.Common; using GraphQL.Client.Tests.Common.Chat.Schema; +using GraphQL.Client.Tests.Common.StarWars; using GraphQL.Server; using GraphQL.Server.Ui.Altair; using GraphQL.Server.Ui.GraphiQL; -using GraphQL.Server.Ui.Playground; -using GraphQL.StarWars; using GraphQL.Types; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting;