discourse/plugins/chat/spec/lib/guardian_extensions_spec.rb
Martin Brennan 3ee4b59c64
DEV: Use guardian user for can_chat? (#19418)
Instead of passing `user` to `guardian.can_chat?`, we
can just use the inner `@user` that is part of the guardian
instance already to determine whether that user can chat,
since this is how it works for all other usages of guardian
even within chat.
2022-12-13 09:14:17 +10:00

431 lines
15 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
RSpec.describe Chat::GuardianExtensions do
fab!(:user) { Fabricate(:user) }
fab!(:staff) { Fabricate(:user, admin: true) }
fab!(:chat_group) { Fabricate(:group) }
fab!(:channel) { Fabricate(:category_channel) }
fab!(:dm_channel) { Fabricate(:direct_message_channel) }
let(:guardian) { Guardian.new(user) }
let(:staff_guardian) { Guardian.new(staff) }
it "cannot chat if the user is not in the Chat.allowed_group_ids" do
SiteSetting.chat_allowed_groups = ""
expect(guardian.can_chat?).to eq(false)
end
it "staff can always chat regardless of chat_allowed_grups" do
SiteSetting.chat_allowed_groups = ""
expect(staff_guardian.can_chat?).to eq(true)
end
it "allows TL1 to chat by default and by extension higher trust levels" do
Group.refresh_automatic_groups!
expect(guardian.can_chat?).to eq(true)
user.update!(trust_level: TrustLevel[3])
Group.refresh_automatic_groups!
expect(guardian.can_chat?).to eq(true)
end
it "allows user in specific group to chat" do
SiteSetting.chat_allowed_groups = chat_group.id
expect(guardian.can_chat?).to eq(false)
chat_group.add(user)
user.reload
expect(guardian.can_chat?).to eq(true)
end
describe "chat channel" do
it "only staff can create channels" do
expect(guardian.can_create_chat_channel?).to eq(false)
expect(staff_guardian.can_create_chat_channel?).to eq(true)
end
it "only staff can edit chat channels" do
expect(guardian.can_edit_chat_channel?).to eq(false)
expect(staff_guardian.can_edit_chat_channel?).to eq(true)
end
it "only staff can close chat channels" do
channel.update(status: :open)
expect(guardian.can_change_channel_status?(channel, :closed)).to eq(false)
expect(staff_guardian.can_change_channel_status?(channel, :closed)).to eq(true)
end
it "only staff can open chat channels" do
channel.update(status: :closed)
expect(guardian.can_change_channel_status?(channel, :open)).to eq(false)
expect(staff_guardian.can_change_channel_status?(channel, :open)).to eq(true)
end
it "only staff can archive chat channels" do
channel.update(status: :read_only)
expect(guardian.can_change_channel_status?(channel, :archived)).to eq(false)
expect(staff_guardian.can_change_channel_status?(channel, :archived)).to eq(true)
end
it "only staff can mark chat channels read_only" do
channel.update(status: :open)
expect(guardian.can_change_channel_status?(channel, :read_only)).to eq(false)
expect(staff_guardian.can_change_channel_status?(channel, :read_only)).to eq(true)
end
describe "#can_see_chat_channel?" do
context "for direct message channels" do
fab!(:chatable) { Fabricate(:direct_message) }
fab!(:channel) { Fabricate(:direct_message_channel, chatable: chatable) }
it "returns false if the user is not part of the direct message" do
expect(guardian.can_see_chat_channel?(channel)).to eq(false)
end
it "returns true if the user is part of the direct message" do
DirectMessageUser.create!(user: user, direct_message: chatable)
expect(guardian.can_see_chat_channel?(channel)).to eq(true)
end
end
context "for category channel" do
fab!(:category) { Fabricate(:category, read_restricted: true) }
before { channel.update(chatable: category) }
it "returns true if the user can see the category" do
expect(Guardian.new(user).can_see_chat_channel?(channel)).to eq(false)
group = Fabricate(:group)
CategoryGroup.create(group: group, category: category)
GroupUser.create(group: group, user: user)
# have to make a new instance of guardian because `user.secure_category_ids`
# is memoized there
expect(Guardian.new(user).can_see_chat_channel?(channel)).to eq(true)
end
end
end
describe "#can_flag_in_chat_channel?" do
alias_matcher :be_able_to_flag_in_chat_channel, :be_can_flag_in_chat_channel
context "when channel is a direct message channel" do
let(:channel) { Fabricate(:direct_message_channel) }
it "returns false" do
expect(guardian).not_to be_able_to_flag_in_chat_channel(channel)
end
end
context "when channel is a category channel" do
it "returns true" do
expect(guardian).to be_able_to_flag_in_chat_channel(channel)
end
end
context "with a private channel" do
let(:private_group) { Fabricate(:group) }
let(:private_category) { Fabricate(:private_category, group: private_group) }
let(:private_channel) { Fabricate(:category_channel, chatable: private_category) }
context "when the user can't see the channel" do
it "returns false" do
expect(guardian).not_to be_able_to_flag_in_chat_channel(private_channel)
end
end
context "when the user can see the channel" do
before { private_group.add(user) }
it "returns true" do
expect(guardian).to be_able_to_flag_in_chat_channel(private_channel)
end
end
end
end
describe "#can_flag_chat_message?" do
let!(:message) { Fabricate(:chat_message, chat_channel: channel) }
before { SiteSetting.chat_message_flag_allowed_groups = "" }
context "when user isn't staff" do
it "returns false" do
expect(guardian.can_flag_chat_message?(message)).to eq(false)
end
end
context "when user is staff" do
it "returns true" do
expect(staff_guardian.can_flag_chat_message?(message)).to eq(true)
end
end
end
describe "#can_moderate_chat?" do
context "for category channel" do
fab!(:category) { Fabricate(:category, read_restricted: true) }
before { channel.update(chatable: category) }
it "returns true for staff and false for regular users" do
expect(staff_guardian.can_moderate_chat?(channel.chatable)).to eq(true)
expect(guardian.can_moderate_chat?(channel.chatable)).to eq(false)
end
context "when enable_category_group_moderation is true" do
before { SiteSetting.enable_category_group_moderation = true }
it "returns true if the regular user is part of the reviewable_by_group for the category" do
moderator = Fabricate(:user)
mods = Fabricate(:group)
mods.add(moderator)
category.update!(reviewable_by_group: mods)
expect(Guardian.new(Fabricate(:admin)).can_moderate_chat?(channel.chatable)).to eq(true)
expect(Guardian.new(moderator).can_moderate_chat?(channel.chatable)).to eq(true)
end
end
end
context "for DM channel" do
fab!(:dm_channel) { DirectMessage.create! }
before { channel.update(chatable_type: "DirectMessageType", chatable: dm_channel) }
it "returns true for staff and false for regular users" do
expect(staff_guardian.can_moderate_chat?(channel.chatable)).to eq(true)
expect(guardian.can_moderate_chat?(channel.chatable)).to eq(false)
end
end
end
describe "#can_restore_chat?" do
fab!(:message) { Fabricate(:chat_message, chat_channel: channel, user: user) }
fab!(:chatable) { Fabricate(:category) }
context "when channel is closed" do
before { channel.update!(status: :closed) }
it "disallows a owner to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
end
it "allows a staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
end
context "when chatable is a direct message" do
fab!(:chatable) { DirectMessage.create! }
it "allows owner to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
end
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
end
context "when user is not owner of the message" do
fab!(:message) { Fabricate(:chat_message, chat_channel: channel, user: Fabricate(:user)) }
context "when chatable is a category" do
context "when category is not restricted" do
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
it "disallows any user to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
end
end
context "when category is restricted" do
fab!(:chatable) { Fabricate(:category, read_restricted: true) }
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
it "disallows any user to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
end
context "when group moderation is enabled" do
before { SiteSetting.enable_category_group_moderation = true }
it "allows a group moderator to restore" do
moderator = Fabricate(:user)
mods = Fabricate(:group)
mods.add(moderator)
chatable.update!(reviewable_by_group: mods)
expect(Guardian.new(moderator).can_restore_chat?(message, chatable)).to eq(true)
end
end
end
context "when chatable is a direct message" do
fab!(:chatable) { DirectMessage.create! }
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
it "disallows any user to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
end
end
end
end
context "when user is owner of the message" do
context "when chatable is a category" do
it "allows to restore if owner can see category" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
end
context "when category is restricted" do
fab!(:chatable) { Fabricate(:category, read_restricted: true) }
it "disallows to restore if owner can't see category" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
end
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
end
end
context "when chatable is a direct message" do
fab!(:chatable) { DirectMessage.create! }
it "allows staff to restore" do
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
end
it "allows owner to restore" do
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
end
end
end
end
describe "#can_delete_category?" do
alias_matcher :be_able_to_delete_category, :be_can_delete_category
let(:category) { channel.chatable }
context "when user is staff" do
context "when category has no channel" do
before do
category.category_channel.destroy
category.reload
end
it "allows to delete the category" do
expect(staff_guardian).to be_able_to_delete_category(category)
end
end
context "when category has a channel" do
context "when channel has no messages" do
it "allows to delete the category" do
expect(staff_guardian).to be_able_to_delete_category(category)
end
end
context "when channel has messages" do
let!(:message) { Fabricate(:chat_message, chat_channel: channel) }
it "does not allow to delete the category" do
expect(staff_guardian).not_to be_able_to_delete_category(category)
end
end
end
end
context "when user is not staff" do
context "when category has no channel" do
before do
category.category_channel.destroy
category.reload
end
it "does not allow to delete the category" do
expect(guardian).not_to be_able_to_delete_category(category)
end
end
context "when category has a channel" do
context "when channel has no messages" do
it "does not allow to delete the category" do
expect(guardian).not_to be_able_to_delete_category(category)
end
end
context "when channel has messages" do
let!(:message) { Fabricate(:chat_message, chat_channel: channel) }
it "does not allow to delete the category" do
expect(guardian).not_to be_able_to_delete_category(category)
end
end
end
end
end
end
describe "#can_create_channel_message?" do
context "when user is staff" do
it "returns true if the channel is open" do
channel.update!(status: :open)
expect(staff_guardian.can_create_channel_message?(channel)).to eq(true)
end
it "returns true if the channel is closed" do
channel.update!(status: :closed)
expect(staff_guardian.can_create_channel_message?(channel)).to eq(true)
end
it "returns false if the channel is archived" do
channel.update!(status: :archived)
expect(staff_guardian.can_create_channel_message?(channel)).to eq(false)
end
context "for direct message channels" do
it "returns true if the channel is open" do
dm_channel.update!(status: :open)
expect(staff_guardian.can_create_channel_message?(dm_channel)).to eq(true)
end
end
end
context "when user is not staff" do
it "returns true if the channel is open" do
channel.update!(status: :open)
expect(guardian.can_create_channel_message?(channel)).to eq(true)
end
it "returns false if the channel is closed" do
channel.update!(status: :closed)
expect(guardian.can_create_channel_message?(channel)).to eq(false)
end
it "returns false if the channel is archived" do
channel.update!(status: :archived)
expect(guardian.can_create_channel_message?(channel)).to eq(false)
end
context "for direct message channels" do
before { Group.refresh_automatic_groups! }
it "it still allows the user to message even if they are not in direct_message_enabled_groups because they are not creating the channel" do
SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_4]
dm_channel.update!(status: :open)
expect(guardian.can_create_channel_message?(dm_channel)).to eq(true)
end
end
end
end
end