public void ClearingVoteGeneratesRemoveVoteMetric() { // Arrange Guid tokenGuid = Guid.NewGuid(); var existingVote = new Vote() { Choice = new Choice() { Id = 1 }, Poll = new Poll() { UUID = _mainUUID }, Ballot = new Ballot() { TokenGuid = tokenGuid } }; _dummyVotes.Add(existingVote); var ballotRequest = new BallotRequestModel(); // Act _controller.Put(_mainUUID, tokenGuid, ballotRequest); // Assert _mockMetricHandler.Verify(m => m.HandleVoteDeletedEvent(existingVote, _mainUUID), Times.Once()); }
public void PutOnOpenPollWithUnrecognisedTokenIsAllowed() { // Arrange var ballotRequest = new BallotRequestModel() { Votes = new List <VoteRequestModel>() { new VoteRequestModel() { ChoiceId = 1 } } }; // Act _controller.Put(_mainUUID, Guid.NewGuid(), ballotRequest); }
public void PutOnInviteOnlyPollWithUnrecognisedTokenIsForbidden() { // Arrange var ballotRequest = new BallotRequestModel() { Votes = new List <VoteRequestModel>() { new VoteRequestModel() { ChoiceId = 1 } } }; // Act _controller.Put(_tokenUUID, Guid.NewGuid(), ballotRequest); }
public void PutNewVoteGeneratesAddVoteMetric() { // Arrange var ballotRequest = new BallotRequestModel() { Votes = new List <VoteRequestModel>() { new VoteRequestModel() { ChoiceId = 1 } } }; // Act _controller.Put(_mainUUID, Guid.NewGuid(), ballotRequest); // Assert _mockMetricHandler.Verify(m => m.HandleVoteAddedEvent(It.Is <Vote>(v => v.Choice.Id == 1), _mainUUID), Times.Once()); }
public void Put(Guid pollId, Guid tokenGuid, BallotRequestModel ballotRequest) { using (IVotingContext context = _contextFactory.CreateContext()) { if (ballotRequest == null) { ThrowError(HttpStatusCode.BadRequest); } if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } Poll poll = context .Polls .Where(p => p.UUID == pollId) .Include(p => p.Ballots) .Include(p => p.Choices) .SingleOrDefault(); if (poll == null) { ThrowError(HttpStatusCode.NotFound, String.Format("Poll {0} not found", pollId)); } if (poll.ExpiryDateUtc.HasValue && poll.ExpiryDateUtc < DateTime.UtcNow) { ThrowError(HttpStatusCode.Forbidden, String.Format("Poll {0} has expired", pollId)); } foreach (VoteRequestModel voteRequest in ballotRequest.Votes) { if (poll.Choices.All(o => o.Id != voteRequest.ChoiceId)) { ModelState.AddModelError("OptionId", "Option choice not valid for this poll"); } } Ballot ballot = poll .Ballots .SingleOrDefault(t => t.TokenGuid == tokenGuid); if (ballot == null) { if (poll.InviteOnly) { ThrowError(HttpStatusCode.Forbidden, String.Format("Token {0} not valid for this poll", tokenGuid)); } else { ballot = new Ballot() { TokenGuid = tokenGuid }; poll.Ballots.Add(ballot); } } // Poll specific validation IVoteValidator voteValidator = _voteValidatorFactory.CreateValidator(poll.PollType); voteValidator.Validate(ballotRequest.Votes, poll, ModelState); if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } List <Vote> existingVotes = context .Votes .Include(v => v.Poll) .Where(v => v.Ballot.TokenGuid == tokenGuid && v.Poll.UUID == pollId) .ToList(); foreach (Vote contextVote in existingVotes) { _metricHandler.HandleVoteDeletedEvent(contextVote, pollId); context.Votes.Remove(contextVote); } // For some reason, we don't have an addrange function on Entity Framework foreach (VoteRequestModel voteRequest in ballotRequest.Votes) { Choice option = context .Choices .Single(o => o.Id == voteRequest.ChoiceId); Vote modelToVote = ModelToVote(voteRequest, ballot, option, poll); context.Votes.Add(modelToVote); _metricHandler.HandleVoteAddedEvent(modelToVote, pollId); } if (!String.IsNullOrEmpty(ballotRequest.VoterName)) { ballot.VoterName = Regex.Replace(ballotRequest.VoterName, ValidVoterNameRegex, ""); } ballot.HasVoted = true; poll.LastUpdatedUtc = DateTime.UtcNow; context.SaveChanges(); ClientSignaller.SignalUpdate(poll.UUID.ToString()); } }