discourse/plugins/chat/spec/lib/chat_sdk/message_spec.rb
Joffrey JAFFEUX 26c8eab1f3
FIX: allows bots to create/update/stream messages (#26900)
Prior to this commit, only system users had this pass.

Another significant change of the PR, is to make membership of a channel the angular stone of the permission check to create/update/stop streaming a message. The idea being, if you are a member of a channel already we don't need to check if you can join it AGAIN.

We also have `Chat::AutoRemove::HandleCategoryUpdated` which will deal with permissions change so it's simpler and less prone to error to consider the membership as the only source of truth.
2024-05-07 15:17:42 +02:00

194 lines
5.7 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
describe ChatSDK::Message do
describe ".create" do
fab!(:channel_1) { Fabricate(:chat_channel) }
let(:guardian) { Discourse.system_user.guardian }
let(:params) do
{ enforce_membership: false, raw: "something", channel_id: channel_1.id, guardian: guardian }
end
it "creates the message" do
message = described_class.create(**params)
expect(message.message).to eq("something")
end
context "when thread_id is present" do
fab!(:thread_1) { Fabricate(:chat_thread, channel: channel_1) }
it "creates the message in a thread" do
message = described_class.create(**params, thread_id: thread_1.id)
expect(message.thread_id).to eq(thread_1.id)
end
end
context "when force_thread is present" do
it "creates the message in a thread" do
message_1 = described_class.create(**params)
message_2 =
described_class.create(**params, in_reply_to_id: message_1.id, force_thread: true)
expect(message_2.thread.force).to eq(true)
end
end
context "when channel doesnt exist" do
it "fails" do
expect { described_class.create(**params, channel_id: -999) }.to raise_error(
"Couldn't find channel with id: `-999`",
)
end
end
context "when user can't join channel" do
it "fails" do
params[:guardian] = Fabricate(:user).guardian
expect { described_class.create(**params) }.to raise_error(
"Couldn't find membership for user with id: `#{params[:guardian].user.id}`",
)
end
end
context "when membership is enforced" do
it "works" do
SiteSetting.chat_allowed_groups = [Group::AUTO_GROUPS[:everyone]]
params[:enforce_membership] = true
params[:guardian] = Fabricate(:user).guardian
message = described_class.create(**params)
expect(message.message).to eq("something")
end
end
context "when thread doesn't exist" do
it "fails" do
expect { described_class.create(**params, thread_id: -999) }.to raise_error(
"Couldn't find thread with id: `-999`",
)
end
end
context "when params are invalid" do
it "fails" do
expect { described_class.create(**params, raw: nil, channel_id: nil) }.to raise_error(
"Chat channel can't be blank, Message can't be blank",
)
end
end
end
describe ".create_with_stream" do
fab!(:channel_1) { Fabricate(:chat_channel) }
let(:guardian) { Discourse.system_user.guardian }
let(:params) { { raw: "something", channel_id: channel_1.id, guardian: guardian } }
it "allows streaming" do
created_message =
described_class.create_with_stream(**params) do |helper, message|
expect(message.streaming).to eq(true)
edit =
MessageBus
.track_publish("/chat/#{channel_1.id}") { helper.stream(raw: " test") }
.find { |m| m.data["type"] == "edit" }
expect(edit.data["chat_message"]["message"]).to eq("something test")
end
expect(created_message.streaming).to eq(false)
expect(created_message.message).to eq("something test")
end
end
describe ".stop_stream" do
fab!(:message_1) { Fabricate(:chat_message, message: "first") }
before do
SiteSetting.chat_allowed_groups = [Group::AUTO_GROUPS[:everyone]]
message_1.chat_channel.add(message_1.user)
message_1.update!(streaming: true)
end
it "stop streaming message" do
described_class.stop_stream(message_id: message_1.id, guardian: message_1.user.guardian)
expect(message_1.reload.streaming).to eq(false)
end
context "when user can't stop streaming" do
it "fails" do
user = Fabricate(:user)
message_1.chat_channel.add(user)
expect {
described_class.stop_stream(message_id: message_1.id, guardian: user.guardian)
}.to raise_error("User with id: `#{user.id}` can't stop streaming this message")
end
end
context "when user is not part of the channel" do
fab!(:message_1) do
Fabricate(:chat_message, chat_channel: Fabricate(:private_category_channel))
end
it "fails" do
user = Fabricate(:user)
expect {
described_class.stop_stream(message_id: message_1.id, guardian: user.guardian)
}.to raise_error("Couldn't find membership for user with id: `#{user.id}`")
end
end
end
describe ".start_stream" do
fab!(:message_1) { Fabricate(:chat_message, message: "first") }
it "enables streaming" do
edit =
MessageBus
.track_publish("/chat/#{message_1.chat_channel.id}") do
described_class.start_stream(
message_id: message_1.id,
guardian: message_1.user.guardian,
)
end
.find { |m| m.data["type"] == "edit" }
expect(edit.data["chat_message"]["message"]).to eq("first")
expect(message_1.reload.streaming).to eq(true)
end
end
describe ".stream" do
fab!(:message_1) { Fabricate(:chat_message, message: "first\n") }
before do
message_1.chat_channel.add(message_1.user)
message_1.update!(streaming: true)
end
it "streams" do
edit =
MessageBus
.track_publish("/chat/#{message_1.chat_channel.id}") do
described_class.stream(
raw: " test\n",
message_id: message_1.id,
guardian: message_1.user.guardian,
)
end
.find { |m| m.data["type"] == "edit" }
expect(edit.data["chat_message"]["message"]).to eq("first\n test\n")
expect(message_1.reload.streaming).to eq(true)
end
end
end