From d39f19abb8e972edc2a291ca6ca043ca5a63ac2a Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 16:28:39 +0100 Subject: [PATCH] Defines Poll::Question#answerable_by?(user) and uses it in abilities --- app/models/abilities/common.rb | 4 ++- app/models/poll/question.rb | 11 +++++++ spec/models/abilities/common_spec.rb | 47 ++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 5635cc7d7..9d6ad84a8 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -49,7 +49,9 @@ module Abilities can :create, DirectMessage can :show, DirectMessage, sender_id: user.id can(:answer, Poll, Poll.current){ |poll| poll.current? } - can :answer, Poll::Question, geozones: {id: user.geozone_id} + can(:answer, Poll::Question, Poll::Question.answerable_by(user)) do |question| + question.answerable_by?(user) + end end can [:create, :show], ProposalNotification, proposal: { author_id: user.id } diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 59ff11a70..6d56a31f2 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -46,6 +46,17 @@ class Poll::Question < ActiveRecord::Base end end + def answerable_by?(user) + user.present? && poll.current? && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) + end + def self.answerable_by(user) + return where(false) unless user.present? + where(poll_id: Poll.current.pluck(:id)) + .joins(:geozones) + .where('poll_questions.all_geozones = ? or geozones.id = ?', + true, + user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql + end end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index 6be4e0dce..59618f785 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -20,6 +20,13 @@ describe "Abilities::Common" do let(:poll_question_from_own_geozone) { create(:poll_question, geozones: [geozone]) } let(:poll_question_from_other_geozone) { create(:poll_question, geozones: [create(:geozone)]) } + let(:poll_question_from_all_geozones) { create(:poll_question, all_geozones: true) } + let(:expired_poll_question_from_own_geozone) { create(:poll_question, poll: expired_poll, geozones: [geozone]) } + let(:expired_poll_question_from_other_geozone) { create(:poll_question, poll: expired_poll, geozones: [create(:geozone)]) } + let(:expired_poll_question_from_all_geozones) { create(:poll_question, poll: expired_poll, all_geozones: true) } + let(:incoming_poll_question_from_own_geozone) { create(:poll_question, poll: incoming_poll, geozones: [geozone]) } + let(:incoming_poll_question_from_other_geozone) { create(:poll_question, poll: incoming_poll, geozones: [create(:geozone)]) } + let(:incoming_poll_question_from_all_geozones) { create(:poll_question, poll: incoming_poll, all_geozones: true) } it { should be_able_to(:index, Debate) } it { should be_able_to(:show, debate) } @@ -117,7 +124,27 @@ describe "Abilities::Common" do it { should_not be_able_to(:answer, incoming_poll) } it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + + context "without geozone" do + before(:each) { user.geozone = nil } + it { should_not be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + end end describe "when level 3 verified" do @@ -142,6 +169,26 @@ describe "Abilities::Common" do it { should_not be_able_to(:answer, incoming_poll) } it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + + context "without geozone" do + before(:each) { user.geozone = nil } + it { should_not be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + end end end