public async Task <Reservation> BookCarReservationAsync(BookCarReservationParameters parameters) { var clientTask = clientRep.GetAsync(parameters.ClientId); var carTask = carRep.GetAsync(parameters.CarId); var client = await clientTask; var car = await carTask; await ValidateAsync(parameters, car, client); var reservation = new Reservation() { Car = car, Client = client, PickUpDateTime = parameters.PickUpDateTime, ReturnDateTime = parameters.ReturnDateTime, State = ReservationState.Booked }; reservation.ClientAccount = new ClientAccount() { CancellationFeeValueAtBookingMoment = car.Type.CancellationRateFee, RentalRateFeeValueAtBookingMoment = car.Type.RentalRateFee, DepositFeePaid = CalculateDepositFeeToPay(reservation) }; reservationRep.Insert(reservation); await uow.CompleteAsync(); return(reservation); }
[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); }
private async Task ValidateAsync(BookCarReservationParameters parameters, Car car, Client client) { if (car == null) { throw new CustomException($"Unknown Car - Id {parameters.CarId}", ErrorCode.UnknownCar); } if (client == null) { throw new CustomException($"Unknown Client - Id {parameters.ClientId}", ErrorCode.UnknownClient); } if (parameters.PickUpDateTime < DateTime.Now) { throw new CustomException($"PickUpDateTime must be greater than current DateTime", ErrorCode.PickUpDateTimeInThePast); } if (parameters.PickUpDateTime >= parameters.ReturnDateTime) { throw new CustomException($"ReturnDateTime must be greater than PickUpDateTime", ErrorCode.ReturnDateTimeBeforePickUpDateTime); } var pendingReservations = await reservationRep.GetPendingReservationByCarAsync(car.Id, parameters.PickUpDateTime, parameters.ReturnDateTime); if (pendingReservations.Any()) { throw new CustomException($"Car is not available in the selected period - CarId {car.Id} - PickUpDateTime {parameters.PickUpDateTime} - ReturnDateTime {parameters.ReturnDateTime} - Existing pending reservation id {pendingReservations.First().Id}", ErrorCode.PendingReservationExists); } }
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); }