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);
        }
        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 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 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);
        }