summaryrefslogtreecommitdiff
path: root/spec/controllers/concerns/check_rate_limit_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers/concerns/check_rate_limit_spec.rb')
-rw-r--r--spec/controllers/concerns/check_rate_limit_spec.rb85
1 files changed, 85 insertions, 0 deletions
diff --git a/spec/controllers/concerns/check_rate_limit_spec.rb b/spec/controllers/concerns/check_rate_limit_spec.rb
new file mode 100644
index 00000000000..34ececfe639
--- /dev/null
+++ b/spec/controllers/concerns/check_rate_limit_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CheckRateLimit do
+ let(:key) { :some_key }
+ let(:scope) { [:some, :scope] }
+ let(:request) { instance_double('Rack::Request') }
+ let(:user) { build_stubbed(:user) }
+
+ let(:controller_class) do
+ Class.new do
+ include CheckRateLimit
+
+ attr_reader :request, :current_user
+
+ def initialize(request, current_user)
+ @request = request
+ @current_user = current_user
+ end
+
+ def redirect_back_or_default(**args)
+ end
+
+ def render(**args)
+ end
+ end
+ end
+
+ subject { controller_class.new(request, user) }
+
+ before do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:log_request)
+ end
+
+ describe '#check_rate_limit!' do
+ it 'calls ApplicationRateLimiter#throttled? with the right arguments' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(false)
+ expect(subject).not_to receive(:render)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'renders error and logs request if throttled' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(true)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:log_request).with(request, "#{key}_request_limit".to_sym, user)
+ expect(subject).to receive(:render).with({ plain: _('This endpoint has been requested too many times. Try again later.'), status: :too_many_requests })
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'redirects back if throttled and redirect_back option is set to true' do
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(key, scope: scope).and_return(true)
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:log_request).with(request, "#{key}_request_limit".to_sym, user)
+ expect(subject).not_to receive(:render)
+ expect(subject).to receive(:redirect_back_or_default).with(options: { alert: _('This endpoint has been requested too many times. Try again later.') })
+
+ subject.check_rate_limit!(key, scope: scope, redirect_back: true)
+ end
+
+ context 'when the bypass header is set' do
+ before do
+ allow(Gitlab::Throttle).to receive(:bypass_header).and_return('SOME_HEADER')
+ end
+
+ it 'skips rate limit if set to "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('1')
+
+ expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
+ expect(subject).not_to receive(:render)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+
+ it 'does not skip rate limit if set to something else than "1"' do
+ allow(request).to receive(:get_header).with(Gitlab::Throttle.bypass_header).and_return('0')
+
+ expect(::Gitlab::ApplicationRateLimiter).to receive(:throttled?)
+
+ subject.check_rate_limit!(key, scope: scope)
+ end
+ end
+ end
+end