diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 48054ce6a..0e0d02ae6 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -6,7 +6,29 @@ class Officing::BaseController < ApplicationController skip_authorization_check - def verify_officer - raise CanCan::AccessDenied unless current_user.try(:poll_officer?) - end + private + + def verify_officer + raise CanCan::AccessDenied unless current_user.try(:poll_officer?) + end + + def load_officer_assignment + @officer_assignments ||= current_user.poll_officer. + officer_assignments. + voting_days. + where(date: Time.current.to_date) + end + + def verify_officer_assignment + if @officer_assignments.blank? + redirect_to officing_root_path, notice: t("officing.residence.flash.not_allowed") + end + end + + def verify_booth + if session[:booth_id].blank? + redirect_to new_officing_booth_path + end + end + end diff --git a/app/controllers/officing/booth_controller.rb b/app/controllers/officing/booth_controller.rb new file mode 100644 index 000000000..7dfee5400 --- /dev/null +++ b/app/controllers/officing/booth_controller.rb @@ -0,0 +1,43 @@ +class Officing::BoothController < Officing::BaseController + before_action :load_officer_assignment + before_action :verify_officer_assignment + + def new + load_booths + + if only_one_booth? + set_booth(@booths.first) + redirect_to officing_root_path, notice: t("officing.booth.new.success", booth: @booths.first.name) + end + end + + def create + find_booth + set_booth(@booth) + redirect_to officing_root_path, notice: t("officing.booth.new.success", booth: @booth.name) + end + + private + + def booth_params + params.require(:booth).permit(:id) + end + + def load_booths + officer = current_user.poll_officer + @booths = officer.officer_assignments.by_date(Date.today).map(&:booth) + end + + def only_one_booth? + @booths.count == 1 + end + + def find_booth + @booth = Poll::Booth.find(booth_params[:id]) + end + + def set_booth(booth) + session[:booth_id] = booth.id + end + +end diff --git a/app/controllers/officing/residence_controller.rb b/app/controllers/officing/residence_controller.rb index da39f8428..cb7b96a64 100644 --- a/app/controllers/officing/residence_controller.rb +++ b/app/controllers/officing/residence_controller.rb @@ -1,6 +1,8 @@ class Officing::ResidenceController < Officing::BaseController - before_action :validate_officer_assignment + before_action :load_officer_assignment + before_action :verify_officer_assignment + before_action :verify_booth def new @residence = Officing::Residence.new @@ -21,17 +23,4 @@ class Officing::ResidenceController < Officing::BaseController params.require(:residence).permit(:document_number, :document_type, :year_of_birth) end - def load_officer_assignment - @officer_assignments ||= current_user.poll_officer. - officer_assignments. - voting_days. - where(date: Date.current) - end - - def validate_officer_assignment - load_officer_assignment - if @officer_assignments.blank? - redirect_to officing_root_path, notice: t("officing.residence.flash.not_allowed") - end - end end diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 564d71ba7..3354795b6 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -1,6 +1,10 @@ class Officing::VotersController < Officing::BaseController respond_to :html, :js + before_action :load_officer_assignment + before_action :verify_officer_assignment + before_action :verify_booth + def new @user = User.find(params[:id]) booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq @@ -29,7 +33,13 @@ class Officing::VotersController < Officing::BaseController def officer_assignment(poll) Poll::OfficerAssignment.by_officer(current_user.poll_officer) .by_poll(poll) + .by_booth(current_booth) .by_date(Date.current) .first end + + def current_booth + Poll::Booth.find(session[:booth_id]) + end + end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index d16f9c87e..0409a9d5e 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -3,7 +3,9 @@ class Users::SessionsController < Devise::SessionsController private def after_sign_in_path_for(resource) - if !verifying_via_email? && resource.show_welcome_screen? + if current_user.poll_officer? + new_officing_booth_path + elsif !verifying_via_email? && resource.show_welcome_screen? welcome_path else super diff --git a/app/models/poll/officer_assignment.rb b/app/models/poll/officer_assignment.rb index 7d0e31ded..7de4f98b3 100644 --- a/app/models/poll/officer_assignment.rb +++ b/app/models/poll/officer_assignment.rb @@ -18,7 +18,8 @@ class Poll where("officer_id = ? AND poll_booth_assignments.poll_id = ?", officer_id, poll_id) end scope :by_officer, ->(officer){ where(officer_id: officer.id) } - scope :by_poll, ->(poll){ joins(:booth_assignment).where("poll_booth_assignments.poll_id" => poll.id) } + scope :by_poll, ->(poll){ joins(:booth_assignment).where("poll_booth_assignments.poll_id" => poll.id) } + scope :by_booth, ->(booth){ joins(:booth_assignment).where("poll_booth_assignments.booth_id" => booth.id) } scope :by_date, ->(date){ where(date: date) } before_create :log_user_data @@ -26,5 +27,10 @@ class Poll def log_user_data self.user_data_log = "#{officer.user_id} - #{officer.user.name_and_email}" end + + def booth + booth_assignment.booth + end + end end diff --git a/app/views/officing/booth/new.html.erb b/app/views/officing/booth/new.html.erb new file mode 100644 index 000000000..5fbcd429e --- /dev/null +++ b/app/views/officing/booth/new.html.erb @@ -0,0 +1,25 @@ +
+
+
+

+ <%= t("officing.booth.new.title") %> +

+ <%= form_for Poll::Booth.new, + as: :booth, + url: officing_booth_path, + method: :post do |f| %> +
+
+ <%= f.select :id, + @booths.collect { |booth| [booth.name, booth.id] }, + selected: @booths.first, + label: false, + tabindex: "1" %> + + <%= f.submit(t("devise_views.sessions.new.submit"), class: "button expanded") %> +
+
+ <% end %> +
+
+
diff --git a/config/locales/en/officing.yml b/config/locales/en/officing.yml index 568c0e146..b38418e51 100644 --- a/config/locales/en/officing.yml +++ b/config/locales/en/officing.yml @@ -16,6 +16,10 @@ en: no_polls: You are not officing final recounts in any active poll select_poll: Select poll add_results: Add results + booth: + new: + title: "Choose your booth" + success: "You are officing booth %{booth}" results: flash: create: "Results saved" diff --git a/config/locales/es/officing.yml b/config/locales/es/officing.yml index 1314713b1..04ee109f6 100644 --- a/config/locales/es/officing.yml +++ b/config/locales/es/officing.yml @@ -16,6 +16,10 @@ es: no_polls: No tienes permiso para recuento final en ninguna votación reciente select_poll: Selecciona votación add_results: Añadir resultados + booth: + new: + title: "Escoge tu urna" + success: "Estás presidiendo la urna %{booth}" results: flash: create: "Datos guardados" diff --git a/config/routes/officing.rb b/config/routes/officing.rb index 7adfbbf60..6be5e5bc2 100644 --- a/config/routes/officing.rb +++ b/config/routes/officing.rb @@ -4,6 +4,7 @@ namespace :officing do resources :results, only: [:new, :create, :index] end + resource :booth, controller: "booth", only: [:new, :create] resource :residence, controller: "residence", only: [:new, :create] resources :voters, only: [:new, :create] root to: "dashboard#index" diff --git a/spec/features/officing/booth_spec.rb b/spec/features/officing/booth_spec.rb new file mode 100644 index 000000000..07d2fc7b9 --- /dev/null +++ b/spec/features/officing/booth_spec.rb @@ -0,0 +1,60 @@ +require "rails_helper" + +feature "Booth" do + + scenario "Officer with no booth assignments today" do + officer = create(:poll_officer) + + login_through_form_as(officer.user) + + expect(page).to have_content "You don't have officing shifts today" + end + + scenario "Officer with booth assignments another day" do + officer = create(:poll_officer) + create(:poll_officer_assignment, officer: officer, date: 1.day.from_now) + + login_through_form_as(officer.user) + + expect(page).to have_content "You don't have officing shifts today" + end + + scenario "Officer with single booth assignment today" do + officer = create(:poll_officer) + poll = create(:poll) + + booth = create(:poll_booth) + + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment, date: Date.today) + + login_through_form_as(officer.user) + + expect(page).to have_content "You are officing booth #{booth.name}" + end + + scenario "Officer with multiple booth assignments today" do + officer = create(:poll_officer) + poll = create(:poll) + + booth1 = create(:poll_booth) + booth2 = create(:poll_booth) + + ba1 = create(:poll_booth_assignment, poll: poll, booth: booth1) + ba2 = create(:poll_booth_assignment, poll: poll, booth: booth2) + + create(:poll_officer_assignment, officer: officer, booth_assignment: ba1, date: Date.today) + create(:poll_officer_assignment, officer: officer, booth_assignment: ba2, date: Date.today) + + login_through_form_as(officer.user) + + expect(page).to have_content "You have been signed in successfully." + expect(page).to have_content "Choose your booth" + + select booth2.name, from: "booth_id" + click_button "Enter" + + expect(page).to have_content "You are officing booth #{booth2.name}" + end + +end diff --git a/spec/features/officing/residence_spec.rb b/spec/features/officing/residence_spec.rb index 9f07eb8ce..664678e82 100644 --- a/spec/features/officing/residence_spec.rb +++ b/spec/features/officing/residence_spec.rb @@ -93,4 +93,28 @@ feature "Residence", :with_frozen_time do end + scenario "Verify booth", :js do + booth = create(:poll_booth) + poll = create(:poll) + + ba = create(:poll_booth_assignment, poll: poll, booth: booth ) + create(:poll_officer_assignment, officer: officer, booth_assignment: ba) + + login_as(officer.user) + + # User somehow skips setting session[:booth_id] + # set_officing_booth(booth) + + visit new_officing_residence_path + expect(page).to have_content "You are officing booth #{booth.name}" + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + click_button "Confirm vote" + + expect(page).to have_content "Vote introduced!" + end + end diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb index 01935b6f3..19e3cca33 100644 --- a/spec/features/officing/voters_spec.rb +++ b/spec/features/officing/voters_spec.rb @@ -15,6 +15,8 @@ feature "Voters" do end scenario "Can vote", :js do + create(:poll_officer_assignment, officer: officer) + visit new_officing_residence_path officing_verify_residence diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index 587932ebe..7bb20af10 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -23,7 +23,13 @@ module CommonActions def validate_officer allow_any_instance_of(Officing::ResidenceController). - to receive(:validate_officer_assignment).and_return(true) + to receive(:verify_officer_assignment).and_return(true) end + def set_officing_booth(booth=nil) + booth = create(:poll_booth) if booth.blank? + + allow_any_instance_of(Officing::VotersController). + to receive(:current_booth).and_return(booth) + end end