public async Task Notify_all_registered_clients_as_soon_as_it_detects_new_reserved_seats()
        {
            const string showId        = "3";
            var          reservedSeats = new List <string> {
                "A1", "A7"
            };
            var reservationProvider = SetupStubForReservationProvider(showId, reservedSeats);

            var reservationWatcher =
                new ShowReservationsWatcher(showId, reservationProvider, TimeSpan.FromMilliseconds(1));
            await reservationWatcher.Start();

            var client1 = new ClientProxy(showId, "connectionId1", new List <string>(),
                                          PublisherFactory.GetFakePublisher());
            var client2 = new ClientProxy(showId, "connectionId1", new List <string>(),
                                          PublisherFactory.GetFakePublisher());

            await reservationWatcher.RegisterClient(client1);

            await reservationWatcher.RegisterClient(client2);

            Check.That(client1.ReservedSeats).ContainsExactly(reservedSeats);
            Check.That(client2.ReservedSeats).ContainsExactly(reservedSeats);

            // Change the vision of the stub
            reservedSeats.Add("B7");
            reservationProvider.GetReservedSeats(showId).Returns(new ReservedSeatsDto(reservedSeats.ToList()));
            WaitUntilTaskRunHasEnoughTimeToEnd();

            Check.That(client1.ReservedSeats).ContainsExactly(reservedSeats);
            Check.That(client2.ReservedSeats).ContainsExactly(reservedSeats);
        }
Ejemplo n.º 2
0
        public async Task Publish_diff_when_receiving_another_state_of_the_show()
        {
            var showId             = "3";
            var clientConnectionId = "signalR...";
            var topic = TopicBuilder.BuildTopicFor(showId);

            var fakeSignalR      = Substitute.For <IPublishMessages>();
            var publisherFactory = new PublisherFactory(fakeSignalR);
            IObserveReservedSeats clientProxy = new ClientProxy(showId, clientConnectionId, new List <string>(),
                                                                publisherFactory.GetPublisher());

            // Fake a new state of the show reception
            await clientProxy.Notify(new[] { "A1", "B7" });

            // Check that we published those new seats to the client
            var expectedPublication = new[] { "A1", "B7" };
            await fakeSignalR.Received().SendNewlyReservedSeatsAsync(topic, clientConnectionId,
                                                                     Arg.Is <string[]>(x => expectedPublication.SequenceEqual(x)));


            // Fake a new state of the show reception
            await clientProxy.Notify(new[] { "A1", "B2", "B7", "D99" });

            // Only the diff must be published then
            expectedPublication = new[] { "B2", "D99" };
            await fakeSignalR.Received().SendNewlyReservedSeatsAsync(topic, clientConnectionId,
                                                                     Arg.Is <string[]>(x => expectedPublication.SequenceEqual(x)));
        }
        public async Task Not_notify_changes_to_a_client_once_it_has_been_unregistered()
        {
            const string showId = "3";
            var          initialListOfReservedSeats = new List <string> {
                "A1", "A7"
            };
            var reservedSeats       = new List <string>(initialListOfReservedSeats);
            var reservationProvider = Substitute.For <IProvideReservedSeats>();

            reservationProvider.GetReservedSeats(showId).Returns(new ReservedSeatsDto(reservedSeats.ToList()));

            var stubTimer          = new StubTimer();
            var reservationWatcher =
                new ShowReservationsWatcher(showId, reservationProvider, TimeSpan.FromMilliseconds(2), stubTimer);
            await reservationWatcher.Start();

            var client1 = new ClientProxy(showId, "connectionId1", new List <string>(),
                                          PublisherFactory.GetFakePublisher());

            await reservationWatcher.RegisterClient(client1);

            reservationWatcher.UnregisterObserver(client1);

            // Change the vision of the stub
            reservedSeats.Add("B7");
            reservationProvider.GetReservedSeats(showId).Returns(new ReservedSeatsDto(reservedSeats.ToList()));

            stubTimer.ExecuteMethod();
            WaitUntilTaskRunHasEnoughTimeToEnd();

            Check.That(client1.ReservedSeats).ContainsExactly(initialListOfReservedSeats);
        }
        public async Task Instantiate_and_keep_a_ClientProxy_in_the_pool_when_Starting_a_subscription()
        {
            const string showId = "7";

            var proxyPool = new ClientProxyPool(PublisherFactory.GetFakePublisher(),
                                                new ShowReservationsWatcherPool(InstantiateFakeReservationProvider(showId)));
            const string connectionId = "SignalRStuff-45";
            var          initialReservedSeatsAsViewedByTheClient = new List <string> {
                "Z1", "Z27"
            };

            var clientProxy = proxyPool.GetClientProxy(showId, connectionId);

            Check.That(clientProxy).IsNull();

            await proxyPool.StartSubscription(showId, connectionId, initialReservedSeatsAsViewedByTheClient);

            clientProxy = proxyPool.GetClientProxy(showId, connectionId);
            Check.That(clientProxy).IsNotNull();
        }
        public async Task Throw_invalid_operation_exception_when_trying_to_register_a_client_on_unStarted_watcher()
        {
            const string showId = "3";
            var          reservationProvider = SetupStubForReservationProvider(showId, new List <string> {
                "A1", "A7"
            });

            var reservationWatcher =
                new ShowReservationsWatcher(showId, reservationProvider, TimeSpan.FromMilliseconds(1));

            // Here, we forget to start the watcher before we register our first client

            Check.ThatCode(async() =>
            {
                var client1 = new ClientProxy(showId, "connectionId1", new List <string>(),
                                              PublisherFactory.GetFakePublisher());
                await reservationWatcher.RegisterClient(client1);
            }).Throws <InvalidOperationException>()
            .WithMessage(
                $"Must start the {nameof(ShowReservationsWatcher)} instance before being able to register any client.");
        }
        public async Task Remove_the_ClientProxy_from_the_pool_when_ending_its_subscription()
        {
            const string showId    = "7";
            var          proxyPool = new ClientProxyPool(PublisherFactory.GetFakePublisher(),
                                                         new ShowReservationsWatcherPool(InstantiateFakeReservationProvider(showId)));
            const string connectionId = "SignalRStuff-45";

            var clientProxy = proxyPool.GetClientProxy(showId, connectionId);

            Check.That(clientProxy).IsNull();

            await proxyPool.StartSubscription(showId, connectionId, new List <string>());

            clientProxy = proxyPool.GetClientProxy(showId, connectionId);
            Check.That(clientProxy).IsNotNull();

            proxyPool.EndSubscription(showId, connectionId);

            // The client proxy is not within the pool now
            clientProxy = proxyPool.GetClientProxy(showId, connectionId);
            Check.That(clientProxy).IsNull();
        }
        public async Task Provide_current_SeatReservations_to_clients_as_soon_as_they_have_registered()
        {
            const string showId        = "3";
            var          reservedSeats = new List <string> {
                "A1", "A7"
            };
            var reservationProvider = SetupStubForReservationProvider(showId, reservedSeats);

            var reservationWatcher =
                new ShowReservationsWatcher(showId, reservationProvider, TimeSpan.FromMilliseconds(1));
            await reservationWatcher.Start();

            var client1 = new ClientProxy(showId, "connectionId1", new List <string>(),
                                          PublisherFactory.GetFakePublisher());
            var client2 = new ClientProxy(showId, "connectionId2", new List <string>(),
                                          PublisherFactory.GetFakePublisher());

            await reservationWatcher.RegisterClient(client1);

            await reservationWatcher.RegisterClient(client2);

            Check.That(client1.ReservedSeats).ContainsExactly(reservedSeats);
            Check.That(client2.ReservedSeats).ContainsExactly(reservedSeats);
        }
        Register_the_ClientProxy_as_an_observer_of_a_showReservationWatcher_when_Starting_a_subscription()
        {
            const string showId = "7";
            var          showReservationsWatcherPool =
                new ShowReservationsWatcherPool(InstantiateFakeReservationProvider(showId));
            var          proxyPool    = new ClientProxyPool(PublisherFactory.GetFakePublisher(), showReservationsWatcherPool);
            const string connectionId = "SignalRStuff-45";
            var          initialReservedSeatsAsViewedByTheClient = new List <string> {
                "Z1", "Z27"
            };

            var clientProxy = proxyPool.GetClientProxy(showId, connectionId);

            Check.That(clientProxy).IsNull();

            await proxyPool.StartSubscription(showId, connectionId, initialReservedSeatsAsViewedByTheClient);

            clientProxy = proxyPool.GetClientProxy(showId, connectionId);
            Check.That(clientProxy).IsNotNull();

            var watcherForShow7 = showReservationsWatcherPool.GetWatcherForShow(showId);

            Check.That(watcherForShow7.IsObservedBy(clientProxy)).IsTrue();
        }