From 8125d470ded213fc40fe074e7f8ac53ad47d556e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 5 Feb 2017 17:59:24 +0100 Subject: [PATCH 1/2] Add methods to obtain polls votable by a user --- app/models/poll.rb | 32 +++++++++++++----- spec/models/poll/poll_spec.rb | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 4733432c3..65d78446a 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -65,12 +65,32 @@ class Poll < ActiveRecord::Base .where('geozone_restricted = ? OR geozones_polls.geozone_id = ?', false, user.geozone_id) end - def votable_by?(user) - !document_has_voted?(user.document_number, user.document_type) + def self.votable_by(user) + answerable_by(user). + not_voted_by(user) end - def document_has_voted?(document_number, document_type) - voters.where(document_number: document_number, document_type: document_type).exists? + def votable_by?(user) + answerable_by?(user) && + not_voted_by?(user) + end + + def self.not_voted_by(user) + where("polls.id not in (?)", poll_ids_voted_by(user)) + end + + def self.poll_ids_voted_by(user) + return -1 if Poll::Voter.where(user: user).empty? + + Poll::Voter.where(user: user).pluck(:poll_id) + end + + def not_voted_by?(user) + Poll::Voter.where(poll: self, user: user).empty? + end + + def voted_by?(user) + Poll::Voter.where(poll: self, user: user).exists? end def voted_in_booth?(user) @@ -81,10 +101,6 @@ class Poll < ActiveRecord::Base Poll::Voter.where(poll: self, user: user, origin: "web").exists? end - def voted_by?(user) - Poll::Voter.where(poll: self, user: user).exists? - end - def date_range unless starts_at.present? && ends_at.present? && starts_at <= ends_at errors.add(:starts_at, I18n.t('errors.messages.invalid_date_range')) diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index 6090adbe1..4fea6431c 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -147,6 +147,70 @@ describe Poll do end end + describe "votable_by" do + it "returns polls that have not been voted by a user" do + user = create(:user, :level_two) + + poll1 = create(:poll) + poll2 = create(:poll) + poll3 = create(:poll) + + create(:poll_voter, user: user, poll: poll1) + + expect(Poll.votable_by(user)).to include(poll2) + expect(Poll.votable_by(user)).to include(poll3) + expect(Poll.votable_by(user)).not_to include(poll1) + end + + it "returns polls that are answerable by a user" do + user = create(:user, :level_two, geozone: nil) + poll1 = create(:poll) + poll2 = create(:poll) + + allow(Poll).to receive(:answerable_by).and_return(Poll.where(id: poll1)) + + expect(Poll.votable_by(user)).to include(poll1) + expect(Poll.votable_by(user)).not_to include(poll2) + end + + it "returns polls even if there are no voters yet" do + user = create(:user, :level_two) + poll = create(:poll) + + expect(Poll.votable_by(user)).to include(poll) + end + + end + + describe "#votable_by" do + it "returns false if the user has already voted the poll" do + user = create(:user, :level_two) + poll = create(:poll) + + create(:poll_voter, user: user, poll: poll) + + expect(poll.votable_by?(user)).to eq(false) + end + + it "returns false if the poll is not answerable by the user" do + user = create(:user, :level_two) + poll = create(:poll) + + allow_any_instance_of(Poll).to receive(:answerable_by?).and_return(false) + + expect(poll.votable_by?(user)).to eq(false) + end + + it "return true if a poll is answerable and has not been voted by the user" do + user = create(:user, :level_two) + poll = create(:poll) + + allow_any_instance_of(Poll).to receive(:answerable_by?).and_return(true) + + expect(poll.votable_by?(user)).to eq(true) + end + end + describe "#voted_by?" do it "return false if the user has not voted for this poll" do user = create(:user, :level_two) From 151239924b6c34781ee04239a8faa4568fdb7288 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 21 Jun 2018 15:36:39 +0200 Subject: [PATCH 2/2] Display 'validate document' menu item only when applicable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are trying to avoid Officers from forgetting to click the “Confirm vote” button, which is necessary to keep track of who has voted a Poll To do that, we are not displaying the menu item to go back to the next person that wants to vote, until the Officer clicks the “Confirm Vote” button or the “The user has decided not to vote” button Note: Due to mobile version we have duplicate ids, so using classes for the menu items to hide them without errors Note2: We are only hidding the menu item, if there are votable polls, otherwise the “Confirm vote” button does not appear, and there is no way of going back to help the next person that wants to vote --- app/views/officing/_menu.html.erb | 4 ++- app/views/officing/voters/create.js.erb | 3 +- spec/features/polls/voter_spec.rb | 44 ++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index 173c72582..17b57a087 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -1,7 +1,9 @@
    <% if vote_collection_shift? %> -
  • > +
  • + <%= " is-active" if controller_name == "voters" %> + <%= " is-hidden" if controller_name == "voters" && Poll.votable_by(@user).any? %>"> <%= link_to new_officing_residence_path do %> <%= t("officing.menu.voters") %> diff --git a/app/views/officing/voters/create.js.erb b/app/views/officing/voters/create.js.erb index 3837f017e..7a9a4cf03 100644 --- a/app/views/officing/voters/create.js.erb +++ b/app/views/officing/voters/create.js.erb @@ -1,2 +1,3 @@ $("#<%= dom_id(@poll) %> #actions").html('<%= j render("voted") %>'); -$("#<%= dom_id(@poll) %> #can_vote_callout").hide(); \ No newline at end of file +$("#<%= dom_id(@poll) %> #can_vote_callout").hide(); +$(".js-vote-collection").removeClass("is-hidden"); diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index ae0022302..8e0271f8f 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -164,6 +164,48 @@ feature "Voter" do expect(Poll::Voter.count).to eq(1) end - end + context "Side menu" do + scenario "'Validate document' menu item with votable polls", :js do + login_through_form_as_officer(officer.user) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + + within("#side_menu") do + expect(page).not_to have_content("Validate document") + end + + within("#poll_#{poll.id}") do + click_button("Confirm vote") + expect(page).to have_content "Vote introduced!" + end + + within("#side_menu") do + expect(page).to have_content("Validate document") + end + end + + scenario "'Validate document' menu item without votable polls", :js do + create(:poll_voter, poll: poll, user: create(:user, :in_census)) + + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + + within("#poll_#{poll.id}") do + expect(page).to have_content "Has already participated in this poll" + end + + within("#side_menu") do + expect(page).to have_content("Validate document") + end + end + + end + end end