public async Task TestCancelAsync_WithStartedWorkout_ShouldThrowInvOpEx()
        {
            var testUserId    = "TrainConnectedUserId1";
            var testCoachId   = "TestCoachId1";
            var testWorkoutId = "TestWorkoutId";
            var testPrice     = 15.00m;

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testUserId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testCoachId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.workoutsRepository.AddAsync(new Workout
            {
                Id              = testWorkoutId,
                CoachId         = testCoachId,
                Time            = DateTime.Now.AddDays(1),
                MaxParticipants = 10,
            });

            await this.workoutsRepository.SaveChangesAsync();

            await this.paymentMethodsRepository.AddAsync(new PaymentMethod
            {
                Name             = "cash",
                PaymentInAdvance = true,
            });

            await this.paymentMethodsRepository.SaveChangesAsync();

            var testInput = new BookingCreateInputModel()
            {
                WorkoutId     = testWorkoutId,
                PaymentMethod = "cash",
                Price         = testPrice,
            };

            await this.bookingsService.CreateAsync(testInput, testUserId);

            var bookingPopulateInDb = await this.bookingsRepository.All()
                                      .Where(x => x.WorkoutId == testWorkoutId)
                                      .Where(p => p.TrainConnectedUserId == testUserId)
                                      .FirstOrDefaultAsync();

            Assert.NotNull(bookingPopulateInDb);
            Assert.Equal(testUserId, bookingPopulateInDb.TrainConnectedUserId);
            Assert.Equal(testWorkoutId, bookingPopulateInDb.WorkoutId);

            await Assert.ThrowsAsync <InvalidOperationException>(async() => await this.bookingsService.CancelAsync(bookingPopulateInDb.Id));
        }
        public async Task TestCreateAsync_WithCorrectData_ShouldCreateBooking()
        {
            var testUserId    = "TrainConnectedUserId1";
            var testCoachId   = "TestCoachId1";
            var testWorkoutId = "TestWorkoutId";
            var testPrice     = 15.00m;

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testUserId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testCoachId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.workoutsRepository.AddAsync(new Workout
            {
                Id              = testWorkoutId,
                CoachId         = testCoachId,
                Time            = DateTime.Now.AddDays(1),
                MaxParticipants = 10,
            });

            await this.workoutsRepository.SaveChangesAsync();

            await this.paymentMethodsRepository.AddAsync(new PaymentMethod
            {
                Name             = "cash",
                PaymentInAdvance = true,
            });

            await this.paymentMethodsRepository.SaveChangesAsync();

            var testInput = new BookingCreateInputModel()
            {
                WorkoutId     = testWorkoutId,
                PaymentMethod = "cash",
                Price         = testPrice,
            };

            await this.bookingsService.CreateAsync(testInput, testUserId);

            var actualResult = await this.bookingsRepository.All()
                               .Where(x => x.WorkoutId == testWorkoutId)
                               .Where(p => p.TrainConnectedUserId == testUserId)
                               .FirstOrDefaultAsync();

            Assert.NotNull(actualResult);
            Assert.Equal(testUserId, actualResult.TrainConnectedUserId);
            Assert.Equal(testWorkoutId, actualResult.WorkoutId);
        }
        public async Task TestCreateAsync_WithFullWorkout_ShouldThrowInvOpEx()
        {
            var testUserId    = "TrainConnectedUserId1";
            var testCoachId   = "TestCoachId1";
            var testWorkoutId = "TestWorkoutId";
            var testPrice     = 15.00m;

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testUserId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testCoachId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.workoutsRepository.AddAsync(new Workout
            {
                Id      = testWorkoutId,
                CoachId = testCoachId,
                Time    = DateTime.Now.AddDays(1),
            });

            await this.workoutsRepository.SaveChangesAsync();

            await this.paymentMethodsRepository.AddAsync(new PaymentMethod
            {
                Name             = "cash",
                PaymentInAdvance = true,
            });

            await this.paymentMethodsRepository.SaveChangesAsync();

            var testInput = new BookingCreateInputModel()
            {
                WorkoutId     = testWorkoutId,
                PaymentMethod = "cash",
                Price         = testPrice,
            };

            await Assert.ThrowsAsync <InvalidOperationException>(async() => await this.bookingsService.CreateAsync(testInput, testUserId));
        }
        public async Task TestCreateAsync_WithNoPaymentMethodData_ShouldThrowNullRefEx()
        {
            var testUserId    = "TrainConnectedUserId1";
            var testCoachId   = "TestCoachId1";
            var testWorkoutId = "TestWorkoutId";
            var testPrice     = 15.00m;

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testUserId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testCoachId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.workoutsRepository.AddAsync(new Workout
            {
                Id              = testWorkoutId,
                CoachId         = testCoachId,
                Time            = DateTime.Now.AddDays(1),
                MaxParticipants = 10,
            });

            await this.workoutsRepository.SaveChangesAsync();

            var testInput = new BookingCreateInputModel()
            {
                WorkoutId     = testWorkoutId,
                PaymentMethod = "cash",
                Price         = testPrice,
            };

            await Assert.ThrowsAsync <NullReferenceException>(async() => await this.bookingsService.CreateAsync(testInput, testUserId));
        }
        public async Task TestCreateAsync_WithNoWorkoutData_ShouldThrowNullRefEx()
        {
            var testUserId    = "TrainConnectedUserId1";
            var testCoachId   = "TestCoachId1";
            var testWorkoutId = "TestWorkoutId";
            var testPrice     = 15.00m;

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testUserId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.usersRepository.AddAsync(new TrainConnectedUser()
            {
                Id = testCoachId,
            });

            await this.usersRepository.SaveChangesAsync();

            await this.paymentMethodsRepository.AddAsync(new PaymentMethod
            {
                Name             = "cash",
                PaymentInAdvance = true,
            });

            await this.paymentMethodsRepository.SaveChangesAsync();

            var testInput = new BookingCreateInputModel()
            {
                WorkoutId     = testWorkoutId,
                PaymentMethod = "cash",
                Price         = testPrice,
            };

            await Assert.ThrowsAsync <NullReferenceException>(async() => await this.bookingsService.CreateAsync(testInput, testUserId));
        }
        public async Task <IActionResult> Create(BookingCreateInputModel bookingCreateInputModel)
        {
            var userId = this.User.FindFirst(ClaimTypes.NameIdentifier).Value;

            if (!this.ModelState.IsValid)
            {
                WorkoutDetailsViewModel workout;

                workout = await this.workoutsService.GetDetailsAsync(bookingCreateInputModel.WorkoutId, userId);

                var paymentMethodsByType = await this.GetApplicablePaymentMethodsByTypeAsync(workout);

                this.ViewData["workout"] = workout;
                this.ViewData["paymentMethodsInAdvance"] = paymentMethodsByType["paymentMethodsInAdvance"];
                this.ViewData["paymentMethodsOnSite"]    = paymentMethodsByType["paymentMethodsOnSite"];

                return(this.View(bookingCreateInputModel));
            }

            var result = await this.bookingsService.CreateAsync(bookingCreateInputModel, userId);

            return(this.RedirectToAction(nameof(this.Details), new { id = result.Id }));
        }
示例#7
0
        public async Task <BookingDetailsViewModel> CreateAsync(BookingCreateInputModel bookingCreateInputModel, string userId)
        {
            var workout = await this.workoutsRepository.All()
                          .FirstOrDefaultAsync(x => x.Id == bookingCreateInputModel.WorkoutId);

            if (workout == null)
            {
                throw new NullReferenceException(string.Format(ServiceConstants.Workout.NullReferenceWorkoutId, bookingCreateInputModel.WorkoutId));
            }

            var workoutBookings = await this.workoutsRepository.All()
                                  .Where(x => x.Id == bookingCreateInputModel.WorkoutId)
                                  .To <WorkoutDetailsViewModel>()
                                  .Select(b => b.BookingsCount)
                                  .FirstOrDefaultAsync();

            var user = await this.usersRepository.All()
                       .FirstOrDefaultAsync(x => x.Id == userId);

            var paymentMethod = await this.paymentMethodsRepository.All()
                                .FirstOrDefaultAsync(pm => pm.Name == bookingCreateInputModel.PaymentMethod);

            if (paymentMethod == null)
            {
                throw new NullReferenceException(string.Format(ServiceConstants.PaymentMethod.NullReferencePaymentMethodName, bookingCreateInputModel.PaymentMethod));
            }

            /*
             * Check if:
             * 1. Workout has not begun;
             * 2. User is not the coach;
             * 3. Workout is not fully booked;
             * 4. user has not yet booked the workout.
             */
            if (workout.Time <= DateTime.UtcNow ||
                workout.CoachId == userId ||
                workoutBookings >= workout.MaxParticipants ||
                user.Bookings.Any(x => x.WorkoutId == workout.Id))
            {
                throw new InvalidOperationException(string.Format(ServiceConstants.Booking.BookingCriteriaNotMet));
            }

            var booking = new Booking
            {
                TrainConnectedUser   = user,
                TrainConnectedUserId = user.Id,
                PaymentMethod        = paymentMethod,
                Price     = bookingCreateInputModel.Price,
                WorkoutId = workout.Id,
                Workout   = workout,
            };

            await this.trainConnectedUsersWorkoutsRepository.AddAsync(new TrainConnectedUsersWorkouts
            {
                TrainConnectedUserId = user.Id,
                WorkoutId            = workout.Id,
            });

            await this.trainConnectedUsersWorkoutsRepository.SaveChangesAsync();

            await this.bookingsRepository.AddAsync(booking);

            await this.bookingsRepository.SaveChangesAsync();

            if (booking.PaymentMethod.PaymentInAdvance)
            {
                var coachUser = await this.usersRepository.All()
                                .FirstOrDefaultAsync(x => x.Id == workout.CoachId);

                coachUser.Balance += booking.Price;
                this.usersRepository.Update(coachUser);
                await this.usersRepository.SaveChangesAsync();
            }

            var bookingDetailsViewModel = AutoMapper.Mapper.Map <BookingDetailsViewModel>(booking);

            return(bookingDetailsViewModel);
        }