[InlineData(200, 100, 1, 10, true, ErrorCode.PendingReservationExists)]           //exists pending reservation
        public async Task BookCarReservationAsync_InvalidReservation_ThrowsCustomException(long carId, long clientId, int pickupHours, int returnHours, bool hasReservation, ErrorCode errorCode)
        {
            //Arrange
            var rentalRateFee       = 10;
            var depositFee          = 0.5m;
            var cancellationRateFee = 5;

            var mockedReservationRepository = hasReservation ? GetReservationRepositoryWithPendingReservation() : GetReservationRepositoryWithoutReservation();
            var mockedCarRepository         = GetCarRepositoryWithCar(200, rentalRateFee, depositFee, cancellationRateFee);
            var mockedClientRepository      = GetClientRepositoryWithClient(100);
            var bl = new BLReservation(mockedReservationRepository, mockedCarRepository, mockedClientRepository, mockedUnitOfWork);

            var pickupDateTime = DateTime.Now.AddHours(pickupHours);
            var returnDateTime = DateTime.Now.AddHours(returnHours);
            var parameters     = new BookCarReservationParameters()
            {
                CarId          = carId,
                ClientId       = clientId,
                PickUpDateTime = pickupDateTime,
                ReturnDateTime = returnDateTime
            };

            //Act
            async Task act() => await bl.BookCarReservationAsync(parameters);

            //Assert
            var exception = await Assert.ThrowsAsync <CustomException>(act);

            Assert.Equal(errorCode, exception.code);
        }
        public async Task PickUpCarAsync_Valid_UpdatesReservationState()
        {
            //Arrange
            var mockedReservationRepository = GetReservationRepositoryWithReservation(50, ReservationState.Booked);
            var bl = new BLReservation(mockedReservationRepository, null, null, mockedUnitOfWork);

            //Act
            var reservation = await bl.PickUpCarAsync(50);

            //Assert
            Assert.Equal(ReservationState.PickedUp, reservation.State);
        }
        public async Task CancelCarReservationAsync_Valid_UpdatesReservationStateAndRentalFeePaid()
        {
            //Arrange
            var mockedReservationRepository = GetReservationRepositoryWithReservation(50, ReservationState.Booked);
            var bl = new BLReservation(mockedReservationRepository, null, null, mockedUnitOfWork);

            //Act
            var reservation = await bl.CancelCarReservationAsync(50);

            //Assert
            Assert.Equal(ReservationState.Cancelled, reservation.State);
            Assert.Equal(5, reservation.ClientAccount.CancellationFeePaid);
        }
        public async Task ReturnCarAsync_Invalid_ThrowsCustomException(long reservationIdToReturn, long reservationIdInDb, ReservationState previousState, ErrorCode errorCode)
        {
            //Arrange
            var mockedReservationRepository = GetReservationRepositoryWithReservation(reservationIdInDb, previousState);
            var bl = new BLReservation(mockedReservationRepository, null, null, mockedUnitOfWork);

            //Act
            async Task act() => await bl.ReturnCarAsync(reservationIdToReturn);

            //Assert
            var exception = await Assert.ThrowsAsync <CustomException>(act);

            Assert.Equal(errorCode, exception.code);
        }
        public async Task BookCarReservationAsync_ValidReservation_CreatesNewReservation()
        {
            //Arrange
            var carId               = 200;
            var clientId            = 100;
            var rentalRateFee       = 10;
            var depositFee          = 0.5m;
            var cancellationRateFee = 5;

            var mockedReservationRepository = GetReservationRepositoryWithoutReservation();
            var mockedCarRepository         = GetCarRepositoryWithCar(carId, rentalRateFee, depositFee, cancellationRateFee);
            var mockedClientRepository      = GetClientRepositoryWithClient(clientId);
            var bl = new BLReservation(mockedReservationRepository, mockedCarRepository, mockedClientRepository, mockedUnitOfWork);

            var pickupDateTime = DateTime.Now.AddHours(1);
            var returnDateTime = pickupDateTime.AddHours(10).AddMinutes(30);
            var parameters     = new BookCarReservationParameters()
            {
                CarId          = 200,
                ClientId       = 100,
                PickUpDateTime = pickupDateTime,
                ReturnDateTime = returnDateTime
            };

            //Act
            var reservation = await bl.BookCarReservationAsync(parameters);

            //Assert
            Assert.Equal(10.5m, reservation.DurationInHours);
            Assert.Equal(pickupDateTime, reservation.PickUpDateTime);
            Assert.Equal(returnDateTime, reservation.ReturnDateTime);
            Assert.Equal(carId, reservation.Car.Id);
            Assert.Equal(clientId, reservation.Client.Id);
            Assert.Equal(ReservationState.Booked, reservation.State);
            Assert.Equal(reservation.Car.Type.CancellationRateFee, reservation.ClientAccount.CancellationFeeValueAtBookingMoment);
            Assert.Equal(reservation.Car.Type.RentalRateFee, reservation.ClientAccount.RentalRateFeeValueAtBookingMoment);
            Assert.Equal(reservation.DurationInHours * rentalRateFee * depositFee, reservation.ClientAccount.DepositFeePaid);
        }