Rubocop was complaining about a Layout/ExtraSpacing in a couple of places. These issues weren't detected by Pronto because they didn't affect lines changed in the pull request. These lines were fine until we removed the lines next to them in commits4b42a68b6and00f0c4410.
333 lines
15 KiB
Ruby
333 lines
15 KiB
Ruby
require "rails_helper"
|
|
require "cancan/matchers"
|
|
|
|
describe Abilities::Common do
|
|
subject(:ability) { Ability.new(user) }
|
|
|
|
let(:geozone) { create(:geozone) }
|
|
|
|
let(:user) { create(:user, geozone: geozone) }
|
|
|
|
let(:debate) { create(:debate) }
|
|
let(:comment) { create(:comment) }
|
|
let(:proposal) { create(:proposal) }
|
|
let(:own_debate) { create(:debate, author: user) }
|
|
let(:own_comment) { create(:comment, author: user) }
|
|
let(:own_proposal) { create(:proposal, author: user) }
|
|
let(:own_legislation_proposal) { create(:legislation_proposal, author: user) }
|
|
|
|
let(:accepting_budget) { create(:budget, :accepting) }
|
|
let(:reviewing_budget) { create(:budget, :reviewing) }
|
|
let(:selecting_budget) { create(:budget, :selecting) }
|
|
let(:balloting_budget) { create(:budget, :balloting) }
|
|
|
|
let(:investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget) }
|
|
let(:investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget) }
|
|
let(:investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget) }
|
|
let(:investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget) }
|
|
let(:own_investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget, author: user) }
|
|
let(:own_investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget, author: user) }
|
|
let(:own_investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget, author: user) }
|
|
let(:own_investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget, author: user) }
|
|
let(:ballot_in_accepting_budget) { create(:budget_ballot, budget: accepting_budget) }
|
|
let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) }
|
|
let(:ballot_in_balloting_budget) { create(:budget_ballot, budget: balloting_budget) }
|
|
|
|
let(:current_poll) { create(:poll) }
|
|
let(:expired_poll) { create(:poll, :expired) }
|
|
let(:expired_poll_from_own_geozone) { create(:poll, :expired, geozone_restricted: true, geozones: [geozone]) }
|
|
let(:expired_poll_from_other_geozone) { create(:poll, :expired, geozone_restricted: true, geozones: [create(:geozone)]) }
|
|
let(:poll) { create(:poll, geozone_restricted: false) }
|
|
let(:poll_from_own_geozone) { create(:poll, geozone_restricted: true, geozones: [geozone]) }
|
|
let(:poll_from_other_geozone) { create(:poll, geozone_restricted: true, geozones: [create(:geozone)]) }
|
|
|
|
let(:poll_question_from_own_geozone) { create(:poll_question, poll: poll_from_own_geozone) }
|
|
let(:poll_question_from_other_geozone) { create(:poll_question, poll: poll_from_other_geozone) }
|
|
let(:poll_question_from_all_geozones) { create(:poll_question, poll: poll) }
|
|
|
|
let(:expired_poll_question_from_own_geozone) { create(:poll_question, poll: expired_poll_from_own_geozone) }
|
|
let(:expired_poll_question_from_other_geozone) { create(:poll_question, poll: expired_poll_from_other_geozone) }
|
|
let(:expired_poll_question_from_all_geozones) { create(:poll_question, poll: expired_poll) }
|
|
|
|
let(:own_proposal_document) { build(:document, documentable: own_proposal) }
|
|
let(:proposal_document) { build(:document, documentable: proposal) }
|
|
let(:own_budget_investment_document) { build(:document, documentable: own_investment_in_accepting_budget) }
|
|
let(:budget_investment_document) { build(:document, documentable: investment_in_accepting_budget) }
|
|
|
|
let(:own_proposal_image) { build(:image, imageable: own_proposal) }
|
|
let(:proposal_image) { build(:image, imageable: proposal) }
|
|
let(:own_budget_investment_image) { build(:image, imageable: own_investment_in_accepting_budget) }
|
|
let(:budget_investment_image) { build(:image, imageable: investment_in_accepting_budget) }
|
|
|
|
it { should be_able_to(:index, Debate) }
|
|
it { should be_able_to(:show, debate) }
|
|
it { should be_able_to(:vote, debate) }
|
|
|
|
it { should be_able_to(:show, user) }
|
|
it { should be_able_to(:edit, user) }
|
|
|
|
it { should be_able_to(:index, Proposal) }
|
|
it { should be_able_to(:show, proposal) }
|
|
it { should_not be_able_to(:vote, Proposal) }
|
|
|
|
it { should_not be_able_to(:comment_as_administrator, debate) }
|
|
it { should_not be_able_to(:comment_as_moderator, debate) }
|
|
it { should_not be_able_to(:comment_as_administrator, proposal) }
|
|
it { should_not be_able_to(:comment_as_moderator, proposal) }
|
|
|
|
it { should be_able_to(:new, DirectMessage) }
|
|
it { should_not be_able_to(:create, DirectMessage) }
|
|
it { should_not be_able_to(:show, DirectMessage) }
|
|
|
|
it { should be_able_to(:destroy, own_proposal_document) }
|
|
it { should_not be_able_to(:destroy, proposal_document) }
|
|
|
|
it { should be_able_to(:destroy, own_budget_investment_document) }
|
|
it { should_not be_able_to(:destroy, budget_investment_document) }
|
|
|
|
it { should be_able_to(:destroy, own_proposal_image) }
|
|
it { should_not be_able_to(:destroy, proposal_image) }
|
|
|
|
it { should be_able_to(:destroy, own_budget_investment_image) }
|
|
it { should_not be_able_to(:destroy, budget_investment_image) }
|
|
it { should_not be_able_to(:manage, Dashboard::Action) }
|
|
|
|
it { should_not be_able_to(:manage, LocalCensusRecord) }
|
|
|
|
describe "Comment" do
|
|
it { should be_able_to(:create, Comment) }
|
|
it { should be_able_to(:vote, Comment) }
|
|
|
|
it { should be_able_to(:hide, own_comment) }
|
|
it { should_not be_able_to(:hide, comment) }
|
|
end
|
|
|
|
describe "flagging content" do
|
|
it { should be_able_to(:flag, debate) }
|
|
it { should be_able_to(:unflag, debate) }
|
|
|
|
it { should be_able_to(:flag, comment) }
|
|
it { should be_able_to(:unflag, comment) }
|
|
|
|
it { should be_able_to(:flag, proposal) }
|
|
it { should be_able_to(:unflag, proposal) }
|
|
|
|
describe "own content" do
|
|
it { should_not be_able_to(:flag, own_comment) }
|
|
it { should_not be_able_to(:unflag, own_comment) }
|
|
|
|
it { should_not be_able_to(:flag, own_debate) }
|
|
it { should_not be_able_to(:unflag, own_debate) }
|
|
|
|
it { should_not be_able_to(:flag, own_proposal) }
|
|
it { should_not be_able_to(:unflag, own_proposal) }
|
|
end
|
|
end
|
|
|
|
describe "follows" do
|
|
let(:other_user) { create(:user) }
|
|
|
|
it { should be_able_to(:create, build(:follow, :followed_proposal, user: user)) }
|
|
it { should_not be_able_to(:create, build(:follow, :followed_proposal, user: other_user)) }
|
|
|
|
it { should be_able_to(:destroy, create(:follow, :followed_proposal, user: user)) }
|
|
it { should_not be_able_to(:destroy, create(:follow, :followed_proposal, user: other_user)) }
|
|
end
|
|
|
|
describe "other users" do
|
|
let(:other_user) { create(:user) }
|
|
|
|
it { should be_able_to(:show, other_user) }
|
|
it { should_not be_able_to(:edit, other_user) }
|
|
end
|
|
|
|
describe "editing debates" do
|
|
let(:own_debate_non_editable) { create(:debate, author: user) }
|
|
|
|
before { allow(own_debate_non_editable).to receive(:editable?).and_return(false) }
|
|
|
|
it { should be_able_to(:edit, own_debate) }
|
|
it { should_not be_able_to(:edit, debate) } # Not his
|
|
it { should_not be_able_to(:edit, own_debate_non_editable) }
|
|
end
|
|
|
|
describe "editing proposals" do
|
|
let(:own_proposal_non_editable) { create(:proposal, author: user) }
|
|
|
|
before { allow(own_proposal_non_editable).to receive(:editable?).and_return(false) }
|
|
|
|
it { should be_able_to(:edit, own_proposal) }
|
|
it { should_not be_able_to(:edit, proposal) } # Not his
|
|
it { should_not be_able_to(:edit, own_proposal_non_editable) }
|
|
|
|
it { should be_able_to(:destroy, own_proposal_image) }
|
|
it { should be_able_to(:destroy, own_proposal_document) }
|
|
|
|
it { should_not be_able_to(:destroy, proposal_image) }
|
|
it { should_not be_able_to(:destroy, proposal_document) }
|
|
end
|
|
|
|
it { should_not be_able_to(:edit, own_legislation_proposal) }
|
|
it { should_not be_able_to(:update, own_legislation_proposal) }
|
|
|
|
describe "proposals dashboard" do
|
|
it { should be_able_to(:dashboard, own_proposal) }
|
|
it { should_not be_able_to(:dashboard, proposal) }
|
|
end
|
|
|
|
describe "proposal polls" do
|
|
let(:poll) { create(:poll, related: own_proposal) }
|
|
|
|
it { should be_able_to(:manage_polls, own_proposal) }
|
|
it { should_not be_able_to(:manage_polls, proposal) }
|
|
it { should_not be_able_to(:stats, poll) }
|
|
it { should be_able_to(:results, poll) }
|
|
end
|
|
|
|
describe "proposal mailing" do
|
|
it { should be_able_to(:manage_mailing, own_proposal) }
|
|
it { should_not be_able_to(:manage_mailing, proposal) }
|
|
end
|
|
|
|
describe "proposal poster" do
|
|
it { should be_able_to(:manage_poster, own_proposal) }
|
|
it { should_not be_able_to(:manage_poster, proposal) }
|
|
end
|
|
|
|
describe "publishing proposals" do
|
|
let(:draft_own_proposal) { create(:proposal, :draft, author: user) }
|
|
let(:retired_proposal) { create(:proposal, :draft, :retired, author: user) }
|
|
|
|
it { should be_able_to(:publish, draft_own_proposal) }
|
|
it { should_not be_able_to(:publish, own_proposal) }
|
|
it { should_not be_able_to(:publish, proposal) }
|
|
it { should_not be_able_to(:publish, retired_proposal) }
|
|
end
|
|
|
|
describe "when level 2 verified" do
|
|
let(:own_direct_message) { create(:direct_message, sender: user) }
|
|
|
|
before { user.update(residence_verified_at: Time.current, confirmed_phone: "1") }
|
|
|
|
describe "Proposal" do
|
|
it { should be_able_to(:vote, Proposal) }
|
|
end
|
|
|
|
describe "Direct Message" do
|
|
it { should be_able_to(:new, DirectMessage) }
|
|
it { should be_able_to(:create, DirectMessage) }
|
|
it { should be_able_to(:show, own_direct_message) }
|
|
it { should_not be_able_to(:show, create(:direct_message)) }
|
|
end
|
|
|
|
describe "Poll" do
|
|
it { should be_able_to(:answer, current_poll) }
|
|
it { should_not be_able_to(:answer, expired_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) }
|
|
|
|
context "without geozone" do
|
|
before { 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) }
|
|
end
|
|
end
|
|
|
|
describe "Budgets" do
|
|
it { should be_able_to(:create, investment_in_accepting_budget) }
|
|
it { should_not be_able_to(:create, investment_in_selecting_budget) }
|
|
it { should_not be_able_to(:create, investment_in_balloting_budget) }
|
|
|
|
it { should be_able_to(:create, user.votes.build(votable: investment_in_selecting_budget)) }
|
|
it { should_not be_able_to(:create, user.votes.build(votable: investment_in_accepting_budget)) }
|
|
it { should_not be_able_to(:create, user.votes.build(votable: investment_in_balloting_budget)) }
|
|
it { should be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_selecting_budget)) }
|
|
it { should_not be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_accepting_budget)) }
|
|
it { should_not be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_balloting_budget)) }
|
|
|
|
it { should_not be_able_to(:destroy, investment_in_accepting_budget) }
|
|
it { should_not be_able_to(:destroy, investment_in_reviewing_budget) }
|
|
it { should_not be_able_to(:destroy, investment_in_selecting_budget) }
|
|
it { should_not be_able_to(:destroy, investment_in_balloting_budget) }
|
|
|
|
it { should be_able_to(:destroy, own_investment_in_accepting_budget) }
|
|
it { should be_able_to(:destroy, own_investment_in_reviewing_budget) }
|
|
it { should_not be_able_to(:destroy, own_investment_in_selecting_budget) }
|
|
it { should_not be_able_to(:destroy, own_investment_in_balloting_budget) }
|
|
|
|
it { should be_able_to(:edit, own_investment_in_accepting_budget) }
|
|
it { should_not be_able_to(:edit, own_investment_in_reviewing_budget) }
|
|
it { should_not be_able_to(:edit, own_investment_in_selecting_budget) }
|
|
it { should_not be_able_to(:edit, own_investment_in_balloting_budget) }
|
|
|
|
it { should be_able_to(:create, ballot_in_balloting_budget) }
|
|
it { should_not be_able_to(:create, ballot_in_accepting_budget) }
|
|
it { should_not be_able_to(:create, ballot_in_selecting_budget) }
|
|
|
|
it { should be_able_to(:destroy, own_budget_investment_image) }
|
|
it { should be_able_to(:destroy, own_budget_investment_document) }
|
|
|
|
it { should_not be_able_to(:destroy, budget_investment_image) }
|
|
it { should_not be_able_to(:destroy, budget_investment_document) }
|
|
end
|
|
end
|
|
|
|
describe "when level 3 verified" do
|
|
let(:own_direct_message) { create(:direct_message, sender: user) }
|
|
|
|
before { user.update(verified_at: Time.current) }
|
|
|
|
it { should be_able_to(:vote, Proposal) }
|
|
|
|
it { should be_able_to(:new, DirectMessage) }
|
|
it { should be_able_to(:create, DirectMessage) }
|
|
it { should be_able_to(:show, own_direct_message) }
|
|
it { should_not be_able_to(:show, create(:direct_message)) }
|
|
|
|
it { should be_able_to(:answer, current_poll) }
|
|
it { should_not be_able_to(:answer, expired_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) }
|
|
|
|
context "without geozone" do
|
|
before { 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) }
|
|
end
|
|
end
|
|
|
|
describe "#disable_recommendations" do
|
|
it { should be_able_to(:disable_recommendations, Debate) }
|
|
it { should be_able_to(:disable_recommendations, Proposal) }
|
|
end
|
|
|
|
it { should_not be_able_to(:read, SDG::Target) }
|
|
|
|
it { should_not be_able_to(:read, SDG::Manager) }
|
|
it { should_not be_able_to(:create, SDG::Manager) }
|
|
it { should_not be_able_to(:delete, SDG::Manager) }
|
|
end
|