From 540e12a3ac690c919f04a616fb7ad0f3f8785c38 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:47:47 +0200 Subject: [PATCH 1/5] Add RECOUNT_DURATION Poll constant for recount period duration --- app/helpers/shifts_helper.rb | 5 ++++- app/models/poll.rb | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index dc9f97a91..7c2d5c1b3 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -5,7 +5,10 @@ module ShiftsHelper end def shift_recount_scrutiny_dates(polls) - date_options(polls.map(&:ends_at).map(&:to_date).sort.inject([]) { |total, date| total << (date..date + 1.week).to_a }.flatten.uniq) + dates = polls.map(&:ends_at).map(&:to_date).sort.inject([]) do |total, date| + total << (date..date + Poll::RECOUNT_DURATION).to_a + end + date_options(dates.flatten.uniq) end def date_options(dates) diff --git a/app/models/poll.rb b/app/models/poll.rb index 8675ce49a..c572a4765 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -2,6 +2,9 @@ class Poll < ActiveRecord::Base include Imageable acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases + + RECOUNT_DURATION = 1.week + has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :booths, through: :booth_assignments has_many :partial_results, through: :booth_assignments From ca2d9a1d688ac24656d1be57eb01a1992b0489ae Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:48:25 +0200 Subject: [PATCH 2/5] Add recounting Poll scope with trait and spec --- app/models/poll.rb | 1 + spec/factories.rb | 5 +++++ spec/models/poll/poll_spec.rb | 16 ++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/app/models/poll.rb b/app/models/poll.rb index c572a4765..41d4a9ab9 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -25,6 +25,7 @@ class Poll < ActiveRecord::Base scope :current, -> { where('starts_at <= ? and ? <= ends_at', Date.current.beginning_of_day, Date.current.beginning_of_day) } scope :incoming, -> { where('? < starts_at', Date.current.beginning_of_day) } scope :expired, -> { where('ends_at < ?', Date.current.beginning_of_day) } + scope :recounting, -> { Poll.where(ends_at: (Date.current.beginning_of_day - RECOUNT_DURATION)..Date.current.beginning_of_day) } scope :published, -> { where('published = ?', true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } diff --git a/spec/factories.rb b/spec/factories.rb index 69aa92c62..b1c5ff329 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -489,6 +489,11 @@ FactoryGirl.define do ends_at { 15.days.ago } end + trait :recounting do + starts_at { 1.month.ago } + ends_at { Date.current } + end + trait :published do published true end diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index 5083d7439..dba964928 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -76,6 +76,22 @@ describe :poll do end end + describe "#recounting" do + it "returns polls in recount & scrutiny phase" do + current = create(:poll, :current) + incoming = create(:poll, :incoming) + expired = create(:poll, :expired) + recounting = create(:poll, :recounting) + + recounting_polls = Poll.recounting + + expect(recounting_polls).to_not include(current) + expect(recounting_polls).to_not include(incoming) + expect(recounting_polls).to_not include(expired) + expect(recounting_polls).to include(recounting) + end + end + describe "answerable_by" do let(:geozone) {create(:geozone) } From 9146d68c5342fc358cf52d3bd7bcf8b2345b35fe Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:53:03 +0200 Subject: [PATCH 3/5] Add current_or_recounting_or_incoming method to Poll model --- app/models/poll.rb | 4 ++++ spec/models/poll/poll_spec.rb | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/models/poll.rb b/app/models/poll.rb index 41d4a9ab9..5c65b688f 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -51,6 +51,10 @@ class Poll < ActiveRecord::Base current + incoming end + def self.current_or_recounting_or_incoming + current + recounting + incoming + end + def answerable_by?(user) user.present? && user.level_two_or_three_verified? && diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index dba964928..bfb5881f2 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -92,6 +92,22 @@ describe :poll do end end + describe "#current_or_recounting_or_incoming" do + it "returns current or recounting or incoming polls" do + current = create(:poll, :current) + incoming = create(:poll, :incoming) + expired = create(:poll, :expired) + recounting = create(:poll, :recounting) + + current_or_recounting_or_incoming = Poll.current_or_recounting_or_incoming + + expect(current_or_recounting_or_incoming).to include(current) + expect(current_or_recounting_or_incoming).to include(recounting) + expect(current_or_recounting_or_incoming).to include(incoming) + expect(current_or_recounting_or_incoming).to_not include(expired) + end + end + describe "answerable_by" do let(:geozone) {create(:geozone) } From 79c8c2f826dc53eb4ca1219c65d8efc4f36f9c57 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 16:55:40 +0200 Subject: [PATCH 4/5] Add scope on shift creation date ranges to current/recounting/incoming polls, plus cover with test --- app/views/admin/poll/shifts/_form.html.erb | 4 ++-- spec/features/admin/poll/shifts_spec.rb | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/admin/poll/shifts/_form.html.erb b/app/views/admin/poll/shifts/_form.html.erb index 1a13edf45..4004a949b 100644 --- a/app/views/admin/poll/shifts/_form.html.erb +++ b/app/views/admin/poll/shifts/_form.html.erb @@ -24,12 +24,12 @@
<%= select 'shift[date]', 'vote_collection_date', - options_for_select(shift_vote_collection_dates(@booth.polls)), + options_for_select(shift_vote_collection_dates(@booth.polls.current_or_incoming)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-vote-collection-dates' %> <%= select 'shift[date]', 'recount_scrutiny_date', - options_for_select(shift_recount_scrutiny_dates(@booth.polls)), + options_for_select(shift_recount_scrutiny_dates(@booth.polls.current_or_recounting_or_incoming)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-recount-scrutiny-dates', diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 2ac290216..edefd0844 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -35,7 +35,8 @@ feature 'Admin shifts' do create(:poll, :incoming) poll = create(:poll, :current) booth = create(:poll_booth) - assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_booth_assignment, poll: create(:poll, :expired), booth: booth) officer = create(:poll_officer) vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } From 16f499d5fd732578bc5fd138b97659da9d7c5eb7 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Fri, 13 Oct 2017 17:19:11 +0200 Subject: [PATCH 5/5] Force shift dates to start on current date at minimun --- app/helpers/shifts_helper.rb | 6 ++++-- spec/features/admin/poll/shifts_spec.rb | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/helpers/shifts_helper.rb b/app/helpers/shifts_helper.rb index 7c2d5c1b3..5c99bad66 100644 --- a/app/helpers/shifts_helper.rb +++ b/app/helpers/shifts_helper.rb @@ -6,7 +6,8 @@ module ShiftsHelper def shift_recount_scrutiny_dates(polls) dates = polls.map(&:ends_at).map(&:to_date).sort.inject([]) do |total, date| - total << (date..date + Poll::RECOUNT_DURATION).to_a + initial_date = date < Date.current ? Date.current : date + total << (initial_date..date + Poll::RECOUNT_DURATION).to_a end date_options(dates.flatten.uniq) end @@ -16,7 +17,8 @@ module ShiftsHelper end def start_date(polls) - polls.map(&:starts_at).min.to_date + start_date = polls.map(&:starts_at).min.to_date + start_date < Date.current ? Date.current : start_date end def end_date(polls) diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index edefd0844..7512d8b6d 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -38,7 +38,7 @@ feature 'Admin shifts' do create(:poll_booth_assignment, poll: poll, booth: booth) create(:poll_booth_assignment, poll: create(:poll, :expired), booth: booth) officer = create(:poll_officer) - vote_collection_dates = (poll.starts_at.to_date..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } + vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a.map { |date| I18n.l(date, format: :long) } recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a.map { |date| I18n.l(date, format: :long) } visit available_admin_booths_path @@ -53,14 +53,14 @@ feature 'Admin shifts' do expect(page).to have_select('shift_date_vote_collection_date', options: ["Select day", *vote_collection_dates]) expect(page).not_to have_select('shift_date_recount_scrutiny_date') - select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date_vote_collection_date' + select I18n.l(Date.current, format: :long), from: 'shift_date_vote_collection_date' click_button "Add shift" expect(page).to have_content "Shift added" within("#shifts") do expect(page).to have_css(".shift", count: 1) - expect(page).to have_content(I18n.l(poll.starts_at.to_date, format: :long)) + expect(page).to have_content(I18n.l(Date.current, format: :long)) expect(page).to have_content("Collect Votes") expect(page).to have_content(officer.name) end