protected internal Poll PollByPollId(Guid pollId, IVotingContext context) { Expression <Func <Poll, bool> > predicate = (p => p.UUID == pollId); string errorMessage = string.Format("Poll {0} not found", pollId); return(PollByPredicate(predicate, errorMessage, context)); }
private void RemoveOptions(IVotingContext context, Poll poll, IEnumerable <int> optionsToRemove) { foreach (int pollOptionNumber in optionsToRemove) { Choice option = poll .Choices .Single(o => o.PollChoiceNumber == pollOptionNumber); _metricHandler.HandleChoiceDeletedEvent(option, poll.UUID); poll.Choices.Remove(option); context.Choices.Remove(option); List <Vote> votes = context .Votes .Include(v => v.Choice) .Where(v => v.Choice.PollChoiceNumber == pollOptionNumber) .ToList(); foreach (Vote vote in votes) { Ballot ballot = context .Ballots .Include(b => b.Votes) .Single(b => b.Votes.Any(v => v.Id == vote.Id)); _metricHandler.HandleVoteDeletedEvent(vote, poll.UUID); ballot.Votes.Remove(vote); context.Votes.Remove(vote); } } }
private void StoreEvent(Metric eventToStore) { using (IVotingContext context = _contextFactory.CreateContext()) { context.Metrics.Add(eventToStore); context.SaveChanges(); } }
public ManagePollTypeRequestResponse Get(Guid manageId) { using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByManageId(manageId, context); return(pollToModel(poll)); } }
public List <ManageChoiceResponseModel> Get(Guid manageId) { using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByManageId(manageId, context); return(poll .Choices .Select(CreateOptionResponseModel) .ToList()); } }
private Poll GetPoll(Guid manageId, IVotingContext context) { Poll poll = context .Polls .Include(p => p.Choices) .SingleOrDefault(p => p.ManageId == manageId); if (poll == null) { ThrowError(HttpStatusCode.NotFound, string.Format("Poll for manage id {0} not found", manageId)); } return(poll); }
public CopyPollResponseModel Copy(CopyPollRequestModel pollCopyRequest) { if (pollCopyRequest == null) { ThrowError(HttpStatusCode.BadRequest); } if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } using (IVotingContext context = _contextFactory.CreateContext()) { string userId = User.Identity.GetUserId(); Poll pollToCopy = context .Polls .Include(p => p.Choices) .SingleOrDefault(p => p.UUID == pollCopyRequest.UUIDToCopy); if (pollToCopy == null) { ThrowError(HttpStatusCode.BadRequest); } if (pollToCopy.CreatorIdentity != userId) { ThrowError(HttpStatusCode.Forbidden); } Poll newPoll = CopyPoll(pollToCopy); _metricHandler.HandlePollClonedEvent(newPoll); Ballot creatorBallot = CreateBallotForCreator(); newPoll.Ballots.Add(creatorBallot); context.Polls.Add(newPoll); context.SaveChanges(); return(new CopyPollResponseModel() { NewPollId = newPoll.UUID, NewManageId = newPoll.ManageId, CreatorBallotToken = creatorBallot.TokenGuid }); } }
public PollRequestResponseModel Get(Guid id) { using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByPollId(id, context); Guid?tokenGuid = GetTokenGuidFromHeaders(); if (poll.InviteOnly) { if (!tokenGuid.HasValue) { ThrowError(HttpStatusCode.Unauthorized); } if (poll.Ballots.All(b => b.TokenGuid != tokenGuid.Value)) { ThrowError(HttpStatusCode.Unauthorized); } } Ballot ballot; if (tokenGuid.HasValue) { ballot = poll.Ballots.SingleOrDefault(b => b.TokenGuid == tokenGuid.Value); if (ballot == null) { ThrowError(HttpStatusCode.NotFound); } } else { tokenGuid = Guid.NewGuid(); ballot = new Ballot() { TokenGuid = tokenGuid.Value }; poll.Ballots.Add(ballot); context.Ballots.Add(ballot); context.SaveChanges(); } return(CreateResponse(poll, tokenGuid.Value, ballot)); } }
public void Put(Guid manageId, ManageChoiceUpdateRequest request) { ValidateRequest(request); if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = GetPoll(manageId, context); List <int> existingPollOptionNumbers = GetExistingPollOptionNumbers(poll); List <int> requestPollOptionNumbers = GetRequestPollOptionNumbers(request); if (requestPollOptionNumbers.Except(existingPollOptionNumbers).Any()) { ThrowError(HttpStatusCode.NotFound, String.Format("Options do not all belong to poll {0}", manageId)); } List <int> optionsToRemove = existingPollOptionNumbers .Except(requestPollOptionNumbers) .ToList(); RemoveOptions(context, poll, optionsToRemove); List <int> optionsToUpdate = existingPollOptionNumbers .Intersect(requestPollOptionNumbers) .ToList(); UpdateOptions(request, poll, optionsToUpdate); List <ChoiceUpdate> optionUpdatesToAdd = request .Choices .Where(o => o.ChoiceNumber.HasValue == false) .ToList(); AddNewOptions(context, poll, optionUpdatesToAdd); poll.LastUpdatedUtc = DateTime.UtcNow; context.SaveChanges(); } }
public List <DashboardPollResponseModel> Polls() { using (IVotingContext context = _contextFactory.CreateContext()) { string userId = User.Identity.GetUserId(); IEnumerable <DashboardPollResponseModel> userPolls = context .Polls .Where(p => p.CreatorIdentity == userId) .OrderByDescending(p => p.CreatedDateUtc) .Include(p => p.Choices) .Select(CreateDashboardResponseFromModel); return(userPolls.ToList()); } }
protected internal Poll PollByManageId(Guid manageId, IVotingContext context) { Expression <Func <Poll, bool> > predicate = (p => p.ManageId == manageId); string errorMessage = string.Format("Poll for manage id {0} not found", manageId); Poll poll = PollByPredicate(predicate, errorMessage, context); if (String.IsNullOrEmpty(poll.CreatorIdentity) && !String.IsNullOrEmpty(User.Identity.GetUserId())) { poll.CreatorIdentity = User.Identity.GetUserId(); poll.Creator = User.Identity.GetUserName(); context.SaveChanges(); } return(poll); }
private void AddNewOptions(IVotingContext context, Poll poll, IEnumerable <ChoiceUpdate> optionUpdatesToAdd) { foreach (ChoiceUpdate optionRequest in optionUpdatesToAdd) { var option = new Choice { Name = optionRequest.Name, Description = optionRequest.Description }; _metricHandler.HandleChoiceAddedEvent(option, poll.UUID); poll.Choices.Add(option); context.Choices.Add(option); } }
public void Put(Guid manageId, ManagePollTypeRequest updateRequest) { using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByManageId(manageId, context); PollType pollType; if (!Enum.TryParse <PollType>(updateRequest.PollType, true, out pollType)) { ModelState.AddModelError("PollType", "Invalid PollType"); } if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } if (poll.PollType == pollType) { if (pollType != PollType.Points || (poll.MaxPoints == updateRequest.MaxPoints && poll.MaxPerVote == updateRequest.MaxPerVote)) { return; } } List <Vote> removedVotes = context.Votes.Include(v => v.Poll) .Where(v => v.Poll.UUID == poll.UUID) .ToList(); foreach (Vote oldVote in removedVotes) { _metricHandler.HandleVoteDeletedEvent(oldVote, poll.UUID); context.Votes.Remove(oldVote); } _metricHandler.HandlePollTypeChangedEvent(pollType, updateRequest.MaxPerVote ?? 0, updateRequest.MaxPoints ?? 0, poll.UUID); poll.PollType = pollType; poll.MaxPerVote = updateRequest.MaxPerVote; poll.MaxPoints = updateRequest.MaxPoints; poll.LastUpdatedUtc = DateTime.UtcNow; context.SaveChanges(); } }
public void Setup() { _dummyPolls = new InMemoryDbSet <Poll>(true); var mockContextFactory = new Mock <IContextFactory>(); var mockContext = new Mock <IVotingContext>(); _mockContext = mockContext.Object; mockContextFactory.Setup(a => a.CreateContext()).Returns(_mockContext); mockContext.Setup(a => a.Polls).Returns(_dummyPolls); var mockMetricHandler = new Mock <IMetricHandler>(); _controller = new WebApiController(mockContextFactory.Object, mockMetricHandler.Object); _controller.Request = new HttpRequestMessage(); _controller.Configuration = new HttpConfiguration(); }
private void DeleteBallot(IVotingContext context, Ballot ballot, Poll poll) { List <Vote> redundantVotes = ballot.Votes.ToList(); foreach (Vote redundantVote in redundantVotes) { _metricHandler.HandleVoteDeletedEvent(redundantVote, poll.UUID); context.Votes.Remove(redundantVote); } if (ballot.TokenGuid != Guid.Empty) { _metricHandler.HandleBallotDeletedEvent(ballot, poll.UUID); } poll.Ballots.Remove(ballot); context.Ballots.Remove(ballot); }
public void Post(Guid pollId, ChoiceCreationRequestModel choiceCreationRequest) { using (IVotingContext context = _contextFactory.CreateContext()) { if (choiceCreationRequest == null) { ThrowError(HttpStatusCode.BadRequest); } Poll poll = context .Polls .Include(p => p.Choices) .SingleOrDefault(p => p.UUID == pollId); if (poll == null) { ThrowError(HttpStatusCode.NotFound, string.Format("Poll {0} does not exist", pollId)); } if (!poll.ChoiceAdding) { ThrowError(HttpStatusCode.MethodNotAllowed, string.Format("Option adding not allowed for poll {0}", pollId)); } if (!ModelState.IsValid) { ThrowError(HttpStatusCode.BadRequest, ModelState); } Choice newOption = CreateChoiceFromRequest(choiceCreationRequest); _metricHandler.HandleChoiceAddedEvent(newOption, pollId); poll.Choices.Add(newOption); context.Choices.Add(newOption); poll.LastUpdatedUtc = DateTime.UtcNow; context.SaveChanges(); ClientSignaller.SignalUpdate(poll.UUID.ToString()); } }
// Make sure we are using the PollId, not the corresponding ManageId, if available private Guid GetExistingPollId(Guid guid) { if (guid == Guid.Empty) { return(Guid.Empty); } // Find corresponding pollId for manageId using (IVotingContext context = _contextFactory.CreateContext()) { Poll matchingPoll = context.Polls.SingleOrDefault(p => p.UUID == guid || p.ManageId == guid); if (matchingPoll == null) { return(Guid.Empty); } return(matchingPoll.UUID); } }
public ResultsRequestResponseModel Get(Guid pollId) { using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByPollId(pollId, context); Guid?tokenGuid = GetTokenGuidFromHeaders(); if (poll.InviteOnly) { if (!tokenGuid.HasValue) { ThrowError(HttpStatusCode.Unauthorized); } if (poll.Ballots.All(b => b.TokenGuid != tokenGuid.Value)) { ThrowError(HttpStatusCode.Unauthorized); } } List <Vote> votes = context .Votes .Include(v => v.Choice) .Include(v => v.Ballot) .Where(v => v.Poll.UUID == pollId) .ToList(); _metricHandler.HandleResultsUpdateEvent(HttpStatusCode.OK, pollId); ResultsRequestResponseModel response = GenerateResults(votes, poll.Choices, poll.NamedVoting); response.PollName = poll.Name; response.NamedVoting = poll.NamedVoting; response.ExpiryDateUtc = poll.ExpiryDateUtc; response.PollType = poll.PollType.ToString(); return(response); } }
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()); } }
private Poll PollByPredicate(Expression <Func <Poll, bool> > predicate, string notFoundMessage, IVotingContext context) { Poll poll = context.Polls .Include(p => p.Choices) .Include(p => p.Ballots) .Include(p => p.Ballots.Select(b => b.Votes)) .Include(p => p.Ballots.Select(b => b.Votes.Select(v => v.Choice))) .SingleOrDefault(predicate); if (poll == null) { ThrowError(HttpStatusCode.NotFound, notFoundMessage); } return(poll); }
public void Delete(Guid manageId, DeleteVotersRequestModel request) { if (request == null) { ThrowError(HttpStatusCode.BadRequest); } if (!request.BallotDeleteRequests.Any()) { ThrowError(HttpStatusCode.BadRequest); } if (request.BallotDeleteRequests.Any(b => !b.VoteDeleteRequests.Any())) { ThrowError(HttpStatusCode.BadRequest); } using (IVotingContext context = _contextFactory.CreateContext()) { Poll poll = PollByManageId(manageId, context); List <Guid> requestBallotGuids = request .BallotDeleteRequests .Select(b => b.BallotManageGuid) .ToList(); List <Guid> pollBallotGuids = poll .Ballots .Select(b => b.ManageGuid) .ToList(); if (requestBallotGuids.Except(pollBallotGuids).Any()) { ThrowError(HttpStatusCode.NotFound, String.Format("Ballots requested for delete do not all belong to poll {0}", manageId)); } List <Ballot> ballots = poll.Ballots.ToList(); foreach (DeleteBallotRequestModel ballotRequest in request.BallotDeleteRequests) { Ballot ballot = ballots.Single(b => b.ManageGuid == ballotRequest.BallotManageGuid); foreach (DeleteVoteRequestModel voteRequest in ballotRequest.VoteDeleteRequests) { Vote vote = ballot.Votes.ToList().SingleOrDefault(v => v.Choice.PollChoiceNumber == voteRequest.ChoiceNumber); if (vote == null) { ThrowError(HttpStatusCode.NotFound, String.Format("Ballot {0} does not contain an option {1}", ballotRequest.BallotManageGuid, voteRequest.ChoiceNumber)); } _metricHandler.HandleVoteDeletedEvent(vote, poll.UUID); ballot.Votes.Remove(vote); context.Votes.Remove(vote); } if (!ballot.Votes.Any()) { poll.Ballots.Remove(ballot); context.Ballots.Remove(ballot); } } poll.LastUpdatedUtc = DateTime.UtcNow; context.SaveChanges(); } }