From 29f5268e42ec199d9530d26664405d5998bf5dcf Mon Sep 17 00:00:00 2001 From: voodoorai2000 Date: Wed, 13 Mar 2019 13:15:48 +0100 Subject: [PATCH 1/3] Display polls for current booth Polls that were not votable by a user were not being displayed in the officing interface. Creating a confusing situation for officers. With this commit polls that are not votable by a user will be displayed, with the corresponding message explaining that that poll can only be voted by residents of a certain geozone. --- app/controllers/officing/voters_controller.rb | 3 +- .../officing/voters/_cannot_vote.html.erb | 7 ++ app/views/officing/voters/new.html.erb | 4 +- config/locales/en/officing.yml | 1 + config/locales/es/officing.yml | 1 + spec/features/officing/voters_spec.rb | 119 ++++++++++++++---- 6 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 app/views/officing/voters/_cannot_vote.html.erb diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 78233d41c..8ed778b2d 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -7,8 +7,7 @@ class Officing::VotersController < Officing::BaseController def new @user = User.find(params[:id]) - booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq - @polls = Poll.answerable_by(@user).where(id: Poll::BoothAssignment.where(booth: booths).pluck(:poll_id).uniq) + @polls = current_booth.polls.current end def create diff --git a/app/views/officing/voters/_cannot_vote.html.erb b/app/views/officing/voters/_cannot_vote.html.erb new file mode 100644 index 000000000..bc0d52211 --- /dev/null +++ b/app/views/officing/voters/_cannot_vote.html.erb @@ -0,0 +1,7 @@ + +

+ <%= t("officing.voters.show.cannot_vote") %> +

+ + + diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index a61f4f842..8f218c09c 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -19,8 +19,10 @@ <% if poll.votable_by?(@user) %> <%= render "can_vote", poll: poll %> - <% else %> + <% elsif poll.voted_by?(@user) %> <%= render "already_voted" %> + <% else %> + <%= render "cannot_vote" %> <% end %> <% end %> diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index 91b1aeb4e..6fcaef57f 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -82,6 +82,7 @@ en: not_to_vote: The person has decided not to vote at this time show: can_vote: Can vote + cannot_vote: The person cannot vote because they are not registered in the district(s) where the voting takes place. error_already_voted: Has already participated in this poll submit: Confirm vote success: "Vote introduced!" diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index 94f75ae25..82e6d1dcc 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -82,6 +82,7 @@ es: not_to_vote: La persona ha decidido no votar por el momento show: can_vote: Puede votar + cannot_vote: La persona no puede votar porque no está empadronada en el/los distrito/s en los que la votación tiene lugar. error_already_voted: Ya ha participado en esta votación. submit: Confirmar voto success: "¡Voto introducido!" diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb index 2f21234e7..4fcd2f29d 100644 --- a/spec/features/officing/voters_spec.rb +++ b/spec/features/officing/voters_spec.rb @@ -36,7 +36,22 @@ feature "Voters" do expect(Poll::Voter.last.officer_id).to eq(officer.id) end - scenario "Already voted", :js do + scenario "Cannot vote" do + unvotable_poll = create(:poll, :current, geozone_restricted: true, geozones: [create(:geozone, census_code: "02")]) + booth_assignment = create(:poll_booth_assignment, poll: unvotable_poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + set_officing_booth(booth) + visit new_officing_residence_path + officing_verify_residence + + within("#poll_#{unvotable_poll.id}") do + expect(page).to have_content "The person cannot vote" + expect(page).not_to have_button "Confirm vote" + end + end + + scenario "Already voted" do poll2 = create(:poll, :current) booth_assignment = create(:poll_booth_assignment, poll: poll2, booth: booth) create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) @@ -71,35 +86,89 @@ feature "Voters" do expect(page).to have_content poll.name end - scenario "Display only current polls on which officer has a voting shift today, and user can answer", :js do - poll_current = create(:poll, :current) - second_booth = create(:poll_booth) - booth_assignment = create(:poll_booth_assignment, poll: poll_current, booth: second_booth) - create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) - create(:poll_shift, officer: officer, booth: second_booth, date: Date.current, task: :recount_scrutiny) - create(:poll_shift, officer: officer, booth: second_booth, date: Date.tomorrow, task: :vote_collection) + context "Polls displayed to officers" do - poll_expired = create(:poll, :expired) - create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: poll_expired, booth: booth)) + scenario "Display current polls assigned to a booth" do + poll = create(:poll, :current) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) - poll_geozone_restricted_in = create(:poll, :current, geozone_restricted: true, geozones: [Geozone.first]) - booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_in, booth: booth) - create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + set_officing_booth(booth) + visit new_officing_residence_path + officing_verify_residence - poll_geozone_restricted_out = create(:poll, :current, geozone_restricted: true, geozones: [create(:geozone, census_code: "02")]) - booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_out, booth: booth) - create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + expect(page).to have_content "Polls" + expect(page).to have_content poll.name + end - set_officing_booth(second_booth) - visit new_officing_residence_path - officing_verify_residence + scenario "Display polls that the user can vote" do + votable_poll = create(:poll, :current, geozone_restricted: true, geozones: [Geozone.first]) + booth_assignment = create(:poll_booth_assignment, poll: votable_poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) - expect(page).to have_content "Polls" - expect(page).to have_content poll.name - expect(page).not_to have_content poll_current.name - expect(page).not_to have_content poll_expired.name - expect(page).to have_content poll_geozone_restricted_in.name - expect(page).not_to have_content poll_geozone_restricted_out.name + set_officing_booth(booth) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content votable_poll.name + end + + scenario "Display polls that the user cannot vote" do + unvotable_poll = create(:poll, :current, geozone_restricted: true, geozones: [create(:geozone, census_code: "02")]) + booth_assignment = create(:poll_booth_assignment, poll: unvotable_poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + set_officing_booth(booth) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content unvotable_poll.name + end + + scenario "Do not display expired polls" do + expired_poll = create(:poll, :expired) + booth_assignment = create(:poll_booth_assignment, poll: expired_poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + set_officing_booth(booth) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).not_to have_content expired_poll.name + end + + scenario "Do not display polls from other booths" do + poll1 = create(:poll, :current) + poll2 = create(:poll, :current) + + booth1 = create(:poll_booth) + booth2 = create(:poll_booth) + + booth_assignment1 = create(:poll_booth_assignment, poll: poll1, booth: booth1) + booth_assignment2 = create(:poll_booth_assignment, poll: poll2, booth: booth2) + + officer_assignment1 = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment1) + officer_assignment2 = create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment2) + + set_officing_booth(booth1) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content poll1.name + expect(page).not_to have_content poll2.name + + set_officing_booth(booth2) + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content poll2.name + expect(page).not_to have_content poll1.name + end end scenario "Store officer and booth information", :js do From 5abde6da6e77d335e11e664214e671ce80530f03 Mon Sep 17 00:00:00 2001 From: voodoorai2000 Date: Wed, 13 Mar 2019 14:00:11 +0100 Subject: [PATCH 2/3] Simplify html tag structure --- app/views/officing/voters/_already_voted.html.erb | 4 +--- app/views/officing/voters/_cannot_vote.html.erb | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/views/officing/voters/_already_voted.html.erb b/app/views/officing/voters/_already_voted.html.erb index cc144eb09..5baa6eaa7 100644 --- a/app/views/officing/voters/_already_voted.html.erb +++ b/app/views/officing/voters/_already_voted.html.erb @@ -1,7 +1,5 @@ - +

<%= t("officing.voters.show.error_already_voted") %>

- - diff --git a/app/views/officing/voters/_cannot_vote.html.erb b/app/views/officing/voters/_cannot_vote.html.erb index bc0d52211..ed5f50898 100644 --- a/app/views/officing/voters/_cannot_vote.html.erb +++ b/app/views/officing/voters/_cannot_vote.html.erb @@ -1,7 +1,5 @@ - +

<%= t("officing.voters.show.cannot_vote") %>

- - From e1141d1cd36ee0f1377d7f9c77b8cbef7bbbced6 Mon Sep 17 00:00:00 2001 From: voodoorai2000 Date: Wed, 13 Mar 2019 15:01:36 +0100 Subject: [PATCH 3/3] Display already voted message for budget polls Budget polls behave slightly differently to non-budget polls. In budget polls we use Budget::Ballot::Lines to verify if a user has already voted online. In non-budget polls we use Poll::Voter to verify this. In this commit we are adding an extra check to make sure that the correct message is displayed if the user has already voted online for a budget poll[1] [1] https://github.com/AyuntamientoMadrid/consul/blob/master/spec/features/budget_polls/voter_spec.rb#L122 --- app/models/poll.rb | 4 ++-- app/views/officing/voters/new.html.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 6d0e344b0..30068820c 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -91,12 +91,12 @@ class Poll < ApplicationRecord end def votable_by?(user) - return false if user_has_an_online_ballot(user) + return false if user_has_an_online_ballot?(user) answerable_by?(user) && not_voted_by?(user) end - def user_has_an_online_ballot(user) + def user_has_an_online_ballot?(user) budget.present? && budget.ballots.find_by(user: user)&.lines.present? end diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 8f218c09c..e88e86d85 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -19,7 +19,7 @@ <% if poll.votable_by?(@user) %> <%= render "can_vote", poll: poll %> - <% elsif poll.voted_by?(@user) %> + <% elsif poll.voted_by?(@user) || poll.user_has_an_online_ballot?(@user) %> <%= render "already_voted" %> <% else %> <%= render "cannot_vote" %>