Пример #1
0
        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();
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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());
            }
        }
Пример #5
0
        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();
        }
Пример #6
0
        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();
            }
        }