public void FindAndHoldSeats_SecondTimeWithNotEnoughSeats_ShouldThrowException()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(2, 2);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(3, TestData.TestCustomerEmail);
            ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
        }
        public void FindAndHoldSeats_ThreeSeatHolds_ShouldHaveIncreasingSeatIds()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            SeatHold thirdSeatHold  = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            // Assert
            Assert.IsTrue(firstSeatHold.Id < secondSeatHold.Id);
            Assert.IsTrue(secondSeatHold.Id < thirdSeatHold.Id);
        }
        public void FindAndHoldSeats_FirstHoldReleased_ShouldGiveSecondHoldSameSeats()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.NegativeHoldDuration);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(3, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(3, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(0, secondSeatHold.Seats[0].RowNumber);
            Assert.AreEqual(0, secondSeatHold.Seats[1].RowNumber);
            Assert.AreEqual(0, secondSeatHold.Seats[2].RowNumber);
        }
        public void ReserveSeats_TwoReservations_ShouldHaveDifferentReservationCodes()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            string firstReservationCode  = ticketService.ReserveSeats(firstSeatHold.Id, TestData.TestCustomerEmail);
            string secondReservationCode = ticketService.ReserveSeats(secondSeatHold.Id, TestData.TestCustomerEmail);

            // Assert
            Assert.AreNotEqual(firstReservationCode, secondReservationCode, "Reservation codes should never be the same.");
        }
        public void FindAndHoldSeats_WhenReservationSizeLargerThanAvailableSeatsInEachRow_ShouldSplitGroup()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(2, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
            SeatHold thirdSeatHold  = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(0, thirdSeatHold.Seats[0].RowNumber);
            Assert.AreEqual(2, thirdSeatHold.Seats[0].SeatNumber);
            Assert.AreEqual(1, thirdSeatHold.Seats[1].RowNumber);
            Assert.AreEqual(2, thirdSeatHold.Seats[1].SeatNumber);
        }
        public void FindAndHoldSeats_WhenInsufficientAvailableSeatsInCloserRow_ShouldHoldSeatsInHigherRow()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(0, firstSeatHold.Seats[0].RowNumber);
            Assert.AreEqual(0, firstSeatHold.Seats[1].RowNumber);

            Assert.AreEqual(1, secondSeatHold.Seats[0].RowNumber);
            Assert.AreEqual(1, secondSeatHold.Seats[1].RowNumber);
        }
        public void FindAndHoldSeats_RequestingFewerThanOneSeat_ShouldThrowException(int numSeats)
        {
            // Arrange
            BasicVenue     singleSeatVenue = new BasicVenue(1, 1);
            ITicketService ticketService   = new BasicTicketService(singleSeatVenue, TestData.HourHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(numSeats, TestData.TestCustomerEmail);
        }
        public void FindAndHoldSeats_RequestingMoreSeatsThanAvailable_ShouldThrowException()
        {
            // Arrange
            BasicVenue     singleSeatVenue = new BasicVenue(1, 1);
            ITicketService ticketService   = new BasicTicketService(singleSeatVenue, TestData.HourHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
        }
        public void ReserveSeats_NonRegisteredSeatId_ShouldThrowException()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            ticketService.ReserveSeats(0, TestData.TestCustomerEmail);
        }
        public void ReserveSeats_WithDifferentEmail_ShouldThrowException()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            ticketService.ReserveSeats(seatHold.Id, TestData.SecondTestCustomerEmail);
        }
        public void ReserveSeats_ExpiredSeatHold_ShouldThrowException()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.NegativeHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            ticketService.ReserveSeats(seatHold.Id, TestData.TestCustomerEmail);
        }
        public void FindAndHoldSeats_RequestingOneSeat_ShouldReturnOneSeat()
        {
            // Arrange
            BasicVenue     singleSeatVenue = new BasicVenue(1, 1);
            ITicketService ticketService   = new BasicTicketService(singleSeatVenue, TestData.HourHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(1, seatHold.Seats.Count);
        }
        public void FindAndHoldSeats_FirstHoldExpiresWhileSecondStillValid_ShouldGiveLaterHoldsFirstHoldsSeats()
        {
            // Arrange
            BasicVenue venue = new BasicVenue(3, 3);
            // To mock DateTime.UtcNow, make it so if there are an even number of seats in the seat hold and there are an
            // even number of seat holds, it will expire immediately. Otherwise it will never expire.
            Func <bool, DateTime> dateTimeFunc  = (b => b ? DateTime.MaxValue : DateTime.MinValue);
            ITicketService        ticketService = new BasicTicketService(venue, TestData.HourHoldDuration, getNow: dateTimeFunc);

            // Act
            SeatHold firstSeatHold  = ticketService.FindAndHoldSeats(2, TestData.TestCustomerEmail);
            SeatHold secondSeatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            SeatHold thirdSeatHold  = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            SeatHold fourthSeatHold = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);

            // Assert
            Assert.IsFalse(secondSeatHold.Expired);
            Assert.AreEqual(0, thirdSeatHold.Seats[0].SeatNumber);
            Assert.AreEqual(0, thirdSeatHold.Seats[0].RowNumber);
            Assert.AreEqual(1, fourthSeatHold.Seats[0].SeatNumber);
            Assert.AreEqual(0, fourthSeatHold.Seats[0].RowNumber);
        }
        public void NumSeatsAvailable_AfterReleasingHold_ShouldIncrementAvailableSeats()
        {
            // Arrange
            BasicVenue     singleSeatVenue = new BasicVenue(1, 1);
            ITicketService ticketService   = new BasicTicketService(singleSeatVenue, TestData.NegativeHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            int actualNumSeatsAvailable = ticketService.NumSeatsAvailable();

            // Assert
            Assert.AreEqual(1, actualNumSeatsAvailable, $"The seat should be released when NumSeatsAvailable is called.");
        }
        public void NumSeatsAvailable_AfterHoldingAllSeats_ShouldReturnNoAvailableSeats()
        {
            // Arrange
            BasicVenue     oneRowFiveSeatsVenue = new BasicVenue(1, 5);
            ITicketService ticketService        = new BasicTicketService(oneRowFiveSeatsVenue, TestData.HourHoldDuration);

            // Act
            ticketService.FindAndHoldSeats(5, TestData.TestCustomerEmail);
            int actualNumSeatsAvailable = ticketService.NumSeatsAvailable();

            // Assert
            Assert.AreEqual(0, actualNumSeatsAvailable);
        }
        public void ReserveSeats_ValidSeatHold_ShouldReserveSeats()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration, 8);

            // Act
            SeatHold seatHold        = ticketService.FindAndHoldSeats(1, TestData.TestCustomerEmail);
            string   reservationCode = ticketService.ReserveSeats(seatHold.Id, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(8, reservationCode.Length);
        }
        public void FindAndHoldSeats_RequestingThreeSeats_ShouldReturnThreeAdjacentSeats()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(5, 5);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(5, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(0, seatHold.Seats[0].SeatNumber);
            Assert.AreEqual(1, seatHold.Seats[1].SeatNumber);
            Assert.AreEqual(2, seatHold.Seats[2].SeatNumber);
        }
        public void FindAndHoldSeats_WhenReservationSizeLargerThanRowSize_ShouldSplitGroup()
        {
            // Arrange
            BasicVenue     venue         = new BasicVenue(3, 3);
            ITicketService ticketService = new BasicTicketService(venue, TestData.HourHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(4, TestData.TestCustomerEmail);

            // Assert
            Assert.AreEqual(0, seatHold.Seats[0].RowNumber);
            Assert.AreEqual(0, seatHold.Seats[2].RowNumber);
            Assert.AreEqual(1, seatHold.Seats[3].RowNumber);
        }
        public void NumSeatsAvailable_AfterReservingSeatHold_ShouldReturnSameNumberOfAvailableSeats()
        {
            // Arrange
            BasicVenue     oneRowFiveSeatsVenue = new BasicVenue(1, 5);
            ITicketService ticketService        = new BasicTicketService(oneRowFiveSeatsVenue, TestData.HourHoldDuration);

            // Act
            SeatHold seatHold = ticketService.FindAndHoldSeats(3, TestData.TestCustomerEmail);
            int      numSeatsAvailableAfterHold = ticketService.NumSeatsAvailable();

            ticketService.ReserveSeats(seatHold.Id, TestData.TestCustomerEmail);
            int numSeatsAvailableAfterReservation = ticketService.NumSeatsAvailable();

            // Assert
            Assert.AreEqual(2, numSeatsAvailableAfterHold);
            Assert.AreEqual(2, numSeatsAvailableAfterReservation);
        }