public async void CanConnectTwoSubscriptionsSimultaneously() { var port = NetworkHelpers.GetFreeTcpPortNumber(); var callbackTester = new CallbackMonitor <Exception>(); var callbackTester2 = new CallbackMonitor <Exception>(); using (CreateServer(port)) { var client = WebHostHelpers.GetGraphQLClient(port, serializer: Serializer); var callbackMonitor = client.ConfigureMonitorForOnWebsocketConnected(); await client.InitializeWebsocketConnection(); callbackMonitor.Should().HaveBeenInvokedWithPayload(); Debug.WriteLine("creating subscription stream"); IObservable <GraphQLResponse <MessageAddedSubscriptionResult> > observable1 = client.CreateSubscriptionStream <MessageAddedSubscriptionResult>(SubscriptionRequest, callbackTester.Invoke); IObservable <GraphQLResponse <UserJoinedSubscriptionResult> > observable2 = client.CreateSubscriptionStream <UserJoinedSubscriptionResult>(SubscriptionRequest2, callbackTester2.Invoke); Debug.WriteLine("subscribing..."); var tester = observable1.Monitor(); var tester2 = observable2.Monitor(); const string message1 = "Hello World"; var response = await client.AddMessageAsync(message1).ConfigureAwait(false); response.Data.AddMessage.Content.Should().Be(message1); tester.Should().HaveReceivedPayload() .Which.Data.MessageAdded.Content.Should().Be(message1); var joinResponse = await client.JoinDeveloperUser().ConfigureAwait(false); joinResponse.Data.Join.DisplayName.Should().Be("developer", "because that's the display name of user \"1\""); var payload = tester2.Should().HaveReceivedPayload().Subject; payload.Data.UserJoined.Id.Should().Be("1", "because that's the id we sent with our mutation request"); payload.Data.UserJoined.DisplayName.Should().Be("developer", "because that's the display name of user \"1\""); Debug.WriteLine("disposing subscription..."); tester2.Dispose(); const string message3 = "lorem ipsum dolor si amet"; response = await client.AddMessageAsync(message3).ConfigureAwait(false); response.Data.AddMessage.Content.Should().Be(message3); tester.Should().HaveReceivedPayload() .Which.Data.MessageAdded.Content.Should().Be(message3); // disposing the client should complete the subscription client.Dispose(); tester.Should().HaveCompleted(); } }
public async void PreprocessHttpRequestMessageIsCalled() { var callbackTester = new CallbackMonitor <HttpRequestMessage>(); var graphQLRequest = new GraphQLHttpRequest($"{{ human(id: \"1\") {{ name }} }}") { PreprocessHttpRequestMessage = callbackTester.Invoke }; var defaultHeaders = StarWarsClient.HttpClient.DefaultRequestHeaders; var response = await StarWarsClient.SendQueryAsync(graphQLRequest, () => new { Human = new { Name = string.Empty } }); callbackTester.Should().HaveBeenInvokedWithPayload().Which.Headers.Should().BeEquivalentTo(defaultHeaders); Assert.Null(response.Errors); Assert.Equal("Luke", response.Data.Human.Name); }
public async void PreprocessHttpRequestMessageIsCalled() { var callbackTester = new CallbackMonitor <HttpRequestMessage>(); var graphQLRequest = new GraphQLHttpRequest($"{{ human(id: \"1\") {{ name }} }}") { PreprocessHttpRequestMessage = callbackTester.Invoke }; using (var setup = SetupTest()) { var defaultHeaders = setup.Client.HttpClient.DefaultRequestHeaders; var response = await setup.Client.SendQueryAsync(graphQLRequest, () => new { Human = new { Name = string.Empty } }) .ConfigureAwait(false); callbackTester.CallbackShouldHaveBeenInvoked(message => { Assert.Equal(defaultHeaders, message.Headers); }); Assert.Null(response.Errors); Assert.Equal("Luke", response.Data.Human.Name); } }
public async void CanHandleConnectionTimeout() { var errorMonitor = new CallbackMonitor <Exception>(); var reconnectBlocker = new ManualResetEventSlim(false); var callbackMonitor = ChatClient.ConfigureMonitorForOnWebsocketConnected(); // configure back-off strategy to allow it to be controlled from within the unit test ChatClient.Options.BackOffStrategy = i => { Debug.WriteLine("back-off strategy: waiting on reconnect blocker"); reconnectBlocker.Wait(); Debug.WriteLine("back-off strategy: reconnecting..."); return(TimeSpan.Zero); }; var websocketStates = new ConcurrentQueue <GraphQLWebsocketConnectionState>(); using (ChatClient.WebsocketConnectionState.Subscribe(websocketStates.Enqueue)) { websocketStates.Should().ContainSingle(state => state == GraphQLWebsocketConnectionState.Disconnected); Debug.WriteLine($"Test method thread id: {Thread.CurrentThread.ManagedThreadId}"); Debug.WriteLine("creating subscription stream"); var observable = ChatClient.CreateSubscriptionStream <MessageAddedSubscriptionResult>(_subscriptionRequest, errorMonitor.Invoke); Debug.WriteLine("subscribing..."); var observer = observable.Observe(); callbackMonitor.Should().HaveBeenInvokedWithPayload(); websocketStates.Should().ContainInOrder( GraphQLWebsocketConnectionState.Disconnected, GraphQLWebsocketConnectionState.Connecting, GraphQLWebsocketConnectionState.Connected); // clear the collection so the next tests on the collection work as expected websocketStates.Clear(); await observer.Should().PushAsync(1); observer.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(InitialMessage.Content); const string message1 = "Hello World"; var response = await ChatClient.AddMessageAsync(message1); response.Data.AddMessage.Content.Should().Be(message1); await observer.Should().PushAsync(2); observer.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(message1); Debug.WriteLine("stopping web host..."); await Fixture.ShutdownServer(); Debug.WriteLine("web host stopped"); errorMonitor.Should().HaveBeenInvokedWithPayload(10.Seconds()) .Which.Should().BeOfType <WebSocketException>(); websocketStates.Should().Contain(GraphQLWebsocketConnectionState.Disconnected); Debug.WriteLine("restarting web host..."); await InitializeAsync(); Debug.WriteLine("web host started"); reconnectBlocker.Set(); callbackMonitor.Should().HaveBeenInvokedWithPayload(3.Seconds()); await observer.Should().PushAsync(3); observer.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(InitialMessage.Content); websocketStates.Should().ContainInOrder( GraphQLWebsocketConnectionState.Disconnected, GraphQLWebsocketConnectionState.Connecting, GraphQLWebsocketConnectionState.Connected); // disposing the client should complete the subscription ChatClient.Dispose(); await observer.Should().CompleteAsync(5.Seconds()); } }
public async void CanConnectTwoSubscriptionsSimultaneously() { var port = NetworkHelpers.GetFreeTcpPortNumber(); var callbackTester = new CallbackMonitor <Exception>(); var callbackTester2 = new CallbackMonitor <Exception>(); var callbackMonitor = ChatClient.ConfigureMonitorForOnWebsocketConnected(); await ChatClient.InitializeWebsocketConnection(); callbackMonitor.Should().HaveBeenInvokedWithPayload(); Debug.WriteLine("creating subscription stream"); var observable1 = ChatClient.CreateSubscriptionStream <MessageAddedSubscriptionResult>(_subscriptionRequest, callbackTester.Invoke); var observable2 = ChatClient.CreateSubscriptionStream <UserJoinedSubscriptionResult>(_subscriptionRequest2, callbackTester2.Invoke); Debug.WriteLine("subscribing..."); var blocker = new ManualResetEventSlim(false); FluentTestObserver <GraphQLResponse <MessageAddedSubscriptionResult> > messagesMonitor = null; FluentTestObserver <GraphQLResponse <UserJoinedSubscriptionResult> > joinedMonitor = null; var tasks = new List <Task> { Task.Run(() => { blocker.Wait(); messagesMonitor = observable1.Observe(); }), Task.Run(() => { blocker.Wait(); joinedMonitor = observable2.Observe(); }) }; blocker.Set(); await Task.WhenAll(tasks); await messagesMonitor.Should().PushAsync(1); messagesMonitor.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(InitialMessage.Content); const string message1 = "Hello World"; var response = await ChatClient.AddMessageAsync(message1); response.Data.AddMessage.Content.Should().Be(message1); await messagesMonitor.Should().PushAsync(2); messagesMonitor.RecordedMessages.Last().Data.MessageAdded.Content.Should().Be(message1); joinedMonitor.Should().NotPush(); messagesMonitor.Clear(); joinedMonitor.Clear(); var joinResponse = await ChatClient.JoinDeveloperUser(); joinResponse.Data.Join.DisplayName.Should().Be("developer", "because that's the display name of user \"1\""); var payload = await joinedMonitor.Should().PushAsync().GetLastMessageAsync(); using (new AssertionScope()) { payload.Data.UserJoined.Id.Should().Be("1", "because that's the id we sent with our mutation request"); payload.Data.UserJoined.DisplayName.Should().Be("developer", "because that's the display name of user \"1\""); } messagesMonitor.Should().NotPush(); messagesMonitor.Clear(); joinedMonitor.Clear(); Debug.WriteLine("disposing subscription..."); joinedMonitor.Dispose(); const string message3 = "lorem ipsum dolor si amet"; response = await ChatClient.AddMessageAsync(message3); response.Data.AddMessage.Content.Should().Be(message3); var msg = await messagesMonitor.Should().PushAsync().GetLastMessageAsync(); msg.Data.MessageAdded.Content.Should().Be(message3); // disposing the client should complete the subscription ChatClient.Dispose(); await messagesMonitor.Should().CompleteAsync(); }
public async void CanHandleConnectionTimeout() { var port = NetworkHelpers.GetFreeTcpPortNumber(); var server = CreateServer(port); var errorMonitor = new CallbackMonitor <Exception>(); var reconnectBlocker = new ManualResetEventSlim(false); var client = WebHostHelpers.GetGraphQLClient(port, serializer: Serializer); var callbackMonitor = client.ConfigureMonitorForOnWebsocketConnected(); // configure back-off strategy to allow it to be controlled from within the unit test client.Options.BackOffStrategy = i => { reconnectBlocker.Wait(); return(TimeSpan.Zero); }; var websocketStates = new ConcurrentQueue <GraphQLWebsocketConnectionState>(); using (client.WebsocketConnectionState.Subscribe(websocketStates.Enqueue)) { websocketStates.Should().ContainSingle(state => state == GraphQLWebsocketConnectionState.Disconnected); Debug.WriteLine("creating subscription stream"); IObservable <GraphQLResponse <MessageAddedSubscriptionResult> > observable = client.CreateSubscriptionStream <MessageAddedSubscriptionResult>(SubscriptionRequest, errorMonitor.Invoke); Debug.WriteLine("subscribing..."); var tester = observable.Monitor(); callbackMonitor.Should().HaveBeenInvokedWithPayload(); websocketStates.Should().ContainInOrder( GraphQLWebsocketConnectionState.Disconnected, GraphQLWebsocketConnectionState.Connecting, GraphQLWebsocketConnectionState.Connected); // clear the collection so the next tests on the collection work as expected websocketStates.Clear(); const string message1 = "Hello World"; var response = await client.AddMessageAsync(message1).ConfigureAwait(false); response.Data.AddMessage.Content.Should().Be(message1); tester.Should().HaveReceivedPayload() .Which.Data.MessageAdded.Content.Should().Be(message1); Debug.WriteLine("stopping web host..."); await server.StopAsync(CancellationToken.None).ConfigureAwait(false); server.Dispose(); Debug.WriteLine("web host stopped..."); errorMonitor.Should().HaveBeenInvokedWithPayload(TimeSpan.FromSeconds(10)) .Which.Should().BeOfType <WebSocketException>(); websocketStates.Should().Contain(GraphQLWebsocketConnectionState.Disconnected); server = CreateServer(port); reconnectBlocker.Set(); callbackMonitor.Should().HaveBeenInvokedWithPayload(); websocketStates.Should().ContainInOrder( GraphQLWebsocketConnectionState.Disconnected, GraphQLWebsocketConnectionState.Connecting, GraphQLWebsocketConnectionState.Connected); // disposing the client should complete the subscription client.Dispose(); tester.Should().HaveCompleted(TimeSpan.FromSeconds(5)); server.Dispose(); } }