From 8125d470ded213fc40fe074e7f8ac53ad47d556e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 5 Feb 2017 17:59:24 +0100 Subject: [PATCH] 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)