Exemple #1
0
        public void CreatePostVoteShouldAddVoteOnPostAndIncreaseOrDecreaseVoteCount()
        {
            var options = new DbContextOptionsBuilder <ApplicationDbContext>()
                          .UseInMemoryDatabase(databaseName: "CreatePostVoteShouldAddVoteOnPostAndIncreaseOrDecreaseVoteCountDB")
                          .Options;

            var dbContext = new ApplicationDbContext(options);

            var commentService = new Mock <ICommentService>();

            var postId = "asdasdasd";

            var post = new Post
            {
                Id        = postId,
                VoteCount = 5,
            };

            var postService = new Mock <IPostService>();

            postService.Setup(x => x.GetPostById(postId)).Returns(post);


            var vote = new VotePost
            {
                PostId   = post.Id,
                UpOrDown = false,
            };

            var voteService = new VoteService(dbContext, postService.Object, commentService.Object);

            voteService.CreatePostVote(vote);

            Assert.Equal(4, post.VoteCount);
        }
Exemple #2
0
        public async Task <IActionResult> Post([FromBody] VotePost v)
        {
            try
            {
                await _repo.SubmitVoteAsync(v, Request.HttpContext.Connection.RemoteIpAddress.ToString());

                return(StatusCode(201));
            }
            catch (TooManyVotesException)
            {
                return(StatusCode(403));
            }
            catch (LowIntegrityVotingException)
            {
                return(StatusCode(403));
            }
            catch (InvalidVoteException)
            {
                return(StatusCode(400));
            }
            catch (RepeatVoteException)
            {
                return(StatusCode(403));
            }
        }
Exemple #3
0
        public void ChangePostVote(VotePost vote, bool up)
        {
            if (vote == null)
            {
                return;
            }

            var post = this.postService.GetPostById(vote.PostId);

            if (up == true)
            {
                vote.UpOrDown = true;
            }
            else
            {
                vote.UpOrDown = false;
            }

            if (vote.UpOrDown == true)
            {
                post.VoteCount += 2;
            }
            else
            {
                post.VoteCount -= 2;
            }

            this.context.SaveChanges();
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="topicId"></param>
        /// <param name="votes"></param>
        public List <Vote> Vote(string topicId, VotePost votes)
        {
            // 获取这个人所有的投票
            // 清除原来的票
            // 投新票

            if (string.IsNullOrEmpty(votes.uid))
            {
                throw new ArgumentNullException("wechat id");
            }

            var userVotes = GetUserVotes(topicId, votes.uid);

            if (Connection.State == System.Data.ConnectionState.Closed)
            {
                Connection.Open();
            }

            var trans = Connection.BeginTransaction();

            try {
                #region - 清除voteUser在主题topicId下的所有投票结果
                foreach (var vote in userVotes)
                {
                    Connection.Execute(SQL_VOTE_DECREASE_OPTION_VOTE, new { topicId = vote.Topic.Id, subjectId = vote.Subject.Id, optionId = vote.Option.Id }, trans);
                }
                Connection.Execute(SQL_TOPIC_REMOVE_VOTES, new { topicId, voteUser = votes.uid }, trans);
                userVotes.Clear();
                #endregion

                for (var i = 0; i < votes.subs.Count(); i++)
                {
                    var subject = votes.subs[i];
                    for (var j = 0; j < subject.ops.Count(); j++)
                    {
                        var option = subject.ops[j];
                        if (option.order <= 0)
                        {
                            option.order = Option.DefaultOrder;
                        }
                        Connection.Execute(SQL_TOPIC_VOTE, new { TopicId = topicId, SubjectId = subject.id, OptionId = option.id, VoteUser = votes.uid, VoteOrder = option.order }, trans);
                        Connection.Execute(SQL_VOTE_INCREASE_OPTION_VOTE, new { topicId, subjectId = subject.id, optionId = option.id }, trans);
                    }
                }
                trans.Commit();
                return(userVotes);
            }
            catch (Exception ex) {
                trans.Rollback();
                throw ex;
            }
            finally {
                trans.Dispose();
                Connection.Close();
            }
        }
        private VotePost CreateVotePost(User user, Post post)
        {
            var dbVotePost = new VotePost()
            {
                User = user,
                Post = post
            };

            return(dbVotePost);
        }
        private VotePost CreatePost(string userId, string postId)
        {
            var dbVotePost = new VotePost()
            {
                UserId = userId,
                PostId = postId
            };

            return(dbVotePost);
        }
 public IHttpActionResult Vote(string id, [FromBody] VotePost voteBody)
 {
     try {
         voteService = new VoteService();
         return(Ok(voteService.Vote(id, voteBody)));
     }
     catch (Exception ex) {
         log.Error(ex);
         return(InternalServerError(ex));
     }
 }
        internal IUserVotePostService GetService(User user, Post post, VotePost votePost)
        {
            var unitOfWork = this.GetRedditCloneUnitOfWork();

            unitOfWork.Users.Add(user);
            unitOfWork.Posts.Add(post);
            unitOfWork.VotePostRepository.Add(votePost);
            unitOfWork.Complete();

            var service = this.GetService(unitOfWork, user.Id);

            return(service);
        }
 private bool IsDownVoteValid(VotePost votePost)
 {
     if (votePost == null)
     {
         return(false);
     }
     if (votePost.Value >= 0)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Exemple #10
0
        public void CreatePostVote(VotePost vote)
        {
            this.context.VotePosts.Add(vote);

            var post = this.postService.GetPostById(vote.PostId);

            if (vote.UpOrDown == true)
            {
                post.VoteCount++;
            }
            else
            {
                post.VoteCount--;
            }

            this.context.SaveChanges();
        }
Exemple #11
0
        public void DeletePostVote(VotePost vote)
        {
            if (vote == null)
            {
                return;
            }

            var post = this.postService.GetPostById(vote.PostId);

            if (vote.UpOrDown == true)
            {
                post.VoteCount--;
            }
            else
            {
                post.VoteCount++;
            }

            this.context.VotePosts.Remove(vote);
            this.context.SaveChanges();
        }
Exemple #12
0
        public async Task VoteAsync(int postId, string userId, bool isUpVote)
        {
            var postVote = this.postRepository.All()
                           .FirstOrDefault(x => x.PostId == postId && x.UserId == userId);

            if (postVote != null)
            {
                postVote.Type = isUpVote ? VoteType.UpVote : VoteType.DownVote;
            }
            else
            {
                postVote = new VotePost
                {
                    PostId = postId,
                    UserId = userId,
                    Type   = isUpVote ? VoteType.UpVote : VoteType.DownVote
                };

                await this.postRepository.AddAsync(postVote);
            }
            await this.postRepository.SaveChangesAsync();
        }
Exemple #13
0
        public IActionResult VotePost([FromBody] VoteInputModel model)
        {
            var currentUser = this.userService.GetUserByName(this.User.Identity.Name);
            var post        = this.postService.GetPostById(model.Id);
            var userVote    = this.voteService.GetVotePostById(post.Id, currentUser.Id);

            if (model.VoteDown != model.VoteUp && userVote == null)
            {
                var vote = new VotePost
                {
                    PostId = model.Id,
                    UserId = currentUser.Id,
                };

                if (model.VoteUp == true)
                {
                    vote.UpOrDown = true;
                }
                else if (model.VoteDown == true)
                {
                    vote.UpOrDown = false;
                }

                this.voteService.CreatePostVote(vote);
            }
            else if (model.VoteDown != model.VoteUp && userVote != null)
            {
                this.voteService.ChangePostVote(userVote, model.VoteUp);
            }
            else if (model.VoteDown == model.VoteUp && userVote != null)
            {
                this.voteService.DeletePostVote(userVote);
            }

            return(new JsonResult(post.VoteCount.ToString()));
        }
Exemple #14
0
        // POST: api/Vote
        public StatusCodeResult Post([FromBody] VotePost v)
        {
            int ipId = GetIpId();


            // Make sure the call isn't malformed

            if (!ModelState.IsValid || v.WinId == v.LoseId)
            {
                //return BadRequest();
                return(StatusCode(400));
            }


            // Check if the player names are valid

            if (!_context.Players.Where(x => x.Id == v.WinId).Any() ||
                !_context.Players.Where(x => x.Id == v.LoseId).Any())
            {
                //return BadRequest();
                return(StatusCode(400));
            }


            // Check if the user has made this vote combination before

            bool hasUserMadeThisVote = (from votes in _context.Votes
                                        where votes.IpId == ipId &&
                                        votes.WinId == v.WinId &&
                                        votes.LoseId == v.LoseId
                                        select votes).Any();

            bool hasUserMadeOppositeVote = (from votes in _context.Votes
                                            where votes.IpId == ipId &&
                                            votes.WinId == v.LoseId &&
                                            votes.LoseId == v.WinId
                                            select votes).Any();

            if (hasUserMadeThisVote || hasUserMadeOppositeVote)
            {
                //return Forbid();
                return(StatusCode(403));
            }


            // Prepare data

            Player playerWin  = _context.Players.Where(x => x.Id == v.WinId).SingleOrDefault();
            Player playerLose = _context.Players.Where(x => x.Id == v.LoseId).SingleOrDefault();

            _context.Update(playerWin);
            _context.Update(playerLose);


            // Update vote counts

            playerWin.Wins++;
            playerLose.Losses++;


            // Calculate change in player rating

            int oldWinRating  = playerWin.Shitlo;
            int oldLoseRating = playerLose.Shitlo;
            int ratingDiff    = Math.Abs(oldWinRating - oldLoseRating);

            const int MIN_CHANGE  = 1;                  // Minimum rating change for a comparison
            const int MAX_CHANGE  = 50;                 // Maximum rating change for a comparison
            const int EVEN_CHANGE = 15;                 // Rating change for an even comparison

            const double EULERS_NUMBER      = 2.71828;  //                                       |   1000 beats 1000 -> +/- 15
            const double EXPECTED_SCALING   = -0.00264; // k value of    15 e^(-k 500) = 4       |   1500 beats 1000 -> +/- 4
            const double UNEXPECTED_SCALING = 0.00240;  // k value of    15 e^( k 500) = 50      |   1000 beats 1500 -> +/- 50

            double CalcRatingChange(double scaling)
            {
                return(EVEN_CHANGE * Math.Pow(EULERS_NUMBER, scaling * ratingDiff));
            }                                                                                                                                                                                                   // Ae^(kx), HUGE thanks to Itheory and Eight Bit for the formula & helping me implement it.

            int change = Convert.ToInt32((oldWinRating >= oldLoseRating) ? Math.Max(CalcRatingChange(EXPECTED_SCALING), MIN_CHANGE)                                                                             // Expected result
                                                                                                                                                 : Math.Min(CalcRatingChange(UNEXPECTED_SCALING), MAX_CHANGE)); // Unexpected result

            playerWin.Shitlo  = oldWinRating + change;
            playerLose.Shitlo = oldLoseRating - change;


            // Save vote to database

            Vote vote = new Vote
            {
                Date   = DateTime.Now,
                IpId   = ipId,
                WinId  = v.WinId,
                LoseId = v.LoseId
            };

            _context.Votes.Add(vote);


            // Send this vote to subscribed clients

            _hub.Clients.All.SendAsync("recentvote", new string[] { playerWin.Name, playerLose.Name });


            // Commit changes & return success

            _context.SaveChanges();             // TODO: return different status code if this fails

            //return Ok();
            return(StatusCode(201));
        }
 internal void AddEnitytiesToUnitOfWork(IRedditCloneUnitOfWork unitOfWork, User user, Post post, VotePost votePost)
 {
     this.AddEnitytiesToUnitOfWork(unitOfWork, user, post);
     unitOfWork.VotePostRepository.Add(votePost);
     unitOfWork.Complete();
 }
Exemple #16
0
        public async Task SubmitVoteAsync(VotePost v, string ip)
        {
            User user = await IdentifyUserAsync(ip);


            // Make sure they're allowed to vote

            if (user.VoteLimit >= _ALLOWED_VOTES_PER_MINUTE)             // Haven't voted more than X times per minute
            {
                throw new TooManyVotesException();
            }

            if (user.AntiTamper >= _ANTI_TAMPERING_THRESHOLD)             // Haven't made too many "troll" votes
            {
                throw new LowIntegrityVotingException();
            }


            // Make sure the call isn't malformed

            if (v.WinId == v.LoseId)
            {
                throw new InvalidVoteException();
            }


            // Check if the player names are valid

            if (!_context.Players.Where(x => x.Id == v.WinId).Any() ||
                !_context.Players.Where(x => x.Id == v.LoseId).Any())
            {
                throw new InvalidVoteException();
            }


            // Disable vote flooding

            Vote latestVote = await _context.Votes.LastAsync();

            if (v.WinId == latestVote.WinId || _ANTI_FLOOD)
            {
                throw new TooManyVotesException();
            }


            // Make player instances

            Player playerWin  = _context.Players.Where(x => x.Id == v.WinId).SingleOrDefault();
            Player playerLose = _context.Players.Where(x => x.Id == v.LoseId).SingleOrDefault();


            // Check if the player roles are valid

            if (playerWin.Role != playerLose.Role)
            {
                throw new InvalidVoteException();
            }


            // Check if the user has made this vote combination before

            bool hasUserMadeThisVote =
                (from votes in _context.Votes
                 where votes.UserId == user.Id &&
                 votes.WinId == v.WinId &&
                 votes.LoseId == v.LoseId
                 select votes)
                .Any();

            bool hasUserMadeOppositeVote =
                (from votes in _context.Votes
                 where votes.UserId == user.Id &&
                 votes.WinId == v.LoseId &&
                 votes.LoseId == v.WinId
                 select votes)
                .Any();

            if (hasUserMadeThisVote || hasUserMadeOppositeVote)
            {
                throw new RepeatVoteException();
            }


            // Prepare data

            _context.Update(playerWin);
            _context.Update(playerLose);
            _context.Update(user);


            // Update stats

            playerWin.Wins++;
            playerLose.Losses++;


            // Calculate change in player rating

            int    ratingDiff    = Math.Max(Math.Abs(playerWin.Rating - playerLose.Rating), 100);
            int    maxRatingDiff = Math.Max((int)await this.GetMaxRatingDiffAsync(playerWin.Role), 100);
            double quotient      = ratingDiff / maxRatingDiff;

            const double EULERS_NUMBER       = 2.71828;
            const double MIN_CHANGE_PERCENT  = 0.01;             // Minimum rating change for a comparison
            const double EVEN_CHANGE_PERCENT = 0.025;            // Rating change for an even comparison
            const double MAX_CHANGE_PERCENT  = 0.05;             // Maximum rating change for a comparison

            int ratingChange = 0;

            if (/* Unexpected result */ playerWin.Rating < playerLose.Rating)
            {
                ratingChange = Convert.ToInt32(ratingDiff * Math.Max(EVEN_CHANGE_PERCENT * Math.Pow(EULERS_NUMBER, 2 * Math.Log(MIN_CHANGE_PERCENT / EVEN_CHANGE_PERCENT) * quotient), MIN_CHANGE_PERCENT));
            }
            else             // Expected result
            {
                ratingChange = Convert.ToInt32(ratingDiff * Math.Min(EVEN_CHANGE_PERCENT * Math.Pow(EULERS_NUMBER, 2 * Math.Log(MAX_CHANGE_PERCENT / EVEN_CHANGE_PERCENT) * quotient), MAX_CHANGE_PERCENT));
            }

            playerWin.Rating  += ratingChange;
            playerLose.Rating -= ratingChange;


            // Add vote to database

            _context.Votes.Add(new Vote {
                Date = DateTime.Now, UserId = user.Id, WinId = v.WinId, LoseId = v.LoseId
            });


            // Make this vote show up in everyone's browser

            if (_REAL_TIME_VOTES)
            {
                await _hub.Clients.All.SendAsync("recentvote", new string[] { playerWin.Name, playerLose.Name });
            }


            // Increment user limits

            user.VoteLimit++;

            if (_ANTI_TROLL)
            {
                user.AntiTamper = Convert.ToInt32(user.AntiTamper * Math.Pow(4.64158883361, quotient));
            }


            // Done

            await _context.SaveChangesAsync();
        }