docbrown/spec/policies/article_policy_spec.rb
Joshua Wehner 445fd0f9e5
Try renaming moderator -> super_moderator (#18261)
* Try renaming moderator -> super_moderator

* Still finding 'moderator' words

* Fixes for failing specs

* Update test with new role name

* Update app/services/moderator/manage_activity_and_roles.rb

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>

Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
2022-08-10 16:43:30 +02:00

267 lines
10 KiB
Ruby

require "rails_helper"
# See ./spec/policies/shared_examples/authorization_shared_examples.rb for the various shared examples.
RSpec.describe ArticlePolicy do
subject(:method_call) { policy.public_send(policy_method) }
let(:organization) { org_admin&.organizations&.first }
# The named "folks" with one or more roles
let(:org_admin) { create(:user, :org_admin) }
let(:anyone) { create(:user) }
let(:super_admin) { create(:user, :super_admin) }
let(:suspended_user) { create(:user, :suspended) }
let(:admin) { create(:user, :admin) }
let(:trusted) { create(:user, :trusted) }
let(:other_users) { create(:user) }
let(:author) { create(:user) }
let(:moderator) { create(:user, :super_moderator) }
let(:tag_mod) { create(:user, :tag_moderator) }
let(:tagmod_tag) { tag_mod.roles.find_by(name: "tag_moderator").resource }
let(:random_tag) { create(:tag, name: "randomtag") }
let(:resource) { build(:article, user: author, organization: organization) }
let(:policy) { described_class.new(user, resource) }
describe ".scope_users_authorized_to_action" do
before do
User.destroy_all # For some reason I'm getting extra users than there should be
super_admin
author
suspended_user
end
context "when limit_post_creation_to_admins is true" do
before { allow(described_class).to receive(:limit_post_creation_to_admins?).and_return(true) }
it "omits suspended and regular users" do
results = described_class.scope_users_authorized_to_action(users_scope: User, action: :create?).to_a
expect(results).to match_array([super_admin])
end
end
context "when limit_post_creation_to_admins is false" do
before { allow(described_class).to receive(:limit_post_creation_to_admins?).and_return(false) }
it "omits only suspended users" do
results = described_class.scope_users_authorized_to_action(users_scope: User, action: :create?).to_a
expect(results).to match_array([author, super_admin])
end
end
end
describe ".include_hidden_dom_class_for?" do
[
[true, :create?, true],
[false, :create?, false],
[true, :edit?, false],
[false, :edit?, false],
].each do |limit, query, expected_value|
context "when limit_post_creation_to_admins is #{limit} and query is #{query}" do
subject { described_class.include_hidden_dom_class_for?(query: query) }
before { allow(described_class).to receive(:limit_post_creation_to_admins?).and_return(limit) }
it { is_expected.to eq(expected_value) }
end
end
end
describe "#feed?" do
let(:policy_method) { :feed? }
let(:user) { build(:user) }
it { is_expected.to be_truthy }
end
%i[create? new?].each do |method_name|
describe "##{method_name}" do
let(:policy_method) { method_name }
it_behaves_like "it requires an authenticated user"
it_behaves_like "it requires a user in good standing"
it_behaves_like "permitted roles", to: %i[anyone], limit_post_creation_to_admins?: false
it_behaves_like "permitted roles", to: %i[super_admin admin], limit_post_creation_to_admins?: true
it_behaves_like "disallowed roles", to: %i[anyone], limit_post_creation_to_admins?: true
end
end
%i[preview? has_existing_articles_or_can_create_new_ones?].each do |method_name|
describe method_name.to_s do
let(:policy_method) { method_name }
it_behaves_like "permitted roles", to: %i[anyone], limit_post_creation_to_admins?: false
it_behaves_like "permitted roles", to: %i[super_admin admin], limit_post_creation_to_admins?: true
it_behaves_like "disallowed roles", to: %i[anyone], limit_post_creation_to_admins?: true
context "when user has published articles" do
before do
create(:article, published: true, user: user)
end
# Below are two scenarios: one with limit_post_creation_to_admins? as true and the other as
# limit_post_creation_to_admins? as false. In both cases, when the user has published
# articles, it doesn't matter if they can create an article or not, the
# `has_existing_articles_or_can_create_new_ones?` should return true (which is what the
# "permitted roles" shared spec verifies).
it_behaves_like "permitted roles", to: %i[anyone], limit_post_creation_to_admins?: false
it_behaves_like "permitted roles", to: %i[anyone], limit_post_creation_to_admins?: true
end
context "when user has no published articles" do
before { user.articles.delete_all }
it_behaves_like "permitted roles", to: %i[anyone], limit_post_creation_to_admins?: false
it_behaves_like "disallowed roles", to: %i[anyone], limit_post_creation_to_admins?: true
end
end
end
describe "#moderate?" do
let(:policy_method) { :moderate? }
it_behaves_like "it requires a user in good standing"
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[trusted super_admin admin], limit_post_creation_to_admins?: false
it_behaves_like "disallowed roles", to: %i[author], limit_post_creation_to_admins?: false
it_behaves_like "disallowed roles", to: %i[trusted super_admin admin], limit_post_creation_to_admins?: true
end
describe "#allow_tag_adjustment?" do
let(:policy_method) { :allow_tag_adjustment? }
# need "create" (as opposed to "build") for the article to be published
let(:resource) { create(:article, tags: tagmod_tag, user: author, organization: organization) }
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[super_admin admin moderator tag_mod]
it_behaves_like "disallowed roles", to: %i[org_admin author other_users]
end
describe "#tag_moderator_eligible?" do
subject(:policy) { described_class.new(tag_mod, resource) }
context "when article includes tagmod_tag, has no room for more tags, and no relevant adjustments" do
let(:resource) { create(:article, tags: "tagtwo, tagthree, tagfour, #{tagmod_tag}") }
it { is_expected.to be_tag_moderator_eligible }
end
context "when article has room for more tags and no relevant adjustments" do
let(:resource) { create(:article, tags: "tagtwo, tagthree, #{tagmod_tag}") }
it { is_expected.to be_tag_moderator_eligible }
end
context "when an irrelevant tag has been adjusted" do
let(:resource) { create(:article, tags: "tagtwo, tagthree, #{random_tag}, #{tagmod_tag}") }
it "is tag_moderator_eligible" do
create(
:tag_adjustment,
user_id: super_admin.id,
article_id: resource.id,
tag_id: random_tag.id,
tag_name: random_tag,
adjustment_type: "removal",
)
expect(policy).to be_tag_moderator_eligible
end
end
context "when article excludes tagmod_tag, has no room for more tags, and no relevant adjustments" do
let(:resource) { create(:article, tags: "tagtwo, tagthree, tagfour, tagfive") }
it { is_expected.not_to be_tag_moderator_eligible }
end
context "when tag moderator's tag has been adjusted" do
let(:resource) { create(:article, tags: "tagtwo, tagthree, tagfour, #{tagmod_tag}") }
it "is not tag_moderator_eligible" do
create(
:tag_adjustment,
user_id: super_admin.id,
article_id: resource.id,
tag_id: tagmod_tag.id,
tag_name: tagmod_tag,
adjustment_type: "removal",
)
expect(policy).not_to be_tag_moderator_eligible
end
end
context "when user is not a tag moderator" do
subject(:policy) { described_class.new(anyone, resource) }
let(:resource) { create(:article, tags: tagmod_tag.to_s) }
it { is_expected.not_to be_tag_moderator_eligible }
end
end
%i[update? edit?].each do |method_name|
describe "##{method_name}" do
let(:policy_method) { method_name }
it_behaves_like "it requires an authenticated user"
it_behaves_like "it requires a user in good standing"
it_behaves_like "permitted roles", to: %i[super_admin admin org_admin]
it_behaves_like "disallowed roles", to: [:other_users]
end
end
describe "#stats?" do
let(:policy_method) { :stats? }
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[super_admin org_admin suspended_author]
it_behaves_like "disallowed roles", to: %i[admin other_users]
end
describe "subscriptions?" do
let(:policy_method) { :subscriptions? }
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[super_admin suspended_author]
it_behaves_like "disallowed roles", to: %i[admin org_admin other_users]
end
%i[admin_unpublish? admin_featured_toggle? revoke_publication? toggle_featured_status?
can_adjust_any_tag? can_perform_moderator_actions?].each do |method_name|
describe "##{method_name}" do
let(:policy_method) { method_name }
context "when published article" do
# need "create" (as opposed to "build") for the article to be published
let(:resource) { create(:article, user: author, organization: organization) }
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[super_admin admin moderator]
it_behaves_like "disallowed roles", to: %i[org_admin author other_users]
end
context "when unpublished article" do
let(:resource) do
build(:article, user: author, organization: organization, published: false, published_at: nil)
end
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[]
it_behaves_like "disallowed roles", to: %i[super_admin admin moderator org_admin author other_users]
end
end
end
%i[destroy? delete_confirm? discussion_lock_confirm? discussion_unlock_confirm?].each do |method_name|
describe "##{method_name}" do
let(:policy_method) { method_name }
it_behaves_like "it requires an authenticated user"
it_behaves_like "permitted roles", to: %i[super_admin admin org_admin suspended_author]
it_behaves_like "disallowed roles", to: [:other_users]
end
end
end