This way only verified users will be able to access this page, which shows the username of the receiver of the direct message. With this, it's no longer possible for unverified users to browse direct message URLs in order to collect usernames from every user.
376 lines
17 KiB
Ruby
376 lines
17 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(:another_user) { create(:user) }
|
|
|
|
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(:legislation_proposal) { create(:legislation_proposal) }
|
|
|
|
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) do
|
|
create(:budget_investment, budget: accepting_budget, author: user)
|
|
end
|
|
let(:own_investment_in_reviewing_budget) do
|
|
create(:budget_investment, budget: reviewing_budget, author: user)
|
|
end
|
|
let(:own_investment_in_selecting_budget) do
|
|
create(:budget_investment, budget: selecting_budget, author: user)
|
|
end
|
|
let(:own_investment_in_balloting_budget) do
|
|
create(:budget_investment, budget: balloting_budget, author: user)
|
|
end
|
|
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_to: [geozone]) }
|
|
let(:expired_poll_from_other_geozone) { create(:poll, :expired, geozone_restricted_to: [create(:geozone)]) }
|
|
let(:poll) { create(:poll, geozone_restricted: false) }
|
|
let(:poll_from_own_geozone) { create(:poll, geozone_restricted_to: [geozone]) }
|
|
let(:poll_from_other_geozone) { create(:poll, geozone_restricted_to: [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) do
|
|
create(:poll_question, poll: expired_poll_from_own_geozone)
|
|
end
|
|
let(:expired_poll_question_from_other_geozone) do
|
|
create(:poll_question, poll: expired_poll_from_other_geozone)
|
|
end
|
|
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(:create, user.votes.build(votable: debate)) }
|
|
it { should_not be_able_to(:create, another_user.votes.build(votable: debate)) }
|
|
it { should be_able_to(:destroy, user.votes.build(votable: debate)) }
|
|
it { should_not be_able_to(:destroy, another_user.votes.build(votable: 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_not 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(:create, user.votes.build(votable: comment)) }
|
|
it { should_not be_able_to(:create, another_user.votes.build(votable: comment)) }
|
|
it { should be_able_to(:destroy, user.votes.build(votable: comment)) }
|
|
it { should_not be_able_to(:destroy, another_user.votes.build(votable: 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
|
|
it { should be_able_to(:create, build(:follow, :followed_proposal, user: user)) }
|
|
it { should_not be_able_to(:create, build(:follow, :followed_proposal, user: another_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: another_user)) }
|
|
end
|
|
|
|
describe "other users" do
|
|
it { should be_able_to(:show, another_user) }
|
|
it { should_not be_able_to(:edit, another_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 "vote legislation proposal" do
|
|
context "when user is not level_two_or_three_verified" do
|
|
it { should_not be_able_to(:create, user.votes.build(votable: legislation_proposal)) }
|
|
it { should_not be_able_to(:destroy, user.votes.build(votable: legislation_proposal)) }
|
|
end
|
|
|
|
context "when user is level_two_or_three_verified" do
|
|
before { user.update(level_two_verified_at: Date.current) }
|
|
it { should be_able_to(:create, user.votes.build(votable: legislation_proposal)) }
|
|
it { should_not be_able_to(:create, another_user.votes.build(votable: legislation_proposal)) }
|
|
it { should be_able_to(:destroy, user.votes.build(votable: legislation_proposal)) }
|
|
it { should_not be_able_to(:destroy, another_user.votes.build(votable: legislation_proposal)) }
|
|
end
|
|
end
|
|
|
|
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 "Poll::Answer" do
|
|
let(:own_answer) { create(:poll_answer, author: user) }
|
|
let(:other_user_answer) { create(:poll_answer) }
|
|
let(:expired_poll) { create(:poll, :expired) }
|
|
let(:question) { create(:poll_question, :yes_no, poll: expired_poll) }
|
|
let(:expired_poll_answer) { create(:poll_answer, author: user, question: question, answer: "Yes") }
|
|
|
|
it { should be_able_to(:destroy, own_answer) }
|
|
it { should_not be_able_to(:destroy, other_user_answer) }
|
|
it { should_not be_able_to(:destroy, expired_poll_answer) }
|
|
end
|
|
|
|
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, user.votes.create!(votable: investment_in_selecting_budget)) }
|
|
it { should_not be_able_to(:destroy, user.votes.create!(votable: investment_in_accepting_budget)) }
|
|
it { should_not be_able_to(:destroy, user.votes.create!(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
|