discourse/plugins/chat/spec/components/chat_message_rate_limiter_s...

75 lines
2.3 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
describe Chat::ChatMessageRateLimiter do
fab!(:user) { Fabricate(:user, trust_level: 3) }
let(:limiter) { described_class.new(user) }
before do
freeze_time
RateLimiter.enable
SiteSetting.chat_allowed_messages_for_trust_level_0 = 1
SiteSetting.chat_allowed_messages_for_other_trust_levels = 2
SiteSetting.chat_auto_silence_duration = 30
end
after { limiter.clear! }
it "does nothing when rate limits are not exceeded" do
limiter.run!
expect(user.reload.silenced?).to be false
end
it "silences the user for the correct amount of time when they exceed the limit" do
2.times do
limiter.run!
expect(user.reload.silenced?).to be false
end
expect { limiter.run! }.to raise_error(RateLimiter::LimitExceeded)
expect(user.reload.silenced?).to be true
expect(user.silenced_till).to be_within(0.1).of(30.minutes.from_now)
end
it "silences the user correctly based on trust level" do
user.update(trust_level: 0) # Should only be able to run once without hitting limit
limiter.run!
expect(user.reload.silenced?).to be false
expect { limiter.run! }.to raise_error(RateLimiter::LimitExceeded)
expect(user.reload.silenced?).to be true
end
it "doesn't hit limit if site setting for allowed messages equals 0" do
SiteSetting.chat_allowed_messages_for_other_trust_levels = 0
5.times do
limiter.run!
expect(user.reload.silenced?).to be false
end
end
it "doesn't silence the user even when the limit is broken if auto_silence_duration is set to 0" do
SiteSetting.chat_allowed_messages_for_other_trust_levels = 1
SiteSetting.chat_auto_silence_duration = 0
limiter.run!
expect(user.reload.silenced?).to be false
expect { limiter.run! }.to raise_error(RateLimiter::LimitExceeded)
expect(user.reload.silenced?).to be false
end
it "logs a staff action when the user is silenced" do
SiteSetting.chat_allowed_messages_for_other_trust_levels = 1
limiter.run!
expect { limiter.run! }.to raise_error(RateLimiter::LimitExceeded).and change {
UserHistory.where(
target_user: user,
acting_user: Discourse.system_user,
action: UserHistory.actions[:silence_user],
).count
}.by(1)
end
end