FIX: Duplicate error for chat messages for upload-only messages (#31539)

This commit fixes an issue where if you tried to post
2 chat messages in quick succession which only contained
uploads (both `message` fields would be `""`), then we
would show the "You posted an identical message too recently."
error.

We should not do this for upload-only messages, they
are not identical messages.
This commit is contained in:
Martin Brennan
2025-02-27 17:17:36 +10:00
committed by GitHub
parent e92e05b22e
commit bf287b4560
3 changed files with 40 additions and 8 deletions

View File

@ -168,6 +168,10 @@ module Chat
Emoji.gsub_emoji_to_unicode(message).truncate(400)
end
def only_uploads?
self.message.blank? && self.uploads.present?
end
def to_markdown
upload_markdown =
self

View File

@ -12,14 +12,26 @@ module Chat
def validate
return if chat_message.nil? || chat_channel.nil?
return if chat_message.user.bot?
# Rules are a lot looser for DMs between 2 people, allows for
# things like "ok", "yes", "no", "lol", "haha", "tee-hee"
# to be sent multiple times.
return if chat_channel.direct_message_channel? && chat_channel.user_count <= 2
if chat_channel
.chat_messages
.where(created_at: 10.seconds.ago..)
.where("LOWER(message) = ?", chat_message.message.strip.downcase)
.where(user: chat_message.user)
.exists?
# It's not possible to duplicate a message that only contains uploads,
# since the message is empty.
return if chat_message.only_uploads?
recent_identical_message_found =
chat_channel
.chat_messages
.includes(:uploads)
.where(created_at: 10.seconds.ago..)
.where("LOWER(message) = ?", chat_message.message.strip.downcase)
.where(user: chat_message.user)
.exists?
if recent_identical_message_found
chat_message.errors.add(:base, I18n.t("chat.errors.duplicate_message"))
end
end

View File

@ -6,8 +6,8 @@ describe Chat::DuplicateMessageValidator do
fab!(:dm_channel) { Fabricate(:direct_message_channel) }
fab!(:user)
def message_blocked?(message:, chat_channel:, user:)
chat_message = Fabricate.build(:chat_message, user:, message:, chat_channel:)
def message_blocked?(message:, chat_channel:, user:, upload_ids: nil)
chat_message = Fabricate.build(:chat_message, user:, message:, chat_channel:, upload_ids:)
described_class.new(chat_message).validate
chat_message.errors.full_messages.include?(I18n.t("chat.errors.duplicate_message"))
end
@ -105,4 +105,20 @@ describe Chat::DuplicateMessageValidator do
expect(message_blocked?(message:, user:, chat_channel: dm_channel)).to eq(false)
end
it "doesn't block a message if both are uploads only" do
upload = Fabricate(:upload)
Fabricate(
:chat_message,
created_at: 1.second.ago,
user:,
message: "",
chat_channel: category_channel,
upload_ids: [upload.id],
)
expect(
message_blocked?(message: "", user:, chat_channel: category_channel, upload_ids: [upload.id]),
).to eq(false)
end
end