public async Task GetWordsAsyncUserHasOne()
        {
            // arrange
            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await CreateTestContext(context);

            WordSetWordsRequest requestData = new WordSetWordsRequest()
            {
                WordSetId = context.Games.First().GameId
            };
            var request = new AuthorizedRequestObject <WordSetWordsRequest, WordSetWordsReply>(requestData)
            {
                UserId = context.Users.First().UserId
            };

            context.UserWordPairs.Add(new UserWordPair()
            {
                UserId     = context.Users.First().UserId,
                WordPairId = context.Games.First().GameLevels.First().GameLevelWords.First().WordPairId
            });;
            context.SaveChanges();
            // act
            var reply = await new GetMarkedWordsHandler(context).Handle(request);

            // assert
            Assert.Single(reply.Words.Where(d => d.HasAdded.Equals(true)));
            Assert.Single(reply.Words.Where(d => d.HasAdded.Equals(false)));
        }
示例#2
0
        public override async Task <ConfirmEmailReply> HandleRequest(
            AuthorizedRequestObject <ConfirmEmailRequest, ConfirmEmailReply> request,
            CancellationToken cancellationToken = default)
        {
            if (request == null)
            {
                throw new ArgumentNullException($"{nameof(request)} is null");
            }

            var requestData = request.Value;
            var userId      = request.UserId;

            // throw exception if not found
            Account account = await Context.Accounts.FindAsync(userId).ConfigureAwait(false);

            // throw exception if invalid
            EmailVerifies codeValidation = GetValidCode(requestData, userId);

            // this code executed only in valid state
            account.Email = codeValidation.Email;

            var emails = Context.EmailVerifies.OutOfDated(requestData.Code, requestData.Email, userId);

            Context.EmailVerifies.RemoveRange(emails);

            await Context.SaveChangesAsync().ConfigureAwait(false);

            ConfirmEmailReply confirmEmailReply = new ConfirmEmailReply
            {
                Email = codeValidation.Email
            };

            return(confirmEmailReply);
        }
示例#3
0
        public async void RequestContainsExistedWords()
        {
            // arrange
            int userId  = 1;
            int otherId = 2;

            using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            await context.AddAccount(otherId);

            await context.SaveChangesAsync();

            context.Add(CreateUserWordPair(userId, "0", "0-0", 1));
            context.Add(CreateUserWordPair(userId, "1", "1-1", 2));
            context.Add(CreateUserWordPair(otherId, "2", "2-2", 3));
            context.Add(CreateUserWordPair(userId, "3", "3-3", 4));
            await context.SaveChangesAsync();

            // act
            var service     = new GetUserWords(context);
            var requestData = new GetWordsRequest();

            requestData.UserWordpairIds.Add(new int[] { 1, 2, 99, 100 });
            var request = new AuthorizedRequestObject <GetWordsRequest, WordsReply>(requestData)
            {
                UserId = userId
            };
            var reply = await service.HandleRequest(request, default);

            // assert
            Assert.Equal(4, reply.ToAdd[0].UserWordPair);
            Assert.Equal(new int[] { 99, 100 }, reply.ToDelete.ToArray());
        }
示例#4
0
        public async void GetUserWords()
        {
            // arrange
            int userId  = 1;
            int otherId = 2;

            using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            await context.AddAccount(otherId);

            await context.SaveChangesAsync();

            context.Add(CreateUserWordPair(userId, "0", "0-0"));
            context.Add(CreateUserWordPair(userId, "1", "1-1"));
            context.Add(CreateUserWordPair(userId, "3", "3-3"));
            context.Add(CreateUserWordPair(otherId, "2", "2-2"));
            await context.SaveChangesAsync();

            // act
            var service     = new GetUserWords(context);
            var requestData = new GetWordsRequest();
            var request     = new AuthorizedRequestObject <GetWordsRequest, WordsReply>(requestData)
            {
                UserId = userId
            };
            var reply = await service.HandleRequest(request, default);

            // assert
            Assert.Equal(context.UserWordPairs.Where(d => d.UserId == userId).Count(), reply.ToAdd.Count());
            Assert.Empty(reply.ToDelete);
        }
示例#5
0
        public async void DeleteExistedAccount()
        {
            // arrange
            int userId  = 1;
            int otherId = 2;

            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            await context.AddAccount(otherId);

            await context.SaveChangesAsync();

            // act
            var requestObject =
                new AuthorizedRequestObject <DeleteAccountRequest, Empty>(
                    new DeleteAccountRequest()
            {
                Text = "Delete me just for test"
            })
            {
                UserId = userId
            };

            var registration = new DeleteAccount(context);
            await registration.HandleRequest(requestObject).ConfigureAwait(false);

            // assert
            Assert.Single(context.Accounts);
            Assert.Equal(otherId, context.Accounts.First().AccountId);
        }
示例#6
0
        public override async Task <WordsReply> GetWords(GetWordsRequest request, ServerCallContext context)
        {
            var reqestObject = new AuthorizedRequestObject <GetWordsRequest, WordsReply>(request)
            {
                UserId = context.GetHttpContext().User.GetUserId()
            };
            WordsReply reply = await mediator.Send(reqestObject).ConfigureAwait(false);

            return(reply);
        }
示例#7
0
        public async Task <IActionResult> AddWords([FromBody] AddWordsRequest request)
        {
            var reqestObject = new AuthorizedRequestObject <AddWordsRequest, AddWordsReply>(request)
            {
                UserId = User.GetUserId()
            };
            AddWordsReply reply = await mediator.Send(reqestObject).ConfigureAwait(false);

            return(Ok(reply));
        }
示例#8
0
        public async Task <IActionResult> Register(WordSetWordsRequest request)
        {
            var requestObject = new AuthorizedRequestObject <WordSetWordsRequest, WordSetWordsReply>(request)
            {
                UserId = User.GetUserId()
            };
            WordSetWordsReply reply = await mediator.Send(requestObject).ConfigureAwait(false);

            return(Ok(reply));
        }
示例#9
0
        public override async Task <ConfirmEmailReply> ConfirmEmail(ConfirmEmailRequest request, ServerCallContext context)
        {
            var reqestObject = new AuthorizedRequestObject <ConfirmEmailRequest, ConfirmEmailReply>(request)
            {
                UserId = context.GetHttpContext().User.GetUserId()
            };
            ConfirmEmailReply reply = await mediator.Send(reqestObject).ConfigureAwait(false);

            return(reply);
            // TODO: how to return error in grpc
        }
示例#10
0
        public override async Task <EmailChangeReply> RequestEmailUpdate(EmailChangeRequest request, ServerCallContext context)
        {
            var reqestObject = new AuthorizedRequestObject <EmailChangeRequest, EmailChangeReply>(request)
            {
                // TODO: how it works
                UserId = context.GetHttpContext().User.GetUserId()
            };
            EmailChangeReply reply = await mediator.Send(reqestObject).ConfigureAwait(false);

            return(reply);
        }
示例#11
0
        public override async Task <EmailChangeReply> HandleRequest(
            AuthorizedRequestObject <EmailChangeRequest, EmailChangeReply> request,
            CancellationToken cancellationToken = default)
        {
            // TODO: add time change email timelock
            EmailChangeRequest requestValue = request.Value;
            string             email        = requestValue.Email;

            // check if email aldeary linked
            var linkedEmail = Context.Accounts.Any(a => a.Email == email && a.Role > RoleType.Unverified);

            if (linkedEmail)
            {
                request.StatusCode = StatusCode.AlreadyExists;
                request.Detail     = $"Email address '{ email }' is already linked to another account";
                return(new EmailChangeReply());
            }

            ApproveEmailTemplate approveEmailTemplate = new ApproveEmailTemplate();

            try
            {
                await emailTemplateSender.SendMailAsync(email, approveEmailTemplate).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                request.StatusCode = StatusCode.InvalidArgument;
                request.Detail     = $"The mail server could not send the email {email} to the address and threw an error {e.Message}";
                return(new EmailChangeReply());
            }

            // add code
            EmailVerifies emailVerifies = new EmailVerifies()
            {
                Code     = approveEmailTemplate.Code,
                SentTime = DateTime.UtcNow,
                Attempts = 0,
                UserId   = request.UserId,
                Guid     = Guid.Parse(approveEmailTemplate.Link),
                Email    = email
            };

            Context.EmailVerifies.Add(emailVerifies);
            await Context.SaveChangesAsync().ConfigureAwait(false);


            EmailChangeReply confirmReply = new EmailChangeReply
            {
                Email = email
            };

            return(confirmReply);
        }
示例#12
0
        public override async Task <Empty> DeleteAccount(DeleteAccountRequest request, ServerCallContext context)
        {
            CheckIfArgumentIsNull(ref context);

            var reqestObject = new AuthorizedRequestObject <DeleteAccountRequest, Empty>(request)
            {
                UserId = context.GetHttpContext().User.GetUserId()
            };
            Empty reply = await mediator.Send(reqestObject).ConfigureAwait(false);

            if (reqestObject.StatusCode != StatusCode.OK)
            {
                context.Status = new Status(reqestObject.StatusCode, reqestObject.Detail);
            }
            return(reply);
        }
示例#13
0
        public async Task <IActionResult> UpdateEmail([FromBody] EmailChangeRequest request)
        {
            try
            {
                var reqestObject = new AuthorizedRequestObject <EmailChangeRequest, EmailChangeReply>(request)
                {
                    UserId = User.GetUserId()
                };
                EmailChangeReply reply = await mediator.Send(reqestObject).ConfigureAwait(false);

                return(Ok(reply));
            }
            catch (ArgumentNullException e)
            {
                return(BadRequest(e.Message));
            }
        }
示例#14
0
        public async void ResendEmailIfUnverfed()
        {
            string testEmail = "*****@*****.**";

            // arrange
            await using InWordsDataContext context = InWordsDataContextFactory.Create();

            Account account = new Account()
            {
                Email = testEmail, Hash = new byte[255], Role = RoleType.Unverified
            };
            User User = new User()
            {
                Account = account, NickName = "user"
            };

            await context.SaveChangesAsync();

            var mock = new Mock <IEmailTemplateSender>();

            mock.Setup(a => a.SendMailAsync(testEmail, It.IsAny <EmailTemplateBase>()));
            // act
            var registration = new ChangeEmail(context, mock.Object);

            var requestObject = new AuthorizedRequestObject <EmailChangeRequest, EmailChangeReply>(
                new EmailChangeRequest()
            {
                Email = testEmail,
            })
            {
                UserId = account.AccountId
            };

            var test = await registration.HandleRequest(
                new AuthorizedRequestObject <EmailChangeRequest, EmailChangeReply>(
                    new EmailChangeRequest()
            {
                Email = testEmail,
            }))
                       .ConfigureAwait(false);

            // assert
            Assert.Equal(1, context.EmailVerifies.Count());
            mock.Verify(a => a.SendMailAsync(testEmail, It.IsAny <EmailTemplateBase>()), Times.Once());
        }
示例#15
0
        /// <summary>
        /// Delete account by id if exist
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <exception cref="ArgumentNullException">Account not found</exception>
        /// <returns></returns>
        public override async Task <Empty> HandleRequest(
            AuthorizedRequestObject <DeleteAccountRequest, Empty> request,
            CancellationToken cancellationToken = default)
        {
            var     accountId = request.UserId;
            Account account   = await Context.Accounts.FindAsync(accountId).ConfigureAwait(false);

            if (account == default)
            {
                request.StatusCode = StatusCode.NotFound;
            }
            else
            {
                Context.Remove(account);
                await Context.SaveChangesAsync().ConfigureAwait(false);
            }
            return(new Empty());
        }
示例#16
0
        public override Task <WordsReply> HandleRequest(AuthorizedRequestObject <GetWordsRequest, WordsReply> request,
                                                        CancellationToken cancellationToken = default)
        {
            return(Task.Run(() =>
            {
                int userId = request.UserId;
                GetWordsRequest value = request.Value;
                WordsReply reply = new WordsReply();

                HashSet <int> clientIds = value.UserWordpairIds.ToHashSet();
                var serverIds = Context.UserWordPairs.WhereUser(userId).Select(d => d.UserWordPairId).ToHashSet();

                IEnumerable <int> wordsToAdd = serverIds.Except(clientIds);

                IEnumerable <int> wordsToDelete = clientIds.Except(serverIds);
                reply.ToDelete.Add(wordsToDelete);


                var wordReplies = Context.UserWordPairs
                                  .Where(u => wordsToAdd.Any(w => w == u.UserWordPairId))
                                  .Include(d => d.WordPair)
                                  .ThenInclude(w => w.WordForeign)
                                  .Include(d => d.WordPair.WordNative)
                                  .Select(u => new
                {
                    u.UserWordPairId,
                    u.WordPair.WordForeign,
                    u.WordPair.WordNative,
                    u.IsInvertPair,
                    u.LearningPeriod
                }).AsNoTracking();

                var wordReply = wordReplies.Select(w => new WordReply()
                {
                    UserWordPair = w.UserWordPairId,
                    WordNative = w.IsInvertPair ? w.WordNative.Content : w.WordForeign.Content,
                    WordForeign = w.IsInvertPair ? w.WordForeign.Content : w.WordNative.Content,
                    Period = w.LearningPeriod
                });
                reply.ToAdd.Add(wordReply);

                return reply;
            }));
        }
示例#17
0
        public async Task <IActionResult> Delete([FromBody] DeleteAccountRequest request)
        {
            int id = User.GetUserId();

            try
            {
                var reqestObject = new AuthorizedRequestObject <DeleteAccountRequest, Empty>(request)
                {
                    UserId = User.GetUserId()
                };
                await mediator.Send(reqestObject).ConfigureAwait(false);

                return(Ok());
            }
            catch (ArgumentNullException e)
            {
                return(BadRequest(e.Message));
            }
        }
        public async Task GetWordsAsync()
        {
            // arrange
            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await CreateTestContext(context);

            WordSetWordsRequest requestData = new WordSetWordsRequest()
            {
                WordSetId = context.Games.First().GameId
            };
            var request = new AuthorizedRequestObject <WordSetWordsRequest, WordSetWordsReply>(requestData)
            {
                UserId = context.Users.First().UserId
            };

            // act
            var reply = await new GetMarkedWordsHandler(context).Handle(request);

            // assert
            Assert.Equal(2, reply.Words.Count);
        }
示例#19
0
        public async void AddUserWordPair()
        {
            // arrange
            int userId  = 1;
            int otherId = 2;

            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            await context.AddAccount(otherId);

            await context.SaveChangesAsync();

            AddWordsRequest addWordsRequest = new AddWordsRequest();

            addWordsRequest.Words.Add(new AddWordRequest()
            {
                LocalId = 0, WordForeign = "0", WordNative = "0-0"
            });
            addWordsRequest.Words.Add(new AddWordRequest()
            {
                LocalId = 2, WordForeign = "2", WordNative = "2-2"
            });

            // act
            var requestObject = new AuthorizedRequestObject <AddWordsRequest, AddWordsReply>(addWordsRequest)
            {
                UserId = userId
            };

            var           registration = new AddWords(context);
            AddWordsReply response     = await registration.HandleRequest(requestObject).ConfigureAwait(false);

            // assert
            Assert.Equal(4, context.Words.Count());
            Assert.Equal(2, context.WordPairs.Count());
            Assert.Equal(2, context.UserWordPairs.Count());

            CheckPairs(addWordsRequest, response, context, userId);
        }
示例#20
0
        public async void ConfirmValidCode()
        {
            // arrange
            int    userId    = 1;
            int    rightCode = 111111;
            string newEmail  = "*****@*****.**";

            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            context.EmailVerifies.Add(new EmailVerifies()
            {
                UserId = userId,
                Code   = rightCode,
                Email  = newEmail
            });
            await context.SaveChangesAsync();

            Account account = context.Accounts.First();

            // act
            var requestObject =
                new AuthorizedRequestObject <ConfirmEmailRequest, ConfirmEmailReply>(
                    new ConfirmEmailRequest()
            {
                Email = newEmail, Code = rightCode
            })
            {
                UserId = account.AccountId
            };

            var registration = new ConfirmEmail(context);
            var test         = await registration.HandleRequest(requestObject).ConfigureAwait(false);

            // assert
            Assert.Equal(0, context.EmailVerifies.Count());
            Assert.Equal(newEmail, test.Email);
            Assert.Equal(newEmail, context.Accounts.First().Email);
        }
示例#21
0
        public override async Task <AddWordsReply> HandleRequest(
            AuthorizedRequestObject <AddWordsRequest, AddWordsReply> request,
            CancellationToken cancellationToken = default)
        {
            if (request == null)
            {
                throw new ArgumentNullException($"{nameof(request)}");
            }

            int userId      = request.UserId;
            var requestData = request.Value;

            // Add words transation (savechanges)
            List <Word> dataBaseWords = await AddWordsAsync(requestData).ConfigureAwait(false);

            // Add wordPairs transaction
            List <(int, WordPair)> pairsToAdd = SelectWordPairs(requestData, dataBaseWords);
            HashSet <int>          inverted   = Context.WordPairs.AddWordPairs(pairsToAdd.Select(d => d.Item2));
            await Context.SaveChangesAsync().ConfigureAwait(false);

            // Add user's word pair transation
            (int, UserWordPair)[] userWords = ConvertToUserWordPairs(userId, pairsToAdd, inverted).ToArray();
示例#22
0
        public override Task <WordSetWordsReply> HandleRequest(
            AuthorizedRequestObject <WordSetWordsRequest, WordSetWordsReply> request,
            CancellationToken cancellationToken = default)
        {
            return(Task.Run(() =>
            {
                if (request == null)
                {
                    throw new ArgumentNullException($"{request} is null");
                }

                int userId = request.UserId;
                WordSetWordsRequest requestData = request.Value;

                // usersWords
                var usersWords = Context.UserWordPairs.Where(u => u.UserId.Equals(userId));
                // levels in game
                var levelsInSet = Context.GameLevels.Where(g => g.GameId.Equals(requestData.WordSetId));
                var wordsIdInLevels = Context.GameLevelWords.Where(n => levelsInSet.Any(d => d.GameLevelId.Equals(n.GameLevelId)));
                var wordsByWordIds = Context.WordPairs.Where(w => wordsIdInLevels.Any(d => d.WordPairId.Equals(w.WordPairId)));
                var loadedWords = wordsByWordIds
                                  .Include(d => d.WordForeign)
                                  .Include(w => w.WordNative)
                                  .Select(wp => new WordSetWord()
                {
                    WordPairId = wp.WordPairId,
                    WordForeign = wp.WordForeign.Content,
                    WordNative = wp.WordNative.Content,
                    HasAdded = usersWords.Any(d => d.WordPairId.Equals(wp.WordPairId))
                });

                WordSetWordsReply wordSetWordsReply = new WordSetWordsReply();
                wordSetWordsReply.Words.AddRange(loadedWords);

                return wordSetWordsReply;
            }));
        }
示例#23
0
        public async void ConfirmInValidCode()
        {
            // arrange
            int    userId    = 1;
            int    rightCode = 111111;
            int    badCode   = 222222;
            string newEmail  = "*****@*****.**";

            await using InWordsDataContext context = InWordsDataContextFactory.Create();
            await context.AddAccount(userId);

            context.EmailVerifies.Add(new EmailVerifies()
            {
                UserId = userId,
                Code   = rightCode,
                Email  = newEmail
            });
            await context.SaveChangesAsync();

            Account account = context.Accounts.First();

            // act
            var requestObject =
                new AuthorizedRequestObject <ConfirmEmailRequest, ConfirmEmailReply>(
                    new ConfirmEmailRequest()
            {
                Email = newEmail, Code = badCode
            })
            {
                UserId = account.AccountId
            };

            // assert
            var registration = new ConfirmEmail(context);
            await Assert.ThrowsAsync <ArgumentNullException>(() => registration.HandleRequest(requestObject));
        }