public async Task AddAsync_CreateRequestOrderModel_ReturnsOkResponse(CreateRequestOrderModel model, Guid userId)
        {
            //Arrange
            var user = UserDumbData.GetRandomEntity();

            userId = user.Id;
            var order = OrderDumbData.GetRandomEntity();

            model.OrderId = order.Id;
            var enoughXP          = user.XP < order.Price;
            var cancellationToken = new CancellationToken();

            ICollection <string> emailCollection = new List <string> {
                RandomHelper.GetRandomString(),
                                 RandomHelper.GetRandomString(),
            };

            _userRepository.Setup(x => x.GetByIdAsync(It.IsAny <Guid>(), cancellationToken)).Returns(Task.FromResult(user));
            _orderRepository.Setup(x => x.GetByIdAsync(It.IsAny <Guid>(), cancellationToken)).Returns(Task.FromResult(order));
            _userRepository.Setup(x => x.GetAdminsEmailsAsync(cancellationToken)).Returns(Task.FromResult(emailCollection));
            _unitOfWork.Setup(x => x.SaveChangesAsync(cancellationToken)).Returns(Task.CompletedTask);
            _emailService.Setup(x => x.SendEmailsAsync(It.IsAny <string>(), It.IsAny <string>(), cancellationToken, It.IsAny <string[]>())).Returns(Task.CompletedTask);
            string key             = "RequestOrderPage";
            var    localizedString = new LocalizedString(key, key);

            _stringLocalizer.Setup(_ => _[key]).Returns(localizedString);

            // Act
            var response = await _requestOrderService.AddAsync(model, userId, cancellationToken);

            // Assert
            _userRepository.Verify(x => x.GetByIdAsync(It.IsAny <Guid>(), cancellationToken), Times.Once);
            _orderRepository.Verify(x => x.GetByIdAsync(It.IsAny <Guid>(), cancellationToken), Times.Once);
            if (enoughXP)
            {
                response.Should().BeOfType <NotAllowedResponse>();
            }
            else
            {
                _userRepository.Verify(x => x.GetAdminsEmailsAsync(cancellationToken), Times.Once);
                _stringLocalizer.Verify(_ => _[key], Times.Once);
                _unitOfWork.Verify(x => x.SaveChangesAsync(cancellationToken), Times.Once);
                _emailService.Verify(x => x.SendEmailsAsync(It.IsAny <string>(), It.IsAny <string>(), cancellationToken, It.IsAny <string[]>()), Times.Once);
                response.Should().BeOfType <OkResponse>();
            }
        }
        public async Task <IActionResult> AddRequestAsync([FromBody] CreateRequestOrderModel model, CancellationToken cancellationToken)
        {
            var resultValidation = await _requestOrderModelValidator.ValidateAsync(model, cancellationToken);

            resultValidation.AddToModelState(ModelState, null);

            if (!ModelState.IsValid)
            {
                return(UnprocessableEntity(ModelState));
            }

            var result = await _requestOrderService.AddAsync(model, UserId, cancellationToken);

            if (result.Type == GamificationEnums.ResponseType.NotAllowed)
            {
                return(Unauthorized());
            }

            return(Ok());
        }
        public async Task <IResponse> AddAsync(CreateRequestOrderModel model, Guid userId, CancellationToken cancellationToken)
        {
            var user = await _userRepository.GetByIdAsync(userId, cancellationToken);

            var order = await _orderRepository.GetByIdAsync(model.OrderId, cancellationToken);

            if (user.XP < order.Price)
            {
                return(new NotAllowedResponse("The user doesn't have enough XP!"));
            }

            var requestOrderPage = _stringLocalizer["RequestOrderPage"].ToString();
            var pageWithParams   = requestOrderPage.Replace("{userLastName}", user.LastName);

            pageWithParams = pageWithParams.Replace("{userFirstName}", user.FirstName);
            pageWithParams = pageWithParams.Replace("{message}", model.Message);
            pageWithParams = pageWithParams.Replace("{orderTitle}", order.Title);

            var emails = await _userRepository.GetAdminsEmailsAsync(cancellationToken);

            await _emailService.SendEmailsAsync("Request order", pageWithParams, cancellationToken, emails.ToArray());

            var entity = _mapper.Map <RequestOrder>(model);

            entity.UserId = userId;
            entity.Status = GamificationEnums.RequestStatus.Pending;

            user.XP -= order.Price;

            _userRepository.Update(user);

            await _requestOrderRepository.AddAsync(entity, cancellationToken);

            await _unitOfWork.SaveChangesAsync(cancellationToken);

            return(new OkResponse());
        }