diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb
index dee1e00bd..a5343f83d 100644
--- a/app/controllers/officing/voters_controller.rb
+++ b/app/controllers/officing/voters_controller.rb
@@ -12,7 +12,8 @@ class Officing::VotersController < Officing::BaseController
@voter = Poll::Voter.new(document_type: @user.document_type,
document_number: @user.document_number,
user: @user,
- poll: @poll)
+ poll: @poll,
+ origin: "booth")
@voter.save!
end
diff --git a/app/models/poll.rb b/app/models/poll.rb
index 24ffa3a06..78ef2bc90 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -61,6 +61,10 @@ class Poll < ActiveRecord::Base
voters.where(document_number: document_number, document_type: document_type).exists?
end
+ def voted_in_booth?(user)
+ Poll::Voter.where(poll: self, user: user, origin: "booth").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/app/models/poll/answer.rb b/app/models/poll/answer.rb
index c2ea5724b..01eebd553 100644
--- a/app/models/poll/answer.rb
+++ b/app/models/poll/answer.rb
@@ -15,6 +15,6 @@ class Poll::Answer < ActiveRecord::Base
scope :by_question, ->(question_id) { where(question_id: question_id) }
def record_voter_participation
- Poll::Voter.find_or_create_by!(user: author, poll: poll)
+ Poll::Voter.find_or_create_by!(user: author, poll: poll, origin: "web")
end
end
\ No newline at end of file
diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb
index 02ab70525..6895397de 100644
--- a/app/views/polls/show.html.erb
+++ b/app/views/polls/show.html.erb
@@ -31,8 +31,14 @@
- <% @questions.each do |question| %>
- <%= render 'polls/questions/question', question: question %>
+ <% if @poll.voted_in_booth?(current_user) %>
+
+ <%= t("polls.show.already_voted_in_booth") %>
+
+ <% else %>
+ <% @questions.each do |question| %>
+ <%= render 'polls/questions/question', question: question %>
+ <% end %>
<% end %>
diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml
index 29c81c074..67d8eef2c 100644
--- a/config/locales/en/general.yml
+++ b/config/locales/en/general.yml
@@ -481,6 +481,7 @@ en:
help_text_1: "Voting takes place when a citizen proposal supports reaches 1% of the census with voting rights. Voting can also include questions that the City Council ask to the citizens decision."
help_text_2: "To participate in the next vote you have to sign up on %{org} and verify your account. All registered voters in the city over 16 years old can vote. The results of all votes are binding on the government."
show:
+ already_voted_in_booth: "You have already participated in a booth for this poll."
dates_title: "Participation dates"
cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate."
signin: Sign in
diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml
index c5322c84c..cace38212 100644
--- a/config/locales/es/general.yml
+++ b/config/locales/es/general.yml
@@ -481,6 +481,7 @@ es:
help_text_1: "Las votaciones se convocan cuando una propuesta ciudadana alcanza el 1% de apoyos del censo con derecho a voto. En las votaciones también se pueden incluir cuestiones que el Ayuntamiento somete a decisión directa de la ciudadanía."
help_text_2: "Para participar en la próxima votación tienes que registrarte en %{org} y verificar tu cuenta. Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años. Los resultados de todas las votaciones serán vinculantes para el gobierno."
show:
+ already_voted_in_booth: "Ya has participado en esta votación en una urna."
dates_title: "Fechas de participación"
cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar."
signin: iniciar sesión
diff --git a/spec/factories.rb b/spec/factories.rb
index f3d70a529..a67cd2e8e 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -52,6 +52,12 @@ FactoryGirl.define do
trait :verified do
verified_at Time.current
end
+
+ trait :in_census do
+ document_number "12345678Z"
+ document_type "1"
+ verified_at Time.current
+ end
end
factory :identity do
diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb
new file mode 100644
index 000000000..08bc6f963
--- /dev/null
+++ b/spec/features/polls/voter_spec.rb
@@ -0,0 +1,94 @@
+require 'rails_helper'
+
+feature "Voter" do
+
+ context "Origin" do
+
+ scenario "Voting via web", :js do
+ poll = create(:poll)
+ question = create(:poll_question, poll: poll, valid_answers: 'Yes, No')
+ user = create(:user, :level_two)
+
+ login_as user
+ visit question_path(question)
+
+ click_link 'Answer this question'
+ click_link 'Yes'
+
+ expect(page).to_not have_link('Yes')
+ expect(Poll::Voter.count).to eq(1)
+ expect(Poll::Voter.first.origin).to eq("web")
+ end
+
+ scenario "Voting in booth", :js do
+ user = create(:user, :in_census)
+ create(:geozone, :in_census)
+
+ poll = create(:poll)
+ officer = create(:poll_officer)
+
+ ba = create(:poll_booth_assignment, poll: poll)
+ create(:poll_officer_assignment, officer: officer, booth_assignment: ba)
+
+ login_through_form_as_officer(officer.user)
+
+ visit new_officing_residence_path
+ officing_verify_residence
+
+ expect(page).to have_content poll.name
+
+ first(:button, "Confirm vote").click
+ expect(page).to have_content "Vote introduced!"
+
+ expect(Poll::Voter.count).to eq(1)
+ expect(Poll::Voter.first.origin).to eq("booth")
+ end
+
+ context "Trying to vote the same poll in booth and web" do
+
+ let(:poll) { create(:poll) }
+ let(:question) { create(:poll_question, poll: poll, valid_answers: 'Yes, No') }
+ let!(:user) { create(:user, :in_census) }
+
+ let(:officer) { create(:poll_officer) }
+ let(:ba) { create(:poll_booth_assignment, poll: poll) }
+ let!(:oa) { create(:poll_officer_assignment, officer: officer, booth_assignment: ba) }
+
+ scenario "Trying to vote in web and then in booth", :js do
+ login_as user
+ vote_for_poll_via_web
+
+ click_link "Sign out"
+
+ login_through_form_as_officer(officer.user)
+
+ visit new_officing_residence_path
+ officing_verify_residence
+
+ expect(page).to have_content poll.name
+ expect(page).to_not have_button "Confirm vote"
+ expect(page).to have_content "Has already participated in this poll"
+ end
+
+ scenario "Trying to vote in booth and then in web", :js do
+ login_through_form_as_officer(officer.user)
+
+ vote_for_poll_via_booth
+
+ visit root_path
+ click_link "Sign out"
+
+ login_as user
+ visit question_path(question)
+
+ click_link 'Answer this question'
+
+ expect(page).to_not have_link('Yes')
+ expect(page).to have_content "You have already participated in a booth for this poll."
+ expect(Poll::Voter.count).to eq(1)
+ end
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb
index ac0cc44ea..5083d7439 100644
--- a/spec/models/poll/poll_spec.rb
+++ b/spec/models/poll/poll_spec.rb
@@ -138,4 +138,33 @@ describe :poll do
end
end
end
+
+ describe "#voted_in_booth?" do
+
+ it "returns true if the user has already voted in booth" do
+ user = create(:user, :level_two)
+ poll = create(:poll)
+
+ create(:poll_voter, poll: poll, user: user, origin: "booth")
+
+ expect(poll.voted_in_booth?(user)).to be
+ end
+
+ it "returns false if the user has not already voted in a booth" do
+ user = create(:user, :level_two)
+ poll = create(:poll)
+
+ expect(poll.voted_in_booth?(user)).to_not be
+ end
+
+ it "returns false if the user has voted in web" do
+ user = create(:user, :level_two)
+ poll = create(:poll)
+
+ create(:poll_voter, poll: poll, user: user, origin: "web")
+
+ expect(poll.voted_in_booth?(user)).to_not be
+ end
+
+ end
end
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index 8b8470293..97f05294c 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -24,6 +24,17 @@ module CommonActions
click_button 'Enter'
end
+ def login_through_form_as_officer(user)
+ visit root_path
+ click_link 'Sign in'
+
+ fill_in 'user_login', with: user.email
+ fill_in 'user_password', with: user.password
+
+ click_button 'Enter'
+ visit new_officing_residence_path
+ end
+
def login_as_authenticated_manager
expected_response = {login: login, user_key: user_key, date: date}.with_indifferent_access
login, user_key, date = "JJB042", "31415926", Time.current.strftime("%Y%m%d%H%M%S")
@@ -287,4 +298,26 @@ module CommonActions
end
end
+ def vote_for_poll_via_web
+ visit question_path(question)
+
+ click_link 'Answer this question'
+ click_link 'Yes'
+
+ expect(page).to_not have_link('Yes')
+ expect(Poll::Voter.count).to eq(1)
+ end
+
+ def vote_for_poll_via_booth
+ visit new_officing_residence_path
+ officing_verify_residence
+
+ expect(page).to have_content poll.name
+
+ first(:button, "Confirm vote").click
+ expect(page).to have_content "Vote introduced!"
+
+ expect(Poll::Voter.count).to eq(1)
+ end
+
end